Solidity ERC-20 – How to Call a Smart Contract Function from Another Smart Contract

erc-20openzeppelin-contractssolidity

I am new to Solidity and I'm having some trouble when calling a function of a smart contract from another one.

Basically I have smart contract A, which extends ERC20 and the Ownable contract from openzeppelin.

contract contractA is ERC20, Ownable {
    constructor() ERC20("MyToken", "MTK") {
    }

    function mint(address account, uint256 amount) external onlyOwner {
        _mint(account, amount);
    }
}

Then I have smart contract B:

contract contractB is Ownable {
  address contract_a;

  constructor(address contract_address) {
    contract_a = account;
  }

  function mint(address account, uint256 amount) public onlyOwner {
    (bool success, ) = contract_a.call(
      abi.encodeWithSignature("mint(address,uint256)", account, amount)
    );

    require(success, "call failed");
  }
}

Both smart contracts are being deployed by the same user address, and I want that to be the owner of both smart contracts. I firstly deploy contractA, and then deploy contractB using the contractA's address.

When calling the mint function in contractB, success is always false, and I have no idea why this is failing. If I remove the onlyOwner from the mint function in contractA it starts working, so I believe it has something to do with this.

Does anyone know what's wrong here?
Thank you in advance.

Best Answer

You can think of the call from contractB to contractA as an additional "internal transaction", so it still has to adhere to the rules of contractA. In other words, since your mint function can only be called by the owner, and the owner of contractA is not contractB, the transaction fails.

To remedy this, you could create your own modifier that checks if the caller (msg.sender) is either the owner or contractB.

More specifically, the onlyOwner modifier checks that msg.sender is the owner, and msg.sender is the address of the calling account, which in your case is the address of contractB, not the address that signed the original transaction.

Related Topic