I want to write unit-test (using ethers.js on top of an hardhat-project) that covers a hook-function for OpenZeppelin's ERC1155 contract: onERC1155Received.

The special thing here is that the msg.sender of this function will be the original Token contract, that calls the transfer-method which executes eventually the onERC1155Received method.

How can I make the msg.sender being a contract instead of a normal user-account?

Let's say, the Contract has code like this:

function onERC1155Received(
    address operator,
    address from,
    uint256 tokenId,
    uint256 amount,
    bytes memory data
) public virtual override returns (bytes4) {
    address originalToken = msg.sender;
    if (!isTokenSupported(originalToken)) {
        revert ErrWrongToken(originalToken);

How can I inject an appropriate msg.sender here that reflects a token-contract?

When I want to use a special signer on a contract, I do:

const signer = token.connect(mySignerAccount);

But I can not use the same approach to use a contract-instance here as signer-account.

Any ideas how to achieve that?

1 Answer 1


You can impersonate any address with the impersonateAccount network helper. Given the address of some contract, you have to do something like this:

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

This assumes that the contract has enough ETH to send the transaction. If it doesn't, you should use the setBalance helper first. You can also just send ETH to its address, but that assumes that the contract can accept ETH, which is not always the case.

  • Thank you so much! This is exactly what I was looking for!
    – delete
    Nov 21, 2022 at 19:26

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.