Kerne Logo

Deployed vs Source

Last updated: July 25, 2026

On any young protocol the repository moves faster than the chain. This page is the canonical table of every place where Kerne's deployed bytecode behaves differently from the current source, so a reviewer reading the code finds context here rather than surprises there. It was first published before any external review began, and it is where the gap between the audited commit and the deployed contracts is stated.

The reading rule: when an internal security document marks a finding FIXED, that means fixed in source. Whether the fix is live on chain is a separate fact, and this page is where that fact lives.

How to read the protocol's state

Every security finding Kerne has published falls into one of four buckets:

  1. Fixed and deployed. The fix is live bytecode. The findings tracker cites the closing commit and date per finding.
  2. Fixed in source, not yet on chain. The deployment ceremony this page once described as pending has since executed, in two parts: the vault on 2026-06-16 and the mint PSM on 2026-07-10. The PSM was deployed from the frozen audit commit and matches it. The vault was deployed from source that predates the vault fixes, so those fixes did not close on chain when the ceremony ran, and the eight Hexens remediations written afterwards are not on chain either. That is the first row of the table below, stated rather than left for a reader to infer from the word FIXED.
  3. Open on chain, with a mitigation and an operating rule. The three standing divergences in the table below. These are the gaps that persist today, each with a stated rule that bounds its exposure.
  4. Source only, never deployed. The repository contains contracts that have never been deployed (including kUSDMinter and the entire cross-chain bridge stack, the latter under an explicit do-not-deploy quarantine). Findings against them affect no live funds. The auditor-facing scope document draws this boundary precisely.

The three standing divergences

Each row states what the live bytecode does, what the current source does instead, the practical exposure, and the operating rule that bounds it. All three contracts are source-verified on BaseScan and Sourcify, so everything described here is independently checkable against the deployed code itself.

KerneVault v2

Deployed 2026-06-16
0x8ccc56B5624e2FDB592F6609d81F4c3798e3292B

Deployed bytecode

The verified source of the live vault is byte-identical to repository commit ecc95cf7 (2026-06-15), the day before it was deployed. That is roughly three weeks earlier than commit 0912c870, the commit the Hexens review covers. All ten findings in the Hexens initial report are live on this bytecode, along with three defects we found and fixed ourselves after the deploy and before the audit freeze: two NAV accounting gaps on the sweep, L1 and prime-allocation paths, and the withdrawal-side esKERNE forfeiture dust bypass reported by a whitehat. The on-chain public-deposits gate is also absent, so calling depositsEnabled() on the live contract reverts.

Current source

Current source carries the two NAV reclassification fixes, the forfeiture high-water fix, and the depositsEnabled gate. The remediation branch flip/hexens-remediation-jul20 at commit 98f29e55, a child of the audited commit, additionally carries eight of the ten Hexens fixes. The other two findings are acknowledged by design, with the reasoning published in full rather than patched under time pressure.

Practical exposure

The vault holds no user funds. totalSupply() is 0, its WETH balance is 0, and no third party has ever held a share. Both High findings concern esKERNE forfeiture, and esKERNE totalSupply() and totalEmitted() are both 0, so nothing has ever been emitted for the mechanism to act on. There is no open drain. The real exposure is forward-looking and it is specific: because the on-chain deposits gate was never deployed, maxDeposit() returns the maximum uint256 for any address, so a depositor could put funds into pre-audit bytecode before the remediated build is live.

Operating rule

Standing operating rule, and the sequencing this protocol commits to: remediated bytecode before capital, not before announcement. No deposit is opened into this address until the remediated build is deployed and verified. Closing the door on chain is a single 2-of-3 Safe call to setWhitelistEnabled(true), which reproduces the missing gate exactly and leaves withdrawals untouched. The full finding-by-finding on-chain map, with commands to reproduce every claim, is in the repository at docs/security/DEPLOYED_BYTECODE_VS_AUDITED_SOURCE_2026-07-25.md.

kUSD

Deployed 2026-04-08
0x5C2EfdF0D8D286959b42308966bc2B97f5680AA3

Deployed bytecode

Standard OpenZeppelin ERC20Burnable: burnFrom is callable by any address holding an allowance from the token owner. No role gate on burning.

Current source

Burning is gated behind BURNER_ROLE in src/kUSD.sol; only role holders can burn third-party balances, allowance or not.

Practical exposure

An attacker must first obtain an allowance from the holder (a malicious or compromised approval target). With one, they can destroy the holder's kUSD rather than transfer it. There is no path to burn without an allowance, so the practical surface is the same approval hygiene every ERC-20 demands.

Operating rule

Permanent disclosure item. No kUSD redeploy is planned: a token migration would cost holders more than the role gate is worth at current scale. Treat kUSD approvals with the same care as any token approval.

KerneYieldDistributor

Deployed 2026-04 (pre-timelock source)
0x096e38a04B632D28E017f86836225E0956CaD878

Deployed bytecode

ROOT_UPDATER_ROLE can set a new Merkle distribution root with immediate effect. The role is held by the operational hot wallet 0x09a2780ac8Be6D5d2d1F85A8D92b09D40C9CA37e (the same EOA that signs the hourly Proof of Reserves).

Current source

Root updates go through proposeMerkleRoot and executeMerkleRoot with a 24-hour ROOT_UPDATE_TIMELOCK, so a compromised updater key cannot route funds instantly.

Practical exposure

If the deployed contract held funds and the hot key were compromised, an arbitrary root could claim them. Today the exposure is zero in practice because the contract is deliberately unfunded: there is nothing on it to route.

Operating rule

Standing operating rule: never fund the deployed distributor. Redeploy from current source (with the timelock) before any real yield routes through it. The unfunded state is verifiable on chain at any time.

Recently closed on chain

Verified July 13, 2026

skUSD immediate distribution. This was a standing divergence until the 2026-07-03 redeploy to 0x96F5102C shipped the streaming distribution code. Each yield distribution now vests over a 24-hour window (yieldVestingPeriod = 86,400 seconds), so a depositor can no longer bracket a distribution with transient capital. Deployed now matches source, so the row has left the table above. The value is readable on chain at any time.

Why we publish this

A reviewer who finds a source-versus-chain gap on their own has every reason to read it as concealment. The same facts, stated by the team first with addresses and operating rules, are evidence the team knows its own system. Kerne has found and published over two hundred findings against its own code; this page is where the honest residue of that work lives. If a future deployment changes any row above, this page changes in the same commit.

Continue the audit trail: the audit and security posture page, the per-finding status tracker, the public contract registry, and the one-link diligence surface at kerne.fi/dataroom.