I'm working with OpenZeppelin upgradable proxies, as well as their governance. I have a propose function that looks like:

 function propose(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        string memory description
    ) public virtual override returns (uint256) {
        uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description)));

        require(targets.length == values.length, "Governor: invalid proposal length");
        require(targets.length == calldatas.length, "Governor: invalid proposal length");
        require(targets.length > 0, "Governor: empty proposal");

        ProposalCore storage proposal = _proposals[proposalId];
        require(proposal.voteStart.isUnset(), "Governor: proposal already exists");

        uint64 snapshot = block.number.toUint64() + votingDelay().toUint64();
        uint64 deadline = snapshot + votingPeriod().toUint64();


        emit ProposalCreated(
            new string[](targets.length),

        return proposalId;

Which is the same as OpenZeppelin's GovernorUpgradeable contract.

Then, I'm calling the function from a proxy contract like so (in brownie):

tx = proxy_governor.propose(
                vote_token.transfer, account.address, 1000000000000000000
        "I want to pay myself 1 token. ",
        {"from": account},
  • vote_token_address is an ERC20 address.

  • encode_function_data is a way to turn the function call into calldata. That part outputs: 0xa9059cbb00000000000000000000000066ab6d9362d4f35596279692f0251db6351658710000000000000000000000000000000000000000000000000de0b6b3a7640000, which should be the ABI encoded data for calling transfer on an ERC20, and sending 1 token to 0x643315C9Be056cDEA171F4e7b2222a4ddaB9F88D

I'm just trying to propose sending myself 1 token.

However, I'm running into this issue:

VirtualMachineError: Transaction reverted without a reason string: Transaction reverted without a reason string
Trace step 2517, program counter 862:
  File "/Users/patrick/.brownie/packages/OpenZeppelin/openzeppelin-contracts@4.2.0/contracts/proxy/Proxy.sol", line 38, in Proxy._delegate:    
    case 0 {
        revert(0, returndatasize())
  • revert "without a reason" might be because of lacking funds on senders account, or running invalid opcode instruction. So, in your case, the error is not emitted by your requires, but by some other instruction
    – Nulik
    Aug 23 at 20:26
  • 1
    run debug.traceTransaction() and see what is the latest opcode executed, might give a hint
    – Nulik
    Aug 23 at 20:27
  • DELEGATECALL returns the return value meant by calling code, and pushes 1 on the stack in case of success, and pushes 0 on the stack in case of an error. The return value is a separate thing from the codes pushed on the stack
    – Nulik
    Aug 23 at 20:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.