2

When solc creates code for arrays when they are declared public. In particular, it contains a check on the length of the array. For example, this:

contract OutOfBoundsException {
    uint256[8] public array;
}

compiled with solc --optimize produces:

...
tag_3:
  pop
    /* "contracts/oobtest.sol":46:68  uint256[8] public array */
  tag_4
  calldataload(0x4)
  jump(tag_5)
tag_4:
 # dead code
tag_5:
  0x0
  dup1
  sload
  dup3
  swap1
  dup2
  lt
  tag_6
  jumpi
  invalid
tag6
 # ...

The --optimize flag was used to remove some of the crud and simplify some of the above.

What is going on in the basic block that starts tag_5 and why is it needed?

1 Answer 1

0

The short answer: that code would be used if the contract had tried to access array using an accessor function. But solc is not smart enough to notice that that can't happen here and in many other situations like this.

Here is a situation where this check is needed:

contract PublicArray {
   uint256[8] public array;
}

contract InvalidAccess {  
    PublicArray array_contract;
    constructor() {
         array_contract = PublicArray.at(0x(...))
    }

    function go() {
       return array_contract.array[1000];
    }
}

This information and the above code is from the famous Bernhard Mueller.

Since array is public, solc creates an accessor function for it.

tag3 is the start of that function. calldataload(0x4) loads the index from calldata, then at tag_5 there is a check that calldataload(0x4) < array.length.

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.