Transaction would revert: could not estimate gas for transaction

I built a vending machine which is loaded (initialized) with an NFT (ERC721) and dispenses generic tokens (ERC20) to any wallet. The main functions are fractionalize & allocate included below:

function fractionalize(uint256 _tokenId) external onlyRole(FRACTIONALIZE_ROLE) {
        uint256 _quantity = (nft.getTreeQuantity(_tokenId)); // improvement removing the quantity entered.
        _stake(msg.sender, _tokenId, _quantity);
        _mintTrees(address(this), _quantity*TOKEN);

function _stake returns true, however _mintTrees does not.

function allocate(uint _tokenId, uint256 _quantity, address _to) external {
        _unstake(msg.sender, _tokenId, _quantity, _to);
        _transferTrees(_to, TOKEN*_quantity);

function _unstake returns true but _transfer does not.

No specific reason for not returning anything. I am to build a node app which can trigger the defender relay from an API call. Although I am having trouble triggering any transaction from my relay wallet automated or not.

:computer: Environment

relay wallet, admin smart contract


Wallet has a balance, 0xef60752fb5daca86f5f2698aeba5d827e8daa7ee

contract on mumbai, 0x350772fa477E6D2473DA3a85a9E76849bf82d43d

:1234: Code to reproduce

I tried to do all the other suggestions of adding modifiers, making the function public/external.. adding roles and setting roles to relay address. I am not sure if it is a problem with the relay set up, or my contract code. Since I can send transactions fine from my wallet on remix I am wondering if it could be a set up issue...

I'm not sure, but looks like you need define limitGas because it cant estimated the gas will be consumed, probably because yours mint and transfers functions looks like batchs and probably have for loops inside for them to work, make sense?

I'll check 2 things, first test locally the contracts its work as expected, then limit some gas locally.

if that work so you look into docs or forum if have way do that limit there. If using ethers should be easy set it.

I hope that help.

Thank you for your ray, I am happy you could figure it out. I have started using chat gpt for those real barriers.

1 Like

So the issue was that the transaction has already occurred. Either by programatic accident or manual error. Do you know how I can return a custom error? If I wanted to make an error describing that the transaction has already occurred, how would i do that?

Inside a transaction, there is no way to determine that it has already occurred, because... well, it didn't.

Every transaction is by definition unique, even if there happens to be some previous transaction which has executed the exact same contract function with the exact same input values.

Hey, what I meant by my message is that I have already minted an NFT with the ID I am using. This is because I am programatically minting a lot of NFTs and the token ID was reused in the previous test. You are right that the same transaction cannot be repeated, but if you use the same token ID as one that has already minted you will get this error.

What I wanted to know is if I can return a custom error so that I can more accurately log this error, if you don't know just say that..