Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 162 additions & 0 deletions docs/cookbook/mastering-cross-chain-state.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# Mastering Cross-Chain State: Bridging & Recovery

**Target Audience:** DApp Developers, Support Engineers, Protocol Architects
**Prerequisites:** Understanding of EVM fundamentals (EOAs vs. Smart Contracts)

In a multi-chain ecosystem, "State" is fragmented. Moving assets between Layer 1 (Ethereum) and Layer 2 (Base) is not just a database update—it is an asynchronous cryptographic protocol. This guide provides deep technical context on the **7-day withdrawal lifecycle**, **bridging architectures**, and **fund recovery scenarios**.

---

## Part 1: The 7-Day Challenge Period (L2 → L1)

When a user deposits funds *into* Base, it takes minutes. When they withdraw *back* to Ethereum using the official bridge, it takes 7 days. This asymmetry is the core security mechanism of an **Optimistic Rollup**.

### The Technical "Why"

Base "optimistically" assumes all transactions are valid. It does not verify them on Ethereum immediately to save gas.

1. **Output Proposal:** A "Proposer" submits a bundle of L2 transactions to L1.
2. **Challenge Window (7 Days):** The system waits. During this time, any "Verifier" node can check the data. If they find an invalid transaction (e.g., minting ETH out of thin air), they submit a **Fraud Proof**.
3. **Finalization:** If no fraud is proven after 7 days, the bundle is finalized. Only then can the L1 smart contract release the locked funds.

### Example Timeline: Alice's Withdrawal

* **Day 0 (Monday 9:00 AM):** Alice initiates a withdrawal of 10 ETH on Base.
* *Status:* Her 10 ETH is burned/locked on Base.
* *L1 Status:* A "Withdrawal Initiated" event is logged.


* **Day 0 (Monday 10:00 AM):** The Proposer submits the Output Root to Ethereum.
* *Timer:* The 7-day clock starts ticking.


* **Day 1-6:** The funds sit in limbo. They do not exist in Alice's L1 wallet yet.
* **Day 7 (Monday 10:01 AM):** The challenge window closes.
* **Day 7 (Monday 10:05 AM):** Alice (or a relayer) must send a second transaction on Ethereum: `proveWithdrawalTransaction`.
* **Day 7 (Monday 10:10 AM):** Alice sends the final transaction: `finalizeWithdrawalTransaction`.
* *Result:* The L1 Bridge contract transfers 10 ETH to Alice.



### UI Implementation Guide

You must manage the user's anxiety during this week-long wait.

**Anti-Pattern (Don't do this):**

> Status: Pending...

**Best Practice (Do this):**
Create a 3-step visual tracker.

```javascript
// React Pseudocode for Withdrawal Status
const WithdrawalStatus = ({ status, daysRemaining }) => {
if (status === 'CHALLENGE_PERIOD') {
return (
<div className="alert alert-info">
<h3>Step 2 of 3: Security Verification</h3>
<p>Your funds are currently undergoing the standard 7-day security challenge.</p>
<ProgressBar value={7 - daysRemaining} max={7} />
<p className="text-sm">
Time remaining: {daysRemaining} days.
It is safe to close this window. You can return on <strong>{getUnlockDate()}</strong> to claim your funds.
</p>
</div>
);
}
if (status === 'READY_TO_CLAIM') {
return <Button>Finalize & Claim Funds</Button>;
}
};

```

---

## Part 2: Native vs. Third-Party Bridges

Understanding the trade-offs allows you to route users correctly.

### 1. The Native Bridge (The "Slow & Secure" Route)

* **Architecture:** Lock-and-Mint. Assets are locked in a contract on L1, and a canonical representation is minted on L2.
* **Security:** Inherits the full security of Ethereum. To steal funds, you would have to break Ethereum's consensus or the Optimism protocol itself.
* **Best For:** * **Whales:** Moving $1M+ where 0.1% fees are too expensive.
* **DAOs:** Governance actions that require canonical tokens.
* **Arbitrageurs:** Who don't care about time delays.



### 2. Third-Party Bridges (The "Fast & Liquid" Route)

* **Architecture:** Liquidity Pools. The bridge has a pool of USDC on L1 and a pool of USDC on L2.
* **Mechanism:** You give the bridge USDC on Base. The bridge (or a liquidity provider) immediately sends you USDC on Ethereum from their own pocket, minus a fee. They take on the 7-day risk for you.
* **Security:** Trust-based or Trust-minimized (depending on the protocol: Across, Hop, Stargate). If the bridge's smart contract is hacked, liquidity providers lose money.
* **Best For:**
* **Retail Users:** "I need ETH on Mainnet *now*."
* **Small Amounts:** Where paying $5 fee is worth saving 7 days.



### Decision Matrix for Developers

| Scenario | Recommended Route | Reason |
| --- | --- | --- |
| **User wants to move 0.5 ETH for gas** | **Third-Party** | Speed is priority. Fee is negligible. |
| **DAO Treasury moving 5,000 ETH** | **Native** | Security is priority. 0.1% fee on 5k ETH is too high (5 ETH!). |
| **User withdrawing NFT** | **Native** | Most third-party bridges only support fungible tokens (ERC20). |

---

## Part 3: The "Stuck Funds" Recovery Guide

This is a critical support topic. Users frequently send funds to the "wrong" address on Base because they assume their address is universal.

### Scenario A: The EOA (Metamask User)

* **The Issue:** "I use address `0x123` on Ethereum. I sent funds to `0x123` on Base, but I can't see them."
* **The Physics:** An Externally Owned Account (EOA) is derived from a **Private Key**. The math (`Public Key = G * Private Key`) is identical on all EVM chains.
* **The Solution:** The funds are safe. The user just needs to configure their wallet.
1. Open Metamask.
2. Add Network -> Base Mainnet.
3. The funds will appear at `0x123`.



### Scenario B: The Smart Contract (Gnosis Safe / Multisig)

* **The Issue:** "I have a Gnosis Safe at `0x888` on Ethereum. I sent 50 ETH to `0x888` on Base. I don't have access to it!"
* **The Physics:** Smart contracts do **not** have private keys. Their addresses are generated deterministically based on creation parameters.

#### Type 1: The `CREATE` Opcode (Standard Deploy)

The address is determined by: `Keccak256(RLP_Encode([Deployer_Address, Nonce]))`.

* **Example:**
* **Ethereum:** You deployed your Safe from your personal wallet (`0xAlice`) when your wallet's nonce was **5**. The Safe landed at `0x888`.
* **Base:** You look at `0xAlice` on Base. If your nonce is currently **2**, you haven't reached nonce 5 yet.


* **Recovery Strategy (Nonce Replay):**
1. On Base, send 2 dummy transactions from `0xAlice` to increment the nonce from 2 to 4.
2. For the **5th transaction**, send the **exact same deployment payload** (same factory code) that you used on Ethereum.
3. **Result:** The contract *must* deploy to `0x888`. You now own the address and the funds.



#### Type 2: The `CREATE2` Opcode (Counterfactual Deploy)

The address is determined by: `Keccak256(0xff + Deployer_Address + Salt + Keccak256(Init_Code))`.

* **Why this is harder:** The `Deployer_Address` is usually a "Factory" contract.
* **Recovery Strategy:**
1. Check if the **Factory Contract** exists on Base at the *exact same address* as Ethereum.
2. If **YES**: You can call that factory with the same `Salt` and `Init_Code`. Your Safe will appear at the correct address.
3. If **NO**: The factory doesn't exist. You must first deploy the factory (using the "Nonce Replay" method above) to the correct spot, *then* use the factory to deploy your Safe.



> ** Critical Warning:** If you sent funds to a contract address on Base, and that address was originally created on Ethereum by a different contract that *cannot* be replicated on Base (e.g., a one-off script that was self-destructed), the funds are **permanently lost**.

---