Solidity代币合约transferFrom()授权后无法转账问题求助
ERC20 transferFrom 无法正常工作的问题排查与修复
核心问题分析
1. transferFrom未验证授权额度
你的transferFrom函数在执行转账前未检查花费者(msg.sender)是否拥有足够的授权额度。根据ERC20标准,必须确保_allowance[pFrom][msg.sender] >= pToken,否则无权从pFrom地址转出代币。
2. _transfer函数余额扣减逻辑错误
_transfer函数中错误地扣减了msg.sender的余额,而非实际转出代币的pFrom地址余额。调用transferFrom时,msg.sender是获得授权的花费者,代币实际从pFrom地址转出,因此应操作_balance[pFrom]。
3. Transfer事件参数不符合ERC20标准
emit Transfer时使用msg.sender作为转出方参数,而非实际转出代币的pFrom地址,导致事件日志记录错误,违反ERC20规范。
修正后的代码片段
修正transferFrom函数
function transferFrom(address pFrom, address pRecipient, uint256 pToken) external returns (bool) { // 新增:检查授权额度是否充足 require(_allowance[pFrom][msg.sender] >= pToken, "Insufficient allowance"); _transfer(pFrom, pRecipient, pToken); _approve(pFrom, msg.sender, _allowance[pFrom][msg.sender] - pToken); return true; }
修正_transfer函数关键逻辑
function _transfer(address pFrom, address pTo, uint256 pToken) private { require(pFrom != address(0)); require(pTo != address(0)); require(pToken > 0); require(pToken <= _balance[pFrom]); uint256 fee = 0; if(_balance[address(this)] >= THRESHOLD) { _liquidate(); } if(!_isExcluded[pFrom] && !_isExcluded[pTo]) { if(_isRouter[pFrom]) { fee = _calculateBuyTax(pToken);//Tax on buys _balance[address(this)] += fee; } else if(_isRouter[pTo]) { fee = _calculateSellTax(pToken);//Tax on sells _balance[address(this)] += fee; } } // 修正:扣减实际转出地址pFrom的余额 _balance[pFrom] -= pToken; _balance[pTo] += (pToken - fee); // 修正:事件参数使用pFrom作为转出方 emit Transfer(pFrom, pTo, pToken - fee); }
内容的提问来源于stack exchange,提问作者Duplicited
相关产品推荐
相关产品推荐

