Protocol Fee:UniswapV2有一个开关可以控制是否在0.3%的交易手续费中再分1/6也就是总手续费的0.05%给开发团队,为了避免影响交易手续费,这个费用只有在增加/减小流动性时才会做相应计算 = address(0), 'UniswapV2: ZERO_ADDRESS'); require(getPair[token0][token1] == address(0), 'UniswapV2 = tokenB, 'UniswapV2: IDENTICAL_ADDRESSES'); (address token0, address token1) = tokenA < tokenB ? = address(0), 'UniswapV2: ZERO_ADDRESS'); require(getPair[token0][token1] == address(0), 'UniswapV2 交易对的代币数量的下限值,注入UniswapV2交易对的ETH数量的下限值,接收UniswapV2交易对流动性的地址,最晚交易期限,函数没有返回值,在该函数的开头首先会调用factoryV1的getExchange
这时候就需要考虑其它价格预言机了,而 UniswapV2 和 UniswapV3 都是不错的选择。 本篇先来聊聊如何使用 UniswapV2 作为价格预言机。 UniswapV2 价格预言机 UniswapV2 使用的价格预言机称为 TWAP(Time-Weighted Average Price),即时间加权平均价格。 但使用 UniswapV2 的 TWAP,其主要缺陷就是需要链下程序定时触发 update() 函数,存在维护成本。
the most recent liquidity event uint private unlocked=1; modifier lock(){ require(unlocked==1,'UniswapV2 uint112 _reserve0,uint112 _reserve1)private{ require(balance0<=uint112(-1)&&balance1<=uint112(-1),'UniswapV2 uint amount1Out,address to,bytes calldata data)external lock{ require(amount0Out>0||amount1Out>0,'UniswapV2 =_token1,'UniswapV2:INVALID_TO'); if(amount0Out>0)_safeTransfer(_token0,to,amount0Out);//optimistically balance1-(_reserve1-amount1Out):0; require(amount0In>0||amount1In>0,'UniswapV2:INSUFFICIENT_INPUT_AMOUNT
amount1Out, address to, bytes calldata data) external lock { require(amount0Out > 0 || amount1Out > 0, 'UniswapV2 reserve1,) = getReserves(); // 获取当前储备 require(amount0Out < _reserve0 && amount1Out < _reserve1, 'UniswapV2 = _token1, 'UniswapV2: INVALID_TO'); if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'UniswapV2 : require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'UniswapV2
UniswapV3 于 2021 年 5 月上线,相比 UniswapV2,改动很大,也变得复杂很多,最主要的有以下这几点改动: 引入了集中流动性(Concentrated Liquidity)机制 LP UniswapV2 添加流动性时,两个代币的价值是相等的。直到你移除流动性时,两个代币的价值依然也是相等的。 UniswapV2 中,每个交易对有且仅有一个流动性池,且交易手续费率都是统一的千分之三。 UniswapV2 中,还有一个协议手续费,和交易手续费一样,也是一个基于全局的费率,如若打开收取协议手续费的话,则可获得交易手续费的 1/6。 价格预言机也做了升级,之前讲区块链预言机章节中已经介绍过 UniswapV2 和 UniswapV3 的预言机。
修改SDK 打开文件: uniswapv2/v2-sdk-a88048e9c4198a5bdaea00883ca00c8c8e582605/src/constants.ts, 修改: export const 然后修改文件: uniswapv2/v2-sdk-a88048e9c4198a5bdaea00883ca00c8c8e582605/src/entities/token.ts [ChainId.RINKEBY 接下来修改文件: uniswapv2/v2-sdk-a88048e9c4198a5bdaea00883ca00c8c8e582605/package.json 将name和version修改为你自己的即可 修改前端代码 修改文件: uniswapv2/interface-f33bba217603765939478a64bb0b672da63eccbc/src/constants/index.ts 将路由合约修改为我们刚刚部署的路由合约的合约地址 需要安装:gh-pages npm i gh-pages 然后修改文件: uniswapv2/interface-f33bba217603765939478a64bb0b672da63eccbc/package.json
前言 前面两篇文章分别讲解了 Chainlink 和 UniswapV2 的 TWAP。 UniswapV2 的 TWAP 则是链上预言机,可适用于获取 Uniswap 上已有的任何 token 价格,主要缺陷就是需要链下程序定时触发更新价格,存在维护成本。 UniswapV3 UniswapV3 的实现机制和 UniswapV2 有很大不同,在计算 TWAP 的数据源方面,UniswapV2 只存储了最新的 price0CumulativeLast、price1CumulativeLast 需要注意的是,在 UniswapV2 中,存储的是价格累计值 priceCumulative,而 UniswapV3 并不直接计算价格累计值,而是计算 tick 累计值。 寻找最优的价格源 我们知道,在 UniswapV2 中,每个币对就组成了一个池子,即指定的 token0 和 token1 有且仅有一个 Pool。
源码结构 SushiSwap协议源码结构如下,在后面的源码分析阶段我们主要对时间锁定合约和SushiSwap文件内容进行分析,UniswapV2协议部分不再深入,如需了解可参考之前的UniswapV2协议分析文章 /uniswapv2/interfaces/IUniswapV2Pair.sol"; import ". /uniswapv2/interfaces/IUniswapV2Pair.sol"; import ". /uniswapv2/interfaces/IUniswapV2Pair.sol"; import ". 解决方案:合理设置owner的权限 文末小结 SushiSwap是在UniswapV2协议的基础上进行了拓展,因为其紧急奖励模型更加偏向于用户利益,所以它相较与UniswapV2更容易吸引更多用户参与质押来提供流动性
如果 Arbitrum Testnet 上还缺少什么东西的话,比如没有 UniswapV2 或者 SushiSwap,那可以自己部署一套 UniswapV2 或 SushiSwap 的合约上去。 其中包括 Uniswap TWAP 价格预言机,包括 UniswapV2 的,也包括 UniswapV3 的。 reserve0, uint112 _reserve1) private { require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'UniswapV2
uint deadline, uint8 v, bytes32 r, bytes32 s) external { require(deadline >= block.timestamp, 'UniswapV2 = address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE'); _approve(owner, spender 上签名的时候应该注意, 不要随便签署没有公开源码的合约, 避免被钓鱼. eip-2612 相关参考链接: "5 Tips & Tricks for DeFi Developers from the UniswapV2 : string } = { [ChainId.MAINNET]: 'https://api.thegraph.com/subgraphs/name/ianlapham/uniswapv2'
开源项目 整个 UniswapV2 产品拆分出了多个小型的开源项目,主要包括: uniswap-interface uniswap-v2-sdk uniswap-sdk-core uniswap-info 最后三个则是合约项目了,uniswap-v2-core 就是核心合约的实现; uniswap-v2-periphery 则提供了和 UniswapV2 进行交互的外围合约,主要就是路由合约;uniswap-lib p=1 将UniswapV2部署到所有区块链--去中心化交易所Uniswap多链部署教学视频:https://www.bilibili.com/video/BV1ph411e7bT? function initialize(address _token0, address _token1) external { require(msg.sender == factory, 'UniswapV2
每个交易对的底层实现,是和 UniswapV2 类似的恒定乘积做市商模式。 LP 提供流动性之后,和 UniswapV2 一样也会得到代表其份额的 LP Token。 Staker 可将 UniswapV2 或 SushiSwap 等外部 DEX 的 APEX-WETH 交易对的 LPToken 质押到 LPTokenPool 赚取 APEX 代币,赚取到的 APEX
但从 UniswapV2 开始,支持任意 ERC20 代币配对,但由于实施的复杂性,以及在 WETH 和 ETH 配对之间的流动性碎片化的担忧,底层池子统一只支持 ERC20 代币,只在上层合约里实现 引入了 Hooks 机制之后,像 UniswapV2 和 UniswapV3 内嵌的价格预言机也变得不再必要了,因此,在 PoolManager 中再见不到价格预言机相关的数据存储和逻辑处理了。
不过功能还比较简单,只聚合了 UniswapV2 和 SushiSwap,且只实现了从这两个平台中找出最优成交价来实现每笔交易。 技术调研 既然接入的是 UniswapV2 和 SushiSwap,而且是从合约层面去接入的,所以第一步就是先要调研如何接入。 UniswapV2 的合约分为了两个项目: uniswap-v2-core uniswap-v2-periphery uniswap-v2-core 的核心有三个合约: UniswapV2ERC20:UNI-V2
require(amount0In > 0 || amount1In > 0, 'UniswapV2: INSUFFICIENT_INPUT_AMOUNT');
将 SimplePair 中的 mint / burn 做得更严谨:LPToken 的 transferFrom/mint/burn 按 UniswapV2 的逻辑实现(包括 MINIMUM_LIQUIDITY
前言 上篇我们主要讲了 UniswapV2 整体分为了哪些项目,并重点讲解了 uniswap-v2-core 的核心代码实现;中篇主要对 uniswap-v2-periphery 的路由合约实现进行了剖析 在 uniswap-v2-periphery 项目中,examples 目录下有个 ExampleFlashSwap.sol,就是实现闪电兑换的一个示例,实现的是在 UniswapV1 和 UniswapV2 总结 至此,所有 UniswapV2 的合约项目就都讲解完了。
Dapp链接:https://www.chainpip.com/dapp-view/6724部署UniswapV2前需要准备的智能合约项目:uniswap-v2-core: 核心合约uniswap-v2
require(amountOut >= params.amountOutMinimum, 'Too little received'); } 其中,需要跨多个池子的路径编码方式如下图: 和 UniswapV2 寻找最优路径的算法也是和 UniswapV2 一样的思路。
我们知道,在 UniswapV2 中,在智能合约层面,价格精度其实可以达到 18 位小数,交易精度是可以非常小的。