1

Scenario: Contract A is a contract that sells ERC20 tokens Specified in Contract A using Open Zeppelin's ERC20 implementation.

Contract A has a payable function that receives ether from a caller, as payment, and then calculates how many units of Contract B's token is mintable for that payment.

// Inside Contract B, the ERC20 contract
 function mint(address to, uint256 amount) public onlyOwner { 
        _mint(to, amount);
    }

Note: Contract A is the Owner of Contract B.

// Inside contract A....
function pay() external payable {
        uint256 numTokens = calculateTokens(msg.value);
        minter.mint(msg.sender, numTokens);  // minter is a ref to the ERC20 contract.
}

receive() external payable {
     uint numTokens = calculateTokens(msg.value);
     minter.mint(msg.sender, numTokens);
 }

No fallback() is implemented as I am calling pay(). For the same reason, I don't expect the receive() to be triggered either.

Question: Can Contract A’s payable function call Contract B’s non-payable mint function?

Remix says no : reverts this transaction and says I cannot send value to a non payable function…

1 Answer 1

0

We can't see your whole contract but it might be because your contract A does not have a payable fallback function in order to receive tokens.

Adding

receive() external payable {}

Or

fallback() external payable {}

Should be enough

1
  • Thanks @cheen! Updated my question to include the receive(). It was there, but have included it in the question now. As i understand it, the fallback is only where there is NO receive function and when there is calldata. Since I'm trying to call pay(), there is calldata, and the the receive should not trigger, nor the fallback.
    – ZeusLawyer
    Commented Aug 25, 2022 at 3:13

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.