0

I can't get the transaction to execute no matter how much I play with it. I know that it reverts during the secondary call because I always get this revert message: Timelock::executeTransaction: Transaction execution reverted.Here is the function I am calling:

function executeTransactions(address[] targets, uint[] values, string[] memory signatures, bytes[] memory data) public payable returns (bytes memory) 

    bytes memory callData;
    for(uint i = 0; i < targets.length; i++){
        
        if (bytes(signatures[i]).length == 0) {
            callData = data[i];
        } else {
            callData = abi.encodePacked(bytes4(keccak256(bytes(signatures[i]))), data[i]);
        }

        // solium-disable-next-line security/no-call-value
        (bool success, bytes memory returnData) = targets[i].call.value(values[i])(callData);
        require(success, "Timelock::executeTransaction: Transaction execution reverted.");

        return returnData;
    }
}

Here is how I'm calling it (with web3.eth.Contract):

      Contract.methods.executeTransactions(
        ["0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"],//targets
        [0],//values
        [web3.eth.abi.encodeFunctionSignature("transfer(address,uint)")],//signatures
        [web3.eth.abi.encodeParameters(["address", "uint"], ["0xC722A3F999983325c611e7E1D967a3c27063F8b0", 5000000000000000000000000])]//calldata

      ).send({from: accounts[0], gas: 5000000})

Help is greatly appreciated as with my current setup I have to run through a simulation that takes ~15 mins per shot in the dark to test this :/

1

The function changes execution according to signature passed

    if (bytes(signatures[i]).length == 0) {
        callData = data[i];
    } else {
        callData = abi.encodePacked(bytes4(keccak256(bytes(signatures[i]))), data[i]);
    }

If it is empty it will assume the function call is contained in data[i]. You would have to use web3.eth.abi.encodeFunctionCall to encode the function call.

If it is not empty it will calculate the signature bytes4(keccak256(bytes(signatures[i]))), so it is expecting as signature parameter a string like "transfer(address,uint)".

One option is to pass signature as string

  Contract.methods.executeTransactions(
    ["0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"],//targets
    [0],//values
    ["transfer(address,uint)"],//signatures
    [web3.eth.abi.encodeParameters(["address", "uint"], ["0xC722A3F999983325c611e7E1D967a3c27063F8b0", 5000000000000000000000000])]//calldata

  ).send({from: accounts[0], gas: 5000000})
1
  • THANK YOU!!! I'm testing it right now, but this makes so much sense – skrrrraaaa Oct 24 '20 at 18:51

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.