[474, multichain] ETHFI OFT security hardening (4-DVN + library pinning)#11
[474, multichain] ETHFI OFT security hardening (4-DVN + library pinning)#11jtfirek wants to merge 3 commits into
Conversation
Adds Forge script and config to generate Gnosis Safe batches that pin LZ SendUln302 / ReceiveUln302 libraries and upgrade ETHFI OFT (0xe008...fD3f) to a 4-of-4 required-DVN ULN config (LZ Labs / Nethermind / Horizen / Canary, 45-block confirmations) on Ethereum, Optimism, Arbitrum, Base, and Scroll. Mirrors the LayerZero-config portions of weETH 3CP-455/461. - script/SecurityUpgrade.s.sol: produces 5 ETHFI JSONs in ./output/ - addresses/lz-oft-config.json: full LZ-Endpoint / library / 4-DVN / controller-Safe config for the 5 ETHFI chains, cross-checked against the LayerZero metadata API - .gitignore: ignores ./output/ (batches are committed in 3CP-secure) Made-with: Cursor
Forking the live endpoint at script-run time and querying isDefaultSendLibrary / getReceiveLibrary lets us elide setSendLibrary and setReceiveLibrary calls that would otherwise revert with LZ_SameValue. After the audit, the only ETHFI peer still on the default library is the OP peer (eid 30111) on ethereum / arbitrum / base / scroll — every other peer is already custom-pinned, so those calls are dropped from the batch. Optimism's ETHFI is already fully pinned, so its batch collapses to just the two setConfig calls. Adds test/SecurityUpgradeSendSim.t.sol which forks every chain in scope, replays the per-chain Gnosis batch as the controller Safe, and asserts oft.send still succeeds afterwards (5 cases, all passing). The Adapter chains (ethereum, arbitrum, base, scroll) deal the underlying ERC20 to the sender and approve the OFT before sending. Made-with: Cursor
|
Added the post-upgrade send simulation requested in the parent PR. Forks ethereum / optimism / arbitrum / base / scroll, replays the ETHFI SecurityUpgrade Gnosis batch as the controller Safe, then calls The simulation also flagged a real bug — most ETHFI peers are already custom-pinned to the target SendUln302 / ReceiveUln302 today, so the original |
End-to-end test that, on a fork of every chain in scope: 1. Applies the COMBINED 3CP-secure Gnosis batch (the exact bytes signers will execute) via ../3CP-secure/queued/474/<batch>.json 2. Calls oft.send for every asset deployed on that chain (EURC + ETHFI on shared chains, ETHFI-only on arb / base) 3. Iterates every (oft, peer) route and asserts both isDefaultSendLibrary == false / getSendLibrary == target SendUln302 and getReceiveLibrary == (target ReceiveUln302, isDefault=false) Coverage: 8 send calls + 26 routes verified pinned across 5 chains. All passing. Adds ../3CP-secure read access to fs_permissions so the test can read the parent repo's combined batches directly. Made-with: Cursor
Summary
Adds the Forge script and LZ-config that generates the 5 Gnosis Safe batches used by 3CP-474 to harden the ETHFI OFT (
0xe0080d2F853ecDdbd81A643dC10DA075Df26fD3f) on Ethereum, Optimism, Arbitrum, Base and Scroll.For every peer EID on every chain, each batch:
setSendLibrary/setReceiveLibrary, andsetConfig(send + receive).This mirrors the LayerZero-config portions of weETH PR #74 (3CP-455 / 3CP-461) but without the
unpauseBridge/ rate-limiter calls, since ETHFI'sOFTUpgradeable/EtherfiOFTAdapterUpgradeabledoes not expose those entry-points.Files
script/SecurityUpgrade.s.sol(new) — emitsethfi-{ethereum,op,arbitrum,base,scroll}-SecurityUpgrade.jsonto./output/addresses/lz-oft-config.json(new) — full LZ-Endpoint / library / 4-DVN / controller-Safe config for the 5 ETHFI chains. All addresses cross-checked against the LayerZero metadata API (https://metadata.layerzero-api.com/v1/metadata/dvns?chainName=<chain>)..gitignore— ignores./output/(batches are committed in 3CP-secure).Per-chain summary
0x2aCA71020De61bb532008049e1Bd41E451aE8AdC0x764682c769CcB119349d92f1B63ee1c03d6AECFf0x0c6ca434756EeDF928a55EBeAf0019364B2797320x7a00657a45420044bc526B90Ad667aFfaee0A8680x3cD08f51D0EA86ac93368DE31822117cd70CECA3Each Safe is the OApp delegate on the LZ Endpoint (verified via
endpoint.delegates(oft)on each RPC).Reproduction
Hashes for the produced JSONs are then re-derived in
3CP-secureviabuild_multisend.sh+safe_hashes.sh --offline(see the companion 3CP-secure PR for the full hash table).Companion PRs
Made with Cursor