{"state":"live-vault-degraded","tvl":1110.8880060000001,"psmReservesUSD":1110.8880060000001,"tvlBasis":"psm-usdc-reserves-only","collateralUSD":1148.2286148098415,"collateral":{"basis":"recognised retired-v1-vault collateral USD + insurance fund USD + combined PSM USDC reserves, over the same reads /api/por publishes. Wider than tvl, which counts PSM USDC only while vaultDegraded is true.","source":"https://kerne.fi/api/por -> solvency.collateralUSD","blockNumber":51121224,"asOf":"2026-09-10T09:16:36.944Z","components":{"psmReservesUSD":1110.8880060000001,"retiredVaultV1USD":37.34060880984133,"insuranceFundUSD":0}},"apy":6.08,"modeled":true,"apyBasis":"deployed","realizedApy":0,"realizedApyWindowDays":30,"kusdSupply":1144.707154,"kusdOutstanding":1109.707154,"kusdPsmInventory":35,"kusdPsmInventoryLegacy":32,"kusdPsmInventoryMint":0,"kusdPsmInventoryPrevMint":3,"psmMintAuthority":[{"address":"0xaBDE1138aa1Ce88d1dF06422C0c3b05D70569803","role":"live mint module","mintingEnabledFlag":true,"pausedFlag":false,"kusdMinterRole":true,"usdc":30},{"address":"0x07eBb486e11BD217e6085eb5ab663e4517595993","role":"retired mint module, superseded 2026-07-10","mintingEnabledFlag":true,"pausedFlag":false,"kusdMinterRole":false,"usdc":995.003},{"address":"0xFf3025ec18e301855aB0f36Ec6ECa115a29A5Fbc","role":"redeem reserve module, minter revoked 2026-06-16","mintingEnabledFlag":true,"pausedFlag":false,"kusdMinterRole":false,"usdc":85.885006}],"vaultAddress":"0x8005bc7A86AD904C20fd62788ABED7546c1cF2AC","vaultV1Address":"0x8005bc7A86AD904C20fd62788ABED7546c1cF2AC","vaultV2Address":"0x8ccc56B5624e2FDB592F6609d81F4c3798e3292B","chain":"base","chainId":8453,"timestamp":"2026-09-10T09:25:27.366Z","ethPrice":2475.5640559338035,"totalAssetsETH":0.04991987960114005,"psmUSDC":1110.8880060000001,"psmUSDCLegacy":85.885006,"psmUSDCMint":30,"psmUSDCPrevMint":995.003,"psmStableCap":10000000,"psmCurrentExposure":30,"psmCapHeadroom":9999970,"vaultDegraded":true,"vaultDegradedReason":"Describes the RETIRED v1 KerneVault at 0x8005bc7A86AD904C20fd62788ABED7546c1cF2AC, not kUSD solvency and not a failure of the live protocol. v1 carries a phantom totalSupply on the order of 4.87e36 kLP from a bucket-transition asymmetry documented in ADVERSARIAL_AUDIT_2026-05-08 section 1.3. It holds no user deposits, backs no kUSD, and its assets are therefore excluded from tvl. Public deposits into it are closed at the UI and on chain since 2026-07-30. kUSD backing is an independent read and is healthy: divide psmReservesUSD by kusdOutstanding, or read psm_solvency_ratio in the signed attestation at /api/por/signed, which covers the live v2 vault at 0x8ccc56B5624e2FDB592F6609d81F4c3798e3292B and discloses this same v1 state under retired_vault_v1. Neither vault field on this endpoint is a backing signal.","hedgeActive":true,"skusdSharePrice":1.000098667771067,"skusdRealizedYieldPct":0.009866777106704028,"skusdParDate":"2026-07-03","_meta":{"schemaVersion":13,"disclaimer":"While vaultDegraded=true, tvl reflects PSM USDC reserves only, and the same number is published under the unambiguous key psmReservesUSD with tvlBasis naming which of the two things tvl currently measures. tvl is retained unchanged for back-compat; psmReservesUSD is the one to key on. collateralUSD is a WIDER figure and is not tvl: it is mirrored from /api/por solvency.collateralUSD and adds the recognised collateral of the retired v1 vault and the insurance fund, neither of which backs any current mint. collateral.components breaks it into the three legs so the difference against tvl closes inside this payload, and collateral.blockNumber is the block the mirror was taken at. Both vaults are published by version: vaultV1Address (equal to vaultAddress, retired, the one this endpoint has always reported) and vaultV2Address (live, Safe-governed, no user deposits, public deposits closed). Neither is a backing signal, and vaultAddress is deliberately not repointed. vaultDegradedReason carries the explanation of the vaultDegraded flag at the same level as the flag. The v1 KerneVault at 0x8005bc7A86AD904C20fd62788ABED7546c1cF2AC is in a known degraded state pending v2 redeploy: its totalSupply (~4.87e36 kLP) does not reconcile with its small residual WETH backing (live read: the totalAssetsETH field in this response). The vault leg is therefore NOT counted toward protocol TVL while degraded. Outstanding kUSD is USDC-backed by the combined reserves of three Peg Stability Modules, and psmUSDC is their sum: the redeem-reserve PSM at 0xFf3025ec18e301855aB0f36Ec6ECa115a29A5Fbc (psmUSDCLegacy), the live mint PSM at 0xaBDE1138aa1Ce88d1dF06422C0c3b05D70569803 (psmUSDCMint), which holds kUSD MINTER_ROLE and receives every mint since the 2026-07-10 cutover, and the retired mint PSM at 0x07eBb486e11BD217e6085eb5ab663e4517595993 (psmUSDCPrevMint), whose MINTER_ROLE is revoked but which still custodies the reserve for kUSD minted before that cutover. READ psmMintAuthority BEFORE CONCLUDING ANYTHING FROM THE MODULE FLAGS. All three modules return mintingEnabled() true and paused() false, because those are flags stored on each module and neither is the mint authority. The authority is MINTER_ROLE on the kUSD token, published per module as psmMintAuthority[n].kusdMinterRole and true for exactly one of the three, so a mint attempted on either retired module reverts inside the same transaction and the depositor keeps their stable. A state dump that keys on the flags and stops reports three live minting contracts, which is why the flags and the authority are published side by side rather than described. On a retired module the flag being TRUE is what makes a swap there fail: the contract branches on it, calls mint, and reverts when the token refuses; with the flag false the same function pays the caller out of the kUSD inventory that module already holds, which needs no role, so switching it off would open a small live path rather than close one. The reserve sits where it sits because a module funds redemptions only from its own balance and the deployed bytecode has no administrative withdrawal. What that concentration means for a first large deposit, with the multiple stated against three denominators, is at https://kerne.fi/first-money and in the first_money object at https://kerne.fi/facts.json. Compare psmUSDC against kusdOutstanding to check backing yourself. Use kusdOutstanding, NOT kusdSupply: the PSM contracts keep the kUSD a redeemer hands over instead of burning it, so the raw ERC-20 totalSupply counts kUSD that the protocol itself holds and that nobody can present as a claim. That inventory is published as kusdPsmInventory, broken out per contract as kusdPsmInventoryLegacy, kusdPsmInventoryMint and kusdPsmInventoryPrevMint, all read live on every request. Until 2026-08-10 this sentence asserted the inventory sat ENTIRELY in the redeem-reserve PSM, which was a hardcoded location claim about a balance that moves: it was 32 there and 3 in the retired mint PSM when it was caught, while /api/por had the split right the whole time under reserves.psmRedeemReserve.kusdHeld and reserves.psmRetiredMint.kusdHeld. The legs are published rather than described, so the sentence cannot go stale again. Dividing psmUSDC by kusdSupply instead understates backing by exactly that inventory and produces a shortfall that does not exist. The ratio computed the correct way is published as psm_solvency_ratio in the signed attestation at /api/por/signed, which sums the same three legs and uses the same denominator (this endpoint reads them live, the attestation reads them hourly, so the two can differ by recent flow). apy is the modeled delta-neutral carry and is published ONLY while hedgeActive is true, meaning the signed attestation measured an open hedge book. It is null whenever the strategy is not running, because a carry that is not being earned is not a rate. The model itself, and its assumptions, stay available at /api/apy. Since 2026-07-24 apy is on the DEPLOYED basis (apyBasis): the engine sizes its short one for one against on-chain spot, so the carry is multiplied by L/(L+1), which is below one, and never by L. Before that date this field carried a flat 3.0x multiplier, which overstated the deployed book by roughly four and a half times. That 3.0x figure was retained under the label apyModeledTargetAtScale until 2026-07-28 and has now been withdrawn entirely: it was reachable only with a levered spot leg Kerne does not operate, it charged no borrow cost against itself, and it was never a rate any holder could be paid. apy is the only forward figure this endpoint publishes. modeled is hardcoded true because apy is a forward model. For yield actually paid read realizedApy (annualized on-chain skUSD share-price growth) or skusdRealizedYieldPct (the same growth, cumulative and not annualized). If any number here disagrees with those two, those two are the ones that are true. See /api/risk-status and /api/por for the canonical reserve and solvency reads, and /docs/exit-triggers-and-emergency-runbook for the documented v2 redeploy plan. /api/risk-status also publishes the state of the PSM contract safety gates, including solvencyCheckDisabled, which is true on the live mint PSM.","canonicalSources":["https://kerne.fi/api/risk-status","https://kerne.fi/api/por","https://kerne.fi/api/por/signed"],"fieldNotes":{"psmMintAuthority":"The three Peg Stability Modules side by side, read live on every request. The point of the block is the separation: mintingEnabledFlag and pausedFlag are stored ON EACH MODULE and are true and false respectively on ALL THREE, so a consumer keying on them concludes Kerne runs three live mint paths. Neither flag is the authority. kusdMinterRole is, it is read on the kUSD token rather than on the module, and it is true for exactly one of the three. A mint attempted on either other module reverts inside the same transaction and the caller keeps their stable. A null on any field means that call did not resolve this request; it never means false. Cross-check with cast call <kUSD> \"hasRole(bytes32,address)(bool)\" $(cast keccak \"MINTER_ROLE\") <module>. Note that MINTER_ROLE really is the hash of its name while DEFAULT_ADMIN_ROLE is bytes32(0) and is not.","psmCapHeadroom":"How much more USDC the live mint PSM (0xaBDE1138aa1Ce88d1dF06422C0c3b05D70569803) will accept before swapStableForKUSD reverts StableCapExceeded (0x40e97e29). Derived the way the contract derives it, cap - max(currentExposure, balanceOf(module)), NOT cap - currentExposure: a redemption whose stable payout exceeds the tracked counter floors that counter to zero while the module still holds the stable, and a counter-only gate would then re-open the full cap. Executed against deployed bytecode, including a one million USDC mint and the revert one USDC past this figure, in test/fork/PsmCapacityIsReal.t.sol in kerne-protocol/contracts-public. Capacity is not demand: this is what the contract will take, not what anyone has deposited. Compare against psmUSDC for the latter.","psmStableCap":"stableCaps(USDC) on the live mint PSM, in USDC. The getter takes the stable's address; stableCap, cap, mintCap, maxMint and supplyCap all revert on this contract, and an internal review that probed those five once concluded the cap was unreadable. It is readable.","psmCurrentExposure":"currentExposure(USDC) on the live mint PSM, in USDC. A net counter (gross mint in, minus net redeem out, saturating at zero) that is GROSS of mint fees. It is one of the two inputs to psmCapHeadroom and is not the cap binding on its own; see that note.","state":"'live-vault-degraded' describes the retired v1 KerneVault leg (0x8005bc7A86AD904C20fd62788ABED7546c1cF2AC), NOT kUSD solvency. It means the first PSM mint has happened while the v1 vault is still in its documented phantom-supply state. kUSD backing is independent and healthy: compare psmUSDC against kusdOutstanding, or read psm_solvency_ratio in the signed attestation at /api/por/signed.","vaultAddress":"This is v1 (0x8005bc7A86AD904C20fd62788ABED7546c1cF2AC) by deliberate design: public WETH vault deposits are hard-closed at the UI and closed on chain since 2026-07-30, so the funnel keeps pointing at the retired vault rather than opening a deposit path into v2. It is intentionally NOT repointed. The live mint and backing run through the PSM, and the hourly signed attestation at /api/por/signed covers the live v2 vault (0x8ccc56B5624e2FDB592F6609d81F4c3798e3292B), which holds no user deposits. Neither vault field is a backing signal.","vaultV1Address":"Equal to vaultAddress, published under a version-explicit name so the version does not have to be inferred from prose. Retired 2026-06-16, MINTER_ROLE revoked, public deposits closed. It is the vault this endpoint has always reported and the vault /api/por reports under reserves.vault.","vaultV2Address":"The live Safe-governed ERC-4626 vault (0x8ccc56B5624e2FDB592F6609d81F4c3798e3292B), the one the hourly signed attestation at /api/por/signed covers, and the one /api/por reports under reserves.vaultV2. It holds NO user deposits (zero share supply) and public deposits into it are closed, so this is a disambiguation field and not a deposit surface. It does not hold kUSD MINTER_ROLE: that was revoked 2026-08-03 and is published as a live per-request read at /api/por -> reserves.vaultV2.minterRole.holdsRole rather than asserted from any constant. Neither vault field is a backing signal; backing is psmReservesUSD over kusdOutstanding.","vaultDegraded":"True reflects the v1 vault phantom kLP supply, an accounting artifact, not a solvency failure. kUSD is USDC-backed via the PSM regardless; this flag and kUSD backing are separate reads. The full explanation is published beside the flag itself, at the top level, as vaultDegradedReason, so a consumer that drops _meta still receives it.","vaultDegradedReason":"Prose companion to the vaultDegraded boolean, carried at the top level rather than only in _meta because a flag that reads as failure must not arrive without its context. It states which vault is degraded, that the artifact is a phantom share supply rather than a shortfall, and how to check kUSD backing independently. Same facts as retired_vault_v1 in the signed attestation.","tvl":"A back-compat key whose MEANING moves with vaultDegraded, which is why it is no longer the only place the number appears. While vaultDegraded is true, tvl is the three PSM USDC legs summed and nothing else: the retired v1 vault backs no user position and is excluded. Read tvlBasis for which of the two definitions is live, and prefer psmReservesUSD, which is the same number under a name that cannot be misread. tvl is deliberately NOT renamed: an aggregator reading it today keeps reading it. Note that tvl is NOT collateralUSD and the two are expected to differ.","psmReservesUSD":"The combined USDC reserve across the three PSM contracts, identical to psmUSDC and equal to tvl for as long as vaultDegraded is true. This is the backing for outstanding kUSD; divide it by kusdOutstanding (NOT kusdSupply) to reproduce the published solvency ratio. Added because tvl alone left the semantics to prose, and the merged DefiLlama TVL adapter sums exactly these three balances on chain, so this key and that row measure one thing.","tvlBasis":"'psm-usdc-reserves-only' while the v1 vault is degraded: tvl counts PSM USDC and nothing else. 'psm-usdc-reserves-plus-vault-collateral' once a vault leg genuinely backs user positions, at which point tvl widens. The label exists so the widening is announced in a field rather than showing up as an unexplained jump in a number an aggregator has been trending.","collateralUSD":"Total USD collateral, MIRRORED verbatim from /api/por solvency.collateralUSD rather than recomputed here, so the two endpoints cannot disagree. It is WIDER than tvl on purpose: it adds the recognised collateral of the retired v1 vault and the insurance fund, neither of which backs a current mint, which is exactly why tvl excludes them. Do NOT quote it as the backing ratio numerator; that is psmReservesUSD over kusdOutstanding. The three legs are broken out under collateral.components so the difference against tvl closes without a second request. null means /api/por could not be read this cycle, never that collateral is zero.","collateral":"Provenance for collateralUSD. basis names the formula, source names the exact key it was mirrored from, blockNumber and asOf are the Base block and instant /api/por read at, and components carries the three legs, which sum to collateralUSD exactly. Reconciliation between this endpoint and /api/por is exact AT collateral.blockNumber: this response is cached for 300s while /api/por reads live, so a later fetch of /api/por can differ by flow. The block is published so that is checkable rather than something a reader has to take on trust. Note that collateral.components.psmReservesUSD is the MIRRORED PSM figure, read at collateral.blockNumber, while the top-level psmReservesUSD is this endpoint's own live read. They are the same quantity from two instants and can differ by recent flow. The top-level field is the one to key on; the component exists so collateralUSD adds up.","apy":"null is this endpoint declining to quote a modeled carry it cannot confirm is being earned (hedgeActive is not true this cycle). It is not an error and not a claim of zero yield. The model lives at /api/apy; for yield actually paid, read realizedApy or skusdRealizedYieldPct, which are the numbers that are true if anything here disagrees.","kusdSupply":"The raw ERC-20 totalSupply, published for reconciliation against a block explorer. It is NOT the backing denominator. Divide psmUSDC by kusdOutstanding instead.","kusdOutstanding":"kusdSupply less kusdPsmInventory: the kUSD actually held outside the protocol, which is the liability the reserves back and the denominator every published solvency ratio uses, including psm_solvency_ratio in the signed attestation. This is the field to divide psmUSDC by.","kusdPsmInventory":"kUSD sitting inside the three PSM contracts. A redemption transfers the redeemer's kUSD into the PSM and does not burn it, so it accumulates there. It is held by the protocol, is a claim on nobody, and is therefore excluded from the liability. Counting it would understate backing by exactly this amount. Where it sits is published, not described: read kusdPsmInventoryLegacy, kusdPsmInventoryMint and kusdPsmInventoryPrevMint, which are live per-contract reads and sum to this field. They match reserves.psmRedeemReserve.kusdHeld, reserves.psmMint.kusdHeld and reserves.psmRetiredMint.kusdHeld at /api/por.","kusdPsmInventoryLegacy":"kUSD held by the redeem-reserve PSM at 0xFf3025ec18e301855aB0f36Ec6ECa115a29A5Fbc. Live read, never a constant. This leg and the two beside it replaced a prose sentence that claimed the whole inventory sat here; it did not, and a hardcoded location claim about a balance that moves is a defect whether or not it happens to be true on the day it ships.","kusdPsmInventoryMint":"kUSD held by the live mint PSM at 0xaBDE1138aa1Ce88d1dF06422C0c3b05D70569803. Live read. Expected to be near zero: this contract receives mints, and redemptions are served by the reserve legs, so inventory accumulates there rather than here.","kusdPsmInventoryPrevMint":"kUSD held by the retired mint PSM at 0x07eBb486e11BD217e6085eb5ab663e4517595993. Live read. MINTER_ROLE is revoked here, but a revoked minter can still serve redemptions (the redeem path transfers kUSD in rather than burning it), which is exactly why this leg is non-zero and why assuming the inventory sits in one contract is wrong.","modeled":"Hardcoded true, and it will never be false. apy is a forward model computed from market funding and staking rates. It is not a record of yield distributed. An aggregator that ingests it as a realized rate is misreading this endpoint; realizedApy is the field for that.","apyBasis":"'deployed' means apy is computed as [L/(L+1)] x (staking + funding) x the three published haircuts, where L is the venue leverage the engine targets at the prevailing funding rate. The multiplier is below one because the short is sized one for one against spot and the margin posted behind it earns nothing. Venue leverage reduces posted margin; it does not multiply the carry earned on the underlying. 'deployed+incentive' means apy is NOT strategy carry: a funded Genesis incentive is live and apy is the total of that carry plus a subsidy paid out of USDC escrowed on chain. Read the decomposition, the escrow address and the balance behind it in the incentive block at /api/apy, and verify the escrow yourself at the address published there. An aggregator ingesting this value as organic yield is misreading it, which is why the label changes rather than the number changing silently.","realizedApy":"Annualized growth of the on-chain skUSD share price over the measurement window (realizedApyWindowDays), sourced from /api/honesty-index. This is the only yield figure on this endpoint that is a measurement rather than a model, and it is deliberately NOT gated on hedgeActive: it describes yield already paid, which stays true whether or not a book is open right now. null means the read missed or failed its plausibility bounds, never that the yield was zero.","hedgeActive":"Whether the signed hourly attestation MEASURED an open hedge book this cycle: true = measured, false = no book or the venue read failed, null = the attestation could not be verified or predates the v5 qualifier. null is not a claim that the hedge is off. The signed source is delta_neutral_state at /api/por/signed."}}}