Contracts and tooling for Status' L1 pre-deposit vaults, Linea bridge relayer, and the single-asset L2 claim vault that settles user withdrawals. The repo uses Foundry with Cancun solc (^0.8.22) and includes fork tests, Specs, and deployment scripts for both layers.
src/core contracts (PreDepositVault,LineaBridgeRelayer,L2ClaimVault, strategies, interfaces).script/DeployL1.s.soldeploys the L1 vault + Linea bridge relayer and wires roles/limits.script/DeployL2.s.soldeploys the Linea claim vault per bridged asset instance.test/unit, fuzz, and fork tests (useBaseTesthelpers and labeled addresses).spec/comprehensive system documentation including architecture overview and detailed contract specifications.lib/external deps (forge-std,openzeppelin-contracts, etc.).- Build artifacts live under
out/andcache/(Git ignored).
spec/Status_PreDeposit_Vaults_Architecture.md— system architecture and cross-chain flow overviewspec/contracts/— detailed documentation for each contract component- Individual contract documentation with purpose, features, integration points, and security considerations
forge build --sizes— compile with solc ^0.8.22 and print bytecode sizes.forge test -vvv— run the full suite with traces (use--match-contract/--match-testto filter).FOUNDRY_PROFILE=lite forge test— fast dev loop with optimizer off.forge coverage --report summary --report lcov— coverage target is 100%.scopelint check/scopelint fmtandslither .— formatting and static analysis gates.
- Copy the template and fill every variable that applies to your deployment:
cp .env.example .env
- Populate RPC endpoints, private keys, admin/guardian addresses, token addresses (WETH, SNT, etc.),
and Linea bridge endpoints. The scripts read the values at runtime via
vm.env*. - Keep production secrets out of git; use a secure secret manager for CI/CD overrides.
Both scripts emit console.log lines with every deployed contract and any role/config transaction
executed. Provide the private key for each actor (deployer, admin) to automate follow-up calls.
- Ensure
DEPLOYER_PRIVATE_KEY,L1_ADMIN_ADDRESS, bridge endpoints, and vault limits are set. - Optional: set
L1_ADMIN_PRIVATE_KEYif the admin is different from the deployer (enables the script to grant guardian/keeper roles, allowlist the vault on the bridge, and push vault limits). - Broadcast and verify on Etherscan:
forge script script/DeployL1.s.sol:DeployL1 \ --rpc-url "$L1_RPC_URL" \ --broadcast \ --verify \ --etherscan-api-key "$ETHERSCAN_API_KEY" \ -vvvv
- Re-run with
--slowif rate limited. - If verification fails due to missing metadata, run
forge verify-contractwith the address and the artifact underout/DeployL1.s.sol/DeployL1.json.
- Re-run with
- Confirm the on-chain roles (guardian, keeper) if the script skipped them due to missing admin key.
- Fill
L2_DEPLOYER_PRIVATE_KEY(defaults toDEPLOYER_PRIVATE_KEYif omitted) and the Linea-specific env vars:L2_MESSAGE_SERVICE,L2_L1_BRIDGE_ADDRESS, and the managed asset (use0x000...000for native ETH). - Provide
L2_ADMIN_PRIVATE_KEYto let the script grant the guardian role automatically. - Broadcast and verify against LineaScan (Etherscan-compatible API):
forge script script/DeployL2.s.sol:DeployL2 \ --rpc-url "$L2_RPC_URL" \ --broadcast \ --verify \ --etherscan-api-key "$LINEASCAN_API_KEY" \ --verifier etherscan \ --verifier-url https://api.lineascan.build/api \ --chain-id 59144 \ -vvvv
- Record the emitted address for the asset-specific
L2ClaimVault. Deploy one instance per pre-deposit vault asset.
- Confirm the Linea bridge relayer has the vault allowlisted (
isVaultAllowed(address(vault))). - Double-check vault limits and state before opening deposits (use
advanceState()to enable deposits). - Monitor emitted events (
DepositRecorded,ClaimFulfilled) through the ops dashboards.
- Run
scopelint checkandslither .locally before submitting PRs. - Validate bridge endpoints and admin addresses in documentation (
spec/) prior to mainnet deploys. - Track size limits with
forge build --sizes; document any required mitigation.
- Scripts will warn when admin follow-up actions are skipped due to missing keys — re-run with the
appropriate
*_ADMIN_PRIVATE_KEYpopulated. - Use
cast callto inspect live contract state between transactions. - Export
FOUNDRY_PROFILE=litefor cheaper dry-runs on testnets.