← Bond stages

What the 33 probes actually demonstrate

All 33 listed transactions were fetched from public devnet RPC at finalized commitment. Each failed, its recorded guard matched the execution logs, and its pre/post token balances were unchanged. Failed transactions still paid fees. Verification: 2026-10-10T16:50:43.431535+00:00.

The harness sends real transactions with skipPreflight: true. It calls a test passed when the transaction failed and its reason contains the expected guard token. Naming a PDA while clearing its signer flag tests missing authorization; it does not forge a signature. Some probes use cooperating authorized holders, the registrar or the bank.

The custom checks are meaningful integration evidence for this bond profile. Standard token and loader checks are authority regression tests. The frozen cash account is controlled recovery testing. The separate localnet deposit probe detects a reconciliation discrepancy. These results cover the supplied transactions and scenarios; they do not establish an exhaustive security proof, million-holder throughput, or atomic securities-plus-cash trade settlement.

Raw finalized RPC responses · All measured hostile-run data · Full change log and assessment · Solana transaction semantics · Solana fees

Probe and classMechanism and evidential limitObserved rejection / inspect
register-self
Program authorization
Calls register_holder with the attacker signing as registrar.

Checks this Bond's registrar binding; it does not test a compromised registrar.

ConstraintHasOne: A has one constraint was violated.
Finalized transaction ↗
Instruction constructor ↗
mint-bonds
Native authority
Calls Token-2022 mint_to with the attacker's key as mint authority.

Ordinary token authority rejection, not a bond-math attack.

owner does not match
Finalized transaction ↗
Instruction constructor ↗
mint-as-program
Native signature
Names the Bond PDA as mint authority, but removes its signer flag.

Tests missing PDA authorization; no PDA signature was forged.

MissingRequiredSignature
Finalized transaction ↗
Instruction constructor ↗
take-bonds
Native authority
Calls transfer_checked on the victim account with the attacker's key.

Stops at token ownership, before the bond hook's business rules.

owner does not match
Finalized transaction ↗
Instruction constructor ↗
take-as-delegate
Native signature
Names the permanent-delegate PDA but supplies no PDA signature.

Tests signature enforcement, not a malicious authorized delegate.

MissingRequiredSignature
Finalized transaction ↗
Instruction constructor ↗
burn-bonds
Token configuration
Calls standard burn_checked on the permissioned-burn mint.

Shows the standard burn instruction is disabled; this attempt is not signed by the rightful holder.

Invalid instruction
Finalized transaction ↗
Instruction constructor ↗
burn-permissioned
Token configuration
Calls raw permissioned BurnChecked (46,2), naming attacker as both authorities.

Rejection at the configured burn-authority check; valid owner/delegate authorization is also absent.

InvalidAccountData
Finalized transaction ↗
Instruction constructor ↗
burn-as-program
Native signature
Names the PDA in permissioned burn, clearing its signer flag.

No PDA signature is supplied or broken.

MissingRequiredSignature
Finalized transaction ↗
Instruction constructor ↗
freeze-holder
Token configuration
Calls freeze_account on a mint created with no freeze authority.

Verifies mint configuration; it does not exercise freezing of the separate cash token.

This token mint cannot freeze accounts
Finalized transaction ↗
Instruction constructor ↗
send-unregistered
Program invariant
The victim signs a hook-aware transfer to the unregistered attacker's ATA.

A meaningful registry check with valid transfer authority. The holder cooperates in the test.

AccountOwnedByWrongProgram: The given account is owned by a different program than expected.
Finalized transaction ↗
Instruction constructor ↗
second-account
Program invariant
The victim signs a transfer to a valid second token account owned by the victim.

Verifies the one-ATA position model; rejecting non-ATAs is an integration policy, not universal bond law.

NotAssociatedTokenAccount: Bonds may be held only in the owner's associated token account.
Finalized transaction ↗
Instruction constructor ↗
skip-hook
Token integration
A holder signs the legacy unchecked Transfer, which omits the mint.

Token-2022 requires the mint for this account profile; it is not a successful hook bypass.

custom program error: 0x1f
Finalized transaction ↗
Instruction constructor ↗
forge-position
Program invariant
Calls the hook Execute entry point directly with amount 5 and real holder records.

The transferring flag rejects this call. Does not cover every CPI/reentrancy composition.

NotTransferring: The hook was called outside a token transfer.
Finalized transaction ↗
Instruction constructor ↗
take-program
Native authority
Calls the upgradeable loader's SetAuthority with the attacker as current authority.

Does not test the real upgrade authority being compromised or upgrading maliciously.

Incorrect authority provided
Finalized transaction ↗
Instruction constructor ↗
fee-cash-token
Configuration guard
The registrar creates a real 1% fee mint, then attempts create_bond using it.

An authorized bad-configuration test, not an outsider attack. Other cash extensions require their own tests.

UnsupportedCashToken: Cash token has an extension that changes or conditions delivery (transfer fee, transfer hook, non-transferable) or one this program cannot read.
Finalized transaction ↗
Instruction constructor ↗
place-late
Program invariant
The registrar calls place for 100 after the first record boundary.

A business-time restriction tested with real issuance authority.

PlacementClosed: Placement is allowed only before the first record moment.
Finalized transaction ↗
Instruction constructor ↗
sell-others-bonds
Program authorization
Attacker signs sell_to_offer while the retirement accounts identify the victim.

Tests seller/account binding in the custom buyback path.

ConstraintRaw: A raw constraint was violated.
Finalized transaction ↗
Instruction constructor ↗
over-maximum
Program invariant
A holder signs one more sale after the first-come offer cap is reached.

A meaningful funded-offer quantity-boundary test.

ExceedsOffer: Quantity exceeds what the offer still accepts.
Finalized transaction ↗
Instruction constructor ↗
confirm-short
Program invariant
Bank funds budget minus one base unit; attacker calls confirm_funding.

Checks full numerical backing before activation; does not prove the cash token remains available forever.

InsufficientFunding: Vault balance does not cover the event's budget.
Finalized transaction ↗
Instruction constructor ↗
pay-unfunded
Program invariant
Calls pay_coupon before successful funding confirmation.

Checks the funded gate, separately from the actual cash balance.

NotFunded: The event is not funded.
Finalized transaction ↗
Instruction constructor ↗
drain-vault
Native authority
Calls cash-token transfer_checked from the vault with attacker as owner.

Standard cash-account authority rejection.

owner does not match
Finalized transaction ↗
Instruction constructor ↗
drain-as-program
Native signature
Names the vault's PDA owner but clears its signer flag.

Standard missing-signature check; no PDA signature forgery.

MissingRequiredSignature
Finalized transaction ↗
Instruction constructor ↗
redirect-coupon
Program invariant
Passes the victim's right with the attacker's cash ATA as destination.

Tests beneficiary binding in a deliberately permissionless payout.

ConstraintTokenOwner: A token owner constraint was violated.
Finalized transaction ↗
Instruction constructor ↗
claim-as-owner
Program invariant
Passes the victim's HolderRecord with attacker as owner and recipient.

Observed rejection is ConstraintSeeds; the harness only required the broad substring 'Constraint'.

ConstraintSeeds: A seeds constraint was violated.
Finalized transaction ↗
Instruction constructor ↗
pay-twice
Program invariant
Repeats the same coupon/account payout after the first committed payment.

Tests the consumed bit for this event/account, not all concurrency or migration cases.

AlreadyPaid: Already paid.
Finalized transaction ↗
Instruction constructor ↗
late-buyer
Entitlement rule
Requests coupon 0 for a holder with zero at record time and a positive later balance.

No entitlement exists. Acting as a permissionless payer is otherwise allowed.

NothingToPay: Nothing to pay.
Finalized transaction ↗
Instruction constructor ↗
sell-tendered
Program invariant
A tendering holder signs a transfer of its entire position, including locked quantity.

Checks lock enforcement with genuine transfer authority.

BondsLocked: Bonds are locked in a tender.
Finalized transaction ↗
Instruction constructor ↗
other-vault
Program invariant
Passes coupon 0's vault while paying coupon 1.

Tests event-vault isolation; a failed transaction proves this supplied substitution was rejected.

ConstraintHasOne: A has one constraint was violated.
Finalized transaction ↗
Instruction constructor ↗
frozen-cash
Recovery test
The bank freezes a holder's cash ATA; a normal payer attempts the coupon, then bank thaws it.

Controlled failure injection by the real cash freeze authority, not an outsider exploit.

Account is frozen
Finalized transaction ↗
Instruction constructor ↗
trade-at-maturity
Program invariant
A holder signs a hook-aware transfer after the final record boundary.

Verifies this profile's trading cutoff; other contractual cutoffs are separate profiles.

TransfersClosedAtMaturity: Transfers are closed from the final record moment (redemption).
Finalized transaction ↗
Instruction constructor ↗
redirect-principal
Program invariant
Redeems the victim's position but supplies the attacker's cash ATA.

Tests principal beneficiary binding; rejected before any committed retirement.

ConstraintTokenOwner: A token owner constraint was violated.
Finalized transaction ↗
Instruction constructor ↗
coupon-from-principal
Program invariant
Calls pay_coupon with the redemption Event and its real vault.

Tests event-kind separation with otherwise corresponding accounts.

WrongEventKind: Instruction does not apply to this event type.
Finalized transaction ↗
Instruction constructor ↗
redeem-twice
Program invariant
Repeats redemption after the victim's live position is retired.

NothingToPay establishes this position has no remaining redeemable quantity.

NothingToPay: Nothing to pay.
Finalized transaction ↗
Instruction constructor ↗

Successful hostile-wallet operations: permitted servicing

The measurement enumerates successful operator-recorded transactions whose fee payer is the hostile wallet. These 11 recorded operations include account setup and permissionless event opening, funding confirmation and payments. Four have positive cash recipients, all legitimate holders. The measured positive cash/bond movements to the hostile wallet are zero. This is not a claim about unrecorded wallet history.

OperationCash recipientsPositive movement to hostile wallet (base units)Inspect
attacker opens its own bond and cash accounts, and a second bond account for the victimNo positive cash recipient0 cash / 0 bondsTransaction ↗
open_event coupon 2 [outside keeper]No positive cash recipient0 cash / 0 bondsTransaction ↗
confirm_funding coupon 2 [outside keeper]No positive cash recipient0 cash / 0 bondsTransaction ↗
pay_coupon 2 BH#1..BH#6 [outside keeper]BH#1, BH#2, BH#5, BH#60 cash / 0 bondsTransaction ↗
open_event coupon 3 [outside keeper]No positive cash recipient0 cash / 0 bondsTransaction ↗
confirm_funding coupon 3 [outside keeper]No positive cash recipient0 cash / 0 bondsTransaction ↗
pay_coupon 3 BH#1..BH#6 [outside keeper]BH#1, BH#2, BH#3, BH#4, BH#5, BH#60 cash / 0 bondsTransaction ↗
open_event redemption [outside keeper]No positive cash recipient0 cash / 0 bondsTransaction ↗
confirm_funding redemption [outside keeper]No positive cash recipient0 cash / 0 bondsTransaction ↗
redeem_holder BH#1..BH#4 [outside keeper]BH#1, BH#2, BH#3, BH#40 cash / 0 bondsTransaction ↗
redeem_holder BH#5..BH#6 [outside keeper]BH#5, BH#60 cash / 0 bondsTransaction ↗

Source pages are current local build snapshots with hashes and line links. They are not attestations of the historical deployed binary. Changes were prepared locally; no deployment was performed.