⛓️
Blockchain
  • Start!
  • Go_lang
    • Tutorial
    • 1. Banking
    • 2. Dictionary
    • 3. URL Checker
    • Useful Methods - Slice
    • Useful data structure
  • RUST
    • Start
    • Basic
    • Basic Programming Concepts
      • Variables and Mutability
  • Bitcoin
    • Start
    • Introduction
    • Transactions
  • GO-BITCOIN
    • Start
    • 1. Blocks & Blockchain
    • 2. Proof of work
    • 3. BadgerDB
    • 4. Transactions
    • 5. Wallet
    • 6. Adding Digital Signatures
  • COSMOS
    • 코스모스 SDK
    • 코스모스 SDK 실습 - nameservice
    • 코스모스 허브는 어떻게 사용하는가?
    • 코스모스 허브, 금융의 역사를 다시 쓰다
    • Tendermint
      • ABCI
      • Messages
  • Cosmos Tutorial
    • Tutorials
    • 1. Blog
    • Nameservice
    • [Starport] Escrow Account: Scavenge
    • [Starport] Inter-Blockchain Communication: Basics
    • Create an IBC Interchain Exchange module
      • Introduction
      • App Design
      • Initialize the Blockchain
      • Create the Order Book
  • Ethereum
    • Start
    • Gas
    • Oracle Problem
  • consensus
    • DPoS
    • PBFT
    • Network model
  • cryptosystem
    • 대칭키 암호
    • IPFS
  • Social token
    • Rally
    • DeSo
      • Bitclout
      • Deso: The Decentralized Social Network
      • Setting Up Your Dev Environment
      • Deso Code Walkthrough
      • Web3 Will Not Be Built on Smart Contracts
  • 재윤TV
    • Start
    • 유니스왑에 대해서 아라보자
      • Concept
      • V2 백서 분석
      • V2 코드 분석
Powered by GitBook
On this page
  • V1 pair
  • V2 pair
  • 거래 수수료 변경
  • Price oracle
  • 주소 변경
  • Initialization of liquidity token supply
  • 프로토콜 fee
  • Reference

Was this helpful?

  1. 재윤TV
  2. 유니스왑에 대해서 아라보자

V2 백서 분석

유니스왑 V2란?

유니스왑이 투자를 받고나서 2020년 5월에 새로 컨트랙트를 개발했다. 그렇게 배포한 것이 유니스왑 V2이다. 기존의 단점을 해결했다.

V1 pair

V1에서는 토큰 pair를 만들 때 ERC-20 토큰과 이더리움을 서로 pair로 만들어서 사용했다.

Token exchange contract 가 전부 ERC-20과 이더리움 pair로 이루어져 있었다. 이더리움을 bridge currency로 사용했다.

  • 어떤 사람이 두 스테이블 코인 DAI와 USDT를 pair로 만들고 싶은데 유니스왑에서는 반드시 이더리움을 bridge로 써야 한다.

  • DAI-ETH pair와 USDT-ETH pair를 만들어야 한다.

  • 이더리움을 무조건 들고 있어야 한다.

  • 이 사람은 스테이블 코인만을 pool로 제공하고 싶었는데 어쩔 수 없이 이더리움을 제공함으로 인해서 이더리움 가격이 떨어졌을 때 impermanent loss가 발생한다.

V2 pair

ERC-20 토큰과 ERC-20토큰을 가지고 pair를 만들 수 있게 변경했다.

  • DAI-USDT pair를 생성 가능

  • 이더리움을 보유하지 않아도 되기 때문에 impermanent loss가 방지된다.

하지만 ERC-20과 이더리움 간의 pair도 생성을 해줘야 한다.

그렇기 때문에 예외 케이스가 생기고 코드 양이 배로 늘어난다.

이를 막기 위해서 V2에서는 이더리움을 쓰지 않고 Wrapped ETH라고 하는 이더리움을 ERC-20 토큰 형태로 wrapping한 WETH를 사용한다.

V2에서는 무조건 ERC-20 표준을 가지는 두 토큰을 pair로 만들어서 사용한다.

→ 코드가 간단해지고 수수료가 적게 든다. (이 토큰이 이더리움인지 ERC-20인지 판단하는 로직이 사라지기 때문에)

거래 수수료 변경

V1에서는 거래 수수료 0.3%를 LP들이 가지고 있는 토큰의 지분만큼 분배해줬다.

V2에서는 0.25%만을 지급하고 0.05%는 프로토콜 fee로 따로 걷는다.

0.05%의 프로토콜 수수료는 유니스왑 토큰인 UNI 홀더들에게 제공된다.

Price oracle

유니스왑에서 거래되는 토큰의 교환비가 시중에서 거래되는 토큰의 교환비와 매우 유사하다, 거의 일치한다라는 논문이 발표가 되었다. 이 논문을 근거로 유니스왑에서 거래되는 토큰 비율을 가격 정보로 사용하는 로직을 V2에 넣어놨다.

유니스왑을 price oracle로 사용하게 되면 공격자가 나타날 수 있다. 다량의 토큰을 교환하거나 pool에 집어넣는다거나 해서 정보를 왜곡시킬 수 있다. 그러면 다른 컨트랙트들이 피해를 볼 수 있기 때문에 가격 정보를 그냥 반영하지 않고 과거부터 현재까지 쭉 이어지는 가격 변화들을 가격이 유지된 시간만큼 곱해서 가격을 결정한다. 이렇게 하면 가격이 급격하게 변동하지 않는다.

유니스왑에서 두 토큰의 교환 비율을 정할 때 정수로 딱 떨어지지 않는다. 그런데 Solidity는 소수를 표현할 수 있는 데이터 타입을 지원하지 않는다. 그래서 소수를 표현할 수 있는 새로운 데이터 타입을 정의해서 사용한다. 256-bit 자료형을 사용한다. 첫 112-bit는 정수형을 사용, 그 뒤 112-bit는 소수점 자리수를 위해 사용, 나머지 32-bit는 그 가격이 유지되는 시간을 표현하기 위해서 사용한다.

주소 변경

V2에서는 두 토큰 pair에 대한 주소를 변경할 수 있는 로직을 넣어놨다.

Initialization of liquidity token supply

  • S_minted : 새로 생성되는 LP 토큰

  • X_starting : X 토큰을 풀에 넣기 전의 수량

  • X_deposited : X 토큰을 풀에 넣은 수량

  • S_starting : X 토큰을 풀에 넣기 전에 원래 있던 LP 토큰의 양

새로 생성되는 LP 토큰의 양은 어떤 특정한 ERC-20 토큰의 (이 사람이 넣은 수량 / 전체 수량) 만큼 생성된다.

X-Y 간의 교환인데 왜 X만으로 계산하는가?

  • 두 토큰 중에 S_minted의 값이 더 작은 값이 되도록 하는 S_minted를 찾아서 생성을 해낸다.

  • X가 Y가 될 수도 있다.

토큰 pair를 처음 만들었을 경우 LP 토큰의 수량을 어떻게 결정하는가?

처음 생성할 경우 X_starting이 0이기 때문에 다른 공식을 따른다.

집어넣는 X, Y 토큰 수량의 곱의 루트 값이 새로 생기는 LP 토큰의 양이다. 기하평균값.

예시

ABC 토큰과 XYZ 토큰이 있다.

ABC-XYZ 교환 비율이 1:100이다.

initial deposit이 2ABC, 200XYZ 이다.

이때 depositor가 받는 LP 토큰의 양은 (2*200)^(1/2) = 20 이다.

처음 토큰 pair를 생성하는 사람은 그 LP 토큰을 온전히 갖지 못하고 수수료를 낸다.

그 수수료는 0번 주소로 전송되어서 영원히 묶이게 된다. (burn)

이렇게 하는 이유는 어떤 공격이 있을 수 있기 때문이다.

LP share는 최소 단위가 10^-18이다. 보통 ERC-20 토큰의 최소 단위랑 같다.

그런데 그 사람이 넣는 토큰 지분의 비중이 10^-18보다 작으면 LP share를 못 받는다. 이런 경우를 대비하기 위해 그 사람이 넣은 LP share의 10^-15만큼(10^-18의 1000배)의 LP token을 태워야 한다.

예를 들어 어떤 사람이 LP share하나의 가격을 100$로 맞추고 싶으면 그것의 1000배인 10만$에 해당하는 토큰이 없어진다.

그렇기 때문에 사람들이 초기에 돈을 넣을 때 너무 많이 집어넣지 않는다. 본인이 나중에 수수료를 받아서 얻을 수 있는 이득보다 태워지는 양이 더 많을 수 있기 때문이다.

프로토콜 fee

fee라는 것은 전체 LP 토큰 풀의 인플레이션에 비례해서 부과된다.

k : 두 토큰 수량의 곱

k_2 : 늘어난 LP 토큰의 양 (루트 X*Y)

k_1 : 늘어나기 전 LP 토큰의 양

사람들이 풀에 토큰을 더 많이 넣었다고 하면 k_2의 양이 k_1보다 크다.

이 인플레이션에서 프로토콜 fee로 0.05%를 가지고 간다.

이 수수료는 LP 토큰이 생성되거나 burn 될 때만 호출되어서 부과 된다.

s_1 : 기존에 있던 LP token 의 양

s_m : 프로토콜 fee로 가져가는 LP token의 양

ϕ : 수수료 비율

f_1,2 : 인플레이션 비율

이때 ϕ를 1/6로 잡았다.

위의 두 식을 합치면 다음 식을 유도할 수 있다.

ϕ에 1/6을 대입한 공식을 따라서 프로토콜이 정한 fee를 가져가는 사람에게 수여되는 LP 토큰의 양이 정해진다.

예시

100 DAI와 1 ETH가 존재하면 처음 LP token은 10개가 있다.

k_1 : 1* 100 = 100

s_1 : 10

이 상태에서 인플레이션이 돼서 96DAI와 1.5ETH가 됐다.

k_2 : 96 * 1.5

이 값들을 대입하면

s_m : 0.0286

0.0286 만큼을 프로토콜 fee로 가져간다.

Reference

PreviousConceptNextV2 코드 분석

Last updated 3 years ago

Was this helpful?

[UNISWAP SERIES] 1. 유니스왑 이해하기Medium
Logo