D00R

Security and trust

The point of D00R is that nobody has to trust the person on the other side, or us. This page lists who can move a bond and when, and what the program refuses.

Who can move a bond

ActionSignerWhenEffect on the bond
replyRecipientAny time while the knock is open100% back to the sender
mark_spamRecipientBefore expires_at95% to the recipient, 5% to the fee vault
expireAnyoneAt or after expires_at100% back to the sender

There is no other instruction that touches a bond vault. There is no admin withdrawal, no pause of the vaults and no instruction after init_config that the deployer can call.

What the program refuses

  • A sender pulling a bond back before the recipient decides. There is no such instruction.
  • A recipient keeping a bond after the deadline. mark_spam fails with WindowPassed.
  • Anyone else marking spam or replying. Both fail with NotRecipient.
  • Bait and switch. send_knock repeats the bond and window; if the inbox changed them, it fails with TermsChanged.
  • Stacking. One open knock per sender per inbox, by the knock's address.
  • Wiping a record. No instruction closes an inbox, so received, replied, kept, expired and kept_amount only go up.
  • Knocking yourself from the same wallet (OwnInbox).

What is public and what is not

Public: every inbox's terms and counters, every open knock's sender, bond and deadline, and every event.

Private: the message text. It is encrypted with AES-256-GCM under a key both people derive with X25519 (the inbox's encryption_key and the sender's reply_key) and HKDF-SHA256: 0x01 || nonce(12) || ciphertext. Replies use the same pair of keys. Each key comes from a wallet signature and never leaves the browser. The program never reads either.

What can be gamed, plainly

An owner can make their reply rate look better by knocking themselves from other wallets and replying. Each padded knock costs about 10,000 lamports in fees; the bond and rent come back. What cannot be faked is kept and kept_amount: they rise only through a real spam mark that moved a real bond, and never fall. The app shows those next to the spam rate, never the rate alone.

Solvency

After every step of a fuzz run (8 seeds, 500 random steps each) the tests check: each bond vault equals the treasury books equals the sum of open bonds in that mint; the fee vault equals fees collected minus fees spent; the counters equal the events; and at the end every honest knock cost its sender exactly the network fee.

Upgrade authority

Until an external audit, the upgrade authority should be a multisig. The launch constants in Config are written once and cannot be changed by any instruction.