PACTAby Fractal Neurons
Pacta / Onboarding briefs / kerne-kusd-base
Onboarding verification briefEuler forum #1862

kUSD (Kerne): control-plane state at Base Mainnet block 57,050,397

Read-only verification of who can change kUSD (Kerne) and the Euler (Base) · isolated kUSD/USDC market it is proposed for, pinned to a canonical block and reproducible on any archive node. Forum thread: kUSD/USDC isolated market on Euler Base: deployed, ungoverned, and an underwriting packet for curators ↗.

Asset
kUSD (Kerne)
Venue
Euler (Base) · isolated kUSD/USDC market
Pinned block
Base Mainnet #57,050,397 · 2026-11-13 20:07:35 UTC Canonical (EIP-1898)
Block hash
0xd6d02efb…eb88a7
Data
/api/v1/onboarding.json · slug kerne-kusd-base
Market governor
address(0)
Vaults + router immutable
kUSD admin
48h timelock
Proposer: 2-of-3 Safe
Oracle
1.00 USDC
Fixed rate per kUSD
LTV (borrow / liq.)
60% / 65%
Set at deploy

1. Findings

  • The market layer has no governor: governorAdmin() returns 0x0000…0000 on the USDC vault and 0x0000…0000 on the kUSD escrow vault, and EulerRouter.governor() returns 0x0000…0000. Oracle, LTVs and caps cannot be changed by anyone.
  • Caps are unset and cannot be set: supply cap none (AmountCap 0), borrow cap none (AmountCap 0). Exposure limits exist only in the curator vault that allocates to this market.
  • kUSD is priced at a fixed rate: getQuote(1e18 kUSD → USDC) = 1.00 USDC from 0x8f27…D2D3. Borrow / liquidation LTV 60.00% / 65.00%. No market price feeds liquidations, so lender recovery depends on kUSD redemption and its backing.
  • kUSD implements AccessControl (supportsInterface(0x7965db0b) = true). DEFAULT_ADMIN_ROLE on kUSD is held by the TimelockController 0x36A1…0D72 (hasRole = true; getMinDelay() = 172,800s, 48h). The 2-of-3 Safe 0x52d3…4877 is its proposer, executor and canceller (true / true / true) and does not hold DEFAULT_ADMIN_ROLE on kUSD itself.
  • MINTER_ROLE is held by 0xaBDE…9803 (kUSD() = 0x5C2E…0AA3, paused() = false), whose DEFAULT_ADMIN_ROLE is the same timelock (true). Role changes on kUSD and on the minter pass a 48-hour public queue.
  • kUSD AccessControl role history (16 events, blocks 44,448,090–57,050,397): DEFAULT_ADMIN_ROLE → 0x36A1…0D72 (contract, 6,536 bytes); MINTER_ROLE → 0xaBDE…9803 (contract, 11,376 bytes).
  • kUSD admin TimelockController role history (4 events, blocks 49,495,127–57,050,397): DEFAULT_ADMIN_ROLE → 0x36A1…0D72 (contract, 6,536 bytes); PROPOSER_ROLE → 0x52d3…4877 (2-of-3 Safe); EXECUTOR_ROLE → 0x52d3…4877 (2-of-3 Safe); CANCELLER_ROLE → 0x52d3…4877 (2-of-3 Safe).
  • kUSD minter contract role history (11 events, blocks 48,469,020–57,050,397): DEFAULT_ADMIN_ROLE → 0x36A1…0D72 (contract, 6,536 bytes); MANAGER_ROLE → 0x36A1…0D72 (contract, 6,536 bytes), 0xC47a…Cc8E (contract, 1,012 bytes).

2. Observed state at block 57,050,397

Block hash 0xd6d02efb…eb88a7; every read below used EIP-1898 {blockHash, requireCanonical: true} and returned byte-identical results on 3 independent RPC endpoints.

CheckContractValue
kUSD totalSupply()0x5C2E…0AA31135263248000000000000
kUSD decimals()0x5C2E…0AA318
kUSD symbol()0x5C2E…0AA3kUSD
kUSD supportsInterface(IAccessControl)0x5C2E…0AA3true
eUSDC vault governorAdmin()0xe87c…6AA30x0000000000000000000000000000000000000000
eUSDC vault oracle()0xe87c…6AA30xB95407727d33fB2E444966fd0B7D0E7767Ce019E
eUSDC vault caps() (supplyCap, borrowCap)0xe87c…6AA30, 0
eUSDC LTVBorrow(ekUSD)0xe87c…6AA36000
eUSDC LTVLiquidation(ekUSD)0xe87c…6AA36500
eUSDC totalAssets()0xe87c…6AA350129596
eUSDC totalBorrows()0xe87c…6AA320129596
ekUSD escrow governorAdmin()0xD380…509e0x0000000000000000000000000000000000000000
ekUSD escrow asset()0xD380…509e0x5C2EfdF0D8D286959b42308966bc2B97f5680AA3
ekUSD escrow totalAssets()0xD380…509e80000000000000000000
EulerRouter governor()0xB954…019E0x0000000000000000000000000000000000000000
EulerRouter getConfiguredOracle(kUSD, USDC)0xB954…019E0x8f27228f02E798c17B7d6b270F32F8EC6afDD2D3
FixedRateOracle getQuote(1e18 kUSD -> USDC)0x8f27…D2D31000000
Kerne Safe getThreshold()0x52d3…48772
Kerne Safe getOwners()0x52d3…4877[3] 0x14f04cE02f35B29Af564A98544dD7e2393993946, 0x0CeC7021f4c20f3D5eBb55c1AC591c15eFBb7895, 0xf4A43C88b7370Bd6e370c7Af5FE663c6D223B3fb
kUSD hasRole(DEFAULT_ADMIN_ROLE, Kerne Safe)0x5C2E…0AA3false
kUSD hasRole(DEFAULT_ADMIN_ROLE, admin timelock)0x5C2E…0AA3true
kUSD admin timelock getMinDelay()0x36A1…0D72172800
timelock hasRole(PROPOSER_ROLE, Kerne Safe)0x36A1…0D72true
timelock hasRole(EXECUTOR_ROLE, Kerne Safe)0x36A1…0D72true
timelock hasRole(CANCELLER_ROLE, Kerne Safe)0x36A1…0D72true
kUSD hasRole(MINTER_ROLE, minter contract)0x5C2E…0AA3true
minter contract kUSD()0xaBDE…98030x5C2EfdF0D8D286959b42308966bc2B97f5680AA3
minter contract paused()0xaBDE…9803false
minter hasRole(DEFAULT_ADMIN_ROLE, admin timelock)0xaBDE…9803true

3. Role maps (replayed from events)

kUSD AccessControl role history · 0x5C2E…0AA3 · 16 events, blocks 44,448,090–57,050,397

RoleHolders at the pinned blockCapability (target · function)
DEFAULT_ADMIN_ROLE0x36A1…0D72 (contract, 6,536 bytes)—
MINTER_ROLE0xaBDE…9803 (contract, 11,376 bytes)—

kUSD admin TimelockController role history · 0x36A1…0D72 · 4 events, blocks 49,495,127–57,050,397

RoleHolders at the pinned blockCapability (target · function)
DEFAULT_ADMIN_ROLE0x36A1…0D72 (contract, 6,536 bytes)—
PROPOSER_ROLE0x52d3…4877 (2-of-3 Safe)—
EXECUTOR_ROLE0x52d3…4877 (2-of-3 Safe)—
CANCELLER_ROLE0x52d3…4877 (2-of-3 Safe)—

kUSD minter contract role history · 0xaBDE…9803 · 11 events, blocks 48,469,020–57,050,397

RoleHolders at the pinned blockCapability (target · function)
DEFAULT_ADMIN_ROLE0x36A1…0D72 (contract, 6,536 bytes)—
MANAGER_ROLE0x36A1…0D72 (contract, 6,536 bytes)
0xC47a…Cc8E (contract, 1,012 bytes)
—

4. Reproduce

Reproduce every value on any archive node
# Base Mainnet block 57050397
cast block 57050397 --field hash --rpc-url "$BASE_RPC_URL"
# expect 0xd6d02efb420f81b3f0e095d78453362c4488afb9adc0f8e1c411bb265beb88a7

# kUSD totalSupply()
cast call 0x5C2EfdF0D8D286959b42308966bc2B97f5680AA3 "totalSupply()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# kUSD decimals()
cast call 0x5C2EfdF0D8D286959b42308966bc2B97f5680AA3 "decimals()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# kUSD symbol()
cast call 0x5C2EfdF0D8D286959b42308966bc2B97f5680AA3 "symbol()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# kUSD supportsInterface(IAccessControl)
cast call 0x5C2EfdF0D8D286959b42308966bc2B97f5680AA3 "supportsInterface(bytes4)" 0x7965db0b00000000000000000000000000000000000000000000000000000000 --block 57050397 --rpc-url "$BASE_RPC_URL"
# eUSDC vault governorAdmin()
cast call 0xe87c294E1139C31770727193e3Be0ccEd73d6AA3 "governorAdmin()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# eUSDC vault oracle()
cast call 0xe87c294E1139C31770727193e3Be0ccEd73d6AA3 "oracle()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# eUSDC vault caps() (supplyCap, borrowCap)
cast call 0xe87c294E1139C31770727193e3Be0ccEd73d6AA3 "caps()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# eUSDC LTVBorrow(ekUSD)
cast call 0xe87c294E1139C31770727193e3Be0ccEd73d6AA3 "LTVBorrow(address)" 0xD3800ceb6bBeB90101ed5d5A46017fE846c9509e --block 57050397 --rpc-url "$BASE_RPC_URL"
# eUSDC LTVLiquidation(ekUSD)
cast call 0xe87c294E1139C31770727193e3Be0ccEd73d6AA3 "LTVLiquidation(address)" 0xD3800ceb6bBeB90101ed5d5A46017fE846c9509e --block 57050397 --rpc-url "$BASE_RPC_URL"
# eUSDC totalAssets()
cast call 0xe87c294E1139C31770727193e3Be0ccEd73d6AA3 "totalAssets()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# eUSDC totalBorrows()
cast call 0xe87c294E1139C31770727193e3Be0ccEd73d6AA3 "totalBorrows()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# ekUSD escrow governorAdmin()
cast call 0xD3800ceb6bBeB90101ed5d5A46017fE846c9509e "governorAdmin()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# ekUSD escrow asset()
cast call 0xD3800ceb6bBeB90101ed5d5A46017fE846c9509e "asset()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# ekUSD escrow totalAssets()
cast call 0xD3800ceb6bBeB90101ed5d5A46017fE846c9509e "totalAssets()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# EulerRouter governor()
cast call 0xB95407727d33fB2E444966fd0B7D0E7767Ce019E "governor()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# EulerRouter getConfiguredOracle(kUSD, USDC)
cast call 0xB95407727d33fB2E444966fd0B7D0E7767Ce019E "getConfiguredOracle(address,address)" 0x5C2EfdF0D8D286959b42308966bc2B97f5680AA3 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 --block 57050397 --rpc-url "$BASE_RPC_URL"
# FixedRateOracle getQuote(1e18 kUSD -> USDC)
cast call 0x8f27228f02E798c17B7d6b270F32F8EC6afDD2D3 "getQuote(uint256,address,address)" 1000000000000000000 0x5C2EfdF0D8D286959b42308966bc2B97f5680AA3 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 --block 57050397 --rpc-url "$BASE_RPC_URL"
# Kerne Safe getThreshold()
cast call 0x52d3E450bA6c299B1B07298F1E87DD74732D4877 "getThreshold()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# Kerne Safe getOwners()
cast call 0x52d3E450bA6c299B1B07298F1E87DD74732D4877 "getOwners()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# kUSD hasRole(DEFAULT_ADMIN_ROLE, Kerne Safe)
cast call 0x5C2EfdF0D8D286959b42308966bc2B97f5680AA3 "hasRole(bytes32,address)" 0x0000000000000000000000000000000000000000000000000000000000000000 0x52d3E450bA6c299B1B07298F1E87DD74732D4877 --block 57050397 --rpc-url "$BASE_RPC_URL"
# kUSD hasRole(DEFAULT_ADMIN_ROLE, admin timelock)
cast call 0x5C2EfdF0D8D286959b42308966bc2B97f5680AA3 "hasRole(bytes32,address)" 0x0000000000000000000000000000000000000000000000000000000000000000 0x36A14976980B7Dd33136f6613545EB0A2C0a0D72 --block 57050397 --rpc-url "$BASE_RPC_URL"
# kUSD admin timelock getMinDelay()
cast call 0x36A14976980B7Dd33136f6613545EB0A2C0a0D72 "getMinDelay()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# timelock hasRole(PROPOSER_ROLE, Kerne Safe)
cast call 0x36A14976980B7Dd33136f6613545EB0A2C0a0D72 "hasRole(bytes32,address)" 0xb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1 0x52d3E450bA6c299B1B07298F1E87DD74732D4877 --block 57050397 --rpc-url "$BASE_RPC_URL"
# timelock hasRole(EXECUTOR_ROLE, Kerne Safe)
cast call 0x36A14976980B7Dd33136f6613545EB0A2C0a0D72 "hasRole(bytes32,address)" 0xd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63 0x52d3E450bA6c299B1B07298F1E87DD74732D4877 --block 57050397 --rpc-url "$BASE_RPC_URL"
# timelock hasRole(CANCELLER_ROLE, Kerne Safe)
cast call 0x36A14976980B7Dd33136f6613545EB0A2C0a0D72 "hasRole(bytes32,address)" 0xfd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783 0x52d3E450bA6c299B1B07298F1E87DD74732D4877 --block 57050397 --rpc-url "$BASE_RPC_URL"
# kUSD hasRole(MINTER_ROLE, minter contract)
cast call 0x5C2EfdF0D8D286959b42308966bc2B97f5680AA3 "hasRole(bytes32,address)" 0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6 0xaBDE1138aa1Ce88d1dF06422C0c3b05D70569803 --block 57050397 --rpc-url "$BASE_RPC_URL"
# minter contract kUSD()
cast call 0xaBDE1138aa1Ce88d1dF06422C0c3b05D70569803 "kUSD()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# minter contract paused()
cast call 0xaBDE1138aa1Ce88d1dF06422C0c3b05D70569803 "paused()" --block 57050397 --rpc-url "$BASE_RPC_URL"
# minter hasRole(DEFAULT_ADMIN_ROLE, admin timelock)
cast call 0xaBDE1138aa1Ce88d1dF06422C0c3b05D70569803 "hasRole(bytes32,address)" 0x0000000000000000000000000000000000000000000000000000000000000000 0x36A14976980B7Dd33136f6613545EB0A2C0a0D72 --block 57050397 --rpc-url "$BASE_RPC_URL"

# kUSD AccessControl role history: replay 16 events
cast logs --from-block 44448090 --to-block 57050397 --address 0x5C2EfdF0D8D286959b42308966bc2B97f5680AA3 --rpc-url "$BASE_RPC_URL"

# kUSD admin TimelockController role history: replay 4 events
cast logs --from-block 49495127 --to-block 57050397 --address 0x36A14976980B7Dd33136f6613545EB0A2C0a0D72 --rpc-url "$BASE_RPC_URL"

# kUSD minter contract role history: replay 11 events
cast logs --from-block 48469020 --to-block 57050397 --address 0xaBDE1138aa1Ce88d1dF06422C0c3b05D70569803 --rpc-url "$BASE_RPC_URL"

5. Scope

  • Observations of on-chain state only. They do not assess code correctness, reserves, legal structure or off-chain key custody, and they are not investment advice.
  • Issuers can clear or document these findings with a 24h Collateral Onboarding & Delta Clearance Attestation ($5,000 USDC flat): block-pinned audit, docs / config reconciliation PR, Base EAS Aligned attestation and a Curator Diligence Dossier for the forum thread.
For issuers

Issuing kUSD (Kerne)? Reconcile & Anchor 24h Institutional Clearance

Reconcile documentation drift, verify multisig and timelock control planes across archive RPCs, prepare an upstream docs reconciliation PR, and anchor a Base EAS Aligned Attestation + Curator Diligence Dossier within 24 hours.

Read-only on-chain analysis. Not investment advice. Exploit-sensitive vulnerabilities are never published here; they go through Immunefi or Cantina bounty programmes.Clear these findings in 24h · $5,000 USDC →