> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Polymarket/ctf-exchange/llms.txt
> Use this file to discover all available pages before exploring further.

# Signature Types

> Learn about the different signature types supported by the CTF Exchange - EOA, POLY_PROXY, POLY_GNOSIS_SAFE, and POLY_1271

The CTFExchange supports multiple signature types to accommodate different wallet architectures and user setups. Each signature type has specific validation rules to ensure security and compatibility.

## SignatureType Enum

The exchange defines four signature types:

```solidity OrderStructs.sol theme={null}
enum SignatureType {
    // 0: ECDSA EIP712 signatures signed by EOAs
    EOA,
    // 1: EIP712 signatures signed by EOAs that own Polymarket Proxy wallets
    POLY_PROXY,
    // 2: EIP712 signatures signed by EOAs that own Polymarket Gnosis safes
    POLY_GNOSIS_SAFE,
    // 3: EIP1271 signatures signed by smart contracts. To be used by smart contract wallets or vaults
    POLY_1271
}
```

## Signature Type Details

<Tabs>
  <Tab title="EOA">
    ### EOA (Externally Owned Account)

    **Value:** `0`

    **Description:** Standard ECDSA EIP-712 signatures signed by regular Ethereum accounts.

    #### Validation Rules

    <Steps>
      <Step title="Signature Recovery">
        The signature is validated using standard ECDSA signature recovery:

        ```solidity Signatures.sol theme={null}
        function verifyECDSASignature(
            address signer,
            bytes32 structHash,
            bytes memory signature
        ) internal pure returns (bool) {
            return ECDSA.recover(structHash, signature) == signer;
        }
        ```
      </Step>

      <Step title="Address Verification">
        The `signer` and `maker` addresses **must be identical**:

        ```solidity Signatures.sol theme={null}
        function verifyEOASignature(
            address signer,
            address maker,
            bytes32 structHash,
            bytes memory signature
        ) internal pure returns (bool) {
            return (signer == maker) && verifyECDSASignature(signer, structHash, signature);
        }
        ```
      </Step>
    </Steps>

    #### Use Cases

    <CardGroup cols={2}>
      <Card title="MetaMask" icon="fox">
        Direct signing with MetaMask or other browser wallets
      </Card>

      <Card title="Hardware Wallets" icon="usb-drive">
        Ledger, Trezor, and other hardware wallet users
      </Card>

      <Card title="Private Keys" icon="key">
        Direct private key signing in backend services
      </Card>

      <Card title="Mobile Wallets" icon="mobile">
        Rainbow, Trust Wallet, and other mobile wallet apps
      </Card>
    </CardGroup>

    <Note>
      This is the most common signature type and the simplest to implement for individual users.
    </Note>
  </Tab>

  <Tab title="POLY_PROXY">
    ### POLY\_PROXY (Polymarket Proxy Wallet)

    **Value:** `1`

    **Description:** EIP-712 signatures signed by EOAs that own Polymarket Proxy wallets.

    #### How It Works

    Polymarket Proxy wallets allow users to interact with the exchange through a proxy contract owned by their EOA.

    <Steps>
      <Step title="EOA Signs Order">
        The EOA (externally owned account) signs the order using their private key.
      </Step>

      <Step title="Proxy Ownership Verification">
        The exchange verifies that the EOA owns the proxy wallet:

        ```solidity Signatures.sol theme={null}
        function verifyPolyProxySignature(
            address signer,
            address proxyWallet,
            bytes32 structHash,
            bytes memory signature
        ) internal view returns (bool) {
            return verifyECDSASignature(signer, structHash, signature) 
                && getPolyProxyWalletAddress(signer) == proxyWallet;
        }
        ```
      </Step>

      <Step title="Assets Transfer from Proxy">
        When the order is matched, assets are transferred from the proxy wallet address, not the EOA.
      </Step>
    </Steps>

    #### Order Field Setup

    ```solidity theme={null}
    Order memory order = Order({
        // ... other fields
        maker: 0xABCD..., // Proxy wallet address
        signer: 0x1234..., // EOA that owns the proxy
        signatureType: SignatureType.POLY_PROXY,
        // ... other fields
    });
    ```

    <Warning>
      The `signer` must be the EOA that owns the proxy wallet specified in `maker`. The exchange validates this relationship on-chain.
    </Warning>

    #### Benefits

    * **Gas Optimization**: Proxy contracts can implement gas-efficient patterns
    * **Flexibility**: Additional logic can be implemented in the proxy
    * **Security**: Separation between signing key and asset holder
  </Tab>

  <Tab title="POLY_GNOSIS_SAFE">
    ### POLY\_GNOSIS\_SAFE (Polymarket Gnosis Safe)

    **Value:** `2`

    **Description:** EIP-712 signatures signed by EOAs that own Polymarket Gnosis Safe wallets.

    #### How It Works

    Similar to POLY\_PROXY, but specifically for Gnosis Safe multi-signature wallets.

    <Steps>
      <Step title="Safe Owner Signs">
        One of the safe owners (EOA) signs the order with their private key.
      </Step>

      <Step title="Safe Ownership Verification">
        The exchange verifies that the EOA is an owner of the Gnosis Safe:

        ```solidity Signatures.sol theme={null}
        function verifyPolySafeSignature(
            address signer,
            address safeAddress,
            bytes32 hash,
            bytes memory signature
        ) internal view returns (bool) {
            return verifyECDSASignature(signer, hash, signature) 
                && getSafeAddress(signer) == safeAddress;
        }
        ```
      </Step>

      <Step title="Assets Transfer from Safe">
        When matched, assets are transferred from the Gnosis Safe contract.
      </Step>
    </Steps>

    #### Order Field Setup

    ```solidity theme={null}
    Order memory order = Order({
        // ... other fields
        maker: 0xSAFE..., // Gnosis Safe address
        signer: 0x1234..., // EOA that owns the safe
        signatureType: SignatureType.POLY_GNOSIS_SAFE,
        // ... other fields
    });
    ```

    #### Use Cases

    <CardGroup cols={2}>
      <Card title="Multi-Sig" icon="users">
        Institutional accounts with multiple signers
      </Card>

      <Card title="Treasury" icon="vault">
        DAO or protocol treasuries
      </Card>

      <Card title="Security" icon="shield-check">
        Enhanced security through multi-party approval
      </Card>

      <Card title="Shared Accounts" icon="user-group">
        Team or organizational trading accounts
      </Card>
    </CardGroup>

    <Note>
      While Gnosis Safe supports multiple owners, only one owner's signature is required for order signing in this implementation.
    </Note>
  </Tab>

  <Tab title="POLY_1271">
    ### POLY\_1271 (EIP-1271 Smart Contract Signature)

    **Value:** `3`

    **Description:** EIP-1271 signatures for smart contract wallets and vaults.

    #### How It Works

    EIP-1271 allows smart contracts to validate signatures according to their own custom logic.

    <Steps>
      <Step title="Contract Signature">
        The smart contract implements the EIP-1271 `isValidSignature` function:

        ```solidity EIP-1271 theme={null}
        interface IERC1271 {
            function isValidSignature(
                bytes32 hash,
                bytes memory signature
            ) external view returns (bytes4 magicValue);
        }
        ```
      </Step>

      <Step title="Exchange Validation">
        The exchange calls the contract's validation function:

        ```solidity Signatures.sol theme={null}
        function verifyPoly1271Signature(
            address signer,
            address maker,
            bytes32 hash,
            bytes memory signature
        ) internal view returns (bool) {
            return (signer == maker) 
                && maker.code.length > 0
                && SignatureCheckerLib.isValidSignatureNow(maker, hash, signature);
        }
        ```
      </Step>

      <Step title="Custom Logic">
        The smart contract can implement any validation logic (multi-sig, time-locks, custom rules, etc.).
      </Step>
    </Steps>

    #### Order Field Setup

    ```solidity theme={null}
    Order memory order = Order({
        // ... other fields
        maker: 0xCONTRACT..., // Smart contract address
        signer: 0xCONTRACT..., // Same as maker
        signatureType: SignatureType.POLY_1271,
        // ... other fields
    });
    ```

    <Warning>
      For POLY\_1271, `signer` and `maker` **must be the same address** and must be a deployed smart contract.
    </Warning>

    #### Use Cases

    <CardGroup cols={2}>
      <Card title="Smart Wallets" icon="wallet">
        Account abstraction wallets (e.g., Argent, Safe)
      </Card>

      <Card title="Vaults" icon="building-columns">
        DeFi protocol vaults and automated strategies
      </Card>

      <Card title="DAOs" icon="users-gear">
        Decentralized autonomous organizations
      </Card>

      <Card title="Custom Logic" icon="code">
        Any contract with custom signature validation rules
      </Card>
    </CardGroup>

    #### Implementation Example

    ```solidity Example Smart Contract Wallet theme={null}
    contract SmartWallet is IERC1271 {
        address public owner;
        
        function isValidSignature(
            bytes32 hash,
            bytes memory signature
        ) external view override returns (bytes4) {
            // Custom validation logic
            if (ECDSA.recover(hash, signature) == owner) {
                return 0x1626ba7e; // EIP-1271 magic value
            }
            return 0xffffffff; // Invalid
        }
    }
    ```
  </Tab>
</Tabs>

## Signature Validation Flow

The exchange validates signatures through a unified interface:

```solidity Signatures.sol theme={null}
function isValidSignature(
    address signer,
    address associated,
    bytes32 structHash,
    bytes memory signature,
    SignatureType signatureType
) internal view returns (bool) {
    if (signatureType == SignatureType.EOA) {
        // EOA
        return verifyEOASignature(signer, associated, structHash, signature);
    } else if (signatureType == SignatureType.POLY_GNOSIS_SAFE) {
        // POLY_GNOSIS_SAFE
        return verifyPolySafeSignature(signer, associated, structHash, signature);
    } else if (signatureType == SignatureType.POLY_1271) {
        // POLY_1271
        return verifyPoly1271Signature(signer, associated, structHash, signature);
    } else {
        // POLY_PROXY
        return verifyPolyProxySignature(signer, associated, structHash, signature);
    }
}
```

## Signature Type Comparison

| Feature              | EOA        | POLY\_PROXY | POLY\_GNOSIS\_SAFE | POLY\_1271 |
| -------------------- | ---------- | ----------- | ------------------ | ---------- |
| **Signer = Maker**   | ✅ Required | ❌ Different | ❌ Different        | ✅ Required |
| **Must be Contract** | ❌ No       | ❌ No        | ❌ No               | ✅ Yes      |
| **Ownership Check**  | ❌ No       | ✅ Proxy     | ✅ Safe             | ❌ No       |
| **Signature Type**   | ECDSA      | ECDSA       | ECDSA              | EIP-1271   |
| **Complexity**       | Low        | Medium      | Medium             | High       |
| **Gas Cost**         | Lowest     | Medium      | Medium             | Variable   |

## Security Considerations

<AccordionGroup>
  <Accordion title="EOA Security" icon="shield">
    * Private key must be kept secure
    * No recovery mechanism if key is lost
    * Single point of failure
    * Simplest but least flexible
  </Accordion>

  <Accordion title="Proxy Security" icon="shield-halved">
    * Ownership relationship is validated on-chain
    * Proxy contract code must be trusted
    * Additional attack surface through proxy contract
    * More flexible than raw EOA
  </Accordion>

  <Accordion title="Safe Security" icon="shield-check">
    * Multi-signature provides redundancy
    * Owner set can be updated
    * More complex validation logic
    * Higher gas costs but better security
  </Accordion>

  <Accordion title="EIP-1271 Security" icon="shield-virus">
    * Security depends entirely on contract implementation
    * Must carefully audit validation logic
    * Potential for complex vulnerabilities
    * Maximum flexibility but requires expertise
  </Accordion>
</AccordionGroup>

## Choosing the Right Signature Type

<Steps>
  <Step title="Individual Users">
    Use **EOA** for simplicity and lowest gas costs. Suitable for most retail traders.
  </Step>

  <Step title="Advanced Users">
    Use **POLY\_PROXY** if you need gas optimization or additional wallet features.
  </Step>

  <Step title="Teams & Organizations">
    Use **POLY\_GNOSIS\_SAFE** for multi-signature security and shared account management.
  </Step>

  <Step title="Protocols & Smart Contracts">
    Use **POLY\_1271** for vaults, DAOs, or any custom signature validation logic.
  </Step>
</Steps>

## Related Resources

<CardGroup cols={2}>
  <Card title="Order Structure" icon="file-lines" href="/concepts/order-structure">
    Learn about the complete Order struct
  </Card>

  <Card title="EIP-712" icon="book" href="https://eips.ethereum.org/EIPS/eip-712">
    Read the EIP-712 specification
  </Card>

  <Card title="EIP-1271" icon="book" href="https://eips.ethereum.org/EIPS/eip-1271">
    Read the EIP-1271 specification
  </Card>
</CardGroup>
