Beginner FriendlyFoundryBridge
100 EXP
View results
Submission Details
Severity: high
Valid

Lack of Compiler Awareness for 'contractBytecode', Potential for Incorrect Contract Deployment and Address Calculation in zkSync

Summary

As the contract will be deployed on both L1 and L2 (zkSync), the issue lies in the lack of compiler awareness for contractBytecode in zkSync, potentially resulting in incorrect contract deployments and address calculation.

Vulnerability Details

The lack of compiler awareness regarding the runtime contractBytecode may lead to incorrect contract deployments and address calculation in zkSync, potentially causing operational issues.

Impact

This vulnerability can result in unreliable and potentially non-compliant contract deployments in zkSync, compromising the stability and integrity of the system.

Proof of Concept:

To demonstrate the impact of the lack of compiler awareness in zkSync contract deployment, consider a scenario where a contract is deployed using the create function with runtime bytecode provided as a parameter, such as in the myFactory function. This could result in a contract deployment that does not adhere to zkSync's bytecode format requirements and may lead to operational issues, highlighting the necessity of following zkSync's guidelines for bytecode and compiler awareness.

ref @ https://era.zksync.io/docs/reference/architecture/differences-with-ethereum.html#evm-instructions

Tools Used

  • manual review and foundry

Recommendations

To address the lack of compiler awareness and ensure correct contract deployment in the zkSync environment, the following recommendations are suggested:

  • Compile-Time Bytecode: Modify the contract deployment process to ensure that the bytecode is known at compile time. Use type(T).creationCode to determine the bytecode in advance, aligning with zkSync's specific requirements.

  • Bytecode Validation: Implement bytecode validation to ensure that the contractBytecode parameter adheres to zkSync's bytecode format requirements. Validate the bytecode's length, word count, and other format criteria before deployment to prevent issues.

Replace deploy function with this

function deployToken(string memory symbol, bytes memory contractBytecode) public onlyOwner returns (address addr) {
address deployedContract;
// Check if the deployment is on L1 or L2 (zkSync)
if (block.chainid == 1) {
// On L1 (Ethereum mainnet), use the provided bytecode
assembly {
addr := create(0, add(contractBytecode, 0x20), mload(contractBytecode))
}
require(addr != address(0), "Deployment failed on L1.");
deployedContract = addr;
} else if (block.chainid == 77) {
// On L2 (zkSync), use the bytecode of MyContract (replace with your contract's name)
bytes memory bytecode = type(MyContract).creationCode;
// Ensure the bytecode adheres to zkSync's format requirements
require(bytecode.length % 32 == 0, "Bytecode length must be divisible by 32.");
require(bytecode.length / 32 % 2 == 1, "Word count must be odd.");
require(bytecode.length <= 2 ** 21, "Bytecode exceeds maximum length.");
// Deploy the contract with create2 and calculated salt
assembly {
addr := create2(0, add(bytecode, 32), mload(bytecode), salt)
}
require(addr != address(0), "Deployment failed on L2.");
deployedContract = addr;
} else {
revert("Invalid chainid. Deployment is supported on L1 (Ethereum) and L2 (zkSync) only.");
}
// Store the symbol-address mapping
s_tokenToAddress[symbol] = deployedContract;
// Emit an event to signal successful deployment
emit TokenDeployed(symbol, deployedContract);
}
Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

deployToken(): zksync compatibility issues

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.