borrowing::liquidate() sends the wrong liquidation index to the destination chain, overwritting liquidation information and getting collateral stuck
Summary
borrowing::liquidate() sends the noOfLiquidations variable as liquidation index to the other chain. However, liquidations are tracked in omniChainData.noOfLiquidations, on both chains. For example, if a liquidation happens on chain A, it increases to 1 and sends this information to chain B. If a liquidation happens on chain B, it will have index 2, not 1.
Root Cause
In borrowing:402, the wrong variable is sent as liquidation index to the other chain.
Internal pre-conditions
None.
External pre-conditions
None.
Attack Path
- Liquidation happens on chain A, incrementing
omniChainData.noOfLiquidationsto 1 andnoOfLiquidationsto 1 also. - Liquidation happens on chain B, with index 2 (it received the omnichain data from chain A and then incremented it). In chain B, it sends the liquidation info to chain A, but sends with index 1, not 2, as it uses the local
noOfLiquidationsto send the index. - Chain A will have liquidation info with index 1 overiwritten by the liquidation of chain B, leading to stuck collateral of the first liquidation in chain A (as long as depositors have not withdraw, but if they have, they can't withdraw the second liquidation anyway).
Impact
Stuck collateral.
PoC
See above.
Mitigation
Pass in the correct index, given by omnichainData.noOfLiquidations.