Getting proper error message from Solidity requires

Hi, I spent a lot of time searching in the web for this simple question:
I have a standard dapp with

  • a Solidity contract with some require(s)
  • Metamask (chrome extension)
  • a simple client that makes calls/sends to the smart contract via web3

Anytime I do a call/send and the contract hits a require, Metamask returns an error that masks the real require error message, this way is impossible to create a meaningful client side error handling.

I cannot upload a picture because I’m a new user, so I try to explain the behaviour:

Basically Metamask says “Insufficient funds”, which is not true (it really hits a require in solidity)

The only thing I can do is “Annul” on the Metamask popup window and this generates an error:

{code: 4001, message: “MetaMask Tx Signature: User denied transaction signature.”, stack: “Error: MetaMask Tx Signature: User denied transaction signature.”}

completely hiding the real solidity error.

Can someone help me understanding what I’m doing wrong?
Thanks a lot!

Hi @Giggioz ! Thanks for asking this question.

Could you share the function you are trying to call along with the require statement that is in your smart contract code?

(for example: require(msg.value > 0, “You must send some ether!”) ).

Hi! Thank you for your question:

From the client I do something like this

forestContract.methods
    .participate(new BigNumber(amount).times(new BigNumber(10).pow(18)).toString())
    .send({ from: account, gasPrice: '7000000000'  })
    .on('transactionHash', (tx) => {
      console.log('transactionHash', tx)
    })
    .on('error', (error, receipt) => {
      console.log('Participate Error - Receipt', error, receipt)
    })

The Solidity Function is

function participate(uint256 amount) public nonReentrant notContract() {
        require(!hasWinner(), "winner, claim first");
        require(block.timestamp >= nextStartTime, "CoolDown period not met");
        require(!blacklist[msg.sender], "Player is backlisted");
        require(lastWinner != msg.sender, "Winner of the last round can not participate"); <<<=== THIS IS THE REQUIRE THAT TRIGGERS THE ERROR
        require(amount == bidAmount, "amount must be equal to bidAmount");

        uint256 burnAmount = amount / 10; //10%
        amountBurned += burnAmount;
        token.safeTransferFrom(msg.sender, burnAddress, burnAmount);
        token.safeTransferFrom(msg.sender, address(this), amount - burnAmount);

        emit OnBid(msg.sender, amount);
        emit OnBurn(burnAmount);

        lastBidTime = block.timestamp;
        lastBidder = msg.sender;
    }

I’m 100% sure that the requires got hit because if I reset that variable (lastWinner) the function works

I’m using web3 v1.3.6 and Solidity v0.6.12

Hi @Tom !
Did you have any chance to take a look at this issue?
Thanks a lot!