chore(deploy): add ReceiverOIF v1.0.0 on 8 chains (EXSC-684) - #2136
chore(deploy): add ReceiverOIF v1.0.0 on 8 chains (EXSC-684)#21360xDEnYO wants to merge 7 commits into
Conversation
Deploys ReceiverOIF v1.0.0 to arc, bsc, megaeth, optimism, pharos, polygon and robinhood, so the facet-required-periphery invariant from #2125 has a receiver to find wherever an intent-escrow facet is live. Also adds the two pieces of framework config the rollout needed: a ReceiverOIF entry in deployRequirements.json (constructor-arg validation) and ReceiverOIF 1.0.0 in _targetState.json for the target chains plus mainnet/base/arbitrum, which had it deployed but never declared. jovay is excluded: neither OIF settler has code there, so the contract cannot be deployed. katana is pending a deployer top-up. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 38 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (14)
WalkthroughAdds ReceiverOIF deployment requirements, production facet mappings, and network deployment addresses. Katana’s configuration also gains a gas estimate multiplier and expanded deployment notes. ChangesReceiverOIF deployment configuration
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
katana's deploy failed forge's pre-flight balance check: the pinned 3 gwei gasPrice combined with the repo-wide GAS_ESTIMATE_MULTIPLIER=500 made forge reserve 5,023,370 gas x 3 gwei (0.01507 ETH) against a 0.01006 ETH balance, for a deploy whose real cost is ~918k gas (~0.0000009 ETH at the 0.001 gwei live base fee). Sets katana's gasEstimateMultiplier to 200 rather than touching the gasPrice pin, which is a deliberate documented workaround for the RPC over-reporting eth_gasPrice. 200 keeps a 2x buffer on the gas limit and is fundable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@config/networks.json`:
- Line 664: Update the devNotes entry for this network to accurately describe
the gas estimate multiplier used by deploySingleContract.sh: explain the source
of 500 if it is applied elsewhere, or replace that value with the script’s
default of 130 and mention GAS_ESTIMATE_MULTIPLIER only when relevant. Keep the
guidance about the 3 gwei gas price and 200 buffer consistent with the corrected
multiplier details.
- Line 663: Rename the networks configuration key from gasEstimateMultiplier to
gas_estimate_multiplier, preserving its current value. Ensure the configuration
contains only the snake_case key and no duplicate legacy or overlapping
multiplier entry; leave deploySingleContract.sh unchanged so its legacy lookup
can be updated separately.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 92d7418c-b3b3-4807-b848-5b028067bc41
📒 Files selected for processing (11)
config/networks.jsondeployments/arc.jsondeployments/bsc.jsondeployments/katana.jsondeployments/megaeth.jsondeployments/optimism.jsondeployments/pharos.jsondeployments/polygon.jsondeployments/robinhood.jsonscript/deploy/_targetState.jsonscript/deploy/resources/deployRequirements.json
…684) The note claimed 500 was the repo-wide multiplier; .env.example ships 130, so 500 was the local operator value. Restates the reserve as scaling with whatever GAS_ESTIMATE_MULTIPLIER the operator's .env carries, which is the actual reason the per-network pin makes the reserve deterministic. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e (EXSC-684) The override existed only to get katana's ReceiverOIF deploy past forge's pre-flight gas reserve; the deploy and its Safe proposal are complete, so the override is no longer load-bearing. config/networks.json returns to main. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…0 cut execution [EXSC-685] Registration + allowlist timelock ops executed on-chain (safeTxHash 0xfe8aa8c8…, 0x1c3bb518…). Regenerated from on-chain state; robinhood also shows ReceiverOIF from the sibling rollout #2136 (both now live on the diamond). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… chains (EXSC-684) diamondUpdatePeriphery timelock ops executed on-chain for arc, bsc, katana, megaeth, optimism, pharos, polygon, robinhood. Registry entries regenerated and scoped to ReceiverOIF only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the ReceiverOIF entry that on-chain regeneration pulled in; it belongs to the sibling rollout #2136. Keeps this PR consistent with its own flat log + whitelist (address-consistency gate). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ler-e4cd5a # Conflicts: # script/deploy/_targetState.json
) * chore(deploy): add OutputValidator v1.0.0 on robinhood * chore(deploy): sync robinhood diamond log after OutputValidator v1.0.0 cut execution [EXSC-685] Registration + allowlist timelock ops executed on-chain (safeTxHash 0xfe8aa8c8…, 0x1c3bb518…). Regenerated from on-chain state; robinhood also shows ReceiverOIF from the sibling rollout #2136 (both now live on the diamond). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
🔍 QA Review — EXSC-684 — PR #2136Ticket: EXSC-684 — Couple facets to their companion periphery contracts so a Receiver can't be silently forgotten What This PR DoesDeploys
Also updates Code Review
All three
Process Notes
Ticket CoverageRating: Partial (companion deployment — completes EXSC-684 alongside PR #2125) ✅ Verdict: Pass Deployment configuration is correct, consistently structured, and approved by SC core dev. QA review by lifi-qa-agent[bot] · Run #26 · 2026-07-29 |
There was a problem hiding this comment.
✅ QA approved. ReceiverOIF v1.0.0 deployment configuration is correct: constructor parameters reference the correct config keys, all allowToDeployWithZeroAddress=false, targetState entries consistent. SC core dev approved. (lifi-qa-agent Run #26)
…ler-e4cd5a Resolves deployments/robinhood.json conflict by keeping both ReceiverOIF (this branch) and OutputValidator (main, #2132). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8ed677e
Which Linear task belongs to this PR?
EXSC-684 (origin: #2125 — the
facet-required-peripheryhealth-check invariant).No dedicated sub-ticket was created: the Linear connector is not authorised in the
session that produced this PR. Happy to split one out if you'd rather not hang this
off EXSC-684.
Why did I implement it this way?
#2125 adds a
facet-required-peripheryinvariant requiringReceiverOIFon everychain running an intent-escrow facet. Before this PR it was live only on
mainnet,baseandarbitrum, so the daily sweep would go red on every other such chain themoment #2125 merges. This deploys it and adds the two missing pieces of framework
config it needed.
Deployed (production)
ReceiverOIFv1.0.0 on 8 chains. Each registration is a timelock-wrappeddiamondUpdatePeripherySafe proposal carrying one signature.
0xEbf54fFDdAF89518DF79EC2F6b786a21b502Db4A0xf6eB75d27ef8eAE08A5917fB3E1C35E2c64398c60xd47D8866848bcb6eE610E5f24f9d4Af48d6CbDcE0x6115D73bC128f5327a8939794FE12B60731e5D200xf6eB75d27ef8eAE08A5917fB3E1C35E2c64398c60xEbf54fFDdAF89518DF79EC2F6b786a21b502Db4A0xf6eB75d27ef8eAE08A5917fB3E1C35E2c64398c60xdD54bEa53F94554d632d0D844D88a4fd51b2C576Each deployment was checked on chain:
EXECUTOR()equals that chain's deployedExecutor,owner()equalsglobal.json .refundWallet, andOUTPUT_SETTLER()equals
lifiintentescrow.json .OIFOutputSettlerSimple. The production<chain>.diamond.jsonregistries update only once the timelock ops execute, so theyare deliberately not touched here.
Framework config added
deployRequirements.jsonhad noReceiverOIFentry, so the framework could notvalidate its constructor args. Added one modelled on
ReceiverChainflip/ReceiverAcrossV4:_ownerfromglobal.json .refundWallet,_outputSettlerfromlifiintentescrow.json .OIFOutputSettlerSimple(a flat key, following the existingLiFiIntentEscrowFacetV2._inputSettlerprecedent), andExecutoras acontractAddressesdependency._targetState.jsonnow lists"ReceiverOIF": "1.0.0"for the eight targetchains plus
mainnet,baseandarbitrum— those three have had it deployed fora while but were never declared, so the file was already understating reality.
ReceiverOIFis deliberately not added tocorePeripheryorwhitelistPeripheryFunctions: receivers call the Executor rather than being called bythe diamond, same as every other
Receiver*, so no allowlist sync is involved.katananote (no config change in this PR)katanafirst failed forge's pre-flight balance check, not for lack of funds. It isthe only network pinning a
gasPrice(3 gwei, a deliberate workaround in itsdevNotesbecause its RPC over-reportseth_gasPrice), so forge reservesgasLimit × 3 gweiup front and the reserve scales with whateverGAS_ESTIMATE_MULTIPLIERthe operator's.envcarries..env.exampleships130;this rollout ran on a machine carrying
500, which reserved5,023,370 gas × 3 gwei = 0.01507011 ETHagainst a 0.010063015677188902 ETH balance —for a deploy whose measured cost is 918,183 gas, i.e. ~0.0000009 ETH at katana's live
0.001 gwei base fee.
A temporary
katana.gasEstimateMultiplieroverride got the deploy through and hasbeen reverted —
config/networks.jsonis untouched by this PR. An operator on thedocumented
130would not hit this at all.Two things this surfaced, both left for separate tickets rather than widening a deploy
PR: katana has now hit this twice (also in #2108 on 22 Jul), so it recurs for anyone
running a high local multiplier; and the 3 gwei pin's premise has drifted badly — the
devNotesdescribes real txs at 1–4 gwei, but katana's base fee is now 0.001 gwei, sothe pin overpays roughly 3000×.
One chain is not in the table
jovay— dropped, and it is a finding in its own right. Both OIF settlers haveno code there:
OIFOutputSettlerSimple(
0x0000000000eC36B683C2E6AC89e9A75989C22a2e) andlifiEscrowInputSettler(
0x000025c3226C00B2Cdc200005a1600509f4e00C0). Both are real contracts elsewhere —cast codereturns 5,374 and 17,570 bytes respectively on every other chain checked(mainnet, base, arbitrum, optimism, polygon, katana, megaeth, pharos, robinhood, arc,
bsc) and exactly
0xonjovay, the same as a plain EOA. The addresses aredeterministic but the contracts were never deployed there, so
DeployReceiverOIFaborts with
.OIFOutputSettlerSimple … is not a contract.jovaynonetheless has bothLiFiIntentEscrowFacetandLiFiIntentEscrowFacetV2registered on chain — pointingat settlers that do not exist.
ReceiverOIFis therefore left out ofjovay'starget state, and the new invariant will flag
jovayuntil either the settlers shipthere or the escrow facets come off.
Explorer verification
Verified on all chains except
arc.explorer.arc.io/apisits behind a CircleCloudflare Access login wall, so no API key helps, and Sourcify does not support chain
5042 — this is a standing arc-wide explorer limitation rather than anything specific to
ReceiverOIF. Shipping it unverified and tracking it; it can be redone wheneversomeone with Circle Cloudflare Access is available.
(
megaethinitially failed too — Blockscout reported "Address is not asmart-contract" for an address that demonstrably had code. That was indexer lag; it
verified cleanly on retry.)
Checklist before requesting a review
Checklist for reviewer (DO NOT DEPLOY and contracts BEFORE CHECKING THIS!!!)