-
Notifications
You must be signed in to change notification settings - Fork 9
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
Limit Price Can Be Bypassed #67
Comments
Orders in PerpMarket, unlike those in CEX, have both limit and stop price attributes in a single order. For example, if the current price is 1000, you can place a buy order with a limit price of 900 and a stop price of 1100. The order will be executed when either condition is met. Therefore, the revert condition should be when neither condition is met, so |
The submission specifies that an order will be considered valid if either its limit or its stop price has been validated when both attributes have been defined for it. Per the Sponsor's comments, this is desirable behavior as the code would effectively permit an order to be executed outside a particular range. |
alex-ppg marked the issue as unsatisfactory: |
Thank you for judging @alex-ppg, Using the sponsor's example, I believe this is an issue. Current Market Price (1000) When a user sets a trade (900) and goes long his/her take profit region should be above his entry while his stop should always be below his entry price. limit at 1200 For stop limit
For limit/Take profit
BUT Based on the code's implementation, using the sponsor's example if current at 1000 Hence if the market goes down to 900 the trade is activated but if the price keeps failing the system fails to trigger a stop limit order because of an invalid stop limit. Thus the user who has automated his trading system by executing the trade and setting a stop and limit will be unfairly liquidated when the system should have taken him out of the trade at 900 because the stop limit is invalid at 1100. This action also applies to the short trade example, this MUST revert if any of the Limits are invalid to protect the user because that was why it was added in the first place, everything doesn't always go according to the plan while trading. If you need any more explanation, I would be more than happy to elaborate. Thank you. |
Hello @alex-ppg, First, I think we should establish that the order represents order's maker or user's intent.
Second, if we take user's intent into account and evaulaute sponsor's example. If they want to buy low (price less than 900) and also don't want to miss out if the price doesn't come down and go up pass 1100, it would make more sense to submit two separate orders, a limit order and a stop order. Third, we should also establish a common understanding of stop-limit order because it represents the intent of users submitting order specifying both limit and stop price at a given point in time. A simple research on google yields:
Basically, stop-limit order is a stop order that triggers another limit order. From all above, I think that if we were to reject this issue, it should be on the ground that protocol will not support stop-limit order not that the order attributes can have both limit and stop price and will be executed when either condition is met. Because if the protocol do support stop-limit order, the logic to validate this order is definitely flawed, and can cause users's fund loss from unintended execution of users' order as this finding and mine describes. |
Hey @Tomiwasa0 and @nnez, thank you for your contributions! While I understand that you may believe the Sponsor's intentions to be counterintuitive, a configuration with a limit at I do not see a security vulnerability pointed out, and the code fulfills the Sponsor's intended purpose which can also be considered a sensible approach albeit perhaps rarely supported. |
Thanks @alex-ppg,
Trades are executed at Trade Price because it contains the perpEntryUpdate which serves as the entry price. limit order use in the protocol is not for entry but exit (Take Profit point) , limit is used for calculating the profit point where the position should be close
and stop limit where a user wants to leaves the market with minimum loss, This must always be below the Trade Price(entry) for a valid trade to be executed. Following the example used, For a trade to be executed below Oracle price, Trade Price(Entry) is the entry point and must be below not the limitprice. Kindly check out the struct for order execution
|
Hey @Tomiwasa0, thank you for your contribution. I strongly advise adhering to PJQA guidelines so as to avoid risking your SR access. I do not see any new information introduced in your reply and will retain my original ruling. No further feedback is expected for this submission. |
Lines of code
https://github.com/code-423n4/2024-05-predy/blob/main/src/markets/perp/PerpMarketLib.sol#L101
Vulnerability details
Users could have orders executed at prices that were not agreed upon by the limit and stop order parameters that were set. The worst case will lead to users having orders wrongly executed at a loss for the users, and in most cases, users will execute orders at unexpected and unfavorable prices.
The reason this is the case is because the stop limit order check uses
&&
instead of||
. Currently, it will only revert if both the limit order AND the stop loss order are met. This is wrong as it should revert if either check is not met.Impact
Orders will not be honored leading to potential loss of funds or entering at undesirable price
Proof of Concept
validateTrade
is calledelse if (limitPrice > 0 && stopPrice > 0)
is enteredvalidateLimitPrice
returns false sincelimitPrice
($4000) is greater than thetradePrice
($3800)validateStopPrice
returns true sincestopPrice
is not lower thanoraclePrice
validateTrade
check will now pass since bothvalidateLimitPrice
andvalidateStopPrice
did not return false.Tools Used
Manual analysis
Recommended Mitigation Steps
Change the
&&
to||
as follows:Assessed type
Invalid Validation
The text was updated successfully, but these errors were encountered: