TransactionRevertedWithoutReasonError: Transaction has been reverted by the EVM:

Hello! When I execute the Approve function on an ERC20 contract from Remix on mumbai polygon using my metamask, everything works fine.
However, when I execute it using my front end, it fails giving the error: TransactionRevertedWithoutReasonError: Transaction has been reverted by the EVM:
I am not able to find why this is occuring.....

Without you sharing the relevant details, neither is anyone else reading this.

Please describe by the least:

  • How you call it from Remix
  • How you call it from the front-end
1 Like

Hello!
This is the ERC20 contract from Openzeppelin:

</>

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MockUSDT is ERC20 {
    constructor(uint256 _initialSupply) ERC20("Tether", "USDT") {
        _mint(msg.sender, _initialSupply * (10**uint256(decimals())));
    }
}

The way I am calling it from Remix after it being deployed is simply by using the injected Metamask in the Environement section and pressing on the approve button after entering the amount. In this way everything is working fine. (on mumbai polygon)
But when I interact with the contract using my front end, the transaction is failing by giving this error "TransactionRevertedWithoutReasonError: Transaction has been reverted by the EVM:".
This is my front end code snippet:

onClick = async (event) => {
        event.preventDefault();
try {
const gasPrice = await web3.eth.getGasPrice();
const gasLimit = 300000; 
await mockUSDT.methods.approve(myContract, amount)
              .send({ from: accounts[0],  gas: gasLimit, gasPrice: gasPrice })
              .on('transactionHash', (hash) => { console.log("transaction hash: ", hash ) })
              .on('confirmation', (confirmationNumber, receipt) => { console.log("confirmation & receipt : ", confirmationNumber, receipt) })
              .on('error', (error) => { console.log("error: ", error) })
} catch (err) {
console.log(err)
}}
</> ```

NB: for reading values on the contract there is no problem. this error occurs only when I want to send transactions

Hello
This is my Openzeppelin contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MockUSDT is ERC20 {
    constructor(uint256 _initialSupply) ERC20("Tether", "USDT") {
        _mint(msg.sender, _initialSupply * (10**uint256(decimals())));
    }
}

When using Remix, after I deploy my contract, I just press on the Approve button after inserting the amount to approve. I have the injected Metamask as environement and I am on mumbai polygon network.
everything is going fine here
But when I interact with the contract from my front end with the following code, the transaction fail :

      onClick = async (event) => {
        event.preventDefault();
        
          const accounts = await web3.eth.getAccounts();
              const gasPrice = await web3.eth.getGasPrice();
              const gasLimit = 300000; // Increase the gas limit if needed.
     await  mockUSDT.methods.approve(myContract, amount)
              .send({ from: accounts[0],  gas: gasLimit, gasPrice: gasPrice })
              .on('transactionHash', (hash) => { console.log("transaction hash: ", hash ) })
              .on('confirmation', (confirmationNumber, receipt) => { console.log("confirmation & receipt : ", confirmationNumber, receipt) })
              .on('error', (error) => { console.log("error: ", error) })
}

Please note that call from my front end using he same code for only reading value are successful

Get rid of the await, then the on error part should be triggered and tell you what the problem is.

You may also want to add an on receipt part, as shown in the official documentation:

.on('receipt', function(receipt){
    ...
})

Alternatively, you can do something like:

try {
    await mockUSDT.methods.approve(myContract, amount);
}
catch (error) {
    console.log(error.message);
}

Thank you for your reply!
I did the changes as advised but it did not solve my problem.
The error I have is the following:

Uncaught (in promise) TransactionRevertedWithoutReasonError: Transaction has been reverted by the EVM:
 {"blockHash":"0xb64e8591a27715980cc7d5823e03a75f4b9d2ab16cb249ac68a32f75af7ccda9","blockNumber":"41718832","cumulativeGasUsed":"846318","effectiveGasPrice":"1509513136","from":"0xac3ed7b1b178f89f36eaeaa9ae7fe6e485df5e71","gasUsed":"21046","logs":[{"address":"0x0000000000000000000000000000000000001010","blockHash":"0xb64e8591a27715980cc7d5823e03a75f4b9d2ab16cb249ac68a32f75af7ccda9","blockNumber":"41718832","data":"0x00000000000000000000000000000000000000000000000000001ce4d8aa0df60000000000000000000000000000000000000000000000001e9e63cb9b4abbbe0000000000000000000000000000000000000000000000113e95c6280cf2b21a0000000000000000000000000000000000000000000000001e9e46e6c2a0adc80000000000000000000000000000000000000000000000113e95e30ce59cc010","logIndex":"28","removed":false,"topics":["0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63","0x0000000000000000000000000000000000000000000000000000000000001010","0x000000000000000000000000ac3ed7b1b178f89f36eaeaa9ae7fe6e485df5e71","0x00000000000000000000000004ba3ef4c023c1006019a0f9baf6e70455e41fcf"],"transactionHash":"0x0a3f192f477e3a6558663ec2438e930fdeaf76fe7b33d72a68bafad1218931d1","transactionIndex":"12"}],"logsBloom":"0x00000000000000008000000000000000000000000000000000000000000004000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000004000000000000000000000000000100000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000002000000000000000000000000000000000000100000","status":"0","to":"0x5b3ab0e6dfb6737a1cb68f00707447f49783d7ca","transactionHash":"0x0a3f192f477e3a6558663ec2438e930fdeaf76fe7b33d72a68bafad1218931d1","transactionIndex":"12","type":"2"}
    at eval (get_transaction_error.js:42:1)
    at Generator.next (<anonymous>)
    at eval (get_transaction_error.js:23:1)
    at new Promise (<anonymous>)
    at __awaiter (get_transaction_error.js:19:1)
    at getTransactionError (get_transaction_error.js:30:1)
    at eval (rpc_method_wrappers.js:361:64)
    at Generator.next (<anonymous>)
    at fulfilled (rpc_method_wrappers.js:20:43)

Assuming that you've actually tried my suggestion:

Your description is impossible - you should not be getting an uncaught exception as described in your response, but rather, just a simple printout of the error-message.

Hello! I did now exactly as you described but my metamask was not triggered.
Shouldn't I put a .send with the account to send the transaction...?

I believe that the way you are using web3.js here, is designated primary for testing (for example, via Truffle, HardHat, etc).

You can use .send, but you'll probably need to unlock your account prior to that, on the Ethereum Node which you're connected to (there's a function for that on web3.js).

As far as I know, however, this is not the recommend way of doing things, since anyone hacking the Ethereum Node could technically exploit your account at will.

The correct approach (again - as far as I know) is to sign the transaction with your private key, and then send the signed transaction to the Ethereum Node (there are functions for that too on web3.js).

That being said, it sounds like your Ethereum Node is provided via your MetaMask connection, so I guess that your method might be safe after all (again - unless someone hacks your MetaMask).

Hello! Thanks for replying again!
So you mean every transaction needs to be signed in order to go through and it is not possible just to use the below code? (I am working on the mumbai polygon chain)

await mockUSDTcontract.methods.approve(spenderAddress, amount)
                .send({ 
                  from: accounts[0], 
                  gas: gasLimit, 
                  gasPrice: gasPrice })

No, I did not say this.

I only postulated that it might not be the recommended way, other than for testing purpose.

it is strange the error I am getting because when calling a variable from my frontend everything works fine but when sending transactions using metamask, it fails.
However, if I send the same transaction from Remix everything works fine ...