Breaker control
Watches the stored ratio against circuit_bps. Below the floor it pauses issuance; burns and redemptions — which only raise the ratio — remain open so the vault can heal.
The security model is built around one idea: the on-chain program is the only thing that can move collateral or mint supply, and it will refuse to do either the moment the ratio slips out of tolerance. Everything else — attestors, the indexer, the wizard, the SDK — is a reporter, not a custodian. This page states the trust boundaries, the breaker thresholds, and the surface an auditor should read first.
pegd_issuance program owns every collateral vault and holds mint authority for every registered stablecoin. No human key can mint or withdraw directly.The breaker is checked before the mode floor on every mint. The collateral floor circuit_bps is 12000 basis points — 120 percent. If a post-mint ratio would fall below it, issuance halts entirely; the mode's healthy minimum (min_ratio_bps, 15000 for the crypto demo) is the target a mint must clear above that hard floor.
| Threshold | Value | Meaning |
|---|---|---|
| min_ratio_bps | 15000 | Healthy mint floor for the crypto mode |
| circuit_bps | 12000 | Hard floor — issuance pauses below it |
| liquidation_bps | 11000 | Below this, liquidation assistance opens |
// Enforced on every mint. Breaker is checked BEFORE the mode floor,
// so a vault under the hard floor halts even if the mode would allow it.
require!(post_ratio_bps >= cfg.circuit_bps, PegdError::CircuitBreaker); // 12000
require!(post_ratio_bps >= cfg.min_ratio_bps, PegdError::BelowMinRatio); // 15000
// pause_issuance / resume_issuance let the admin trip or clear the breaker
// manually. resume requires a fresh attestation within the staleness window.The risk module reads the attested ratio and drives the breaker state. It holds the tunable thresholds in a RiskParams account, updated only through set_risk_params under the config admin lock. When the ratio drops below liquidation_bps, the module opens a liquidation-assistance path.
Watches the stored ratio against circuit_bps. Below the floor it pauses issuance; burns and redemptions — which only raise the ratio — remain open so the vault can heal.
Below liquidation_bps, third parties may burn supply against collateral at a configured bonus to pull the ratio back over the floor. The program never seizes an issuer position on its own.
Compliance is opt-in and off the main path. An issuer may attach the optional Token-2022 transfer hook at registration to enforce a per-mint allowlist; the extension order is fixed at allocation and cannot be added later. The hook is a validation program — it can approve or reject a transfer, but it never has custody of tokens and never touches the collateral vault. The public demo registers without it.
// The hook is a pure validator: it reads the allowlist PDA and returns
// Ok or an error. It cannot move, mint, or freeze tokens.
pub fn execute(ctx: Context<TransferHookExecute>, _amount: u64) -> Result<()> {
let allow = &ctx.accounts.allowlist;
require!(allow.contains(ctx.accounts.destination.key()), HookError::NotAllowed);
Ok(())
}| Threat | Mitigation |
|---|---|
| Under-collateral mint | Ratio recomputed on-chain in mint_stable |
| Breaker bypass | circuit_bps enforced before the mode floor |
| Attestor collusion | Median M-of-N over a trusted set |
| Stale price feed | Staleness and confidence bounds reject the quote |
| Compromised issuer key | Multisig advised; floors hold regardless |
The surface an auditor must trust is small and immutable. Everything outside the Anchor crate is a reporter that the program does not believe. Reading these four things gives full coverage of what can move value.
pegd_issuance crate — the only code with custody and mint authority. Small enough to read line by line.mint_stable and redeem_collateral — where every value decision is made.commit_attestation using the ed25519 precompile via the Instructions sysvar.Anchor deployment to any cluster — mainnet or devnet — is blocked until an operator explicitly supplies three things: the deploy keypair path, the cluster name, and a confirmed SOL balance. There is no automatic airdrop, keygen, or fallback deploy path. Nothing reaches a validator without a deliberate human decision.