The Dreaded 24K Limit

My contract was so big it could not deploy. Here are some tips to reducing contract size while retaining needed functionality.

NOTE: to find the size of your contracts, add “truffle-contract-size”: “latest” to the dependancies of your package.json file. Run “npm install”. Use the command “truffle run contact-size” to view the sizes of the contracts in your projects.

Like a leagal contract, a deFi contract should describe a simple agreement and then use modifiers to describe the conditions and limits of that agreement. Just as some legal contracts contain a lot of boiler plate that ensures the contract is binding within its jurisdiction, a deFi contract can require security and supporting mechanisms that ensure the contract executes in the desired manner while, if possible, making impossible for the contract to act in a manner not within the scope of its design. As such, contracts with complicated functionality can become large.

Since contracts are stored on the block chain there is a limit to how large they can be. In Solidity, this limit is 24Kb.

I created a ERC-1155 NFT contract and included functionality specific to my solution plus code needed for decentralized governance. The result was a contract of over 30Kb. I went through the steps below and reduced the contract size to just over 23Kb.

Here are some things I did to reduce the size of my contract.

  1. Condense duplicated code into internal functions when possible. If there is code that you use more than twice and the only difference or the variables used, turn it into an internal function.
  2. If you have pure functions that do not access state, move these to external library contracts.
  3. Strings - each character in a string is at least 8bits. Though those wordy messages make easy to read error messages, they take up a lot of space. Replace require, assert and other messages with short codes, the shorter the better. In the documentation you right for your dApp create a message dictionary that exlains the meanings of these codes.
  4. If you use the same string two or more times, consider creating a const variable for each string and replace each string with its representative variable.
  5. Every contract your contract decends from (those contract names after the “is” that are not interfaces e.g. ERC1155 is ERC165) become part of the byte code of your contract and add to the size. Adjust these as needed.
  6. Recheck your code, re-examine each function and ask yourself, is this function really needed? If not remove it.
4 Likes

Can you share the contract? I’d be happy to have a look

@dagr,

Thank you, I fixed the issue by following the steps I poseted. I posted this in case anyone else runs into the issue.

Regards,

David

Sometimes it’s better to use composability. It really depends of an use case.