Skip to main content

How Swaps Resolve

This page explains the complete lifecycle of a swap, from input to output.

Direct swap flow

When calling swap(fromStablecoin, toStablecoin, amount, queueIfUnavailable):

1. Protocol transfers fromStablecoin from user to contract

2. Process fromStablecoin queue (FIFO)
→ Fill waiting positions with incoming tokens
→ Add remainder to supply

3. Check toStablecoin supply

4a. If supply >= amount:
→ Protocol transfers toStablecoin to user
→ Done (instant swap)

4b. If supply < amount:
→ If some supply available (partial fill):
- Protocol transfers available amount to user
- Remaining either queued (if queueIfUnavailable = true)
or user takes back their remaining fromStablecoin (if false)
→ If zero supply:
- Queue entire amount (if queueIfUnavailable = true)
- REVERT (if queueIfUnavailable = false)

Note: For "all or nothing" behavior, use queueIfUnavailable = false and rely on the revert when supply is insufficient.

Example: Full instant swap

State before:
USDC in supply: 10,000
USDT in supply: 5,000
USDC queue: empty

User swaps 3,000 USDC → USDT:

1. 3,000 USDC transferred to contract
2. USDC queue is empty, so 3,000 added to supply
3. USDT in supply (5,000) >= 3,000 ✓
4. 3,000 USDT transferred to user

State after:
USDC in supply: 13,000
USDT in supply: 2,000

Example: Partial fill with queue

State before:
USDC in supply: 10,000
USDT in supply: 1,000
USDT queue: empty

User swaps 3,000 USDC → USDT (queueIfUnavailable = true):

1. 3,000 USDC transferred to contract
2. USDC queue empty, 3,000 added to supply
3. USDT in supply (1,000) < 3,000
4. 1,000 USDT transferred to user (partial)
5. User gets in line for remaining 2,000 USDT

State after:
USDC in supply: 13,000
USDT in supply: 0
USDT queue: [User: 2,000]

Example: Queue gets filled

Continuing from above:

State:
USDT in supply: 0
USDT queue: [User: 2,000]

Someone supplies 5,000 USDT:

1. 5,000 USDT transferred to contract
2. Process USDT queue:
→ User receives 2,000 USDT (leaves queue)
3. Remaining 3,000 added to supply

State after:
USDT in supply: 3,000
USDT queue: empty

Aggregator flow

The swapExactInput function follows a simpler flow:

1. Check deadline hasn't passed
2. Check toStablecoin supply >= amountIn
→ If not, REVERT (no partial fills, no queue)
3. Transfer fromStablecoin from user
4. Process fromStablecoin queue
5. Add remainder to fromStablecoin supply
6. Deduct from toStablecoin supply
7. Transfer toStablecoin to recipient

This guarantees: either full execution or complete failure. No intermediate states.