前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >IDO代币预售合约系统开发技术详细

IDO代币预售合约系统开发技术详细

原创
作者头像
DD_MrsFu123
发布2022-08-02 20:41:35
6780
发布2022-08-02 20:41:35
举报
Uniswap代码结构

Uniswap智能合约代码由两个github项目组成。一个是core,一个是periphery。

core偏核心逻辑,单个swap的逻辑。periphery偏外围服务,一个个swap的基础上构建服务。单个swap,两种代币形成的交易对,俗称“池子”。每个交易对有一些基本属性:reserve0/reserve1以及total supply。reserve0/reserve1是交易对的两种代币的储存量。total supply是当前流动性代币的总量。每个交易对都对应一个流动性代币(LPT  - liquidity provider token)。简单的说,LPT记录了所有流动性提供者的贡献。所有流动性代币的总和就是total supply。Uniswap协议的思想是reserve0*reserve1的乘积不变。

Periphery逻辑

核心逻辑实现在UniswapV2Router02.sol中。称为Router,因为Periphery实现了“路由”,支持各个swap之间的连接。基本上实现了三个功能:1/ add liquidity(增加流动性)2/remove liqudity (抽取流动性) 3/ swap(交换)。

1. add liqudity  

增加流动性,就是同时提供两种代币。因为代币有可能是ETH,针对不同情况有不同的接口。逻辑类似。

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external virtual override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity)

add liqudity查看之前有没有创建相应的交易对。如果有相应的交易对,确定目前的兑换比例在希望的范围内(期望amountDesired和不低于amountMin)。如果兑换比例OK,将相应的代币转入对应的交易对池子,并调用其的mint函数。

2. remove liqudity  

提供流动性的相反的操作就是抽取流动性。也就是说,流动性提供者不再提供相应的流动性:

    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) public virtual override ensure(deadline) returns (uint amountA, uint amountB) {

liquidity是抽取的流动性的量。amountMin是抽取代币的最小的个数。to是抽取代币的目标地址。deadline是个有意思的设计:抽取的操作有时效性。超过了一定的deadline(区块高度),这次抽取操作看成无效。

先收回需要抽取的Token,并且销毁:

IUniswapV2Pair(pair).transferFrom(msg.sender, pair, liquidity); // send liquidity to pair
(uint amount0, uint amount1) = IUniswapV2Pair(pair).burn(to);
3. swap

swap是普通用户进行代币交易的操作。普通用户通过swap操作实现两种token之间的交易。

function swapExactTokensForTokens(
    uint amountIn,
    uint amountOutMin,
    address[] calldata path,
    address to,
    uint deadline
) external virtual override ensure(deadline) returns (uint[] memory amounts) {

Uniswap支持多种代币的交换。具体的含义是,Uniswap提供了多级交易池的路由功能。举个例子,已有两个交易对TokenA-TokenB,以及TokenB-TokenC,通过swap接口,可以实现TokenA-TokenC的交换,其中经过的TokenA-TokenB,TokenB-TokenC,称为路径(path)。amountIn是路径中的第一个代币的数量,amountOutMin是期望的交换后的最少的数量。

amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path);
require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT');

amounts是每个路径上的交换后的数量。amounts[amounts.length-1]也就是最后一条路径的输出数量。注意,UniswapV2Library.getAmountsOut的实现(在获取每个交易对的reserve信息后,调用getAmountOut函数):

    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) {
        require(amountIn > 0, 'UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT');
        require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
        uint amountInWithFee = amountIn.mul(997);
        uint numerator = amountInWithFee.mul(reserveOut);
        uint denominator = reserveIn.mul(1000).add(amountInWithFee);
        amountOut = numerator / denominator;
    }

注意,其中的997/1000的系数。在进入每个交易池之前,进入的金额先扣除了0.3%的本金。这个就是交易费。注意的是,路径上的交易池,每个池子都收。有点像高速收费站,一段段的收。

TransferHelper.safeTransferFrom(
    path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]
);

将代币path[0],转入到交易对,数量为amounts[0]。转入代币后,进行真正的swap操作:

    function _swap(uint[] memory amounts, address[] memory path, address _to) internal virtual {
        for (uint i; i < path.length - 1; i++) {
            (address input, address output) = (path[i], path[i + 1]);
            (address token0,) = UniswapV2Library.sortTokens(input, output);
            uint amountOut = amounts[i + 1];
            (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOut) : (amountOut, uint(0));
            address to = i < path.length - 2 ? UniswapV2Library.pairFor(factory, output, path[i + 2]) : _to;
            IUniswapV2Pair(UniswapV2Library.pairFor(factory, input, output)).swap(
                amount0Out, amount1Out, to, new bytes(0)
            );
        }
    }

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Uniswap代码结构
  • Periphery逻辑
    • 1. add liqudity  
      • 2. remove liqudity  
        • 3. swap
        相关产品与服务
        云数据库 MongoDB
        腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档