Exchange._liquidate
function can cause liquidator to burn too much powerPerp
tokens
#226
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
H-01
satisfactory
satisfies C4 submission criteria; eligible for awards
selected for report
This submission will be included/highlighted in the audit report
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Lines of code
https://github.com/code-423n4/2023-03-polynomial/blob/main/src/Exchange.sol#L333-L353
https://github.com/code-423n4/2023-03-polynomial/blob/main/src/ShortCollateral.sol#L121-L144
Vulnerability details
Impact
When calling the following
Exchange._liquidate
function,uint256 totalCollateralReturned = shortCollateral.liquidate(positionId, debtRepaying, msg.sender)
is executed.https://github.com/code-423n4/2023-03-polynomial/blob/main/src/Exchange.sol#L333-L353
In the following
ShortCollateral.liquidate
function, when executinguint256 collateralClaim = debt.mulDivDown(markPrice, collateralPrice)
, wheredebt
isdebtRepaying
,collateralClaim
can be high ifcollateralPrice
has become much lower comparing tomarkPrice
, such as due to a market sell-off that causes the collateral to be worth much less than before. In this case,totalCollateralReturned
can be high as well, which can causetotalCollateralReturned > userCollateral.amount
to be true. When such condition is true,totalCollateralReturned = userCollateral.amount
is executed, and onlyuserCollateral.amount
is transferred to the liquidator after executingERC20(userCollateral.collateral).safeTransfer(user, totalCollateralReturned)
.https://github.com/code-423n4/2023-03-polynomial/blob/main/src/ShortCollateral.sol#L121-L144
Back in the
Exchange._liquidate
function, the liquidator burnsdebtRepaying
powerPerp
tokens afterpowerPerp.burn(msg.sender, debtRepaying)
is executed. However, in this situation, the liquidator only receivesuserCollateral.amount
collateral tokens that are less than the collateral token amount that should be equivalent todebtRepaying
powerPerp
tokens but this liquidator still burnsdebtRepaying
powerPerp
tokens. As a result, this liquidator loses the extrapowerPerp
tokens, which are burnt, that are equivalent to the difference betweendebtRepaying
powerPerp
tokens' equivalent collateral token amount anduserCollateral.amount
collateral tokens.Proof of Concept
The following steps can occur for the described scenario.
Exchange._liquidate
function withdebtRepaying
being 1000e18.ShortCollateral.liquidate
function is called,totalCollateralReturned > userCollateral.amount
is true, anduserCollateral.amount
collateral tokens that are equivalent to 500e18powerPerp
tokens are transferred to Alice.powerPerp.burn(msg.sender, debtRepaying)
is executed in theExchange._liquidate
function, Alice burns 1000e18powerPerp
tokens.userCollateral.amount
collateral tokens that are equivalent to 500e18powerPerp
tokens, she loses 500e18powerPerp
tokens.Tools Used
VSCode
Recommended Mitigation Steps
The
Exchange._liquidate
function can be updated to burn the number ofpowerPerp
tokens that are equivalent to the actual collateral token amount received by the liquidator instead of burningdebtRepaying
powerPerp
tokens.The text was updated successfully, but these errors were encountered: