AMM에서 상수 곱 공식 이해하기 (k에 속지 않기)
Source: Dev.to
핵심 아이디어: x * y = k 가 실제로 의미하는 것은?
상수‑곱 AMM에서는:
x * y = k
- x = 토큰 A의 풀량
- y = 토큰 B의 풀량
- k = 상수
스왑이 일어나는 동안 k는 변하지 않아야 합니다. 풀량은 변하지만 풀량들의 곱은 그대로 유지됩니다—이것이 가격 메커니즘 전체입니다.
초기 상태
uint256 reserveA = 1000;
uint256 reserveB = 1000;
k 계산:
uint256 k = reserveA * reserveB; // 1_000_000
이 k가 풀(pool)이 머물러야 할 곡선을 정의합니다.
사용자가 토큰 A를 토큰 B로 스왑
사용자는 다음과 같이 스왑합니다:
uint256 amountAIn = 100;
단계 1: 현재 불변량 사용
uint256 k = reserveA * reserveB; // 1,000,000
이것이 이번 스왑에 유효한 유일한 k입니다.
단계 2: 들어온 토큰을 추가
uint256 newReserveA = reserveA + amountAIn; // 1,100
새로운 A 풀량은 알게 되었지만, 새로운 B 풀량은 아직 모릅니다.
단계 3: 새로운 B 풀량을 구함
불변량을 유지하기 위해:
uint256 newReserveB = k / newReserveA; // ≈ 909.09
단계 4: 사용자가 받는 양 계산
uint256 amountBOut = reserveB - newReserveB; // ≈ 90.91
사용자는 약 90.91 토큰 B를 받으며, 풀은 같은 곡선 위에 머무릅니다.
불변량 검증
1100 * 909.09 ≈ 1,000,000
불변량이 유지됩니다.
흔히 저지르는 실수: k 재계산
많은 사람들이 직관적으로 다음과 같이 시도합니다:
uint256 newK = newReserveA * reserveB; // 1,100 * 1,000 = 1,100,000
uint256 newReserveB = newK / newReserveA; // = 1,000
uint256 amountBOut = reserveB - newReserveB; // = 0
사용자는 아무것도 받지 못합니다. 이 로직은 풀을 새로운 곡선으로 이동시켜 근본적인 불변량을 위반하기 때문입니다.
실제 스왑 방정식
스왑 중 실제 AMM 방정식은:
(reserveA + amountIn) * (reserveB - amountOut) = reserveA * reserveB
amountOut을 풀면:
uint256 amountOut = reserveB - (reserveA * reserveB) / (reserveA + amountIn);
이것이 바로 Uniswap‑스타일 계약이 구현하는 방식—마법이 아니라 순수한 대수입니다.
왜 기존 k 를 사용해야 하는가
- k는 곡선을 나타냅니다.
- 스왑은 풀을 같은 곡선 위에서 이동시킵니다.
- 유동성을 추가하면 새로운 곡선이 생깁니다.
- 스왑은 새로운 곡선을 만들지 않습니다.
스왑 중에 k를 다시 계산하면 다른 곡선으로 점프하게 되고, 가격이 즉시 깨집니다.
도움이 되는 사고 모델
- k를 철도 트랙이라고 생각하세요.
- 유동성 제공자는 새로운 트랙(새 k)을 깁니다.
- 트레이더는 기존 트랙을 따라 이동합니다.
- 스왑 도중에 트랙을 다시 그리지 않습니다.
요약
- 스왑 중에는 k를 재계산하지 않는다.
- 불변량이 가격 곡선을 정의합니다.
- 스왑은 같은 곡선의 시작점과 끝점 사이에서 이루어져야 합니다.
- “새 k”를 사용하면 AMM 논리가 파괴됩니다.
다시 직관에 어긋난다고 느껴진다면, 다음을 기억하세요:
스왑은 곡선을 따라 풀을 이동시킬 뿐—곡선을 다시 그리지 않는다.
