How It Works
The contract checks your balance of both tokens and automatically creates a sell order for whichever token you have more of. The trade aims to bring both balances closer to equal, while adding a half-spread markup to the exchange rate.Data Structure
Parameters
One of the two tokens to swap between. Typically a stablecoin (e.g., USDC).
The other token to swap between. Typically another stablecoin (e.g., DAI).
The width of the validity bucket in seconds. This determines how long each order is valid and helps prevent order collision.The This buckets time into fixed windows, ensuring orders queried within the same window have the same
validTo timestamp is calculated as:validTo (and thus same orderUid).Recommended values:- 604800 (1 week)
- 1209600 (2 weeks)
Validity should be between 1-2 weeks. Shorter periods can cause order spam, longer periods may delay updates.
The markup above parity (1:1 exchange rate) charged for each swap, in basis points (1 bp = 0.01%).The buy amount is calculated as:Examples:
- 0 = No spread, trade at parity
- 10 = 0.1% markup
- 50 = 0.5% markup
- 100 = 1% markup
The IPFS hash of the appData associated with the order
Behavior
Side Selection
The contract automatically determines which token to sell:- Get balances:
balanceA = tokenA.balanceOf(owner)andbalanceB = tokenB.balanceOf(owner) - Convert balances to common decimals:
normalizedA = convertAmount(tokenA, balanceA, tokenB) - Compare: if
normalizedA > balanceB, sell tokenA; otherwise sell tokenB
Amount Conversion
The contract handles different token decimals automatically:Receiver
The order always setsreceiver = address(0), which is a special value in CoW Protocol that means “send tokens to the order owner” (self).
Order Properties
- Kind: Always sell orders (
KIND_SELL) - Partially fillable: No (
false) - Fee: 0 (limit order)
- Balance: ERC20 balances for both tokens
Validation
The sell amount is 0, meaning the owner has no balance of the token that should be sold. The order is invalid.
Example Usage
Example 1: USDC/DAI Rebalancing
Automatically maintain equal USDC and DAI holdings with 0.1% spread:- You hold 1000 USDC and 500 DAI
- Contract sells 1000 USDC for at least 1001 DAI (1000 + 0.1%)
- After trade, you have ~0 USDC and ~1501 DAI
- Next time, contract sells DAI back to USDC
- Continues rebalancing perpetually
Example 2: Multi-Stablecoin with Higher Spread
Rebalance between USDT and USDC with 0.5% spread:Example 3: Zero Spread Rebalancing
Rebalance at parity (no profit, pure rebalancing):Use Cases
Liquidity Provision
Maintain balanced holdings while providing liquidity:- Hold equal amounts of two stablecoins
- Automatically rebalance as one is depleted
- Earn spread on each rebalancing trade
Yield Optimization
Capture small price deviations between stablecoins:- Set small spread (0.1-0.5%)
- Profit from peg deviations
- Automatically rebalance to starting position
Portfolio Management
Maintain exposure to multiple stablecoins:- Split holdings across different stablecoins for diversification
- Automatically rebalance to maintain equal positions
- Reduce risk from single stablecoin depegs
Implementation Details
Contract Address
The Perpetual Stable Swap conditional order type is deployed at/src/types/PerpetualStableSwap.sol.
Key Functions
The order uses validity buckets to ensure consistent
orderUid values when queried multiple times within the same time window. This prevents order spam on the CoW Protocol orderbook.