测试部署UniswapV2Swap合约遇ds-math-sub-underflow报错求助
解决UniswapV2Swap合约测试中的
ds-math-sub-underflow报错 1. 修复异步操作的await缺失
你的测试代码中approveTx.wait()未添加await,会导致授权交易还未上链确认就执行后续swap操作,可能引发异常。修改如下:
const approveTx = await daiTokenIN.connect(signer).approve(uniswapV2.target, amountInMax); await approveTx.wait(); // 添加await确保授权完成
2. 验证测试环境的流动性与代币路径
swapMultiHopExactAmountOut依赖UniswapV2池的充足流动性完成多跳兑换:
- 确认合约内定义的兑换路径(DAI -> WETH -> USDC)对应的代币地址,在测试环境(如Hardhat本地链、Goerli测试网)中是正确的。
- 确保DAI/WETH、WETH/USDC交易对的UniswapV2池有足够流动性。本地测试时,需先部署UniswapV2工厂、路由合约,再手动添加流动性。
3. 检查amountOutDesired与amountInMax的合理性
- 若
amountOutDesired设置过大,超过当前流动性池能提供的最大输出量,Uniswap的getAmountsIn计算会出现异常,进而触发减法下溢。可先尝试将值调小(比如改为100而非1000)测试是否正常执行。 - 确认
amountInMax足够覆盖实际所需输入代币量,可通过UniswapV2路由预估所需DAI数量,再设置合理的最大值:
const path = [daiTokenIN.address, wethAddress, usdcTokenOut.address]; const amountsIn = await uniswapRouter.getAmountsIn(amountOutDesired, path); const estimatedAmountIn = amountsIn[0]; // 设置为预估量的1.1倍,留出缓冲空间 const amountInMax = estimatedAmountIn.mul(110).div(100);
4. 确认签名者的代币余额
确保测试用的signer账户持有足够DAI余额,否则即使授权成功,兑换时也会因余额不足引发连锁异常。测试前可添加余额检查:
const daiBalance = await daiTokenIN.balanceOf(await signer.getAddress()); console.log("Signer DAI balance:", ethers.formatUnits(daiBalance)); if (daiBalance.lt(amountInMax)) { throw new Error("Signer has insufficient DAI balance"); }
5. 排查合约内部的DS Math使用
若上述步骤无问题,需检查UniswapV2SwapExamples合约中swapMultiHopExactAmountOut函数的实现:
- 确认所有DS Math的减法操作(如
sub函数)都安全,保证被减数大于等于减数。比如计算余额变化时,先检查当前余额是否大于等于要扣除的数量。 - 确保调用UniswapV2路由的参数正确,尤其是
deadline若设置过小,可能导致交易过期引发异常。
内容的提问来源于stack exchange,提问作者Sukanto
相关产品推荐
相关产品推荐

