Skip to content
frank_

Security

In short: the basics are solid, but a few important protections need to be added before Frank ever handles real money.

Frank moves balances on a chain, so its safety has to come from code the agent can't edit, not from the model behaving well. This page summarises an independent review of the latest contracts and the backend. It describes the risks and the fixes, not how to exploit them.

What holds up

These were checked and work as intended:

  • Reentrancy is blocked on every state-changing path, and on views.
  • Transfers are checked exactly, so fee-on-transfer tokens are rejected on the way in.
  • Bonding and redeeming only ever pull from the caller. Nobody can spend someone else's allowance, and the frontend approves exact amounts, not unlimited.
  • Vault admission pins the vault's code and requires an empty vault, blocking share-inflation tricks.
  • Gaming the price by donating assets loses the donor money.

What's improved since the review

Several protections have been added in the app since the first review:

  • A human approves every new market, and the approval is tied to the exact terms, so nothing different can be signed.
  • Frank no longer picks prices. A pricing service with fixed rules sets them, and refuses any rate that wouldn't be backed by the treasury or that strays too far from market prices.
  • An issuance ceiling. A round of new markets can only create a small share of the existing FRANK supply, split by how risky each asset is.
  • Markets are watched. They're repriced on drift, renewed daily and closed automatically when price data goes bad.
  • Upgrade proposals are pinned to the exact code they install, and the agent can't cancel or replace the human's proposals.
  • The signer caps gas and fees and limits how often it signs.

These live in the app, not the contracts, so they don't yet hold if the app itself is compromised. That's why the list below still matters.

What needs fixing

Grouped by what they threaten, most serious first.

Draining the treasury

RiskWhoWhy it's possible
A single market priced far too generously can mint FRANK worth far more than the asset deposited, then be redeemed for real backing.Anyone who can get a market signed — the agent key, or anyone who compromises the app processThe signer checks the function, not its arguments, and the on-chain bounds on the devnet are effectively unlimited. The app's pricing rules and human approval help, but don't bind a compromised app.
A malicious contract upgrade.A compromised human key, or the agent after retirementThe other party can't cancel the first party's proposal, and after 24 hours anyone can execute it.

Diluting FRANK to worthlessness

RiskWhoWhy it's possible
A token whose owner can mint it for free is bonded in bulk, then redeemed for the real basket.A meme-token creator pitching their own tokenNo cap on issuance relative to current supply.
Issuing far more FRANK than the current supply in one market.The agent or appMarket caps are absolute numbers, not a share of supply.

Freezing everyone's exit

RiskWhoWhy it's possible
One basket token that can be paused, taxed, blacklisted or seized freezes all redemptions, for every asset.The owner of any admitted tokenRedemption pays every asset atomically, and there's no way to quarantine or remove a bad one.
Filling all 16 basket slots with junk permanently blocks any new asset.Repeated low-value pitchesMarkets register their asset permanently, and closing doesn't free the slot.

Trapping holders

RiskWhoWhy it's possible
Setting the redemption fee to its maximum instantly.The governorFee changes have no delay.

Fixes

In priority order:

  1. Issuance limits in the contract (open; an app-side ceiling exists) — cap FRANK minted per rolling day and per market as a share of current supply, not an absolute number. This limits the drain and dilution risks even if the key or app is compromised.
  2. Asset quarantine (open) — a timelocked governor action to drop a broken asset from redemption, plus a way for a holder to skip a named asset, so one bad token can't freeze the basket. Add a way to remove zero-backing assets.
  3. Stronger upgrade governance (partly done) — let either party veto an upgrade, add an independent guardian, and lengthen the delay. Disable upgrades once the design is stable.
  4. Move the caps into the signer (open) — so a compromised app can't sign a drain.
  5. Timelock fee increases (open).
  6. Stricter asset admission in the app (partly done: risky powers are flagged and prices are cross-checked, but not yet hard rejections) — reject tokens with owner-mint, pause, blacklist, tax or proxy powers; require real liquidity; use more than one price source.
  7. Harden Jev (open) — fail closed for code screening, and screen the data code loads, not just the code text. See Jev.