Limitless CTF Exchange 智能合約分析:基於 Polymarket 的 Safe 4337 擴展架構


生成提示詞

請深入分析 Limitless Labs CTF Exchange 智能合約:
1. Clone limitless-ctf-exchange 源代碼
2. 與 Polymarket CTF Exchange 進行差異比較
3. 分析 Safe 4337 賬戶抽象整合方式
4. 研究雙工廠架構(Proxy + Safe)設計
5. 解析自定義 SignatureType 擴展
6. 繪製 Mermaid 對比圖說明架構差異
7. 以繁體中文撰寫工程級深度文章

執行摘要

Limitless Labs CTF Exchange 是基於 Polymarket CTF Exchange 的分叉版本,新增了重要的 Safe 4337 賬戶抽象支援。本文將深入分析其與原版的差異:

  • Safe 4337 整合:原生支援 ERC-4337 賬戶抽象錢包
  • 雙工廠架構:同時管理 Polymarket Proxy 和 Limitless Safe
  • 三種簽名類型:EOA、POLY_PROXY、LIMITLESS_SAFE
  • CREATE2 地址推導:確定性錢包地址計算
  • 域名分離:獨立的 EIP712 簽名域

目錄

  1. Limitless vs Polymarket 架構對比
  2. 簽名類型擴展
  3. Safe 4337 整合
  4. 雙工廠架構設計
  5. 關鍵差異總結

1. Limitless vs Polymarket 架構對比

1.1 整體架構差異

flowchart TB
    subgraph Limitless["Limitless CTF Exchange"]
        LCTF[CTFExchange]
        LSig[Signatures Mixin]
        LFactory[PolyFactoryHelper]

        LSigTypes["簽名類型"]
        LEOA[EOA]
        LProxy[POLY_PROXY]
        LSafe[LIMITLESS_SAFE]

        LLibs["地址推導庫"]
        LPolyProxy[PolyProxyLib]
        LPolySafe[PolySafeLib]
        LSafeLib[SafeLib ⭐新增]

        LCTF --> LSig
        LSig --> LSigTypes
        LSigTypes --> LEOA
        LSigTypes --> LProxy
        LSigTypes --> LSafe

        LSig --> LFactory
        LFactory --> LLibs
        LLibs --> LPolyProxy
        LLibs --> LPolySafe
        LLibs --> LSafeLib
    end

    subgraph Polymarket["Polymarket CTF Exchange"]
        PCTF[CTFExchange]
        PSig[Signatures Mixin]

        PSigTypes["簽名類型"]
        PEOA[EOA]
        PProxy[POLY_PROXY]
        PGnosis[POLY_GNOSIS_SAFE]
        P1271[POLY_1271]

        PLibs["地址推導庫"]
        PPolyProxy[PolyProxyLib]
        PPolySafe[PolySafeLib]

        PCTF --> PSig
        PSig --> PSigTypes
        PSigTypes --> PEOA
        PSigTypes --> PProxy
        PSigTypes --> PGnosis
        PSigTypes --> P1271

        PSig --> PLibs
        PLibs --> PPolyProxy
        PLibs --> PPolySafe
    end

1.2 關鍵差異表

特性PolymarketLimitless影響
EIP712 域名Polymarket CTF ExchangeLimitless CTF Exchange訂單不可跨平台使用
簽名類型4 種 (EOA, POLY_PROXY, POLY_GNOSIS_SAFE, POLY_1271)3 種 (EOA, POLY_PROXY, LIMITLESS_SAFE)不同錢包支援策略
Safe 實作Gnosis Safe (標準)Safe 4337 (賬戶抽象)支援 Gas 代付
工廠數量2 個 (Proxy + Safe)2 個 (Proxy + Safe)相同架構
Safe 地址傳入 implementation硬編碼地址不同部署模式

1.3 主合約對比

Polymarket CTFExchange.sol:

contract CTFExchange is
    BaseExchange,
    Auth,
    Assets,
    Fees,
    Pausable,
    AssetOperations,
    Hashing("Polymarket CTF Exchange", "1"),  // 原版域名
    NonceManager,
    Registry,
    Signatures,
    Trading
{ }

Limitless CTFExchange.sol:

contract CTFExchange is
    BaseExchange,
    Auth,
    Assets,
    Fees,
    Pausable,
    AssetOperations,
    Hashing("Limitless CTF Exchange", "1"),   // ⭐ 修改域名
    NonceManager,
    Registry,
    Signatures,
    Trading
{ }

2. 簽名類型擴展

2.1 SignatureType 枚舉變更

Polymarket 版本:

enum SignatureType {
    EOA,               // 普通外部帳戶
    POLY_PROXY,        // Polymarket Proxy 錢包
    POLY_GNOSIS_SAFE,  // Gnosis Safe 多簽
    POLY_1271          // EIP1271 合約錢包
}

Limitless 版本:

enum SignatureType {
    EOA,               // 普通外部帳戶
    POLY_PROXY,        // Polymarket Proxy 錢包(保持兼容)
    LIMITLESS_SAFE     // ⭐ 新增:Limitless Safe 4337
}

2.2 簽名驗證實作

Limitless Signatures.sol:

function isValidSignature(
    address signer,
    address associated,
    bytes32 structHash,
    bytes memory signature,
    SignatureType signatureType
) internal view returns (bool) {
    if (signatureType == SignatureType.EOA) {
        return verifyEOASignature(signer, associated, structHash, signature);
    }
    else if (signatureType == SignatureType.LIMITLESS_SAFE) {
        // ⭐ 新增的 Safe 4337 驗證
        return verifySafeSignature(signer, associated, structHash, signature);
    }
    else {
        // POLY_PROXY - 保持與 Polymarket 兼容
        return verifyPolyProxySignature(signer, associated, structHash, signature);
    }
}

/// @notice Safe 4337 簽名驗證
function verifySafeSignature(
    address signer,
    address safeAddress,
    bytes32 hash,
    bytes memory signature
) internal view returns (bool) {
    // 1. 驗證 ECDSA 簽名
    // 2. 驗證計算出的 Safe 地址匹配
    return verifyECDSASignature(signer, hash, signature) &&
           getSafeAddress(signer) == safeAddress;
}

2.3 為何移除 POLY_1271?

Limitless 移除了 POLY_1271 類型,原因可能是:

  1. Safe 4337 涵蓋用例:賬戶抽象錢包已支援合約簽名
  2. 簡化驗證邏輯:減少攻擊面
  3. 專注核心場景:EOA、Proxy、Safe 覆蓋大部分用戶

3. Safe 4337 整合

3.1 SafeLib 核心實作

檔案路徑: src/exchange/libraries/SafeLib.sol

Limitless 新增了專門的 Safe 4337 地址推導庫:

library SafeLib {
    // ⭐ 硬編碼的 Safe 4337 合約地址
    address public constant addModuleLibAddress =
        0x8EcD4ec46D4D2a6B64fE960B3D64e8B94B2234eb;

    address public constant safe4337ModuleAddress =
        0xa581c4A4DB7175302464fF3C06380BC3270b4037;

    address public constant safeProxyFactoryAddress =
        0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67;

    address public constant safeSingletonAddress =
        0x41675C099F32341bf84BFc5382aF534df5C7461a;

    address public constant multiSendAddress =
        0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526;

    address internal constant ZERO_ADDRESS = address(0);
}

3.2 CREATE2 地址推導

/// @notice 計算用戶的 Safe 4337 錢包地址
function getSafeAddress(address signer, address deployer)
    internal
    pure
    returns (address safe)
{
    uint256 saltNonce = 0;

    // 計算 Proxy 合約的 bytecode hash
    bytes32 bytecodeHash = keccak256(
        getContractBytecode(safeSingletonAddress)
    );

    // 獲取初始化代碼
    bytes memory initializer = _getInitializerCode(
        signer,
        ZERO_ADDRESS,  // 無額外 token 授權
        ZERO_ADDRESS
    );

    // 計算 salt
    bytes32 salt = keccak256(
        abi.encodePacked(keccak256(initializer), saltNonce)
    );

    // CREATE2 地址計算
    safe = _computeCreate2Address(deployer, bytecodeHash, salt);
}

3.3 Safe 初始化代碼

/// @notice 生成 Safe 初始化調用數據
function _getInitializerCode(
    address owner,
    address token,       // 可選的 token 授權
    address spender      // 可選的授權接收者
) internal pure returns (bytes memory) {
    // 設定 owners 和閾值
    address[] memory owners = new address[](1);
    owners[0] = owner;

    // 多交易設置:啟用 4337 模組
    bytes memory multiSendData = _getMultiSendData(owner, token, spender);

    return abi.encodeWithSelector(
        ISafe.setup.selector,
        owners,                    // _owners
        1,                         // _threshold
        multiSendAddress,          // to (MultiSend)
        multiSendData,             // data (啟用模組)
        safe4337ModuleAddress,     // fallbackHandler
        ZERO_ADDRESS,              // paymentToken
        0,                         // payment
        ZERO_ADDRESS               // paymentReceiver
    );
}

3.4 4337 模組啟用

/// @notice 構建多交易數據以啟用 4337 模組
function _getMultiSendData(
    address owner,
    address token,
    address spender
) internal pure returns (bytes memory) {
    bytes memory transactions;

    // 交易 1: 啟用 4337 模組
    bytes memory enableModuleData = abi.encodeWithSelector(
        ISafe.enableModule.selector,
        safe4337ModuleAddress
    );

    transactions = abi.encodePacked(
        uint8(0),              // operation (Call)
        addModuleLibAddress,   // to
        uint256(0),            // value
        uint256(enableModuleData.length),
        enableModuleData
    );

    // 可選交易 2: Token 授權
    if (token != ZERO_ADDRESS && spender != ZERO_ADDRESS) {
        bytes memory approveData = abi.encodeWithSelector(
            IERC20.approve.selector,
            spender,
            type(uint256).max
        );

        transactions = abi.encodePacked(
            transactions,
            uint8(0),
            token,
            uint256(0),
            uint256(approveData.length),
            approveData
        );
    }

    return abi.encodeWithSelector(
        IMultiSend.multiSend.selector,
        transactions
    );
}

3.5 Safe 4337 vs Gnosis Safe 對比

flowchart TB
    subgraph Safe4337["Safe 4337 (Limitless)"]
        S4User[用戶]
        S4Bundler[Bundler]
        S4EntryPoint[EntryPoint]
        S4Module[4337 Module]
        S4Safe[Safe 合約]
        S4Exchange[CTFExchange]

        S4User -->|簽署 UserOp| S4Bundler
        S4Bundler -->|提交| S4EntryPoint
        S4EntryPoint -->|驗證| S4Module
        S4Module -->|執行| S4Safe
        S4Safe -->|交易| S4Exchange
    end

    subgraph GnosisSafe["Gnosis Safe (Polymarket)"]
        GSUser[用戶]
        GSRelayer[Relayer]
        GSSafe[Safe 合約]
        GSExchange[CTFExchange]

        GSUser -->|簽署交易| GSRelayer
        GSRelayer -->|執行| GSSafe
        GSSafe -->|交易| GSExchange
    end

Safe 4337 優勢:

  • 標準化的 Gas 代付機制
  • 更好的跨鏈兼容性
  • 內建的批量交易支援

4. 雙工廠架構設計

4.1 PolyFactoryHelper

檔案路徑: src/exchange/mixins/PolyFactoryHelper.sol

Limitless 維護兩套工廠基礎設施:

abstract contract PolyFactoryHelper {
    // Polymarket Proxy 工廠
    address public proxyFactory;

    // Limitless Safe 工廠
    address public safeFactory;

    /// @notice 獲取用戶的 Polymarket Proxy 錢包地址
    function getPolyProxyWalletAddress(address _addr)
        public view returns (address)
    {
        return PolyProxyLib.getProxyWalletAddress(
            _addr,
            getPolyProxyFactoryImplementation(),
            proxyFactory
        );
    }

    /// @notice 獲取用戶的 Safe 4337 錢包地址
    function getSafeAddress(address _addr)
        public view returns (address)
    {
        return SafeLib.getSafeAddress(_addr, safeFactory);
    }

    /// @notice 管理員設置 Proxy 工廠
    function setProxyFactory(address _proxyFactory) external onlyAdmin {
        proxyFactory = _proxyFactory;
        emit ProxyFactorySet(_proxyFactory);
    }

    /// @notice 管理員設置 Safe 工廠
    function setSafeFactory(address _safeFactory) external onlyAdmin {
        safeFactory = _safeFactory;
        emit SafeFactorySet(_safeFactory);
    }
}

4.2 地址推導庫對比

flowchart LR
    subgraph PolyProxyLib["PolyProxyLib"]
        PP1[輸入: signer, implementation, deployer]
        PP2[Salt: keccak256(signer)]
        PP3[Bytecode: Proxy 合約]
        PP4[CREATE2 計算]
        PP1 --> PP2 --> PP4
        PP1 --> PP3 --> PP4
    end

    subgraph PolySafeLib["PolySafeLib (Polymarket)"]
        PS1[輸入: signer, implementation, deployer]
        PS2[Salt: keccak256(encode(signer))]
        PS3[Bytecode: 傳入 implementation]
        PS4[CREATE2 計算]
        PS1 --> PS2 --> PS4
        PS1 --> PS3 --> PS4
    end

    subgraph SafeLib["SafeLib (Limitless)"]
        SL1[輸入: signer, deployer]
        SL2[Salt: keccak256(initializer, nonce)]
        SL3[Bytecode: 硬編碼 singleton]
        SL4[CREATE2 計算]
        SL1 --> SL2 --> SL4
        SL3 --> SL4
    end

4.3 關鍵差異

PolySafeLib (Polymarket):

function getSafeAddress(
    address signer,
    address implementation,  // ⭐ 傳入 implementation
    address deployer
) internal pure returns (address safe) {
    bytes32 bytecodeHash = keccak256(
        getContractBytecode(implementation)
    );
    bytes32 salt = keccak256(abi.encode(signer));
    safe = _computeCreate2Address(deployer, bytecodeHash, salt);
}

SafeLib (Limitless):

function getSafeAddress(
    address signer,
    address deployer
) internal pure returns (address safe) {
    // ⭐ 使用硬編碼 singleton
    bytes32 bytecodeHash = keccak256(
        getContractBytecode(safeSingletonAddress)
    );

    // ⭐ 使用 initializer + nonce 作為 salt
    bytes memory initializer = _getInitializerCode(signer, ...);
    bytes32 salt = keccak256(
        abi.encodePacked(keccak256(initializer), saltNonce)
    );

    safe = _computeCreate2Address(deployer, bytecodeHash, salt);
}

設計權衡:

  • Polymarket: 靈活(可更換 implementation)
  • Limitless: 簡單(固定使用 Safe 4337)

5. 關鍵差異總結

5.1 功能對比表

功能PolymarketLimitless說明
域名Polymarket CTF ExchangeLimitless CTF Exchange訂單不互通
EOA 簽名相同實作
Proxy 錢包保持兼容
Gnosis Safe移除
Safe 4337新增
EIP1271移除
Gas 代付依賴 Relayer原生支援更好的 UX

5.2 用戶體驗影響

flowchart TB
    subgraph Polymarket["Polymarket 用戶流程"]
        PU1[創建錢包]
        PU2[存入 Gas]
        PU3[簽署訂單]
        PU4[等待 Relayer]
        PU5[訂單執行]

        PU1 --> PU2 --> PU3 --> PU4 --> PU5
    end

    subgraph Limitless["Limitless 用戶流程 (Safe 4337)"]
        LU1[創建 Safe]
        LU2[簽署 UserOp]
        LU3[Bundler 代付 Gas]
        LU4[訂單執行]

        LU1 --> LU2 --> LU3 --> LU4
    end

Limitless 優勢:

  • 無需預存 Gas(Bundler 代付)
  • 更好的隱私保護(UserOp 批處理)
  • 標準化的賬戶抽象介面

5.3 技術決策權衡

決策Polymarket 方案Limitless 方案權衡分析
Safe 版本Gnosis Safe 1.xSafe 4337新版本需更多測試
地址推導動態 implementation硬編碼簡單但較不靈活
簽名類型4 種3 種更聚焦但較少選擇
兼容性廣泛支援專注 4337未來導向

5.4 源碼文件對比

Polymarket                      Limitless
─────────────────────────────────────────────────────
libraries/
├── PolyProxyLib.sol           ├── PolyProxyLib.sol     (相同)
├── PolySafeLib.sol            ├── PolySafeLib.sol      (相同)
│                              └── SafeLib.sol ⭐        (新增)
└── CalculatorHelper.sol       └── CalculatorHelper.sol (相同)

mixins/
├── Signatures.sol             ├── Signatures.sol       (修改)
│   └── 4種簽名類型             │   └── 3種簽名類型
│                              ├── PolyFactoryHelper.sol (修改)
│                              │   └── 新增 safeFactory
└── ...                        └── ...                  (相同)

5.5 訂單結構對比

兩者使用相同的 Order 結構,但 SignatureType 枚舉不同:

// 相同的訂單結構
struct Order {
    uint256 salt;
    address maker;
    address signer;
    address taker;
    uint256 tokenId;
    uint256 makerAmount;
    uint256 takerAmount;
    uint256 expiration;
    uint256 nonce;
    uint256 feeRateBps;
    Side side;
    SignatureType signatureType;  // ⭐ 枚舉值不同
    bytes signature;
}

重要:由於 SignatureType 枚舉不同,訂單無法在兩個平台間通用。


總結

Limitless Labs 的創新

  1. Safe 4337 原生整合

    • 首個整合 ERC-4337 的預測市場
    • 支援 Bundler 代付 Gas
    • 更好的用戶體驗
  2. 簡化的簽名類型

    • 聚焦三種核心類型
    • 移除 EIP1271 複雜性
    • 更清晰的驗證邏輯
  3. 硬編碼 Safe 地址

    • 簡化部署流程
    • 確保一致的地址推導
    • 犧牲靈活性換取簡單性

適用場景

場景推薦平台
傳統 EOA 用戶兩者皆可
需要多簽Polymarket (Gnosis Safe)
需要 Gas 代付Limitless (Safe 4337)
合約錢包 (EIP1271)Polymarket
未來賬戶抽象生態Limitless

關鍵文件路徑

Limitless 新增/修改:
├── src/exchange/libraries/SafeLib.sol          # Safe 4337 地址推導
├── src/exchange/mixins/Signatures.sol          # 3種簽名類型
├── src/exchange/mixins/PolyFactoryHelper.sol   # 雙工廠管理
└── src/exchange/CTFExchange.sol                # 域名修改

保持不變:
├── src/exchange/mixins/Trading.sol             # 核心交易邏輯
├── src/exchange/libraries/CalculatorHelper.sol # 費用計算
└── src/exchange/libraries/PolyProxyLib.sol     # Proxy 地址推導

Limitless Labs CTF Exchange 展示了如何在保持 Polymarket 核心架構的同時,整合 ERC-4337 賬戶抽象標準,為預測市場帶來更好的用戶體驗。