Kerne Logo

Security / Safe queue

The Safe queue, decoded

Kerne is administered by a 2-of-3 Safe on Base. Its pending queue is public, and one of the entries in it is a fully signed transaction against the kUSD token contract that has been sitting there since April 2026. This page decodes every pending entry from its calldata, explains why that one can never execute, and publishes how long the Safe has actually taken to produce a second signature across every transaction it has ever executed.

Snapshot taken at block 49,457,217, 2026-08-02T20:49:41Z. Every figure below carries the command to re-read it. Nothing here needs our cooperation.

1. What is in the queue right now

Three entries. The Safe's live nonce is 19, its threshold is 2, its guard slot is zero and its module list is empty.

Nonce 02 of 2 signaturessubmitted 2026-04-16T00:20:47Z

Target: kUSD token 0x5C2EfdF0D8D286959b42308966bc2B97f5680AA3

selector 0x2f2ff15a, arguments MINTER_ROLE and 0x7286200Ba4C6Ed5041df55965c484a106F4716FD

Permanently unexecutable. Four independent reasons, section 2.

Nonce 191 of 2 signaturessubmitted 2026-08-01T23:03:25Z

Target: kUSD token 0x5C2EfdF0D8D286959b42308966bc2B97f5680AA3

revokeRole(MINTER_ROLE, 0x8ccc56B5624e2FDB592F6609d81F4c3798e3292B)

Awaiting a second signature.

Nonce 201 of 2 signaturessubmitted 2026-08-01T23:03:26Z

Target: live mint module 0xaBDE1138aa1Ce88d1dF06422C0c3b05D70569803

setMaxOracleDelay(0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, 172800)

Awaiting a second signature.

Every call above is operation 0, a plain CALL, with zero value and zero in every gas field. None of them is a DELEGATECALL, and none of them is wrapped in a MultiSend.

2. The fully signed entry at nonce 0, and why it is inert

This is the entry that looks alarming. It carries two confirmations out of two, it targets the kUSD token, and its payload contains the hash of MINTER_ROLE. A reader who stops there reasonably concludes that a mint-authority grant is one click from executing. It is not, and here is each reason separately, because any one of them is sufficient on its own.

  1. Its nonce is spent. Safe transactions consume nonces strictly in order, and the Safe's live nonce is 19. A nonce-0 payload cannot be executed at 19: the nonce is part of the EIP-712 struct that the signatures are checked against, so the existing signatures do not even authorise a re-nonced version of the same call.
  2. Its function selector does not exist on kUSD. The payload begins 0x2f2ff15a. The selector for grantRole(bytes32,address) is 0x2f2ff15d. They differ in the last nibble. Searching the deployed kUSD runtime finds 0x2f2ff15d present and 0x2f2ff15a absent, which is an apples-to-apples control rather than a bare absence claim. The 4-byte directory has no entry for it at all.
  3. The identical payload has already been executed, and it reverted. On 2026-04-16 the Safe executed this exact call at nonce 0 in transaction 0x46eb8404 at block 44,762,366. The Safe emitted ExecutionFailure, not ExecutionSuccess. So this is not a theoretical argument about selectors: the call was tried on chain and did nothing. The pending entry is a duplicate proposal for the same nonce that was orphaned when the other one consumed it.
  4. Its target is a superseded contract that holds no role. The address in the payload, 0x7286200Ba4C6Ed5041df55965c484a106F4716FD, is the original April 2026 peg module, superseded twice since. Its own kUSD() getter still returns a placeholder address, so it was never wired to the live token, and hasRole returns false for it on both MINTER_ROLE and DEFAULT_ADMIN_ROLE today.

The honest summary is that an internal command line tool mis-encoded a function selector in April 2026, three transactions were executed with it and all three reverted, the bug was fixed, and the corrected call went through at nonce 3. The queue entry is the residue of that. It cannot be cancelled without spending a nonce on a replacement transaction, which is why it is still visible.

3. The two live entries, and what they do

Nonce 19: revoke the v2 vault's minting role

MINTER_ROLE on kUSD currently has two holders: the live mint module, which needs it, and 0x8ccc56B5624e2FDB592F6609d81F4c3798e3292B, the v2 vault, which was granted it in May 2026 and has never used it. This transaction removes the second one.

We want to be precise about what this is worth, because it would be easy to oversell. The vault cannot mint kUSD and never could. Its deployed runtime contains no kUSD address, no mint selector, and no delegatecall opcode at all, so there is no route by which the grant could be used. Revoking it closes no live path. What it buys is that the answer to "who can mint kUSD" stops needing a paragraph of explanation and becomes one contract. That is a clarity improvement, not a security fix, and it is queued rather than urgent for exactly that reason.

Nonce 20: widen the oracle staleness window from 26 hours to 48

The mint module fails closed if its price feed is stale. The Chainlink USDC/USD feed on Base that it reads is a pure 24 hour heartbeat: across 15 consecutive rounds the gaps ran from 24.003 to 24.008 hours with no deviation-triggered updates in between. The window today is 93,600 seconds, 26 hours, which leaves under two hours of margin over the worst observed heartbeat. If the feed is ever late by more than that, minting and redemption both stop.

This transaction sets it to 172,800 seconds, 48 hours, which is the maximum the contract accepts. This is a deliberate loosening and we are recording it as one. In a genuine USDC depeg the staleness gate would react up to 48 hours late instead of 26. We judged the availability risk of a two hour margin to be the larger one, given the depeg band is a separate check that is not being touched. It is reversible by setting the value back.

4. How fast the Safe actually responds

Our anchor terms page has a section headed "who can change things, and how fast" and until today it did not answer the second half. This is the answer, measured across all 19 transactions the Safe has executed between 2026-04-16 and 2026-07-28. It is a description of past behaviour. It is not a service level, and we are not offering it as one.

IntervalMedianFastestSlowest
Proposal to second signature12m 11s43s25d 14h
Second signature to execution8m 31s1s13h 24m
  • 14 of 19 reached two signatures within 24 hours. 15 within 48 hours, 17 within 72 hours.
  • The tail is long and we are not hiding it. Two transactions proposed on 2026-05-17 waited 25 days and 14 hours for a second signature. A third waited 2 days 19 hours, and a fourth 1 day 5 hours. If you need a change made on a deadline, the median is not the number to plan against.
  • Both non-founder signers demonstrably sign. Across those 19 transactions one co-signer provided 11 second signatures and the other 8. All 19 reached the threshold; none was abandoned.
  • Three of the 19 executed with a failed inner call. Nonces 0, 1 and 2, all on 2026-04-16, all from the same command line tool and the same encoding bug described in section 2. The Safe transaction succeeded and the call inside it reverted. No transaction since April has failed.
  • The current queue is already slower than the median. Nonces 19 and 20 were proposed on 2026-08-01 at 23:03 UTC and were still at one signature at the snapshot above.

5. What a decoded queue does not fix

Nothing on this page reduces what two signatures can do. The Safe has no timelock, no guard and no modules, so there is no enforced delay between a second signature and an executed change, and no restriction on what that change can be. Two signatures can still mint kUSD against nothing and redeem the reserve. This page makes the queue legible. It does not make the custody position safer, and it should not be read as if it did.

There are two independent routes to that outcome, and both are open today. The first is the one our terms page already documents: the Safe holds DEFAULT_ADMIN_ROLE on kUSD and can grant the minting role to any address. The second does not touch kUSD's admin role at all: the live mint module already holds MINTER_ROLE, and the Safe holds MANAGER_ROLE on that module, which is what gates listing a new collateral asset and pointing it at a price feed. We are stating the second route explicitly because a remediation that closed only the first one would look like a fix and would not be one.

A design that puts both routes behind a published delay, while keeping the emergency pause immediate, has been written and tested against a fork of Base. It is not deployed and not proposed, and it needs a second signature from a co-signer to proceed, the same dependency the two transactions above are waiting on. We will say it is done when it is done and not before. The full position, including the fee and exit mechanics, is on the anchor terms page.

6. Reproduce all of it

These need no API key and no cooperation from us. Any public Base RPC works.

export RPC=https://base.gateway.tenderly.co
export SAFE=0x52d3E450bA6c299B1B07298F1E87DD74732D4877
export KUSD=0x5C2EfdF0D8D286959b42308966bc2B97f5680AA3

# The pending queue, straight from the Safe transaction service.
curl -s "https://api.safe.global/tx-service/base/api/v1/safes/$SAFE/multisig-transactions/?executed=false"

# The live nonce. Anything queued below this can never execute.
cast call $SAFE "nonce()(uint256)" --rpc-url $RPC

# No guard, no modules.
cast storage $SAFE $(cast keccak "guard_manager.guard.address") --rpc-url $RPC
cast call $SAFE "getModulesPaginated(address,uint256)(address[],address)" \
  0x0000000000000000000000000000000000000001 10 --rpc-url $RPC

# Section 2, reason 2. The selector in the payload versus the real one.
cast sig "grantRole(bytes32,address)"        # 0x2f2ff15d, not 0x2f2ff15a

# Section 2, reason 3. The receipt that already reverted.
cast receipt 0x46eb84049ab234071d0a17220accb4e1f008a37ad2bb28b4b89f678d885eb6b8 \
  --rpc-url $RPC

# Section 2, reason 4. The target holds nothing.
cast call $KUSD "hasRole(bytes32,address)(bool)" \
  $(cast keccak "MINTER_ROLE") 0x7286200Ba4C6Ed5041df55965c484a106F4716FD --rpc-url $RPC

# Section 4. Every executed transaction, with confirmation timestamps.
curl -s "https://api.safe.global/tx-service/base/api/v1/safes/$SAFE/multisig-transactions/?executed=true&limit=200"

# The minter set cannot be enumerated in one call: kUSD is plain AccessControl
# and getRoleMemberCount reverts. Replay the events instead.
cast logs --from-block 44448090 --address $KUSD \
  "RoleGranted(bytes32,address,address)" --rpc-url $RPC

The event replay needs chunked block ranges on every public provider we have tried. If a single call returns nothing, split the range rather than concluding there are no events.