如何无需发送交易即可模拟真实Uniswap V2滑点,适配带转账税ERC20场景
Uniswap V2 带转账税代币滑点预执行模拟方案
为什么普通预执行不会触发滑点报错
普通eth_call调用swapExactETHForTokens方法时,仅会校验Router合约层面的逻辑:Router只会在把代币转出给用户前,检查自己持有待转出的代币数量是否≥你传入的minAmountOut。但带转账税的ERC20代币会在transfer执行时直接扣除税费,Router实际转入用户地址的金额已经是扣税后的数值,这个过程Router本身不会做二次校验,所以普通预执行不会回滚。
DEX的模拟实现逻辑
Uniswap、Pancake等DEX的滑点模拟是在eth_call的基础上额外增加了余额校验逻辑:预执行前先查询接收地址的目标代币余额,预执行结束后再次查询该地址的余额,对比两次余额的差值和用户设置的minAmountOut,如果差值小于阈值就主动抛出INSUFFICIENT_OUTPUT_AMOUNT报错。
依托Metamask的无交易模拟方案
不需要实际发送上链交易,在前端调用层做如下处理即可实现准确模拟:
- 第一步:调用目标
ERC20合约的balanceOf方法,查询你的接收地址在预执行前的代币余额,记为beforeBalance - 第二步:构造和实际交易完全一致的
swapExactETHForTokens参数(包括from地址、ETH数量、兑换路径、接收地址、交易截止时间等),通过eth_call发起预执行调用,不要实际签名发送交易 - 第三步:预执行调用完成后,再次调用
balanceOf查询同一个接收地址的目标代币余额,记为afterBalance - 第四步:计算实际到账金额
actualAmountOut = afterBalance - beforeBalance,将这个数值和你设置的minAmountOut对比,如果actualAmountOut < minAmountOut,就说明交易会因为滑点不足回滚,和DEX的模拟结果一致
如果你的节点支持debug_traceCall接口,也可以直接追踪交易执行过程中目标代币转给接收地址的转账数值,不需要两次查询余额,模拟效率更高。
注意:预执行时要使用最新的pending区块高度,参数要和实际发起交易的参数完全一致,避免出现模拟偏差
内容的提问来源于stack exchange,提问作者NStal
相关产品推荐
相关产品推荐

