Solidity ERC20 transferFrom 没有错误但不执行

问题描述

我有一个 solidity 代码,旨在将 BUSD 与 myToken(均为 ERC20)交换,该代码调用 BUSD.transferFrom() 和 myToken.transfer(),但尽管核心执行没有错误,但只有 myToken 被转移。 帐户已获批准并且有足够的余额。

你能指出错误吗?

bytes4 private constant SELECTOR_TRANSFER = bytes4(keccak256(bytes('transfer(address,uint256)')));
bytes4 private constant SELECTOR_TRANSFERFROM = bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));


  function _myTokenTransfer(uint256 amount) private {
      _safeTransfer(myToken_addr,_msgSender(),amount);
  }
  
  function _busdTransfer(uint256 amount) private {
      _safeTransferFrom(busd_addr,address(this),amount);
  }

  function _safeTransferFrom(address token,address from,address to,uint value) private {
      (bool success,bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR_TRANSFERFROM,from,to,value));
      require(success && (data.length == 0 || abi.decode(data,(bool))),'myTokenPrivateSale: TRANSFERFROM_Failed');
  }
  

  function _safeTransfer(address token,bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR_TRANSFER,'myTokenPrivateSale: TRANSFER_Failed');
  }
  
}

解决方法

您的 busd_addr 未设置(即 0x0)。

_safeTransferFrom() 函数被执行时,它会向 0x0 地址发送一个内部交易。交易不会恢复(没有会在 0x0 地址上引发异常的合约)并且不会返回任何数据(同样,没有会返回任何数据的合约)。

(bool success,bytes memory data)
// `success` is true because it didn't revert
// `data` is 0x00,the default value

然后验证就好像成功一样通过了。

require(success && (data.length == 0 || ...));
// `success` is true
// `data.length` is 0,so the rest of the OR condition is ignored

我看到您executed setBUSD() 函数。但此函数不设置 busd_addr 值,该值在 _safeTransferFrom() 函数中使用。 (它只设置 busdbusd_set。)

目前无法在您的代码中设置 busd_addr 值。因此,您需要对代码进行适当的更改 - 在 busd_addr 函数中设置 setBUSD() 值,然后重新部署您的合同。