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

giraffe - Unsafe casting of Int256 perpNetValue leads to DOS #65

Closed
sherlock-admin2 opened this issue Jan 18, 2024 · 17 comments
Closed
Labels
Escalation Resolved This issue's escalations have been approved/rejected Non-Reward This issue will not receive a payout Sponsor Confirmed The sponsor acknowledged this issue is valid Won't Fix The sponsor confirmed this issue will not be fixed

Comments

@sherlock-admin2
Copy link
Contributor

sherlock-admin2 commented Jan 18, 2024

giraffe

medium

Unsafe casting of Int256 perpNetValue leads to DOS

Summary

In FundingRateArbitrage.sol, the function getNetValue() does SafeCast.toUint256(perpNetValue). When perpNetValue is negative, this cast will revert.

Vulnerability Detail

function getNetValue() public view returns (uint256) {
        ...
        (int256 perpNetValue,,,) = JOJODealer(jojoDealer).getTraderRisk(address(this));
        
        //@audit when perpNetValue is negative Safecast will revert
        return
            SafeCast.toUint256(perpNetValue) + collateralAmount.decimalMul(collateralPrice) + usdcBuffer - jusdBorrowed;
    }

perpNetValue can be a negative value when the trades (by contract Owner) are losing money (confirmed with Sponsor). This will result in SafeCast reverting:

function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

Impact

All deposit and withdraw functions in FundingRateArbitrage.sol are DOS-ed as they rely on getNetValue() and will revert when called. The impact is significant because users are likely to want to withdraw if the trades are losing money, but are unable to do so due to the bug described.

Code Snippet

https://github.com/sherlock-audit/2023-12-jojo-exchange-update/blob/main/smart-contract-EVM/src/FundingRateArbitrage.sol#L94

Tool used

Manual Review

Recommendation

Add additional if/else conditions in deposit and withdraw to handle a negative perpNetValue scenario and possible overall negative netValue scenario.

@github-actions github-actions bot added the Medium A valid Medium severity issue label Jan 22, 2024
@sherlock-admin2
Copy link
Contributor Author

1 comment(s) were left on this issue during the judging contest.

takarez commented:

invalid because { It will not revert as its in int256 which is to hold negative values}

@JoscelynFarr JoscelynFarr added Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed labels Jan 23, 2024
JoscelynFarr added a commit to JOJOexchange/smart-contract-EVM that referenced this issue Jan 26, 2024
@sherlock-admin sherlock-admin changed the title Suave Mint Hare - Unsafe casting of Int256 perpNetValue leads to DOS giraffe - Unsafe casting of Int256 perpNetValue leads to DOS Jan 27, 2024
@sherlock-admin sherlock-admin added the Reward A payout will be made for this issue label Jan 27, 2024
@detectiveking123
Copy link
Collaborator

Escalate

This issue is invalid. If you look at getTraderRisk function, then it computes the TOTAL value of the position (including margin), not whether they're just up or down.

In order to get to this state, the FundingRateArbitrage contract, whose positions are managed by admins:

  1. Must have incurred bad debt
  2. Must not have been liquidated for whatever reason

Furthermore, even after we get to this position, the contract can still be liquidated and the bad debt can be taken care of.

@sherlock-admin
Copy link
Contributor

Escalate

This issue is invalid. If you look at getTraderRisk function, then it computes the TOTAL value of the position (including margin), not whether they're just up or down.

In order to get to this state, the FundingRateArbitrage contract, whose positions are managed by admins:

  1. Must have incurred bad debt
  2. Must not have been liquidated for whatever reason

Furthermore, even after we get to this position, the contract can still be liquidated and the bad debt can be taken care of.

You've created a valid escalation!

To remove the escalation from consideration: Delete your comment.

You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final.

@sherlock-admin2 sherlock-admin2 added the Escalated This issue contains a pending escalation label Jan 27, 2024
@Hash01011122
Copy link

Correct me if I am wrong
Building upon the points raised during the escalation, it’s important to note that the impact of this issue is minimal. In the event that a user’s perpNetValue goes negative, the transaction would simply revert without any loss of funds or the contract getting bricked.
Moreover, the probability of this scenario occurring is quite low. For this to happen, a user would need to have bad debt or not have incurred any liquidation, which is not the situation we’re dealing with, as highlighted during the escalation.
This is low-informational severity.

@nevillehuang
Copy link
Collaborator

nevillehuang commented Jan 30, 2024

I believe even though this would require a trusted admin action on trades, it should not explicitly DoS core functionalities like depositing and requesting withdrawal. While this is an edge case, if theres a bad trade causing the value to fall to negative, why wouldn't the protocol be open to more collateral deposits?

If any of the watsons here can provide me a reasonable numerical example that this will never realistically occur, I will considering lowering severity, if not I believe the severity is correct.

@giraffe0x
Copy link

giraffe0x commented Jan 30, 2024

To add on: Funding Rate Arbitrage is advertised by JOJO as a low-risk, stable return product. In the unfortunate event that positions are negative, admins may decide to inject funds via deposit to avoid liquidation. However, it is at this critical moment deposit() reverts due to the described bug, allowing for liquidation and losses to JOJO's users.

@detectiveking123
Copy link
Collaborator

@nevillehuang @giraffe0x I believe you are misunderstanding the point. getTraderRisk does not return a trader's PNL. It returns the value of their overall position, including margin. They should have been liquidated already, before bad debt is incurred. Even if bad debt is incurred, the situation can be resolved through a liquidation and then bad debt resolution.

@nevillehuang
Copy link
Collaborator

nevillehuang commented Jan 31, 2024

@JoscelynFarr Can you confirm @detectiveking123 comments? I might have missed protocol mechanisms revolving around liquidation mechanisms given the limited time I have to judge a huge update contest. If it is true that admin/any liquidator can resolve issue via a liquidation, I can agree that it is low severity.

@JoscelynFarr
Copy link

Agree with @detectiveking123. No need to fix the issue. Will remove the fix label

@JoscelynFarr
Copy link

@JoscelynFarr Can you confirm @detectiveking123 comments? I might have missed protocol mechanisms revolving around liquidation mechanisms given the limited time I have to judge a huge update contest. If it is true that admin/any liquidator can resolve issue via a liquidation, I can agree that it is low severity.

getTraderRisk does not return a trader's PNL. It returns the value of their overall position, including margin. which is true, so I think before it becomes negative. It would be liquidated
.

@nevillehuang
Copy link
Collaborator

nevillehuang commented Feb 2, 2024

@JoscelynFarr Can you point to the code logic that performs this liquidation? Once I verify I agree this can be low/invalid severity.

@JoscelynFarr
Copy link

@JoscelynFarr Can you point to the code logic that performs this liquidation? Once I verify I agree this can be low/invalid severity.

Sure getTraderRisk function returns users' netValue which includes USDC + JUSD + netPositionValue
https://github.com/JOJOexchange/smart-contract-EVM/blob/main/src/libraries/Liquidation.sol#L69

The liquidation formulation can be find in here
https://github.com/JOJOexchange/smart-contract-EVM/blob/main/src/libraries/Liquidation.sol#L189
So if netValue < SafeCast.toInt256(maintenanceMargin); then the user will be liquidated. So netValue will bigger than zero.

@Evert0x
Copy link

Evert0x commented Feb 5, 2024

@nevillehuang did you verify it?

@nevillehuang
Copy link
Collaborator

Yes @Evert0x can be invalid, but what I can tell you is if it so happens nobody is willing to liquidate, core functionalities like depositing will indeed be bricked. However, I trust that admin will liquidate appropriately to unblock DoS

@MLON33 MLON33 added Won't Fix The sponsor confirmed this issue will not be fixed and removed Will Fix The sponsor confirmed this issue will be fixed labels Feb 5, 2024
@Evert0x
Copy link

Evert0x commented Feb 6, 2024

Ok planning to accept escalation and invalidate issue

@Czar102 Czar102 removed the Medium A valid Medium severity issue label Feb 8, 2024
@sherlock-admin sherlock-admin added Non-Reward This issue will not receive a payout and removed Reward A payout will be made for this issue labels Feb 8, 2024
@Czar102 Czar102 closed this as completed Feb 8, 2024
@Czar102
Copy link

Czar102 commented Feb 8, 2024

Result:
Invalid
Unique

@sherlock-admin sherlock-admin removed the Escalated This issue contains a pending escalation label Feb 8, 2024
@sherlock-admin
Copy link
Contributor

Escalations have been resolved successfully!

Escalation status:

@sherlock-admin2 sherlock-admin2 added the Escalation Resolved This issue's escalations have been approved/rejected label Feb 8, 2024
coin96 pushed a commit to coin96/smart-contract-EVM that referenced this issue Apr 29, 2024
Tvenus added a commit to Tvenus/smart-contract-EVM that referenced this issue May 27, 2024
Omokami added a commit to Omokami/smart-contract-EVM that referenced this issue May 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Escalation Resolved This issue's escalations have been approved/rejected Non-Reward This issue will not receive a payout Sponsor Confirmed The sponsor acknowledged this issue is valid Won't Fix The sponsor confirmed this issue will not be fixed
Projects
None yet
Development

No branches or pull requests

10 participants