ERGO
DeFi Primitives
Intermediate
1-2 weeks

Constant-Product AMM Liquidity Pool

Build a Uniswap-style AMM on Ergo (x*y=k) with LP tokens

GitHub

問題

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.

運作方式

  1. 1Pool holds reserves of two tokens (X and Y)
  2. 2Price is determined by ratio: price = reserveY / reserveX
  3. 3Trades must maintain invariant: reserveX * reserveY >= k
  4. 4LP tokens represent proportional share of pool
  5. 5Fees (typically 0.3%) go to liquidity providers
  6. 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

實際應用案例

Spectrum Finance (sunset 2024)

Reference AMM implementation on Ergo's eUTXO. Sunset notice issued; contracts frozen since Feb 2024 — not an active venue. Useful as a study of eUTXO AMM design.

資源

手續費注意事項

Swap fees typically 0.3%. Transaction fees standard. Consider batching for gas efficiency.

提升您的 ErgoScript 技能

獲取新模式、教學和開發者資源的通知。

Follow for daily updates