In order to handle low decimals tokens everywhere in the protocol, Zaros starts by scaling such token amount to 18 decimals so rounding errors are avoided.
When users adjust their positions, a part of their trades are collected as fees and sent to the fee recipients. There are 3 types of fees :
settlement fees
order fees
PnL fees
The fees are collected when an account is being liquidated or an order is fulfilled, in the SettlementBranch::_fillOrder() and LiquidationBranch::liquidateAccounts() functions respectively.
These 2 functions use another interal function called TradingAccount::deductAccountMargin() where all the logic is implemented.
This function will loop through all the allowed collateral and give the due scaled USD value to withdrawMarginUsd()
https://github.com/Cyfrin/2024-07-zaros/blob/main/src/perpetuals/leaves/TradingAccount.sol#L528-L566
In withdrawMarginUsd(), before transferring the tokens to the recipients, the scaled token amount will be down scaled using the MarginCollateralConfiguration::convertUd60x18ToTokenAmount() function.
https://github.com/Cyfrin/2024-07-zaros/blob/main/src/perpetuals/leaves/TradingAccount.sol#L434-L469
The issue is that the given requiredMarginInCollateralX18 is so small, when the downscaling occurs, the returned token amount will equal 0.
When dealing with WBTC for example, the requiredMarginInCollateralX18 will be divided by 1e10 which will round to 0.
So the contract will transfer 0 WBTC to the fee recipients, leaving this fee in the contract but still reducing the trader's account margins as if the transfer actually happened.
Currently, the supported tokens allow 0 amount transfers but the protocol should keep in mind that some tokens revert when attempting to transfer zero tokens.
This coded PoC can be pasted in test\integration\perpetuals\perp-market-branch\getFundingRate\getFundingRate.t.sol and demonstrates a user performing various operations that should be collecting fees. However, the recipients never receive them.
Fee recipients do not receive their due and these fees end up stuck in the contract.
Manual review
The issue can hardly be patched because the fee percentages are so small, the downscaling will most likely round to 0.
An idea when this happens would be to collect a flat amount of tokens.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.