Constant-Product AMM Liquidity Pool
Build a Uniswap-style AMM on Ergo (x*y=k) with LP tokens
Проблема
You need permissionless, always-available liquidity for token trading without order books.
Решение
Automated Market Makers use a mathematical formula (x * y = k) to price assets. Liquidity providers deposit token pairs and earn fees from trades.
Как это работает
- 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
Примеры кода
These snippets are educational references. Before using them with real funds, pin the exact SDK/compiler versions, validate register encodings, add collection-size guards before indexing arrays, publish test vectors, and keep production deployment behind an explicit review/audit gate.
{
// AMM Pool Contract
val safeShape =
SELF.tokens.size > 3 &&
OUTPUTS.size > 0 &&
OUTPUTS(0).tokens.size > 3
if (safeShape) {
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
val nonZeroReserves = reserveX > 0 && reserveY > 0 && lpTokens > 0
// Swap validation: constant product with fee
val validSwap = nonZeroReserves && {
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 = nonZeroReserves && {
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)
} else {
false
}
}Core AMM logic with 0.3% swap fee. Validates both swaps (constant product) and liquidity operations (proportional).
Варианты использования
- →Decentralized token exchanges
- →Liquidity bootstrapping for new tokens
- →Yield farming infrastructure
- →Price discovery for illiquid assets
- →Stablecoin swaps
Вопросы безопасности
- !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
Ресурсы
Swap fees typically 0.3%. Transaction fees standard. Consider batching for gas efficiency.