The ZetaNonEth contract relies on the source chain's ZetaSent event to mint tokens on destination chains. Lack of availability of this event on chains like Solana enables an attacker to mint tokens without actually locking the assets on the source chain. This results in minting unbacked tokens leading to inflation.
Proof of Concept
The cross-chain minting logic relies on the ZetaSent event emitted from the source chain's Connector contract indicating tokens have been locked:
Since the Relayer/Observer only sees the ZetaSent event, if the source chain has data availability issues, the event may not reliably propagate to the Observer.
For example, chains like Solana can temporarily have data availability issues due to network partitions or heavly throttled message queues.
An attacker could leverage this by:
a. Call ZetaConnector.send() to lock tokens
b. Call ZetaConnectorNonEth.onReceive() pretending to have seen the blocked ZetaSent event
c. ZetaNonEth.mint() is called minting free tokens for the attacker!
At the architecture level, the root cause is that the system relies on the source chain's ZetaSent event to trigger minting on the destination chain.
The expected end-to-end flow is:
User locks tokens on Source Chain via ZetaConnector.send()
ZetaSent event is emitted on Source Chain
Zeta Relayer observes this event and picks it up
Relayer triggers ZetaConnector.onReceive() on Destination Chain
Tokens are minted for User on Destination Chain
However, due to data availability issues on chains like Solana, the actual behavior could be:
User locks tokens on Solana Chain via ZetaConnector.send()
ZetaSent event is emitted but not propagated reliably due to network issues
Relayer never picks up the ZetaSent event
Attacker directly calls ZetaConnector.onReceive() on Destination Chain
Tokens are minted for Attacker without actual lock on Source Chain!
Relying solely on the ZetaSent event to authorize minting. If this event is blocked or unavailable, it breaks the integrity of the asset locking on source chain to minting on destination chain.
This discrepancy in expected vs actual behavior is what enables the asset theft attack.
Tools Used
Vs
Recommended Mitigation Steps
Leverage decentralized message queues like Celestia to ensure cross-chain event delivery
Implement fraud proofs in onReceive() to verify source chain asset locks
Alert integration teams to data availability risks on target chains
Increase mint asset reserves to cover inflation from delayed event flows
Lines of code
https://github.com/code-423n4/2023-11-zetachain/blob/2834e3f85b2c7774e97413936018a0814c57d860/repos/protocol-contracts/contracts/zevm/ZetaConnectorZEVM.sol#L67-L86 https://github.com/code-423n4/2023-11-zetachain/blob/2834e3f85b2c7774e97413936018a0814c57d860/repos/protocol-contracts/contracts/evm/ZetaConnector.eth.sol#L52-L70
Vulnerability details
Impact
The ZetaNonEth contract relies on the source chain's ZetaSent event to mint tokens on destination chains. Lack of availability of this event on chains like Solana enables an attacker to mint tokens without actually locking the assets on the source chain. This results in minting unbacked tokens leading to inflation.
Proof of Concept
The cross-chain minting logic relies on the
ZetaSent
event emitted from the source chain's Connector contract indicating tokens have been locked:ZetaConnectorZEVM.sol#ZetaSent
The ZetaRelayer/Observer then sees this event on the source chain and mints the tokens on the destination chain by calling the
onReceive
method:ZetaConnector.eth.sol#onReceive
Since the Relayer/Observer only sees the
ZetaSent
event, if the source chain has data availability issues, the event may not reliably propagate to the Observer.For example, chains like Solana can temporarily have data availability issues due to network partitions or heavly throttled message queues.
An attacker could leverage this by:
a. Call
ZetaConnector.send()
to lock tokens b. CallZetaConnectorNonEth.onReceive()
pretending to have seen the blocked ZetaSent event c.ZetaNonEth.mint()
is called minting free tokens for the attacker!At the architecture level, the root cause is that the system relies on the source chain's
ZetaSent
event to trigger minting on the destination chain.The expected end-to-end flow is:
ZetaConnector.send()
ZetaSent
event is emitted on Source ChainZetaConnector.onReceive()
on Destination ChainHowever, due to data availability issues on chains like Solana, the actual behavior could be:
ZetaConnector.send()
ZetaSent
event is emitted but not propagated reliably due to network issuesZetaSent
eventZetaConnector.onReceive()
on Destination ChainRelying solely on the
ZetaSent
event to authorize minting. If this event is blocked or unavailable, it breaks the integrity of the asset locking on source chain to minting on destination chain.This discrepancy in expected vs actual behavior is what enables the asset theft attack.
Tools Used
Vs
Recommended Mitigation Steps
Leverage decentralized message queues like Celestia to ensure cross-chain event delivery
Implement fraud proofs in
onReceive()
to verify source chain asset locksAlert integration teams to data availability risks on target chains
Increase mint asset reserves to cover inflation from delayed event flows
Assessed type
Other