The current implementation of the SablierV2MerkleLockupFactory contract is designed to deploy other contracts, such as SablierV2MerkleLL and SablierV2MerkleLT, on EVM-compatible chains. However, zkSync has specific requirements for contract deployment that differ from Ethereum, making the current implementation incompatible with zkSync. This report outlines the key differences and suggests the necessary modifications to achieve compatibility.
When you deploy to Ethereum, A user sends a transaction to the zero address with the contract bytecode
concatenated with the constructor parameters.
However, ZK sync differs.
A user calls the CREATE
function of the ContractDeployer system contract, providing the hash of the contract
to be published and the constructor arguments.
The contract bytecode itself is supplied in the factory_deps field of the transaction (EIP-712 transaction).If the contract is a factory (deploys other contracts), the bytecodes of these contracts must also be included in the factory_deps
field.
Specific Requirements for zkSync:
zkSync requires EIP-712 transactions for contract deployment, which includes additional fields such as factory_deps
for contract bytecodes.
The factory_deps
field must contain the bytecodes of all contracts that a factory contract can deploy.
This ensures that the zkSync operator knows the contract bytecode before deployment.
The current SablierV2MerkleLockupFactory deploys contracts using the new keyword, which is compatible with Ethereum but
does not meet zkSync's requirement for the factory_deps
field and EIP-712 transaction format.
Without the factory_deps
field and EIP-712 transactions, attempts to deploy contracts on zkSync will fail.
Manual Review & ZKSYNC Documentation
Align SablierV2MerkleLockupFactory and all deployments to zkSync in line with the documentation
https://docs.zksync.io/build/developer-reference/contract-deployment.html#note-on-factory-deps
ContractDeployer https://docs.zksync.io/build/developer-reference/system-contracts.html#l2-system-contracts
This contract is used to deploy new smart contracts. Its job is to make sure that the bytecode for each deployed contract is known. This contract also defines the derivation address. Whenever a contract is deployed, it emits the ContractDeployed event.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.