No slippage control for supply and withdraw functions in PredyPool
#113
Labels
bug
Something isn't working
downgraded by judge
Judge downgraded the risk level of this issue
duplicate-95
grade-c
QA (Quality Assurance)
Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax
🤖_135_group
AI based duplicate group recommendation
sufficient quality report
This report is of sufficient quality
unsatisfactory
does not satisfy C4 submission criteria; not eligible for awards
Lines of code
https://github.com/code-423n4/2024-05-predy/blob/a9246db5f874a91fb71c296aac6a66902289306a/src/PredyPool.sol#L222
https://github.com/code-423n4/2024-05-predy/blob/a9246db5f874a91fb71c296aac6a66902289306a/src/PredyPool.sol#L237
Vulnerability details
Impact
When a user supplies
quoteTokens
orbaseTokens
, they get bond tokens in return, representing their share in the pool. The problem is there is no slippage check on the amount of bond tokens that a user wants to receive in return. This could result in the user receiving fewer bond tokens than intended.Proof of Concept
When a user calls
supply
function within thePredyPool
, it internally calls thesupply
function inSupplyLogic
, which then calls thereceiveTokenAndMintBond
function:The amount to be minted is decided by the
addAsset
function.addAsset
is defined as:It returns the value
claimAmount
which is the amount being minted.claimAmount
is calculated asFixedPointMathLib.mulDivDown(_amount, Constants.ONE, tokenState.assetScaler);
. It is dependent on the valuetokenState.assetScaler
.assetScaler
gets updated every timeupdateScaler
is called in the following lines:Note 1:
assetScaler
is dependent onsupplyInterestRate
which is dependent ongetTotalDebtValue
andgetTotalCollateralValue
.Note 2:
updateScaler
is called inside theapplyInterestForPoolStatus
function.applyInterestForPoolStatus
is called withinapplyInterestForToken
.applyInterestForToken
is called every time a supply, withdraw or trade transaction is executed. So, every time a supply, withdraw or trade transaction is executed, theassetScaler
value is also updated.Let's say a user calls the
supply
function, and a bigwithdraw
or atrade
transaction is also included in the same block. Thesewithdraw
ortrade
transactions are executed in a way such that thetokenState.totalCompoundDeposited
ortokenStatus.totalNormalDeposited
is decreased significantly (whenever withdraw is called,tokenState.totalCompoundDeposited
is decreased andtokenStatus.totalNormalDeposited
can similarly be decreased whentrade
is called). This decreases thegetTotalCollateralValue
. This increases thesupplyInterestRate
(check the above code block).assetScaler
is directly proportional tosupplyInterestRate
, soassetScaler
increases. This causes theclaimAmount
to decrease as it is inversely proportional toassetScaler
(check the second code block). Therefore, the amount of bond tokens to be minted decreases.So,
tokenState.totalCompoundDeposited
ortokenStatus.totalNormalDeposited
⬇️ ->getTotalCollateralValue
⬇️ ->supplyInterestRate
⬆️ ->assetScaler
⬆️ ->claimAmount
⬇️ -> bond tokens ⬇️Had there been no withdrawal or trade transaction before the supply transaction, the user would have got more bond tokens. Hence, the bond tokens intended for the user with the supply transaction will decrease if there was a previous withdraw transaction in the same block. As there is no slippage control, the user cannot control the minimum amount of bond tokens he wants.
Tools Used
Manual review
Recommended Mitigation Steps
Introduce slippage control in supply and withdraw functions in
PredyPool
Assessed type
Other
The text was updated successfully, but these errors were encountered: