Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constructor size check #57

Closed
wants to merge 9 commits into from
Closed

Constructor size check #57

wants to merge 9 commits into from

Conversation

gvladika
Copy link
Contributor

Adds constructor size check to CI for certain contracts.

The reason why we perform constructor size check is because of atomic token bridge creator implementation. Due to contract size limits, we deploy child chain templates to the parent chain. When token bridge is being created, parent chain creator will fetch the runtime bytecode of the templates and send it to the child chain via retryable tickets. Child chain factory will then prepend the empty-constructor bytecode to the runtime code and use resulting bytecode for deployment. That's why we need to ensure that those impacted contracts don't have any logic in their constructors, as that logic can't be
executed when deploying to the child chain.

All impacted contracts have 32 bytes of constructor bytecode which look like this:
608060405234801561001057600080fd5b50615e7c806100206000396000f3fe
This constructor checks that there's no callvalue, copies the contract code to memory and returns it. The only place where constructor bytecode differs between contracts is in 61xxxx80 where xxxx is the length of the contract's bytecode.

One exception is aeWETH, which has a constructor size of 348 bytes. This is because it inhertis from 'aeERC20' which has 'initializer' modifier in its constructor. This modifier will set the contract to the initialized state. When aeWETH is created on the child chain there will be no constructor code invoked as mentioned earlier, so we do the initialization of the logic contract explicitly in the child chain factory.

@cla-bot cla-bot bot added the cla-signed label Nov 17, 2023
@gvladika gvladika marked this pull request as ready for review November 17, 2023 13:08
import hre from 'hardhat'

/**
* Contracts defined here are the ones for which cosntructor size check will be performed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Contracts defined here are the ones for which cosntructor size check will be performed.
* Contracts defined here are the ones for which constructor size check will be performed.

console.log('Start constructor size check')

// get constructor bytecode and check if it has expected length
for (const [contractName, expectedLength] of Object.entries(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's a danger here that a new contract will be added that should be checked, but we forget to add to the list above. Perhaps the list should be an exclusions list, or we somehow have another check that dynamically creates a list from the contracts that are used by the atomic token bridge creator.

const constructorBytecode = await _getConstructorBytecode(contractName)
const constructorBytecodeLength = _lengthInBytes(constructorBytecode)

if (constructorBytecodeLength !== expectedLength) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we know that all the contracts should have the constructor equal to 608060405234801561001057600080fd5b50615e7c806100206000396000f3fe why dont we check for that value instead of length?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're not exactly the same between contracts, because constructor will push the length of the bytecode to the stack -> 61xxxx80 where xxxx is the length. This length will also change if some contract is modified (but not its constructor). We could calculate the length, insert it in the expected constructor code and compare to the actual one. But not sure if we gain much compared to this simple check

@gvladika
Copy link
Contributor Author

gvladika commented Dec 6, 2023

out of date

@gvladika gvladika closed this Dec 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants