Protocol Fund Drain via LayerZero Fee Exhaustion Through Invalid Cross-Chain Withdrawals
Summary
A malicious user will cause fund loss and potential denial of service to the protocol and its users by initiating small withdrawals that are guaranteed to fail on the Solana side after consuming LayerZero fees paid by the protocol.
Root Cause
The withdraw() function being non-payable and Protocol pays fees via internal _payNative():
function _payNative(uint256 _nativeFee) internal virtual returns (uint256 nativeFee) {
// Protocol balance is used to pay fees
if (msg.value < _nativeFee && address(this).balance < _nativeFee) revert NotEnoughNative(msg.value);
return _nativeFee;
}
Solana side trying to take fee from very small token_amount that will fail:
if lz_message.msg_type == MsgType::Withdraw as u8 {
let withdraw_params = AccountWithdrawSol::decode_packed(&lz_message.payload).unwrap();
let amount_to_transfer = withdraw_params.token_amount - withdraw_params.fee;
transfer(
ctx.accounts
.transfer_token_ctx()
.with_signer(&[&vault_authority_seeds[..]]),
amount_to_transfer,
)?;
}
Internal pre-conditions
No response
External pre-conditions
No response
Attack Path
Attacker initiates multiple withdrawals of 0.000001 USDC each
Protocol pays LayerZero fees on EVM side for message relay from its own balance
Messages get relayed to Solana
Transactions revert on Solana due to underflow in amount_to_transfer = token_amount - fee
Protocol loses fee with no successful transfer
Repeat to amplify impact and drain protocol's fee reserves
Impact
The protocol suffers financial losses equal to the LayerZero message fees for each failed transaction, with fees being paid from protocol's own balance rather than users'. Other users experience denial of service as the attack consumes funds meant for fee. The attacker loses minimal funds (just EVM transaction gas fees) while causing significant protocol losses.
Plain Corduroy Goblin
Medium
Protocol Fund Drain via LayerZero Fee Exhaustion Through Invalid Cross-Chain Withdrawals
Summary
A malicious user will cause fund loss and potential denial of service to the protocol and its users by initiating small withdrawals that are guaranteed to fail on the Solana side after consuming LayerZero fees paid by the protocol.
Root Cause
The withdraw() function being non-payable and Protocol pays fees via internal _payNative():
LayerZero message initiation showing fee payment from protocol: https://github.com/sherlock-audit/2024-09-orderly-network-solana-contract/blob/main/sol-cc/contracts/SolConnector.sol#L97
Solana side trying to take fee from very small token_amount that will fail:
Internal pre-conditions
No response
External pre-conditions
No response
Attack Path
Impact
The protocol suffers financial losses equal to the LayerZero message fees for each failed transaction, with fees being paid from protocol's own balance rather than users'. Other users experience denial of service as the attack consumes funds meant for fee. The attacker loses minimal funds (just EVM transaction gas fees) while causing significant protocol losses.
PoC
No response
Mitigation
No response