fix: enforce mint authority key validation in mint and set_authority

- mint.rs: validate caller account_id matches stored mint_authority key
- set_authority.rs: validate caller matches mint_authority before rotation/revoke
- tests.rs: align AUTHORITY constant and fixtures to match account_id [15; 32]
- demo-full-flow.sh: fix --public flag, remove || true from spel commands,
  update test count to 60
This commit is contained in:
bristinWild 2026-06-02 02:03:35 +05:30
parent 7e788f4215
commit b561f91db2
4 changed files with 29 additions and 21 deletions

View File

@ -24,10 +24,16 @@ pub fn mint(
// LP-0013: enforce mint authority — minting is only allowed if mint_authority is Some.
if let TokenDefinition::Fungible { mint_authority, .. } = &definition {
assert!(
mint_authority.is_some(),
"Mint authority has been revoked; this token has a fixed supply"
);
match mint_authority {
None => panic!("Mint authority has been revoked; this token has a fixed supply"),
Some(authority_key) => {
assert_eq!(
definition_account.account_id.as_ref(),
authority_key,
"Signer is not the mint authority"
);
}
}
}
let mut holding = if user_holding_account.account == Account::default() {
TokenHolding::zeroized_from_definition(definition_account.account_id, &definition)

View File

@ -9,9 +9,6 @@ pub fn set_authority(
definition_account: AccountWithMetadata,
new_authority: Option<[u8; 32]>,
) -> Vec<AccountPostState> {
// The definition account must be authorized — this means the transaction
// signer controls the definition account, which is how mint authority
// is enforced in LEZ (account-level authorization).
assert!(
definition_account.is_authorized,
"Definition account authorization is missing; only the mint authority can call SetAuthority"
@ -26,8 +23,13 @@ pub fn set_authority(
None => {
panic!("Mint authority already revoked; supply is permanently fixed");
}
Some(_) => {
// Rotate to new authority, or revoke by setting to None
Some(authority_key) => {
// Validate caller matches the stored mint authority key
assert_eq!(
definition_account.account_id.as_ref(),
authority_key.as_ref(),
"Signer does not match the stored mint authority"
);
*mint_authority = new_authority;
}
}
@ -41,4 +43,4 @@ pub fn set_authority(
definition_post.data = Data::from(&definition);
vec![AccountPostState::new(definition_post)]
}
}

View File

@ -42,7 +42,7 @@ impl AccountForTests {
name: String::from("test"),
total_supply: BalanceForTests::init_supply(),
metadata_id: None,
mint_authority: Some([1_u8; 32]),
mint_authority: Some([15_u8; 32]),
}),
nonce: Nonce(0),
},
@ -160,7 +160,7 @@ impl AccountForTests {
name: String::from("test"),
total_supply: BalanceForTests::init_supply_burned(),
metadata_id: None,
mint_authority: Some([1_u8; 32]),
mint_authority: Some([15_u8; 32]),
}),
nonce: Nonce(0),
},
@ -242,7 +242,7 @@ impl AccountForTests {
name: String::from("test"),
total_supply: BalanceForTests::init_supply_mint(),
metadata_id: None,
mint_authority: Some([1_u8; 32]),
mint_authority: Some([15_u8; 32]),
}),
nonce: Nonce(0),
},
@ -1325,7 +1325,7 @@ mod authority_tests {
use super::*;
use crate::{mint::mint, set_authority::set_authority};
const AUTHORITY: [u8; 32] = [9_u8; 32];
const AUTHORITY: [u8; 32] = [15_u8; 32];
const TOKEN_PROGRAM_ID: [u32; 8] = [5_u32; 8];
fn def_with_authority() -> AccountWithMetadata {

View File

@ -26,7 +26,7 @@
# 4. Submit NewFungibleDefinitionWithAuthority transaction
# 5. Submit Mint transaction
# 6. Submit SetAuthority (revoke) transaction
# 7. Run unit tests to verify authority logic (49 tests)
# 7. Run unit tests to verify authority logic (60 tests)
set -euo pipefail
@ -66,11 +66,11 @@ lgs wallet topup 2>&1 | grep -E "complete|funded|Address" || true
echo " Wallet funded."
echo "[3/7] Creating token accounts..."
DEF_RESULT=$(lgs wallet -- account new public 2>&1)
DEF_RESULT=$(lgs wallet -- account new --public 2>&1)
DEF_ID=$(echo "$DEF_RESULT" | grep -oE '[0-9a-f]{64}' | head -1)
SUPPLY_RESULT=$(lgs wallet -- account new public 2>&1)
SUPPLY_RESULT=$(lgs wallet -- account new --public 2>&1)
SUPPLY_ID=$(echo "$SUPPLY_RESULT" | grep -oE '[0-9a-f]{64}' | head -1)
RECIPIENT_RESULT=$(lgs wallet -- account new public 2>&1)
RECIPIENT_RESULT=$(lgs wallet -- account new --public 2>&1)
RECIPIENT_ID=$(echo "$RECIPIENT_RESULT" | grep -oE '[0-9a-f]{64}' | head -1)
echo " Definition account: $DEF_ID"
echo " Supply account: $SUPPLY_ID"
@ -84,7 +84,7 @@ ${TIMEOUT:+$TIMEOUT 30} "$SPEL" --idl "$IDL" --program "$TOKEN_BIN" \
--holding-target-account "$SUPPLY_ID" \
--name "DemoCoin" \
--initial-supply 1000000 \
--mint-authority "$DEF_ID" 2>&1 || true
--mint-authority "$DEF_ID"
echo " Token 'DemoCoin' submitted. Initial supply: 1,000,000"
sleep 2
@ -95,7 +95,7 @@ ${TIMEOUT:+$TIMEOUT 30} "$SPEL" --idl "$IDL" --program "$TOKEN_BIN" \
-- mint \
--definition-account "$DEF_ID" \
--user-holding-account "$RECIPIENT_ID" \
--amount-to-mint 500000 2>&1 || true
--amount-to-mint 500000
echo " Mint transaction submitted. New total supply: 1,500,000"
sleep 2
@ -105,7 +105,7 @@ NSSA_WALLET_HOME_DIR="$WALLET_DIR" \
${TIMEOUT:+$TIMEOUT 30} "$SPEL" --idl "$IDL" --program "$TOKEN_BIN" \
-- set-authority \
--definition-account "$DEF_ID" \
--new-authority none 2>&1 || true
--new-authority none
echo " Authority revoked. Supply permanently fixed at 1,500,000"
sleep 2