- Update dbis_core, cross-chain-pmm-lps, explorer-monorepo, metamask-integration, pr-workspace/chains - Omit embedded publish git dirs and empty placeholders from index Made-with: Cursor
408 lines
20 KiB
Markdown
408 lines
20 KiB
Markdown
# Runbook: Deploy cW* and Wire Config
|
||
|
||
**Created:** 2026-02-27
|
||
**Purpose:** Steps to deploy generic `cW*` mirrors on a chain, set `CW_BRIDGE_<CHAIN>`, update token-mapping, and verify roles. Covers Phase D and E from [CW_BRIDGE_TASK_LIST.md](../00-meta/CW_BRIDGE_TASK_LIST.md).
|
||
|
||
For the single-runbook Proxmox operator flow, including generic lane wiring and generic outbound sends, see [PROXMOX_CSTAR_TO_CW_BRIDGE_RUNBOOK.md](../03-deployment/PROXMOX_CSTAR_TO_CW_BRIDGE_RUNBOOK.md).
|
||
|
||
---
|
||
|
||
## Prerequisites
|
||
|
||
- `smom-dbis-138/.env` has `CW_BRIDGE_<CHAIN>` set (already done from deployed bridge suite for Mainnet, Cronos, BSC, Polygon, Gnosis, Avalanche, Base, Arbitrum, Optimism).
|
||
- For **cross-chain mint** to work, the bridge at that address must either be extended to mint cW* in `ccipReceive` or you must deploy a dedicated cW* receiver (e.g. TwoWayTokenBridgeL2) and point `CW_BRIDGE_<CHAIN>` to it; see [CW_BRIDGE_APPROACH.md](CW_BRIDGE_APPROACH.md).
|
||
- RPC URL and `PRIVATE_KEY` for the target chain(s).
|
||
|
||
### Optional hard-peg deployment knobs
|
||
|
||
`DeployCWTokens.s.sol` now supports:
|
||
|
||
- `CW_STRICT_MODE=1` — revoke deployer `MINTER_ROLE` / `BURNER_ROLE` after granting the bridge
|
||
- `CW_GOVERNANCE_ADMIN=0x...` — grant `DEFAULT_ADMIN_ROLE` to governance; in strict mode the deployer admin role is revoked when this is set
|
||
- `CW_FREEZE_OPERATIONAL_ROLES=1` — freeze future `MINTER_ROLE` / `BURNER_ROLE` changes on the token after setup
|
||
|
||
For production hard-peg rollouts, use at least `CW_STRICT_MODE=1`.
|
||
|
||
### Strict bridge hard-peg requirements
|
||
|
||
If you are using [`CWMultiTokenBridgeL1.sol`](../../smom-dbis-138/contracts/bridge/CWMultiTokenBridgeL1.sol) and [`CWMultiTokenBridgeL2.sol`](../../smom-dbis-138/contracts/bridge/CWMultiTokenBridgeL2.sol) for `cWUSDC` / `cWUSDT`, strict mode now also means:
|
||
|
||
- L1 must explicitly allowlist the canonical token with `configureSupportedCanonicalToken(token, true)`
|
||
- L1 should set a per-destination ceiling with `setMaxOutstanding(token, chainSelector, amount)` unless you intentionally want unlimited capacity
|
||
- L1 should attach [`CWReserveVerifier.sol`](../../smom-dbis-138/contracts/bridge/integration/CWReserveVerifier.sol) so new outbound wraps are blocked when canonical backing is unsafe
|
||
- L2 token pairs and destination peers should be frozen after wiring with `freezeTokenPair(canonicalToken)` and `freezeDestination(chainSelector)`
|
||
- Admin withdrawal of supported canonical escrow is blocked while funds are locked, so “rescue” flows must use the bridge or pause process instead of `withdrawToken`
|
||
|
||
Operational note: the verifier gates new `lockAndSend` mints. Return `ccipReceive` releases on Chain 138 are intentionally left live so users are not trapped in wrapped positions during a reserve incident.
|
||
|
||
---
|
||
|
||
## Phase D: Deploy cW* and wire config
|
||
|
||
**One-command helper (from repo root):**
|
||
`./scripts/deployment/run-cw-remaining-steps.sh` runs a dry-run and `--update-mapping` by default. Use `--deploy` to broadcast, then set CWUSDT_*/CWUSDC_* in .env from output and run again with `--update-mapping` (or run `--update-mapping` after editing .env). Use `--verify` to check MINTER/BURNER roles per chain and `--verify-hard-peg` to inspect the Avalanche hard-peg bridge state (`supportedCanonicalToken`, `maxOutstanding`, verifier attachment/config, and L2 freeze flags).
|
||
|
||
**Generic lane wiring helper (from repo root):**
|
||
`./scripts/deployment/configure-cstar-cw-bridge-pair.sh --chain <CHAIN> --asset <c*>` wires one canonical-to-mirrored lane on `CWMultiTokenBridgeL1` / `CWMultiTokenBridgeL2`. Add `--execute` to broadcast and `--freeze` for strict-mode production locks.
|
||
|
||
**Generic outbound send helper (from repo root):**
|
||
`./scripts/bridge/bridge-cstar-to-cw.sh --asset <c*> --chain <CHAIN> --amount <human>` preflights allowance plus `calculateFee(address,uint64,address,uint256)` and prints or submits the exact `lockAndSend(...)` call. Add `--approve --execute` to broadcast.
|
||
|
||
### D1. Run cW* deploy
|
||
|
||
**All supported chains:**
|
||
|
||
```bash
|
||
cd smom-dbis-138
|
||
./scripts/deployment/deploy-tokens-and-weth-all-chains-skip-canonical.sh --deploy-cw
|
||
```
|
||
|
||
Or from repo root (runs same deploy, then can run update-mapping/verify):
|
||
|
||
```bash
|
||
./scripts/deployment/run-cw-remaining-steps.sh --deploy
|
||
```
|
||
|
||
**Single chain (e.g. BSC 56):**
|
||
|
||
```bash
|
||
cd smom-dbis-138
|
||
source .env
|
||
# Use the per-chain bridge; script will pick CW_BRIDGE_BSC when running for chain 56
|
||
CW_BRIDGE_ADDRESS="$CW_BRIDGE_BSC" forge script script/deploy/DeployCWTokens.s.sol:DeployCWTokens \
|
||
--rpc-url "$BSC_RPC_URL" --chain-id 56 --broadcast --private-key "$PRIVATE_KEY" --legacy
|
||
```
|
||
|
||
**Strict production example:**
|
||
|
||
```bash
|
||
cd smom-dbis-138
|
||
source .env
|
||
CW_STRICT_MODE=1 \
|
||
CW_GOVERNANCE_ADMIN=0xYourMultisig \
|
||
CW_BRIDGE_ADDRESS="$CW_BRIDGE_BSC" forge script script/deploy/DeployCWTokens.s.sol:DeployCWTokens \
|
||
--rpc-url "$BSC_RPC_URL" --chain-id 56 --broadcast --private-key "$PRIVATE_KEY" --legacy
|
||
```
|
||
|
||
Or with the wrapper (target one chain only if the script supports `--chain 56`):
|
||
|
||
```bash
|
||
./scripts/deployment/deploy-tokens-and-weth-all-chains-skip-canonical.sh --deploy-cw --chain 56
|
||
```
|
||
|
||
Record the printed addresses for **cWUSDT** and **cWUSDC** per chain.
|
||
|
||
### D2. Set CWUSDT_<CHAIN> and CWUSDC_<CHAIN> in .env
|
||
|
||
Append or update in `smom-dbis-138/.env` (replace with actual addresses from D1 output):
|
||
|
||
```bash
|
||
# Example for BSC (56)
|
||
CWUSDT_BSC=0x...
|
||
CWUSDC_BSC=0x...
|
||
|
||
# Example for Polygon (137)
|
||
CWUSDT_POLYGON=0x...
|
||
CWUSDC_POLYGON=0x...
|
||
```
|
||
|
||
Use the chain suffix that matches the deploy script: MAINNET, CRONOS, BSC, POLYGON, GNOSIS, AVALANCHE, BASE, ARBITRUM, OPTIMISM.
|
||
|
||
### D3. Update token-mapping-multichain.json
|
||
|
||
**Automated:** After setting `CWUSDT_<CHAIN>` and `CWUSDC_<CHAIN>` in `smom-dbis-138/.env`, run from repo root:
|
||
|
||
```bash
|
||
./scripts/deployment/run-cw-remaining-steps.sh --update-mapping
|
||
```
|
||
|
||
This updates `config/token-mapping-multichain.json` for all chains that have `CWUSDT_*`/`CWUSDC_*` in .env (138→chain pairs; Compliant_USDT_cW, Compliant_USDC_cW, and Compliant_EURC_cW if `CWEURC_*` is set).
|
||
|
||
**Manual:** For each chain where cW* was deployed, set `addressTo` for the `_cW` entries (replace the `0x0` placeholder) in `config/token-mapping-multichain.json`: Compliant_USDT_cW → CWUSDT_<CHAIN>, Compliant_USDC_cW → CWUSDC_<CHAIN>, Compliant_EURC_cW if cWEURC deployed.
|
||
|
||
### D3b. Update the active GRU Transport overlay
|
||
|
||
After the mapping is correct, confirm or update [`config/gru-transport-active.json`](../../config/gru-transport-active.json):
|
||
|
||
- ensure the destination chain is enabled
|
||
- ensure the `transportPairs` entry points at the correct `peerKey`
|
||
- ensure `maxOutstanding` policy is set for the pair
|
||
- ensure the reserve-verifier reference is correct for hard-peg pairs
|
||
- leave public pools inactive until they are actually deployed and recorded in `deployment-status.json`
|
||
|
||
### D4. Verify on-chain
|
||
|
||
Confirm the bridge/receiver has MINTER_ROLE and BURNER_ROLE on the cW* token:
|
||
|
||
```bash
|
||
# MINTER_ROLE = keccak256("MINTER_ROLE")
|
||
cast keccak "MINTER_ROLE"
|
||
# Example: 0x...
|
||
|
||
# Check cWUSDT on BSC (replace addresses and rpc)
|
||
cast call <CWUSDT_BSC> "hasRole(bytes32,address)(bool)" $(cast keccak "MINTER_ROLE") $CW_BRIDGE_BSC --rpc-url $BSC_RPC_URL
|
||
cast call <CWUSDT_BSC> "hasRole(bytes32,address)(bool)" $(cast keccak "BURNER_ROLE") $CW_BRIDGE_BSC --rpc-url $BSC_RPC_URL
|
||
```
|
||
|
||
Both should return `true`.
|
||
|
||
### D5. Configure strict escrow bridge state
|
||
|
||
For hard-peg deployments using `CWMultiTokenBridgeL1` / `CWMultiTokenBridgeL2`, wire the bridge state after roles are verified.
|
||
|
||
Example on Chain 138 for `cUSDC -> cWUSDC` on Avalanche:
|
||
|
||
```bash
|
||
cd smom-dbis-138 && source .env
|
||
|
||
# Allowlist the canonical token on the 138-side escrow bridge
|
||
cast send "$CHAIN138_L1_BRIDGE" "configureSupportedCanonicalToken(address,bool)" "$CUSDC_138" true \
|
||
--rpc-url "$RPC_URL_138" --private-key "$PRIVATE_KEY" --legacy
|
||
|
||
# Optional but recommended: cap how much this destination can keep outstanding
|
||
cast send "$CHAIN138_L1_BRIDGE" "setMaxOutstanding(address,uint64,uint256)" "$CUSDC_138" 6433500567565415381 1000000000000 \
|
||
--rpc-url "$RPC_URL_138" --private-key "$PRIVATE_KEY" --legacy
|
||
```
|
||
|
||
Example on the destination chain:
|
||
|
||
```bash
|
||
cd smom-dbis-138 && source .env
|
||
|
||
# Freeze the token pair once canonical -> wrapped mapping is correct
|
||
cast send "$AVAX_CW_BRIDGE" "freezeTokenPair(address)" "$CUSDC_138" \
|
||
--rpc-url "$AVALANCHE_RPC_URL" --private-key "$PRIVATE_KEY" --legacy
|
||
|
||
# Freeze the Chain 138 peer once the bridge address is confirmed
|
||
cast send "$AVAX_CW_BRIDGE" "freezeDestination(uint64)" 138 \
|
||
--rpc-url "$AVALANCHE_RPC_URL" --private-key "$PRIVATE_KEY" --legacy
|
||
```
|
||
|
||
Recommended verification calls:
|
||
|
||
```bash
|
||
cast call "$CHAIN138_L1_BRIDGE" "supportedCanonicalToken(address)(bool)" "$CUSDC_138" --rpc-url "$RPC_URL_138"
|
||
cast call "$CHAIN138_L1_BRIDGE" "maxOutstanding(address,uint64)(uint256)" "$CUSDC_138" 6433500567565415381 --rpc-url "$RPC_URL_138"
|
||
cast call "$AVAX_CW_BRIDGE" "tokenPairFrozen(address)(bool)" "$CUSDC_138" --rpc-url "$AVALANCHE_RPC_URL"
|
||
cast call "$AVAX_CW_BRIDGE" "destinationFrozen(uint64)(bool)" 138 --rpc-url "$AVALANCHE_RPC_URL"
|
||
```
|
||
|
||
For the production Avalanche route, `smom-dbis-138/scripts/deployment/complete-nonprefunded-avax-cutover.sh` now applies these controls directly from env:
|
||
|
||
- `CW_MAX_OUTSTANDING_USDT_AVALANCHE`
|
||
- `CW_MAX_OUTSTANDING_USDC_AVALANCHE`
|
||
- `CW_FREEZE_AVAX_L2_CONFIG`
|
||
|
||
### D6. Deploy and attach the canonical reserve verifier
|
||
|
||
Use the helper script in `smom-dbis-138/script/DeployCWReserveVerifier.s.sol` to deploy the verifier and optionally attach it to `CWMultiTokenBridgeL1`.
|
||
|
||
Example:
|
||
|
||
```bash
|
||
cd smom-dbis-138 && source .env
|
||
|
||
CW_L1_BRIDGE="$CHAIN138_L1_BRIDGE" \
|
||
CW_STABLECOIN_RESERVE_VAULT="$STABLECOIN_RESERVE_VAULT" \
|
||
CW_RESERVE_SYSTEM="$RESERVE_SYSTEM" \
|
||
CW_CANONICAL_USDT="$CUSDT_138" \
|
||
CW_CANONICAL_USDC="$CUSDC_138" \
|
||
CW_USDT_RESERVE_ASSET=0xOfficialUSDTReserveAsset \
|
||
CW_USDC_RESERVE_ASSET=0xOfficialUSDCReserveAsset \
|
||
forge script script/DeployCWReserveVerifier.s.sol:DeployCWReserveVerifier \
|
||
--rpc-url "$RPC_URL_138" --broadcast --private-key "$PRIVATE_KEY" --legacy
|
||
```
|
||
|
||
The script defaults to:
|
||
|
||
- attaching the verifier to the L1 bridge
|
||
- requiring vault backing when `CW_STABLECOIN_RESERVE_VAULT` is set
|
||
- requiring reserve-system balance checks when `CW_RESERVE_SYSTEM` is set
|
||
- requiring canonical token ownership to match the reserve vault when a vault is set
|
||
|
||
Recommended post-deploy verification:
|
||
|
||
```bash
|
||
cast call "$CHAIN138_L1_BRIDGE" "reserveVerifier()(address)" --rpc-url "$RPC_URL_138"
|
||
cast call <CW_RESERVE_VERIFIER> "verifyLock(address,uint64,uint256)(bool)" "$CUSDC_138" 6433500567565415381 1 --rpc-url "$RPC_URL_138"
|
||
cast call <CW_RESERVE_VERIFIER> "getVerificationStatus(address,uint64)((bool,bool,bool,bool,bool,bool,bool,bool,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256))" "$CUSDC_138" 6433500567565415381 --rpc-url "$RPC_URL_138"
|
||
```
|
||
|
||
For the production Avalanche route, `smom-dbis-138/scripts/deployment/complete-nonprefunded-avax-cutover.sh` now also reads and converges:
|
||
|
||
- `CW_RESERVE_VERIFIER_CHAIN138`
|
||
- `CW_STABLECOIN_RESERVE_VAULT`
|
||
- `CW_RESERVE_SYSTEM`
|
||
- `CW_ATTACH_VERIFIER_TO_L1`
|
||
- `CW_REQUIRE_VAULT_BACKING`
|
||
- `CW_REQUIRE_RESERVE_SYSTEM_BALANCE`
|
||
- `CW_REQUIRE_TOKEN_OWNER_MATCH_VAULT`
|
||
- `CW_CANONICAL_USDT`
|
||
- `CW_CANONICAL_USDC`
|
||
- `CW_USDT_RESERVE_ASSET`
|
||
- `CW_USDC_RESERVE_ASSET`
|
||
|
||
---
|
||
|
||
## Phase E: Relay and send path (138 → other chains)
|
||
|
||
### E1. Relay service (138 → Mainnet)
|
||
|
||
Mainnet now has a relay-compatible cW receiver for the generic `c* -> cW*` path:
|
||
|
||
- Mainnet relay router: `0x416564Ab73Ad5710855E98dC7bC7Bff7387285BA`
|
||
- Mainnet cW bridge (`CW_BRIDGE_MAINNET`): `0x2bF74583206A49Be07E0E8A94197C12987AbD7B5`
|
||
- Chain 138 sender bridge (`CW_L1_BRIDGE_CHAIN138`): `0x152ed3e9912161b76bdfd368d0c84b7c31c10de7`
|
||
|
||
The legacy Mainnet `CCIPRelayBridge` at `0xF9A32F37099c582D28b4dE7Fca6eaC1e5259f939` remains the WETH-only release bridge. Do not point cW mint flows at that contract.
|
||
|
||
The current proven Mainnet mint-on-receive corridor is:
|
||
|
||
- `138 cUSDC -> Mainnet cWUSDC`
|
||
- Source send tx: `0x1228c6aa540e59055b0c548390272554135ef6611bec7f5424da6da0c85944af`
|
||
- Message id: `0x1fc04053a22f9aaa51a43d883a7d154d952a523873995e106cc2c90889376952`
|
||
- Mainnet relay tx: `0xa67a85dc0fd8b20f6f3516c5db68e75084ff10adb40cc7edc9fb00f54ff2ad47`
|
||
|
||
That canary completed with `processed(messageId)=true` on the Mainnet cW bridge and increased the deployer's Mainnet `cWUSDC` balance by `1` token.
|
||
|
||
### E2. Direct CCIP (138 → chain)
|
||
|
||
If Chain 138 uses UniversalCCIPBridge or a dedicated sender to send c* to a destination chain:
|
||
|
||
- Add destination config for the c* token with **receiver** = the cW* receiver on the destination (e.g. TwoWayTokenBridgeL2 address).
|
||
- Ensure the receiver on the destination has MINTER_ROLE on the cW* token and implements `ccipReceive` → `cW*.mint(recipient, amount)` (see [CW_BRIDGE_APPROACH.md](CW_BRIDGE_APPROACH.md)).
|
||
|
||
### E3. Test E2E
|
||
|
||
1. On Chain 138: Lock or transfer cUSDT to the sender/bridge and trigger a send to the target chain (recipient = test address).
|
||
2. Wait for CCIP execution on the destination chain.
|
||
3. On the destination chain: Verify the recipient’s cWUSDT balance increased (e.g. `cast call <CWUSDT_<CHAIN>> "balanceOf(address)(uint256)" <recipient> --rpc-url <RPC>`).
|
||
|
||
---
|
||
|
||
## New chain checklist (summary)
|
||
|
||
| Step | Action |
|
||
|------|--------|
|
||
| 1 | Set `CW_BRIDGE_<CHAIN>` in .env (or use existing from bridge suite). |
|
||
| 2 | Run DeployCWTokens for that chain (D1). |
|
||
| 3 | Set `CWUSDT_<CHAIN>`, `CWUSDC_<CHAIN>` in .env (D2). |
|
||
| 4 | Update `config/token-mapping-multichain.json` `addressTo` for _cW entries (D3). |
|
||
| 4a | Confirm `config/gru-transport-active.json` activation and policy refs for the new chain (D3b). |
|
||
| 5 | Verify MINTER_ROLE and BURNER_ROLE on cW* for the bridge (D4). |
|
||
| 6 | In hard-peg mode, allowlist canonical tokens and set `maxOutstanding` on `CWMultiTokenBridgeL1`, then freeze token pair and destination on `CWMultiTokenBridgeL2` (D5). |
|
||
| 7 | Deploy and attach `CWReserveVerifier`, then configure canonical `cUSDT` / `cUSDC` backing requirements (D6). |
|
||
| 8 | If cross-chain mint is required, ensure the bridge/receiver code mints cW* in ccipReceive (Phase B or C); then wire relay/direct CCIP (E1, E2) and run E2E test (E3). Mainnet `cUSDC -> cWUSDC` is now the reference completed relay-backed example. |
|
||
|
||
---
|
||
|
||
## Retry or finalize cW* deploys (Mainnet focus; Cronos verifier; Arbitrum replay only if drift appears)
|
||
|
||
As of **2026-04-03**, the public EVM mesh is no longer blocked on token deployment:
|
||
|
||
- **Cronos** now has the full 12-token `cW*` suite live and bridge-role verified.
|
||
- **Arbitrum** has the full address set recorded in `.env`; only rerun deployment there if a verifier shows bytecode or role drift.
|
||
- **Mainnet** recovery is complete: the full 12-token `cW*` suite is now live there alongside the earlier `cWUSDT` and `cWUSDC`.
|
||
|
||
Use the steps below only for replay or disaster recovery on a chain that drifts from the recorded mesh.
|
||
|
||
### Mainnet (1) — replay only if drift reappears
|
||
|
||
The Mainnet nonce-recovery flow below is now historical recovery guidance. Use it only if a fresh verifier shows missing bytecode or a stuck deployment nonce again.
|
||
|
||
1. **Check nonce and balance:**
|
||
`./scripts/deployment/check-deployer-nonce-and-balance.sh`
|
||
|
||
2. **Options:**
|
||
- **Wait** for pending transactions to confirm, then re-run the deploy.
|
||
- **Replace/cancel** pending txs: send a 0-value transaction from the deployer to itself with the *next expected nonce* (e.g. 253) and higher gas so it replaces the stuck one; repeat until the queue is cleared.
|
||
- Use the same wallet in another tool (e.g. MetaMask) and ensure no other process is sending from this account.
|
||
|
||
3. **Run deploy** once nonce is aligned:
|
||
|
||
```bash
|
||
cd smom-dbis-138 && source .env
|
||
DEPLOY_CWUSDT=0 DEPLOY_CWUSDC=0 CW_BRIDGE_ADDRESS="$CW_BRIDGE_MAINNET" forge script script/deploy/DeployCWTokens.s.sol:DeployCWTokens \
|
||
--rpc-url "${ETHEREUM_MAINNET_RPC}" --chain-id 1 --broadcast --private-key "$PRIVATE_KEY" --legacy -vvv
|
||
```
|
||
|
||
Add the printed CWEURC_MAINNET … CWXAUT_MAINNET to `.env`, then run `./scripts/deployment/run-cw-remaining-steps.sh --update-mapping`.
|
||
|
||
### Cronos (25) — complete and verified; keep these steps only for replay / disaster recovery
|
||
|
||
If you ever need to replay Cronos because of a fresh RPC or nonce issue, use the flow below. The current expected post-recovery result is:
|
||
|
||
```bash
|
||
CRONOS_CW_VERIFY_RPC_URL=https://cronos-evm-rpc.publicnode.com \
|
||
bash ../scripts/verify/check-cw-cronos-wave1.sh
|
||
```
|
||
|
||
That verifier should report `missing_code=0 missing_roles=0`.
|
||
|
||
```bash
|
||
cd smom-dbis-138
|
||
source scripts/lib/deployment/dotenv.sh
|
||
load_deployment_env --repo-root "$PWD"
|
||
DEPLOY_CWUSDT=0 DEPLOY_CWUSDC=0 CW_BRIDGE_ADDRESS="$CW_BRIDGE_CRONOS" forge script script/deploy/DeployCWTokens.s.sol:DeployCWTokens \
|
||
--rpc-url "${CRONOS_RPC_URL}" --chain-id 25 --broadcast --private-key "$PRIVATE_KEY" --legacy -vvv
|
||
```
|
||
|
||
If `evm.cronos.org` starts rate-limiting (`Cloudflare 1015`), retry against `https://cronos-evm-rpc.publicnode.com` and reduce the batch size:
|
||
|
||
```bash
|
||
cd smom-dbis-138
|
||
source scripts/lib/deployment/dotenv.sh
|
||
load_deployment_env --repo-root "$PWD"
|
||
DEPLOY_CWUSDT=0 DEPLOY_CWUSDC=0 DEPLOY_CWAUSDT=0 DEPLOY_CWUSDW=0 DEPLOY_CWEURC=0 CW_BRIDGE_ADDRESS="$CW_BRIDGE_CRONOS" forge script script/deploy/DeployCWTokens.s.sol:DeployCWTokens \
|
||
--rpc-url "https://cronos-evm-rpc.publicnode.com" --chain-id 25 --broadcast --private-key "$PRIVATE_KEY" --legacy -vvv
|
||
```
|
||
|
||
Then set `CWEURC_CRONOS` … `CWXAUT_CRONOS` in `.env`, run `./scripts/deployment/run-cw-remaining-steps.sh --update-mapping`, and confirm with:
|
||
|
||
```bash
|
||
CRONOS_CW_VERIFY_RPC_URL=https://cronos-evm-rpc.publicnode.com \
|
||
bash ../scripts/verify/check-cw-cronos-wave1.sh
|
||
```
|
||
|
||
### Arbitrum (42161) — rerun only if verifier shows drift
|
||
|
||
[Arbitrum One gas](https://arbiscan.io/gastracker) is often ~0.02 Gwei; the 10-contract deploy then costs <0.001 ETH. Only rerun this section if the mesh verifier or a direct bytecode check shows an actual gap. If you do need to replay, set `ARBITRUM_GAS_PRICE` slightly above base (e.g. `25000000` = 0.025 gwei). Only use 35 gwei if the network is congested. Run the deploy:
|
||
|
||
```bash
|
||
cd smom-dbis-138 && source .env
|
||
# Only if you see "max fee per gas less than block base fee" (check https://arbiscan.io/gastracker)
|
||
export ARBITRUM_GAS_PRICE=25000000
|
||
./scripts/deployment/deploy-tokens-and-weth-all-chains-skip-canonical.sh --deploy-cw --chain 42161
|
||
```
|
||
|
||
Or single-run without the script (use 25000000 = 0.025 gwei when gas is ~0.02 Gwei):
|
||
|
||
```bash
|
||
DEPLOY_CWUSDT=0 DEPLOY_CWUSDC=0 CW_BRIDGE_ADDRESS="$CW_BRIDGE_ARBITRUM" forge script script/deploy/DeployCWTokens.s.sol:DeployCWTokens \
|
||
--rpc-url "${ARBITRUM_MAINNET_RPC}" --chain-id 42161 --broadcast --private-key "$PRIVATE_KEY" --legacy --with-gas-price 25000000 -vvv
|
||
```
|
||
|
||
Then set in `.env` (expected addresses from script when it runs):
|
||
|
||
- CWEURC_ARBITRUM=0xd6969bC19b53f866C64f2148aE271B2Dae0C58E4
|
||
- CWEURT_ARBITRUM=0x3CD9ee18db7ad13616FCC1c83bC6098e03968E66
|
||
- CWGBPC_ARBITRUM=0xBeF5A0Bcc0E77740c910f197138cdD90F98d2427
|
||
- CWGBPT_ARBITRUM=0x948690147D2e50ffe50C5d38C14125aD6a9FA036
|
||
- CWAUDC_ARBITRUM=0x58a8D8F78F1B65c06dAd7542eC46b299629A60dd
|
||
- CWJPYC_ARBITRUM=0xFb4B6Cc81211F7d886950158294A44C312abCA29
|
||
- CWCHFC_ARBITRUM=0xf9f5D0ACD71C76F9476F10B3F3d3E201F0883C68
|
||
- CWCADC_ARBITRUM=0xeE17bB0322383fecCA2784fbE2d4CD7d02b1905B
|
||
- CWXAUC_ARBITRUM=0xc9750828124D4c10e7a6f4B655cA8487bD3842EB
|
||
- CWXAUT_ARBITRUM=0x328Cd365Bb35524297E68ED28c6fF2C9557d1363
|
||
|
||
Then run `./scripts/deployment/run-cw-remaining-steps.sh --update-mapping`.
|
||
|
||
---
|
||
|
||
## References
|
||
|
||
- [CW_BRIDGE_TASK_LIST.md](../00-meta/CW_BRIDGE_TASK_LIST.md)
|
||
- [CW_BRIDGE_APPROACH.md](CW_BRIDGE_APPROACH.md)
|
||
- [CW_TOKENS_AND_NETWORKS.md](../11-references/CW_TOKENS_AND_NETWORKS.md)
|
||
- [C_TO_CW_MAPPER_MAPPING.md](../04-configuration/C_TO_CW_MAPPER_MAPPING.md)
|