Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
28a161c
fix: tighten validate_reserve_shape — remaining+release<=anchor + pen…
aeyakovenko Apr 16, 2026
512252d
fix: reject zero-sized present buckets in validate_reserve_shape
aeyakovenko Apr 16, 2026
63abb5f
fix: R_i entry invariant + bankruptcy NoPositiveIncrease + insurance …
aeyakovenko Apr 16, 2026
b78a9d3
fix: update proofs_audit for garbage_collect_dust Result<u32>
aeyakovenko Apr 16, 2026
94df734
fix: equity overflow saturation flipped to fail-conservative
aeyakovenko Apr 16, 2026
331810a
feat: implement v12.18 admission-pair + sticky h_max + touch accelera…
aeyakovenko Apr 17, 2026
ffbf54e
feat: add v12.18 admission/acceleration Kani proofs
aeyakovenko Apr 17, 2026
f486a22
fix: integrate admit_outstanding_reserve_on_touch into touch lifecycle
aeyakovenko Apr 17, 2026
d761f0f
fix: validate_admission_pair rejects admit_h_max == 0 (Bug 9)
aeyakovenko Apr 17, 2026
6b6321b
fix: dt envelope + degenerate resolve branch (Bugs 1 & 2)
aeyakovenko Apr 17, 2026
cf4f9d3
fix: Bug 92 + Bug 73 + Kani proofs K-71 + K-104 (Pass 2 audit)
aeyakovenko Apr 17, 2026
443de02
fix: Bugs 3, 4, 5, 6, 9 from v12.18.1 pass 3 audit
aeyakovenko Apr 17, 2026
ef2a754
fix: Pass 3 cleanup — record_uninsured_protocol_loss + dead code + ch…
aeyakovenko Apr 17, 2026
38bcb32
proofs: strengthen weak/vacuous proofs identified in substantiveness …
aeyakovenko Apr 17, 2026
1b397cc
proofs: fix resolve-bypass tests + strengthen counter tracking
aeyakovenko Apr 17, 2026
b87b5b5
proofs: fix 24 test failures after v12.18 + envelope + fail-conservat…
aeyakovenko Apr 17, 2026
5666357
v12.18.1 opening-fee/materialization removal (spec item 1)
aeyakovenko Apr 17, 2026
9cbc515
v12.18.1 per-market active-position cap (spec item 2)
aeyakovenko Apr 17, 2026
9c0fdde
v12.18.1 uninsured-loss bookkeeping no-op (spec item 3)
aeyakovenko Apr 17, 2026
3bf4ca1
v12.18.1 reserve validation ordering + bounds (spec item 4)
aeyakovenko Apr 17, 2026
aed6012
v12.18.1 fallible sticky-admission helper (spec item 5)
aeyakovenko Apr 17, 2026
4445b92
v12.18.1 API surface tightening + keeper_crank clamp→error (items 8-9)
aeyakovenko Apr 17, 2026
ea5205c
v12.18.1 public endpoint postcondition checks (item 7)
aeyakovenko Apr 17, 2026
ea735af
v12.18.1 resolved semantics spec-exactness (item 6)
aeyakovenko Apr 17, 2026
088b668
proofs: strengthen admission/postcondition/keeper_crank coverage
aeyakovenko Apr 17, 2026
498543d
v12.18.1 reserve atomicity + deposit_fee_credits + O(1) materialize
aeyakovenko Apr 17, 2026
43c8bfc
proofs: close remaining reserve-validation gaps (reviewer pass)
aeyakovenko Apr 17, 2026
6619269
tests: strengthen assertions in added Kani + unit tests
aeyakovenko Apr 17, 2026
7435d77
fix: resolve band check always runs + deposit_fee_credits rejects ove…
aeyakovenko Apr 17, 2026
23abe05
fix: free_slot capital/fee_credits checks + init_in_place full canon …
aeyakovenko Apr 17, 2026
ad47bb0
feat: v12.18.4 per-account recurring-fee checkpoint
aeyakovenko Apr 18, 2026
6e9d2a5
feat: v12.18.5 explicit resolve_mode + R_i<=max(PNL,0) postcondition
aeyakovenko Apr 18, 2026
8b1a012
fix: reviewer pass — current_slot cap, zero-hmax init reject, freelis…
aeyakovenko Apr 18, 2026
04a111c
fix: reviewer pass 2 — engine-picked fee anchor, freelist hardening, …
aeyakovenko Apr 18, 2026
13512f4
tests: audit — strengthen spec coverage, mark implementation-hardening
aeyakovenko Apr 18, 2026
8685828
fix: reviewer pass 3 — LP annotation doc, hardening, atomicity
aeyakovenko Apr 18, 2026
0f28779
docs: fold owner pubkey into spec §2.1.1 wrapper-owned annotations
aeyakovenko Apr 18, 2026
379c3ca
fix: reject now_slot jumps past live accrual envelope (liveness DoS)
aeyakovenko Apr 18, 2026
072a62e
fix: apply live accrual envelope check to deposit_not_atomic
aeyakovenko Apr 18, 2026
af18b09
fix: gate dt envelope to funding-active accrual; idle markets can fas…
aeyakovenko Apr 18, 2026
470b273
fix: enforce cumulative F saturation lifetime at init (min_funding_li…
aeyakovenko Apr 18, 2026
190656d
fix: pre-check active-position cap as net delta in execute_trade
aeyakovenko Apr 18, 2026
c602ce9
fix: ADL must leave K future-mark headroom; correct lifetime-year doc
aeyakovenko Apr 18, 2026
8837b45
fix: zero live K_side / F_side on begin_full_drain_reset
aeyakovenko Apr 18, 2026
42f4790
fix: execute_trade flushes dust-only empty sides before opening fresh OI
aeyakovenko Apr 18, 2026
2f51f96
fix: materialize_at must reject idx >= cfg_max_accounts
aeyakovenko Apr 19, 2026
b8f0572
fix: two accounting blockers (stranded vault surplus; resolved-close …
aeyakovenko Apr 19, 2026
fea80d8
fix: keeper_crank skips candidates with stale last_fee_slot
aeyakovenko Apr 19, 2026
d0906ae
revert: engine-side fee-sync preconditions; keep fee ordering in wrapper
aeyakovenko Apr 19, 2026
2b34c86
proofs: refresh 7 stale Kani proofs after engine-semantics changes
aeyakovenko Apr 19, 2026
8264871
audit: Kani proof audit snapshot — 261/262 PASS, 1 TIMEOUT, 0 FAIL
aeyakovenko Apr 19, 2026
43a08e7
audit: final Kani audit — 287/288 PASS, 1 TIMEOUT, 0 FAIL
aeyakovenko Apr 19, 2026
bf9c093
feat: add small/medium slab capacity feature flags
aeyakovenko Apr 20, 2026
95665cb
config: tighten funding ceiling to 1e4 e9/slot, raise accrual dt to 10M
aeyakovenko Apr 21, 2026
0b02e8f
docs: correct year math for cumulative-F lifetime
aeyakovenko Apr 21, 2026
dd5b34c
proofs: refresh 3 Kani proofs after funding-ceiling + sweep changes
aeyakovenko Apr 21, 2026
79f1734
audit: final Kani audit after funding-cap tightening — 287/288 PASS
aeyakovenko Apr 21, 2026
335d74c
audit: annotate proof_execute_trade_full_margin_enforcement TIMEOUT
aeyakovenko Apr 21, 2026
b47eb93
remove: insurance_floor from engine and spec
aeyakovenko Apr 22, 2026
0eae228
cleanup: drop vestigial helpers (add_u128, sub_u128, dead fee_cash vars)
aeyakovenko Apr 22, 2026
7e698b9
spec: align resolved-close signatures and fee-ordering with engine
aeyakovenko Apr 22, 2026
54a2365
spec: cfg_min_initial_deposit + wrapper-recurring-fee is the anti-spa…
aeyakovenko Apr 22, 2026
5f6075b
remove: cfg_min_initial_deposit — anti-spam is a wrapper concern
aeyakovenko Apr 22, 2026
3f55f87
audit: post-min_initial_deposit-removal Kani audit — 286/286 PASS
aeyakovenko Apr 22, 2026
ab2a4f1
v12.19 WIP: add cfg_max_price_move_bps_per_slot + init-time envelope
aeyakovenko Apr 23, 2026
3eda21d
v12.19 WIP: fix all legacy unit tests for envelope compatibility
aeyakovenko Apr 23, 2026
28d0213
v12.19 WIP: admission gate, threshold validation, deterministic trade…
aeyakovenko Apr 23, 2026
1b3de8c
v12.19 WIP: two-phase keeper_crank with Phase 2 round-robin sweep
aeyakovenko Apr 23, 2026
ce2cc7a
v12.19 WIP: add Kani proof harnesses for v12.19 spec deltas
aeyakovenko Apr 23, 2026
d550cb7
v12.19 WIP: atomicity rollback + composition-safety Kani proofs
aeyakovenko Apr 23, 2026
9f5ce98
v12.19 critical safety + correctness fixes
aeyakovenko Apr 23, 2026
5d2e841
v12.19 proof audit pass 1: strengthen consumption-rollback + goal-52 …
aeyakovenko Apr 23, 2026
bc7f119
v12.19 proof audit pass 2: fix cascade_safety + trade_touch proofs
aeyakovenko Apr 23, 2026
70857de
v12.19 pass 2: resolved-close guard, bool-return cleanup, defensive b…
aeyakovenko Apr 23, 2026
f8af0c7
v12.19 pass 3: spec-local cap postcondition + init_in_place safety co…
aeyakovenko Apr 23, 2026
e52d337
v12.19 proof audit pass 3: add monotone consumption + simplify touch-…
aeyakovenko Apr 23, 2026
d27d4b7
v12.19 pass 4: validate-then-mutate + withdraw cast + free-list + dep…
aeyakovenko Apr 23, 2026
70c88b6
v12.19 pass 5: §12.21 doc comments, old_rel cleanup, stale doc fixes
aeyakovenko Apr 23, 2026
ff3863d
v12.19 pass 6: spec-local active-position cap + dead-code cleanup
aeyakovenko Apr 23, 2026
7420a0d
v12.19 pass 7: raise MAX_TOUCHED cap, sorted-insert, bitmap sticky set
aeyakovenko Apr 23, 2026
f248d80
v12.19 pass 8: is_terminal_ready defense-in-depth
aeyakovenko Apr 23, 2026
85aad85
v12.19 pass 9: clean up dead bindings flagged by the compiler
aeyakovenko Apr 23, 2026
5678746
v12.19 pass 10: TDD-driven fixes for free_slot, enqueue_adl, postcond…
aeyakovenko Apr 23, 2026
229f530
v12.19: remove all backwards-compat shims + vestigial deposit oracle arg
aeyakovenko Apr 23, 2026
e56d350
v12.19: collapse MAX_MATERIALIZED_ACCOUNTS onto params.max_accounts
aeyakovenko Apr 23, 2026
346994a
v12.19: tighten mode postconditions, accrue pre/post asserts, enum docs
aeyakovenko Apr 24, 2026
fe1d2d8
v12.19: align spec invariants and strengthen proofs
aeyakovenko Apr 24, 2026
e8774bf
fix engine proof-aligned margin gates
aeyakovenko Apr 24, 2026
6652411
Harden risk engine invariants
aeyakovenko Apr 24, 2026
33c2b04
Fail closed on corrupt engine state
aeyakovenko Apr 24, 2026
bc88671
Bound solvency and harden fee credits
aeyakovenko Apr 24, 2026
1299bbd
Harden account-local fee state checks
aeyakovenko Apr 24, 2026
babfe83
Harden engine state invariants
aeyakovenko Apr 24, 2026
f93336b
Add insurance accounting regressions
aeyakovenko Apr 24, 2026
7d89767
Strengthen proof audit harnesses
aeyakovenko Apr 24, 2026
3969c31
Update full Kani audit timings
aeyakovenko Apr 25, 2026
3234d2c
merge: upstream/master @ 3969c31 (v12.19 baseline) into fork main
dcccrypto Apr 25, 2026
b29df2e
Document price movement bound invariant
aeyakovenko Apr 25, 2026
c32bc0b
Rewrite README around three invariants
aeyakovenko Apr 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ proptest = "1.4"

[features]
default = []
test = [] # Use MAX_ACCOUNTS=64 for tests
test = [] # MAX_ACCOUNTS=64 for tests
stress = [] # Expose test_visible methods but keep MAX_ACCOUNTS=4096
fuzz = ["test"] # Enable fuzzing tests (includes test feature for test_visible helpers)
small = [] # MAX_ACCOUNTS=256 (~0.68 SOL rent)
medium = [] # MAX_ACCOUNTS=1024 (~2.7 SOL rent)
small = [] # MAX_ACCOUNTS=256 for low-traffic markets
medium = [] # MAX_ACCOUNTS=1024 for mid-range markets
audit-scan = [] # Enable full account-table invariant scans on public exits

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(kani)'] }
Expand Down
129 changes: 100 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,33 @@

Risk engine library for permissionless perpetual futures on Solana.

A predictable alternative to ADL queues.
A predictable perpetual-futures risk engine built around backed exits, lazy
overhang clearing, and bounded cranks.

If you want the `xy = k` of perpetual futures risk engines -- something you can reason about, audit, and run without human intervention -- the cleanest move is simple: stop treating profit like money. Treat it like what it really is in a stressed exchange: a junior claim on a shared balance sheet.

> No user can ever withdraw more value than actually exists on the exchange balance sheet.

## Two Problems, Two Mechanisms
## Three Invariants

A perp exchange has two fairness problems:
A stressed perp exchange has three jobs:

1. **Exit fairness:** when the vault is stressed, who gets paid and how much?
2. **Overhang clearing:** when positions go bankrupt, how does the opposing side absorb the residual without deadlocking the market?
1. **Backed exits:** when the vault is stressed, nobody can extract more value than the balance sheet can pay.
2. **Fair overhang clearing:** when positions go bankrupt, the residual is absorbed pro rata instead of by a discretionary ADL queue.
3. **Bounded cranks:** when the oracle moves, the live book is repriced only inside the configured one-step risk budget.

Percolator solves them with two independent mechanisms that compose cleanly:
Percolator composes three mechanisms:

- **H** (the haircut ratio) keeps all exits fair.
- **A/K** (the lazy side indices) keeps all residual overhang clearing fair, and guarantees markets always return to healthy.
- **H** (the haircut ratio) makes positive PnL a junior claim on residual value.
- **A/K/F** (lazy side indices) settles mark moves, funding, and ADL overhang without selecting individual losers.
- **The price/funding envelope** bounds every exposed accrual step before K/F/price/slot state can mutate.

Comment on lines +14 to 27

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Version signaling is inconsistent with the rest of the document.

Lines 14–27 present the v12.19 model, but later sections still label the feature/spec baseline as v12.17 (e.g., Line 180 and Line 209). For operator and auditor traceability, keep one explicit version target throughout or add a clear “mixed-version” note.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 14 - 27, The README mixes version labels (the top
section describes the v12.19 model while later sections still state v12.17);
pick a single canonical version or add a clear “mixed-version” note and then
update all version mentions to match that choice—search for the explicit version
strings "v12.19" and "v12.17" and make them consistent across the document (or
insert a brief note after the "Three Invariants" / "Percolator" headings
explaining that some sections remain at v12.17 and why).

---

## H: Fair Exits
## H: Backed Exits

Capital is senior. Profit is junior. A single global ratio determines how much profit is real.
Capital is senior. Profit is junior. A single global ratio determines how much
released positive PnL is actually backed.

```
Residual = max(0, V - C_tot - I)
Expand All @@ -36,44 +40,62 @@ Residual = max(0, V - C_tot - I)
PNL_matured_pos_tot
```

If fully backed, `h = 1`. If stressed, `h < 1`. Every profitable account sees the same fraction of its *released* profit:
If fully backed, `h = 1`. If stressed, `h < 1`. Every profitable account sees
the same fraction of its *released* positive PnL:

```
ReleasedPos_i = max(PNL_i, 0) - R_i
effective_pnl_i = floor(ReleasedPos_i * h)
```

Fresh profit sits in a per-account reserve `R_i` and converts to released (matured) profit through a warmup period. Only matured profit enters the haircut denominator (`PNL_matured_pos_tot`) and the per-account effective PnL. This is the core oracle-manipulation defense — an attacker who spikes a price sees their unrealized gain locked in `R_i`, excluded from both the ratio and their withdrawable amount, until the warmup window passes.
Fresh profit sits in a per-account reserve `R_i` and converts to released
(matured) profit through admission and warmup. Only admitted matured profit
enters the haircut denominator (`PNL_matured_pos_tot`) and per-account effective
PnL.

This is the core anti-oracle-manipulation defense. An attacker who spikes a
price sees live gain locked in reserve, excluded from both the ratio and their
withdrawable amount, until the instruction policy admits it. Public wrappers
using untrusted live oracle or execution-price PnL must use nonzero admission
warmup; stress-threshold gating is not a substitute.

No rankings, no queue priority, no first-come advantage. The floor rounding is conservative — the sum of all effective PnL never exceeds what exists in the vault.

When the system is stressed, `h` falls and less converts. When losses settle or buffers recover, `h` rises. Self-healing.
When the system is stressed, `h` falls and less profit converts. When losses
settle or buffers recover, `h` rises. Self-healing.

Flat accounts are always protected — `h` only gates profit extraction, never touches deposited capital.

---

## A/K: Fair Overhang Clearing
## A/K/F: Fair Overhang Clearing

When a leveraged account goes bankrupt, two things need to happen: remove the position quantity from open interest, and distribute any uncovered deficit across the opposing side.

Traditional ADL queues pick specific counterparties and force-close them. Percolator replaces the queue with two global coefficients per side:
Traditional ADL queues pick specific counterparties and force-close them.
Percolator replaces the queue with lazy side indices:

- **A** scales everyone's effective position equally.
- **K** accumulates all PnL events (mark, funding, deficit socialization) into one index.
- **K** accumulates mark and ADL overhang effects.
- **F** accumulates funding effects.

```
effective_pos(i) = floor(basis_i * A / a_basis_i)
pnl_delta(i) = floor(|basis_i| * (K - k_snap_i) / (a_basis_i * POS_SCALE))
pnl_delta(i) =
floor(|basis_i| * ((K - k_snap_i) * FUNDING_DEN + (F - f_snap_i))
/ (a_basis_i * POS_SCALE * FUNDING_DEN))
```

When a liquidation reduces OI, `A` decreases — every account on that side shrinks by the same ratio. When a deficit is socialized, `K` shifts — every account absorbs the same per-unit loss.
When a liquidation reduces OI, `A` decreases -- every account on that side
shrinks by the same ratio. When a deficit is socialized, `K` shifts -- every
account absorbs the same per-unit loss. Funding moves through `F` the same way:
accounts settle against their snapshots when touched.

No account is singled out. Settlement is O(1) per account and order-independent.

### Markets Always Return to Healthy
### Markets Return to Healthy

A/K guarantees forward progress through a deterministic cycle:
A/K/F guarantees forward progress through a deterministic cycle:

**DrainOnly** — when `A` drops below a precision threshold, no new OI can be added. Positions can only close.

Expand All @@ -85,22 +107,71 @@ No admin intervention. No governance vote. The state machine always makes progre

---

## Price/Funding Envelope

The third invariant is a system bound: an exposed market cannot be cranked
through an arbitrary oracle or funding jump in one step.

For any crank that advances the engine price while open interest exists, the
allowed price move is capped by elapsed slots:

```
abs(P_new - P_last) * 10_000
<= max_price_move_bps_per_slot * dt * P_last
```
Comment on lines +118 to +121

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add a language tag to the fenced formula block (markdownlint MD040).

Line 118 opens a fence without a language identifier. Please set one (for example text) to satisfy lint and keep formatting consistent.

Suggested patch
-```
+```text
 abs(P_new - P_last) * 10_000
     <= max_price_move_bps_per_slot * dt * P_last
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 118-118: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 118 - 121, The fenced formula block containing the
inequality with symbols P_new, P_last, max_price_move_bps_per_slot and dt is
missing a language tag; update the opening fence from ``` to a tagged fence such
as ```text (or another appropriate tag) so the block becomes ```text and
satisfies markdownlint MD040 while preserving the formula formatting.


Equivalently, the normalized move is bounded by
`max_price_move_bps_per_slot * dt / 10_000`.

At a high level, the maximum price movement between exposed cranks is bounded by
the system's risk budget. If the market is configured around `L` times leverage,
the safe one-step move is roughly on the order of `1 / L`, with room reserved
for funding, liquidation fees, integer rounding, and fee floors/caps.

This turns "crank often enough" into a hard solvency boundary rather than an
operator preference. A stale or fast-moving oracle target must be fed into the
engine as a capped staircase of effective prices. Same-slot exposed cranks use
the previous price; they cannot mark live OI through a zero-time jump.

Active price or funding accrual also has a maximum elapsed-slot window; beyond
that, ordinary live catch-up fails closed and the wrapper must use recovery or
resolution.

Initialization proves a per-risk-notional envelope for the worst allowed
price/funding step plus liquidation fees. At runtime, before any K/F/price/slot
mutation, the engine checks that the next effective step stays inside that
envelope. If it does not fit, the crank fails closed instead of moving the
market into an unbudgeted state.

---

## How They Compose

| | H | A/K |
|---|---|---|
| **Solves** | Exit fairness | Overhang clearing |
| **Math** | Pro-rata profit scaling | Pro-rata position/deficit scaling |
| **Triggered by** | Withdrawal or conversion | Bankrupt liquidation |
| **Recovery** | Automatic as Residual improves | Deterministic three-phase reset |
| | H | A/K/F | Price/funding envelope |
|---|---|---|---|
| **Solves** | Backed exits | Bankrupt overhang clearing | Bounded live repricing |
| **Math** | Pro-rata profit scaling | Pro-rata position, mark, funding, and deficit scaling | Exact per-risk-notional loss budget |
| **Triggered by** | Withdrawal, conversion, settlement | Mark, funding, liquidation, reset | Live accrual/crank |
| **Failure mode** | Less profit is released | Side drains and resets | Crank fails closed or wrapper stair-steps |

Together:
- No user can withdraw more than exists.
- No user is singled out for forced closure.
- Markets always recover.
- Flat accounts keep their deposits.

A/K fairness is exact for open-position economics. H fairness is exact only for the currently stored realized claim set, not for the economically "true" claim set you would get after globally cranking everyone.
- Risk-increasing trades cannot count their own favorable execution slippage as margin.
- Markets recover through deterministic side resets.
- Exposed cranks are bounded to the configured price/funding budget.
- Raw oracle targets are wrapper-owned; the engine only sees capped effective prices.

A/K/F fairness is exact for open-position economics. H fairness is exact for the
currently stored realized claim set, not for the economically "true" claim set
you would get after globally touching every account.

The engine is not the whole public protocol by itself. A compliant wrapper must
enforce authorization, source and clamp oracle/funding inputs, use nonzero live
PnL admission for untrusted public flows, sync recurring fees when enabled, and
reject extraction-sensitive actions while raw oracle target and effective engine
price diverge.

---

Expand Down
12 changes: 9 additions & 3 deletions examples/sizecheck.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
use percolator::*;
use core::mem::offset_of;
use percolator::*;
fn main() {
println!("ACCOUNT_SIZE={}", std::mem::size_of::<Account>());
println!("ACCOUNTS_OFF={}", offset_of!(RiskEngine, accounts));
println!("CAPITAL_OFF={}", offset_of!(Account, capital));
println!("PBQ_OFF={}", offset_of!(Account, position_basis_q));
println!("ADL_A_BASIS_OFF={}", offset_of!(Account, adl_a_basis));
println!("ADL_EPOCH_SNAP_OFF={}", offset_of!(Account, adl_epoch_snap));
println!("ADL_EPOCH_LONG_OFF={}", offset_of!(RiskEngine, adl_epoch_long));
println!("ADL_EPOCH_SHORT_OFF={}", offset_of!(RiskEngine, adl_epoch_short));
println!(
"ADL_EPOCH_LONG_OFF={}",
offset_of!(RiskEngine, adl_epoch_long)
);
println!(
"ADL_EPOCH_SHORT_OFF={}",
offset_of!(RiskEngine, adl_epoch_short)
);
println!("C_TOT_OFF={}", offset_of!(RiskEngine, c_tot));
println!("VAULT_OFF={}", offset_of!(RiskEngine, vault));
println!("INSURANCE_OFF={}", offset_of!(RiskEngine, insurance_fund));
Expand Down
2 changes: 1 addition & 1 deletion examples/sizecheck2.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use percolator::*;
use core::mem::offset_of;
use percolator::*;
fn main() {
println!("capital={}", offset_of!(Account, capital));
println!("kind={}", offset_of!(Account, kind));
Expand Down
55 changes: 44 additions & 11 deletions examples/sizecheck3.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,47 @@
fn main() {
println!("ACCOUNTS_OFF={}", core::mem::offset_of!(percolator::RiskEngine, accounts));
println!("C_TOT={}", core::mem::offset_of!(percolator::RiskEngine, c_tot));
println!("PNL_POS_TOT={}", core::mem::offset_of!(percolator::RiskEngine, pnl_pos_tot));
println!("ADL_MULT_LONG={}", core::mem::offset_of!(percolator::RiskEngine, adl_mult_long));
println!("ADL_MULT_SHORT={}", core::mem::offset_of!(percolator::RiskEngine, adl_mult_short));
println!("ADL_EPOCH_LONG={}", core::mem::offset_of!(percolator::RiskEngine, adl_epoch_long));
println!("ADL_EPOCH_SHORT={}", core::mem::offset_of!(percolator::RiskEngine, adl_epoch_short));
println!("NUM_USED={}", core::mem::offset_of!(percolator::RiskEngine, num_used_accounts));
println!("BITMAP={}", core::mem::offset_of!(percolator::RiskEngine, used));
println!("ENGINE_SIZE={}", std::mem::size_of::<percolator::RiskEngine>());
println!("ACCOUNT_SIZE={}", std::mem::size_of::<percolator::Account>());
println!(
"ACCOUNTS_OFF={}",
core::mem::offset_of!(percolator::RiskEngine, accounts)
);
println!(
"C_TOT={}",
core::mem::offset_of!(percolator::RiskEngine, c_tot)
);
println!(
"PNL_POS_TOT={}",
core::mem::offset_of!(percolator::RiskEngine, pnl_pos_tot)
);
println!(
"ADL_MULT_LONG={}",
core::mem::offset_of!(percolator::RiskEngine, adl_mult_long)
);
println!(
"ADL_MULT_SHORT={}",
core::mem::offset_of!(percolator::RiskEngine, adl_mult_short)
);
println!(
"ADL_EPOCH_LONG={}",
core::mem::offset_of!(percolator::RiskEngine, adl_epoch_long)
);
println!(
"ADL_EPOCH_SHORT={}",
core::mem::offset_of!(percolator::RiskEngine, adl_epoch_short)
);
println!(
"NUM_USED={}",
core::mem::offset_of!(percolator::RiskEngine, num_used_accounts)
);
println!(
"BITMAP={}",
core::mem::offset_of!(percolator::RiskEngine, used)
);
println!(
"ENGINE_SIZE={}",
std::mem::size_of::<percolator::RiskEngine>()
);
println!(
"ACCOUNT_SIZE={}",
std::mem::size_of::<percolator::Account>()
);
println!("MAX_ACCOUNTS={}", percolator::MAX_ACCOUNTS);
}
Loading