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 emitted0 passing (370ms)
1 failing
- 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 ;)