1

Deployed bytecode (i.e. the one returned by contract creation) ought to be at most 0x6000 = 24576 bytes long. Does this limitation apply to

  • init code passed on as input data of a user triggered contract creation
  • CREATE and CREATE2,

In the sense that their third stack argument, the size i.e. the number of bytes to read from memory and pass on as intialization code, should also be at most 0x6000?

2 Answers 2

1

Yes.

Typically the factory contract contains the code to deploy. The size of the factory includes that.

Hope it helps.

5
  • Hi Rob, thank you for your answer. I agree with your point that typically the code to deploy is simply a fragment of the init code. However, as far as I know it's the deployed bytecode that has this 24576 byte size limitation. It does seem to me that there is absolutely nothing preventing me from deploying a smartcontract with 1MB of input data that is a standard init code appended with some random bytes at the end. The end result will be the same: I'll deploy the same code on chain. But is this legal or does the init code have to obey the 24576 rule, too ? Commented Jul 6, 2022 at 7:56
  • Although reading your answer again, the "Yes" seems quite categorical. Do you have a reference for that? Commented Jul 6, 2022 at 7:57
  • I did some digging of my own and came to the conclusion that the likely answer is actually No. Commented Jul 6, 2022 at 8:49
  • Deployment enforces the 24576 rule. Other transactions are limited by the block gasLimit which is larger and variable. Note that the gasLimit is consumption, not payload size, so a small transaction that executes a big loop can exceed the limit. Commented Jul 6, 2022 at 16:30
  • I'm not sure whether we agree or not ... do we ? Commented Jul 6, 2022 at 17:50
1

It seems the answer is No. This makes sense a priori in that the DOS attack this code size limitation was designed to thwart was about loading huge chunks of bytecode from the database at very low cost to the attacker. But this problem doesn't arise for initialization code (which is provided in the input data of a transaction or which is gathered from RAM of a smartcontract under execution, in either case no call is made to the DB.)

I'm relying on Geth to substantiate this. Geth defines MaxCodeSize = 24576 and this number is referenced thrice in the code. The only reference that matters to this question is in core/vm/evm.go. The relevant code snippet is in the create method on line 455:

// Check whether the max code size has been exceeded, assign err if the case.
if err == nil && evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize {
    err = ErrMaxCodeSizeExceeded
}

It compares the length of what is returned to the MaxCodeSize. I.e. it makes sure that the bytecode that will be deployed on chain contains at most 24576 bytes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.