ERC20预售合约transferTokensToPresale函数测试无报错但未生效
问题原因分析与解决方案
核心原因1:合约未同步更新内部预售代币计数变量
你的transferTokensToPresale函数仅完成了代币从owner到预售合约的转账操作,但没有更新预售合约内部跟踪可用预售代币的状态变量(比如_presaleAvailableTokens这类自定义变量)。而tokensAvailable()函数大概率是返回这个内部变量的值,而非直接查询合约的ERC20代币余额。
举个例子,如果tokensAvailable的实现是这样的:
function tokensAvailable() public view returns(uint256) { return _presaleAvailableTokens; }
但你的转账函数里没有执行_presaleAvailableTokens += presaleSupplyAmount_;,那这个变量的值永远不会变化,调用前后自然一致。
核心原因2:tokensAvailable函数实现逻辑错误
检查tokensAvailable()函数是否正确返回了预售合约的代币余额。如果它的实现不是查询token.balanceOf(address(this)),而是依赖未被更新的内部变量,就会出现这个问题。
正确的实现应该是直接查询合约的代币余额:
function tokensAvailable() public view returns(uint256) { return token.balanceOf(address(this)); }
或者在转账函数里同步更新内部计数变量:
function transferTokensToPresale(uint256 presaleSupplyAmount_) public onlyOwner returns (bool) { // 原有的require检查逻辑 require(presaleSupplyAmount_ > 0, "Amount must be greater than zero"); require(token.balanceOf(msg.sender) >= presaleSupplyAmount_, "Insufficient balance"); require(block.timestamp < startTime, "Presale has already started"); SafeERC20.safeTransferFrom(token, msg.sender, address(this), presaleSupplyAmount_); // 新增:更新内部可用代币计数 _presaleAvailableTokens += presaleSupplyAmount_; return true; }
其他排查点
确认owner完成代币授权
确保在测试脚本中,owner已经给预售合约授权了足够的代币额度:// 测试脚本添加授权步骤 await token.connect(owner).approve(presale.address, presaleSupply);因为
safeTransferFrom要求转账发起方(owner)先授权合约转移对应数量的代币,若未授权交易本应revert,但如果你的ERC20是非标准实现,可能出现无报错但转账未生效的情况。修正测试脚本的日志文案
你的测试脚本两次输出的文案都是token amount before transferring...,第二次应该改为after,避免混淆判断。
内容的提问来源于stack exchange,提问作者Alen Schmitt
相关产品推荐
相关产品推荐

