Skip to content

SDK-8: computeMaxLeverage uses BigInt floor division, understating leverage in UI #329

Description

@Ayomisco

Summary

computeMaxLeverage (src/math/trading.ts line 269) computes Number(10000n / initialMarginBps). The division is performed in BigInt, which floors the result, and then converted to Number. For non-round margin values the fractional leverage is silently discarded.

Example

computeMaxLeverage(3000n)
// BigInt path: Number(10000n / 3000n) = Number(3n) = 3
// Correct:     10000 / 3000          = 3.333...
// Error:       ~10% understatement of maximum leverage

For initialMarginBps = 1500n (15% margin = 6.67x), the function returns 6 instead of 6.67.

Impact

HIGH. The UI trade form uses computeMaxLeverage to set the slider maximum and to validate user leverage input. Understating max leverage means:

  1. Users cannot open positions up to the true on-chain limit, losing potential notional.
  2. A trader who is shown "max 6x" but is actually allowed 6.67x on-chain has an inaccurate picture of their risk capacity.

Fix

Use floating-point division: 10000 / Number(initialMarginBps).

initialMarginBps is always small (on-chain it is a u16 capped at 10_000), so Number() conversion is exact and precision is not a concern.

See the linked PR.

Severity

HIGH - incorrect max leverage calculation affects all non-round margin tiers

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions