Commit 3fa1e22
authored
fix(perps): TP/SL orders disappear after creating a market order (#28073)
## **Description**
**Bug 1 (TAT-2636):** The WS-cache path in `updatePositionTPSL` was
missing an `isPositionTpsl` filter, causing it to cancel all trigger
reduce-only orders (including `normalTpsl` children of pending limit
orders) instead of only position-bound TP/SL orders. The REST fallback
already had the correct filter. This fix adds the matching
`isPositionTpsl` check to the cache path.
**Bug 2 (TAT-2835):** Fixing bug 1 exposed a display-side issue: the
position TP/SL display logic (both REST `getPositions` and WS cached
orders path in `extractTPSLFromOrders`) wasn't filtering by
`isPositionTpsl`, so when normalTpsl and positionTpsl orders coexist,
the position would show the limit order's TP/SL values instead of the
position-bound ones. Added `isPositionTpsl` filter to both display
paths.
## **Changelog**
CHANGELOG entry: Fixed a bug where placing a market order with TP/SL
would incorrectly cancel TP/SL orders belonging to existing pending
limit orders, and fixed position TP/SL display showing limit order
values instead of position-bound values.
## **Related issues**
Fixes:
[TAT-2636](https://consensyssoftware.atlassian.net/browse/TAT-2636)
Fixes:
[TAT-2835](https://consensyssoftware.atlassian.net/browse/TAT-2835)
## **Manual testing steps**
```gherkin
Feature: TP/SL orders from limit orders preserved after market order with TP/SL
Scenario: user places a market order with TP/SL when a limit order with TP/SL already exists
Given testnet mode is active
And user has placed a BTC limit order at $50,000 with TP/SL (normalTpsl grouping)
And the normalTpsl child orders are visible in open orders
When user places a BTC market order with TP/SL (new position, triggers updatePositionTPSL)
Then positionTpsl orders are created for the new position
And the normalTpsl TP/SL children of the limit order are NOT cancelled
And the position displays the market order's TP/SL values, not the limit order's
```
## **Screenshots/Recordings**
_Evidence available in task artifacts — will be added by reviewer if
needed._
### **Before**
<!-- Recipe fails at `verify-display-matches-position-tpsl`:
displayedTp=62500 (limit order value), expectedTp=74285 -->
### **After**
<!-- Recipe passes 12/12: displayedTp=74285 matches expectedTp=74285
(position-bound value) -->
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
## **Recipe proof (before/after)**
| | Key assertion | displayedTp | expectedTp | Result |
|---|---|---|---|---|
| **Without fix** | `verify-display-matches-position-tpsl` | **62,500**
(limit order's TP) | 74,285 | **FAIL** |
| **With fix** | `verify-display-matches-position-tpsl` | **74,285**
(position's TP) | 74,285 | **PASS** |
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches perps TP/SL cancellation and position display logic; incorrect
filtering could cancel the wrong orders or show wrong TP/SL values in
trading UI.
>
> **Overview**
> Fixes TP/SL handling to distinguish *position-bound* TP/SL orders from
`normalTpsl` child orders.
>
> `updatePositionTPSL` now applies the same `isPositionTpsl` filter when
using the WebSocket orders cache as it already did in the REST fallback,
preventing cancellation of limit-order TP/SL children. Position TP/SL
extraction/display is also updated (both `getPositions` and
`HyperLiquidSubscriptionService.#extractTPSLFromOrders`) to ignore
non-position-bound TP/SL when `UsePositionBoundTpsl` is enabled.
>
> Adds/updates tests to cover mixed cached-order scenarios and ensures
`isPositionTpsl`/`triggerPrice` are propagated in subscription order
adaptation.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
371108e. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[TAT-2636]:
https://consensyssoftware.atlassian.net/browse/TAT-2636?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ1 parent 7362ef0 commit 3fa1e22
4 files changed
Lines changed: 157 additions & 4 deletions
File tree
- app/controllers/perps
- providers
- services
Lines changed: 133 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| 20 | + | |
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
| |||
3570 | 3571 | | |
3571 | 3572 | | |
3572 | 3573 | | |
| 3574 | + | |
| 3575 | + | |
| 3576 | + | |
| 3577 | + | |
| 3578 | + | |
| 3579 | + | |
| 3580 | + | |
| 3581 | + | |
| 3582 | + | |
| 3583 | + | |
| 3584 | + | |
| 3585 | + | |
| 3586 | + | |
| 3587 | + | |
| 3588 | + | |
| 3589 | + | |
| 3590 | + | |
| 3591 | + | |
| 3592 | + | |
| 3593 | + | |
| 3594 | + | |
| 3595 | + | |
| 3596 | + | |
| 3597 | + | |
| 3598 | + | |
| 3599 | + | |
| 3600 | + | |
| 3601 | + | |
| 3602 | + | |
| 3603 | + | |
| 3604 | + | |
| 3605 | + | |
| 3606 | + | |
| 3607 | + | |
| 3608 | + | |
| 3609 | + | |
| 3610 | + | |
| 3611 | + | |
| 3612 | + | |
| 3613 | + | |
| 3614 | + | |
| 3615 | + | |
| 3616 | + | |
| 3617 | + | |
| 3618 | + | |
| 3619 | + | |
| 3620 | + | |
| 3621 | + | |
| 3622 | + | |
| 3623 | + | |
| 3624 | + | |
| 3625 | + | |
| 3626 | + | |
| 3627 | + | |
| 3628 | + | |
| 3629 | + | |
| 3630 | + | |
| 3631 | + | |
| 3632 | + | |
| 3633 | + | |
| 3634 | + | |
| 3635 | + | |
| 3636 | + | |
| 3637 | + | |
| 3638 | + | |
| 3639 | + | |
| 3640 | + | |
| 3641 | + | |
| 3642 | + | |
| 3643 | + | |
| 3644 | + | |
| 3645 | + | |
| 3646 | + | |
| 3647 | + | |
| 3648 | + | |
| 3649 | + | |
| 3650 | + | |
| 3651 | + | |
| 3652 | + | |
| 3653 | + | |
| 3654 | + | |
| 3655 | + | |
| 3656 | + | |
| 3657 | + | |
| 3658 | + | |
| 3659 | + | |
| 3660 | + | |
| 3661 | + | |
| 3662 | + | |
| 3663 | + | |
| 3664 | + | |
| 3665 | + | |
| 3666 | + | |
| 3667 | + | |
| 3668 | + | |
| 3669 | + | |
| 3670 | + | |
| 3671 | + | |
| 3672 | + | |
| 3673 | + | |
| 3674 | + | |
| 3675 | + | |
| 3676 | + | |
| 3677 | + | |
| 3678 | + | |
| 3679 | + | |
| 3680 | + | |
| 3681 | + | |
| 3682 | + | |
| 3683 | + | |
| 3684 | + | |
| 3685 | + | |
| 3686 | + | |
| 3687 | + | |
| 3688 | + | |
| 3689 | + | |
| 3690 | + | |
| 3691 | + | |
| 3692 | + | |
| 3693 | + | |
| 3694 | + | |
| 3695 | + | |
| 3696 | + | |
| 3697 | + | |
| 3698 | + | |
| 3699 | + | |
| 3700 | + | |
| 3701 | + | |
| 3702 | + | |
| 3703 | + | |
| 3704 | + | |
| 3705 | + | |
3573 | 3706 | | |
3574 | 3707 | | |
3575 | 3708 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4350 | 4350 | | |
4351 | 4351 | | |
4352 | 4352 | | |
4353 | | - | |
4354 | | - | |
| 4353 | + | |
| 4354 | + | |
4355 | 4355 | | |
4356 | 4356 | | |
| 4357 | + | |
| 4358 | + | |
4357 | 4359 | | |
4358 | 4360 | | |
4359 | 4361 | | |
4360 | 4362 | | |
4361 | 4363 | | |
4362 | 4364 | | |
| 4365 | + | |
| 4366 | + | |
4363 | 4367 | | |
4364 | 4368 | | |
4365 | 4369 | | |
4366 | 4370 | | |
4367 | | - | |
4368 | 4371 | | |
4369 | 4372 | | |
4370 | 4373 | | |
| |||
4953 | 4956 | | |
4954 | 4957 | | |
4955 | 4958 | | |
| 4959 | + | |
| 4960 | + | |
4956 | 4961 | | |
4957 | 4962 | | |
4958 | 4963 | | |
4959 | 4964 | | |
4960 | | - | |
| 4965 | + | |
| 4966 | + | |
| 4967 | + | |
4961 | 4968 | | |
4962 | 4969 | | |
4963 | 4970 | | |
| |||
Lines changed: 4 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
62 | 66 | | |
63 | 67 | | |
64 | 68 | | |
| |||
Lines changed: 9 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
732 | 732 | | |
733 | 733 | | |
734 | 734 | | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
735 | 744 | | |
736 | 745 | | |
737 | 746 | | |
| |||
0 commit comments