initialize_protocol
One-time setup creating the ProtocolState singleton with initial configuration. Location:lib.rs:18-35
Parameters
Protocol fee rate in basis points (1/100th of 1%). Must be between 0-10000.Common values:
250 (2.5%), 100 (1%), 500 (5%)Accounts
Protocol admin wallet. Becomes the authority stored in ProtocolState. Pays for account creation.
The ProtocolState singleton PDA being initialized. Seeds:
["protocol_state"]Treasury wallet address for fee collection. Not validated on-chain; admin must ensure it has a BIO token account.
Solana System Program for account creation.
Behavior
- Creates the ProtocolState PDA with space
8 + ProtocolState::INIT_SPACE - Sets
authorityto the signer’s pubkey - Initializes both counters (
nka_counter,bounty_counter) to 0 - Stores the
fee_basis_pointsparameter - Stores the
treasurypubkey - Saves the PDA bump seed
- Emits
ProtocolInitializedevent
Code Reference
submit_null_result
Submits a new Null Knowledge Asset (NKA) to the protocol. Any wallet can call this. Location:lib.rs:37-70
Parameters
UTF-8 encoded hypothesis tested. Maximum 128 bytes. Pad with zeros if shorter.
UTF-8 encoded methodology summary. Maximum 128 bytes. Pad with zeros if shorter.
UTF-8 encoded expected outcome description. Maximum 128 bytes. Pad with zeros if shorter.
UTF-8 encoded actual outcome description. Maximum 128 bytes. Pad with zeros if shorter.
Statistical p-value as fixed-point integer (multiply by 10000). Example:
4200 = 0.42Number of subjects or observations in the experiment.
SHA-256 hash of the underlying dataset. Can be all zeros if no file attached.
Accounts
The researcher submitting the NKA. Pays for NullResult PDA creation.
The protocol state singleton.
nka_counter will be incremented.The NullResult PDA being created. Seeds:
["null_result", researcher.key(), &(nka_counter + 1).to_le_bytes()]Solana System Program for account creation.
Behavior
- Increments
protocol_state.nka_counterby 1 - Assigns the new counter value as
specimen_number - Creates the NullResult PDA with all provided fields
- Sets
statusto 0 (Pending) - Records the current timestamp via
Clock::get()?.unix_timestamp - Saves the PDA bump seed
- Emits
NullResultSubmittedevent withspecimen_numberandresearcher
Code Reference
create_bounty
Creates a new bounty and escrows BIO tokens into a PDA-controlled vault. Location:lib.rs:72-121
Parameters
UTF-8 encoded description of the desired null result. Maximum 256 bytes. Pad with zeros if shorter.
BIO token reward in base units (6 decimals). Must be > 0 or instruction fails with
InvalidRewardAmount.Example: 1000000 = 1 BIOUnix timestamp deadline for submissions. Currently not enforced by program logic.
Accounts
Bounty creator wallet. Pays for PDA creation and must approve BIO token transfer.
Protocol state singleton.
bounty_counter will be incremented.The NullBounty PDA being created. Seeds:
["null_bounty", creator.key(), &(bounty_counter + 1).to_le_bytes()]The vault token account PDA for escrowed BIO tokens. Seeds:
["bounty_vault", bounty.key()]. Authority is the vault itself.Creator’s BIO token associated token account. Must have sufficient balance for
reward_amount. Field name is creator_usdc_ata in code but holds BIO tokens.BIO token mint address. Field name is
usdc_mint in code but refers to the BIO mint. Used to validate the transfer and derive decimals (6).SPL Token program for CPI transfer.
Associated Token program for vault creation.
System program for account creation.
Validation
reward_amount > 0(line 78) → else returnsNullGraphError::InvalidRewardAmount
Behavior
- Validates
reward_amount > 0 - Increments
protocol_state.bounty_counterby 1 - Assigns the new counter value as
bounty_number - Creates the NullBounty PDA with all provided fields
- Initializes the vault token account with authority set to the vault itself
- Executes
transfer_checkedCPI transferringreward_amountBIO tokens from creator’s ATA to vault - Sets bounty
statusto 0 (Open) andmatched_submissiontoPubkey::default() - Records timestamp and saves bump seeds
- Emits
BountyCreatedevent
Code Reference
submit_to_bounty
Links a researcher’s existing NKA to an open bounty, transitioning the bounty to Matched status. Location:lib.rs:123-153
Parameters
None. The instruction derives all data from the provided accounts.Accounts
The researcher submitting their NKA. Must be the owner of the
null_result account. Pays for BountySubmission PDA creation.The NullResult PDA being submitted. Must satisfy
has_one = researcher constraint.The target bounty. Must have status 0 (Open).
The BountySubmission PDA being created. Seeds:
["bounty_submission", bounty.key(), null_result.key()]System program for account creation.
Validation
bounty.status == 0(line 125) → else returnsNullGraphError::InvalidBountyStatusnull_result.researcher == researcher.key()(enforced by Anchorhas_oneconstraint)
Behavior
- Validates bounty status is 0 (Open)
- Creates the BountySubmission PDA
- Sets
submission.researcher,submission.null_result,submission.bounty - Sets
submission.statusto 0 (Pending) - Records timestamp
- Updates
bounty.statusto 1 (Matched) - Sets
bounty.matched_submissionto the new submission PDA’s address - Emits
BountySubmissionCreatedevent
Code Reference
The PDA seeds ensure each NKA can only be submitted to a given bounty once. Attempting to submit the same NKA to the same bounty twice will fail with “Account already exists”.
approve_bounty_submission
Bounty creator approves a submission, triggering automatic payout minus protocol fee. Location:lib.rs:155-229
Parameters
None. All data derived from accounts.Accounts
Bounty creator. Must match
bounty.creator.The bounty being fulfilled. Must satisfy
has_one = creator constraint. Must have status 1 (Matched).The submission being approved. Must match
bounty.matched_submission. Must have status 0 (Pending).The NullResult linked to the submission. Used to emit
specimen_number in event.The bounty’s vault token account. Seeds:
["bounty_vault", bounty.key()]Researcher’s BIO token associated token account. Receives
reward - fee. Field name is researcher_usdc_ata in code but holds BIO tokens.Treasury BIO token associated token account. Receives protocol fee. Field name is
treasury_usdc_ata in code but holds BIO tokens.Protocol state to read
fee_basis_points.BIO token mint for decimal validation in transfers. Field name is
usdc_mint in code but refers to the BIO mint.SPL Token program for CPI transfers.
Validation
bounty.status == 1(line 157) → else returnsNullGraphError::InvalidBountyStatusbounty.matched_submission == submission.key()(line 158) → else returnsNullGraphError::SubmissionMismatchsubmission.status == 0(line 164) → else returnsNullGraphError::InvalidSubmissionStatus- All arithmetic operations use
checked_mul,checked_div,checked_sub→ else returnsNullGraphError::FeeOverflow
Behavior
- Validates bounty status, submission match, and submission status
- Calculates fee:
fee = (reward_amount * fee_basis_points) / 10000 - Calculates payout:
payout = reward_amount - fee - Derives vault signer seeds:
["bounty_vault", bounty.key(), &[bounty.vault_bump]] - Transfers
payoutBIO tokens from vault to researcher via CPI with signer - If
fee > 0, transfersfeeBIO tokens from vault to treasury via CPI with signer - Updates
bounty.statusto 2 (Fulfilled) - Updates
submission.statusto 1 (Approved) - Emits
BountyFulfilledevent with breakdown
Code Reference
close_bounty
Bounty creator reclaims escrowed BIO tokens from an Open or Matched bounty, setting status to Closed. Location:lib.rs:231-273
Parameters
None. All data derived from accounts.Accounts
Bounty creator. Must match
bounty.creator.The bounty being closed. Must satisfy
has_one = creator constraint. Must have status 0 (Open) or 1 (Matched).The bounty’s vault token account. Seeds:
["bounty_vault", bounty.key()]Creator’s BIO token associated token account. Receives the refund. Field name is
creator_usdc_ata in code but holds BIO tokens.BIO token mint for decimal validation. Field name is
usdc_mint in code but refers to the BIO mint.SPL Token program for CPI transfer.
Validation
bounty.status == 0 || bounty.status == 1(line 233) → else returnsNullGraphError::InvalidBountyStatus
Behavior
- Validates bounty status is Open (0) or Matched (1)
- Reads the vault’s current token balance
- Derives vault signer seeds:
["bounty_vault", bounty.key(), &[bounty.vault_bump]] - If
vault_balance > 0, transfers entire balance back to creator via CPI with signer - Updates
bounty.statusto 3 (Closed) - Emits
BountyClosedevent with refunded amount