Perpetual Engine Series Part 3: Funding Rates
Source: Dev.to
Introduction

In Part 2 we built the “heartbeat” of our engine: PnL Calculation. We ensured that every price tick accurately updates a trader’s equity with decimal precision. But a market cannot survive on price action alone. Without an anchor, the price of a perpetual contract would drift aimlessly away from the actual value of the underlying asset.
That anchor is Funding Rates. It is the regulatory mechanism that ensures the perpetual market remains fair, balanced, and tethered to reality. Below is how I implemented this “incentive engine” in Rust.
1. What are Funding Rates? (The Market’s Anchor)
In perpetual futures there is no expiration date. To prevent the contract price from deviating too far from the Spot Price, the system uses a peer‑to‑peer payment exchange.
- When Longs dominate (Bullish): Perpetual Price > Spot Price → Longs pay Shorts.
- When Shorts dominate (Bearish): Perpetual Price < Spot Price → Shorts pay Longs.
Implementation in Rust
Result {
let rate = self.funding_rate; // e.g., 0.0001 for 0.01%
let mut total_applied = Decimal::ZERO;
for position in self.positions.values_mut() {
let notional_value = position.quantity * self.mark_price;
let funding_amount = notional_value * rate;
// Longs pay when rate is positive, Shorts receive
if position.position_type == PositionType::Long {
position.pnl -= funding_amount;
total_applied += funding_amount;
} else {
position.pnl += funding_amount;
total_applied -= funding_amount;
}
}
self.last_funding_time = std::time::Instant::now();
Ok(FundingResult { total_applied, rate })
}
4. The “Silent Killer”: Funding‑Triggered Liquidation
This is the most critical integration point between Part 1 (Liquidations) and Part 3. A position can be liquidated even if the price doesn’t move.
If a trader is at max leverage and has very little “maintenance margin” left, a single funding payment can push their PnL into the red, triggering an immediate liquidation.
Logic Flow
- Trigger: Timer hits 3600 seconds.
- Apply: Subtract/add funding from all open positions’ PnL.
- Audit: Immediately run the
should_liquidatecheck. - Execute: Close positions that no longer meet margin requirements.
5. Multi‑User Scalability with Tokio
In a production‑ready engine you can’t block the order book to calculate funding. Using tokio::time::interval runs the funding logic in a background task, keeping the engine responsive.
Background Task
tokio::spawn(async move {
let mut interval = tokio::time::interval(Duration::from_secs(3600));
loop {
interval.tick().await;
// Acquire write lock and apply funding to all users
engine.apply_funding().await?;
}
});
6. Summary Table
| Concept | What | Why |
|---|---|---|
| Funding Rate | % paid between traders | Keeps perp price near spot price. |
| Notional Value | Qty × Price | Ensures fees scale with total market exposure. |
| Zero‑Sum | Longs pay Shorts (or vice‑versa) | Exchange remains a neutral facilitator. |
| Liquidation Risk | Margin erosion via fees | High leverage can be killed by funding alone. |
Conclusion
Funding rates turn a simple “betting” engine into a sophisticated financial instrument. By implementing this in Rust we leverage thread safety to ensure that, while thousands of trades are happening, the “funding heartbeat” accurately adjusts every balance without a single cent going missing.