DeFi Primitives
Intermediate
1-2 weeksConstant-Product AMM Liquidity Pool
Build a Uniswap-style AMM on Ergo (x*y=k) with LP tokens
Problem
You need permissionless, always-available liquidity for token trading without order books.
Solution
Automated Market Makers use a mathematical formula (x * y = k) to price assets. Liquidity providers deposit token pairs and earn fees from trades.
How It Works
- 1Pool holds reserves of two tokens (X and Y)
- 2Price is determined by ratio: price = reserveY / reserveX
- 3Trades must maintain invariant: reserveX * reserveY >= k
- 4LP tokens represent proportional share of pool
- 5Fees (typically 0.3%) go to liquidity providers
- 6Anyone can add/remove liquidity by depositing/withdrawing proportionally
Code Examples
{
// AMM Pool Contract
val poolNFT = SELF.tokens(0)._1 // Unique pool identifier
val reserveX = SELF.tokens(1)._2 // Token X reserve
val reserveY = SELF.tokens(2)._2 // Token Y reserve
val lpTokens = SELF.tokens(3)._2 // LP tokens in pool
val feeNum = 997L // 0.3% fee (1000 - 3)
val feeDenom = 1000L
// Pool must continue with same NFT
val poolContinues = OUTPUTS(0).tokens(0)._1 == poolNFT
val newReserveX = OUTPUTS(0).tokens(1)._2
val newReserveY = OUTPUTS(0).tokens(2)._2
// Swap validation: constant product with fee
val validSwap = {
val deltaX = newReserveX - reserveX
val deltaY = newReserveY - reserveY
if (deltaX > 0) {
// Selling X for Y (X increases, Y decreases)
val xWithFee = deltaX * feeNum
newReserveY * (reserveX * feeDenom + xWithFee) >=
reserveY * reserveX * feeDenom
} else {
// Selling Y for X (Y increases, X decreases)
val yWithFee = -deltaY * feeNum
newReserveX * (reserveY * feeDenom + yWithFee) >=
reserveX * reserveY * feeDenom
}
}
// Add/remove liquidity validation
val validLiquidity = {
val newLpTokens = OUTPUTS(0).tokens(3)._2
val lpDelta = newLpTokens - lpTokens
if (lpDelta > 0) {
// Adding liquidity: must add proportionally
val xRatio = (newReserveX - reserveX) * lpTokens / reserveX
val yRatio = (newReserveY - reserveY) * lpTokens / reserveY
lpDelta <= min(xRatio, yRatio)
} else {
// Removing liquidity: receive proportionally
val xOut = -lpDelta * reserveX / lpTokens
val yOut = -lpDelta * reserveY / lpTokens
(reserveX - newReserveX) <= xOut &&
(reserveY - newReserveY) <= yOut
}
}
poolContinues && (validSwap || validLiquidity)
}Core AMM logic with 0.3% swap fee. Validates both swaps (constant product) and liquidity operations (proportional).
Use Cases
- →Decentralized token exchanges
- →Liquidity bootstrapping for new tokens
- →Yield farming infrastructure
- →Price discovery for illiquid assets
- →Stablecoin swaps
Security Considerations
- !Protect against sandwich attacks with slippage limits
- !Use time-weighted average prices for oracles
- !Implement emergency pause mechanisms
- !Audit math for overflow/underflow
- !Consider concentrated liquidity for efficiency
Resources
Fee Considerations
Swap fees typically 0.3%. Transaction fees standard. Consider batching for gas efficiency.