Skip to content

Commit 2b91bc9

Browse files
committed
feat: add bridge to L1 scripts
1 parent 5c3ebfe commit 2b91bc9

7 files changed

Lines changed: 1128 additions & 1 deletion

File tree

claim_contracts/base/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ docs/
1212

1313
# Dotenv file
1414
.env
15+
16+
# Node
17+
node_modules/

claim_contracts/base/Makefile

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
-include .env
2+
export
23

3-
.PHONY: help deploy-base-sepolia deploy-base-mainnet verify bridge-l1-to-base-sepolia bridge-l1-to-base-mainnet
4+
.PHONY: help deploy-base-sepolia deploy-base-mainnet verify bridge-l1-to-base-sepolia bridge-l1-to-base-mainnet withdraw-base-to-l1-sepolia withdraw-base-to-l1-mainnet prove-withdrawal-sepolia prove-withdrawal-mainnet finalize-withdrawal-sepolia finalize-withdrawal-mainnet withdraw-full-sepolia withdraw-full-mainnet
45

56
help: ## Show help
67
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
@@ -53,3 +54,57 @@ bridge-l1-to-base-mainnet: ## Bridge ALIGN from Ethereum to Base (requires AMOUN
5354
cast send $(L1_BRIDGE_MAINNET) "depositERC20(address,address,uint256,uint32,bytes)" \
5455
$(L1_TOKEN_MAINNET) $(L2_TOKEN_MAINNET) $(AMOUNT) 200000 0x \
5556
--private-key $(USER_PRIVATE_KEY) --rpc-url $(L1_MAINNET_RPC_URL)
57+
58+
bridge-l1-to-base-sepolia-to: ## Bridge ALIGN from Sepolia to BaseSepolia to a different address (requires AMOUNT, TO)
59+
cast send $(L1_TOKEN_SEPOLIA) "approve(address,uint256)" $(L1_BRIDGE_SEPOLIA) $(AMOUNT) \
60+
--private-key $(USER_PRIVATE_KEY) --rpc-url $(L1_SEPOLIA_RPC_URL)
61+
cast send $(L1_BRIDGE_SEPOLIA) "depositERC20To(address,address,address,uint256,uint32,bytes)" \
62+
$(L1_TOKEN_SEPOLIA) $(L2_TOKEN_SEPOLIA) $(TO) $(AMOUNT) 200000 0x \
63+
--private-key $(USER_PRIVATE_KEY) --rpc-url $(L1_SEPOLIA_RPC_URL)
64+
65+
bridge-l1-to-base-mainnet-to: ## Bridge ALIGN from Ethereum to Base to a different address (requires AMOUNT, TO)
66+
cast send $(L1_TOKEN_MAINNET) "approve(address,uint256)" $(L1_BRIDGE_MAINNET) $(AMOUNT) \
67+
--private-key $(USER_PRIVATE_KEY) --rpc-url $(L1_MAINNET_RPC_URL)
68+
cast send $(L1_BRIDGE_MAINNET) "depositERC20To(address,address,address,uint256,uint32,bytes)" \
69+
$(L1_TOKEN_MAINNET) $(L2_TOKEN_MAINNET) $(TO) $(AMOUNT) 200000 0x \
70+
--private-key $(USER_PRIVATE_KEY) --rpc-url $(L1_MAINNET_RPC_URL)
71+
72+
# --- Bridging Base -> L1 (withdrawal) ---
73+
# This initiates the withdrawal on L2. After this, you must:
74+
# 1. Wait ~1 hour for the L2 output to be proposed
75+
# 2. Prove the withdrawal on L1 (requires Optimism SDK or Base Bridge UI)
76+
# 3. Wait 7 days (challenge period)
77+
# 4. Finalize the withdrawal on L1
78+
# L2StandardBridge predeploy: 0x4200000000000000000000000000000000000010
79+
80+
withdraw-base-to-l1-sepolia: ## Initiate ALIGN withdrawal from BaseSepolia to Sepolia (requires AMOUNT)
81+
cast send 0x4200000000000000000000000000000000000010 \
82+
"withdraw(address,uint256,uint32,bytes)" \
83+
$(L2_TOKEN_SEPOLIA) $(AMOUNT) 200000 0x \
84+
--private-key $(USER_PRIVATE_KEY) --rpc-url $(BASE_SEPOLIA_RPC_URL)
85+
86+
withdraw-base-to-l1-mainnet: ## Initiate ALIGN withdrawal from Base to Ethereum (requires AMOUNT)
87+
cast send 0x4200000000000000000000000000000000000010 \
88+
"withdraw(address,uint256,uint32,bytes)" \
89+
$(L2_TOKEN_MAINNET) $(AMOUNT) 200000 0x \
90+
--private-key $(USER_PRIVATE_KEY) --rpc-url $(BASE_MAINNET_RPC_URL)
91+
92+
# --- Prove & Finalize (requires npm install) ---
93+
94+
prove-withdrawal-sepolia: ## Prove withdrawal on L1 Sepolia (requires TX_HASH)
95+
npx tsx scripts/withdraw.ts prove --tx-hash $(TX_HASH) --network sepolia
96+
97+
prove-withdrawal-mainnet: ## Prove withdrawal on L1 Mainnet (requires TX_HASH)
98+
npx tsx scripts/withdraw.ts prove --tx-hash $(TX_HASH) --network mainnet
99+
100+
finalize-withdrawal-sepolia: ## Finalize withdrawal on L1 Sepolia (requires TX_HASH)
101+
npx tsx scripts/withdraw.ts finalize --tx-hash $(TX_HASH) --network sepolia
102+
103+
finalize-withdrawal-mainnet: ## Finalize withdrawal on L1 Mainnet (requires TX_HASH)
104+
npx tsx scripts/withdraw.ts finalize --tx-hash $(TX_HASH) --network mainnet
105+
106+
withdraw-full-sepolia: ## Full withdrawal flow: prove + finalize on Sepolia (requires TX_HASH)
107+
npx tsx scripts/withdraw.ts full --tx-hash $(TX_HASH) --network sepolia
108+
109+
withdraw-full-mainnet: ## Full withdrawal flow: prove + finalize on Mainnet (requires TX_HASH)
110+
npx tsx scripts/withdraw.ts full --tx-hash $(TX_HASH) --network mainnet

claim_contracts/base/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,35 @@ make bridge-l1-to-base-mainnet AMOUNT=1000000000000000000
3535

3636
Tokens appear on Base after ~20 minutes.
3737

38+
## Withdraw (Base -> L1)
39+
40+
Withdrawals are a [multi-step process](https://docs.optimism.io/app-developers/tutorials/bridging/cross-dom-bridge-erc20#withdraw-tokens). No approval is needed. All three steps use the same `TX_HASH` — the **L2 initiation tx hash** from step 1.
41+
42+
1. **Initiate** on L2 (burns tokens on Base):
43+
44+
```bash
45+
make withdraw-base-to-l1-sepolia AMOUNT=1000000000000000000
46+
make withdraw-base-to-l1-mainnet AMOUNT=1000000000000000000
47+
```
48+
49+
Save the tx hash from this step — it's needed for prove and finalize.
50+
51+
2. **Prove** on L1 — wait ~1 hour for the L2 output to be proposed, then prove:
52+
53+
```bash
54+
make prove-withdrawal-sepolia TX_HASH=<L2 initiation tx hash>
55+
make prove-withdrawal-mainnet TX_HASH=<L2 initiation tx hash>
56+
```
57+
58+
3. **Finalize** on L1 — wait 7 days challenge period (shorter on testnet), then finalize:
59+
60+
```bash
61+
make finalize-withdrawal-sepolia TX_HASH=<L2 initiation tx hash>
62+
make finalize-withdrawal-mainnet TX_HASH=<L2 initiation tx hash>
63+
```
64+
65+
> **Note:** Prove and finalize use `viem` + `viem/op-stack`. Run `npm install` first.
66+
3867
## Bridge Addresses
3968

4069
Source: [Base Contracts](https://docs.base.org/chain/base-contracts)
@@ -54,4 +83,5 @@ Source: [Base Contracts](https://docs.base.org/chain/base-contracts)
5483
## References
5584

5685
- [OP Standard Bridge Standard Token Tutorial](https://docs.optimism.io/app-developers/tutorials/bridging/standard-bridge-standard-token)
86+
- [OP Bridge ERC-20 Tutorial (withdraw flow)](https://docs.optimism.io/app-developers/tutorials/bridging/cross-dom-bridge-erc20)
5787
- [Base Contracts](https://docs.base.org/chain/base-contracts)

0 commit comments

Comments
 (0)