1

In my contract I have a modifier that doesn't allow for other contracts to call the function

modifier callerIsUser() {
    require(tx.origin == msg.sender, "The caller cannot be another contract");
    _;
}

Let's assume the method it's being used in is here

contract MyToken {
    // ...
    constructor(a,b,c,d) ERC721A("name", "MTK") {
       // assigns the a, b, c, d variables
    }

    function mint() callerIsUser {}
}

How can I write a test to make sure it reverts? I tried deploying a mock contract to call it but this errors (not the error I'm looking for).

await expect(
  token.connect(mockContract).mint()).to.be.revertedWith("The caller cannot be another contract");
// Error: invalid signer or provider 

await expect(
  token.attach(mockContract.address).mint()).to.be.revertedWith("The caller cannot be another contract");
// Error: Transaction reverted: function selector was not recognized and there's no fallback function

So I think I need to create a mock Contract that takes in the address of the original contract and call the function but I'm confused how to do so...

contract MyTokenMock is MyToken {
    address public myTokenAddress;

    constructor(address myTokenAddress_) {
        myTokenAddress = myTokenAddress_;
    }

    function mint () {
        // How do I call the token address here?
    }
}

2 Answers 2

1

I ended up figuring out how to create a mock contract. Essentially create an interface of the actual contract. Use it as a template for your mock contract. Pass in the address in the constructor and instantiate it with the template and then call it as if calling the deployed contract.

interface IMyToken {
    function mint() {} external payable;
}

contract Mock {
    IMyToken public myToken;

    constructor(address payable myTokenAddress) payable {
        myToken = IMyToken(myTokenAddress);
    }

    function mint() public payable {
        myToken.mint();
    }
}
0

According to this answer https://ethereum.stackexchange.com/a/139774/18153 on a similar question you could use impersonateAccounts from hardhat-network-helpers-library and connect to your token-instance like this:

   await helpers.impersonateAccount(contractAddress);
   const contractSigner = await ethers.getSigner(contractAddress);
   await token.connect(contractSigner)

(Cudos and credits to Franco Victorio)

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.