0

I have a Solidity code that aims to Exchange BUSD with myToken (both ERC20) which calls a BUSD.transferFrom() and a myToken.transfer(), but despite the core executes with no errors only myToken is transferred. The account is approved and has enough balance.

Can you please point the error?

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, _msgSender(), 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, address to, uint value) private {
      (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR_TRANSFER, to, value));
      require(success && (data.length == 0 || abi.decode(data, (bool))), 'myTokenPrivateSale: TRANSFER_FAILED');
  }
  
}

mortain
  • 3
  • 3

1 Answers1

0

Your busd_addr is unset (i.e. 0x0).

When the _safeTransferFrom() function gets executed, it sends an internal transaction to the 0x0 address. The transaction doesn't revert (there's no contract that would throw an exception on the 0x0 address) and doesn't return any data (again, no contract that would return any data).

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

The validation then passes as if it were sucessful.

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

I see that you executed the setBUSD() function. But this function doesn't set the busd_addr value, that is used in the _safeTransferFrom() function. (It only sets the busd and busd_set.)

There's currently no way to set the busd_addr value in your code. So you'll need to make the proper changes in your code - set busd_addr value in the setBUSD() function, and then redeploy your contract.

Petr Hejda
  • 40,554
  • 8
  • 72
  • 100