Open code423n4 opened 1 year ago
Picodes marked the issue as primary issue
ramenforbreakfast marked the issue as sponsor confirmed
Picodes marked the issue as satisfactory
Picodes marked the issue as selected for report
Would ask judge to consider the merits of #307 (mine) as the selected-for-report, primarily because it shows an exploitation flow where admin can make maximum profit. This report only reviews the properties of the bug.
Lines of code
https://github.com/prepo-io/prepo-monorepo/blob/3541bc704ab185a969f300e96e2f744a572a3640/apps/smart-contracts/core/contracts/PrePOMarket.sol#L119
Vulnerability details
Impact
If
finalLongPayout
is changed twice by admin fault, the market would be insolvent as it should pay more collateral than it has.Proof of Concept
If
finalLongPayout
is less thanMAX_PAYOUT
, it means the market is ended andlongToken Price = finalLongPayout, shortToken Price = MAX_PAYOUT - finalLongPayout
.So when users redeem their long/short tokens, the total amount of collateral tokens will be the same as the amount that users transferred during mint().
Btw in
setFinalLongPayout()
, there is no validation that this function can't be called twice and the below scenario would be possible.Bob
in the market for simplicity.Bob
transferred 100 amounts ofcollateral
and got 100 long/short tokens. The market has 100collateral
.finalLongPayout = 60 * 1e16
andBob
redeemed 100longToken
and received 60collateral
. The market has 40collateral
now.finalLongPayout
is too high and changedfinalLongPayout = 40 * 1e16
again.Bob
tries to redeem 100shortToken
and receive 60collateral
but the market can't offer as it has 40collateral
only.When there are several users in the market, some users can't redeem their long/short tokens as the market doesn't have enough
collaterals
.Tools Used
Manual Review
Recommended Mitigation Steps
We should modify
setFinalLongPayout()
like below so it can't be finalized twice.