Documentation menu

Security model

Immutability

The bridges and the representation implementations are direct, immutable deployments. There are no UUPS proxies, no beacon proxies, no upgrade scripts, and no way to change deployed code. Representations are OpenZeppelin clones initialized exactly once by their local bridge.

If a deployment were ever found faulty, the only remedy is deploying a new contract set and updating frontends and indexers to that new set. Existing contracts and already-set peers cannot be mutated.

What the owner can and cannot do

The bridge owner (intended to be a multisig after setup) controls operational configuration only:

Owner canOwner cannot
Set each LayerZero peer once (setPeer)Upgrade bridge or representation code
Set the LayerZero delegateMint, burn, or move user tokens
Adjust the fixed protocol feesBlock a specific token or user (the bridge is permissionless)
Adjust minTransferGas / minCreationGas floorsWithdraw locked originals
Withdraw collected protocol feesReach into lockedBalance

Fee withdrawal functions operate on fee accounting (collectedProtocolFees, collectedFeeTokenProtocolFees), which is tracked separately from locked token balances.

Peer setup is one-way

The single most sensitive owner power - pointing the bridge at a remote peer - is constrained on-chain:

  • setPeer can initialize an unset endpoint ID with a nonzero peer. After that, the same peer is a no-op, while clearing it or replacing it with a different peer reverts.
  • A first-time peer at the bridge's own CREATE3 address (the only legitimate Omnisea deployment on any chain) becomes trusted immediately.
  • A first-time peer at any other address only becomes trusted after a 7-day activation delay (endpointActivationTime = 7 days). Until then isTrustedPeer is false and its messages are rejected.

Anyone can verify this live on either bridge: peers(eid) returns the configured peer, peerSetAt(eid) records when it was first set, peerActivationTime(eid) returns when it activates, and isPeerActive(eid) tells you whether the route is currently trusted. A compromised owner key cannot redirect an already configured message channel. For new unset routes, any non-CREATE3 peer still has a 7-day public activation window.

Message verification (LayerZero V2)

Every transfer is a LayerZero V2 message:

  • Peers. Each bridge only accepts messages whose sender is the configured and active peer for the source endpoint ID. Peers are immutable once set. Same-address CREATE3 peers are active immediately; first-time peers at different addresses enter a 7-day activation delay before they are trusted. Anything else reverts with InvalidPeer.
  • DVNs. Each directed route is verified by configured Decentralized Verifier Networks before the message becomes executable. Routes launch with a required LayerZero Labs DVN, with a hardening path to three independent required DVNs (LayerZero Labs, Nethermind, Canary) for production scale.
  • Executor. The LayerZero executor delivers the message with the gas the sender purchased via options. Execution gas floors (minTransferGas, minCreationGas) are enforced at send time and restore time so messages cannot be sent with unexecutable gas.
  • Endpoint-only entry. lzReceive is callable only by the LayerZero endpoint (onlyEndpoint), and allowInitializePath only admits active trusted peers.

Failure containment

Destination-side execution failures do not strand the LayerZero channel:

  • Endpoint, inactive/untrusted peer, and payload-decode failures revert outright (and are surfaced by LayerZero's own retry machinery). If a message arrives during a peer activation delay, it is not cached in failedMessages; LayerZero can retry it after the peer becomes active.
  • Trusted transfer messages that fail during execution (e.g. a hook that reverts, an exotic token edge case) are cached as failedMessages(guid) and emit MessageFailed. Anyone can retry or restore them - there is no admin gate on recovery.
  • Restore messages that fail on the source are intentionally not cached, preserving LayerZero's native retry and preventing restore loops.

Reentrancy and token edge cases

  • All send paths and recovery paths are nonReentrant.
  • ERC-20 locking measures balance deltas, so fee-on-transfer tokens credit what actually arrived; zero-delta transfers revert with InvalidAmount.
  • Rebasing, reflection, blacklist, pausable, or admin-blocked transfer tokens are unsupported. Balance-delta accounting does not protect against later supply/balance mutations or outbound transfers that an external token admin can block, so these assets can redeem less than expected or fail during retry/restore.
  • Token metadata reads (name, symbol, decimals, contractURI, owner) are defensive: assets that do not implement them still bridge, with sensible defaults (e.g. 18 decimals).

Audit status

Feedback