You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solidity合约deposit方法transferFrom执行失败 Hardhat测试报错如何解决

问题根因
  • 授权逻辑错误:你当前在合约内写的ERC20(token).approve(address(this), amount)属于无效操作。approve的作用是「调用方给目标地址授权可操作自己代币的额度」,这行代码的调用方是合约本身,相当于合约自己给自己授权了操作自身代币的额度,完全满足不了transferFrom(msg.sender, address(this), amount)的要求——后者需要的是调用deposit的用户(msg.sender)给合约地址授权可操作自己代币的额度。
  • 测试环节缺失授权步骤:当前你的JS测试代码中,owner账户从未给你的业务合约地址授权过WETH的转账额度,因此执行transferFrom时会因为授权额度不足直接触发回滚。
修复方案

1. 调整Solidity合约代码

删掉合约中无效的approve行,修正后的deposit函数如下:

function deposit(address token, uint256 amount) external onlyOwner {
    uint256 balance = ERC20(token).balanceOf(msg.sender);
    require(balance > amount, "not enough money to deposit");
    // 删掉原有的无效approve行,授权操作需要用户在链下主动发起
    ERC20(token).transferFrom(msg.sender, address(this), amount);
}

2. 调整Hardhat测试代码

在调用业务合约的deposit方法之前,新增owner给合约授权WETH额度的逻辑,修正后的测试代码如下:

let IWETH = await ethers.getContractAt(
    "IWETH",
    "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
);
await IWETH.deposit({
    value: ethers.utils.parseUnits("100.0", "ether"),
});
// 新增授权步骤:owner给业务合约授权2个WETH的额度
await IWETH.connect(owner).approve(contract.address, ethers.utils.parseUnits("2", "ether"));
await contract
    .connect(owner)
    .deposit(
        "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
        ethers.utils.parseUnits("2", "ether")
    );

内容的提问来源于stack exchange,提问作者Dadan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 02:15:03