AMM 불변식: x*y=k, StableSwap, Weighted Pool
도입
AMM은 "자동으로 가격을 정하는 pool" 정도로 설명하면 핵심이 빠진다. AMM은 reserve 상태를 가격 함수로 바꾸는 시스템이다. 사용자가 token A를 넣고 token B를 받으면 pool reserve가 바뀌고, reserve가 바뀌면 다음 사용자의 가격도 바뀐다.
이 강의의 출발점은 constant product다. x * y = k는 단순하지만 slippage, fee, LP exposure, arbitrage, MEV를 모두 이해하는 입구가 된다. StableSwap이나 weighted pool은 이 원리를 버리는 것이 아니라 특정 자산 성격에 맞게 곡선과 reserve weight를 바꾼다.
학습 목표
- AMM을 orderbook 대체물이 아니라 reserve state machine으로 설명한다.
- constant product, stable curve, weighted pool이 어떤 가격 곡선을 만드는지 구분한다.
- slippage, fee, invariant check를 코드로 계산한다.
개념 설명
Reserve state
- token0 reserve
- token1 reserve
- fee growth
- LP share
Pricing function
- x*y=k
- stable amplification
- weighted invariant
Execution risk
- slippage
- sandwich
- stale quote
- thin liquidity
| 곡선 | 적합한 자산 | 장점 | 실패 조건 |
|---|---|---|---|
| Constant product | 변동성이 있는 두 자산 | 단순하고 permissionless | 큰 주문에서 slippage가 빠르게 증가 |
| StableSwap | 가격이 비슷해야 하는 자산 | peg 주변에서 낮은 slippage | depeg 때 pool imbalance가 커짐 |
| Weighted pool | 비율이 다른 index basket | 다양한 weight 구성 | weight와 oracle 가정이 틀리면 가격 왜곡 |
코드로 확인하기
export function getAmountOut({ reserveIn, reserveOut, amountIn, feeBps}: { reserveIn: bigint; reserveOut: bigint; amountIn: bigint; feeBps: bigint;}) { const amountInAfterFee = amountIn * (10_000n - feeBps); const numerator = amountInAfterFee * reserveOut; const denominator = reserveIn * 10_000n + amountInAfterFee; return numerator / denominator;}export function priceImpactBps(spotOut: bigint, quotedOut: bigint) { if (spotOut === 0n) return 0n; return ((spotOut - quotedOut) * 10_000n) / spotOut;}// SPDX-License-Identifier: MITpragma solidity ^0.8.24;library MinOutGuard { function assertMinOut(uint256 quotedOut, uint256 minOut, uint256 maxImpactBps, uint256 impactBps) internal pure { require(quotedOut >= minOut, "too little output"); require(impactBps <= maxImpactBps, "price impact too high"); }}TypeScript 계산기는 quote가 reserve에서 나온다는 점을 보여준다. Solidity guard는 사용자가 quote만 믿지 않고 minOut과 maxImpactBps를 함께 걸어야 한다는 실무 원칙을 담는다.
강의 포인트
| 관점 | 확인할 질문 | 증거로 남길 것 |
|---|---|---|
| Reserve | 어떤 자산이 얼마만큼 들어 있는가 | reserve snapshot |
| Function | 가격 곡선은 무엇을 보존하는가 | invariant formula |
| Fee | fee가 quote와 LP share에 어떻게 반영되는가 | fee bps와 recipient |
| Risk | 큰 주문이 pool을 얼마나 흔드는가 | price impact와 minOut |
실무 예시
클라이언트[BACKEND] swap UI가 "100,000 USDC를 ETH로 교환"만 보여주면 부족하다. 사용자는 expected output, minimum output, price impact, route, pool depth를 같이 봐야 한다. 특히 stable pair라고 해서 slippage가 항상 낮은 것은 아니다. peg가 깨지면 stable curve도 한쪽 reserve로 쏠릴 수 있다.
운영자는 pool의 TVL보다 reserve ratio와 trade size 대비 depth를 더 자주 본다. LP token을 담보로 쓰는 lending market이라면 AMM reserve 변화가 lending risk로 전이된다. AMM 강의가 DeFi core 첫 강의인 이유가 여기에 있다.
흔한 오해와 실패 시나리오
| 오해 | 실패 시나리오 | 교정 방식 |
|---|---|---|
| AMM 가격은 oracle이다 | 얇은 pool 가격을 담보 평가에 써 조작된다 | oracle과 execution price를 분리한다 |
| TVL이 크면 slippage가 작다 | 한쪽 reserve가 얕거나 concentrated range 밖이면 체결이 나쁘다 | trade size 대비 depth를 본다 |
| stable pool은 안전하다 | depeg 때 imbalance가 급격히 커진다 | reserve ratio와 peg deviation을 같이 본다 |
| minOut은 옵션이다 | sandwich와 stale quote에 노출된다 | 모든 swap에 minOut 정책을 둔다 |
실습 과제
- Constant product swap 계산기 만들기: reserveIn, reserveOut, amountIn, feeBps를 받아 amountOut과 price impact를 계산한다.
- AMM 곡선 비교표 작성하기: constant product, stable swap, weighted pool을 자산 성격, 장점, 실패 조건으로 비교한다.
완료 기준
- x*y=k swap 계산에서 fee와 minOut을 반영했다.
- stable pair와 weighted pool이 constant product와 다른 이유를 reserve 관점으로 설명했다.
근거 자료
- 03 DEX and AMM
- 11 Protocol Development
- Uniswap v4 Overview