回退

ZetaChain’s New Revert Handling for Cross-Chain

Apr 11, 2025

ZetaChain Dev Team

ZetaChain’s new onAbort mechanism prevents stuck assets in cross-chain transactions. With onRevert for rollbacks and onAbort as a failsafe, every transaction is either executed or accounted for — ensuring seamless failure recovery without manual intervention. Learn more here.

Why Reverts Matter in Cross-Chain Transactions

If you’ve ever interacted with a smart contract and seen your transaction fail, you’ve likely encountered a “revert.” A revert occurs when a contract refuses to execute a transaction, undoing any changes and returning an error.

While it’s not an ideal scenario, reverts are a built-in safety feature that ensures only valid transactions are processed. They effectively roll back all changes made to the state during the transaction, helping prevent unintended effects or harmful actions.

But handling reverts in cross-chain applications is far more complex than on a single chain. If a failure occurs on one blockchain, it can cause ripple effects that impact other parts of the application. Without proper handling, assets can get stranded, smart contract logic can break, and users can be left in a frustrating state of uncertainty.

The Challenge: Why Cross-Chain Reverts Are Hard

In a single-chain smart contract, revert handling is straightforward: the transaction fails, and all state changes are rolled back automatically. In a cross-chain environment, however, things are not as simple:

  1. What happens if a transaction fails after crossing chains?

  2. How do we ensure assets aren’t stuck if a cross-chain transaction doesn’t complete?

  3. Who pays for the gas needed to execute a revert?

Many existing cross-chain solutions do not handle reverts natively, leaving developers to build their own rollback logic or rely on manual intervention.

How ZetaChain Handles Cross-Chain Reverts

ZetaChain provides a built-in framework for managing cross-chain failures automatically, preventing a single failure from leaving an application in a broken or inconsistent state.

Types of Transactions: Incoming vs. Outgoing

To understand ZetaChain’s approach, let’s define two types of cross-chain transactions:

  • An incoming transaction goes from a connected chain (for example, Ethereum) to ZetaChain.

  • An outgoing transaction goes from ZetaChain to a connected chain.

ZetaChain provides a structured approach to handling failures in both scenarios, including the new onAbort functionality that mitigates scenarios where a traditional revert process cannot fully complete.

Handling Incoming Transactions: A Smarter Revert Process

Consider a scenario where a transaction originates on Ethereum and calls a function on ZetaChain using depositAndCall:

depositAndCall triggers an exection of the onCall function of a universal contract call on ZetaChain. If the execution succeeds, the transaction completes normally.. However, if onCall fails, ZetaChain attempts a revert.

Ensuring There’s Enough Gas for a Revert

For ZetaChain to execute a revert transaction back to Ethereum, the original deposit must include enough tokens to cover cross-chain execution fees.

If the transaction amount is sufficient for a revert, ZetaChain will:

  1. Use deposited funds to cover the gas costs of the revert. If the deposited amount is in gas tokens, the gas fee will be deducted from the amount. If the deposited amount is in non-gas fungible tokens (for example, supported ERC-20), ZetaChain will swap the amount required for a gas fee on the liquidity pools on ZetaChain (currently, a Uniswap v2 instance is used).

  2. ZetaChain creates a cross-chain transaction from ZetaChain to Ethereum.

  3. Call onRevert on the original Ethereum contract:

The protocol first checks whether the amount of tokens supplied in the original transaction is sufficient to cover the costs of calling back to the source chain. If, for example, making a call from ZetaChain back to Ethereum costs 0.001 ETH, the original deposit must exceed that amount. If the deposited token is not the gas token (e.g., USDC), ZetaChain will use its liquidity pools to swap for enough gas to cover the return call, provided the deposit is sufficient.

If the amount covers the return call costs, the protocol initiates a cross-chain transaction that returns execution back to the connected chain. On that chain, the contract specified in RevertOptions.revertAddress has its onRevert function called:

Under normal circumstances, the flow is: Ethereum -> ZetaChain onCall → Ethereum onRevert.

Introducing onAbort: Preventing Stuck Transactions

But what happens if there aren’t enough funds to pay for the revert? In many cross-chain systems, this would result in an aborted state, leaving assets stranded on the destination chain.

ZetaChain introduces onAbort, a new mechanism that executes locally on ZetaChain when a traditional revert cannot be completed: Ethereum → ZetaChain onCall fails → Insufficient gas → ZetaChain onAbort executes.

The onAbort function provides a final failsafe, ensuring assets are never trapped and allowing contracts to recover gracefully.

This is particularly critical for non-asset transfer transactions (gatewayEVM.call). Without onAbort, these transactions would have no way to recover.

The abort context provides the information you need to handle the recovery. sender is the original sender from the connected chain, asset and amount represent the deposited ZRC-20 tokens, chainID is the connected chain's ID and revertMessage has the same value passed to the original Gateway call. outgoing is false when a call was made from a connected chain and reverted on ZetaChain and true when the call was made from ZetaChain.

Handling Outgoing Transactions: When Reverts Happen on Another Chain

When a transaction is sent from ZetaChain to a connected chain, the flow is slightly different.

If the onCall function on the connected chain reverts, a cross-chain transaction automatically calls back into the universal contract on ZetaChain. Because ZetaChain features free cross-chain calls from connected chains, the revert mechanism doesn’t depend on having deposited tokens; the system will still call onRevert on ZetaChain, allowing the contract to handle cleanup or error logic.

In this scenario, the flow is: ZetaChain → Connected chain onCall reverts → ZetaChain onRevert

However, if onRevert itself fails on ZetaChain, the onAbort function is triggered to provide a final fallback: ZetaChain → Connected chain onCall reverts → ZetaChain onRevert reverts → ZetaChain onAbort

While most revert-related logic should be handled gracefully in onRevert, it’s reassuring to have an additional failsafe should something go wrong there as well.

Why This Matters: The Future of Cross-Chain Reliability

The introduction of onAbort makes ZetaChain’s failure handling far more robust than traditional cross-chain protocols:

  • No stranded assets — Every transaction is either fully executed or accounted for.

  • Automated failure recovery — Developers no longer need manual fallback solutions.

  • Gas-aware reverts — The protocol ensures transactions have the resources they need to fail gracefully.

  • Safer cross-chain applications — App logic remains consistent, even in failure scenarios.

This feature will be available in the next ZetaChain testnet release, and developers can already start integrating it with the latest Localnet version.

About ZetaChain

ZetaChain is the first Universal Blockchain with native access to Bitcoin, Ethereum, Solana, and more, offering seamless user experience and unified liquidity to the next billions of users. With its Universal EVM, ZetaChain empowers developers to build Universal Apps that operate natively across any blockchain, creating a fluid crypto ecosystem from a single platform.

Follow ZetaChain on Twitter @zetablockchain and join the conversation on Discord and Telegram. Reach out to [email protected] if you’re building on top of ZetaChain.

Any projects mentioned are 3rd party, not ZetaChain.

Categories