Nomad series: Generalized message passing with optimistic verification using Nomad and Connext
What is Nomad?
Nomad is a security-first cross-chain message passing protocol. Nomad focus on security rather than speed. Nomad utilizes optimistic verification, which is well battle-tested, and fundamental innovation in security. In contrast, Axelar, LayerZero, and many other cross-chain message passing protocols choose to develop their consensus, which uses external verification and requires higher trust assumptions. Custom consensus may have some critical vulnerabilities that hackers can use to steal all funds from the bridge. Bridges nowadays are widely hacked due to vulnerabilities.
Why is Nomad security first?
Nomad is security first because it adopts an optimistic verification mechanism that only requires a single honest watcher to prevent fraud (as opposed to externally verified bridges that the coordination of dishonest watchers can hack). Moreover, Nomad also sacrificed speed, which is an essential requirement in most DApps for security.
Nomad’s optimistic verification is battle tested because it has been audited by Quantstamp and is inspired by popular protocol designs, including Optimism and Arbitrum chains that have billions in TVL. These chains have been running for years and never got hacked.
Nomad is security first but why it still get hacked?
Nomad is not getting hacked due to its optimistic verification mechanism. It is getting hacked due to a human error in initializing the Merkle tree root as 0x0000…0000 while upgrading the Replica contract. 0x0000…0000 or bytes32(0) is a unique value representing something invalid or hasn’t been initialized. This breaks the optimistic verification mechanism by allowing every message, including the malicious one, to be executed without validation.
If the initial Merkle tree root is initialized as the last valid Merkle tree root before upgrading the contract, or Nomad is using a better way to upgrade contract logic by preserving the storage, such as an upgradeable proxy. The optimistic verification will run as usual, and this incident may never happen.
Read more detail here: https://twitter.com/samczsun/status/1554252024723546112.
What is the downside of Nomad?
The main downside of Nomad is speed. Once you transfer a message from the source chain, you must wait 30 minutes before executing the message on the destination chain. This characteristic of Optimistic verification requires some waiting period for the external verifier to submit the fraud-proof. The message is approved if an external verifier does not submit fraud proof within 30 minutes.
Connext, a significant integrator using Nomad, is introducing an Amarok upgrade to provide a fast liquidity route for their bridge to solve these problems. The fast liquidity route only takes 3 minutes rather than 30–60 minutes to bridge assets cross-chain. We will discuss the Amarok upgrade in the next blog.
Why 30 minutes waiting time for Nomad and Connext?
Because Nomad uses an Optimistic verification mechanism to verify cross-chain messages, these optimistic verifications will assume that the transactions submitted by the sequencer are all valid after a while without any further check. However, optimistic verification transactions won’t be approved until a period called a fraud-proof window is passed. During the fraud-proof window, any external validator can submit fraud proof to the destination chain to revert the latest batch of transactions that aren’t approved yet. Nomad has a 30 minutes fraud-proof window.
Connext is using Nomad as its infrastructure. Connext enables trustlessly sending value and calling contracts across chains & L2s. Unlike Nomad, Connext does not allow for fully generalized communication, but it does have much lower latency (typically 2 minutes). Additionally, Connext doesn’t mint tokens on a destination chain — instead, it relies on liquidity minted by other bridging systems like Nomad, thus absorbing their trust/risk assumptions.
How does optimistic verification work?
In optimistic verification, we have a Sequencer and a set of external verifiers. A sequencer is a centralized transaction processor responsible for picking transactions from the source chain, packing it together into a batch, and then generating a Merkle tree root to be submitted into the destination chain. A set of external verifiers monitor the sequencer behavior if the sequencer is offering malicious transactions to the destination chain.
Once a message has been submitted into the source chain. An event will be emitted, and the sequencer will periodically gather these events and put them into a batch. Then the sequencer will calculate a new Merkle root using the previous Merkle root and the batched events. After that, the fresh Merkle root is submitted into the destination chain but isn’t approved yet. Once a 30 minutes fraud-proof window has been passed, these transactions will be approved automatically.
In parallel, external verifiers also do the sequencer’s job by listening to the destination chain for the new Merkle root submitted by the sequencer. After that, external verifiers will gather events up to the latest block the sequencer collected, put it into a batch, and calculate the Merkle root the same way the sequencer does. If the Merkle root is the same as the one that is submitted into the destination chain, the verifier will do nothing. But if it is different, fraud-proof will be generated and submitted to the destination chain. The fraud-proof is used to replay transactions on-chain, which consume a lot of gas but cannot be cheated. However, the chance that a fraudulent transaction is found is almost zero since the sequencer is centralized, designed not to submit any fraudulent transactions, and it isn’t economically feasible to steal money with fraudulent transactions.
You can find an example implementation of a verifier at https://github.com/ethereum-optimism/cannon, which is an on-chain interactive dispute engine implementing EVM-equivalent fault proofs designed for the Optimism chain.
Data availability problem in optimistic verification
To generate a new Merkle root and fraud-proof, we must have a chunk of raw data available to calculate the fresh Merkle root. Luckily, Nomad always has data available by fetching from a source chain’s archive node.
But in some situations, we may not have data available. Celestia is here to help solve this problem. Celestia is also developing Optimint, an ABCI-client implementation for Optimistic Rollups that we will discuss in the future.
Blockchain trilemma of Nomad’s optimistic verification
The intermediate party that verifies the cross-chain transactions can also be viewed as a blockchain. Many cross-chain message passing providers create their blockchains to verify these transactions. In the Nomad case, optimistic verification is used as the verification mechanism. Optimistic verification uses a centralized sequencer that lacks decentralization while providing security and scalability. However, safety comes with the cost of speed.
The interoperability trilemma of Nomad
Generalizable: Nomad can send and receive arbitrary messages, so Nomad is generalizable.
Trustless: Nomad is completely trustless due to the optimistic verification mechanism. However, the trustless property of Nomad comes at the cost of excessive delay.
Extensible: To expand Nomad to other ecosystems, such as Cosmos, Nomad needs to reimplement the fraud-proof mechanism in the new ecosystem. Thus, Nomad is not extensible!
How does Nomad work when passing cross-chain messages?
- Smart contract in the source chain call dispatch function in the Home contract.
- The message will be hashed and added to the Merkle tree in the source chain.
- The Home contract emits events with messageHash, leafIndex, destinationAndNonce, committedRoot, and message information.
- The sequencer will listen to these events and pack them into a batch.
- Sequencer calculates a new Merkle root using old Merkle root and batched events.
- Sequencer submits the old and new Merkle root to the Replica contract in the destination chain through the update function.
- Wait for a 30 minutes fraud-proof window. External verifiers can submit fraud proof in this window to reject the transactions.
- After a 30 minutes fraud-proof window has been passed, transactions will automatically be approved.
- A relayer executes the proveAndProcess function in the Replica contract to perform the message in the destination chain.
You can find an example of how to send messages cross-chain at https://docs.nomad.xyz/developers/quickstart/send-messages.
The source code of the Home contract can be found at https://github.com/nomad-xyz/monorepo/blob/main/packages/contracts-core/contracts/Home.sol.
The source code of the Replica contract can be found at https://github.com/nomad-xyz/monorepo/blob/main/packages/contracts-core/contracts/Replica.sol.
How does Nomad work when bridging assets?
- User call sends function in BridgeRouter contract.
- Token will be locked in the BridgeRouter contract.
- A cross-chain message is created in the BridgeRouter contract.
- The BridgeRouter contract propagates this message to the Home contract.
- Perform the above cross-chain message passing flow.
- Nomad relayer execute handle function in the BridgeRouter contract.
- A wrapped token is minted on the destination chain and sent to the recipient.
Lock-and-Mint Mechanism
The BridgeRouter enforces the following strict invariant: The amount locked on the chain where the token originates must always be equal to the circulation of representational tokens minted on all destination chains.
You can see this in the codebase here:
- Sending side: https://github.com/nomad-xyz/monorepo/blob/main/packages/contracts-bridge/contracts/BridgeRouter.sol#L149
- Receiving side: https://github.com/nomad-xyz/monorepo/blob/main/packages/contracts-bridge/contracts/BridgeRouter.sol#L278
The Pros and Cons of lock-and-mint bridge
Lock-and-mint bridges usually have a wide range of token support but lack liquidity. Minted-wrapped tokens unlocked on the destination chain typically don’t have any LP provided with the real one. So, it cannot be swapped into the real one; thus, it’s worthless.
Connext is here to solve this problem. Stay tuned for the next blog!