Solidity – Disassemble ‘Delete Array’ in Solidity

assemblyevmsolidity

am trying to learn about EVM bytes code, but faced this problem.
First, this is the solidity code

pragma solidity ^0.8.0;

contract Assembly {
    function f() public {
        uint8[3] memory a = [1, 2, 3];
        delete a;
    }
}

I just want to know what' happened under the hood. and for the array init parts, I can understand it.
What I can't understand is delete a part in bytes code.

I first think delete will make array a's elements to the default value, which is zero, but it looks like this.

// maybe delete a?
    005D    5B  JUMPDEST
    005E    60  PUSH1 0x40
    0060    51  MLOAD
    0061    80  DUP1
    0062    60  PUSH1 0x60
    0064    01  ADD
    0065    60  PUSH1 0x40
    0067    52  MSTORE
    0068    80  DUP1
    0069    60  PUSH1 0x03
    006B    90  SWAP1
    006C    60  PUSH1 0x20
    006E    82  DUP3
    006F    02  MUL
    0070    80  DUP1
    0071    36  CALLDATASIZE
    0072    83  DUP4
    0073    37  CALLDATACOPY
    0074    50  POP
    0075    91  SWAP2
    0076    92  SWAP3
    0077    91  SWAP2
    0078    50  POP
    0079    50  POP
    007A    56  *JUMP

Like the solidity code above, I don't have any calldata in function f. What is this code doing? Why did it call CALLDATASIZE and CALLDATACOPY? And why it makes memory[0x40: 0x40 + 0x20] += 0x60, not just leaving it?

Here is the whole bytes code.

6080604052348015600f57600080fd5b506004361060285760003560e01c806326121ff014602d575b600080fd5b60336035565b005b6040805160608101825260018152600260208201526003918101919091526059605d565b5050565b6040518060600160405280600390602082028036833750919291505056fea264697066735822122054404abffe5e82bae9d564c6e7f48ba27772cdcba99b2066167c1c197e1c063964736f6c63430008040033

Thanks in advance!

Best Answer

I found from the yellow paper that CALLDATACOPY just copy 0 to memory if the memory index is greater than or equal to its second input value, which in this case, CALLDATASIZE.

So what this byte code is doing is to make memory[0xe0: 0xe0 + 0x60] = 0.(start from 0xe0 due to this code, uint8[3] memory a = [1, 2, 3];, which makes memory[0x40: 0x60] = 0xe0)

But still, it seems like useless behavior.

I think the code should go with SUB after SWAP1 added, not the ADD in this case. Or if it can't in general, then just do nothing. Don't have any clue about this behavior.

Related Topic