Skip to content

Make ERC7786OpenBridge tolerant to failing gateways#251

Open
Amxx wants to merge 2 commits into
masterfrom
erc7786-bridge-gateway-resilience
Open

Make ERC7786OpenBridge tolerant to failing gateways#251
Amxx wants to merge 2 commits into
masterfrom
erc7786-bridge-gateway-resilience

Conversation

@Amxx

@Amxx Amxx commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Fixes https://audits.openzeppelin.com/openzeppelin-solidity/project/openzeppelin-community-contracts/e2bb51d8-df7a-4d26-934a-be65c637d4e5/issue/any-single-gateway-revert-blocks-sendmessage-for-all-gateways

Summary

Makes ERC7786OpenBridge resilient to individual gateway failures on the source side, so a single misbehaving gateway can no longer block a message that can still satisfy the N-of-M threshold.

Changes

  • sendMessage: each gateway.sendMessage is now wrapped in try/catch. A reverting gateway no longer aborts the whole send; instead the loop continues with the others. After the loop, the call requires at least getThreshold() successful sends (ERC7786OpenBridgeInsufficientGateways otherwise).
  • ERC7786OpenBridgeSendMessageFailed(address indexed gateway): new event emitted for each gateway whose sendMessage reverts, for observability.
  • _addGateway: rejects non-contract addresses (ERC7786OpenBridgeGatewayNotAContract), covering both the constructor and addGateway.
  • The gateway-posting locals are scoped in a block to avoid a stack-too-deep (the project compiles without viaIR).

Tests

  • New gateway resilience test: two synchronous gateways, threshold 1, one gateway set to revert on send — asserts the message is still delivered through the healthy gateway and that ERC7786OpenBridgeSendMessageFailed is emitted for the failing one.
  • Updated the bad return value / EOA recipient cases: under the synchronous mock, the destination revert is now caught on the send side, so they revert with ERC7786OpenBridgeInsufficientGateways.
  • ERC7786GatewayMock gains a setRevertOnSent toggle to drive the resilience test.

All tests pass; prettier / eslint / solhint clean.

Summary by CodeRabbit

  • New Features
    • Cross-chain messages can now succeed when some gateways fail, provided the configured delivery threshold is met.
    • Failed gateway attempts are reported through a dedicated event.
  • Bug Fixes
    • Gateway registration now rejects addresses that are not deployed contracts.
    • A single unresponsive or reverting gateway no longer automatically prevents message delivery through other available gateways.

Amxx added 2 commits July 17, 2026 14:38
Wrap each gateway sendMessage in try/catch so a single failing gateway
does not block the others, and require at least the threshold number of
successful sends. Also reject non-contract gateways in _addGateway.
Emit ERC7786OpenBridgeSendMessageFailed when a gateway's sendMessage
reverts, and add a test covering delivery through a healthy gateway when
another one reverts and the threshold is still met.
@Amxx
Amxx requested a review from a team as a code owner July 17, 2026 12:48
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

OpenBridge now tolerates individual gateway send failures, emits failure events, enforces successful gateway thresholds, rejects non-contract gateways, and adds mock controls and tests for resilient delivery.

Changes

Gateway resilience

Layer / File(s) Summary
Resilient gateway submission and validation
contracts/crosschain/ERC7786OpenBridge.sol
Gateway calls are wrapped in try/catch, failures emit an event, successful sends are counted against the threshold, and non-contract gateways are rejected.
Configurable failure mock and resilience coverage
contracts/mocks/crosschain/ERC7786GatewayMock.sol, test/crosschain/ERC7786OpenBridge.test.js
The mock can force send failures, while tests cover threshold errors and successful delivery through a remaining gateway.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Sender
  participant OpenBridge
  participant FailingGateway
  participant WorkingGateway
  participant Destination
  Sender->>OpenBridge: sendMessage
  OpenBridge->>FailingGateway: sendMessage
  FailingGateway-->>OpenBridge: revert
  OpenBridge-->>Sender: failure event
  OpenBridge->>WorkingGateway: sendMessage
  WorkingGateway->>Destination: deliver message
  WorkingGateway-->>OpenBridge: message ID
  OpenBridge-->>Sender: successful delivery events
Loading

Poem

A bunny watched one gateway fail,
Yet another carried the message trail.
“Catch that error, count the cheer—
The bridge still hops its payload here!” 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: ERC7786OpenBridge now tolerates failing gateways.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch erc7786-bridge-gateway-resilience

Comment @coderabbitai help to get the list of available commands.

@Amxx Amxx added this to the audit milestone Jul 17, 2026
@Amxx
Amxx requested a review from ernestognw July 17, 2026 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant