Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions creator-keys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2403,6 +2403,7 @@ impl CreatorKeysContract {
protocol_bps: u32,
) -> Result<(), ContractError> {
admin.require_auth();
assert_is_admin(&env, &admin)?;
fee::assert_valid_fee_bps(creator_bps, protocol_bps)?;

let config = fee::FeeConfig {
Expand Down Expand Up @@ -2597,6 +2598,7 @@ impl CreatorKeysContract {
recipient: Address,
) -> Result<(), ContractError> {
admin.require_auth();
assert_is_admin(&env, &admin)?;
validate_non_zero_address(&env, &recipient)?;

let old_recipient: Option<Address> = env
Expand Down
72 changes: 70 additions & 2 deletions creator-keys/tests/admin_unauthorized.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//! Integration tests for admin-only functions reverting when called by a non-admin.
//!
//
//! Every function gated by `assert_is_admin` must reject a non-admin caller with
//! `ContractError::Unauthorized` and must not mutate any contract state.

mod contract_test_env;

use contract_test_env::{register_creator_keys, set_pricing_and_fees, test_env_with_auths};
use contract_test_env::{register_creator_keys, set_pricing_and_fees, set_protocol_fee_bps, test_env_with_auths};
use creator_keys::{ContractError, CreatorKeysContractClient};
use soroban_sdk::{testutils::Address as _, Address, Env};

Expand Down Expand Up @@ -131,6 +131,74 @@ fn test_update_protocol_fee_recipient_no_state_change_on_non_admin_call() {
);
}

// ── set_fee_config ──────────────────────────────────────────────────────

#[test]
fn test_set_fee_config_reverts_for_non_admin() {
let env = test_env_with_auths();
let (client, _admin) = full_setup(&env);

let non_admin = Address::generate(&env);
let result = client.try_set_fee_config(&non_admin, &8000u32, &2000u32);
assert_eq!(result, Err(Ok(ContractError::Unauthorized)));
}

#[test]
fn test_set_fee_config_no_state_change_on_non_admin_call() {
let env = test_env_with_auths();
let (client, _admin) = full_setup(&env);

let protocol_bps_before = client.get_protocol_fee_bps().unwrap();

let non_admin = Address::generate(&env);
let result = client.try_set_fee_config(&non_admin, &8000u32, &2000u32);
assert_eq!(result, Err(Ok(ContractError::Unauthorized)));

let protocol_bps_after = client.get_protocol_fee_bps().unwrap();
assert_eq!(
protocol_bps_before, protocol_bps_after,
"protocol fee bps must not change when non-admin set_fee_config call is rejected"
);
}

// ── set_protocol_fee_recipient ──────────────────────────────────────────

#[test]
fn test_set_protocol_fee_recipient_reverts_for_non_admin() {
let env = test_env_with_auths();
let (client, _admin) = full_setup(&env);

let original_recipient = Address::generate(&env);
let admin = setup_admin(&env, &client);
client.set_protocol_fee_recipient(&admin, &original_recipient);

let non_admin = Address::generate(&env);
let new_recipient = Address::generate(&env);
let result = client.try_set_protocol_fee_recipient(&non_admin, &new_recipient);
assert_eq!(result, Err(Ok(ContractError::Unauthorized)));
}

#[test]
fn test_set_protocol_fee_recipient_no_state_change_on_non_admin_call() {
let env = test_env_with_auths();
let (client, _admin) = full_setup(&env);

let admin = setup_admin(&env, &client);
let original_recipient = Address::generate(&env);
client.set_protocol_fee_recipient(&admin, &original_recipient);

let non_admin = Address::generate(&env);
let new_recipient = Address::generate(&env);
let _ = client.try_set_protocol_fee_recipient(&non_admin, &new_recipient);

let stored = client.get_protocol_fee_recipient();
assert_eq!(
stored,
Some(original_recipient),
"fee recipient must not change when non-admin set_protocol_fee_recipient call is rejected"
);
}

// ── withdraw_treasury ─────────────────────────────────────────────────────────

#[test]
Expand Down
1 change: 1 addition & 0 deletions creator-keys/tests/buy_quote_monotonicity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ fn test_buy_quote_updates_after_fee_config_mutation() {

// Update fee config: 50% creator, 50% protocol
let admin = Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
client.set_fee_config(&admin, &5000u32, &5000u32);

// Get quote after fee config update
Expand Down
3 changes: 3 additions & 0 deletions creator-keys/tests/contract_test_env/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ pub fn set_protocol_fee_bps(
protocol_bps: u32,
) -> Address {
let admin = Address::generate(env);
client.set_protocol_admin(&admin, &admin);
client.set_fee_config(&admin, &creator_bps, &protocol_bps);
admin
}
Expand All @@ -93,6 +94,7 @@ pub fn set_pricing_and_fees(
protocol_bps: u32,
) -> Address {
let admin = Address::generate(env);
client.set_protocol_admin(&admin, &admin);
client.set_key_price(&admin, &key_price);
client.set_fee_config(&admin, &creator_bps, &protocol_bps);
admin
Expand Down Expand Up @@ -139,6 +141,7 @@ pub fn register_test_creator_with_fee_config(
protocol_bps: u32,
) -> Address {
let admin = Address::generate(env);
client.set_protocol_admin(&admin, &admin);
client.set_fee_config(&admin, &creator_bps, &protocol_bps);
let creator = Address::generate(env);
client.register_creator(
Expand Down
3 changes: 3 additions & 0 deletions creator-keys/tests/creator_fee_bps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ fn test_get_creator_fee_bps_returns_configured_value() {
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);
let admin = Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
let creator = Address::generate(&env);

client.register_creator(
Expand Down Expand Up @@ -38,6 +39,7 @@ fn test_get_creator_fee_bps_is_read_only() {
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);
let admin = Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
let creator = Address::generate(&env);

client.register_creator(
Expand Down Expand Up @@ -68,6 +70,7 @@ fn test_get_creator_fee_bps_tracks_fee_config_updates() {
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);
let admin = Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
let creator = Address::generate(&env);

client.register_creator(
Expand Down
5 changes: 5 additions & 0 deletions creator-keys/tests/creator_fee_config_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ fn test_get_creator_fee_config_registered_with_fee_config() {
let client = CreatorKeysContractClient::new(&env, &contract_id);

let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
let creator = soroban_sdk::Address::generate(&env);
let handle = String::from_str(&env, "test_creator");

Expand Down Expand Up @@ -92,6 +93,7 @@ fn test_get_creator_fee_config_is_read_only() {
let client = CreatorKeysContractClient::new(&env, &contract_id);

let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
let creator = soroban_sdk::Address::generate(&env);
let handle = String::from_str(&env, "test_creator");

Expand Down Expand Up @@ -127,6 +129,7 @@ fn test_get_creator_fee_config_updates_after_fee_reconfiguration() {
let client = CreatorKeysContractClient::new(&env, &contract_id);

let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
let creator = soroban_sdk::Address::generate(&env);
let handle = String::from_str(&env, "test_creator");

Expand Down Expand Up @@ -163,6 +166,7 @@ fn test_get_creator_fee_config_multiple_creators_independent() {
let client = CreatorKeysContractClient::new(&env, &contract_id);

let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
let creator1 = soroban_sdk::Address::generate(&env);
let creator2 = soroban_sdk::Address::generate(&env);
let handle1 = String::from_str(&env, "creator_one");
Expand Down Expand Up @@ -212,6 +216,7 @@ fn test_get_creator_fee_config_unregistered_after_fee_config_set() {
let client = CreatorKeysContractClient::new(&env, &contract_id);

let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
let unregistered_creator = soroban_sdk::Address::generate(&env);

client.set_fee_config(&admin, &9000u32, &1000u32);
Expand Down
2 changes: 2 additions & 0 deletions creator-keys/tests/creator_treasury_share.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ fn test_get_creator_treasury_share_returns_configured_value() {
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);
let admin = Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
let creator = Address::generate(&env);

client.register_creator(
Expand Down Expand Up @@ -38,6 +39,7 @@ fn test_get_creator_treasury_share_is_read_only() {
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);
let admin = Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
let creator = Address::generate(&env);

client.register_creator(
Expand Down
1 change: 1 addition & 0 deletions creator-keys/tests/fee_config_updated_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ fn test_fee_config_updated_event_emitted() {
let env = test_env_with_auths();
let (client, _) = register_creator_keys(&env);
let admin = Address::generate(&env);
client.set_protocol_admin(&admin, &admin);

// Initial set (no old config)
client.set_fee_config(&admin, &9000, &1000);
Expand Down
4 changes: 4 additions & 0 deletions creator-keys/tests/fee_config_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ fn test_get_protocol_fee_view_returns_configured_values() {
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);
let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);

client.set_fee_config(&admin, &9000u32, &1000u32);

Expand All @@ -40,6 +41,7 @@ fn test_get_protocol_fee_view_is_read_only() {
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);
let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);

client.set_fee_config(&admin, &8000u32, &2000u32);

Expand All @@ -59,6 +61,7 @@ fn test_get_protocol_fee_view_updates_after_reconfiguration() {
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);
let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);

client.set_fee_config(&admin, &9000u32, &1000u32);
let v1 = client.get_protocol_fee_view();
Expand All @@ -78,6 +81,7 @@ fn test_protocol_fee_bps_multiple_sequential_updates() {
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);
let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);

// First update
client.set_fee_config(&admin, &9000u32, &1000u32);
Expand Down
7 changes: 7 additions & 0 deletions creator-keys/tests/fee_split.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ fn test_set_and_get_fee_config() {
let client = CreatorKeysContractClient::new(&env, &contract_id);

let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
client.set_fee_config(&admin, &9000u32, &1000u32);

let config = client.get_fee_config();
Expand All @@ -28,6 +29,7 @@ fn test_compute_fees_for_payment() {
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);
let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);

client.set_fee_config(&admin, &9000u32, &1000u32);

Expand All @@ -45,6 +47,7 @@ fn test_set_fee_config_invalid_sum_fails() {
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);
let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);

let result = client.try_set_fee_config(&admin, &8000u32, &1000u32);
assert_eq!(result, Err(Ok(ContractError::InvalidFeeConfig)));
Expand All @@ -58,6 +61,7 @@ fn test_set_fee_config_max_protocol_bps_succeeds() {
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);
let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);

client.set_fee_config(&admin, &5000u32, &5000u32);
let config = client.get_fee_config().unwrap();
Expand All @@ -73,6 +77,7 @@ fn test_set_fee_config_max_creator_bps_succeeds() {
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);
let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);

client.set_fee_config(&admin, &10000u32, &0u32);
let config = client.get_fee_config().unwrap();
Expand All @@ -88,6 +93,7 @@ fn test_set_fee_config_creator_bps_above_max_fails() {
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);
let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);

let result = client.try_set_fee_config(&admin, &10001u32, &0u32);
assert_eq!(result, Err(Ok(ContractError::InvalidFeeConfig)));
Expand All @@ -101,6 +107,7 @@ fn test_set_fee_config_protocol_bps_above_max_fails() {
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);
let admin = soroban_sdk::Address::generate(&env);
client.set_protocol_admin(&admin, &admin);

let result = client.try_set_fee_config(&admin, &4999u32, &5001u32);
assert_eq!(result, Err(Ok(ContractError::ProtocolFeeExceedsCap)));
Expand Down
1 change: 1 addition & 0 deletions creator-keys/tests/identical_fee_configs_independent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ fn test_fee_config_update_does_not_affect_other_creator() {

// Update global fee config
let admin = Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
client.set_fee_config(&admin, &8000u32, &2000u32);

// Both creators should see the new fee config (since it's global)
Expand Down
4 changes: 4 additions & 0 deletions creator-keys/tests/initialization_event_fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ fn test_initialization_event_admin_matches_argument() {
let (client, _) = register_creator_keys(&env);

let admin = Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
let creator = Address::generate(&env);
let handle = String::from_str(&env, "test_handle");

Expand Down Expand Up @@ -50,6 +51,7 @@ fn test_initialization_event_protocol_fee_bps_matches_argument() {
let (client, _) = register_creator_keys(&env);

let admin = Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
let creator = Address::generate(&env);
let handle = String::from_str(&env, "test_handle");

Expand Down Expand Up @@ -89,6 +91,7 @@ fn test_initialization_event_protocol_fee_recipient_matches_argument() {
let (client, _) = register_creator_keys(&env);

let admin = Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
let creator = Address::generate(&env);
let handle = String::from_str(&env, "test_handle");

Expand Down Expand Up @@ -126,6 +129,7 @@ fn test_initialization_event_initialized_at_ledger_matches_current() {
let (client, _) = register_creator_keys(&env);

let admin = Address::generate(&env);
client.set_protocol_admin(&admin, &admin);
let creator = Address::generate(&env);
let handle = String::from_str(&env, "test_handle");

Expand Down
Loading
Loading