OpenZeppelin / openzeppelin-test-helpers

Assertion library for Ethereum smart contract testing

Home Page:https://docs.openzeppelin.com/test-helpers

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

expectRevert returned error (where it shouldn't)

sjuanati opened this issue · comments

Given this contract:
`

 pragma solidity ^0.6.12;

contract MultisigWallet {

   address[] public approvers; // list of approvers
   uint256 public quorum;      // number of approvers to approve a transfer
   struct Transfer {
      uint256 id;
      uint256 amount;
      address payable to;
       uint256 approvals;
       bool sent;
   }

   Transfer[] public transfers; // list of transfers
   mapping(address => mapping(uint256 => bool)) public approvals;

    constructor(address[] memory _approvers, uint256 _quorum) public {
       approvers = _approvers;
       quorum = _quorum;
   }

   // other functions

   function createTransfer(uint256 amount, address payable to) external onlyApprover {
      transfers.push(Transfer(
         transfers.length,
         amount,
         to,
         0,
         false
      ));
   }
    
   modifier onlyApprover() {
      bool allowed = false;
      for (uint256 i=0; i < approvers.length; i++) {
         if (approvers[i] == msg.sender) {
             allowed = true;
         }
      }
      require(allowed == true, 'only approver allowed');
      _;
   }
}

`

I prepared the following test:

`

const { expectRevert } = require('@openzeppelin/test-helpers')
const MultisigWallet = artifacts.require('MultisigWallet');

contract('MultisigWallet', (accounts) => {
let multisigWallet;

beforeEach(async () => {
    multisigWallet = await MultisigWallet.new([accounts[0], accounts[1], accounts[2]], 2);
    await web3.eth.sendTransaction({ from: accounts[0], to: multisigWallet.address, value: 1000 })
});

it('should NOT create transfers if sender is not approved', async () => {
    await expectRevert(
        await multisigWallet.createTransfer(100, accounts[5], { from: accounts[4] }),
        'only approver allowed'
    );
});

});

`

However, when running the test, I just get returned error where I would expect that test to revert (and consequently pass the test):

Contract: MultisigWallet
1) should NOT create transfers if sender is not approved
> No events were emitted

0 passing (370ms)
1 failing

  1. Contract: MultisigWallet
    should NOT create transfers if sender is not approved:
    Error: Returned error: VM Exception while processing transaction: revert only approver allowed -- Reason given: only approver allowed.
    at Context. (test/MultisigWallet.js:37:34)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

Not sure if relevant, but just noticed that the error message when running the test has a dot at the end of the message: 'only approver allowed.' whereas the require in the smart contract has 'only approver allowed'. I have tried all kind of combinations by adding or removing the dot in the test or contract, but it didn't work.

The funny thing is that I followed this example from a tutorial and did exactly the same steps. In the tutorial the test passed successfully, but not in my case despite the code is exactly the same :(

In case it helps, my setup is:

  • OS: MacOS Big Sur v11.0.1
  • Truffle v5.1.54
  • Node v12.18.4
  • Solidity pragma 0.6.12

Hi @sjuanati,

The problem here is that you're using await in the argument to expectRevert. It should be changed as follows:

     await expectRevert(
-        await multisigWallet.createTransfer(100, accounts[5], { from: accounts[4] }),
+        multisigWallet.createTransfer(100, accounts[5], { from: accounts[4] }),
         'only approver allowed'
     );

This is so that the expectRevert helper can catch the promise rejection, rather than it propagating to your own test.

Please share what tutorial you were following so we can check if it needs to be fixed or maybe explain something better.

Hi @frangio
You are totally right, I added that await incorrectly and therefore my code was obviously not the same as the tutorial -it is now working properly!
Thanks for your help ;)