Guides
Reserves
Prove a treasury’s shielded reserves as one batch, check it, and publish it to a Solana feed that a token can only mint within.
On this page
#1 · Prove a batch
One proof covers up to five notes. A batch covers every usable note: several version 2 proofs in one scope, against one anchor, in a .pofb file. A request of kind reserves makes a batch by default; --batch-size sets how many notes go in each proof.
pof-prove prove --request <encoded> --snapshot target/snapshots/mainnet-<height>.vsnp \
--seed-file ~/.vouch/seed.txt --batch-size 5 --out reserves.pofb#2 · Check it
The verifier checks every member, refuses a batch in which any tag appears twice (a note counted twice), and states the sum. Natively the members’ Halo2 proofs are checked together with one batched multi-scalar multiplication, falling back to one by one to name a bad member. Drop it on /reserves, or:
pof-verify check reserves.pofb --audience reserves:wzec-demo --anchors anchors.jsonValid batch · 4018.12500000 at least, across 3 proofs · anchor 3491040
proof 1 Valid
proof 2 Valid
proof 3 ValidInvalid batch · Proof 2 counts a note another proof in the batch already counted.
proof 1 Valid
proof 2 Valid#3 · Publish the feed
publish accepts the message only if enough distinct allowlisted attestors signed exactly it, the slot is recent, the proofs have not expired, the audience is the feed’s, and the anchor is not older than the one the feed already holds.
#4 · Secure Mint
The feed’s token (its mint authority is the feed PDA) mints only when all of these hold:
- the feed has been published at least once;
- the last publish is within the feed’s heartbeat (the demo feed: 9,000 slots, about an hour);
- the proofs behind it have not expired;
- supply plus the amount stays at or under the proven total;
- the caller is the feed’s issuer.
Try both breakers on /reserves: mint past the reserves, or wait out the heartbeat. Each is refused by the program, not by the site.
#Reading the feed
Any program can read the feed account, a PDA at [b"feed", audience] under pof-reserve (5Q26Tjcd4equ5te5hF15eG4xK6uvkbZtKkEeqdf535h9). The audience is blake2b-256("pof-audience:" ‖ id).
pub struct Feed {
pub audience: [u8; 32],
pub issuer: Pubkey, // may call secure_mint
pub mint: Pubkey, // PDA [b"mint", feed]
pub heartbeat_slots: u64,
pub scope: [u8; 32],
pub total_zatoshi: u64, // the proven reserves
pub members: u16, // proofs in the batch
pub anchor_height: u32, // spent set "as of"
pub nc_height: u32, // unmoved since, when earlier
pub expires_at: i64,
pub updated_slot: u64,
pub publishes: u32,
pub bump: u8,
}Treat the feed as stale exactly as the program does: no publish yet, more than heartbeat_slots since updated_slot, or past expires_at.
#What reserves prove, and what they do not
A feed proves the issuer controlled at least the total at the anchor, with no note counted twice within the batch. It does not prove liabilities (that half of proof of solvency is on the roadmap), and it does not lock the coins: a later publish with a lower total lowers what can be minted, but cannot claw back what was minted already.