前阵子在兴趣驱使之下研究DeFi上的套利搬砖机器人的原理,过程有点坎坷,很多东西都只能靠自己去摸索踩坑出来,这篇文章用来记录一下关于链上智能合约数据的解析过程
前阵子在兴趣驱使之下研究DeFi上的套利搬砖机器人的原理,过程有点坎坷,很多东西都只能靠自己去摸索踩坑出来,这篇文章用来记录一下关于链上智能合约数据的解析过程
我的目标是想看同一个链上UniSwap-V2模型的不同的Dex之前共同的交易对之间的价格差异,如果之间差异大于我的期望值,那就说明存在可套利的空间
那么我需要做的是就是要不断的及时轮询共同交易对的状态数据,以此获取准确的价格差
可以看看UniSwap-V2官方提供的sol级别的interface
我们知道,在创建一个LP的时候,是由IUniswapV2Factory
这个工厂合约来完成的,可以看看对应的interface,找找官方文档可以搜到很多有用的功能函数,比如
通过这两个函数我们可以先获取所有的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);
}
要解析链上的智能合约的数据并加以使用,首先要对合约的架构,代码比较熟悉,充分了解合约的数据结构后再去设计对应的数据获取解析方案
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!