FastWithdrawalPoolV2 — 实现

For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

Goal: Implement a trustless FastWithdrawalPool v2 as an L1 Sidecar contract that uses era Mailbox proof verification for settlement.

Architecture: Standalone Solidity contract on L1 alongside era's native bridge. LPs provide liquidity; users get instant withdrawals by binding an L2 standard withdrawal tx hash; anyone can settle by providing a valid era L2→L1 message proof. No era contracts are modified.

Tech Stack: Solidity 0.8.26, Foundry, OpenZeppelin v5.6.1 (ReentrancyGuard), era IMailbox interface (minimal local copy)

Design Doc: docs/plans/2026-03-03-bridge-enhancement-design.md


Task 1: Interfaces — IFastWithdrawalPoolV2 + IMailbox

Files:

  • Create: contracts/src/interfaces/IFastWithdrawalPoolV2.sol

  • Create: contracts/src/interfaces/IMailbox.sol

Step 1: Create the minimal IMailbox interface

This is a local copy of the era Mailbox proof verification interface. We copy only what we need to avoid cross-project build dependencies.

// contracts/src/interfaces/IMailbox.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

/// @notice Minimal interface for era Diamond Proxy Mailbox facet.
/// Copied from era-contracts: state-transition/chain-interfaces/IMailboxImpl.sol
/// Only includes the proof verification function needed by FastWithdrawalPool v2.
interface IMailbox {
    /// @notice L2-to-L1 message structure
    struct L2Message {
        uint16 txNumberInBatch;
        address sender;
        bytes data;
    }

    /// @notice Verify that an L2-to-L1 message was included in a finalized batch
    /// @param _batchNumber L2 batch number where the message was sent
    /// @param _index Message index within the batch
    /// @param _message The L2 message content
    /// @param _proof Merkle proof of inclusion
    /// @return Whether the proof is valid
    function proveL2MessageInclusion(
        uint256 _batchNumber,
        uint256 _index,
        L2Message calldata _message,
        bytes32[] calldata _proof
    ) external view returns (bool);
}

Step 2: Create the IFastWithdrawalPoolV2 interface

Step 3: Verify compilation

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge build Expected: Compiles with no errors

Step 4: Commit


Task 2: MockMailbox Test Helper

Files:

  • Create: contracts/test/mocks/MockMailbox.sol

Step 1: Create MockMailbox

Step 2: Verify compilation

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge build Expected: Compiles with no errors

Step 3: Commit


Task 3: FastWithdrawalPool v2 — Contract Skeleton + LP Liquidity (TDD)

Files:

  • Create: contracts/src/bridge/FastWithdrawalPoolV2.sol

  • Create: contracts/test/FastWithdrawalPoolV2.t.sol

Step 1: Write failing tests for LP liquidity

Step 2: Run tests to verify they fail

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-contract FastWithdrawalPoolV2Test -v Expected: Compilation error — FastWithdrawalPoolV2 not found

Step 3: Implement FastWithdrawalPoolV2 skeleton + LP functions

Step 4: Run tests to verify they pass

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-contract FastWithdrawalPoolV2Test -v Expected: All 8 tests PASS

Step 5: Commit


Task 4: requestFastWithdrawal (TDD)

Files:

  • Modify: contracts/test/FastWithdrawalPoolV2.t.sol — add tests

  • Modify: contracts/src/bridge/FastWithdrawalPoolV2.sol — implement function

Step 1: Add failing tests

Append to FastWithdrawalPoolV2Test:

Step 2: Run tests to verify new tests fail

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-contract FastWithdrawalPoolV2Test --match-test "test_requestFastWithdrawal" -v Expected: FAIL — "Not implemented yet"

Step 3: Implement requestFastWithdrawal

Replace the requestFastWithdrawal stub in FastWithdrawalPoolV2.sol:

Step 4: Run tests to verify they pass

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-contract FastWithdrawalPoolV2Test -v Expected: All tests PASS (8 LP + 7 request = 15)

Step 5: Commit


Task 5: settleWithdrawal — Trustless Era Proof Settlement (TDD)

Files:

  • Modify: contracts/test/FastWithdrawalPoolV2.t.sol — add settlement tests

  • Modify: contracts/src/bridge/FastWithdrawalPoolV2.sol — implement function

Step 1: Add failing tests for settlement

Append to FastWithdrawalPoolV2Test:

Step 2: Run tests to verify new tests fail

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-contract FastWithdrawalPoolV2Test --match-test "test_settleWithdrawal" -v Expected: FAIL — "Not implemented yet"

Step 3: Implement settleWithdrawal

Replace the settleWithdrawal stub in FastWithdrawalPoolV2.sol:

Step 4: Run tests to verify they pass

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-contract FastWithdrawalPoolV2Test -v Expected: All tests PASS (15 + 6 = 21)

Step 5: Commit


Task 6: reclaimTimedOut (TDD)

Files:

  • Modify: contracts/test/FastWithdrawalPoolV2.t.sol — add timeout tests

  • Modify: contracts/src/bridge/FastWithdrawalPoolV2.sol — implement function

Step 1: Add failing tests for timeout

Append to FastWithdrawalPoolV2Test:

Step 2: Run tests to verify new tests fail

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-contract FastWithdrawalPoolV2Test --match-test "test_reclaimTimedOut" -v Expected: FAIL — "Not implemented yet"

Step 3: Implement reclaimTimedOut

Replace the reclaimTimedOut stub in FastWithdrawalPoolV2.sol:

Step 4: Run all tests

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-contract FastWithdrawalPoolV2Test -v Expected: All tests PASS (21 + 5 = 26)

Step 5: Commit


Task 7: claimFees Tests + Full Integration Test

Files:

  • Modify: contracts/test/FastWithdrawalPoolV2.t.sol — add fee claim + E2E tests

Step 1: Add fee claim and integration tests

Append to FastWithdrawalPoolV2Test:

Step 2: Run full test suite

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-contract FastWithdrawalPoolV2Test -v Expected: All tests PASS (26 + 4 = 30)

Step 3: Commit


Task 8: Run Full Project Test Suite

Files: None (verification only)

Step 1: Run FastWithdrawalPoolV2 tests

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-contract FastWithdrawalPoolV2Test -v Expected: 30 tests PASS

Step 2: Run entire project tests to verify no regressions

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test Expected: All tests pass (existing 83 v1 tests + 30 new v2 tests)

Step 3: Check gas report

Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-contract FastWithdrawalPoolV2Test --gas-report Expected: View gas costs for key functions (requestFastWithdrawal, settleWithdrawal should be < 100k gas)

Step 4: Final commit if any adjustments were made


Summary

Task
Description
Tests

1

Interfaces (IFastWithdrawalPoolV2 + IMailbox)

2

MockMailbox test helper

3

Contract skeleton + LP liquidity

8

4

requestFastWithdrawal

+7 = 15

5

settleWithdrawal (era proof)

+6 = 21

6

reclaimTimedOut

+5 = 26

7

claimFees + E2E tests

+4 = 30

8

Full suite verification

Total: 8 tasks, 30 tests, ~8 commits

Files created:

  • contracts/src/interfaces/IFastWithdrawalPoolV2.sol

  • contracts/src/interfaces/IMailbox.sol

  • contracts/src/bridge/FastWithdrawalPoolV2.sol

  • contracts/test/mocks/MockMailbox.sol

  • contracts/test/FastWithdrawalPoolV2.t.sol

Files NOT modified: Zero era-contracts files. Zero existing BabyDriver files.

Last updated