However, if cares have not been given particularly when inputting params.collateralAmount via a non-frontend method such as https://optimistic.etherscan.io/, a zero or a value smaller than shortPosition.collateralAmount could be accidentally entered. After the transaction has succeeded, the user's collateral would be permanently locked in contract ShortCollateral.
Proof of Concept
As can be seen from the code block pertaining to _closeTrade() below, totalShortAmount == 0 will make the require statement pass easily because minCollateral == 0.
Next, the user's position is adjusted such that its position is burned because of a complete position close. Note that position.shortAmount is assigned 0 whereas position.collateralAmount is assigned a non-zero value.
Because the user's ERC-721 short token is now burned, removing the forgotten/remaining collateral from the short position is going to revert on the ownership check:
Lines of code
https://github.com/code-423n4/2023-03-polynomial/blob/main/src/ShortToken.sol#L82-L84 https://github.com/code-423n4/2023-03-polynomial/blob/main/src/Exchange.sol#L304
Vulnerability details
Impact
When completely closing a short trade, a user is supposed to input
TradeParams
such that:shortPosition.shortAmount == params.shortAmount
shortPosition.collateralAmount == params.collateralAmount
However, if cares have not been given particularly when inputting
params.collateralAmount
via a non-frontend method such as https://optimistic.etherscan.io/, a zero or a value smaller thanshortPosition.collateralAmount
could be accidentally entered. After the transaction has succeeded, the user's collateral would be permanently locked in contractShortCollateral
.Proof of Concept
As can be seen from the code block pertaining to
_closeTrade()
below,totalShortAmount == 0
will make the require statement pass easily becauseminCollateral == 0
.File: Exchange.sol#L310-L319
The inadequate
params.collateralAmount
accidentally inputted is then sent to the user:File: ShortCollateral.sol#L106-L116
Next, the user's position is adjusted such that its position is burned because of a complete position close. Note that
position.shortAmount
is assigned0
whereasposition.collateralAmount
is assigned a non-zero value.File: ShortToken.sol#L79-L84
Because the user's ERC-721 short token is now burned, removing the forgotten/remaining collateral from the short position is going to revert on the ownership check:
File: Exchange.sol#L388
Tools Used
Manual inspection
Recommended Mitigation Steps
Consider adding a check in
_closeTrade()
that will fully send the collateral to the user when the position is intended to be fully closed as follows:File: Exchange.sol#L310-L316