DEX 견적 계산: V2 상수곱 vs V3 집중유동성

🌐 English

DEX 봇의 심장은 "이만큼 넣으면 얼마 나오지?"를 정확히 계산하는 견적 로직입니다. 그런데 프로토콜마다 이 계산이 전혀 다릅니다. 특히 UniswapV2 계열과 V3(집중유동성) 계열은 근본이 다르죠. 이 차이를 모르면 견적이 어긋나고, 어긋난 견적은 곧 손실입니다.

V2 — 상수곱 공식 (x * y = k)

UniswapV2 계열 풀은 두 토큰의 예비금(reserve) 곱이 일정하다는 규칙으로 굴러갑니다. 토큰X를 넣으면 그만큼 예비금이 늘고, k를 유지하기 위해 토큰Y가 나옵니다. 수수료(예: 0.3%)를 반영한 견적 공식은 온체인에서도 값싸게 계산됩니다.

// V2 견적: amountIn 을 넣으면 나오는 amountOut (수수료 0.3% = 997/1000)

func getAmountOutV2(amountIn, reserveIn, reserveOut float64) float64 {

    amountInWithFee := amountIn * 0.997

    numerator := amountInWithFee * reserveOut

    denominator := reserveIn + amountInWithFee

    return numerator / denominator

}

V2의 장점은 계산이 닫힌 공식이라는 것. 예비금 두 개만 알면 오프체인에서 즉시 견적을 냅니다. 외부 호출 없이 수천 개 페어를 빠르게 훑을 수 있죠. 대신 유동성이 0부터 무한대 가격까지 얇게 퍼져 있어 자본 효율은 낮습니다.

V3 — 집중유동성과 tick

UniswapV3는 유동성을 특정 가격 구간(tick)에 집중시킬 수 있게 했습니다. 유동성 공급자가 "이 가격대에만 유동성을 넣겠다"고 지정하죠. 자본 효율은 훨씬 높지만, 견적 계산이 복잡해집니다. 현재 가격이 어느 tick에 있는지, 그 구간에 유동성이 얼마나 있는지, 스왑이 구간 경계를 넘나에 따라 결과가 달라지기 때문입니다.

그래서 V3는 예비금 두 개로 끝나지 않습니다. 가격은 sqrtPriceX96라는 제곱근 고정소수점으로 저장되고, 활성 유동성은 tick 단위로 흩어져 있습니다. 큰 스왑이 여러 tick을 가로지르면, 각 구간마다 유동성이 달라 부분 부분 나눠 계산해야 합니다.

V3 견적은 Quoter에게 물어본다

이 복잡성 때문에, V3 견적을 오프체인에서 손으로 완벽히 재현하기는 까다롭습니다. 그래서 유니스왑은 Quoter 컨트랙트를 제공합니다. Quoter는 실제 스왑 로직을 eth_call시뮬레이션해서 정확한 결과를 돌려줍니다(상태는 바꾸지 않음).

// V3 견적: Quoter 컨트랙트에 실제 스왑을 시뮬레이션시켜 정확값을 얻는다

// (오프체인 근사보다 정확하지만, RPC 호출 비용이 든다)

amountOut, err := quoter.QuoteExactInputSingle(&bind.CallOpts{Context: ctx},

    tokenIn, tokenOut, feeTier, amountIn, big.NewInt(0))

if err != nil {

    return 0, fmt.Errorf("V3 견적 실패: %w", err)

}

트레이드오프가 분명합니다. V2는 공짜로 즉시(닫힌 공식), V3는 정확하지만 RPC 호출이 필요합니다. 그래서 실전 봇은 대개 V2로 후보를 넓게 좁힌 뒤, 유망한 V3 경로만 Quoter로 정밀 확인하는 식으로 호출 비용을 아낍니다.

슬리피지 — 견적과 실제의 간극

어느 프로토콜이든, 넣는 규모가 클수록 체결가는 불리해집니다(슬리피지). V2 공식을 보면 바로 알 수 있죠. amountInreserveIn에 비해 커질수록, 분모가 커져 단위당 받는 양이 줄어듭니다.

// 소액 vs 대액 — 같은 풀이라도 단가가 달라진다

small := getAmountOutV2(1,    1000, 1000) // ≈ 0.997 (거의 1:1)

large := getAmountOutV2(500,  1000, 1000) // ≈ 332  (1:0.66, 크게 불리)

// 진입 규모가 풀 예비금의 일정 비율을 넘으면 스킵하는 가드가 필요

그래서 견적이 좋아 보여도, 그 규모를 실제로 소화하는지는 별개입니다. 유동성 대비 진입 규모를 체크하는 가드를 반드시 함께 둡니다.

정리

  • V2x*y=k 닫힌 공식 — 오프체인에서 공짜로 즉시 견적, 대신 자본 효율 낮음
  • V3는 tick 기반 집중유동성 — 자본 효율 높지만 견적이 복잡해 Quoter 시뮬레이션이 필요
  • 실전은 V2로 넓게 훑고 V3는 정밀 확인하는 2단계로 호출 비용을 아낀다
  • 견적과 별개로 슬리피지·유동성 가드가 있어야 실속 없는 경로를 거른다

같은 "스왑"이라는 단어 뒤에 이렇게 다른 수학이 숨어 있습니다. 프로토콜의 견적 모델을 이해하는 것 — 그게 정확한 봇의 출발점입니다.

이 글은 교육·정보 목적이며 투자 권유가 아닙니다. DeFi 자동매매에는 원금 손실 위험이 있고, 결과에 대한 책임은 본인에게 있습니다.

댓글

이 블로그의 인기 게시물

한국투자증권 KIS API로 실시간 시세 받기 (WebSocket 실전)

파이썬으로 업비트 API 연동하기 — 시세 조회부터 주문까지 기초

Go로 자동매매 신호봇 프레임워크 설계하기