What Is the RheoFi Comptroller?
The RheoFi Comptroller is the per-pool risk engine that approves or rejects every risk-increasing action, inside on-chain bounds of a 95% maximum collateral factor and a close factor between 5% and 90% (RheoFi Whitepaper v1.0, 2025). RheoFi deploys one instance per isolated pool, so each pool's listings, parameters and memberships answer to its own Comptroller.
One Comptroller per pool, one market list per Comptroller
The Comptroller reference states that "each pool deploys its own instance" and that "each Comptroller maintains its own listed markets, user memberships, and risk configurations." The unit is the pool, not the asset: the deployed markets page lists 17 markets across four pools, nine of them under Core's single Comptroller.
The solvency sum is scoped to that list. In the whitepaper's words, because the iteration "is restricted to the Comptroller's own market list, no action in any other pool can alter a user's solvency state in the current pool." Collateral in one pool cannot back debt in another.
What the whitepaper says it enforces
The whitepaper's enumeration: "The Comptroller enforces market listing, account-level liquidity checks, collateral-factor and liquidation-threshold parameters, supply and borrow caps, and the close factor and liquidation incentive." It publishes the hard limits alongside:
MIN_CLOSE_FACTOR_MANTISSA = 0.05e18; // 5%
MAX_CLOSE_FACTOR_MANTISSA = 0.90e18; // 90%
MAX_COLLATERAL_FACTOR_MANTISSA = 0.95e18; // 95%
// invariant: liquidationThreshold >= collateralFactor
The Comptroller does not price loans; borrowers pay "at a rate set by the pool's interest-rate model." Collateral use is opt-in: rToken holders "purely for yield remain outside the liquidation surface."
RheoFi Comptroller vs Single-Weight Risk Engines: What Changes?
The RheoFi Comptroller changes one thing: it carries two weights per market instead of one. The collateral factor gates new borrows and withdrawals, while a liquidation threshold set at or above it decides when a position can be liquidated. The FSB describes platforms setting a collateral factor "typically up to 80% of the collateral value posted" (FSB, February 2023).
Two weights instead of one
In a single-weight engine, one number caps borrowing and marks the liquidation line, so an account borrowed to its limit has zero distance to spare.
RheoFi splits the jobs. The whitepaper says "a separate computation using collateralFactor in place of liquidationThreshold gates new borrows and withdrawals", and because the threshold is at least the factor "by construction, there is always a safety margin." The risks section below tests that "always".
| Property | RheoFi per-pool Comptroller | Single-weight engine | Protocol-wide engine |
|---|---|---|---|
| Weights per market | Two: CF gates, LT triggers | One does both | Varies |
| Liquidity sum scope | Entered markets in this pool | Entered markets in the engine | Whole protocol |
| Gap from borrow limit to liquidation | 1 - CF/LT: 2.44% to 12.5% on testnet | Zero | Design-specific |
| Listing blast radius | One pool | Whole engine | Whole protocol |
| Code isolation | None: four Comptrollers, one beacon | Not applicable | Not applicable |
Pool-scoped sums vs protocol-wide sums
A protocol-wide sum lets one bad listing shift the solvency of accounts that never touched it. RheoFi's sum stops at the pool's list, and the liquidity pools architecture article states that "cross-pool liquidation is impossible by design." The cost is capital efficiency: collateral in Core counts for nothing in Stablecoins.
Why Does Comptroller Design Matter for Lending in 2026?
Comptroller design matters because DeFi losses have moved into logic: 89% of 2025 protocol losses came from protocol logic exploits, in a year that registered $680 million in total losses (Immunefi, April 2026). RheoFi treats the Comptroller as the logic surface integrators should test first, because every borrow, withdrawal and liquidation passes through it.
Losses moved to logic
Immunefi's series shows losses falling from $2.62 billion in 2022 to $534 million in 2024 before "a partial rebound", while ecosystem-class attacks fell "from nearly 19% of DeFi losses in 2022 to under 1% in 2025." A study of 181 incidents counted at least 3.24 billion USD lost from April 2018 to April 2022, with price oracle attacks the most frequent type at 15% (arXiv, April 2023).
Listing is where risk enters
In a May 2024 exploit of a newly listed lending market, an activation proposal cleared its 24 hour timelock and became "executable by anyone." The attacker executed it together with the attack payload in one transaction; it set the market's collateral factor to 35%, and a flash loan attack followed (Rekt News, May 2024). An April 2023 case manipulated an empty duplicate market's exchange rate by donation (Rekt News, April 2023). Both turned on a listed market's configuration: its first weight, or its empty supply.
Liquidation sensitivity
On one of the most widely used lending protocols, "variations of only 3% in an asset's dollar price can result in over 10m USD becoming liquidable", and over 70% of liquidable positions were liquidated immediately (arXiv, December 2021). The gap between the two weights is the Comptroller's buffer against that sensitivity.
How Does the RheoFi Comptroller Compute Account Liquidity?
The RheoFi Comptroller computes account liquidity with two sums over the markets an account has entered, weighting collateral by a collateral factor "typically between 40% and 90%" for borrowing and by a liquidation threshold for solvency (RheoFi Whitepaper v1.0, 2025). RheoFi enforces the threshold at or above the factor on-chain.
The two sums
Both sums value collateral as exchangeRate x oraclePrice x rTokenBalance (how rTokens price supplied collateral); only the weight differs.
weightedCollateral = borrowingPower = totalBorrow = 0
# per market the account has entered, in this pool only
collateralValue = exchangeRate * oraclePrice * rTokenBalance
weightedCollateral += liquidationThreshold * collateralValue # solvency
borrowingPower += collateralFactor * collateralValue # borrow / withdraw gate
totalBorrow += oraclePrice * borrowBalance
HealthFactor = weightedCollateral / totalBorrow if totalBorrow > 0 else float("inf") # liquidatable below 1
The solvency lines are the whitepaper's; the gate line matches the protocol math guide. On testnet, the Core Comptroller answered getAccountLiquidity(address) with three values (error, liquidity, shortfall); the docs reference does not list that function.
A worked Core-pool example
Weights come from the September 30, 2026 testnet read; balances and prices are hypothetical.
| Input | rWBTC (Core) | rUSDC (Core) |
|---|---|---|
| CF / LT (testnet read) | 75% / 80% | 80% / 82% |
| Balance (hypothetical) | 1 WBTC | 20,000 USDC |
| Price (hypothetical) | $60,000 | $1 |
| CF-weighted / LT-weighted | $45,000 / $48,000 | $16,000 / $16,400 |
The account enters both markets and borrows 50,000 USDT (hypothetical $1) in the same pool; amounts are underlying.
- Borrowing power: $61,000, leaving $11,000 of liquidity.
- Health factor: $64,400 / $50,000 = 1.288.
- Withdrawal limit: $11,000 / 0.80 = 13,750 USDC. Redeeming all 20,000 would cut borrowing power to $45,000, under the debt, so the gate rejects it;
exitMarket(rUSDC)fails for the same reason. - Borrow gate closes: below $45,333 WBTC, a 24.4% fall.
- Liquidation opens: below $42,000, a 30% fall.
- Past the line: at $41,000 the health factor is 0.984, and
maxCloseat the testnet close factor of 50% is $25,000.
Seize arithmetic is covered in what a liquidation costs the borrower and the liquidation guide.
The frozen band between the gate and the trigger
Between a 24.4% and a 30% drop, the account can neither borrow nor withdraw, yet nobody can liquidate it. Nothing in the two sums blocks repaying or adding collateral. For a single-collateral account opened at its limit, the band's width is 1 - CF/LT.
What Are the RheoFi Comptroller's Components and Action Checks?
The RheoFi Comptroller's components are its market list, per-market weights and caps, a pool-level close factor and incentive, and per-market pause flags, applied across 17 markets in 4 pools on testnet (RheoFi Docs, September 2026). RheoFi publishes the setter signatures, and the matrix below flags each check the docs leave out.
The action-check matrix
| Action (entry point) | Comptroller check that can block it | Basis |
|---|---|---|
Supply (mint) | Market listed; supply cap | Whitepaper; docs |
Enable collateral (enterMarkets) | Per-market error code, 0 = success | Docs |
Withdraw (redeem, redeemUnderlying) | CF-weighted liquidity stays non-negative | Whitepaper |
Disable collateral (exitMarket) | Rejected if it creates a shortfall | Docs |
Borrow (borrow) | CF-weighted liquidity; borrow cap | Whitepaper; docs |
Repay (repayBorrow, repayBorrowBehalf) | Not documented | Test on testnet |
Liquidate (liquidateBorrow, liquidateAccount) | Health factor below 1; repay at most closeFactor x borrow | Whitepaper; docs |
| Seize, rToken transfer | Not documented | Test on testnet |
| Any action | Per-market pause flag | On-chain probe |
Each rToken "interacts exclusively with its parent pool's Comptroller for risk management", per the RToken reference.
The integration surface
enterMarkets(address[] calldata rTokens): returns an array of error codes; check each entry.exitMarket(address rTokenAddress): allowed "provided the removal does not create a shortfall".supportMarket(IRToken rToken): lists a market; "restricted to governance or authorized callers".setCollateralFactor(IRToken rToken, uint256 newCollateralFactorMantissa, uint256 newLiquidationThresholdMantissa): moves both weights in one call.setMarketSupplyCaps(IRToken[] calldata rTokens, uint256[] calldata newSupplyCaps)and its borrow twinsetMarketBorrowCaps: per-market ceilings.liquidateAccount(address borrower, LiquidationOrder[] calldata orders): batch liquidation; order fields unpublished.markets(address): three words on testnet (listed, CF, LT); all 17 markets listed.closeFactorMantissa(),liquidationIncentiveMantissa(): pool-level; testnet 0.5 everywhere, incentive 1.1 in three pools and 1.02 in Liquid Staked ETH.actionPaused(address, uint8): per-market pause flags.
Caps, listing and pause flags
Caps were non-zero on all 17 testnet markets; borrow caps ran from 90% of the supply cap (Core rUSDC) down to 10% (Liquid Staked ETH rweETH).
The PoolRegistry reference exposes addPool(...), taking a close factor, liquidation incentive and minLiquidatableCollateral, plus addMarket(AddMarketInput memory input), and states that "pool creation is permissioned through governance." minLiquidatableCollateral is 100e18 in each testnet pool; its effect is undocumented. On the Comptroller, "all administrative functions are gated through the AccessControlManager."
actionPaused returned false for indices 0 through 8 on every market and reverted at index 9, which points to nine action slots per market. The docs do not publish which action each index controls.
Read Your Pool's Comptroller Before You Call It
RheoFi runs one Comptroller per isolated pool, each with its own market list, collateral factors, thresholds, caps and pause flags.
Open the testnet app, then read
markets()and your account liquidity against the public testnet RPC before wiring any borrow path.The inherited audit scope names the comptroller and forced liquidations; a RheoFi-specific audit is planned before mainnet.
How to Integrate Against the RheoFi Comptroller?
Integrating against the RheoFi Comptroller means running pre-flight reads before every risk-changing call, because "variations of only 3% in an asset's dollar price can result in over 10m USD becoming liquidable" on a widely used lender (arXiv, December 2021). RheoFi recommends reading every parameter on-chain, never from documentation or from this post.
Prerequisites
Target XRPL EVM testnet (chain ID 1449000) with addresses from the deployed markets page. On the PoolRegistry, getPoolsSupportedByMarket(address market) returns the IDs (uint256[]) of pools that support an asset, getAllPools() returns every pool's metadata, and getPoolByComptroller(address) returns a pool's metadata from its Comptroller address. See the Solidity integration patterns for wider call flows, and measure gas on your own testnet run.
Pre-flight checks before any call
- Take the Comptroller address from the deployed markets page and confirm it with
getPoolByComptroller. - Call
markets(rToken); confirm the listed flag and record CF and LT. - Read
closeFactorMantissa()andliquidationIncentiveMantissa(), which are pool-wide. - Read supply and borrow caps against the size of your call.
- Check
actionPaused, confirming the index mapping against deployed source before hard-coding one. - Call
enterMarketsonly for collateral you use, and check every returned code. - Read
getAccountLiquidity(account)before the action. - Simulate the borrow, redeem or
exitMarketwitheth_call; treat a non-zero error or revert as a rejection. - Recompute both sums off-chain and alert as the health factor approaches 1.
- Re-read everything after any governance action or redeployment.
What Are the Risks and Edge Cases in the RheoFi Comptroller?
The sharpest Comptroller risk is a bad parameter on a newly listed market: in May 2024 an attacker executed a market-activation proposal that set a 35% collateral factor, then exploited it with a flash loan attack (Rekt News, May 2024). RheoFi gates listing and all administrative functions through the AccessControlManager, then names the risks that remain.
Shared logic behind isolated state
On September 30, 2026, the EIP-1967 beacon slot of all four testnet pool Comptrollers held 0xE641c4826CE10b74D607f46b56E99fa0f5b20e17, the markets page's Comptroller Beacon. EIP-1967 describes beacons as "keeping the logic address for multiple proxies in a single location, allowing the upgrade of multiple proxies by modifying a single storage slot" (EIP-1967, April 2019). Lists, weights and memberships are per pool; the code path is shared, so a Comptroller logic flaw would not respect the pool boundary. RheoFi isolates state and parameters, not code.
The zero-margin configuration
The bound liquidationThreshold >= collateralFactor admits equality. At CF = LT the buffer is 0%: a position opened at its borrow limit sits at a health factor of exactly 1.0, and the next accrual ("at the start of every state-changing call") or adverse tick makes it liquidatable. "Always a safety margin" holds only while governance keeps the weights apart. The September 30, 2026 testnet pairs, which may change before mainnet:
| Markets (pool) | CF / LT | Buffer (1 - CF/LT) |
|---|---|---|
| rWBTC, rWETH, rFRAX (Core); rcrvUSD (Curve) | 75% / 80% | 6.25% |
| rUSDC, rUSDT, rcrvUSD (Core) | 80% / 82% | 2.44% |
| rDAI (Core) | 75% / 77% | 2.60% |
| rweETH (Core) | 70% / 75% | 6.67% |
| rCRV (Core) | 35% / 40% | 12.5% |
| rUSDC, rUSDT, rcrvUSD (Stablecoins) | 85% / 90% | 5.56% |
| rCRV (Curve) | 60% / 65% | 7.69% |
| rWETH, rweETH (Liquid Staked ETH) | 90% / 93% | 3.23% |
| reETH (Liquid Staked ETH) | 80% / 85% | 5.88% |
No market sits at equality. The tightest two-point gaps are on Core's dollar-pegged markets, where a 3% move would exceed the buffer; the knife-edge study's 3% case was itself a fall in a dollar-pegged stablecoin (arXiv, December 2021). Debt that outruns liquidators leaves the Comptroller through healAccount() into how residual bad debt is auctioned.
One price, whole account
The liquidity sum covers every entered market, and the ResilientOracle ends in "revert with invalid resilient oracle price" when no tier validates. It follows, as an inference rather than documented behavior, that a liquidity check needs a valid price for every entered market. Oracle manipulation cost DeFi an estimated $403.2 million across 41 attacks in 2022 (Chainalysis, March 2023). Enter only the collateral you use; the three-tier price path covers the oracle side.
What the oracle path means for a liquidity check: Three-Tier Resilient Oracle Configuration Context: Whitepaper v1.0 routes each price through MAIN, PIVOT and FALLBACK feeds, cross-checked by a BoundValidator. Finding: A feed older than its maxStalePeriod "is treated as invalid, and the oracle falls through to the next tier." Result: Testnet fallback-activation results are unpublished; by the inference above, a revert on any entered market's price can block that account's checks (RheoFi v1.0 Whitepaper, 2025).
What the audit lineage covers
The whitepaper's smart-contract mitigations include "pause switches" and "upgradeable proxies gated by Timelock + ACM"; the contracts overview maps the deployed set.
What the whitepaper's audit scope names: Whitepaper v1.0 Publication Context: Whitepaper v1.0 documents the audit lineage the RheoFi codebase inherits, to which it adds XRPL-specific reviews. Finding: Fifteen prior engagements across PeckShield, Hacken, Certik, Quantstamp, FairyProof, and Pessimistic cover the isolated-pool core, rewards distributor, risk fund and shortfall auction, the comptroller, forced liquidations, time-based accrual and the native-token gateway. Result: The comptroller and forced liquidations sit inside that inherited scope; a RheoFi-specific mainnet audit is planned prior to mainnet deployment (RheoFi Whitepaper PDF, 2025).
Documentation gaps to test before you trust
- Repay, seize and transfer checks,
actionPausedindex meanings and the effect ofminLiquidatableCollateralare undocumented. - The PoolRegistry reference names
addPool(...); the liquidity-pools article namescreateRegistryPool(...)with the same arguments. - The protocol math page labels "≥ 1" as the liquidation-eligibility threshold, while the same page and the whitepaper place eligibility below 1.
What Regulatory and Compliance Framework Applies to On-Chain Risk Controls?
MiCA leaves crypto lending to a later review: Article 142(2)(b) calls for "an assessment of the necessity and feasibility of regulating lending and borrowing of crypto-assets" (EUR-Lex, May 2023), while lending protocols held $54.46B in TVL on September 30, 2026 (DeFiLlama, September 2026). For RheoFi, the compliance evidence is the Comptroller's published, on-chain parameter set.
MiCA: Recital 22 and the Article 142 lending review
Regulation (EU) 2023/1114 applies from 30 December 2024 (Article 149(2)), with Titles III and IV applying from 30 June 2024. Recital 22 excludes services "provided in a fully decentralised manner without any intermediary." With Comptroller setters behind an AccessControlManager and timelock (RheoFi Docs, September 2026), RheoFi does not assume that carve-out; counsel should decide. Article 142(1) required a Commission report by 30 December 2024, after consulting EBA and ESMA.
What FSB and BIS flag about collateral-driven lending
The FSB notes that if borrowers do not add collateral in time, "the collateral is automatically liquidated." The BIS adds that "overcollateralisation is pervasive in DeFi lending, which generates procyclicality" (BIS Bulletin 57, June 2022). Both describe dials a Comptroller holds, and publishing them on-chain lets an auditor check each one.
Compliance Corner
Regulation (EU) 2023/1114 (MiCA), signed 31 May 2023; applies from 30 December 2024, Titles III and IV from 30 June 2024. Relevance: Recital 22 carve-out; Article 142 lending review.
FSB, The Financial Stability Risks of Decentralised Finance, 16 February 2023. Relevance: collateral factors and automatic liquidation.
BIS Bulletin No 57, 14 June 2022. Relevance: overcollateralisation and procyclicality.
Conclusion: What the RheoFi Comptroller Means for Integrators
For integrators, the RheoFi Comptroller is a bounded decision engine with published weights, bounds and setters, to be verified as code rather than trusted as a black box. Loss sizes are shrinking: median loss per DeFi incident fell to $1.5 million in 2025 from $6 million in 2022 (Immunefi, April 2026).
Key takeaways for integrators
The collateral-factor sum decides what an account may do; the liquidation-threshold sum decides what others may do to it. The gap between them ran from 2.44% to 12.5% on the September 30, 2026 testnet read, and the bound itself does not stop governance closing it. Isolation covers state and parameters, while the four Comptrollers share one logic source. Read the Comptroller reference, run the pre-flight list on testnet at app.rheofi.com, and compare results with pool-level risk grading. RheoFi is pre-mainnet, so treat every call here as a testnet exercise: nothing in this post is financial advice, and a logic, oracle or governance failure can mean total loss of supplied funds.
References
- RheoFi Whitepaper v1.0, 2025 · RheoFi Whitepaper v1.0
- FSB, February 2023 · FSB
- Immunefi, April 2026 · Immunefi
- arXiv, April 2023 · arXiv
- Rekt News, May 2024 · Rekt News
- Rekt News, April 2023 · Rekt News
- arXiv, December 2021 · arXiv
- how rTokens price supplied collateral · how rTokens price supplied collateral
- RheoFi Docs, September 2026 · RheoFi Docs
- EIP-1967, April 2019 · EIP-1967
- Chainalysis, March 2023 · Chainalysis
- EUR-Lex, May 2023 · EUR-Lex
- DeFiLlama, September 2026 · DeFiLlama
- RheoFi Docs, September 2026 · RheoFi Docs
- BIS Bulletin 57, June 2022 · BIS Bulletin 57
FAQs
The Comptroller is the pool's risk engine. In RheoFi it enforces market listing, account-level liquidity checks, collateral factors and liquidation thresholds, supply and borrow caps, and the close factor and liquidation incentive. Each isolated pool deploys its own Comptroller instance with its own market list and memberships, so a borrow, withdrawal or liquidation in one pool is judged only against positions in that pool.



