New Admin Action error: Could not validate transaction: cannot estimate gas; transaction may fail or may require manual gas limit

:memo:Details
Hello, I am new to OpenZeppelin Defender and still trying things out. I want to automate a method call on my contract which has an onlyOwner modifier. I figured I will need to create a new Admin Action for it. Additionally I want to use gnosis safe mutisig wallet to execute it. I went ahead and deployed the contract on Rinkeby, changed the owner to the multisig wallet address and then created the contract on OpenZeppelin Defender. When I try to create an Admin Action, I filled out the function to call and parameter, then put the gnosis safe wallet address in the admin account field, added a title and when I hit Create, this error shows up:

Error: Could not validate transaction: cannot estimate gas; transaction may fail or may require manual gas limit

Not something that I would like to do but thought could help - if I remove the admin account field, I get this error:

Error: Transaction would revert: Ownable: caller is not the owner

:computer: Environment
Rinkeby

:1234: Code to reproduce
No code involved. Error from https://defender.openzeppelin.com/#/admin

Hi Jorola, thanks for reaching out! Would you mind sharing the address of the contract and, if possible, verifying its code in Etherscan?

Hi @MartinVerzilli, I’m afraid I’m unable to share the contract address until I can confirm that I am allowed to. It is already verified though on Rinkeby Etherscan. The method involved has a function definition similar to below:

function myFunction(uint256 _amount) external onlyOwner {

Will this help? Please let me know if you require more info. I am also trying right now to make this work from Gnosis Safe but facing some unknown issue.

I’m afraid I’m unable to share the contract address until I can confirm that I am allowed to

No problem :).

I am also trying right now to make this work from Gnosis Safe but facing some unknown issue.

When you try to create an Admin proposal, Defender tries to estimate its gas consumption, which fails when the transaction would revert. Gnosis Safe uses the same mechanism.

So if you're not being able to run the action directly through Gnosis Safe, there's a good chance there's something wrong with the TX, which would cause it to revert if it were to be executed. It could either be some problem with permissions or some condition in the code. Unfortunately there's not much more we can do to help you without seeing the code and/or inspecting the contract (and of course we understand if you can't disclose those either).

Hope this helps a bit!

I was able to try executing other methods of the same contract from Gnosis Safe and that went well (I have yet to try on Defender but I have a feeling they’ll work there as well). So it looks like the problem is only with that specific method I am trying to call.

Note that I am able to execute that method though from etherscan (when the owner is still not transferred to Safe wallet and may times before) using the same parameter I entered on Defender/Gnosis. So I’m confident that the TX is supposed to work.

Will look into this more and update you. Thanks for the help & ideas so far @MartinVerzilli!

Hi @MartinVerzilli / @jorola,

I’m also new to Defender and getting the same ‘can’t estimate gas’ error when I try to create an admin proposal to call an ‘onlyOwner’ function. I’m also using an upgradeable (transparent proxy) contract on Rinkeby (the contract is not verified).

I have used Defender to create an upgrade proposal and (after getting proposal approvals) executed the upgrade to the V2 implementation contract (this V2 contract contains a new function setVersion(unit) and an associated new state variable).

When initially I attempted to create a new admin proposal to set the version number (ie. call the setVersion() function), I discovered that the new V2 implementation functions don’t appear in the ‘New admin action’ proposal list of functions. I, therefore, edited the Defender contract details by pasting in the new ABI for the V2 contract (KittyContractV2). I could then select the setVersion() function when creating a new admin action proposal. However, after completing the proposal fields, clicking “Create Admin Action” it gives me the error (see screenshot below):

Here’s my upgraded V2 contract (KittyContractV2):

pragma solidity 0.8.5;

import "./KittyContract.sol"; 

contract KittyContractV2 is KittyContract {

    uint _version;    //ADDED new state variable

    function initialize(
        string memory tokenName, 
        string memory tokenSymbol
    )
        public
        initializer
    {
        KittyContract.init_KittyContract(tokenName, tokenSymbol);
    }

    // ADDED Functionality
    function setVersion(uint number) public onlyOwner {
        _version = number;
    }

    function getVersion() public view whenNotPaused returns (uint) {
        return _version;
    }

    function pause() public onlyOwner whenNotPaused {
        _pause();
    }

    function unpause() public onlyOwner whenPaused {
        _unpause();
    }
}

Here’s the executed contract upgrade proposal (screenshot):

And the addresses (on Rinkeby):
KittyContractV2 (logic): 0x7d519941ecC45FD3b27571594d9385B2C68f67D8

My original pre-upgrade logic contract: KittyContract (logic): 0x3f62AbF91e53123077e069022694f98c5eC4dF6a

Any idea what’s happening and what I need to do to fix this issue?

Hi Mark! Thanks for reaching out, and for the super detailed descriptions of your issue. It really helps us support you! If you take a look at the contract state card at the right side of the proposal form details, you can see that the owner of this contract is MM Account1. Given you chose to execute this proposal through GnosisSafe (KittyMasters-Rinkeby, the transaction would fail to execute because that Gnosis Safe is not the current KittyContract owner, and you're trying to execute an onlyOwner function.

There's at least three possible approaches for you to be able to execute this function:

  1. Transfer ownership of KittyContract to the Gnosis Safe. Then you will only be able to run setVersion via that Safe.
  2. Change to a more flexible permission structure for setVersion, such as AccessControl, and assign adequate roles to both MMAccount 1 and GnosisSafe (KittyMasters-Rinkeby).
  3. Leave the "Admin account" field empty and execute the proposal with MM Account1.

Hope this helps!
Martin

Edit: you might be wondering why the upgrade did work. That is probably because you did transfer ownership of the ProxyAdmin to your Gnosis Safe, otherwise you'd have hit a similar issue.

@MartinVerzilli, Thank you for the quick and detailed reply! That’s a great help!!

You’re right I had only transferred ownership of my proxyAdmin contract to my GnosisSafe account:

Following your option 3, I’m able to create the proposal and execute it by not specifying the Gnosis Safe (leaving that field blank in the proposal form). So that solves my issue and most importantly improves my understanding!

Is it best practice to also have GnosisSafe own each of the contracts (as well as the proxyAdmin) so that any onlyOwner function would also require multi-sig approval to execute (ala our option 1)?
And then if I needed more flexibility (eg. a super-user account who can execute certain restricted functions without having to get multisig approvals via Gnosis safe), add in a more flexible permission structure (ala your option 2)?

And secondly, on the subject of verifying the contracts before I add them to Defender. If I verify each contract version, does that remove the need for me to manually copy & paste into Defender the new ABI after performing a contract upgrade? (E.g. KittyContract ABI added to Defender initially, but upon upgrading to KittyContractV2 would the Defender automatically pick-up the new ABI - so when I create further Admin proposal any new functions automatically appear the function list)?

Is it best practice to also have GnosisSafe own each of the contracts (as well as the proxyAdmin) so that any onlyOwner function would also require multi-sig approval to execute (ala our option 1)?
And then if I needed more flexibility (eg. a super-user account who can execute certain restricted functions without having to get multisig approvals via Gnosis safe), add in a more flexible permission structure (ala your option 2)?

This really depends on the stage of maturity of your project, the size of your team, how decentralized you want it to be at a given point in time, how you want to govern it, etc. We definitely recommend that before going to production and/or managing real funds, you put all critical functions under control of a multisig with more than one signer. Please checkout a much more comprehensive discussion of multisig best practices at this Defender Advisor article: https://defender.openzeppelin.com/#/advisor/docs/use-multiple-signatures-for-critical-administrative-tasks

And secondly, on the subject of verifying the contracts before I add them to Defender. If I verify each contract version, does that remove the need for me to manually copy & paste into Defender the new ABI after performing a contract upgrade? (E.g. KittyContract ABI added to Defender initially, but upon upgrading to KittyContractV2 would the Defender automatically pick-up the new ABI - so when I create further Admin proposal any new functions automatically appear the function list)?

This basically is a missing feature in Defender. We plan to implement it soon, but for now you'll have to keep an eye on it each time you upgrade :(.

1 Like