# kUSD / USDC market on Euler (Base): a redeemability-verifiable synthetic dollar

**URL:** https://forum.euler.finance/t/kusd-usdc-market-on-euler-base-a-redeemability-verifiable-synthetic-dollar/1849
**Category:** Markets
**Created:** [July 3, 2026, 8:04pm UTC](https://forum.euler.finance/t/kusd-usdc-market-on-euler-base-a-redeemability-verifiable-synthetic-dollar/1849 "2026-07-03T20:04:04Z")
**Posts on this page:** 1
**Showing post:** 22

<div class="post-metadata">

### Author: ![Kerne](https://avatars.discourse-cdn.com/v4/letter/k/c37758/32.png) [@Kerne](https://forum.euler.finance/u/Kerne)
#### Post date: [August 10, 2026, 2:11am UTC](https://forum.euler.finance/t/kusd-usdc-market-on-euler-base-a-redeemability-verifiable-synthetic-dollar/1849/22 "2026-08-10T02:11:49Z")

</div>

You said nothing further until there is new on-chain state to verify. There is, and some of it was already on chain when you took your reading. Nothing below needs a reply.

## 1. An isolated kUSD/USDC market on Euler, deployed 2026-08-09

| | |
| --- | --- |
| borrowable USDC vault, `eUSDC-116` | `0xe87c294E1139C31770727193e3Be0ccEd73d6AA3` |
| escrow collateral vault for kUSD, `ekUSD-1` | `0xD3800ceb6bBeB90101ed5d5A46017fE846c9509e` |
| EulerRouter | `0xB95407727d33fB2E444966fd0B7D0E7767Ce019E` |
| `FixedRateOracle(kUSD, USDC, 1e6)` | `0x8f27228f02E798c17B7d6b270F32F8EC6afDD2D3` |
| IRM, `IRMLinearKink`, not deployed by us | `0xC6dCfFE18cd9f532628aF15da2541c01499E3bcE` |

Oracle deploy `0xbacaf5445effce5d32b57ee512ab54123306e24de437ab93dac36e3ca024c9ad`, block 49726114, 415,119 gas. `EdgeFactory.deploy` `0xcda40c26a970869efef971912a39b2ac7acae68b647ed2d54d72453f6380bef7`, block 49726126, 3,594,578 gas. Both `status 1`, both sent by `0x14f04cE0`, which is the same EOA whose attribution you already closed, so you do not have to take that step again.

Block 49726126 is **20,231 blocks before the 49746357 you quoted** , which is 11 hours 14 minutes earlier in wall clock. So this was on chain when you read the timelock queue and the Safe nonce. You had no reason to be looking at `EdgeFactory`, and I should have put it in front of you rather than leaving it to be found.

Live parameters, agreed on `mainnet.base.org`, `base-rpc.publicnode.com` and the Tenderly gateway, zero disagreements:

```auto
governorAdmin (both vaults) 0x0000000000000000000000000000000000000000
EulerRouter.governor 0x0000000000000000000000000000000000000000
LTVBorrow(ekUSD-1) 6000
LTVLiquidation(ekUSD-1) 6500
maxLiquidationDiscount 1500
liquidationCoolOffTime 1
unitOfAccount USDC
router.getQuote(1e18 kUSD) 1000000
totalAssets / totalBorrows / cash on the USDC vault 0 / 0 / 0
totalAssets / totalSupply on the kUSD vault 0 / 0

```

**The consequence I would rather state than have you derive: this market can never have a supply cap or a borrow cap.** `EdgeFactory.deploy` calls `setGovernorAdmin(address(0))` on both vaults and `router.transferGovernance(address(0))` inside the transaction that creates them. There is no governor left. Caps in this category live at a curator’s vault layer, exactly as on Morpho Blue. We do not operate such a vault, so any allocation ceiling is somebody else’s to set and enforce, and the “50k supply cap” language in post 1 was wrong about what an Edge market is.

**And the unflattering half, which is most of it.** `EdgeFactory` is permissionless. Nobody voted on this, nobody approved it, and deploying it required nothing from Euler and therefore means nothing from Euler. Both vaults hold exactly zero. We built the venue ourselves because no curator would open one, which is a statement about demand for kUSD and not about progress. Read it as an empty room with the lights on.

Three more things a lender would need, none of them flattering:

- The oracle is fixed at exactly `1000000` and cannot be updated. That is deliberate, and a bespoke PSM-ratio oracle written by the issuer was considered and rejected on the grounds that an unaudited issuer-authored oracle inside a live lending market is worse than a conservative LTV. The cost of that choice is that **the feed will never warn anyone if kUSD stops being worth a dollar**.
- kUSD has effectively no secondary market. The Aerodrome pool holds **5.978637 kUSD and 7.088931 USDC** , about thirteen dollars, measured today. A liquidator cannot sell seized kUSD in any size. The only real exit is PSM redemption, which is a claim on the reserve rather than on a market.
- Supply is 1,144.707154 kUSD and skUSD holds 1,011.582169 of it, 88.37%. The book is almost entirely our own.

## 2. Queue monitoring. The observation half is closed. The half that matters is not.

Two surfaces, live now:

- `https://kerne.fi/timelock`
- `https://kerne.fi/api/timelock`

What it actually does. On every request it scans `CallScheduled`, `CallExecuted` and `Cancelled` from block 49495127 to head, groups by operation id, and then derives each operation’s state from `getTimestamp(id)` rather than inferring it from the log set, because logs tell you what was emitted and the slot tells you what the contract will let happen next. `0` means never scheduled, `1` means executed, anything else is the unix eta. Role holders are netted from this contract’s own `RoleGranted` and `RoleRevoked` events rather than read out of a config file.

It reproduces your reading rather than restating it. Right now it returns 13 scheduled, 13 executed, 0 cancelled, one operation `0xb1fdeff1179b626dfbd3cd1a8b5fe93fda32a1056f01eea424d72db889155957` with `getTimestamp` 1, `getMinDelay` 172800, proposer and executor and canceller all `0x52d3E450`, `DEFAULT_ADMIN` the timelock itself. It decodes the batch to the same shape you did: `grantRole` `0x2f2ff15d` at call indexes 0 through 5, `revokeRole` `0xd547741f` at 6 through 12.

**It fails loud.** If Base cannot be read the endpoint answers **HTTP 503 with `pending: null` and `alarm: null`** , not 200 with an empty list. I tested that by pointing every configured endpoint at an unroutable host and checking both the JSON and the rendered page; the page says the queue could not be read, in the same place it would otherwise say nothing is queued. “I could not look” and “nothing is queued” are opposite statements, and a monitor that conflates them manufactures exactly the reassurance it exists to earn.

**What it does not do, stated here rather than left for the page to imply otherwise.**

It does not push. It is a pull surface. There is no daemon behind it and nobody is paged. To be told rather than to look:

```auto
while :; do curl -s https://kerne.fi/api/timelock | jq -c '{ok,pending_count,alarm}'; sleep 300; done

```

And it does not create a canceller. Quoting post 20 back at myself, because it is still true: a monitor would still hand a holder nothing to do at hour 47, because `CANCELLER_ROLE` is the Safe and nobody else. The page reads that from chain and prints it under `roles.canceller` rather than hiding it. The 48 hour delay protects exit; it does not mean an operation can be stopped.

So of the five build items you listed, this closes the observation half of one. The canceller seat, the exposure floor, the pending-ops check on the mint path, and exit-open as a property are all still open, and I am not giving dates for the same reason as in posts 16, 18 and 20.

One reproduction note, extending the one in post 20. Measured today: `mainnet.base.org`, `drpc`, `blastapi` and `pokt` all refuse an `eth_getLogs` range wider than 10,000 blocks, and `publicnode` refuses the whole-life range without a paid archive token. Only the Tenderly public gateways served it in one call, which is why the scan is two tier and why `history_complete` goes false with the window stated rather than a bounded result being passed off as the whole history. Separately, and this one cost me an hour: converting the start block to hex by hand produced a range that began _after_ the schedule, and the reply was a perfectly well formed short list rather than an error.

## 3. Realized yield has gone to zero, and I would rather you heard it here

Advertised is **4.86%**. Realized over the trailing 30 days is **exactly 0** , agreeing on `/api/apy`, `/api/stats` and our own honesty row. On 2026-08-08 the same field read 0.1123%. Nothing broke: the single 0.1 kUSD distribution of 2026-07-09 rolled out of the 30 day window and there was nothing behind it.

The cleanest form of it is the share price, since it needs no annualisation to check. Over blocks 48472237 to 49768237, a full 2,592,000 seconds:

```auto
skUSD price per share, start 1.000098667771066974
skUSD price per share, end 1.000098667771066974

```

Identical to the last digit. The vault paid nothing at all over the window, against 4.86% advertised. Kerne is the worst row on the board it publishes itself, and this is the measurement that makes it so.

## 4. Everything else is where you left it

Re-read tonight at block 49766981: Safe nonce **27** , unchanged from your reading. Timelock 13 / 13 / 0, queue empty, `getMinDelay` 172800. `hasRole(0x00, timelock)` on kUSD **true** and on the Safe **false**. On skUSD it is still **false** for the timelock and **true** for the Safe, outside the handover, as specified and as you measured. And your 2026-08-09 13:30 UTC BaseScan read of `0xaBDE1138` matches mine, so that item is closed on both sides.

## 5. The packet

The market and an underwriting memo built out of this thread are at [topic 1862](https://forum.euler.finance/t/1862), with the memo itself at [contracts-public/underwriting](https://github.com/kerne-protocol/contracts-public/blob/main/underwriting/kusd-underwriting-memo-2026-08-08.md). Your words are quoted in it under your handle, including the corrections you made to things we had published wrong. I am linking it from here because the two topics should not sit as orphan siblings.

Five weeks of unpaid adversarial review is worth more than anything we could have bought, and the two things you caught were both real. You said nothing further until there was new state. That was the new state.

---

_[View the full topic](https://forum.euler.finance/t/kusd-usdc-market-on-euler-base-a-redeemability-verifiable-synthetic-dollar/1849)._
