UniSwap-V2合约的数据解析入门

  • jusonalien
  • 更新于 2022-04-27 21:06
  • 阅读 4338

前阵子在兴趣驱使之下研究DeFi上的套利搬砖机器人的原理,过程有点坎坷,很多东西都只能靠自己去摸索踩坑出来,这篇文章用来记录一下关于链上智能合约数据的解析过程

前阵子在兴趣驱使之下研究DeFi上的套利搬砖机器人的原理,过程有点坎坷,很多东西都只能靠自己去摸索踩坑出来,这篇文章用来记录一下关于链上智能合约数据的解析过程

我的目标是想看同一个链上UniSwap-V2模型的不同的Dex之前共同的交易对之间的价格差异,如果之间差异大于我的期望值,那就说明存在可套利的空间

那么我需要做的是就是要不断的及时轮询共同交易对的状态数据,以此获取准确的价格差

可以看看UniSwap-V2官方提供的sol级别的interface

我们知道,在创建一个LP的时候,是由IUniswapV2Factory这个工厂合约来完成的,可以看看对应的interface,找找官方文档可以搜到很多有用的功能函数,比如

  • allPairsLength 返回所有LP的数目
  • allPairs 通过数组下标返回对应LP的地址

通过这两个函数我们可以先获取所有的LP数目,然后依次通过数组下表即可获取所有LP的地址

接下来,我们通过LP的地址再去剖析每个LP内的数据,对于LP的数据结构,可以直接看UniSwap-V2的UniswapV2Pair合约代码

address public factory; // LP地址
address public token0; // token0的合约地址
address public token1; // token1的合约地址

其中,factory是由 token0,token1经过特定的哈希算法后得出来的,阅读上述代码,可以找到一个关键的函数

function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) {
    _reserve0 = reserve0;
    _reserve1 = reserve1;
    _blockTimestampLast = blockTimestampLast;
}

该函数可以返回token0和token1的对应的数量,通过K=X*YK**=X**Y的模型我们就能推断出对应的价格,在计算价格的时候也要注意手续费等相关的问题,这点建议直接套用官方的计算价格的函数,放到你的业务合约代码中即可

//这里有两种计价模型,

// given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
// 你有amountIn个token-x 计算出能兑换amountOut个token-y
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;
}

//given an output amount of an asset and pair reserves, returns a required input amount of the other asset
// 你要兑换amountOut个token-y,计算出需要多少个token-x
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) {
    require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT');
    require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
    uint numerator = reserveIn.mul(amountOut).mul(1000);
    uint denominator = reserveOut.sub(amountOut).mul(997);
    amountIn = (numerator / denominator).add(1);
}

总结

要解析链上的智能合约的数据并加以使用,首先要对合约的架构,代码比较熟悉,充分了解合约的数据结构后再去设计对应的数据获取解析方案

点赞 2
收藏 3
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
jusonalien
jusonalien
0x3730...4a7a
在找Solidity开发岗 个人博客: https://jusonalien.github.io/