The _collateralRate is not checked when calling PreMarkets.listOffer() for the Protected market, where the collateralRate from the preOffer is used for the collateral transfer amount.
This can lead to direct loss of funds for the user or the protocol in situations where _collateralRate does not equal preOffer.collateralRate.
In the PreMarkets.listOffer() function, the check to validate the _collateralRate is only performed for Turbo markets:
Unfortunately, this check is limited to Turbo markets but should also be applied to Protected markets. In Protected markets, the collateral deposit amount is calculated based on the preOffer.collateralRate rather than the _collateralRate:
The _collateralRate is then used to create a new offer:
This can be exploited in the following scenario:
A Maker creates a Protected market and an Ask offer with a collateral factor of 100%.
An attacker, acting as a Taker, takes the Ask for 1 USDC.
The attacker then relists the stock via the PreMarkets.listOffer() function but manipulates the _collateralRate to 1,000,000%, while only providing 1 USDC collateral.
The attacker instantly closes the offer via the PreMarkets.closeOffer() function, where they are refunded based on the manipulated _collateralRate, and receives 10,000 USDC or any other amount held in the CapitalPool contract.
All funds in the system can be stolen.
Manual review.
Validate that the _collateralRate value is equal to preOffer.collateralRate for Protected markets.
OR
Use _collateralRate in the transferAmount calculations when determining collateral.
Valid high severity, because the collateral rate utilized when creating an offer is stale and retrieved from a previously set collateral rate, it allows possible manipilation of refund amounts using an inflated collateral rate to drain funds from the CapitalPool contract
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.