1

ChainBridge has a piece of solidity code:

A:

assembly {
    amount := calldataload(0xC4)

    recipientAddress := mload(0x40)
    lenRecipientAddress := calldataload(0xE4)   // offset 0x20 beside amount is the length variable, I know that.
    mstore(0x40, add(0x20, add(recipientAddress, lenRecipientAddress)))  // load address to the free memory

    calldatacopy(
        recipientAddress, // copy to destinationRecipientAddress
        0xE4, // copy from calldata @ 0x104        **Why copy from 0xE4?
        sub(calldatasize(), 0xE) // copy size (calldatasize - 0x104)    
        //** Why the length is calldatasize()-0xE? Is the original comment by the author correct?
    )
}

and another piece of code

B:

assembly {
    tokenID    := calldataload(0x64)
destinationRecipientAddress        := mload(0x40)              // load free memory pointer
let lenDestinationRecipientAddress := calldataload(0x84)

let lenMeta := calldataload(add(0xA4, lenDestinationRecipientAddress))

mstore(0x40, add(0x40, add(destinationRecipientAddress, lenDestinationRecipientAddress))) // shift free memory pointer

calldatacopy(
    destinationRecipientAddress,                             // copy to destinationRecipientAddress
    0x84,                                                    // copy from calldata after destinationRecipientAddress length declaration @0x84
    sub(calldatasize(), add(0x84, add(0x20, lenMeta)))       // copy size (calldatasize - (0xC4 + the space metaData takes up))
)
// .....

}

The code mstore(0x40, add(0x40, add(destinationRecipientAddress, lenDestinationRecipientAddress))) in B, why is add(0x40, ...) , but in the code of A is add(0x20, add(recipientAddress, lenRecipientAddress). 0x40 or 0x20 ?

Why is 0x40? If I change to mstore(0x40, add(0x20, add(destinationRecipientAddress, lenDestinationRecipientAddress))), it's also success with the test scripts.

And in GenericHandler.sol, Line 200, it's mstore(0x40, add(0x60, add(metaData, lenMeta))). Why is 0x60?

Chen Xing
  • 11
  • 2

1 Answers1

0

The odd numbers 0xC4 are pointer to the parameter inside data

deposit(
    bytes32 resourceID,
    uint8   destinationChainID,
    uint64  depositNonce,
    address depositer,
    bytes   calldata data
)

The parameters are enconded using the contract ABI. For example data starts at offset 0xa0, the first 32 bytes is the length, so the data start at 0xc0. The extra 4 is the function identifier that is required.

The data layout is described in the function documentation

    @notice Data passed into the function should be constructed as follows:
    amount                      uint256     bytes   0 - 32
    recipientAddress length     uint256     bytes  32 - 64
    recipientAddress            bytes       bytes  64 - END
Ismael
  • 30,570
  • 21
  • 53
  • 96