mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-07-31 11:13:19 +00:00
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:
parent
7e788f4215
commit
b561f91db2
@ -24,10 +24,16 @@ pub fn mint(
|
|||||||
|
|
||||||
// LP-0013: enforce mint authority — minting is only allowed if mint_authority is Some.
|
// LP-0013: enforce mint authority — minting is only allowed if mint_authority is Some.
|
||||||
if let TokenDefinition::Fungible { mint_authority, .. } = &definition {
|
if let TokenDefinition::Fungible { mint_authority, .. } = &definition {
|
||||||
assert!(
|
match mint_authority {
|
||||||
mint_authority.is_some(),
|
None => panic!("Mint authority has been revoked; this token has a fixed supply"),
|
||||||
"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() {
|
let mut holding = if user_holding_account.account == Account::default() {
|
||||||
TokenHolding::zeroized_from_definition(definition_account.account_id, &definition)
|
TokenHolding::zeroized_from_definition(definition_account.account_id, &definition)
|
||||||
|
|||||||
@ -9,9 +9,6 @@ pub fn set_authority(
|
|||||||
definition_account: AccountWithMetadata,
|
definition_account: AccountWithMetadata,
|
||||||
new_authority: Option<[u8; 32]>,
|
new_authority: Option<[u8; 32]>,
|
||||||
) -> Vec<AccountPostState> {
|
) -> 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!(
|
assert!(
|
||||||
definition_account.is_authorized,
|
definition_account.is_authorized,
|
||||||
"Definition account authorization is missing; only the mint authority can call SetAuthority"
|
"Definition account authorization is missing; only the mint authority can call SetAuthority"
|
||||||
@ -26,8 +23,13 @@ pub fn set_authority(
|
|||||||
None => {
|
None => {
|
||||||
panic!("Mint authority already revoked; supply is permanently fixed");
|
panic!("Mint authority already revoked; supply is permanently fixed");
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(authority_key) => {
|
||||||
// Rotate to new authority, or revoke by setting to None
|
// 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;
|
*mint_authority = new_authority;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,7 @@ impl AccountForTests {
|
|||||||
name: String::from("test"),
|
name: String::from("test"),
|
||||||
total_supply: BalanceForTests::init_supply(),
|
total_supply: BalanceForTests::init_supply(),
|
||||||
metadata_id: None,
|
metadata_id: None,
|
||||||
mint_authority: Some([1_u8; 32]),
|
mint_authority: Some([15_u8; 32]),
|
||||||
}),
|
}),
|
||||||
nonce: Nonce(0),
|
nonce: Nonce(0),
|
||||||
},
|
},
|
||||||
@ -160,7 +160,7 @@ impl AccountForTests {
|
|||||||
name: String::from("test"),
|
name: String::from("test"),
|
||||||
total_supply: BalanceForTests::init_supply_burned(),
|
total_supply: BalanceForTests::init_supply_burned(),
|
||||||
metadata_id: None,
|
metadata_id: None,
|
||||||
mint_authority: Some([1_u8; 32]),
|
mint_authority: Some([15_u8; 32]),
|
||||||
}),
|
}),
|
||||||
nonce: Nonce(0),
|
nonce: Nonce(0),
|
||||||
},
|
},
|
||||||
@ -242,7 +242,7 @@ impl AccountForTests {
|
|||||||
name: String::from("test"),
|
name: String::from("test"),
|
||||||
total_supply: BalanceForTests::init_supply_mint(),
|
total_supply: BalanceForTests::init_supply_mint(),
|
||||||
metadata_id: None,
|
metadata_id: None,
|
||||||
mint_authority: Some([1_u8; 32]),
|
mint_authority: Some([15_u8; 32]),
|
||||||
}),
|
}),
|
||||||
nonce: Nonce(0),
|
nonce: Nonce(0),
|
||||||
},
|
},
|
||||||
@ -1325,7 +1325,7 @@ mod authority_tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::{mint::mint, set_authority::set_authority};
|
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];
|
const TOKEN_PROGRAM_ID: [u32; 8] = [5_u32; 8];
|
||||||
|
|
||||||
fn def_with_authority() -> AccountWithMetadata {
|
fn def_with_authority() -> AccountWithMetadata {
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
# 4. Submit NewFungibleDefinitionWithAuthority transaction
|
# 4. Submit NewFungibleDefinitionWithAuthority transaction
|
||||||
# 5. Submit Mint transaction
|
# 5. Submit Mint transaction
|
||||||
# 6. Submit SetAuthority (revoke) 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
|
set -euo pipefail
|
||||||
|
|
||||||
|
|
||||||
@ -66,11 +66,11 @@ lgs wallet topup 2>&1 | grep -E "complete|funded|Address" || true
|
|||||||
echo " Wallet funded."
|
echo " Wallet funded."
|
||||||
|
|
||||||
echo "[3/7] Creating token accounts..."
|
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)
|
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)
|
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)
|
RECIPIENT_ID=$(echo "$RECIPIENT_RESULT" | grep -oE '[0-9a-f]{64}' | head -1)
|
||||||
echo " Definition account: $DEF_ID"
|
echo " Definition account: $DEF_ID"
|
||||||
echo " Supply account: $SUPPLY_ID"
|
echo " Supply account: $SUPPLY_ID"
|
||||||
@ -84,7 +84,7 @@ ${TIMEOUT:+$TIMEOUT 30} "$SPEL" --idl "$IDL" --program "$TOKEN_BIN" \
|
|||||||
--holding-target-account "$SUPPLY_ID" \
|
--holding-target-account "$SUPPLY_ID" \
|
||||||
--name "DemoCoin" \
|
--name "DemoCoin" \
|
||||||
--initial-supply 1000000 \
|
--initial-supply 1000000 \
|
||||||
--mint-authority "$DEF_ID" 2>&1 || true
|
--mint-authority "$DEF_ID"
|
||||||
echo " Token 'DemoCoin' submitted. Initial supply: 1,000,000"
|
echo " Token 'DemoCoin' submitted. Initial supply: 1,000,000"
|
||||||
|
|
||||||
sleep 2
|
sleep 2
|
||||||
@ -95,7 +95,7 @@ ${TIMEOUT:+$TIMEOUT 30} "$SPEL" --idl "$IDL" --program "$TOKEN_BIN" \
|
|||||||
-- mint \
|
-- mint \
|
||||||
--definition-account "$DEF_ID" \
|
--definition-account "$DEF_ID" \
|
||||||
--user-holding-account "$RECIPIENT_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"
|
echo " Mint transaction submitted. New total supply: 1,500,000"
|
||||||
|
|
||||||
sleep 2
|
sleep 2
|
||||||
@ -105,7 +105,7 @@ NSSA_WALLET_HOME_DIR="$WALLET_DIR" \
|
|||||||
${TIMEOUT:+$TIMEOUT 30} "$SPEL" --idl "$IDL" --program "$TOKEN_BIN" \
|
${TIMEOUT:+$TIMEOUT 30} "$SPEL" --idl "$IDL" --program "$TOKEN_BIN" \
|
||||||
-- set-authority \
|
-- set-authority \
|
||||||
--definition-account "$DEF_ID" \
|
--definition-account "$DEF_ID" \
|
||||||
--new-authority none 2>&1 || true
|
--new-authority none
|
||||||
echo " Authority revoked. Supply permanently fixed at 1,500,000"
|
echo " Authority revoked. Supply permanently fixed at 1,500,000"
|
||||||
|
|
||||||
sleep 2
|
sleep 2
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user