Cross-chain bridges
A bridge moves value or messages between chains. The hardest engineering question is: how does chain A know that something happened on chain B?
Trusted-validator models put that responsibility on a small federation. Light- client models put it on cryptographic state proofs. Optimistic oracle models put it on an economic game — anyone can claim "this transaction confirmed on chain B", and unless someone disputes within a window, the claim is accepted.
OMY's optimistic oracle is well-suited for this. The bridge consumer asks "did tx 0xabc...123 finalize on chain X by block Y?"; an asserter proposes yes or no; the bridge releases (or refunds) on the oracle's answer.
The integration shape
User → bridge contract on TON
│
│ deposits USDT, requests withdrawal to chain X
│
▼
Bridge state: PendingWithdraw
│
│ user (or relayer) executes the matching tx on chain X
│
▼
Bridge.RequestAttestation → OMY
│ (question: "did tx 0xabc on chain X confirm at block ≥ Y?")
│
▼
OMY Assertion lifecycle
│ (propose YES with bond, no dispute, finalize)
│
▼
Bridge ◄── OracleResult{questionId, answer=true}
│
▼
Bridge.Settle — releases funds / acknowledges receipt
The bridge contract pays the oracle's bond from its own treasury (recoverable on resolution). The proposer can be a relayer bot that watches for finalized remote txs and proposes YES with a small bond. The dispute path catches anyone who tries to claim a fake confirmation.
Why optimistic vs light client
| Optimistic | Light client | |
|---|---|---|
| Verifies | Economic incentives via bond | Cryptographic state proof |
| Cost per query | ~$0 in common case | High (proof verification gas) |
| Sub-block freshness | No (liveness window) | Yes |
| Works for chains without verifiable proofs | Yes | No |
| Setup cost | One contract, two roles | Custom per-chain proof verifier |
Optimistic is the right model when the chain you're bridging from is hard to prove (non-EVM, custom consensus) or when query volume is low enough that the light-client overhead isn't worth it.
For pure EVM-to-EVM with high query volume, a light client may win on cost. OMY is the better fit when:
- You're bridging from / to TON (no production light client for TON in either direction yet)
- You're bridging from a chain where proofs are expensive (e.g., zk-rollups with proof-aggregation latency)
- You're bridging arbitrary messages, not just token balance changes
Bond sizing for bridges
Bonds should be sized to the largest single payout the attacker could extract from a successful lie, not to TVL average. A bridge moving $1M quickly per day with $10M TVL still needs a bond large enough to deter someone from stealing $1M in a single attack.
A conservative formula:
bond = max(min_bond, 10% × max_single_withdrawal)
For a bridge with max_single_withdrawal = 100 000 USDT, bond = 10 000 USDT
(at the cap). This is the upper end of OMY's MAX_BOND_CAP — beyond which
security has to come from the resolver, not the bond.
Anti-spoof on the result
This matters more for bridges than any other use case. The bridge contract
must verify the OracleResult came from the assertion it bound, not just
any contract claiming to be one:
OracleResult => {
assert (in.senderAddress == state.boundAssertion!) throw Err.NotOurOracle;
// safe to settle
}
Without this check, an attacker deploys their own contract with the same
opcode + body shape, points it at the bridge, and triggers a fake "confirmed"
result. Same defense applies to your AssertionCreated callback — verify the
sender is the OracleFactory you registered.
What about bridges going INTO TON?
The flow is symmetric. A remote chain's bridge attests "X USDT was locked at this address on chain B"; OMY verifies it; the TON-side bridge mints the wrapped representation. Same lifecycle, same dispute path.
Integration checklist
import {DocFeatures, DocFeature} from '@site/src/components/docs/DocFeatures';
sender == boundAssertion. The single most important
bridge check.