This commit is contained in:
jonesmarvin8 2025-12-09 15:36:46 -05:00
parent 471611f848
commit 2e37e20014

View File

@ -252,7 +252,6 @@ fn initialize_account(pre_states: &[AccountWithMetadata]) -> Vec<AccountPostStat
}
fn burn(pre_states: &[AccountWithMetadata], balance_to_burn: u128) -> Vec<AccountPostState> {
if pre_states.len() != 2 {
panic!("Invalid number of accounts");
}
@ -262,8 +261,8 @@ fn burn(pre_states: &[AccountWithMetadata], balance_to_burn: u128) -> Vec<Accoun
let definition_values =
TokenDefinition::parse(&definition.account.data).expect("Definition account must be valid");
let user_values =
TokenHolding::parse(&user_holding.account.data).expect("Token Holding account must be valid");
let user_values = TokenHolding::parse(&user_holding.account.data)
.expect("Token Holding account must be valid");
if definition.account_id != user_values.definition_id {
panic!("Mismatch token definition and token holding");
@ -280,22 +279,17 @@ fn burn(pre_states: &[AccountWithMetadata], balance_to_burn: u128) -> Vec<Accoun
let mut post_user_holding = user_holding.account.clone();
let mut post_definition = definition.account.clone();
post_user_holding.data = TokenHolding::into_data(
TokenHolding {
account_type: user_values.account_type,
definition_id: user_values.definition_id,
balance: user_values.balance - balance_to_burn,
}
);
post_definition.data = TokenDefinition::into_data(
TokenDefinition {
account_type: definition_values.account_type,
name: definition_values.name,
total_supply: definition_values.total_supply - balance_to_burn,
}
);
post_user_holding.data = TokenHolding::into_data(TokenHolding {
account_type: user_values.account_type,
definition_id: user_values.definition_id,
balance: user_values.balance - balance_to_burn,
});
post_definition.data = TokenDefinition::into_data(TokenDefinition {
account_type: definition_values.account_type,
name: definition_values.name,
total_supply: definition_values.total_supply - balance_to_burn,
});
vec![
AccountPostState::new(post_definition),
@ -303,11 +297,14 @@ fn burn(pre_states: &[AccountWithMetadata], balance_to_burn: u128) -> Vec<Accoun
]
}
fn mint_additional_supply(pre_states: &[AccountWithMetadata], amount_to_mint: u128) -> Vec<AccountPostState> {
fn mint_additional_supply(
pre_states: &[AccountWithMetadata],
amount_to_mint: u128,
) -> Vec<AccountPostState> {
if pre_states.len() != 2 {
panic!("Invalid number of accounts");
}
let definition = &pre_states[0];
let token_holding = &pre_states[1];
@ -323,22 +320,24 @@ fn mint_additional_supply(pre_states: &[AccountWithMetadata], amount_to_mint: u1
let token_holding_values: TokenHolding = if token_holding.account == Account::default() {
TokenHolding::new(&definition.account_id)
} else { TokenHolding::parse(&token_holding.account.data).expect("Holding account must be valid") };
} else {
TokenHolding::parse(&token_holding.account.data).expect("Holding account must be valid")
};
if definition.account_id != token_holding_values.definition_id {
panic!("Mismatch token definition and token holding");
}
let token_holding_post_data = TokenHolding {
account_type: token_holding_values.account_type,
definition_id: token_holding_values.definition_id,
balance: token_holding_values.balance + amount_to_mint,
account_type: token_holding_values.account_type,
definition_id: token_holding_values.definition_id,
balance: token_holding_values.balance + amount_to_mint,
};
let post_definition_data = TokenDefinition {
account_type: definition_values.account_type,
name: definition_values.name,
total_supply: definition_values.total_supply + amount_to_mint,
account_type: definition_values.account_type,
name: definition_values.name,
total_supply: definition_values.total_supply + amount_to_mint,
};
let post_definition = {
@ -361,7 +360,6 @@ fn mint_additional_supply(pre_states: &[AccountWithMetadata], amount_to_mint: u1
vec![post_definition, token_holding_post]
}
type Instruction = [u8; 23];
fn main() {
@ -447,9 +445,9 @@ mod tests {
use nssa_core::account::{Account, AccountId, AccountWithMetadata};
use crate::{
TOKEN_DEFINITION_DATA_SIZE, TOKEN_HOLDING_DATA_SIZE, TOKEN_HOLDING_TYPE,
TOKEN_DEFINITION_TYPE, TokenDefinition, TokenHolding,
initialize_account, new_definition, transfer, burn, mint_additional_supply,
TOKEN_DEFINITION_DATA_SIZE, TOKEN_DEFINITION_TYPE, TOKEN_HOLDING_DATA_SIZE,
TOKEN_HOLDING_TYPE, TokenDefinition, TokenHolding, burn, initialize_account,
mint_additional_supply, new_definition, transfer,
};
#[should_panic(expected = "Invalid number of input accounts")]
@ -863,49 +861,45 @@ mod tests {
HoldingId,
}
fn helper_account_constructor(selection: AccountsEnum) -> AccountWithMetadata{
fn helper_account_constructor(selection: AccountsEnum) -> AccountWithMetadata {
match selection {
AccountsEnum::DefinitionAccountAuth => AccountWithMetadata {
account: Account {
program_owner: [5u32;8],
balance: 0u128,
data: TokenDefinition::into_data(
TokenDefinition {
account_type: TOKEN_DEFINITION_TYPE,
name: [2; 6],
total_supply: helper_balance_constructor(BalanceEnum::InitSupply),
}),
nonce: 0,
program_owner: [5u32; 8],
balance: 0u128,
data: TokenDefinition::into_data(TokenDefinition {
account_type: TOKEN_DEFINITION_TYPE,
name: [2; 6],
total_supply: helper_balance_constructor(BalanceEnum::InitSupply),
}),
nonce: 0,
},
is_authorized: true,
account_id: helper_id_constructor(IdEnum::PoolDefinitionId),
},
AccountsEnum::DefinitionAccountNotAuth => AccountWithMetadata {
account: Account {
program_owner: [5u32; 8],
balance: 0u128,
data: TokenDefinition::into_data(
TokenDefinition {
account_type: TOKEN_DEFINITION_TYPE,
name: [2; 6],
total_supply: helper_balance_constructor(BalanceEnum::InitSupply),
}),
nonce: 0,
program_owner: [5u32; 8],
balance: 0u128,
data: TokenDefinition::into_data(TokenDefinition {
account_type: TOKEN_DEFINITION_TYPE,
name: [2; 6],
total_supply: helper_balance_constructor(BalanceEnum::InitSupply),
}),
nonce: 0,
},
is_authorized: false,
account_id: helper_id_constructor(IdEnum::PoolDefinitionId),
},
AccountsEnum::HoldingDiffDef => AccountWithMetadata {
account: Account {
program_owner: [5u32;8],
program_owner: [5u32; 8],
balance: 0u128,
data: TokenHolding::into_data(
TokenHolding {
account_type: TOKEN_HOLDING_TYPE,
definition_id: helper_id_constructor(IdEnum::PoolDefinitionIdDiff),
balance: helper_balance_constructor(BalanceEnum::HoldingBalance),
}
),
data: TokenHolding::into_data(TokenHolding {
account_type: TOKEN_HOLDING_TYPE,
definition_id: helper_id_constructor(IdEnum::PoolDefinitionIdDiff),
balance: helper_balance_constructor(BalanceEnum::HoldingBalance),
}),
nonce: 0,
},
is_authorized: true,
@ -913,15 +907,13 @@ mod tests {
},
AccountsEnum::HoldingSameDefAuth => AccountWithMetadata {
account: Account {
program_owner: [5u32;8],
program_owner: [5u32; 8],
balance: 0u128,
data: TokenHolding::into_data(
TokenHolding {
account_type: TOKEN_HOLDING_TYPE,
definition_id: helper_id_constructor(IdEnum::PoolDefinitionId),
balance: helper_balance_constructor(BalanceEnum::HoldingBalance),
}
),
data: TokenHolding::into_data(TokenHolding {
account_type: TOKEN_HOLDING_TYPE,
definition_id: helper_id_constructor(IdEnum::PoolDefinitionId),
balance: helper_balance_constructor(BalanceEnum::HoldingBalance),
}),
nonce: 0,
},
is_authorized: true,
@ -929,15 +921,13 @@ mod tests {
},
AccountsEnum::HoldingSameDefNotAuth => AccountWithMetadata {
account: Account {
program_owner: [5u32;8],
program_owner: [5u32; 8],
balance: 0u128,
data: TokenHolding::into_data(
TokenHolding {
account_type: TOKEN_HOLDING_TYPE,
definition_id: helper_id_constructor(IdEnum::PoolDefinitionId),
balance: helper_balance_constructor(BalanceEnum::HoldingBalance),
}
),
data: TokenHolding::into_data(TokenHolding {
account_type: TOKEN_HOLDING_TYPE,
definition_id: helper_id_constructor(IdEnum::PoolDefinitionId),
balance: helper_balance_constructor(BalanceEnum::HoldingBalance),
}),
nonce: 0,
},
is_authorized: false,
@ -945,30 +935,27 @@ mod tests {
},
AccountsEnum::DefinitionAccountPostBurn => AccountWithMetadata {
account: Account {
program_owner: [5u32;8],
balance: 0u128,
data: TokenDefinition::into_data(
TokenDefinition {
account_type: TOKEN_DEFINITION_TYPE,
name: [2; 6],
total_supply: helper_balance_constructor(BalanceEnum::InitSupplyBurned),
}),
nonce: 0,
program_owner: [5u32; 8],
balance: 0u128,
data: TokenDefinition::into_data(TokenDefinition {
account_type: TOKEN_DEFINITION_TYPE,
name: [2; 6],
total_supply: helper_balance_constructor(BalanceEnum::InitSupplyBurned),
}),
nonce: 0,
},
is_authorized: true,
account_id: helper_id_constructor(IdEnum::PoolDefinitionId),
},
AccountsEnum::HoldingAccountPostBurn => AccountWithMetadata {
account: Account {
program_owner: [5u32;8],
program_owner: [5u32; 8],
balance: 0u128,
data: TokenHolding::into_data(
TokenHolding {
account_type: TOKEN_HOLDING_TYPE,
definition_id: helper_id_constructor(IdEnum::PoolDefinitionId),
balance: helper_balance_constructor(BalanceEnum::HoldingBalanceBurned),
}
),
data: TokenHolding::into_data(TokenHolding {
account_type: TOKEN_HOLDING_TYPE,
definition_id: helper_id_constructor(IdEnum::PoolDefinitionId),
balance: helper_balance_constructor(BalanceEnum::HoldingBalanceBurned),
}),
nonce: 0,
},
is_authorized: false,
@ -981,15 +968,13 @@ mod tests {
},
AccountsEnum::InitMint => AccountWithMetadata {
account: Account {
program_owner: [0u32;8],
program_owner: [0u32; 8],
balance: 0u128,
data: TokenHolding::into_data(
TokenHolding {
account_type: TOKEN_HOLDING_TYPE,
definition_id: helper_id_constructor(IdEnum::PoolDefinitionId),
balance: helper_balance_constructor(BalanceEnum::MintSuccess),
}
),
data: TokenHolding::into_data(TokenHolding {
account_type: TOKEN_HOLDING_TYPE,
definition_id: helper_id_constructor(IdEnum::PoolDefinitionId),
balance: helper_balance_constructor(BalanceEnum::MintSuccess),
}),
nonce: 0,
},
is_authorized: false,
@ -997,36 +982,33 @@ mod tests {
},
AccountsEnum::HoldingSameDefMint => AccountWithMetadata {
account: Account {
program_owner: [5u32;8],
balance: 0u128,
data: TokenHolding::into_data(
TokenHolding {
account_type: TOKEN_HOLDING_TYPE,
definition_id: helper_id_constructor(IdEnum::PoolDefinitionId),
balance: helper_balance_constructor(BalanceEnum::HoldingBalanceMint),
}
),
nonce: 0,
program_owner: [5u32; 8],
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: TOKEN_HOLDING_TYPE,
definition_id: helper_id_constructor(IdEnum::PoolDefinitionId),
balance: helper_balance_constructor(BalanceEnum::HoldingBalanceMint),
}),
nonce: 0,
},
is_authorized: true,
account_id: helper_id_constructor(IdEnum::PoolDefinitionId),
},
AccountsEnum::DefinitionAccountMint => AccountWithMetadata {
account: Account {
program_owner: [5u32;8],
balance: 0u128,
data: TokenDefinition::into_data(
TokenDefinition {
account_type: TOKEN_DEFINITION_TYPE,
name: [2; 6],
total_supply: helper_balance_constructor(BalanceEnum::InitSupplyMint),
}),
nonce: 0,
program_owner: [5u32; 8],
balance: 0u128,
data: TokenDefinition::into_data(TokenDefinition {
account_type: TOKEN_DEFINITION_TYPE,
name: [2; 6],
total_supply: helper_balance_constructor(BalanceEnum::InitSupplyMint),
}),
nonce: 0,
},
is_authorized: true,
account_id: helper_id_constructor(IdEnum::PoolDefinitionId),
},
_ => panic!("Invalid selection")
_ => panic!("Invalid selection"),
}
}
@ -1041,140 +1023,189 @@ mod tests {
BalanceEnum::MintSuccess => 50_000,
BalanceEnum::InitSupplyMint => 150_000,
BalanceEnum::HoldingBalanceMint => 51_000,
_ => panic!("Invalid selection")
_ => panic!("Invalid selection"),
}
}
fn helper_id_constructor(selection: IdEnum) -> AccountId {
match selection {
IdEnum::PoolDefinitionId => AccountId::new([15;32]),
IdEnum::PoolDefinitionIdDiff => AccountId::new([16;32]),
IdEnum::HoldingId => AccountId::new([17;32]),
IdEnum::PoolDefinitionId => AccountId::new([15; 32]),
IdEnum::PoolDefinitionIdDiff => AccountId::new([16; 32]),
IdEnum::HoldingId => AccountId::new([17; 32]),
}
}
#[test]
#[should_panic(expected = "Invalid number of accounts")]
fn test_burn_invalid_number_of_accounts() {
let pre_states = vec![
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
];
let _post_states = burn(&pre_states, helper_balance_constructor(BalanceEnum::BurnSuccess));
let pre_states = vec![helper_account_constructor(
AccountsEnum::DefinitionAccountAuth,
)];
let _post_states = burn(
&pre_states,
helper_balance_constructor(BalanceEnum::BurnSuccess),
);
}
#[test]
#[should_panic(expected = "Mismatch token definition and token holding")]
fn test_burn_mismatch_def() {
let pre_states = vec![
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::HoldingDiffDef),
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::HoldingDiffDef),
];
let _post_states = burn(&pre_states, helper_balance_constructor(BalanceEnum::BurnSuccess));
let _post_states = burn(
&pre_states,
helper_balance_constructor(BalanceEnum::BurnSuccess),
);
}
#[test]
#[should_panic(expected = "Authorization is missing")]
fn test_burn_missing_authorization() {
let pre_states = vec![
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::HoldingSameDefNotAuth),
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::HoldingSameDefNotAuth),
];
let _post_states = burn(&pre_states, helper_balance_constructor(BalanceEnum::BurnSuccess));
let _post_states = burn(
&pre_states,
helper_balance_constructor(BalanceEnum::BurnSuccess),
);
}
#[test]
#[should_panic(expected = "Insufficient balance to burn")]
fn test_burn_insufficient_balance() {
let pre_states = vec![
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::HoldingSameDefAuth),
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::HoldingSameDefAuth),
];
let _post_states = burn(&pre_states, helper_balance_constructor(BalanceEnum::BurnInsufficient));
let _post_states = burn(
&pre_states,
helper_balance_constructor(BalanceEnum::BurnInsufficient),
);
}
#[test]
fn test_burn_success() {
let pre_states = vec![
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::HoldingSameDefAuth),
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::HoldingSameDefAuth),
];
let post_states = burn(&pre_states, helper_balance_constructor(BalanceEnum::BurnSuccess));
let post_states = burn(
&pre_states,
helper_balance_constructor(BalanceEnum::BurnSuccess),
);
let def_post = post_states[0].clone();
let holding_post = post_states[1].clone();
assert!(*def_post.account() == helper_account_constructor(AccountsEnum::DefinitionAccountPostBurn).account);
assert!(*holding_post.account() == helper_account_constructor(AccountsEnum::HoldingAccountPostBurn).account);
assert!(
*def_post.account()
== helper_account_constructor(AccountsEnum::DefinitionAccountPostBurn).account
);
assert!(
*holding_post.account()
== helper_account_constructor(AccountsEnum::HoldingAccountPostBurn).account
);
}
#[test]
#[should_panic(expected = "Invalid number of accounts")]
fn test_mint_invalid_number_of_accounts() {
let pre_states = vec![
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
];
let _post_states = mint_additional_supply(&pre_states, helper_balance_constructor(BalanceEnum::MintSuccess));
let pre_states = vec![helper_account_constructor(
AccountsEnum::DefinitionAccountAuth,
)];
let _post_states = mint_additional_supply(
&pre_states,
helper_balance_constructor(BalanceEnum::MintSuccess),
);
}
#[test]
#[should_panic(expected = "Holding account must be valid")]
fn test_mint_not_valid_holding_account() {
let pre_states = vec![
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::DefinitionAccountNotAuth),
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::DefinitionAccountNotAuth),
];
let _post_states = mint_additional_supply(&pre_states, helper_balance_constructor(BalanceEnum::MintSuccess));
let _post_states = mint_additional_supply(
&pre_states,
helper_balance_constructor(BalanceEnum::MintSuccess),
);
}
#[test]
#[should_panic(expected = "Definition authorization is missing")]
fn test_mint_missing_authorization() {
let pre_states = vec![
helper_account_constructor(AccountsEnum::DefinitionAccountNotAuth),
helper_account_constructor(AccountsEnum::HoldingSameDefNotAuth),
helper_account_constructor(AccountsEnum::DefinitionAccountNotAuth),
helper_account_constructor(AccountsEnum::HoldingSameDefNotAuth),
];
let _post_states = mint_additional_supply(&pre_states, helper_balance_constructor(BalanceEnum::MintSuccess));
let _post_states = mint_additional_supply(
&pre_states,
helper_balance_constructor(BalanceEnum::MintSuccess),
);
}
#[test]
#[should_panic(expected = "Mismatch token definition and token holding")]
fn test_mint_mismatched_token_definition() {
let pre_states = vec![
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::HoldingDiffDef),
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::HoldingDiffDef),
];
let _post_states = mint_additional_supply(&pre_states, helper_balance_constructor(BalanceEnum::MintSuccess));
let _post_states = mint_additional_supply(
&pre_states,
helper_balance_constructor(BalanceEnum::MintSuccess),
);
}
#[test]
fn test_mint_success() {
let pre_states = vec![
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::HoldingSameDefNotAuth),
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::HoldingSameDefNotAuth),
];
let post_states = mint_additional_supply(&pre_states, helper_balance_constructor(BalanceEnum::MintSuccess));
let post_states = mint_additional_supply(
&pre_states,
helper_balance_constructor(BalanceEnum::MintSuccess),
);
let def_post = post_states[0].clone();
let holding_post = post_states[1].clone();
assert!(*def_post.account() == helper_account_constructor(AccountsEnum::DefinitionAccountMint).account);
assert!(*holding_post.account() == helper_account_constructor(AccountsEnum::HoldingSameDefMint).account);
assert!(
*def_post.account()
== helper_account_constructor(AccountsEnum::DefinitionAccountMint).account
);
assert!(
*holding_post.account()
== helper_account_constructor(AccountsEnum::HoldingSameDefMint).account
);
}
#[test]
fn test_mint_uninit_holding_success() {
let pre_states = vec![
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::Uninit),
helper_account_constructor(AccountsEnum::DefinitionAccountAuth),
helper_account_constructor(AccountsEnum::Uninit),
];
let post_states = mint_additional_supply(&pre_states, helper_balance_constructor(BalanceEnum::MintSuccess));
let post_states = mint_additional_supply(
&pre_states,
helper_balance_constructor(BalanceEnum::MintSuccess),
);
let def_post = post_states[0].clone();
let holding_post = post_states[1].clone();
assert!(*def_post.account() == helper_account_constructor(AccountsEnum::DefinitionAccountMint).account);
assert!(*holding_post.account() == helper_account_constructor(AccountsEnum::InitMint).account);
assert!(
*def_post.account()
== helper_account_constructor(AccountsEnum::DefinitionAccountMint).account
);
assert!(
*holding_post.account() == helper_account_constructor(AccountsEnum::InitMint).account
);
assert!(holding_post.requires_claim() == true);
}
}
}