I'm trying to execute a multitransfer (ERC20token) transaction using a multisig contract. The multitransfer got executed successfully when the value of the token is 0, however it always fail (reverted) when I change the amount to non-0.

Is there anyway to debug these between executed and execution failure event logs?

executed: https://kovan.etherscan.io/tx/0xfea8ab49ceaaf69011db45cf7ac78eff29aebe8982ae26811c5027d7dc32813b#eventlog

reverted: https://kovan.etherscan.io/tx/0x550375df362098b67f4f6327c7e4bcdb5dd7ef9ef13a982e64ab42f16bc272b9#eventlog

The multisig uses this code to execute the tx:

    /// @dev Allows anyone to execute a confirmed transaction.
    /// @param transactionId Transaction ID.
    function executeTransaction(uint transactionId)
        confirmed(transactionId, msg.sender)
        if (isConfirmed(transactionId)) {
            Transaction storage txn = transactions[transactionId];
            txn.executed = true;
            if (external_call(txn.destination, txn.value, txn.data.length, txn.data))
            else {
                txn.executed = false;

    // call has been separated into its own function in order to take advantage
    // of the Solidity's code generator to produce a loop that copies tx.data into memory.
    function external_call(address destination, uint value, uint dataLength, bytes data) internal returns (bool) {
        bool result;
        assembly {
            let x := mload(0x40)   // "Allocate" memory for output (0x40 is where "free memory" pointer is stored by convention)
            let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that
            result := call(
                sub(gas, 34710),   // 34710 is the value that solidity is currently emitting
                                   // It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +
                                   // callNewAccountGas (25000, in case the destination address does not exist and needs creating)
                dataLength,        // Size of the input (in bytes) - this is what fixes the padding problem
                0                  // Output is ignored, therefore the output size is zero
        return result;

I tried to change if (external_call(txn.destination, txn.value, txn.data.length, txn.data)) to if (txn.destination.call.value(txn.value)(txn.data))

but still reverted.

  • Comments are not for extended discussion; this conversation has been moved to chat. – eth Apr 25 at 0:57

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.