Skip to content

chore(runway): cherry-pick fix(perps): potential rate limit on close positions#25456

Merged
joaoloureirop merged 3 commits intorelease/7.62.2from
cherry-pick-7-62-2-6f89dec
Jan 30, 2026
Merged

chore(runway): cherry-pick fix(perps): potential rate limit on close positions#25456
joaoloureirop merged 3 commits intorelease/7.62.2from
cherry-pick-7-62-2-6f89dec

Conversation

@runway-github
Copy link
Copy Markdown
Contributor

@runway-github runway-github bot commented Jan 30, 2026

Description

Complete the 429 rate limiting fix for position management operations.
The previous fix (commit 425beaead7) only addressed
updatePositionTPSL(). This PR extends the fix to closePosition(),
closePositions(), and updateMargin() methods.

Problem: These methods were using skipCache: true which forced
REST API calls on every operation, leading to 429 rate limiting errors
during prolonged app usage.

Solution:

  • Remove skipCache: true from closePositions() and updateMargin()
    to use WebSocket cache
  • For closePosition(), add optional position parameter so callers
    can pass the live WebSocket position directly, avoiding the need to
    fetch positions entirely
  • Update usePerpsClosePosition hook to pass the position it already
    has

Changelog

CHANGELOG entry: Fixed rate limiting errors (429) when closing positions
or updating margin after prolonged app usage

Related issues

Fixes: Rate limiting issues during position close/margin update
operations

Manual testing steps

Feature: Position close without rate limiting

  Scenario: User closes position after prolonged usage
    Given user has the app open for extended period (>30 minutes)
    And user has an open perps position

    When user closes the position
    Then the position closes successfully without 429 errors

  Scenario: User updates margin after prolonged usage
    Given user has the app open for extended period (>30 minutes)
    And user has an open perps position with isolated margin

    When user adjusts the margin
    Then the margin updates successfully without 429 errors

  Scenario: User closes all positions
    Given user has multiple open perps positions

    When user uses "close all positions" feature
    Then all positions close successfully without rate limiting errors

Screenshots/Recordings

Before

N/A - Bug fix for rate limiting, no UI changes

After

N/A - Bug fix for rate limiting, no UI changes

Pre-merge author checklist

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.

Note

Medium Risk
Switches critical trading actions to rely on WebSocket-cached positions instead of forced REST fetches, which reduces rate limiting but risks acting on slightly stale position data during rapid state changes.

Overview
Reduces HyperLiquid REST pressure during position management by removing skipCache: true position fetches in closePositions(), closePosition(), and updateMargin(), so these operations prefer the WebSocket/cache-backed getPositions() path.

This change is aimed at preventing 429 rate limiting during prolonged app usage when repeatedly closing positions or adjusting margin.

Written by Cursor Bugbot for commit a84367e. This will update automatically on new commits. Configure here.


Co-authored-by: Michal Szorad michal.szorad@consensys.net 6f89dec

….0 cp-7.62.2 (#25438)

Complete the 429 rate limiting fix for position management operations.
The previous fix (commit `425beaead7`) only addressed
`updatePositionTPSL()`. This PR extends the fix to `closePosition()`,
`closePositions()`, and `updateMargin()` methods.

**Problem:** These methods were using `skipCache: true` which forced
REST API calls on every operation, leading to 429 rate limiting errors
during prolonged app usage.

**Solution:**
- Remove `skipCache: true` from `closePositions()` and `updateMargin()`
to use WebSocket cache
- For `closePosition()`, add optional `position` parameter so callers
can pass the live WebSocket position directly, avoiding the need to
fetch positions entirely
- Update `usePerpsClosePosition` hook to pass the position it already
has

CHANGELOG entry: Fixed rate limiting errors (429) when closing positions
or updating margin after prolonged app usage

Fixes: Rate limiting issues during position close/margin update
operations

```gherkin
Feature: Position close without rate limiting

  Scenario: User closes position after prolonged usage
    Given user has the app open for extended period (>30 minutes)
    And user has an open perps position

    When user closes the position
    Then the position closes successfully without 429 errors

  Scenario: User updates margin after prolonged usage
    Given user has the app open for extended period (>30 minutes)
    And user has an open perps position with isolated margin

    When user adjusts the margin
    Then the margin updates successfully without 429 errors

  Scenario: User closes all positions
    Given user has multiple open perps positions

    When user uses "close all positions" feature
    Then all positions close successfully without rate limiting errors
```

N/A - Bug fix for rate limiting, no UI changes

N/A - Bug fix for rate limiting, no UI changes

- [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.

- [ ] 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.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches perps position-management flows (`closePosition`,
`closePositions`, `updateMargin`) and changes them to rely on
cached/WebSocket position data, which could surface edge cases if the
cache is stale or mismatched, but does not alter core order-placement
logic.
>
> **Overview**
> Reduces 429 errors in perps position management by stopping forced
REST position refreshes during `closePositions` and `updateMargin`, and
by updating `closePosition` to accept an optional live `position`
payload (with a cache-based fallback).
>
> Updates `usePerpsClosePosition` (and its tests) to pass the
already-available position through, avoiding extra `getPositions()`
calls during close flows.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ccfc17e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Michal Szorad <michal.szorad@consensys.net>
@runway-github runway-github bot requested a review from a team as a code owner January 30, 2026 18:00
@github-actions
Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-bots Bot team (for MetaMask Bot, Runway Bot, etc.) label Jan 30, 2026
@joaoloureirop joaoloureirop enabled auto-merge (squash) January 30, 2026 18:05
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

await this.ensureBuilderFeeApproval();

// Force fresh API data (not WebSocket cache) since we're about to mutate the position
const positions = await this.getPositions({ skipCache: true });
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passed position parameter ignored in closePosition method

Medium Severity

The closePosition() method always calls getPositions() and finds the position by coin, completely ignoring any position parameter passed from the hook. The usePerpsClosePosition hook passes position to avoid the API call (as documented in the comment), but closePosition() doesn't extract or use params.position. This defeats the stated rate limiting fix. Compare with updatePositionTPSL() which correctly destructures and uses position: livePosition from params when available.

Additional Locations (1)

Fix in Cursor Fix in Web


// Force fresh API data (not WebSocket cache) since we're about to mutate the position
const positions = await this.getPositions({ skipCache: true });
const positions = await this.getPositions();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment contradicts new cache-using behavior

Low Severity

The comment on line 3652 states "Force fresh API data (not WebSocket cache)" but the code was changed to getPositions() without skipCache: true, which now uses the WebSocket cache. This directly contradicts the code's actual behavior. The other methods modified in this PR (closePositions() and updateMargin()) had their comments correctly updated or removed, but this one was missed.

Fix in Cursor Fix in Web

@github-actions github-actions bot added size-XS and removed size-S labels Jan 30, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

⏭️ Smart E2E selection skipped - base branch is not main (base: release/7.62.2)

All E2E tests pre-selected.

View GitHub Actions results

@joaoloureirop joaoloureirop merged commit 69080ae into release/7.62.2 Jan 30, 2026
39 checks passed
@joaoloureirop joaoloureirop deleted the cherry-pick-7-62-2-6f89dec branch January 30, 2026 18:35
@github-actions github-actions bot locked and limited conversation to collaborators Jan 30, 2026
@metamaskbot
Copy link
Copy Markdown
Collaborator

No release label on PR. Adding release label release-7.62.2 on PR, as PR was cherry-picked in branch 7.62.2.

@metamaskbot metamaskbot added the release-7.62.2 Issue or pull request that will be included in release 7.62.2 label Feb 3, 2026
@metamaskbot
Copy link
Copy Markdown
Collaborator

No release label on PR. Adding release label release-7.62.2 on PR, as PR was cherry-picked in branch 7.62.2.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.62.2 Issue or pull request that will be included in release 7.62.2 size-XS team-bots Bot team (for MetaMask Bot, Runway Bot, etc.)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants