uniswap

  • https://betterprogramming.pub/uniswap-v2-in-depth-98075c826254

  • https://docs.uniswap.org/protocol/V2/concepts/protocol-overview/ecosystem-participants

  • https://github.com/fengluo/uniswap-white-paper/blob/master/uniswap-white-paper.zh-CN.md

v1

  • 概要

    • protocol for automated token exchange

    • 目标

      • ease-of-use

      • gas efficiency

      • censorship resistance

      • zero rent extaction

    • 用途

      • it is useful for traders and functions particularily well as a component of other smart contracts with require guaranteed on-chain liquidity.

    • 机制

      • cex维护一个订单本(order book), 匹配其中的买方和卖方进行交易.

      • uniswap利用智能合约,hold住了一部分token(Reserves)作为池子, 交易双方直接交易这些已经hold住的流动性.

        • 价格机制

          • x*y=k做市商机制

            • keep overall reserves in relative equilibrium

        • 流动性池(Reserves)

          • 通过一个网络系统,使liquidity providers可以提供token放到流动性池中,来分享交易费用.

            • 流动性挖矿?

      • 合约

        • uniswap的一个重要特性是,通过利用一个factory/registry合约, 为每个ERC20token提供一个独立的交易合约.

          • 这些合约hold住一组ETH和相关的ERC20token.

          • 这些合约通过registry被连接.

            • ERC20token和ERC20token以ETH作为媒介可以直接做交易.

Creating Exchanges

uniswap_factory.vy

exchangeTemplate: public(address)
token_to_exchange: address[address] # registry erc20 => exchange 
exchange_to_token: address[address] # registry exchange => erc20
    
@public
def __init__(template: address):
    self.exchangeTemplate = template

@public
def createExchange(token: address) -> address:
    assert self.token_to_exchange[token] == ZERO_ADDRESS
    new_exchange: address = create_with_code_of(self.exchangeTemplate)
    self.token_to_exchange[token] = new_exchange
    self.exchange_to_token[new_exchange] = token
    return new_exchange

@public
@constant
def getExchange(token: address) -> address:
    return self.token_to_exchange[token]

@public
@constant
def getToken(exchange: address) -> address:
    return self.exchange_to_token[exchange]

那么可以估计连上存储的合约有多少? N(token) + 1(create-exchange)

ETH <=> ERC20 Trades

eth_pool: uint256         
token_pool: uint256       
token: address(ERC20) 

@public
@payable
def ethToTokenSwap():
    fee: uint256 = msg.value / 500 
    invariant: uint256 = self.eth_pool * self.token_pool # 定价公式?
    new_eth_pool: uint256 = self.eth_pool + msg.value
    new_token_pool: uint256 = invariant / (new_eth_pool - fee)
    tokens_out: uint256 = self.token_pool - new_token_pool
    self.eth_pool = new_eth_pool
    self.token_pool = new_token_pool
    self.token.transfer(msg.sender, tokens_out)

@public
def tokenToEthSwap(tokens_in: uint256):
    fee: uint256 = tokens_in / 500
    invariant: uint256 = self.eth_pool * self.token_pool
    new_token_pool: uint256 = self.token_pool + tokens_in
    new_eth_pool: uint256 = self.invariant / (new_token_pool - fee)
    eth_out: uint256 = self.eth_pool - new_eth_pool
    self.eth_pool = new_eth_pool
    self.token_pool = new_token_pool
    self.token.transferFrom(msg.sender, self, tokens_out)
    send(msg.sender, eth_out)