Summary
2 Critical, 3 High, 5 Medium, 4 Low findings. Validated by code analysis (Solana, settlement + DA log + SDK).
Validation Method
Full source audit of programs/zul-settlement/src/lib.rs (617 lines), programs/zul-da-log/src/lib.rs (69 lines), programs/smt/src/lib.rs (244 lines), and SDK files.
Findings
C1 (CRITICAL): Sequencer Can Drain Bridge Vault via Arbitrary Root Posting
post_batch accepts state_root and withdrawals_root as raw byte arrays with ZERO on-chain validation. No fraud proof, no challenge window, no ZK proof.
Attack Path:
- Sequencer calls
post_batch(withdrawals_root = crafted_root) with fake withdrawal commitment
- Anyone calls
claim_withdrawal(proof against crafted_root) — proof verifies against sequencer-controlled root
- Vault drains all funds
C2 (CRITICAL): No Vault Balance Check on Claim
claim_withdrawal does not check vault has sufficient lamports before transfer.
H1 (HIGH): DA Log Fully Permissionless — Fake Data Injection
No authority check, no batch existence check, no data validation on post_chunk.
H2 (HIGH): Claim PDA Doesn't Bind batch_no — Cross-Batch Replay
Claim PDA derived from [CLAIM_SEED, recipient, nonce] — no batch_no.
H3 (HIGH): Sequencer Can Mint Unbacked Wrapped Tokens on L2
L2 state entirely controlled by sequencer. Can credit tokens without corresponding L1 deposits.
Summary
2 Critical, 3 High, 5 Medium, 4 Low findings. Validated by code analysis (Solana, settlement + DA log + SDK).
Validation Method
Full source audit of
programs/zul-settlement/src/lib.rs(617 lines),programs/zul-da-log/src/lib.rs(69 lines),programs/smt/src/lib.rs(244 lines), and SDK files.Findings
C1 (CRITICAL): Sequencer Can Drain Bridge Vault via Arbitrary Root Posting
post_batchacceptsstate_rootandwithdrawals_rootas raw byte arrays with ZERO on-chain validation. No fraud proof, no challenge window, no ZK proof.Attack Path:
post_batch(withdrawals_root = crafted_root)with fake withdrawal commitmentclaim_withdrawal(proof against crafted_root)— proof verifies against sequencer-controlled rootC2 (CRITICAL): No Vault Balance Check on Claim
claim_withdrawaldoes not check vault has sufficient lamports before transfer.H1 (HIGH): DA Log Fully Permissionless — Fake Data Injection
No authority check, no batch existence check, no data validation on
post_chunk.H2 (HIGH): Claim PDA Doesn't Bind batch_no — Cross-Batch Replay
Claim PDA derived from
[CLAIM_SEED, recipient, nonce]— nobatch_no.H3 (HIGH): Sequencer Can Mint Unbacked Wrapped Tokens on L2
L2 state entirely controlled by sequencer. Can credit tokens without corresponding L1 deposits.