peard
What can be an underlying

The three gates

Vaultable, accrual, exit. An asset must clear all three before it can back a market.


Whether an asset can back a permissionless market is a narrower question than whether the asset is any good. Three gates decide it, and each one exists because a specific thing goes wrong when it is skipped.

Vaultable

Can a freshly created PDA-owned ATA actually receive and send it?

Accrual

Does its yield arrive in a way a stored-reserve curve can hold?

Exit

Can a holder get out, at size, without the issuer's permission?

Gate 1: vaultable

vaultVerdict in relayer/src/verify-mints.ts has exactly two clauses, and that is not an accident of drafting.

if (das === "frozen")  -> "a fresh vault ATA cannot receive it"
if (hook)              -> "runs on every transfer_checked; we do not pass its accounts"

Every permissioned RWA checked so far fails one of exactly these two, and never a third. That is why the function has two clauses rather than a growing list.

Both are point-in-time verdicts. The transfer hook slot is present but empty on most of the vaultable set, and its authority can fill it later. The registry says to re-run npm run verify-mints before every launch batch.

What the live mint state says today

Better than expected on two counts, both re-read off the mainnet mint accounts on 2026-08-25. defaultAccountState is present on 31 of the 44 hard entries and is initialized rather than frozen on every one of them, so no issuer allowlist gates a market PDA's vault. And the transferHook slot is present on 32 of the 44 with a null programId on every one, so transfer_checked needs no extra accounts today.

Both are powers held in reserve rather than exercised, and both are one issuer decision away from changing.

Gate 2: accrual

yieldVerdict in relayer/src/staked.ts is pure: no RPC, no fetch, no clock. The caller does the I/O and this decides, so the decision is testable without a network.

The entry in seed.json is a claim. This is the cross-examination, and two of its three checks can be settled against the chain and a live price. A registry that took the issuer's word for how yield arrives would eventually list a rebasing token and quietly hand its yield to whoever swaps first.

The one outright refusal

if (staked.accrual === "rebasing") {
  return { ok: false, why:
    "rebasing: the vault balance grows behind the pool's accounting, so the yield is " +
    "paid to whoever swaps first rather than to holders" };
}

A balance that grows inside the vault is inventory the pool does not know it has. peard_amm stores reserves rather than measuring them, precisely so a stranger cannot reprice the curve by sending tokens in, and the same property means a rebase is invisible to the curve and therefore free money for the first arbitrageur.

The chain outranks the declaration

If the mint carries interestBearingConfig or scaledUiAmountConfig, accrual is uiAmount whatever the entry claims, because those extensions make the displayed balance diverge from the raw amount. The verdict notes the drift rather than refusing, and adds the operational consequence: the UI must show the scaled balance and never the raw reserve, or holders read a shortfall that is not there.

The reverse is a refusal. Declaring uiAmount accrual on a mint carrying neither extension means nothing scales the balance, so the entry is simply wrong.

A soft signal worth keeping

A dollar that has been earning for a while and still marks at a dollar is either brand new or not accruing the way the entry claims. valueAccruing below $1.0050 gets a note, not a refusal.

Eight entries declare a yield, and seven of them are still hard

EntryAssetAccrualRedemption lockLiquidityGrade
SYRUP-USDCsyrupUSDCvalueAccruing30 days$11.7mhard
EUSXeUSXvalueAccruing7 days$8.2mhard
ONYCONYCvalueAccruingnone$5.5mhard
USDYUSDYvalueAccruingnone$2.9mhard
CETESCETESuiAmountnone$105khard
TESOUROTESOUROuiAmountnone$83kindex since 2026-08-25
KTBKTBuiAmountnone$33khard
GILTSGILTSuiAmountnone$13khard

TESOURO still declares a yield and is no longer a vault candidate: it was demoted to index grade on 2026-08-25 and its assetMint came off with the grade. The declaration is kept because the entry is kept.

All four Etherfuse sovereign bonds accrue by uiAmount, which is why the UI rule above matters for them specifically. Three of them are hard today.

Gate 3: exit

A cooldown is survivable only because holders of a market's quote asset exit by selling it, not by redeeming it. That is a claim about the secondary market, so it gets tested rather than assumed.

if (staked.lockDays > 0) {
  if (depth !== "deep") {
    return { ok: false, why:
      `${staked.lockDays}-day redemption cooldown and the secondary market is ${depth}: ` +
      `a holder could neither redeem nor sell` };
  }
}

So lockDays is deliberately not disqualifying on its own. It only bites when the secondary market is thin, which is exactly when a locked entry has to clear the depth probe rather than the probe being optional.

SYRUP-USDC carries a 30-day cooldown and passes because $11.7m of pool liquidity fills the probe. A 30-day cooldown on a $13k book would not.

primaryKyc is disclosed, not refused

Seven of the eight yield entries declare primaryKyc: true, meaning allowlisted minting and redemption; EUSX is the one that does not. That is a note on the verdict, because only the secondary market is open to holders anyway and the secondary market is the exit being tested.

What clearing all three does not mean

It does not mean the asset is safe. It means the mechanics work. Everything in ISSUER_POWERS is a power the issuer holds over tokens a vault already holds, and none of them stops a market from working:

ExtensionWhat the issuer can do
permanentDelegatemove your tokens
pausableConfigfreeze all transfers
defaultAccountStategate who may hold it at all
mintCloseAuthorityclose the mint
transferFeeConfigtake a cut of transfers
transferHookrun code on every transfer
scaledUiAmountConfigrestate every balance

All of them belong in front of the user. Pairable carries the risk badge the program writes, and seed.json mirrors issuerPowers per entry so the app can show them without a mainnet round trip.

That mirror is currently incomplete, and it understates the issuer's powers, which is the wrong direction to be wrong in. Read off the mainnet mints on 2026-08-25, the chain carries scaledUiAmountConfig on 31 hard entries where issuerPowers records 13, transferHook on 32 where it records 19, and defaultAccountState on 31 where it records 18. Re-derive it with npm run verify-mints before trusting the badge.

A freeze authority is not an extension, and this table does not see it. ISSUER_POWERS reads the Token-2022 extension list, but the freeze authority lives on the base mint and applies to classic SPL mints too. On 2026-08-25, 37 of the 44 hard entries carry a live freeze authority and issuerPowers records it on two of them, USDY and SYRUP-USDC. The seven with none are SOL, USDE, CETES, GILTS, KTB, PST and EUSX. A freeze authority does not stop a market from working, so it belongs in the disclosure column rather than in vaultVerdict, but it belongs somewhere.