ZK Fault Proofs
Best of Both Worlds
For a visual summary of how state derivation and proofs fit together, see the Architecture Overview.
Traditional rollups forced a choice between two extremes:
Optimistic: Cheap when everyone's honest, but slow multi-round disputes
Validity/ZK: Instant finality, but expensive even when no disputes
Facet's ZK Fault Proofs combine the best of both:
Optimistic by default: No proofs needed unless disputed (cheap normal operation)
ZK for disputes: Single transaction resolves any dispute (no multi-round games)
No admin overrides: Completely immutable system
No Training Wheels Philosophy
Traditional rollups have "training wheels" - admin controls that can pause, upgrade, or override the proof system. Facet takes a different approach:
The protocol has no training wheels:
Cannot be paused, upgraded, or overridden
No guardians, security councils, or admin keys
Bridges bring their own training wheels:
Individual bridges can add safety features
Users choose bridges based on their risk tolerance
Competition determines the right balance
This philosophy recognizes that security preferences vary. Some users want maximum decentralization, others want safety nets. The protocol stays neutral while the market decides.
Anyone Can Deploy
The proof system has no special smart contract status. This means:
Equal access: Anyone can deploy their own Rollup.sol
Fork freedom: Change the state transition function by deploying a new version
No gatekeepers: Your proof system is as valid as the "official" one
Market competition: Better implementations can win adoption
Multiple valid contracts: For any given Facet fork, multiple Rollup.sol contracts can exist and should all produce the same results if functioning correctly
This is possible because Facet's core protocol doesn't depend on any smart contract - just the immutable L1 address 0xface7
.
Deployed Instance and Proposer Whitelisting
The Rollup.sol contract deployed at 0x686E7d01C7BFCB563721333A007699F154C04eb4
includes proposer whitelisting, but this only affects timing, not liveness or censorship resistance:
Whitelisted proposers: Can submit optimistic proposals immediately
Anyone: Can submit validity proofs at any time (no whitelist)
Fallback mechanism: After
FALLBACK_TIMEOUT_SECS
(14 days) of inactivity, anyone can propose optimistically
This means:
The whitelist cannot prevent valid state from being posted
Validity proofs always bypass the whitelist entirely
The fallback ensures liveness even if all whitelisted proposers disappear
To check current parameters:
// Read whitelist status
rollup.whitelist(address) // returns (bool isWhitelisted, uint8 role)
// Read timing parameters
rollup.FALLBACK_TIMEOUT_SECS() // 1209600 (14 days)
rollup.MAX_CHALLENGE_SECS() // 259200 (3 days)
rollup.MAX_PROVE_SECS() // 432000 (5 days)
The Rollup Contract
Here's how Rollup.sol
implements the ZK Fault Proof system:
Dual-Track Design
/// @title Rollup
/// @notice Dual-track ZK fault validity proof system
/// @dev Supports two tracks:
/// @dev 1. Fault proofs: Optimistic proposals that can be challenged (low cost)
/// @dev 2. Validity proofs: Direct ZK proofs that bypass challenges (instant finality)
Immutable Parameters
All critical parameters are immutable - no admin can change them:
uint256 public immutable MAX_CHALLENGE_SECS; // Challenge window
uint256 public immutable MAX_PROVE_SECS; // Proof deadline
uint256 public immutable CHALLENGER_BOND; // ETH required to challenge
uint256 public immutable PROPOSER_BOND; // ETH required to propose
ISP1Verifier public immutable VERIFIER; // ZK proof verifier
bytes32 public immutable ROLLUP_CONFIG_HASH; // Chain configuration
Fault Proof Flow
Propose - Submit a state root with bond:
function submitProposal(
bytes32 root,
uint128 l2BlockNumber,
uint32 parentId
) external payable returns (uint256 proposalId)
Challenge - Dispute a proposal with bond:
function challengeProposal(uint256 id) external payable
Prove - Submit ZK proof to defend:
function proveProposal(
uint256 id,
uint256 l1BlockNumber,
bytes calldata proof
) public
Resolve - Determine winner based on proofs:
function resolveProposal(uint256 id) public
Validity Proof Fast Track
Skip the optimistic flow entirely with a direct proof:
function proveBlock(
uint128 l2BlockNumber,
bytes32 root,
uint256 l1BlockNumber,
bytes calldata proof
) external {
// Creates, proves, and resolves atomically
// No bonds required - pure validity proof
}
The Power of Validity Proofs: A single validity proof doesn't just skip the optimistic flow—it acts as a tool that can invalidate multiple incorrect proposals simultaneously. If several optimistic games target the same root, one validity proof settles them all, making it the ultimate defense against incorrect claims.
That is:
Invalid parents invalidate all children (cascading)
Validity proofs override all conflicting proposals
Integration with Bridges
Bridges integrate with the proof system to enable trust-minimized withdrawals. The key integration points are:
Reading canonical state: Bridges query
Rollup.sol
for accepted state rootsVerifying withdrawals: Using merkle proofs against the canonical state
Handling immutability: Working with a system that cannot be paused or overridden
For complete bridge implementation details, see Building Bridges.
Key Takeaways
Immutable proof system - No admin keys, no upgrades, no pauses
Bring your own safety - Bridges add training wheels, not the protocol
Open competition - Anyone can deploy proof systems and bridges
Single-round disputes - ZK proofs resolve conflicts in one transaction
Trustless verification - Cryptographic proofs, not committees, determine truth
This design ensures that Facet remains unstoppable while allowing innovation and user choice in how assets are bridged.
Reference Implementations
ZK Fault Proofs (contracts + services): https://github.com/0xFacet/zk-fault-proofs
Rust STF & Derivation (used for proofs):
FacetKona (Kona fork): https://github.com/0xFacet/facet-kona
FacetREVM (REVM fork): https://github.com/0xFacet/facet-revm
FacetOpAlloy (supporting components): https://github.com/0xFacet/facet-op-alloy
Last updated