Risk engines
1. TL;DR
Section titled “1. TL;DR”A risk engine is the code path that runs on every borrow, withdrawal, or liquidation to decide, deterministically and in real time, whether a position is within acceptable bounds — marginfi describes its own version plainly as running “Just In Time,” with no separate refresh step required. Because that decision depends entirely on oracle prices and hard-coded weights, a risk engine can be mathematically correct and still be fed a wrong or manipulated input, which is exactly what happened to Loopscale in April 2025. Two structural responses to that gap exist in this page’s sources: delegating some risk parameters to specialized outside managers (Aave’s “Risk Admin” role, exemplified by DAOs like RiskDAO) rather than leaving every tweak to a slow governance vote, and building crypto-native insurance so that when the risk engine is wrong, someone still gets made whole — though neither fully closes the recourse gap DeFi’s speed and anonymity create in the first place.
2. Explain it simply
Section titled “2. Explain it simply”Analogy
Section titled “Analogy”A risk engine is like an elevator’s automatic weight sensor: before the doors close, it checks the current load against the rated maximum and refuses to move if you’re over, instantly and without a human involved. That sensor is excellent at enforcing the rule it was built to enforce, but if the building’s own load-rating number was calculated wrong in the first place — or if someone rigged the scale to under-report — the sensor will happily and confidently let an overloaded elevator run.
The piggy bank has a little robot guard that checks, every single time someone tries to borrow or take something out, whether the rules are still being followed — like making sure nobody borrows more than their toy is worth. The robot is very fast and never gets tired or bribed. But the robot can only check using the information it’s given, like a toy’s reported price — if that price is wrong or someone tricks the robot into believing a fake price, the robot will still say “yes, that’s fine” even though it isn’t.
Step-by-step walkthrough
Section titled “Step-by-step walkthrough”Scenario: marginfi’s own documented risk-engine flow for a borrow instruction (marginfi README, 2026-08 fetch).
- Before the transaction. A user’s account holds collateral and no debt; nothing has been checked yet.
- User submits a borrow instruction. The transaction must include, in
remaining_accounts, every bank and oracle involved in the user’s balances, “sorted in byte order by Bank key.” - The risk engine runs Just In Time. Unlike protocols requiring separate “refresh” instructions first, marginfi’s engine reads live oracle and bank state in the same instruction as the borrow itself.
- The engine computes weighted health. It sums assets (priced low, within an oracle confidence bound) times Initial asset weights, and subtracts liabilities (priced high) times Initial liability weights, as detailed in /lending/collateral-ltv-health/.
- Pass or fail. If post-borrow health would be positive, the transaction succeeds; if negative, “rejecting the tx” — it simply fails, no partial execution.
- A staleness exception, explicitly allowed. If a user is “lending $1 in A and $1000 in B, and trying to borrow $100 in C, the caller might pass a stale oracle for A, because the collateral in B alone is sufficient to complete the borrow” — the engine tolerates staleness on an asset that isn’t load-bearing for that check.
Common misconceptions
Section titled “Common misconceptions”- Myth: A risk engine “knows” whether a position is actually safe. Reality: It only knows whether the position satisfies a formula given the prices and weights it was handed; if those inputs are wrong, the output is wrong with equal confidence — the core lesson of Loopscale, below.
- Myth: Risk parameters (LTV, weights, oracle choice) are set once and left alone. Reality: Aave V3 created a “Risk Admin” role specifically so entities “can be DAOs (e.g., RiskDAO) or automated agents that can build on top of this feature to react automatically if certain invariants are broken” (Aave V3 technical paper, 2022-01, §3.2).
- Myth: Insurance in DeFi works like traditional insurance. Reality: “leverage must exist as full collateralization ($1 needed for every $1 of coverage) is untenably capital inefficient,” yet “in outstanding policies are roughly 50x the underlying collateral in traditional insurance markets” (Paradigm, “Crypto-native Insurance,” 2020-08-11).
- Myth: If something clearly went wrong, an insurance payout is just a matter of proving it. Reality: Vitalik’s objection cuts the other way: “if there was a programmatic oracle IsBroken(x), then the code of x could just be modified to reject all transactions that set IsBroken(x) to true” (Paradigm, 2020-08-11).
- Myth: DeFi’s speed, anonymity, and dispute resolution are three independent design choices. Reality: cc7768’s framework treats them as a triangle where you can have at most two: TradFi has instant resolution and recourse but not anonymity; “Fast DeFi” has instant resolution and anonymity but not recourse (ethresear.ch 11182, 2021-11-04).
If you only remember one thing
Section titled “If you only remember one thing”A risk engine enforces its formula perfectly; it cannot enforce that the formula’s inputs were true, and everything else on this page — delegated risk parameters, insurance, recourse debates — exists to manage that one gap.
3. How it works
Section titled “3. How it works”A deterministic, just-in-time check
Section titled “A deterministic, just-in-time check”marginfi frames its engine’s job in one sentence: “to maintain account health, P0 uses a deterministic risk engine that ensures that borrowing and lending activities are within acceptable risk parameters” (marginfi README, 2026-08 fetch). “Deterministic” matters — given the same prices and weights, the engine always produces the same accept/reject decision, with no discretion or delay. This contrasts with protocols requiring separate refresh instructions: “our Risk Engine runs Just In Time: no refresh instructions are needed, except for those required by integrated venues” (marginfi README, 2026-08 fetch) — it reads current state in the same instruction as the action being checked, rather than trusting an earlier snapshot.
Delegated risk parameterization
Section titled “Delegated risk parameterization”Because a risk engine’s formula is only as good as the parameters fed into it, someone has to set and continuously update those parameters as conditions change — and doing this exclusively through slow, on-chain governance votes is too sluggish for fast-moving risk. Aave V3’s answer is the Risk Admin role: an entity permitted to “update reserve parameters as reserve factor, caps, E-Mode category, borrowing on, stable borrowing allowed, freeze/unfreeze, LTV, liquidation threshold, liquidation bonus” without a full governance vote each time, explicitly citing external specialist DAOs like RiskDAO, or “automated agents that can build on top of this feature to react automatically if certain invariants are broken” (Aave V3 technical paper, 2022-01, §3.2, §4.7). This is what the wider industry calls “Gauntlet-style” parameterization: a specialized, continuously-monitoring third party is delegated narrow, auditable authority over specific risk knobs, trading some decentralization for faster response than governance alone can provide.
The recourse gap, formally
Section titled “The recourse gap, formally”cc7768’s ethresear.ch framework names the trade-off at the center of every risk-engine design: three properties — anonymity, instant resolution, and recourse (the ability to dispute a transaction’s validity after the fact) — cannot all be had together. “Fast DeFi,” covering essentially every protocol on this page, gets anonymity and instant resolution at the cost of recourse: “liquidated users have no opportunity for recourse if the liquidation occurred at an inaccurate price” (ethresear.ch 11182, 2021-11-04). A commenter’s reply raises a genuine philosophical objection worth presenting alongside cc7768’s framing: bowaggoner argues that under a strict “the code is the law” ethos, recourse isn’t separable from “just a change in the incentives of the protocol,” since it requires “a set of rules that it is possible to break… and consequences for breaking them” — rules living outside the code (ethresear.ch 11182, reply #2, 2021-11-05). cc7768 accepts the framing rather than rebutting it: “I agree that this should be viewed as a change in incentives” (reply #3, 2021-11-06) — the disagreement is less about facts than whether “recourse” is coherent inside a code-is-law system.
Insurance as an after-the-fact backstop
Section titled “Insurance as an after-the-fact backstop”If a risk engine’s decision turns out to have been wrong given true, unmanipulated reality, insurance is the mechanism this page’s sources point to for making affected users whole after the fact. Fred Ehrsam frames the opportunity from DeFi’s own growth and incident history: “DeFi has rapidly grown 10x over the last year from $500m in user funds to $5bn today. Money-losing bugs have occurred amidst this growth and the stakes are increasing” (Paradigm, “Crypto-native Insurance,” 2020-08-11). He names Nexus Mutual as the leading example at the time of writing — “governance-driven for payouts,” growing “from ~$0.5m to ~$15m” in coverage over one year and having “successfully completed one payout” (for the bZx attacks, /lending/flash-loans/) — alongside Opyn’s options-based approach, which “requires full collateralization from options writers” and cannot target specific technical failures (Paradigm, 2020-08-11).
4. Worked numeric example
Section titled “4. Worked numeric example”Oracle staleness in the risk engine, using marginfi’s own numbers: a user lending $1 in asset A and $1,000 in asset B wants to borrow $100 in asset C. If A’s oracle price is stale but B’s is fresh, the engine can still approve the borrow, because B alone already covers the $100 request many times over once weighted; it only requires fresh enough data for whichever legs are actually load-bearing for that check (marginfi README, 2026-08 fetch).
Sizing an insurance backstop, extending Ehrsam’s own benchmark: “with $4.5bn locked in DeFi and insurance covers 5% of the market (the rough ratio in traditional credit markets), a successful system could see $225m demand today” (Paradigm, 2020-08-11). Applying the same 5% benchmark to Aave V3’s roughly $17.4B in deposits (secondary, DefiLlama, as of 2026-08, approximate — /lending/money-markets/) implies a hypothetical, fully-adequate insurance pool of — illustrating how far a real-world safety module is likely to sit below that benchmark, since no protocol’s insurance fund in this page’s sources approaches that size.
5. Where it’s used
Section titled “5. Where it’s used”Ethereum
Section titled “Ethereum”- Aave’s Risk Admin role and external risk DAOs — described above; the clearest Ethereum instance of delegating risk-engine parameter changes outside a full governance vote (Aave V3 technical paper, 2022-01, §3.2).
- Nexus Mutual — an on-chain mutual with manual, governance-voted payout decisions for specific protocol failures, the leading crypto-native insurance example in this page’s sources (Paradigm, 2020-08-11).
- Opyn — options-based (oToken) coverage, fully collateralized by writers, offering broader protection but less precision than a dedicated cover product (Paradigm, 2020-08-11).
Solana
Section titled “Solana”- marginfi (rebranded Project 0 / P0) — the deterministic, just-in-time risk engine described throughout this page, the most granular public documentation among this page’s Solana sources (marginfi README, 2026-08 fetch).
- Kamino Lend — publishes a public “Risk dashboard” and separate “Security & Risk” docs, though the fetched navigation-level content did not include the dashboard’s methodology (Kamino docs, 2026-08 fetch).
- Loopscale — the protocol at the center of the incident below; its risk engine’s collateral-pricing logic is the direct subject of the exploit.
6. Risks, attacks, and incidents
Section titled “6. Risks, attacks, and incidents”- Loopscale exploit, 26 April 2025, 15:28–15:32 UTC (Solana). Loopscale’s risk engine priced RateX principal-token (PT) collateral via a cross-program invocation to RateX’s own
get_pt_priceinstruction — but, for non-Loop borrows, never validated that the program actually being called was the genuine RateX program. The attacker deployed a malicious program spoofing RateX’s interface, returning an artificially inflated exchange rate, then borrowed against the resulting fake valuation, draining 5,726,724.97 USDC and 1,211.4 SOL (~$5.8M total). Loopscale’s own post-mortem is precise: “the exploit stemmed from an incomplete validation of the RateX program used to price RateX principal tokens (PT tokens),” traced to a specific change: “the vulnerable code was introduced on March 27 as part of an upgrade to support RateX collateral markets” (Loopscale post-mortem, accessed 2026-08-29). This is the clearest illustration that a risk engine’s job includes verifying the identity of the program supplying a price, not just sanity-checking the number returned — distinct from, but as critical as, the confidence-interval and staleness checks in §3 and /lending/collateral-ltv-health/. Loopscale halted the app, engaged incident-response firm SEAL 911, and the attacker returned all funds within 48 hours for a 10% bounty; the fix enforced strict RateX program-ID validation (Loopscale post-mortem, accessed 2026-08-29). - Correct-formula, wrong-input failures generally. Loopscale is this page’s sharpest example, but Mango Markets (/lending/collateral-ltv-health/) is another instance of a technically correct valuation formula acting on a manipulated input.
- Delegated risk authority as a new trust dependency. The Risk Admin role that lets Aave respond quickly is, by construction, a standing permission that could be misused — Aave’s threat model notes a compromised Risk Admin “can drop the Liquidation Threshold to 0 and liquidate users… atomically in the same transaction or bundle” (Aave V3 technical paper, 2022-01, §4.7).
- Manual insurance claims are slow and can be wrong. Ehrsam flags this via a different protocol’s experience: “the often weeks long delays in resolving Augur markets through manual payout decisions emphasize the benefits of programmatic payouts,” while conceding programmatic payouts carry their own failure mode per Vitalik’s IsBroken(x) objection in §2 (Paradigm, 2020-08-11).
- Recourse-free liquidation and price-feed errors. As in §3, cc7768’s framework treats this not as a bug but as the deliberate trade-off “Fast DeFi” makes for anonymity and speed (ethresear.ch 11182, 2021-11-04).
7. Open problems
Section titled “7. Open problems”- Can insurance payout triggers ever be fully programmatic? Vitalik’s IsBroken(x) critique, as relayed by Ehrsam, suggests a hard limit: any on-chain condition precise enough to trigger a payout automatically is also precise enough for the covered protocol’s own code to avoid tripping it (Paradigm, 2020-08-11) — unresolved here.
- Is delegated risk parameterization a net safety win or a new attack surface? Aave’s materials present Risk Admins as a safety feature and, separately, flag the same role as a threat-model liability if compromised (Aave V3 technical paper, 2022-01, §3.2 vs. §4.7) — the paper doesn’t resolve which effect dominates.
- Whether program-identity verification should be a standard, audited risk-engine primitive. Loopscale’s root cause — an unvalidated cross-program invocation — is a bug class generic oracle-design guidance (price sanity checks, confidence intervals, staleness bounds) doesn’t obviously catch; no industry-standard checklist is pointed to here.
- Whether “recourse” is even a coherent goal inside a code-is-law system. The ethresear.ch thread’s own internal disagreement (§3) is left open by the thread itself, with cc7768 conceding the philosophical point without resolving it (ethresear.ch 11182, 2021-11-04 through 2021-12-01).
8. Ethereum vs Solana
Section titled “8. Ethereum vs Solana”| Aspect | Ethereum | Solana |
|---|---|---|
| Risk engine design documented here | Reserve-by-reserve parameters, some updatable by permissioned Risk Admins without a full vote | marginfi’s deterministic, Just-In-Time engine reading live oracle/bank state in the same instruction |
| Delegated risk parameterization | Aave Risk Admin role, naming RiskDAO as an example holder | Not documented as a distinct delegated role in this page’s Solana sources; Kamino publishes a public risk dashboard instead |
| Insurance/backstop maturity documented | Nexus Mutual (manual claims), Opyn (fully collateralized options) — both from a 2020 vantage point | Not covered by a dedicated insurance-product source in this page’s research |
| Best-documented “correct formula, wrong input” incident | (Mango is Solana; see /lending/collateral-ltv-health/ for a cross-chain comparison point) | Loopscale, April 2025 — spoofed cross-program invocation for collateral pricing |
Both ecosystems’ risk engines share the core limitation this page centers on: perfect enforcement of an imperfectly-informed formula. The failure shapes differ by what each chain’s programs typically compose with — Ethereum’s Aave threat model worries about compromised admin roles and oracle manipulation, while Solana’s Loopscale incident shows that in a composable, cross-program-invocation-heavy environment, verifying which program answered a price query is its own distinct responsibility.
9. Reference doc
Section titled “9. Reference doc”The reference
Section titled “The reference”marginfi-v2 README, “Risk Engine” section — mrgnlabs (GitHub), fetched 2026-08-29. raw.githubusercontent.com/mrgnlabs/marginfi-v2
Summary of the reference
Section titled “Summary of the reference”The README’s “Risk Engine” section opens by stating the engine’s purpose in one line — maintaining account health so borrowing and lending stay “within acceptable risk parameters” — then walks through the health formula (assets minus liabilities, weighted, described in full in /lending/collateral-ltv-health/) with two fully worked numeric examples: one healthy position using Initial weights, and the same position becoming unhealthy once Maintenance weights apply, followed by a partial-liquidation example showing exact dollar figures for the liquidator fee, insurance fee, and resulting improved-but-still-unhealthy state.
The subsequent “Checking Health” and “Third Party Liquidation” sections describe the operational surface: users can query lending_account_pulse_health to see the engine’s live assessment; borrows and withdrawals trigger a mandatory check while deposits and repays don’t need one, “as they can only improve health”; and liquidation is explicitly “open to third parties, and encouraged,” netting a stated 2.5–10% liquidator profit.
The most technically dense part is “Passing Risk Accounts and Cranking Oracles,” which contrasts marginfi’s design against “other borrow-lending protocols” that require separate refresh instructions before a risk-consuming instruction: marginfi’s engine instead “runs Just In Time,” reading live state directly, with callers responsible for passing every relevant bank/oracle account pair in remaining_accounts, sorted by bank key. It specifies oracle-provider-specific staleness rules (Pyth self-updates; Switchboard needs a caller-supplied crank instruction) and an explicit staleness-tolerance carve-out: a caller may supply a stale oracle for a collateral asset if other, fresher-priced collateral alone already covers the requested action. A final subsection covers group-level rate limiting, which requires the withdrawn/borrowed bank and oracle to appear in remaining_accounts even when the core health check wouldn’t otherwise need them, since rate limiting checks projected USD outflow using the same account layout.
Key quotes
Section titled “Key quotes”“To maintain account health, P0 uses a deterministic risk engine that ensures that borrowing and lending activities are within acceptable risk parameters.” (§Risk Engine)
“Our Risk Engine runs Just In Time: no refresh instructions are needed, except for those required by integrated venues.” (§Passing Risk Accounts and Cranking Oracles)
“Liquidation is open to third parties, and encouraged!” (§Third Party Liquidation)
“If the user is lending $1 in A and $1000 in B, and trying to borrow $100 in C, the caller might pass a stale oracle for A, because the collateral in B alone is sufficient to complete the borrow!” (§Passing Risk Accounts and Cranking Oracles)
“Deposits and Repays require no Risk Engine check, as they can only improve health.” (§Checking Health)
How to read the original
Section titled “How to read the original”Background needed: the health-factor / weighted-collateral math from /lending/collateral-ltv-health/ — this section assumes that mechanism and focuses on when and how it’s checked, not what it computes. Nothing needs skipping; the section is short and each subsection covers a distinct operational concern (checking health, third-party liquidation, passing accounts). The hardest paragraph is the group-rate-limiting carve-out at the very end: it’s easy to read as an edge case, but the point is that even an operation the core health check would approve without needing a particular bank’s oracle (e.g. withdraw_all on a position with no resulting liability) may still need that oracle supplied anyway, purely so the separate rate-limiting system can compute its own USD outflow figure — two independent systems sharing one account-passing convention.
What changed since
Section titled “What changed since”- marginfi’s own rebrand to “Project 0” (P0) and expansion into cross-venue collateral (documented on /lending/modular-lending/) postdates the core risk-engine design this README section describes, but the Just-In-Time checking model and health formula have carried over unchanged as of the 2026-08 fetch.
- The Loopscale exploit (2025-04) postdates this README’s own documented staleness/confidence-interval safeguards and demonstrates a validation gap — unverified cross-program invocation identity — that this reference’s own “Passing Risk Accounts and Cranking Oracles” section does not address, since it assumes the oracle account passed in is genuine rather than a spoofed program.
- Aave’s Risk Admin/RiskDAO pattern (2022) and marginfi’s deterministic on-chain engine represent two different eras’ answers to the same problem; no source used for this page documents the two teams converging on a shared standard as of 2026-08.
Secondary references
Section titled “Secondary references”- DeFi: Recourse and tail risks — cc7768 (ethresear.ch, 2021-11-04) — read for the anonymity/instant-resolution/recourse framework this page’s §3, §6, and §7 draw on throughout, and for the genuine unresolved disagreement between cc7768 and commenter bowaggoner about whether recourse is a coherent concept in a code-is-law system.
- Crypto-native Insurance — Fred Ehrsam (Paradigm, 2020-08-11) — read for the fullest treatment of why insurance is hard to build (capital efficiency, payout triggers, market structure) and for the Nexus Mutual/Opyn state of the art at the time of writing.
- Aave V3 Technical Paper, §3.2 and §4.7 (2022-01-27) — read for the Risk Admin role’s design intent alongside its own threat-model acknowledgment of the same role’s abuse potential.
10. Sources
Section titled “10. Sources”- marginfi-v2 README (“Project 0”) — mrgnlabs (GitHub) — fetched 2026-08-29 — https://raw.githubusercontent.com/mrgnlabs/marginfi-v2/main/README.md
- DeFi: Recourse and tail risks — cc7768 (ethresear.ch) — 2021-11-04 — https://ethresear.ch/t/defi-recourse-and-tail-risks/11182
- Crypto-native Insurance — Fred Ehrsam (Paradigm) — 2020-08-11 — https://www.paradigm.xyz/writing/crypto-native-insurance
- Aave V3 Technical Paper — Emilio Frangella, Lasse Herskind (Aave) — 2022-01-27 — https://raw.githubusercontent.com/aave/aave-v3-core/master/techpaper/Aave_V3_Technical_Paper.pdf
- Overview — Kamino Docs (kamino-lend-litepaper landing page) — fetched 2026-08-29 — https://docs.kamino.finance/kamino-lend-litepaper
- Loopscale post-mortem — Loopscale blog — accessed 2026-08-29 — https://blog.loopscale.com/posts/postmortem
- Kamino Lend, Aave V3 TVL — DefiLlama (secondary, approximate) — accessed 2026-08-29 — https://defillama.com/