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

BSC测试网ERC20互换授权异常:调用deposit后未收到对应RAHI代币

问题核心原因

  • 授权逻辑完全错误:你在deposit函数内调用BUSD.approve(address(this), _amount)属于无效操作。ERC20的approve方法是代币持有者主动调用,授予第三方操作自己代币的权限,你在合约代码中调用该方法时,发起方是合约地址,相当于合约给自己授权操作合约本身的BUSD,和用户持有的BUSD没有任何关系,自然不会触发Metamask的授权弹窗。正确操作是用户在调用deposit方法前,需要先在钱包侧手动调用fakeBUSD合约的approve方法,传入你的合约地址和要存入的BUSD额度,完成授权后再调用deposit。
  • 额度未做校验:你调用BUSD.allowance(msg.sender, address(this))仅做了查询操作,没有对返回的授权额度做判断,哪怕用户实际授权额度小于要存入的_amount,代码还是会继续执行后续的safeTransferFrom,必然会调用失败。
  • RAHI转账逻辑冗余错误:合约自身持有RAHI代币的前提下,不需要走approve+transferFrom的流程,直接调用RAHI.safeTransfer(msg.sender, payout)即可完成转账,你现有的逻辑是合约给自己授权允许用户转走RAHI,完全没必要还容易触发不必要的错误。
  • 兑换计算逻辑存疑:注释标注1个RAHI兑换2BUSD,按两个代币均为18位小数的常规设计,payout = _amount.mul(1e18).div(price)即可得到对应RAHI数量,你额外多除以1e9的操作如果不是对应RAHI为9位小数的特殊设计,会导致你实际收到的RAHI数量仅为预期的十亿分之一。

修复后的deposit函数参考代码

function deposit(uint256 _amount) external checkIfPaused {
    require(started, 'Sale has not started');
    require(!ended, 'Sale has ended');
    // 校验用户给合约的BUSD授权额度足够
    require(BUSD.allowance(msg.sender, address(this)) >= _amount, "Insufficient BUSD allowance");
    // 计算兑换数量,如果你确认RAHI是9位小数可以保留div(1e9),否则删掉该行
    uint256 payout = _amount.mul(1e18).div(price).div(1e9); 
    // 直接转用户的BUSD到合约,不需要在合约内重复做approve
    BUSD.safeTransferFrom(msg.sender, address(this), _amount);
    // 直接从合约转RAHI给用户,不需要approve+transferFrom组合操作
    RAHI.safeTransfer(msg.sender, payout);
    emit Deposit(msg.sender, _amount);
}

操作步骤调整

  1. 部署修复后的合约,给合约转入足够的RAHI代币
  2. 调用start方法开启兑换
  3. 用户侧操作:先调用fakeBUSD的approve方法,授权你的合约地址对应数量的BUSD,Metamask会弹出授权确认窗口,授权完成后再调用合约的deposit方法传入对应数量即可完成兑换

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 12:27:04