Skip to main content

Why funding exists

Perpetra’s perpetual price is set by its own orderbook, which can drift from the real spot price of the underlying asset. Funding is a periodic payment between longs and shorts that pulls the perpetual price back toward spot: whichever side is “winning” the price drift pays the other side.

The rate formula

Each market’s funding rate is based on the premium between mark price and index (spot) price:
That premium is then clamped to the market’s configured max rate:
Every market also has an interestRateBps parameter in its config. It’s reserved for a future premium-plus-interest model but isn’t applied in the current implementation, the rate is the clamped premium alone.
Sign convention:
  • Positive rate: mark price is trading above index price. Longs pay shorts.
  • Negative rate: mark price is trading below index price. Shorts pay longs.

How the rate updates

A funding keeper calls updateFundingRate(marketId) on a fixed schedule (the market’s fundingInterval, e.g. every hour). Each call is rate-limited: it reverts if less time than fundingInterval has passed since the last tick. On each tick, the contract pulls fresh mark and index prices from the Oracle, computes the new rate, and advances a per-market cumulative index:
timeDelta is the actual time since the last update, so a late tick still accrues the correct amount rather than snapping to a fixed interval’s worth. This update only touches the market’s shared state. It does not update any individual position, that happens lazily, per position, whenever it’s touched.

How a position settles funding

Every position stores a snapshot of the cumulative index from the moment it was last settled (positionFundingIndex). The Engine calls calcFundingOwed whenever a position is opened, closed, increased, decreased, or liquidated:
  • For longs, fundingOwed is rawFunding as computed. Positive means the position owes funding, deducted from collateral.
  • For shorts, fundingOwed is -rawFunding. When longs are paying (positive delta), shorts receive.
After settlement, the position’s snapshot is updated to the current index, so the next calculation only counts funding accrued since that point.
estimateFundingOwed runs the same math as a read-only call, used by the frontend to show “estimated funding” without actually settling anything.

Checking the current rate

getCurrentRate(marketId) returns the rate in three forms for display purposes:
  • rate: raw signed value scaled to RATE_PRECISION (1e18)
  • rateBps: the same rate converted to basis points
  • isLongPaying: true if the rate is positive
timeUntilNextFunding(marketId) returns the seconds remaining before the next tick is allowed, for countdown displays.