Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Users can bypass the maxWinPercent limit using a partially closing #507

Open
code423n4 opened this issue Dec 16, 2022 · 12 comments
Open

Users can bypass the maxWinPercent limit using a partially closing #507

code423n4 opened this issue Dec 16, 2022 · 12 comments
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) H-09 judge review requested Judge should review this issue primary issue Highest quality submission among a set of duplicates 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")

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2022-12-tigris/blob/b2ebb8ea1def4927a747e7a185174892506540ab/contracts/Trading.sol#L625-L627

Vulnerability details

Impact

Users can bypass the maxWinPercent limit using a partial closing.

As a result, users can receive more funds than their upper limit from the protocol.

Proof of Concept

As we can see from the documentation, there is limitation of a maximum PnL.

Maximum PnL is +500%. The trade won't be closed unless the user sets a Take Profit order or closes the position manually.

And this logic was implemented like below in _closePosition().

File: 2022-12-tigris\contracts\Trading.sol
624:                 _toMint = _handleCloseFees(_trade.asset, uint256(_payout)*_percent/DIVISION_CONSTANT, _trade.tigAsset, _positionSize*_percent/DIVISION_CONSTANT, _trade.trader, _isBot);
625:                 if (maxWinPercent > 0 && _toMint > _trade.margin*maxWinPercent/DIVISION_CONSTANT) { //@audit bypass limit
626:                     _toMint = _trade.margin*maxWinPercent/DIVISION_CONSTANT;
627:                 }

But it checks the maxWinPercent between the partial payout and full margin so the below scenario is possible.

  1. Alice opened an order of margin = 100 and PnL = 1000 after taking closing fees.
  2. If maxWinPercent = 500%, Alice should receive 500 at most.
  3. But Alice closed 50% of the position and she got 500 for a 50% margin because it checks maxWinPercent with _toMint = 500 and _trade.margin = 100
  4. After she closed 50% of the position, the remaining margin = 50 and PnL = 500 so she can continue step 3 again and again.
  5. As a result, she can withdraw almost 100% of the initial PnL(1000) even though she should receive at most 500.

Tools Used

Manual Review

Recommended Mitigation Steps

We should check the maxWinPercent between the partial payout and partial margin like below.

    _toMint = _handleCloseFees(_trade.asset, uint256(_payout)*_percent/DIVISION_CONSTANT, _trade.tigAsset, _positionSize*_percent/DIVISION_CONSTANT, _trade.trader, _isBot);

    uint256 partialMarginToClose = _trade.margin * _percent / DIVISION_CONSTANT; //+++++++++++++++++++++++
    if (maxWinPercent > 0 && _toMint > partialMarginToClose*maxWinPercent/DIVISION_CONSTANT) { 
        _toMint = partialMarginToClose*maxWinPercent/DIVISION_CONSTANT;
    }
@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Dec 16, 2022
code423n4 added a commit that referenced this issue Dec 16, 2022
@c4-judge
Copy link
Contributor

GalloDaSballo marked the issue as duplicate of #111

@TriHaz
Copy link

TriHaz commented Dec 26, 2022

I don't think any of this, #339, #487 is a duplicate of #111
But I would label this as primary for better mitigation.
Also I would label it as med risk as a +500% win is required so assets are not in a direct risk.
@GalloDaSballo

@c4-sponsor
Copy link

TriHaz marked the issue as sponsor confirmed

@c4-sponsor c4-sponsor added the sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") label Dec 26, 2022
@c4-sponsor
Copy link

TriHaz marked the issue as disagree with severity

@c4-sponsor c4-sponsor added the disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) label Dec 26, 2022
@c4-sponsor
Copy link

TriHaz requested judge review

@c4-sponsor c4-sponsor added the judge review requested Judge should review this issue label Jan 3, 2023
C4-Staff added a commit that referenced this issue Jan 6, 2023
@GalloDaSballo
Copy link

Thank you for flagging @TriHaz , will re-dedoup

@c4-judge c4-judge reopened this Jan 22, 2023
@c4-judge
Copy link
Contributor

GalloDaSballo marked the issue as not a duplicate

@GalloDaSballo
Copy link

@TriHaz I see your point, and agree that the findings are different, thank you for the flag

@c4-judge
Copy link
Contributor

GalloDaSballo marked the issue as primary issue

@c4-judge c4-judge added the primary issue Highest quality submission among a set of duplicates label Jan 22, 2023
@GalloDaSballo
Copy link

The Warden has shown how, by partially closing an order, it is possible to bypass the maxWinPercent cap.

Per similar discussion to #111 the fact that not every trade can be above 500% in payout is not a guarantee that some trade will be, and those that will, will cause the invariant to be broken and LPs to be deeper in the red than they should.

Because this causes an immediate gain to the attacker, at a loss for LPs, I agree with High Severity.

@c4-judge
Copy link
Contributor

GalloDaSballo marked the issue as selected for report

@c4-judge c4-judge added the selected for report This submission will be included/highlighted in the audit report label Jan 22, 2023
@C4-Staff C4-Staff added the H-09 label Jan 26, 2023
@GainsGoblin
Copy link

GainsGoblin commented Jan 29, 2023

Mitigation: code-423n4/2022-12-tigris#2 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) H-09 judge review requested Judge should review this issue primary issue Highest quality submission among a set of duplicates 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")
Projects
None yet
Development

No branches or pull requests

7 participants