유니스왑(Uniswap)은 현재와 같은 모습의 탈중앙화 거래소의 시초이자 현재도 탈중앙화 거래소 대표주자 중 하나이다. 유니스왑이 등장하기 전, 기존의 DEX시스템은 문제점이 많아 이용자가 적었다. 기존의 DEX시스템은 거래를 할 때마다 블록체인을 이용했는데, 트랜잭션의 완결성을 기다리는데에는 상당한 시간이 소요된다. 또한 매 트랜잭션 발생마다 수수료가 발생함으로써, 거래를 할 때마다 들어가는 시간과 비용이 중앙화 거래소에 비해 매우 컸다. 게다가 신생 DEX는 이용자가 적어 호가창이 비어있는 경우가 다반사였다. 때문에 유동성을 공급해주는 마켓메이커(Market Maker)가 필요했다.
문제가 많던 기존의 DEX시스템의 대안으로 유니스왑이 혜성같이 등장했다. 유니스왑은 자동으로 Market Price를 만드는 AMM(Auto Market Maker)를 활용했고, 여기에 CPMM 알고리즘을 사용했다. 유니스왑은 AMM을 통해 호가창 없이 시장이 원하는 가격대를 자동으로 형성했다. 또한 유동성을 공급해주는 사용자들에게 거래 수수료를 보상으로 분배했다.
유니스왑은 두 가지 토큰 쌍의 유동성 풀을 만들어, 거기에 토큰을 쌓아두고 사람들이 두 토큰을 거래할 수 있도록 한다. 유동성 풀에 토큰을 쌓아두는 사람을 유동성 공급자라고 하며, 유동성 풀에서 토큰을 교환하는 사람을 거래자라고 한다.
유동성 공급자(Liquidity Provider; LP): 유동성 풀(토큰 페어)에 유동성(토큰)을 공급해 유니스왑 생태계에 기여하는 사람. 공급자가 풀에 유동성을 공급하면, 유동성 공급의 증표로 LP토큰을 받으며, 나중에 이 LP토큰을 돌려주면 공급한 토큰들을 돌려받을 수 있다.
거래자(Trader): 스왑 서비스를 이용하는 고객. 스왑할 때마다 0.3%의 거래수수료를 부담한다.
유니스왑은 크게 Pair와 Factory 두 가지의 컨트랙트로 동작한다.
페어 컨트랙트는 토큰A와 토큰B 두 가지 토큰의 유동성이 공급되어있는 유동성 풀이다. 유동성 공급자는 페어 컨트랙트에 일정 비율과 수량의 토큰A와 토큰B 페어를 예치함으로써 LP토큰을 받을 수 있고, 이 두 토큰의 비율은 컨트랙트 내의 CPMM 알고리즘에 의해 계산된다.
팩토리 컨트랙트는 페어 컨트랙트를 조회하고 생성할 수 있다. 유동성 공급자가 어떤 토큰 페어를 예치하려 할 때 그 토큰 페어의 컨트랙트가 이미 존재하는지를 조회해서, 이미 존재한다면 그 페어 컨트랙트에 예치하도록 하고, 존재하지 않는다면 해당 토큰 페어의 새로운 컨트랙트를 생성한다.
CPMM(Constant Product Market Maker): CPMM, 즉 상수 곱 마켓메이커는 말 그대로 두 변수 와 의 곱을 상수 k로 일정하게 유지함으로써 와 의 교환비율을 결정하는 알고리즘이다. 토큰X와 토큰Y의 페어를 교환하는 유동성 풀을 고려할때, 변수 는 풀에 예치된 토큰X의 수량, 변수 는 풀에 예치된 토큰Y의 수량이며, 이 두 토큰의 수량의 곱 가 상수 k로 일정해야 한다.
거래자가 자신의 토큰X를 토큰Y로 교환받으려고 할때를 생각해보자. 교환을 하려는 토큰X-토큰Y 페어에 예치된 두 토큰의 수량은 현재 각각 개이고 둘의 곱은 이다. 거래자가 자신의 토큰X 개를 토큰Y로 교환받기 위해 풀에 토큰X 개를 공급한다. 그러면 풀의 토큰X 수량은 개로 증가하게 된다. 이때 토큰X와 토큰Y 수량의 곱이 가 되면 상수 가 유지되지 않으므로, 상수 k를 유지시킬만큼 토큰Y 수량을 감소시켜야 한다. 따라서 k값을 유지시키기 위해 식 를 만족하는 토큰Y의 수량인 만큼을 풀에서 빼서 거래자에게 주어서 k값을 유지시킨다. 결국 거래자는 토큰X 개를 주고 토큰Y 개를 교환받은 것이다.
위의 교환식을 에 대해 정리하면 가 되며, 이는 현재 토큰X-토큰Y 풀에 예치된 토큰 수량이 각각 개 일때, 거래자가 토큰X 개를 토큰Y 개로 교환받을 수 있다는 얘기가 된다. 이는 토큰X의 토큰Y로 표시한 가격을 의미한다. 스왑 후에는 의 비율이 k값을 유지하며 로 변하게 된다.
현재 거래소의 토큰A-토큰B 풀에 예치된 토큰A와 토큰B의 수량이 각각 개일때, 즉 거래소에서 표시되는 두 토큰의 교환비율이 일때 거래자가 스왑을 하면 실제로는 의 비율로 교환을 받게되며, 거래소에 표시되는 두 토큰의 교환비율은 로 갱신된다. 이때 거래자는 처음 원했던 교환비율 와 다른 비율로 교환을 받게됨으로써, 교환하려던 비율과 실제 교환받은 비율의 차이인 슬리피지가 발생하게 된다. 즉, 거래자는 토큰A 1개당 토큰B 개를 교환받을 것을 기대했으나, 실제로는 토큰A 1개당 토큰B 개를 교환받게 되는 것이다. 이 슬리피지를 계산하면 이므로, 거래자는 스왑시 토큰A 1개당 토큰B 개를 의도치 않게 손해보는 셈이 된다.
이 슬리피지를 줄이려면 교환하려는 물량 자체를 줄이거나, 유동성 와 의 크기를 키워야 한다. 따라서 거래자들의 슬리피지를 줄이기 위해서는 DEX가 많은 유동성을 확보해야 한다. 또한 유동성 와 의 크기가 커지면, 거래소의 스왑 전후 교환비율의 차이도 줄어들기 때문에 거래에 따른 급격한 가격변동을 막을 수 있다.
스왑시와 달리, 유동성 공급자가 토큰 페어를 예치하려 할 때에는 k값이 변수가 되어 재설정된다. 즉, 현재 토큰A-토큰B 페어의 수량 상태가 일때, 공급자가 토큰A 개와 토큰B 개의 페어를(단, ) 예치를 하면 가 되어 k값이 증가하게 된다(c는 양수). 이때 현재 거래소 풀의 두 토큰의 수량 비율과 동일한 비율의 수량을 예치했기 때문에 예치한 후에도 이 비율은 변하지 않는다. 즉, 유동성을 공급할 때는 의 비율이 상수가 되고, k가 변수가 된다.
그림을 예시로 하면, 현재 거래소 이더리움-오미세고 풀의 이더리움 수량 는 10이고, 오미세고 수량 는 500이며, 따라서 k값은 5000이다. 거래자는 의 교환비율을 생각하고 이더리움 1개를 교환했다. 거래자는 오미세고 50개를 받을 것을 예상했으나, 실제로는 이므로, 오미세고 500/11개, 약 45.45개를 받게 되었다. 슬리피지는 이므로 약 4.55개가 된다.
유니스왑v1은 이더리움을 기축통화로 사용한다. 즉, 모든 페어가 이더리움-ERC20이며, ERC20-ERC20 페어는 지원하지 않는다. ERC20과 ERC20을 교환하려는 거래자는 이더리움을 매개로 이중으로 교환을 함으로써 수수료를 이중으로 부담해야 했다. 유동성 공급자는 풀에 반드시 이더리움을 함께 공급해야함으로써 원치않는 이더리움 가격 하락의 리스크를 부담해야 했다. 이 리스크를 비영구적 손실(Impermanent Loss)이라고 한다.
유니스왑에서 스왑 수수료는 거래금액의 0.3%이다. 유니스왑v1에서는 스왑이 일어날 때마다 이 수수료를 모두 해당 유동성 공급자들에게 LP토큰의 비율에 비례하게 분배한다.
유니스왑v2에서는 더이상 이더리움을 기축통화로 사용하지 않고, 오직 ERC20-ERC20 페어로만 교환이 가능하게 했다. 이더리움은 ERC20기반의 랩트토큰인 wETH로 교환할 수 있다.
유니스왑v2에서는 거래수수료 0.3%에서 일부인 0.05%를 걷어 다른 용도로 사용을 하고, 남은 0.25%만 LP토큰 보유자들에게 분배한다.
UNI토큰