Tokens Permanently Locked in Vault Due to Absence of Revert or Retry Mechanism
Summary
Orderly users can deposit and withdraw their USDC to and from the vaults via Solana or evm chains. However, if the transaction on the destination chain fails, there is no way to revert or retry the transaction on the source chain or destination chain respectively, or refund user's locked tokens. Consequently, user's tokens will be locked in the vault contract permanently.
Messages are sent from the User Application (UA) at source srcUA to the UA at the destination dstUA. Once the message is received by dstUA, the message is considered delivered (transitioning from INFLIGHT to either SUCCESS or STORED)
In case of message failure at the destination chain with caught error/exception:
dstUA is expected to store the message in their contract to be retried (LayerZero will not store any successfully delivered messages). dstUA is expected to monitor and retry STORED messages on behalf of its users.
In case of message failure at the destination chain with uncaught error/exception:
dstUA is expected to gracefully handle all errors/exceptions when receiving a message, and any uncaught errors/exceptions (including out-of-gas) will cause the message to transition into STORED. A STORED message will block the delivery of any future message from srcUA to all dstUA on the same destination chain and can be retried until the message becomes SUCCESS. dstUA should implement a handler to transition the stored message from STORED to SUCCESS. If a bug in dstUA contract results in an unrecoverable error/exception, LayerZero provides a last-resort interface to force resume message delivery, only by the dstUA contract.
However, none of these required mechanisms are provided at the destination chain, and consequently user's tokens will be locked in the vault contract permanently.
Internal pre-conditions
User locks tokens in the vault at the source chain and send a cross chain transaction.
Cross chain transaction fails at the destination chain.
External pre-conditions
No response
Attack Path
The user interacts with the frontend and signs a transaction using their Solana wallet, which employs an ed25519 signature.
The signed transaction is sent to the Vault contract on the Solana blockchain.
The Vault contract triggers the LayerZero cross-chain service, which transfers the transaction data to the Orderly chain.
Transaction fails at Orderly chain (e.g., due to the out-of-gas).
There is no way to revert or retry the transaction at the source chain or refund locked tokens to the user.
User's tokens will be locked in the vault contract permanently.
Impact
In the event of a transaction revert on the destination chain, users funds will be locked in the vault permanently.
Raspy Seaweed Bear
High
Tokens Permanently Locked in Vault Due to Absence of Revert or Retry Mechanism
Summary
Orderly users can deposit and withdraw their USDC to and from the vaults via Solana or evm chains. However, if the transaction on the destination chain fails, there is no way to revert or retry the transaction on the source chain or destination chain respectively, or refund user's locked tokens. Consequently, user's tokens will be locked in the vault contract permanently.
Root Cause
The end user initiates operations such as deposit or withdrawal through their Solana wallet, signing transactions and sending them to the blockchain. For example, for depositing, The signed transaction is sent to the Vault contract on the Solana chain: https://github.com/sherlock-audit/2024-09-orderly-network-solana-contract/blob/main/solana-vault/packages/solana/contracts/programs/solana-vault/src/instructions/vault_instr/deposit.rs#L107-L167 The Vault contract triggers the LayerZero cross-chain service, which transfers the transaction data to the Orderly chain. However, if the transaction on the destination chain fails, there is no way to revert or retry the transaction on the source chain or destination chain respectively, or refund user's locked tokens. Consequently, user's tokens will be locked in the vault contract permanently. As mentioned in LayerZero documents (https://docs.layerzero.network/v1/home/concepts/messaging-properties):
Internal pre-conditions
External pre-conditions
No response
Attack Path
Impact
In the event of a transaction revert on the destination chain, users funds will be locked in the vault permanently.
PoC
No response
Mitigation
Provide a refund or retry mechanism for users funds in case of a transaction failure on the destination chain. It is needed to follow guideline mentioned in LayerZero docs: https://docs.layerzero.network/v1/home/concepts/messaging-properties