Open code423n4 opened 1 year ago
JustDravee marked the issue as duplicate of #65
JustDravee marked the issue as satisfactory
JustDravee marked the issue as selected for report
The 3rd scenario isn't likely due to frontrunning not being an issue on Optimism. This report still brings the most value and is the most well presented. Selected for report.
Lines of code
https://github.com/code-423n4/2023-03-polynomial/blob/main/src/ShortToken.sol#L82-L84
Vulnerability details
Impact
Users can permanently lose a portion of their collateral due to a malicious attacker or their own mistake.
Vulnerability Details
In the
ShortToken
contract,adjustPosition()
is used to handle changes to a short position's short or collateral amounts. The function also handles the burning of positions with the following logic:ShortToken.sol#L79-L84
Where:
collateralAmount
- New amount of collateral in a position.shortAmount
- New short amount of a position.positionId
- ERC721ShortToken
of a short position.As seen from above, if a position's
shortAmount
is set to 0, it will be burned. Furthermore, as the code does not ensurecollateralAmount
is not 0 before burning, it is possible to burn a position while it still has collateral.If this occurs, the position's owner will lose all remaining collateral in the position. This remaining amount will forever be stuck in the position as its corresponding
ShortToken
no longer has an owner.Proof of Concept
In the
Exchange
contract, users can reduce a position'sshortAmount
usingcloseTrade()
andliquidate()
. With these two functions, there are three realistic scenarios where a position with collateral could be burned.1. User reduces his position's
shortAmount
to 0A user might call
closeTrade()
on a short position with the following parameters:params.amount
- Set to the position's short amount.params.collateralAmount
- Set to any amount less than the position's total collateral amount.This would reduce his position's
shortAmount
to 0 without withdrawing all of its collateral, causing him to lose the remaining amount.Although this could be considered a user mistake, such a scenario could occur if a user does not want to hold a short position temporarily without fully withdrawing his collateral.
2. Attacker fully liquidates a short position
In certain situations, it is possible for a short position to have collateral remaining after a full liquidation (example in the coded PoC below). This collateral will be lost as full liquidations reduces a position's
shortAmount
to 0, thereby burning the position.3. Attacker frontruns a user's
closeTrade()
transaction with a liquidationConsider the following scenario:
closeTrade()
on her position with the following parameters:params.amount
- Set to 40% of the position's short amount.params.collateralAmount
- Set to 0.closeTrade()
transaction in the mempool.liquidate()
with the following parameters:positionId
- ID of Alice's position.debtRepaying
- Set to 60% of Alice's position's short amount.liquidate()
transaction executes first, reducing the short amount of Alice's position to 40% of the original amount.closeTrade()
transaction executes, reducing her position's short amount by 40% of the original amount, thus itsshortAmount
becomes 0.In the scenario above, Alice loses the remaining collateral in her short position as it is burned after
closeTrade()
executes.Note that this attack is possible as long as an attacker can liquidate the position's remaining short amount. For example, if Alice calls
closeTrade()
with 70% of the position's short amount, Bob only has to liquidate 30% of its short amount.Coded PoC
The code below contains three tests that demonstrates the scenarios above:
testCloseBurnsCollateral()
testLiquidateBurnsCollateral()
testAttackerFrontrunLiquidateBurnsCollateral()
Recommended Mitigation
Ensure that positions cannot be burned if they have any collateral:
ShortToken.sol#L82-L84