I am currently developing a donation smart contract for the Polygon blockchain. The donation contract should receive many types of coins like (MATIC, USDT, USDC, etc.).

I first made the donate function like the below:

function donate(address donor, address token, bool isNativeCoin, uint256 amount);

But later, I noticed that the Polygon network has MATIC address differently from other evm-based chains.

So I removed the isNativeCoin flag variable in the method params.

function donate(address donor, address token, uint256 amount);

But I don't know that is real MATIC address is and how Polygon is different from other chains.

Here is my research about Polygon MATIC and WMATIC address.

If I import 0x0000000000000000000000000000000000001010 as a token in my metamask wallet, it shows the same balance with Native MATIC balance. It's so interesting.

Here is the full mockup code.

    address MATIC_TOKEN = 0x0000000000000000000000000000000000001010;

    DonationInfo[] donations;
    function _safeTransferMatic(address to, uint256 amount) internal {
      (bool success, ) = to.call{value: amount}("");
      require(success, "MATIC_TRANSFER_FAILED");
    function donate(address donor, address token, uint256 amount) {
      donations.push(DonationInfo(donor, token, amount);
    function sendDonation(uint256 donateIndex) {
      if (donations[donateIndex].token == MATIC_TOKEN) {
        _safeTransferMatic(charityPartner, donations[donateIndex].amount);
      } else {

Is the above code correct or should I use isNativeCoin flag variable?

Could you explain the Polygon MATIC address?

1 Answer 1


It's not really an ERC20 token as you think it is, the contract deployed at address(0x1010) on polygon mainly the bridges from and to ethereum. It does store everyones MATIC balance (which is why metamask gets your balance, it just looks for a balanceOf() function and returns its output), and implements some methods from the ERC20 standard (the ones that contains the tokens metadata, like name(), symbol(), decimals()) but it isnt a token contract in itself. It doesnt implement any transfer methods, so you won't be able to use transferFrom like you would do for any other ERC20 (MATIC is the native chains token as you know, and is transferred like any other native token on other chains).

Now to answer your question about the bool flag, it really doesnt matter. Whenever i need to write a function that can take both the native chains token and ERC20s as input, i use address(0) to represent the native token, and do something like :

function useToken(address token, uint amount) {
  if(token == address(0)) {
    // Ignore `amount` and use `msg.value` instead
  else {
    // normal ERC20 logic

AAVE, for example, use the same approach (except they use 0xeeeeee...eee) to represent the native token instead. But having a bool flag, or even 2 separate functions (like Uniswap) is perfectly fine too.

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.