Omni Network / Omni Network


Omni’s goal is to make it easy for smart contract developers to source liquidity and users from anywhere. Our v1 release in scope for this competition consists of 2 primary building blocks: xchain messaging and an EVM. These building blocks are supported by 3 components that make up the Omni’s network architecture:

  1. Smart contracts on supported chains
  2. Cosmos sdk client (halo) which acts as our consensus client for xchain messaging and for the EVM
  3. Vanilla geth as the EVM execution client

Prize distribution and scoring

  • Total Prize Pool: $1,000,000

  • Primary Prize Pool: $975,000

  • The prize distribution has 2 possible triggers:

    • If one or more valid medium severity findings are found, the total pot size is $125,000
    • If one or more valid high severity findings are found, the total pot size is $1,000,000
  • $25,000 of the prize pot is reserved for Low Severity findings. These reports are judged based on quality and reviewers are then ranked from 1st to 5th for the purpose of prize allocation.

    • 1st: $10k
    • 2nd: $7.5k
    • 3rd: $5k
    • 4th: $1.25k
    • 5th: $1.25k
  • Scoring described in the competition scoring page.

  • Findings Severities described in detail on our docs page.

Early Submission Incentive

To make sure the Omni Network launch is completed on schedule, researchers are incentivized to submit High/Medium severity findings early, ie: as soon as one is found. The first valid submission will be rewarded an additional 20% reward, in comparison to its subsequent duplicates.

  • The finding must identify the root cause, highest valid impact and describe the finding with all the necessary details to consider it valid.
  • Please note that low quality or vague submissions or submissions that could be subject to interpretations will not be considered for the additional reward.
  • The escalation process will not apply for these rewards and there will be no discussion for these rewards. The decision made by the Judges/Omni network team on these rewards will be final.
  • Example: If a finding has 5 duplicates.
    • Using regular each of the duplicates would get $2000 each
    • With the current incentive of 20%. The earliest valid submission gets $2307.72, and the rest of the duplicates get $1923.07 each.

Documentation

Code Walkthrough

Scope

  • Repository: https://github.com/omni-network/omni

  • Commit: a782d51ad534f59ffaa20201f5711ee7ecb47e79

  • Total LOC: ~10k

  • Files:

    • contracts/core/src
      • octane
        • Preinstalls.sol
          • Slashing.sol
          • Staking.sol
          • Upgrade.sol
        • xchain
          • OmniPortal.sol
          • OmniPortalConstants.sol
          • OmniPortalStorage.sol
          • PortalRegistry.sol
        • Token
          • OmniBridgeCommon.sol
          • OmniBridgeL1.sol
          • OmniBridgeNative.sol
        • libraries
          • ConfLevel.sol
          • Predeploys.sol
          • Quorum.sol
          • XBlockMerkleProof.sol
          • XTypes.sol
        • utils
          • PausableUpgradeable.sol
      • Halo
        • NOTE: For all of these modules
          • INCLUDE: *.go
          • EXCLUDE: *_test.go, *.pulsar.go, *.pb.go
        • app
        • attest
        • evmslashing
        • evmstaking
        • evmupgrade
        • portal
        • registry
        • valsync
      • lib
        • cchain/
        • xchain/
      • Octane
        • NOTE:
          • INCLUDE: *.go
          • EXCLUDE: *_test.go, *.pulsar.go, *.pb.go
        • evmengine

Notes for researchers:

For Golang / Consensus Researchers

  • Cosmos SDK Wiring: integrating cosmos sdk modules into halo/app, and ensuring configuration is done correctly for critical modules
  • Valsync and light clients
    • The valsync module tracks validator set changes and propagates validator set updates to OmniPortal contracts on all supported chains in Omni
    • Each OmniPortal effectively runs a light client – it tracks the current (and last n) validator sets, and allows the current validator set to add new ones
    • It is critical that these validator set updates are propagated correctly
    • How does it do this? Well, the Portals already have a logical flow for confirming that a validator set has attested to some function call (XMsg). So the Omni Consensus chain uses the same logical flow – it packages the validator set update as an XMsg and sends it to each portal, which confirms that the validator set signed the XMsg containing the validator set update.
  • Octane EVM Engine
    • Octane is the cosmos sdk module that runs the consensus side of Ethereum’s EngineAPI
    • It is responsible for communicating with the execution client and building EVM payloads, see above
  • Attest module
    • This module watches omni portals for XMsgs (using lib/xchain), builds XBlocks, attests to them. It is the core logical component for cross-chain messaging.

For solidity researchers

  • OMNI bridge
    • The OMNI bridge (under contracts/core/src/token) has 2 components – a contract on Ethereum and a contract on Omni
    • Each contract holds significant funds – the OMNI ERC20 on Ethereum, and the native token on Omni.
  • xsubmit function
    • This function acts as the entrypoint for cross-chain calls. It must validate all XBlocks / XMsgs.
    • Correct validation of XBlocks and XMsgs is critical since if an invalid XBlock or XMsg can be submitted, the protocol is compromised.
  • sysxcalls (system xcall)
    • The Omni Consensus Chain produces xmsgs relayed to all portals, executed at each portal. We call these “sysxcalls”. These currently include setNetwork and addValidatorSet
    • It’s critical that this sysxcall mechanism cannot be hijacked.

For Both

  • XBlock data structure, merkle root, and merkle multi-proofs
    • Can an invalid XMsg be delivered?
  • Confirmation strategies
    • Omni's xchain message protocol currently offers 2 confirmation strategies. Developers can specify their confirmation strategy with each xcall.
    • Finalized xmsgs are attested to and delivered only after the rollup's transaction data containing this xmsg finalizes on Ethereum Layer 1. This requires 2 beacon chain epochs, which typically takes about 12 minutes. However, this strategy offers strong delivery guarantees – a delivered message can only be "reorg'd out" if Ethereum itself reorgs, which is highly unlikely and requires 2/3 of Ethereum's validators to be slashed.
    • Latest xmsgs are attested to and delivered as soon as the transaction with the xmsg is included by the L2 sequencer in a block. This provides a much lower latency for message delivery – roughly 5-10s. However, it does come with an associated risk: the xmsg has a higher risk of being reorg'd out if the L2 sequencer misbehaves or fails. This may result in unintended consequences, and you should decide how much you're willing to trust L2 sequencers

Build Instructions

This README includes instructions for test harnesses. Each harness has a description.

Out of scope

Known Issues:

  • The validator set is whitelisted in the V1 release. Validator actions are limited – there are no withdrawals, staking rewards, or delegations. It is assumed that there is always ⅔ quorum of honest validators.
  • Blobs vs Calldata
    • FeeOracleV1/V2 is currently out of scope, as it does not currently take into account rollups that use blobs or non-EVM DA services.
  • RANDAO opcode
    • Random attribute of the EVM payload is a predictable hash of the latest block.
    • This should be an actual random value. This will be implemented in a future release.
  • Gas price oracles
    • The gas prices stored in FeeOracleV1 are lagging and also might not accurately represent the gas prices at execution time.
    • Some xcalls may be "underpaid", though it's also true that some will be "overpaid", at an roughly equal rate.
  • Stale streams
    • Context
      • Portals require that an XSubmission includes a validator set within the last 10 validator set IDs.
      • Validator set ID changes each time there is a new validator, a validator leaves, or an (un)delegation.
      • Note that this will happen infrequently in v1, since the validator set is whitelisted, and delegations are not yet enabled.
      • The relayer is an off chain component with a “1 of n” security model.
    • Risk:
      • If an XBlock B was signed by validator set V, AND
      • There were >10 validator set changes such that the current set if V+10 or greater, AND
      • The relayer failed to submit XBlock B to its destination by the time V+10 is active on the destination portal, THEN
      • the XStream will stall – because the submission will be using validator set V, and that is not within the last 10 validator sets
  • Fee refunds
    • Each xcall checks that the user pays enough fees based on the destChainId, the data used in the xcall, and the gasLimit. While a user may accidentally or intentionally pay more than this required amount in the true execution on the destination, any excess payment will not be refunded.
    • Fee refunds are desirable, but will are out of scope for v1.0
  • RPC Endpoints
    • Each validator runs full nodes for each integrated chain. Each validator trusts their RPC endpoints to return valid data.
  • Retry Mechanism
    • A “retry mechanism” is a way to retry a cross-chain message if it fails.
    • An in-protocol retry mechanism for failed cross-chain messages is out of scope for V1.
    • This can be built out-of-protocol in the short term. But likely will be added to the protocol medium-term.
  • Overfilling EVM Blocks
    • In CometBFT, the PrepareProposal() function sets a limit on the maximum number of bytes that are allowed to fit in a proposed block. However, Halo is not allowed to remove any transactions from the proposed block if this limit is exceeded. If a Halo block were to exceed this limit, the chain would simply halt.
    • In practice, this can never happen. The maximum amount of gas in an EVM block is 30,000,000. The largest block possible when constrained by gas is a block filled with 0's. This results in a maximum block of 7,500,000 bytes, or 15,000,000 bytes when hex encoded in the EngineAPI.
    • Since cmttypes.MaxBlockSizeBytes*9/10 evaluates to roughly 94 MB, it is impossible for a 15 MB maximum block size to ever exceed this.
  • Bridge pausing
    • When a user calls bridge() to bridge OMNI tokens, an XMsg is sent to the destination chain to call the destination chain bridge’s withdraw() function. However, if the withdraw function is paused on the destination chain after the XMsg is emitted, the XMsg will fail to be executed on the destination.
    • Deposits will always be paused before withdrawals (withdrawals will only be paused if users are able to withdraw without correct validation)
  • XMsg Ordering
    • We rely on xmsgs being ordered by log index (ascending) to build the xblock merkle tree. This implicitly orders xmsgs by offset per shard. Order by log index is currently not enforced when constructing the xblock merkle tree. We have an open PR to enforce that ordering.
    • Note that portal xsubmission test utilities sort xmsgs per xblock by dest chain / offset.
  • Syscall authorization
    • Syscalls are xmsgs to the VirtualPortalAddress. Currently, the only allowed system xcalls come from consensus chain xmsgs broadcasted to each portal. Verification in the portal contracts does not enforce xmsgs to the VirtualPortalAddress are broadcast from the consensus chain. This allows for more flexible syscalls, but as we do not yet need them, we plan to enforce more strict validation for syscalls.
  • Prior Audits

Contact Us

For any issues or concerns regarding this competition, please reach out to the Cantina core team through the Cantina Discord.

Summary

Status

Completed

Total reward:

$1,000,000

Findings submitted:

780

Start date:

14 Oct 2024 8:00pm (local time)

End date:

4 Nov 2024 8:00pm (local time)