It is recommended to use safeTransfer instead of transfer. But I do not understand if it applies to all tokens even the ones that isn't an(other) ERC20 token.

After reading more about safeERC20 my understanding is It’s a helper to make safe the interaction with someone else’s ERC20 token. Also, in this discussion, someone asked

Am I correct to assume that I shouldn't be using SafeERC20 if I am not interacting with someone else's ERC20 token? To which the response was “you are correct. You use SafeERC20 for safe interactions with an(other) ERC20 token

If a contract is accepting some (someone else's) tokens from the user (eg collateral) it makes sense to use safeTransferFrom however let's say for x amount of collateral deposited user is "transferred" an equal amount of AToken. My question is since this AToken is a standard erc20 token and not someone else's erc20 token. Do I still need to use safeTransfer when returning AToken for making a deposit of collateral? If yes, how does safeTransfer make this transfer safe?

function depositCollateral(
    IErc20 collateral,
    IAToken token,
    uint256 depositAmount
) public override {
    // Transfer the collateral to the DSProxy.
    collateral.safeTransferFrom(msg.sender, address(this), depositAmount);

    // return AToken (assume we have already minted and transferred lot of aToken to this contract)
    token.transfer(msg.sender, depositAmount)
    // Do I need to use safeTransfer in the above line and why?


1 Answer 1


You are correct that you do not need SafeTransfer when transferring your own erc20 or a erc20 that's safe to transfert to start with!

Some erc20 return bool true on a successful transfer, some don't. And if you use erc20.transfer() on an address that's not an ERC20, the function will still return true even if there is no contract at the erc20's address.

So your design (i.e. safeTransfer for unknown token and transfer for Atoken) makes a lot of sense!

That being said, you might want to have a check to verify the erc20 address from a pre-approved list because otherwise, as it is now, I can create a valueless erc20 and send it to your contract to get all your Atoken.

Hope this helps!

  • Thanks for your response. yes, this was just an example to understand the use of safe-Transfer when interacting with two types of tokens (standard ERc20 and random Erc20 i,e collateral in the above case.). the update was requested by auditors for this contract (github.com/hifi-finance/hifi/blob/…). Nov 3, 2022 at 17:02
  • Are there any situations where token.transfer(msg.sender, depositAmount) can fail and still function call would succeed even tho token.transfer didn’t? Become that might need using safe transfer or require. Nov 3, 2022 at 17:11
  • That's a good question. On a theoretical level I would say that it could fail and still revert, for exemple if the address of the erc20 was wrong, or if the erc20 contract self destroyed and now there is nothing at its address. But from a 'trusted' erc20, there shouldn't be any reason for it to fail but still return true. At least, mo reason I can think of Nov 3, 2022 at 17:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.