[Solidity] Contract code size over limit

Sigit H. Yudanto
3 min readFeb 6, 2022
Solidity compiler version 0.8.9+commit.e5eed63a

Contract code size over limit

Contract creation initialization returns data with length of more than 24576 bytes. The deployment will likely fails.
More info: eip-170

This error messages appear when you deploy on mainnet with Solidity compiler version 0.8.9+commit.e5eed63a.

From the error messages it’s clear that we have to DOWNSIZING CONTRACTS TO FIGHT THE CONTRACT SIZE LIMIT.

WHY IS THERE A LIMIT?

On November 22, 2016 the Spurious Dragon hard-fork introduced EIP-170 which added a smart contract size limit of 24.576 kb. For you as a Solidity developer this means when you add more and more functionality to your contract, at some point you will reach the limit and when deploying will see the error:

Warning: Contract code size exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low “runs” value!), turning off revert strings, or using libraries.

This limit was introduced to prevent denial-of-service (DOS) attacks. Any call to a contract is relatively cheap gas-wise. However, the impact of a contract call for Ethereum nodes increases disproportionately depending on the called contract code’s size (reading the code from disk, pre-processing the code, adding data to the Merkle proof). Whenever you have such a situation where the attacker requires few resources to cause a lot of work for others, you get the potential for DOS attacks.

Originally this was less of a problem, because one natural contract size limit is the block gas limit. Obviously a contract needs to be deployed within a transaction that holds all of the contract’s bytecode. If you then include only that one transaction into a block, you can use up all of that gas, but it’s not infinite. The issue in that case though is that the block gas limit changes over time and is in theory unbounded. At the time of the EIP-170 the block gas limit was only 4.7 million. Now the block gas limit just increased again last month to 11.9 million.

To solve this problem you can check the enable optimization on the remix with value 200 before compiling yours.

Enable Optimization

After compiled then it should there no errors if you deploy them on the mainnet.

Here’s the details for EIP-170.

Hard fork

Spurious Dragon

Parameters

  • MAX_CODE_SIZE: 0x6000 (2**14 + 2**13)
  • FORK_BLKNUM: 2,675,000
  • CHAIN_ID: 1 (Mainnet)

Specification

If block.number >= FORK_BLKNUM, then if contract creation initialization returns data with length of more than MAX_CODE_SIZE bytes, contract creation fails with an out of gas error.

Rationale

Currently, there remains one slight quadratic vulnerability in Ethereum: when a contract is called, even though the call takes a constant amount of gas, the call can trigger O(n) cost in terms of reading the code from disk, preprocessing the code for VM execution, and also adding O(n) data to the Merkle proof for the block’s proof-of-validity. At current gas levels, this is acceptable even if suboptimal. At the higher gas levels that could be triggered in the future, possibly very soon due to dynamic gas limit rules, this would become a greater concern — not nearly as serious as recent denial of service attacks, but still inconvenient especially for future light clients verifying proofs of validity or invalidity. The solution is to put a hard cap on the size of an object that can be saved to the blockchain, and do so non-disruptively by setting the cap at a value slightly higher than what is feasible with current gas limits.

References

  1. EIP-170 issue and discussion: https://github.com/ethereum/EIPs/issues/170
  2. pyethereum implementation: https://github.com/ethereum/pyethereum/blob/5217294871283d8dc4fb3ca9d8a78c7d416490e8/ethereum/messages.py#L397.

--

--

Sigit H. Yudanto

⛓️ Blockchain Basic Certified (Coursera) University at Buffalo & State University of New York. ✉️ Inquiry: hello[at]sigit.co.uk