fix(pda-mint-authority): gate Mint behind the creator in native and pinocchio - #6
Open
SwineCoder101 wants to merge 2 commits into
Open
fix(pda-mint-authority): gate Mint behind the creator in native and pinocchio#6SwineCoder101 wants to merge 2 commits into
SwineCoder101 wants to merge 2 commits into
Conversation
… in native and pinocchio Add a test to each variant where an unrelated keypair calls Mint for a mint the creator just created. It currently succeeds: the NFT lands in the outsider's ATA and the master edition takes the mint authority, so the creator's own Mint then fails. Also assert that the creator's Mint lands the token in the creator's ATA with supply 1.
…inocchio Mint had no authorization: anyone could call it for a mint the creator had just set up and receive the one-of-one NFT in their own ATA, after which the creator's own Mint fails because the Master Edition took the mint authority. Mirror solana-foundation#692's MintConfig approach per mint: Create records the payer in a [b"mint_config", mint] PDA and Mint requires that wallet to sign, rejecting others with IncorrectAuthority. One extra account on Create and Mint; instruction data is unchanged. Update the native TS client and both test suites for the new account.
SwineCoder101
force-pushed
the
fix/pda-mint-authority-gate-native-pinocchio
branch
from
August 27, 2026 12:23
0fc8444 to
16eb75b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug: anyone can mint the NFT a creator paid for (native, pinocchio)
Mintin the native and pinocchio variants has no authorization check. Between a creator'sCreateandMint, any wallet can callMintfor that mint and receive the one-of-one NFT in its own associated token account; the Master Edition CPI then hands the mint authority to Metaplex, so the creator's ownMintfails afterwards. This is theft of an asset the creator paid rent and metadata fees to set up, exploitable by any unprivileged wallet that watches the chain. solana-foundation#692 fixed the same missing gate in the anchor variant but assumed the two siblings were safe because the edition caps supply at 1 — the cap prevents inflation, not the wrong recipient.Affected
native/tokens/pda-mint-authority/native/program/src/instructions/mint.rstokens/pda-mint-authority/native/program/src/instructions/create.rstokens/pda-mint-authority/native/program/src/state/mod.rstokens/pda-mint-authority/native/ts/instructions/{create,mint}.tstokens/pda-mint-authority/native/tests/test.tspinocchio/tokens/pda-mint-authority/pinocchio/program/src/instructions/mint.rstokens/pda-mint-authority/pinocchio/program/src/instructions/create.rstokens/pda-mint-authority/pinocchio/program/src/state.rstokens/pda-mint-authority/pinocchio/tests/test.tsThe anchor variant was already fixed in solana-foundation#692 and is untouched.
Functionality
Initcreates the program's global mint-authority PDA ([b"mint_authority"]).Createhas the payer fund a new mint whose mint/freeze authority is that PDA and attaches Metaplex metadata.Mintmints the single token into the payer's ATA, signed by the PDA viainvoke_signed, then creates the Master Edition, which transfers the mint authority to Metaplex and caps supply at 1.The bug
Before this change the only check in
Mintwas thatmint_authorityis the program PDA (nativemint.rs:30-32, pinocchiomint.rs:52-57). Nothing linked the caller to the mint:mint.rs:34-50creates the ATA withcreate_associated_token_account(payer, payer, mint, ...)andmint.rs:59-70mints to it.payeris whoever signed the transaction.mint.rs:64-83does the same withCreateIdempotent { wallet: payer, ... }followed byMintTo.mint_accountis a plain writable account; any mint whose authority is the PDA is accepted. So the sequencecreator: Create(mint)→outsider: Mint(mint)succeeds and the NFT lands in the outsider's ATA. The subsequentcreator: Mint(mint)fails with SPL Token error 4 (owner does not match) because the edition now holds the authority.Reproduce
Test:
Rejects a Mint from a wallet that did not create the NFT(both variants). Against the unpatched program:Fix
Mirrors solana-foundation#692's
MintConfigapproach, made per-mint because these variants create a fresh mint perCreate:MintConfig { bump, admin }state (33 bytes) at PDA[b"mint_config", mint](nativestate/mod.rs, pinocchiostate.rs).Createtakes themint_configaccount aftermetadata_account, verifies its derivation, creates it withinvoke_signed, and recordspayerasadmin(nativecreate.rs:102-122, pinocchiocreate.rs:105-126). The system-program CPI already requirespayerto have signed.Minttakesmint_configaftermint_authority, verifies derivation and program ownership, requirespayerto be a signer, and rejects withProgramError::IncorrectAuthorityunlesspayer == admin(nativemint.rs:37-50, pinocchiomint.rs:60-75).Wire format change: one extra account on
CreateandMintin each variant; instruction data is unchanged. The native TS client (ts/instructions/create.ts,ts/instructions/mint.ts) gained amintConfigparameter and both test suites derive and pass it.Createalso now asserts the recorded creator bytes, andMintasserts the token owner is the creator and mint supply is 1.Verification
Same commands as above, after the fix:
The outsider's transaction now fails with
InstructionError(0, IncorrectAuthority)in both variants, its ATA is never created, mint supply stays 0, and no edition account exists until the creator mints.cargo fmt --check,cargo clippy -p pda-mint-authority-native-program -p pda-mint-authority-pinocchio-program -- -D warnings,tsc --noEmitin both projects, and prettier all pass.