How Approvals Work on CoW Protocol
Before you can trade any ERC-20 token on CoW Protocol, you must grant the protocol permission to transfer your sell tokens. This is standard ERC-20 behavior, but there is one critical detail that trips up many integrators: Here is how the approval flow works at a high level:Approve the VaultRelayer
You call
approve() on the ERC-20 token contract, granting the GPv2VaultRelayer permission to spend your sell token.Token approval is a one-time operation per token. Once you approve the VaultRelayer for a given token, you do not need to approve again for future trades of that same token (unless you revoke or the allowance is exhausted).
GPv2VaultRelayer Addresses
All core CoW Protocol contracts are deployed at identical addresses across every supported chain using CREATE2 deterministic deployment.| Network | Chain ID | VaultRelayer Address |
|---|---|---|
| Ethereum Mainnet | 1 | 0xC92E8bdf79f0507f65a392b0ab4667716BFE0110 |
| Gnosis Chain | 100 | 0xC92E8bdf79f0507f65a392b0ab4667716BFE0110 |
| Arbitrum One | 42161 | 0xC92E8bdf79f0507f65a392b0ab4667716BFE0110 |
| Base | 8453 | 0xC92E8bdf79f0507f65a392b0ab4667716BFE0110 |
| Sepolia (Testnet) | 11155111 | 0xC92E8bdf79f0507f65a392b0ab4667716BFE0110 |
The address is the same on all chains. You can hardcode
0xC92E8bdf79f0507f65a392b0ab4667716BFE0110 in your integration.Standard Approval (On-Chain Transaction)
A standard approval sends a transaction to the token’sapprove function, granting the VaultRelayer a spending allowance. This costs gas but works with every ERC-20 token.
Using the TypeScript SDK
The SDK provides built-in methods that automatically target the correct VaultRelayer address for your chain:Using Python (web3.py)
Using cast (Foundry)
Gasless Approval (EIP-2612 Permit)
Some ERC-20 tokens support EIP-2612, which allows approvals via an off-chain signature instead of an on-chain transaction. This means the user pays zero gas for the approval step.How It Works
User signs a permit message
The user signs an EIP-712 typed data message off-chain. This signature authorizes the VaultRelayer to spend a specific amount of tokens. No transaction is sent, so no gas is consumed.
Permit is submitted with the order
The permit signature is included alongside the order when it is submitted to the CoW Protocol order book.
Which Tokens Support Permit?
Not every token supports EIP-2612. Here are some guidelines:- Supported: USDC, DAI, and most tokens deployed after 2021
- Not supported: WETH, USDT, and many older ERC-20 tokens
- How to check: Call
token.nonces(address)on the token contract. If the call succeeds (does not revert), the token likely supports permit.
Using the SDK (Automatic Detection)
The TypeScript SDK automatically detects whether a token supports EIP-2612 and uses permit when available:Limitations
- Not all tokens support EIP-2612 (notably WETH and USDT)
- Permit signatures expire and cannot be reused
- Some token implementations have non-standard permit behavior
Revoking Approvals
To revoke an existing approval, set the allowance to zero:Common Issues
InsufficientAllowance error
InsufficientAllowance error
You have not approved the VaultRelayer for the sell token, or the approved amount is less than the order’s sell amount (including fees).Fix: Approve the VaultRelayer for at least the sell amount, or use
maxUint256 for an infinite approval. Then resubmit your order.I approved the Settlement contract instead of the VaultRelayer
I approved the Settlement contract instead of the VaultRelayer
This is the most common mistake. The GPv2Settlement contract address is
0x9008D19f58AAbD9eD0D60971565AA8510560ab41, but approvals must go to the GPv2VaultRelayer at 0xC92E8bdf79f0507f65a392b0ab4667716BFE0110.Fix: Send a new approval transaction targeting the VaultRelayer address.Approval transaction succeeded but order still fails
Approval transaction succeeded but order still fails
Several things can cause this:
- You approved the wrong token (e.g., buy token instead of sell token)
- The approved amount is too low (remember to account for fees)
- The approval transaction has not been confirmed yet (wait for at least 1 block confirmation)
- Your wallet does not have a sufficient token balance
Token uses non-standard approve (e.g., USDT)
Token uses non-standard approve (e.g., USDT)
Some tokens like USDT require the allowance to be set to zero before setting a new non-zero value. If you try to change the allowance directly from one non-zero value to another, the transaction will revert.Fix: First approve with amount
0, wait for confirmation, then approve with your desired amount.Next Steps
- TypeScript SDK: Token Approvals — Detailed SDK reference for approval methods
- API Integration — Submit orders via the REST API after approving
- GPv2VaultRelayer Reference — Architecture details and advanced balance mechanisms (Balancer external/internal balances)