Swaps
Swaps are the core trading mechanism in the Oyl AMM protocol. They allow users to exchange one token for another using the liquidity stored in pools.
How Swaps Work
Constant Product Formula
Swaps in Oyl AMM follow the constant product formula:
x * y = k
When a user swaps token A for token B:
- Token A is added to the pool's reserve
- Token B is removed from the pool's reserve
- The product
k
remains constant (minus fees) - Price adjusts based on the new reserve ratio
Price Impact
The price impact of a swap depends on:
- Trade size: Larger trades have higher price impact
- Pool liquidity: More liquidity means lower price impact
- Current reserves: Imbalanced pools have higher impact
Swap Types
Exact Input Swaps
User specifies exact amount of input tokens:
SwapExactTokensForTokens {
path: Vec<AlkaneId>, // Token path for the swap
amount_out_min: u128, // Minimum output amount
deadline: u128, // Transaction deadline in block height
}
Exact Output Swaps
User specifies exact amount of output tokens:
SwapTokensForExactTokens {
path: Vec<AlkaneId>, // Token path for the swap
amount_out: u128, // Exact output amount desired
amount_in_max: u128, // Maximum input amount
deadline: u128, // Transaction deadline in block height
}
Multi-hop Swaps
Path Routing
For tokens without direct pairs, swaps can route through multiple pools:
Token A → Token B → Token C
The path
parameter defines the route:
- First element: input token
- Last element: output token
- Intermediate elements: routing tokens
Swap Calculations
Output Amount Calculation
For exact input swaps:
fn get_amount_out(amount_in: u128, reserve_in: u128, reserve_out: u128) -> u128 {
let amount_in_with_fee = amount_in * 995;
let numerator = amount_in_with_fee * reserve_out;
let denominator = (reserve_in * 1000) + amount_in_with_fee;
numerator / denominator
}
Input Amount Calculation
For exact output swaps:
fn get_amount_in(amount_out: u128, reserve_in: u128, reserve_out: u128) -> u128 {
let numerator = reserve_in * amount_out * 1000;
let denominator = (reserve_out - amount_out) * 995;
(numerator / denominator) + 1
}
Slippage Protection
Minimum Output
For exact input swaps, specify minimum output:
amount_out_min: u128 // Revert if output is less than this
Maximum Input
For exact output swaps, specify maximum input:
amount_in_max: u128 // Revert if input exceeds this
Deadline Protection
All swaps include deadline protection:
deadline: u128 // Revert if block height exceeds this
Low-Level Swap Function
Direct Pool Swap
Advanced users can call the pool's swap function directly:
Swap {
amount_0_out: u128, // Amount of token0 to receive
amount_1_out: u128, // Amount of token1 to receive
to: AlkaneId, // Recipient address
data: Vec<u128>, // Additional data for flash swaps
}
Warning: Direct swaps bypass safety checks and should only be used by experienced developers.
Flash Swaps
Concept
Flash swaps allow borrowing tokens from a pool without upfront payment:
- Receive tokens from the pool
- Use tokens in external operations
- Repay the pool (with fee) in the same transaction
Use Cases
- Arbitrage opportunities
- Liquidations
- Complex trading strategies
Best Practices
Slippage Management
- Calculate expected output off-chain
- Set appropriate slippage tolerance
- Consider market volatility
Deadline Setting
- Use reasonable deadlines (~30 minutes)
- Account for network congestion
- Avoid very short deadlines
Route Selection
- Check multiple paths for best rates
- Consider fuel costs for multi-hop swaps
- Monitor pool liquidity
Swaps are the primary way users interact with the Oyl AMM protocol, providing efficient and decentralized token exchange.