0

I have a call for this function (from here):

    function setup(
        address[] calldata _owners,
        uint256 _threshold,
        address to,
        bytes calldata data,
        address fallbackHandler,
        address paymentToken,
        uint256 payment,
        address payable paymentReceiver
    ) external {

which looks like this (from here):

0xb63e800d0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000f48f2b2d2a534e402487b3ee7c18c33aec0fe5e40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f2a961af157426953e392f6468b0162f86b2acbc0000000000000000000000000000000000000000000000000000000000000000

I understand that the first 4 bytes "0xb63e800d" are function selector, so I split rest of data for 32 bytes each:

0000000000000000000000000000000000000000000000000000000000000100
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000140
000000000000000000000000f48f2b2d2a534e402487b3ee7c18c33aec0fe5e4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000001
000000000000000000000000f2a961af157426953e392f6468b0162f86b2acbc
0000000000000000000000000000000000000000000000000000000000000000

the problem, however, that there's one owner (f2a961af157426953e392f6468b0162f86b2acbc) so I would expect it as a second argument (while first being length of the _owner array), but not the last.

Could you please explain how this data is encoded exactly? What's the first value 0x100? This is initialization of gnosis safe so if "to" is zero then there's should be any data, why then firth value is 0x140?

update:

I found a great answer here https://ethereum.stackexchange.com/a/50616/46496

and here https://docs.soliditylang.org/en/v0.8.7/abi-spec.html

1

The data get's encoded with the abi encoder.

function withManyArguments(
flashToken, 
flashAmount, 
balanceBefore, 
arbToken, 
zrxData, 
oneSplitMinReturn, 
oneSplitDistribution,
flag
) {

bytes memory data = abi.encode(
flashToken, 
flashAmount, 
balanceBefore, 
arbToken, 
zrxData, 
oneSplitMinReturn, 
oneSplitDistribution,
flag
);

PassDataSomewhereElse(data);

}

So inside the PassDataSomewhereElse function you can retrieve your data like that

TradeSequence memory sequence = _decodeParams(params);

and refer to them like so.

sequence.flashToken;

Tradesequence is a struct with the same model as the data you encode. You also might have to declare the encoder after pragma with;

pragma experimental ABIEncoderV2;

This is very useful when you need to encode large amount of data to pass to functions call. Also notice that I am also passing encoded data for ZRX inside an encoded call. So they nest into one another.

I your case it seams like a lot of data is null or not set.

They also sometime use the left end side of the bytes string for a proxy and the right end side for the address. It depend on the protocol you are working with and how it as been encoded.

That was for solidity. Now if you want to encode the call data from the front end with ehters it would look like this.

const signature = orderJson.signature

  const iface = new ethers.utils.Interface(JSON.stringify(FILL_ORDER_ABI));
  const sig = "fillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),uint256,bytes)";
  const data = iface.encodeFunctionData(sig,[orderTuple,fillAmount,signature])

And your transcation along with other data

TX = await TRADER_CONTRACT.withManyArguments(
    flashTokenAddress,
    FLASH_AMOUNT,
    arbTokenAddress,
    data,
    minimunReturn,
    distribution,
    ONE_SPLIT_FLAGS,
    options
  )
 const receipt = await TX.wait(1)

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.