vs CPMM

처음 탈중앙화 거래소가 등장했을때 사용했던 가격 결정 알고리즘은 CPMM(Constant Product Market Maker)라는 방법이었습니다. 이 방법은 지금도 널리 쓰이고 있지만, 가격이 급격하게 변하는 경우 유동성 공급자들이 피해를 입는 경우들이 많이 발생했습니다. 이를 비영구적 손실이라고도 부르죠. 이는 공급된 유동성이 전체 가격범위에 걸쳐 고르게 분배되기 때문에 발생하는 이슈입니다.

image.png

이를 극복하기 위해 유저들이 가격 범위를 정하여 집중적으로 유동성을 공급하는 새로운 방법이 제시됩니다. 이를 집중 유동성 공급, 영어로는 CLMM(Concentrated Liquidity Market Maker)라고 부릅니다. 이 페이지에서는 CLMM이 구체적으로 어떻게 동작하는지에 대한 여러 수학적 원리와, 샘플 코드를 통해 공부해보려고 합니다. 코드는 아래 레포지토리를 참고하세요.

https://github.com/boohyunsik/dive-into-CLMM

예제 코드는 타입스크립트로 작성됐습니다. 따라서 실행하기 위해서 nodejs typesript ts-node 등을 설치해두면 좋습니다.

가격 P

CLMM에서 주로 다루는 변수는 유동성 $L$과, 가격 $P$가 있습니다. 여기서 먼저 잘 따져봐야 하는 변수는 바로 가격인데, 우리가 생각하는 것 처럼 BTC=90000불 처럼 계산되는 것이 아니라 풀에 존재하는 토큰의 상대적인 비율로 계산합니다.

즉 예를 들어 SOL/USDC 풀이 있다고 가정하고, 풀에 SOL=1000개, USDC=10000개가 있다고 가정해봅시다. 여기서 우리는 두 가지 가격을 유도할 수 있는데, 바로 USDC에 상대적인 SOL의 가격과, SOL에 상대적인 USDC의 가격입니다. 각 가격을 구하는 방법은 간단하게 두 토큰의 개수를 나누면 됩니다.

$$ Price(SOL) = Token(USDC) / Token(SOL) $$

USDC에 상대적인 SOL의 가격은 위의 식과 같겠죠. USDC가 10000개 있고, SOL이 1000개 있으니까 SOL의 가격은 10이 됩니다.

$$ Price(USDC) = Token(SOL)/Token(USDC) $$

SOL에 상대적인 USDC의 가격은 위와 같을 것입니다. 마찬가지로 적용해보면, USDC의 가격은 0.1이 됩니다. 보통 새로운 풀을 만들때 토큰 $x$와 $y$를 지정하여 넣기 때문에, 하나만 사용하고 여기서도 SOL의 가격(첫 번째 예시)을 주로 사용하도록 하겠습니다. 정리해보면 가격 $P$(y에 상대적인 x의 가격)은 다음과 같이 정의할 수 있습니다.

$$ P = \frac{y}{x} $$

대부분의 CPMM 컨트랙트에서는 P를 직접 저장하지 않고 제곱근 $\sqrt{P}$ 로 활용하는 것을 볼 수 있습니다. 왜 제곱근을 저장하는 것일까요? CPMM의 여러 로직들에서(가격 계산, 유동성 계산 등) 제곱근이 많이 활용되기 때문입니다. 예를 들어, 아래에서 설명한 유동성 $L$을 계산할 때도 제곱근이 활용됩니다.

유동성 L

유동성 $L$은 두 토큰의 수량의 곱의 제곱근, 즉 $\sqrt{xy}$ 로 계산합니다. 즉 유동성 $L$은 토큰 $x$와 $y$의 기하평균이라고 이해하면 됩니다.

$$ L = \sqrt{xy}

$$

또한 유동성 풀에서 하나의 토큰의 증가하면 다른 한쪽의 토큰은 감소하므로, $L$는 상수라고 생각합니다. 여기서 우리는 위에서 살짝 언급했던, 가격의 제곱근을 저장하는 이유를 찾을 수 있습니다. $P = y/x$ 이고, 이를 유동성 공식에 대입해보면 다음과 같은 결과를 얻을 수 있습니다.