Confused about a withdraw function in a contract I am studying

I am fairly new to Solidity and at this point, reviewing contracts that are active and on chain. I am trying to understand every detail. This withdraw function has got me stumped.

    function withdraw(address token, uint256 amount) external onlyOwner {
        if(token == address(0)) { 
            payable(_msgSender()).transfer(amount);
        } else {
            IERC20(token).transfer(_msgSender(), amount);
        }
    }

Particularly the two parts that are "if(token == address(0))" and "payable(_msgSender()).transfer(amount);".
The best explanation for address(0) is here What is address(0) in Solidity but I have to admit, both answers have me bewildered.
I have read that payable() is casting the address to be payable and that this has been deprecated. Just looking for a short explanation as if to a child.

A decent amount of time searching to no avail.

>Solution :

This code seems to aim to be an universal function for two separate features:

  1. withdraw native token
  2. withdraw ERC-20 token

If you pass 0x0000000000000000000000000000000000000000 as the value of address token, the code transfers amount of native token from the contract balance to the _msgSender() address. Each network has usually different native token – ETH on Ethereum, BNB on Binance Smart Chain, MATIC on Polygon, …

If you pass any other value as address token, the contract assumes that there’s an ERC-20 contract on that address, and tries to transfer out amount of the ERC-20 token from the contract balance to the _msgSender() address.


payable extension of address is not deprecated. Since Solidity v0.8.0, all native transfers need to be performed to an address payable type – while older versions also allowed transfers to the regular address type.

The use of transfer() function might be a bit confusing, though. When it’s called on an address payable type, it’s the native transfer. And when it’s called on an interface or contract type (in your case IERC20), it invokes a function on the specified contract – in this case the external contract function is also called transfer().

Leave a Reply