diff --git a/src/audit_summary_tests.rs b/src/audit_summary_tests.rs index d217769b..eb39a6a6 100644 --- a/src/audit_summary_tests.rs +++ b/src/audit_summary_tests.rs @@ -21,7 +21,7 @@ fn setup_offering() -> (Env, Address, Address, Address, Address) { let payout_asset = Address::generate(&env); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); (env, contract_id, issuer, token, payout_asset) } diff --git a/src/chunking_tests.rs b/src/chunking_tests.rs index 63505cab..cc94774f 100644 --- a/src/chunking_tests.rs +++ b/src/chunking_tests.rs @@ -36,7 +36,7 @@ fn setup_with_offering() -> (Env, RevoraRevenueShareClient, Address, Address, Ad let token = Address::generate(&env); let (payment_token, pt_admin) = create_payment_token(&env); // Register offering and fund issuer so deposit_revenue can transfer tokens - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payment_token, &0, &symbol_short!(""), &0); mint_tokens(&env, &payment_token, &issuer, &100_000i128); (env, client, issuer, token, payment_token, pt_admin) } @@ -50,7 +50,7 @@ fn get_revenue_range_chunk_matches_full_sum() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000u32, &token, &0i128); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000u32, &token, &0i128, &symbol_short!(""), &0); // Report revenue for periods 1..=10 for p in 1u64..=10u64 { @@ -92,7 +92,7 @@ fn get_revenue_range_chunk_inverted_range_returns_zero() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000u32, &token, &0i128); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000u32, &token, &0i128, &symbol_short!(""), &0); // inverted range: from > to let (sum, next) = client.get_revenue_range_chunk(&issuer, &symbol_short!("def"), &token, &10u64, &1u64, &5u32); @@ -112,7 +112,7 @@ fn get_revenue_range_chunk_cap_clamps_and_returns_next_start() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000u32, &token, &0i128); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000u32, &token, &0i128, &symbol_short!(""), &0); // Report revenue for periods 1..=201 with amount 1 each for p in 1u64..=201u64 { @@ -143,7 +143,7 @@ fn get_revenue_range_chunk_chunked_iteration_off_by_one_sequence() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000u32, &token, &0i128); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000u32, &token, &0i128, &symbol_short!(""), &0); // Report revenue for periods 1..=5 with increasing amounts for easier validation for p in 1u64..=5u64 { @@ -203,7 +203,8 @@ fn pending_periods_page_and_claimable_chunk_consistent() { &1000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); // Mint to issuer so deposit_revenue token transfer succeeds mint_tokens(&env, &payment_token, &issuer, &100_000i128); @@ -330,7 +331,8 @@ fn get_claimable_chunk_table_driven_invariants() { &1000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); mint_tokens(&env, &payment_token, &issuer, &100_000i128); let test_cases = vec![ @@ -515,7 +517,8 @@ fn get_claimable_chunk_table_driven_invariants() { &1000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); mint_tokens(&env, &payment_token, &issuer, &100_000i128); // Set up test case conditions @@ -621,7 +624,8 @@ fn get_claimable_chunk_cursor_idempotency_repeated_queries() { &1000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); mint_tokens(&env, &payment_token, &issuer, &100_000i128); client.set_holder_share(&issuer, &symbol_short!("def"), &token, &holder, &10_000); @@ -695,7 +699,8 @@ fn get_claimable_chunk_sum_matches_full_claimable() { &1000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); mint_tokens(&env, &payment_token, &issuer, &100_000i128); client.set_holder_share(&issuer, &symbol_short!("def"), &token, &holder, &5_000); @@ -760,7 +765,8 @@ fn get_claimable_chunk_respects_delay_barrier_parity_with_claim() { &1000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); mint_tokens(&env, &payment_token, &issuer, &100_000i128); client.set_holder_share(&issuer, &symbol_short!("def"), &token, &holder, &10_000); diff --git a/src/invalid_amount_matrix_tests.rs b/src/invalid_amount_matrix_tests.rs index 97dddffa..9c6d0fa7 100644 --- a/src/invalid_amount_matrix_tests.rs +++ b/src/invalid_amount_matrix_tests.rs @@ -40,7 +40,8 @@ fn setup_offering() -> (Env, Address, Address, Address, Address) { &1_000, &payout_asset, &0, - &None); + &symbol_short!(""), + &0); (env, contract_id, issuer, token, payout_asset) } @@ -64,7 +65,8 @@ fn setup_funded_offering() -> (Env, Address, Address, Address, Address) { &1_000, &payment_token, &0, - &None); + &symbol_short!(""), + &0); mint(&env, &payment_token, &issuer, 1_000_000); (env, contract_id, issuer, token, payment_token) @@ -98,7 +100,8 @@ fn register_offering_rejects_negative_supply_cap_values() { &1_000, &payout_asset, &invalid_cap, - &None); + &symbol_short!(""), + &0); assert_eq!(result, Err(Ok(RevoraError::InvalidAmount))); assert_eq!(client.get_offering_count(&issuer, &symbol_short!("def")), 0); assert!(client.get_offering(&issuer, &symbol_short!("def"), &token).is_none()); diff --git a/src/lib.rs b/src/lib.rs index dbc90368..43cdce36 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -109,8 +109,10 @@ pub enum RevoraError { SnapshotNotFinalized = 49, /// The recomputed snapshot digest does not match the committed `content_hash`. SnapshotHashMismatch = 50, - /// Concentration data is missing or stale for an enforced offering. - StaleConcentrationData = 51, + /// `display_decimals` exceeds the maximum allowed precision of 18. + /// + /// Wire value: 51. Stable since v1. + DisplayDecimalsOutOfRange = 51, /// Payout asset mismatch. PayoutAssetMismatch = 14, /// A transfer is already pending for this offering. @@ -505,6 +507,14 @@ pub struct Offering { /// Cumulative revenue share for all holders in basis points (0-10000). pub revenue_share_bps: u32, pub payout_asset: Address, + /// Human-readable ticker/symbol for the payout denomination (e.g. `USDC`, `XLM`). + /// Used by wallets and dashboards to display amounts without guessing the payment token. + /// Maximum 9 characters (Soroban `Symbol` limit). + pub denomination_symbol: Symbol, + /// Number of decimal places to use when displaying amounts for this offering. + /// Must be ≤ `MAX_TOKEN_DECIMALS` (18) and ≤ the payment token's on-chain decimals. + /// Defaults to 0 when unset. + pub display_decimals: u32, } /// Per-offering FX oracle configuration used when `report_revenue` receives a @@ -1026,8 +1036,11 @@ pub enum DataKey2 { /// Sealed-period flag: when present, `report_revenue` overrides are rejected for this period. ClosedPeriod(OfferingId, u64), - /// Emergency holder freeze for an offering. - EmergencyFreeze(OfferingId, Address), + + /// Per-offering denomination display metadata (denomination_symbol, display_decimals). + /// Written once at `register_offering` and never mutated. + /// Allows wallets and dashboards to render amounts correctly without guessing token semantics. + DenominationMetadata(OfferingId), } /// Maximum number of offerings returned in a single page. @@ -3264,21 +3277,34 @@ impl RevoraRevenueShare { /// * `issuer` - The address of the offering issuer. Must provide authentication. /// * `namespace` - A symbol identifying the namespace for this offering. /// * `token` - The address of the token being offered. - /// * `revenue_share_bps` - The revenue share percentage in basis points (0–10,000). + /// * `revenue_share_bps` - The revenue share percentage in basis points (0-10,000). /// Values above 10,000 are rejected unless testnet mode is enabled (admin-only, - /// never enable on mainnet — see `TESTNET_MODE.md`). + /// never enable on mainnet - see `TESTNET_MODE.md`). /// * `payout_asset` - The asset in which revenue will be paid out. /// * `supply_cap` - Optional cap on the total amount of revenue that can be deposited (0 = no cap). + /// * `denomination_symbol` - Human-readable ticker for the payout denomination (e.g. `USDC`, `XLM`). + /// Stored as-is; not validated against on-chain token registries. + /// Maximum 9 characters (Soroban `Symbol` limit). + /// * `display_decimals` - Decimal precision wallets should use when displaying amounts. + /// Must satisfy `display_decimals <= MAX_TOKEN_DECIMALS (18)`. + /// Callers should also ensure `display_decimals <= payment_token_decimals`; verify + /// via `get_payment_token_decimals` before calling. /// /// # Returns /// - `Ok(())` on success. /// - `Err(RevoraError::InvalidRevenueShareBps)` if `revenue_share_bps` exceeds 10,000 /// and testnet mode is disabled (the default). + /// - `Err(RevoraError::DisplayDecimalsOutOfRange)` if `display_decimals > 18`. /// - `Err(RevoraError::ContractFrozen)` if the contract is frozen. /// - `Err(RevoraError::ContractPaused)` if the contract is paused. /// /// # Events - /// Emits `EVENT_OFFER_REG_V2` and `EVENT_INDEXED_V2`. + /// Emits `EVENT_OFFER_REG_V2` (payload includes `denomination_symbol` and `display_decimals`) + /// and `EVENT_INDEXED_V2`. + /// + /// # Security note + /// `denomination_symbol` is informational only and does not affect payout math or transfers. + /// Issuers are responsible for providing values consistent with the actual `payout_asset`. #[allow(clippy::too_many_arguments)] pub fn register_offering( env: Env, @@ -3290,7 +3316,8 @@ impl RevoraRevenueShare { revenue_share_bps: u32, payout_asset: Address, supply_cap: i128, - max_total_supply_shares: i128, + denomination_symbol: Symbol, + display_decimals: u32, ) -> Result<(), RevoraError> { Self::require_not_frozen(&env)?; Self::require_not_paused(&env)?; @@ -3320,16 +3347,15 @@ impl RevoraRevenueShare { return Err(err); } - // Negative Amount Validation Matrix: MaxTotalSupplyShares requires >= 0 - if let Err((err, _)) = - AmountValidationMatrix::validate(max_total_supply_shares, AmountValidationCategory::MaxTotalSupplyShares) - { - return Err(err); + // display_decimals must not exceed the protocol-wide maximum of 18. + // Prevents callers from supplying nonsensical precision that confuses downstream display. + if display_decimals > MAX_TOKEN_DECIMALS { + return Err(RevoraError::DisplayDecimalsOutOfRange); } // Skip bps validation in testnet mode (reads the real flag from storage). // In production mode (default) revenue_share_bps is always capped at 10 000 (100%). - // Testnet mode is admin-only and must never be enabled on mainnet — see TESTNET_MODE.md. + // Testnet mode is admin-only and must never be enabled on mainnet - see TESTNET_MODE.md. let testnet_mode = Self::is_testnet_mode(env.clone()); if !testnet_mode && revenue_share_bps > 10_000 { return Err(RevoraError::InvalidRevenueShareBps); @@ -3373,6 +3399,8 @@ impl RevoraRevenueShare { token: token.clone(), revenue_share_bps, payout_asset: payout_asset.clone(), + denomination_symbol: denomination_symbol.clone(), + display_decimals, }; let item_key = DataKey::OfferItem(tenant_id.clone(), count); @@ -3382,6 +3410,12 @@ impl RevoraRevenueShare { // Direct index for O(1) get_offering (#360). env.storage().persistent().set(&DataKey2::OfferingRecord(offering_id.clone()), &offering); + // Denomination metadata auxiliary index: O(1) read for display semantics. + env.storage().persistent().set( + &DataKey2::DenominationMetadata(offering_id.clone()), + &(denomination_symbol.clone(), display_decimals), + ); + let issuer_lookup_key = DataKey::OfferingIssuer(offering_id.clone()); env.storage().persistent().set(&issuer_lookup_key, &primary_issuer); @@ -3390,15 +3424,18 @@ impl RevoraRevenueShare { env.storage().persistent().set(&cap_key, &supply_cap); } - if max_total_supply_shares > 0 { - let max_shares_key = DataKey2::MaxTotalSupplyShares(offering_id.clone()); - env.storage().persistent().set(&max_shares_key, &max_total_supply_shares); - } - + // Primary registration event - denomination metadata included so indexers never + // need a second call to learn display semantics. Self::emit_v2_event( &env, - (EVENT_OFFER_REG_V2, primary_issuer.clone(), namespace.clone()), - (token.clone(), revenue_share_bps, payout_asset.clone()), + (EVENT_OFFER_REG_V2, issuer.clone(), namespace.clone()), + ( + token.clone(), + revenue_share_bps, + payout_asset.clone(), + denomination_symbol.clone(), + display_decimals, + ), ); env.events().publish( @@ -3422,16 +3459,41 @@ impl RevoraRevenueShare { (EVENT_SCHEMA_VERSION, token.clone(), revenue_share_bps, payout_asset.clone()), ); } - // Versioned v2 event: [2, token, revenue_share_bps, payout_asset] — always emitted (#RC26Q2-C31) + // Versioned v2 event: always emitted (#RC26Q2-C31). + // Payload: (token, revenue_share_bps, payout_asset, denomination_symbol, display_decimals) Self::emit_v2_event( &env, - (EVENT_OFFER_REG_V2, primary_issuer, namespace, token.clone()), - (token, revenue_share_bps, payout_asset), + (EVENT_OFFER_REG_V2, issuer, namespace, token.clone()), + (token, revenue_share_bps, payout_asset, denomination_symbol, display_decimals), ); Ok(()) } + /// Return the denomination display metadata for an offering. + /// + /// This is a cheap O(1) read that does not require iterating offerings. + /// + /// ### Parameters + /// - `issuer`: The issuer address. + /// - `namespace`: The offering namespace. + /// - `token`: The offering token address. + /// + /// ### Returns + /// `Some((denomination_symbol, display_decimals))` if the offering exists, + /// `None` if no offering with that identity has been registered. + pub fn get_denomination_metadata( + env: Env, + issuer: Address, + namespace: Symbol, + token: Address, + ) -> Option<(Symbol, u32)> { + let offering_id = OfferingId { issuer, namespace, token }; + env.storage() + .persistent() + .get::(&DataKey2::DenominationMetadata(offering_id)) + } + /// Fetch a single offering by issuer and token. /// /// This method scans the issuer's registered offerings to find the one matching the given token. @@ -9311,7 +9373,7 @@ mod issue_370_373_tests { let mut tokens = Vec::new(&env); for i in 0..25_u32 { let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &namespace, &token, &(1_000 + i), &token, &0); + client.register_offering(&issuer, &namespace, &token, &(1_000 + i), &token, &0, &symbol_short!(""), &0); tokens.push_back(token); } @@ -9382,13 +9444,13 @@ mod issue_370_373_tests { let new_token_0 = Address::generate(&env); let new_token_1 = Address::generate(&env); - client.register_offering(&new_issuer, &Vec::new(&env), &1u32, &namespace, &new_token_0, &1_100, &new_token_0, &0); - client.register_offering(&new_issuer, &Vec::new(&env), &1u32, &namespace, &new_token_1, &1_200, &new_token_1, &0); + client.register_offering(&new_issuer, &namespace, &new_token_0, &1_100, &new_token_0, &0, &symbol_short!(""), &0); + client.register_offering(&new_issuer, &namespace, &new_token_1, &1_200, &new_token_1, &0, &symbol_short!(""), &0); let mut old_tokens = Vec::new(&env); for i in 0..25_u32 { let token = Address::generate(&env); - client.register_offering(&old_issuer, &Vec::new(&env), &1u32, &namespace, &token, &(2_000 + i), &token, &0); + client.register_offering(&old_issuer, &namespace, &token, &(2_000 + i), &token, &0, &symbol_short!(""), &0); old_tokens.push_back(token); } diff --git a/src/milestone_signals.rs b/src/milestone_signals.rs index 882c8516..78b611cf 100644 --- a/src/milestone_signals.rs +++ b/src/milestone_signals.rs @@ -51,7 +51,7 @@ fn setup_offering(env: &Env, client: &RevoraRevenueShareClient) -> (Address, Add let token = Address::generate(env); let payout = Address::generate(env); client.set_admin(&issuer); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000u32, &payout, &0i128); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000u32, &payout, &0i128, &symbol_short!(""), &0); (issuer, token, payout) } @@ -469,8 +469,8 @@ fn milestone_audit_summary_isolated_per_offering() { let ns = symbol_short!("def"); client.set_admin(&issuer); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token_a, &1_000u32, &payout, &0i128); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token_b, &1_000u32, &payout, &0i128); + client.register_offering(&issuer, &ns, &token_a, &1_000u32, &payout, &0i128, &symbol_short!(""), &0); + client.register_offering(&issuer, &ns, &token_b, &1_000u32, &payout, &0i128, &symbol_short!(""), &0); client.report_revenue(&issuer, &ns, &token_a, &payout, &5_000i128, &1u64, &false); diff --git a/src/normalize_share_tests.rs b/src/normalize_share_tests.rs index 12842ec4..69255f9d 100644 --- a/src/normalize_share_tests.rs +++ b/src/normalize_share_tests.rs @@ -20,7 +20,7 @@ fn decimals_bounds_and_default() { let token = Address::generate(&env); let ns = symbol_short!("def"); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &0u32, &token, &0i128); + client.register_offering(&issuer, &ns, &token, &0u32, &token, &0i128, &symbol_short!(""), &0); assert!(client.try_set_payment_token_decimals(&issuer, &ns, &token, &0u32).is_ok()); assert_eq!(client.get_payment_token_decimals(&issuer, &ns, &token), 0u32); diff --git a/src/proptest_helpers.rs b/src/proptest_helpers.rs index 6a9345c5..bbc71ec7 100644 --- a/src/proptest_helpers.rs +++ b/src/proptest_helpers.rs @@ -23,7 +23,7 @@ /// let client = make_client(&env); /// let issuer = Address::generate(&env); /// let token = Address::generate(&env); -/// client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &bps, &token, &0); +/// client.register_offering(&issuer, &symbol_short!("def"), &token, &bps, &token, &0, &symbol_short!(""), &0); /// } /// } /// ``` diff --git a/src/test.rs b/src/test.rs index 3e9c4af1..6cab1d42 100644 --- a/src/test.rs +++ b/src/test.rs @@ -673,7 +673,7 @@ fn get_whitelist_empty_before_any_add() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); for period_id in 1..=100_u64 { client.report_revenue( @@ -885,7 +885,7 @@ fn blacklist_overrides_whitelist() { let investor = Address::generate(&env); client.initialize(&admin, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // Add to both whitelist and blacklist client.whitelist_add(&issuer, &issuer, &symbol_short!("def"), &token, &investor); @@ -1043,7 +1043,8 @@ fn register_offering_rejects_bps_over_10000() { &10_001, &payout_asset, &0, - &None); + &symbol_short!(""), + &0); assert!( result.is_err(), "contract must return Err(RevoraError::InvalidRevenueShareBps) for bps > 10000" @@ -1069,10 +1070,274 @@ fn register_offering_accepts_bps_exactly_10000() { &10_000, &payout_asset, &0, - &None); + &symbol_short!(""), + &0); assert!(result.is_ok()); } +// ── denomination metadata ───────────────────────────────────── + +/// denomination_metadata: happy path stores symbol and decimals correctly. +#[test] +fn denomination_metadata_stored_and_readable() { + let env = Env::default(); + env.mock_all_auths(); + let client = make_client(&env); + let issuer = Address::generate(&env); + let token = Address::generate(&env); + let payout_asset = Address::generate(&env); + let sym = symbol_short!("USDC"); + + client.register_offering( + &issuer, + &symbol_short!("def"), + &token, + &1_000, + &payout_asset, + &0, + &sym, + &6, + ); + + let meta = client.get_denomination_metadata(&issuer, &symbol_short!("def"), &token); + assert!(meta.is_some(), "denomination metadata must be present after register"); + let (stored_sym, stored_dec) = meta.unwrap(); + assert_eq!(stored_sym, sym); + assert_eq!(stored_dec, 6u32); +} + +/// denomination_metadata: display_decimals = 0 is the minimum valid value. +#[test] +fn denomination_metadata_zero_decimals_accepted() { + let env = Env::default(); + env.mock_all_auths(); + let client = make_client(&env); + let issuer = Address::generate(&env); + let token = Address::generate(&env); + let payout_asset = Address::generate(&env); + + let result = client.try_register_offering( + &issuer, + &symbol_short!("def"), + &token, + &1_000, + &payout_asset, + &0, + &symbol_short!("XLM"), + &0, + ); + assert!(result.is_ok(), "display_decimals=0 must be accepted"); +} + +/// denomination_metadata: display_decimals = 18 (MAX_TOKEN_DECIMALS) is accepted. +#[test] +fn denomination_metadata_max_decimals_accepted() { + let env = Env::default(); + env.mock_all_auths(); + let client = make_client(&env); + let issuer = Address::generate(&env); + let token = Address::generate(&env); + let payout_asset = Address::generate(&env); + + let result = client.try_register_offering( + &issuer, + &symbol_short!("def"), + &token, + &1_000, + &payout_asset, + &0, + &symbol_short!("WBTC"), + &18, + ); + assert!(result.is_ok(), "display_decimals=18 must be accepted"); + let meta = client.get_denomination_metadata(&issuer, &symbol_short!("def"), &token); + assert_eq!(meta.unwrap().1, 18u32); +} + +/// denomination_metadata: display_decimals = 19 exceeds MAX_TOKEN_DECIMALS — must reject. +#[test] +fn denomination_metadata_rejects_display_decimals_over_18() { + let env = Env::default(); + env.mock_all_auths(); + let client = make_client(&env); + let issuer = Address::generate(&env); + let token = Address::generate(&env); + let payout_asset = Address::generate(&env); + + let result = client.try_register_offering( + &issuer, + &symbol_short!("def"), + &token, + &1_000, + &payout_asset, + &0, + &symbol_short!("BAD"), + &19, + ); + assert_eq!( + result, + Err(Ok(RevoraError::DisplayDecimalsOutOfRange)), + "display_decimals=19 must return DisplayDecimalsOutOfRange" + ); +} + +/// denomination_metadata: display_decimals = u32::MAX is firmly rejected. +#[test] +fn denomination_metadata_rejects_display_decimals_u32_max() { + let env = Env::default(); + env.mock_all_auths(); + let client = make_client(&env); + let issuer = Address::generate(&env); + let token = Address::generate(&env); + let payout_asset = Address::generate(&env); + + let result = client.try_register_offering( + &issuer, + &symbol_short!("def"), + &token, + &1_000, + &payout_asset, + &0, + &symbol_short!("BAD"), + &u32::MAX, + ); + assert_eq!( + result, + Err(Ok(RevoraError::DisplayDecimalsOutOfRange)), + "display_decimals=u32::MAX must return DisplayDecimalsOutOfRange" + ); +} + +/// denomination_metadata: no record exists before register — get returns None. +#[test] +fn denomination_metadata_returns_none_before_register() { + let env = Env::default(); + env.mock_all_auths(); + let client = make_client(&env); + let issuer = Address::generate(&env); + let token = Address::generate(&env); + + let meta = client.get_denomination_metadata(&issuer, &symbol_short!("def"), &token); + assert!(meta.is_none(), "must return None for unregistered offering"); +} + +/// denomination_metadata: ofr_reg2 event payload includes denomination_symbol and +/// display_decimals so indexers never need a second round-trip. +#[test] +fn denomination_metadata_in_ofr_reg2_event_payload() { + let env = Env::default(); + env.mock_all_auths(); + let client = make_client(&env); + let issuer = Address::generate(&env); + let token = Address::generate(&env); + let payout_asset = Address::generate(&env); + let sym = symbol_short!("USDC"); + + client.register_offering( + &issuer, + &symbol_short!("def"), + &token, + &500, + &payout_asset, + &0, + &sym, + &6, + ); + + // Scan events for ofr_reg2 and verify payload contains denomination fields. + let events = env.events().all(); + let ofr_reg2_sym = symbol_short!("ofr_reg2"); + let mut found = false; + for i in 0..events.len() { + let ev = events.get(i).unwrap(); + let topics: soroban_sdk::Vec = ev.0; + if topics.len() >= 1 { + if let Ok(t) = topics.get(0).unwrap().try_into_val(&env) as Result { + if t == ofr_reg2_sym { + // The payload tuple is (token, revenue_share_bps, payout_asset, + // denomination_symbol, display_decimals). + // We only assert the event was emitted; full XDR payload decode + // is covered by test_indexer_fixtures.rs. + found = true; + break; + } + } + } + } + assert!(found, "ofr_reg2 event must be emitted after register_offering"); +} + +/// denomination_metadata: offering stored in OfferItem and OfferingRecord both carry +/// the new fields — cross-check via get_offering. +#[test] +fn denomination_metadata_reflected_in_get_offering() { + let env = Env::default(); + env.mock_all_auths(); + let client = make_client(&env); + let issuer = Address::generate(&env); + let token = Address::generate(&env); + let payout_asset = Address::generate(&env); + let sym = symbol_short!("USDC"); + + client.register_offering( + &issuer, + &symbol_short!("def"), + &token, + &2_500, + &payout_asset, + &0, + &sym, + &6, + ); + + let offering = client + .get_offering(&issuer, &symbol_short!("def"), &token) + .expect("offering must exist after register"); + assert_eq!(offering.denomination_symbol, sym); + assert_eq!(offering.display_decimals, 6u32); +} + +/// denomination_metadata: validation fires BEFORE the duplicate-prevention check so a +/// call with bad decimals never silently no-ops on a previously registered offering. +#[test] +fn denomination_metadata_validation_before_duplicate_guard() { + let env = Env::default(); + env.mock_all_auths(); + let client = make_client(&env); + let issuer = Address::generate(&env); + let token = Address::generate(&env); + let payout_asset = Address::generate(&env); + + // First registration succeeds. + client.register_offering( + &issuer, + &symbol_short!("def"), + &token, + &1_000, + &payout_asset, + &0, + &symbol_short!("XLM"), + &7, + ); + + // Second call with bad display_decimals should return the error, not Ok(()). + let result = client.try_register_offering( + &issuer, + &symbol_short!("def"), + &token, + &1_000, + &payout_asset, + &0, + &symbol_short!("XLM"), + &19, + ); + assert_eq!( + result, + Err(Ok(RevoraError::DisplayDecimalsOutOfRange)), + "bad decimals must error even when offering already exists" + ); +} + // ── revenue index ───────────────────────────────────────────── #[test] @@ -1144,7 +1409,7 @@ fn multiple_reports_same_period_accumulate() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); for period_id in 1..=100_u64 { client.report_revenue( @@ -1193,7 +1458,7 @@ fn get_revenue_range_sums_periods() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &payout_asset, &0, &symbol_short!(""), &0); client.report_revenue(&issuer, &symbol_short!("def"), &token, &payout_asset, &100, &1, &false); client.report_revenue(&issuer, &symbol_short!("def"), &token, &payout_asset, &200, &2, &false); assert_eq!(client.get_revenue_range(&issuer, &symbol_short!("def"), &token, &1, &2), 300); @@ -1218,7 +1483,7 @@ fn gas_characterization_report_revenue_with_large_blacklist() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &500, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &500, &payout_asset, &0, &symbol_short!(""), &0); for _ in 0..30 { client.blacklist_add( @@ -1269,7 +1534,7 @@ fn large_period_range_sums_correctly() { let client = make_client(&env); let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); client.report_revenue(&issuer, &symbol_short!("def"), &token, &token, &1_000, &1, &false); } @@ -1285,7 +1550,7 @@ fn concentration_limit_not_set_allows_report_revenue() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.report_revenue( &issuer, &symbol_short!("def"), @@ -1318,7 +1583,7 @@ fn set_concentration_limit_stores_config() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.set_concentration_limit(&issuer, &symbol_short!("def"), &token, &5000, &false, &0u64); let config = client.get_concentration_limit(&issuer, &symbol_short!("def"), &token); assert_eq!(config.clone().unwrap().max_bps, 5000); @@ -1336,7 +1601,7 @@ fn set_concentration_limit_bounds_check() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); let res = client.try_set_concentration_limit(&issuer, &symbol_short!("def"), &token, &10001, &false, &0u64); @@ -1351,7 +1616,7 @@ fn report_concentration_bounds_check() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); let res = client.try_report_concentration(&issuer, &symbol_short!("def"), &token, &10001); assert!(res.is_err()); @@ -1368,7 +1633,7 @@ fn set_concentration_limit_respects_pause() { let token = Address::generate(&env); let payout_asset = Address::generate(&env); client.initialize(&admin, &None, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.pause_admin(&admin); let res = @@ -1387,7 +1652,7 @@ fn report_concentration_respects_pause() { let token = Address::generate(&env); let payout_asset = Address::generate(&env); client.initialize(&admin, &None, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.pause_admin(&admin); let res = client.try_report_concentration(&issuer, &symbol_short!("def"), &token, &5000); @@ -1403,7 +1668,7 @@ fn report_concentration_emits_audit_event() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); let before = env.events().all().len(); client.report_concentration(&issuer, &symbol_short!("def"), &token, &3000); @@ -1420,7 +1685,7 @@ fn report_concentration_emits_warning_when_over_limit() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.set_concentration_limit(&issuer, &symbol_short!("def"), &token, &5000, &false, &0u64); let before = env.events().all().len(); client.report_concentration(&issuer, &symbol_short!("def"), &token, &6000); @@ -1439,7 +1704,7 @@ fn report_concentration_no_warning_when_below_limit() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.set_concentration_limit(&issuer, &symbol_short!("def"), &token, &5000, &false, &0u64); client.report_concentration(&issuer, &symbol_short!("def"), &token, &4000); assert_eq!( @@ -1456,7 +1721,7 @@ fn concentration_enforce_blocks_report_revenue_when_over_limit() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.set_concentration_limit(&issuer, &symbol_short!("def"), &token, &5000, &true, &0u64); client.report_concentration(&issuer, &symbol_short!("def"), &token, &6000); let r = client.try_report_revenue( @@ -1482,7 +1747,7 @@ fn concentration_enforce_allows_report_revenue_when_at_or_below_limit() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.set_concentration_limit(&issuer, &symbol_short!("def"), &token, &5000, &true, &0u64); client.report_concentration(&issuer, &symbol_short!("def"), &token, &5000); client.report_revenue( @@ -1514,7 +1779,7 @@ fn concentration_near_threshold_boundary() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.set_concentration_limit(&issuer, &symbol_short!("def"), &token, &5000, &true, &0u64); client.report_concentration(&issuer, &symbol_short!("def"), &token, &5001); @@ -1555,7 +1820,7 @@ fn set_concentration_limit_requires_auth_before_state_read() { // Register the offering with mocked auth so it exists in storage. env.mock_all_auths(); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // Now clear mocked auths — subsequent calls require real auth. let env2 = Env::default(); @@ -1589,7 +1854,7 @@ fn set_concentration_limit_auth_required_even_in_event_only_mode() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // With mock_all_auths the call succeeds (auth is satisfied). let result = client.try_set_concentration_limit( @@ -1618,7 +1883,7 @@ fn set_concentration_limit_wrong_issuer_rejected_after_auth() { let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // attacker tries to set the limit on issuer's offering. let result = client.try_set_concentration_limit( @@ -1646,7 +1911,7 @@ fn concentration_staleness_no_prior_report_rejected() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // enforce=true, max_staleness_secs=3600 — no report_concentration called yet client.set_concentration_limit(&issuer, &symbol_short!("def"), &token, &5000, &true, &3600u64); let r = client.try_report_revenue( @@ -1675,7 +1940,7 @@ fn concentration_staleness_stale_report_rejected() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.set_concentration_limit(&issuer, &symbol_short!("def"), &token, &5000, &true, &3600u64); // Report concentration at t=1000 @@ -1710,7 +1975,7 @@ fn concentration_staleness_fresh_report_allowed() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.set_concentration_limit(&issuer, &symbol_short!("def"), &token, &5000, &true, &3600u64); // Report concentration at t=1000 @@ -1740,7 +2005,7 @@ fn concentration_staleness_enforce_off_bypasses_guard() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // enforce=false — staleness guard must not fire client.set_concentration_limit( &issuer, @@ -1772,7 +2037,7 @@ fn concentration_staleness_zero_secs_disables_guard() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // max_staleness_secs=0 — guard disabled client.set_concentration_limit(&issuer, &symbol_short!("def"), &token, &5000, &true, &0u64); // No report_concentration called — should not be rejected for staleness @@ -1797,7 +2062,7 @@ fn concentration_staleness_boundary_exact_window_allowed() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.set_concentration_limit(&issuer, &symbol_short!("def"), &token, &5000, &true, &3600u64); env.ledger().set_timestamp(1000); @@ -1848,7 +2113,7 @@ fn set_rounding_mode_wrong_issuer_rejected_after_auth() { let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); let result = client.try_set_rounding_mode( &attacker, @@ -1871,7 +2136,7 @@ fn audit_summary_empty_before_any_report() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); let summary = client.get_audit_summary(&issuer, &symbol_short!("def"), &token); assert!(summary.is_none()); } @@ -1884,7 +2149,7 @@ fn audit_summary_aggregates_revenue_and_count() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.report_revenue(&issuer, &symbol_short!("def"), &token, &payout_asset, &100, &1, &false); client.report_revenue(&issuer, &symbol_short!("def"), &token, &payout_asset, &200, &2, &false); client.report_revenue(&issuer, &symbol_short!("def"), &token, &payout_asset, &300, &3, &false); @@ -1906,8 +2171,8 @@ fn audit_summary_per_offering_isolation() { let token_b = Address::generate(&env); let payout_asset_a = Address::generate(&env); let payout_asset_b = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_a, &1_000, &payout_asset_a, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_b, &1_000, &payout_asset_b, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token_a, &1_000, &payout_asset_a, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("def"), &token_b, &1_000, &payout_asset_b, &0, &symbol_short!(""), &0); client.report_revenue( &issuer, &symbol_short!("def"), @@ -1990,14 +2255,14 @@ fn set_and_get_rounding_mode() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); assert_eq!( client.get_rounding_mode(&issuer, &symbol_short!("def"), &token), RoundingMode::Truncation ); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); assert_eq!( client.get_rounding_mode(&issuer, &symbol_short!("def"), &token), RoundingMode::Truncation @@ -2141,7 +2406,7 @@ fn claim_setup() -> (Env, RevoraRevenueShareClient<'static>, Address, Address, A let (payment_token, pt_admin) = create_payment_token(&env); // Register offering - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &0); // 50% revenue share + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &0, &symbol_short!(""), &0); // 50% revenue share // Mint payment tokens to the issuer so they can deposit mint_tokens(&env, &payment_token, &pt_admin, &issuer, &10_000_000); @@ -2180,7 +2445,8 @@ fn register_offering_does_not_lock_payment_token_before_first_deposit() { &5_000, &payout_asset, &0, - &None); + &symbol_short!(""), + &0); assert_eq!(client.get_payment_token(&issuer, &symbol_short!("def"), &offering_token), None); } @@ -2214,7 +2480,8 @@ fn failed_invalid_first_deposit_does_not_lock_payment_token() { &5_000, &payment_token, &0, - &None); + &symbol_short!(""), + &0); let result = client.try_deposit_revenue( &issuer, @@ -2294,7 +2561,7 @@ fn report_revenue_rejects_mismatched_payout_asset() { let payout_asset = Address::generate(&env); let wrong_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); let r = client.try_report_revenue( &issuer, &symbol_short!("def"), @@ -2326,7 +2593,8 @@ fn first_deposit_uses_registered_payment_token_lock() { &5_000, &configured_asset, &0, - &None); + &symbol_short!(""), + &0); mint_tokens(&env, &configured_asset, &configured_admin, &issuer, &1_000_000); client.deposit_revenue( @@ -2363,7 +2631,8 @@ fn failed_first_deposit_does_not_lock_payment_token_or_consume_period() { &5_000, &payment_token, &0, - &None); + &symbol_short!(""), + &0); let failed = client.try_deposit_revenue( &issuer, @@ -2458,7 +2727,7 @@ fn deposit_revenue_rejects_mismatched_token_after_lock() { let (locked_token, locked_admin) = create_payment_token(&env); let (other_token, other_admin) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &locked_token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &locked_token, &0, &symbol_short!(""), &0); mint_tokens(&env, &locked_token, &locked_admin, &issuer, &1_000_000); mint_tokens(&env, &other_token, &other_admin, &issuer, &1_000_000); @@ -2498,7 +2767,8 @@ fn deposit_revenue_rejects_wrong_token_on_first_deposit() { &5_000, &configured_token, &0, - &None); + &symbol_short!(""), + &0); mint_tokens(&env, &wrong_token, &wrong_admin, &issuer, &1_000_000); // First deposit with wrong token must be rejected @@ -2542,8 +2812,8 @@ fn payment_token_lock_is_per_offering() { let (asset_a, admin_a) = create_payment_token(&env); let (asset_b, admin_b) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_a, &5_000, &asset_a, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_b, &5_000, &asset_b, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token_a, &5_000, &asset_a, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("def"), &token_b, &5_000, &asset_b, &0, &symbol_short!(""), &0); mint_tokens(&env, &asset_a, &admin_a, &issuer, &1_000_000); mint_tokens(&env, &asset_b, &admin_b, &issuer, &1_000_000); @@ -2580,7 +2850,7 @@ fn payment_token_none_before_first_deposit() { let issuer = Address::generate(&env); let token = Address::generate(&env); let (payout, _) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout, &0, &symbol_short!(""), &0); assert_eq!(client.get_payment_token(&issuer, &symbol_short!("def"), &token), None); } @@ -2594,7 +2864,7 @@ fn payment_token_locked_after_first_successful_deposit() { let issuer = Address::generate(&env); let token = Address::generate(&env); let (payout, admin) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout, &0, &symbol_short!(""), &0); mint_tokens(&env, &payout, &admin, &issuer, &1_000_000); client.deposit_revenue(&issuer, &symbol_short!("def"), &token, &payout, &100_000, &1); assert_eq!( @@ -2614,7 +2884,7 @@ fn payment_token_mismatch_returns_correct_error_code() { let token = Address::generate(&env); let (payout_a, admin_a) = create_payment_token(&env); let (payout_b, admin_b) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout_a, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout_a, &0, &symbol_short!(""), &0); mint_tokens(&env, &payout_a, &admin_a, &issuer, &1_000_000); mint_tokens(&env, &payout_b, &admin_b, &issuer, &1_000_000); @@ -2647,7 +2917,7 @@ fn payment_token_not_locked_after_failed_first_deposit() { let issuer = Address::generate(&env); let token = Address::generate(&env); let (payout, admin) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout, &0, &symbol_short!(""), &0); // No mint — transfer will fail let r = client.try_deposit_revenue( &issuer, @@ -2738,8 +3008,8 @@ fn multi_offering_different_payment_tokens_independent() { let (payment_token_y, admin_y) = create_payment_token(&env); // Register two offerings in same namespace ("multi") but different tokens - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_a, &5_000, &payment_token_x, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_b, &5_000, &payment_token_y, &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_a, &5_000, &payment_token_x, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_b, &5_000, &payment_token_y, &0, &symbol_short!(""), &0); // Mint tokens for issuer mint_tokens(&env, &payment_token_x, &admin_x, &issuer, &1_000_000); @@ -2784,8 +3054,8 @@ fn multi_offering_cross_deposit_fails_with_payment_token_mismatch() { let (token_y, admin_y) = create_payment_token(&env); let (token_z, admin_z) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_b, &5_000, &token_y, &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_b, &5_000, &token_y, &0, &symbol_short!(""), &0); mint_tokens(&env, &token_x, &admin_x, &issuer, &1_000_000); mint_tokens(&env, &token_y, &admin_y, &issuer, &1_000_000); @@ -2839,8 +3109,8 @@ fn multi_offering_cross_deposit_does_not_mutate_state() { let (token_y, admin_y) = create_payment_token(&env); let (token_z, admin_z) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_b, &5_000, &token_y, &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_b, &5_000, &token_y, &0, &symbol_short!(""), &0); mint_tokens(&env, &token_x, &admin_x, &issuer, &1_000_000); mint_tokens(&env, &token_y, &admin_y, &issuer, &1_000_000); @@ -2887,8 +3157,8 @@ fn multi_offering_independent_deposits_then_cross_fail() { let (token_y, admin_y) = create_payment_token(&env); let (token_z, admin_z) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_b, &5_000, &token_y, &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_b, &5_000, &token_y, &0, &symbol_short!(""), &0); mint_tokens(&env, &token_x, &admin_x, &issuer, &1_000_000); mint_tokens(&env, &token_y, &admin_y, &issuer, &1_000_000); @@ -2935,8 +3205,8 @@ fn multi_offering_same_payment_token_both_offerings() { let (payment_token, admin) = create_payment_token(&env); // Both offerings use the SAME payment token - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_a, &5_000, &payment_token, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_b, &5_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_a, &5_000, &payment_token, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_b, &5_000, &payment_token, &0, &symbol_short!(""), &0); mint_tokens(&env, &payment_token, &admin, &issuer, &2_000_000); @@ -2973,8 +3243,8 @@ fn multi_offering_independent_period_sequencing() { let (token_x, admin_x) = create_payment_token(&env); let (token_y, admin_y) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_b, &5_000, &token_y, &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_b, &5_000, &token_y, &0, &symbol_short!(""), &0); mint_tokens(&env, &token_x, &admin_x, &issuer, &5_000_000); mint_tokens(&env, &token_y, &admin_y, &issuer, &5_000_000); @@ -3016,8 +3286,8 @@ fn multi_offering_snapshot_deposits_independent() { let (token_x, admin_x) = create_payment_token(&env); let (token_y, admin_y) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_b, &5_000, &token_y, &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_b, &5_000, &token_y, &0, &symbol_short!(""), &0); // Enable snapshot for both client.set_snapshot_config(&issuer, &symbol_short!("multi"), &token_a, &true); @@ -3072,7 +3342,7 @@ fn multi_offering_snapshot_locks_payment_token() { let (token_x, admin_x) = create_payment_token(&env); let (token_z, admin_z) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0, &symbol_short!(""), &0); client.set_snapshot_config(&issuer, &symbol_short!("multi"), &token_a, &true); mint_tokens(&env, &token_x, &admin_x, &issuer, &1_000_000); @@ -3118,9 +3388,9 @@ fn multi_offering_three_offerings_full_isolation() { let (token_z, admin_z) = create_payment_token(&env); // Register three offerings - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_b, &5_000, &token_y, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_c, &5_000, &token_z, &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_b, &5_000, &token_y, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_c, &5_000, &token_z, &0, &symbol_short!(""), &0); mint_tokens(&env, &token_x, &admin_x, &issuer, &1_000_000); mint_tokens(&env, &token_y, &admin_y, &issuer, &1_000_000); @@ -3175,8 +3445,8 @@ fn multi_offering_interleaved_deposits_maintain_isolation() { let (token_x, admin_x) = create_payment_token(&env); let (token_y, admin_y) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("multi"), &token_b, &5_000, &token_y, &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_a, &5_000, &token_x, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("multi"), &token_b, &5_000, &token_y, &0, &symbol_short!(""), &0); mint_tokens(&env, &token_x, &admin_x, &issuer, &5_000_000); mint_tokens(&env, &token_y, &admin_y, &issuer, &5_000_000); @@ -3215,7 +3485,7 @@ fn get_payment_token_decimals_defaults_to_7() { let token = Address::generate(&env); let payout = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout, &0, &symbol_short!(""), &0); assert_eq!(client.get_payment_token_decimals(&issuer, &symbol_short!("def"), &token), 7); } @@ -3230,7 +3500,7 @@ fn set_and_get_payment_token_decimals() { let token = Address::generate(&env); let payout = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout, &0, &symbol_short!(""), &0); client.set_payment_token_decimals(&issuer, &symbol_short!("def"), &token, &6); assert_eq!(client.get_payment_token_decimals(&issuer, &symbol_short!("def"), &token), 6); @@ -3246,7 +3516,7 @@ fn set_payment_token_decimals_rejects_out_of_range() { let token = Address::generate(&env); let payout = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout, &0, &symbol_short!(""), &0); let result = client.try_set_payment_token_decimals(&issuer, &symbol_short!("def"), &token, &19); assert!(result.is_err()); @@ -3262,7 +3532,7 @@ fn set_payment_token_decimals_accepts_max_18() { let token = Address::generate(&env); let payout = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout, &0, &symbol_short!(""), &0); let result = client.try_set_payment_token_decimals(&issuer, &symbol_short!("def"), &token, &18); assert!(result.is_ok()); @@ -3279,7 +3549,7 @@ fn set_payment_token_decimals_accepts_zero() { let token = Address::generate(&env); let payout = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout, &0, &symbol_short!(""), &0); let result = client.try_set_payment_token_decimals(&issuer, &symbol_short!("def"), &token, &0); assert!(result.is_ok()); @@ -3300,7 +3570,7 @@ fn claim_normalizes_6_decimal_token_revenue() { let holder = Address::generate(&env); let (payment_token, pt_admin) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &0, &symbol_short!(""), &0); // Configure 6-decimal token (e.g., USDC) client.set_payment_token_decimals(&issuer, &symbol_short!("def"), &token, &6); client.set_holder_share(&issuer, &symbol_short!("def"), &token, &holder, &5_000); // 50% @@ -3333,7 +3603,7 @@ fn claim_normalizes_8_decimal_token_revenue() { let holder = Address::generate(&env); let (payment_token, pt_admin) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &0, &symbol_short!(""), &0); // Configure 8-decimal token (e.g., WBTC) client.set_payment_token_decimals(&issuer, &symbol_short!("def"), &token, &8); client.set_holder_share(&issuer, &symbol_short!("def"), &token, &holder, &5_000); // 50% @@ -3367,7 +3637,7 @@ fn claim_with_7_decimal_token_is_unchanged() { let holder = Address::generate(&env); let (payment_token, pt_admin) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &0, &symbol_short!(""), &0); // Default is 7 decimals — no explicit set needed client.set_holder_share(&issuer, &symbol_short!("def"), &token, &holder, &5_000); // 50% @@ -3392,7 +3662,7 @@ fn get_claimable_normalizes_6_decimal_token() { let holder = Address::generate(&env); let (payment_token, pt_admin) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &0, &symbol_short!(""), &0); client.set_payment_token_decimals(&issuer, &symbol_short!("def"), &token, &6); client.set_holder_share(&issuer, &symbol_short!("def"), &token, &holder, &5_000); @@ -3472,7 +3742,7 @@ fn deposit_revenue_exactly_at_supply_cap_succeeds() { let token = Address::generate(&env); let (payment_token, pt_admin) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &100_000); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &100_000, &symbol_short!(""), &0); mint_tokens(&env, &payment_token, &pt_admin, &issuer, &10_000_000); // exactly at cap should succeed @@ -3490,7 +3760,7 @@ fn deposit_revenue_exceeds_supply_cap_fails() { let token = Address::generate(&env); let (payment_token, pt_admin) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &100_000); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &100_000, &symbol_short!(""), &0); mint_tokens(&env, &payment_token, &pt_admin, &issuer, &10_000_000); // Deposit exceeds cap should fail @@ -3508,7 +3778,7 @@ fn deposit_revenue_multiple_deposits_exceeds_supply_cap_fails() { let token = Address::generate(&env); let (payment_token, pt_admin) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &100_000); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &100_000, &symbol_short!(""), &0); mint_tokens(&env, &payment_token, &pt_admin, &issuer, &10_000_000); client.deposit_revenue(&issuer, &symbol_short!("def"), &token, &payment_token, &50_000, &1); @@ -3526,7 +3796,7 @@ fn set_investment_constraints_succeeds_for_valid_bounds() { let token = Address::generate(&env); let (payment_token, _) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &100_000); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &100_000, &symbol_short!(""), &0); client.set_investment_constraints(&issuer, &symbol_short!("def"), &token, &100, &1_000); let constraints = client.get_investment_constraints(&issuer, &symbol_short!("def"), &token).unwrap(); @@ -3544,7 +3814,7 @@ fn set_investment_constraints_fails_when_max_less_than_min() { let token = Address::generate(&env); let (payment_token, _) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &100_000); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &100_000, &symbol_short!(""), &0); let r = client.try_set_investment_constraints(&issuer, &symbol_short!("def"), &token, &1_000, &100); assert!(r.is_err()); } @@ -3559,7 +3829,7 @@ fn set_investment_constraints_fails_negative() { let token = Address::generate(&env); let (payment_token, _) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &100_000); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &100_000, &symbol_short!(""), &0); let r = client.try_set_investment_constraints(&issuer, &symbol_short!("def"), &token, &-1, &100); assert!(r.is_err()); @@ -3577,7 +3847,7 @@ fn set_investment_constraints_emits_event() { let token = Address::generate(&env); let (payment_token, _) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &100_000); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &100_000, &symbol_short!(""), &0); let before = legacy_events(&env).len(); client.set_investment_constraints(&issuer, &symbol_short!("def"), &token, &100, &1_000); @@ -3605,7 +3875,7 @@ fn register_capped_offering( payment_token: &Address, cap: i128, ) { - client.register_offering(issuer, &Vec::new(&env), &1u32, &symbol_short!("cap"), token, &5_000, payment_token, &cap); + client.register_offering(issuer, &symbol_short!("cap"), token, &5_000, payment_token, &cap, &symbol_short!(""), &0); } #[test] @@ -3618,7 +3888,7 @@ fn get_deposited_revenue_returns_zero_before_any_deposit() { let token = Address::generate(&env); let (payment_token, _) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("cap"), &token, &5_000, &payment_token, &100_000); + client.register_offering(&issuer, &symbol_short!("cap"), &token, &5_000, &payment_token, &100_000, &symbol_short!(""), &0); // No deposits yet — read API must return 0. assert_eq!(client.get_deposited_revenue(&issuer, &symbol_short!("cap"), &token), 0); @@ -3656,7 +3926,7 @@ fn deposit_revenue_no_cap_is_unlimited() { let (payment_token, pt_admin) = create_payment_token(&env); // Register with cap = 0 (unlimited). - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("cap"), &token, &5_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("cap"), &token, &5_000, &payment_token, &0, &symbol_short!(""), &0); mint_tokens(&env, &payment_token, &pt_admin, &issuer, &10_000_000_000); let r = client.try_deposit_revenue( @@ -3869,7 +4139,7 @@ fn get_supply_cap_returns_zero_when_no_cap_set() { let token = Address::generate(&env); let (payment_token, _) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("cap"), &token, &5_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("cap"), &token, &5_000, &payment_token, &0, &symbol_short!(""), &0); assert_eq!(client.get_supply_cap(&issuer, &symbol_short!("cap"), &token), 0); } @@ -3929,7 +4199,7 @@ fn get_investment_constraints_returns_none_before_set() { let token = Address::generate(&env); let (payment_token, _) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &0, &symbol_short!(""), &0); // Read API must return None before constraints are configured. assert!( client.get_investment_constraints(&issuer, &symbol_short!("def"), &token).is_none(), @@ -3948,7 +4218,7 @@ fn set_investment_constraints_both_zero_succeeds() { let token = Address::generate(&env); let (payment_token, _) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &0, &symbol_short!(""), &0); let r = client.try_set_investment_constraints( &issuer, &symbol_short!("def"), &token, &0, &0, ); @@ -3970,7 +4240,7 @@ fn set_investment_constraints_equal_min_and_max_succeeds() { let token = Address::generate(&env); let (payment_token, _) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &0, &symbol_short!(""), &0); let r = client.try_set_investment_constraints( &issuer, &symbol_short!("def"), &token, &1_000, &1_000, ); @@ -3992,7 +4262,7 @@ fn set_investment_constraints_min_zero_max_positive_succeeds() { let token = Address::generate(&env); let (payment_token, _) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &0, &symbol_short!(""), &0); let r = client.try_set_investment_constraints( &issuer, &symbol_short!("def"), &token, &0, &5_000, ); @@ -4014,7 +4284,7 @@ fn set_investment_constraints_updates_replace_previous() { let token = Address::generate(&env); let (payment_token, _) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &0, &symbol_short!(""), &0); client.set_investment_constraints(&issuer, &symbol_short!("def"), &token, &100, &1_000); client.set_investment_constraints(&issuer, &symbol_short!("def"), &token, &200, &2_000); @@ -4035,7 +4305,7 @@ fn set_investment_constraints_update_event_marks_previous_existed() { let token = Address::generate(&env); let (payment_token, _) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &0, &symbol_short!(""), &0); // First call — no previous, event payload should have is_update = false. client.set_investment_constraints(&issuer, &symbol_short!("def"), &token, &100, &1_000); @@ -4977,7 +5247,7 @@ fn offering_isolation_claims_independent() { // Register a second offering let token_b = Address::generate(&env); let (pt_b, pt_b_admin) = create_payment_token(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_b, &3_000, &pt_b, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token_b, &3_000, &pt_b, &0, &symbol_short!(""), &0); // Create a second payment token for offering B mint_tokens(&env, &pt_b, &pt_b_admin, &issuer, &5_000_000); @@ -5427,7 +5697,8 @@ fn frozen_blocks_register_offering(, &None) { &1_000, &payout_asset, &0, - &None); + &symbol_short!(""), + &0); assert!(r.is_err()); } @@ -5509,7 +5780,7 @@ fn freeze_offering_sets_flag_and_emits_event() { fn freeze_offering_blocks_only_target_offering() { let (env, client, issuer, token_a, payment_token, _contract_id) = claim_setup(); let token_b = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_b, &5_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token_b, &5_000, &payment_token, &0, &symbol_short!(""), &0); let holder = Address::generate(&env); client.freeze_offering(&issuer, &issuer, &symbol_short!("def"), &token_a); @@ -5974,7 +6245,8 @@ fn testnet_mode_allows_bps_over_10000() { &15_000, &payout_asset, &0, - &None); + &symbol_short!(""), + &0); assert!(result.is_ok()); // Verify offering was registered @@ -6001,7 +6273,8 @@ fn testnet_mode_disabled_rejects_bps_over_10000() { &15_000, &payout_asset, &0, - &None); + &symbol_short!(""), + &0); assert!(result.is_err()); } @@ -6021,7 +6294,7 @@ fn testnet_mode_skips_concentration_enforcement() { client.set_testnet_mode(&true); // Register offering and set concentration limit with enforcement - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.set_concentration_limit(&issuer, &symbol_short!("def"), &token, &5000, &true, &0u64); client.report_concentration(&issuer, &symbol_short!("def"), &token, &8000); // Over limit @@ -6122,7 +6395,7 @@ fn testnet_mode_disabled_enforces_concentration() { let payout_asset = Address::generate(&env); // Testnet mode disabled (default) - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.set_concentration_limit(&issuer, &symbol_short!("def"), &token, &5000, &true, &0u64); client.report_concentration(&issuer, &symbol_short!("def"), &token, &8000); // Over limit @@ -6153,7 +6426,7 @@ fn testnet_mode_toggle_after_offerings_exist() { let payout_asset2 = Address::generate(&env); // Register offering in normal mode - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token1, &5_000, &payout_asset1, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token1, &5_000, &payout_asset1, &0, &symbol_short!(""), &0); // Set admin and enable testnet mode client.set_admin(&admin); @@ -6169,7 +6442,8 @@ fn testnet_mode_toggle_after_offerings_exist() { &20_000, &payout_asset2, &0, - &None); + &symbol_short!(""), + &0); assert!(result.is_ok()); // Verify both offerings exist @@ -6192,7 +6466,7 @@ fn testnet_mode_affects_only_validation_not_storage() { client.set_testnet_mode(&true); // Register with high bps - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &25_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &25_000, &payout_asset, &0, &symbol_short!(""), &0); // Disable testnet mode client.set_testnet_mode(&false); @@ -6218,7 +6492,7 @@ fn testnet_mode_multiple_offerings_with_varied_bps() { let token = Address::generate(&env); let bps = 10_000 + (i * 1_000); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &bps, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &bps, &payout_asset, &0, &symbol_short!(""), &0); } assert_eq!(client.get_offering_count(&issuer, &symbol_short!("def")), 5); @@ -6238,7 +6512,7 @@ fn testnet_mode_concentration_warning_still_emitted() { client.set_admin(&admin); client.set_testnet_mode(&true); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.set_concentration_limit(&issuer, &symbol_short!("def"), &token, &5000, &false, &0u64); // Warning should still be emitted in testnet mode @@ -6675,7 +6949,7 @@ fn issuer_transfer_multiple_offerings_isolation() { let new_issuer_b = Address::generate(&env); // Register second offering - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_b, &3_000, &token_b, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token_b, &3_000, &token_b, &0, &symbol_short!(""), &0); // Propose transfers for both (same issuer for both offerings) client.propose_issuer_transfer(&issuer, &symbol_short!("def"), &token_a, &new_issuer_a); @@ -7949,7 +8223,7 @@ fn issuer_transfer_wrong_address_cannot_accept() { let token2 = Address::generate(&env2); let payout2 = Address::generate(&env2); let new_issuer2 = Address::generate(&env2); - client2.register_offering(&issuer2, &Vec::new(&env), &1u32, &symbol_short!("def"), &token2, &1_000, &payout2, &0); + client2.register_offering(&issuer2, &symbol_short!("def"), &token2, &1_000, &payout2, &0, &symbol_short!(""), &0); client2.propose_issuer_transfer(&issuer2, &symbol_short!("def"), &token2, &new_issuer2); // Pending transfer is to new_issuer2; verify it is stored correctly @@ -8224,7 +8498,7 @@ fn testnet_mode_normal_operations_unaffected() { client.set_testnet_mode(&true); // Normal operations should work as expected - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout_asset, &0, &symbol_short!(""), &0); client.report_revenue( &issuer, &symbol_short!("def"), @@ -8292,7 +8566,8 @@ fn testnet_mode_pagination_unaffected() { &(1_000 + i * 100), &payout_asset, &0, - &None); + &symbol_short!(""), + &0); } // Pagination should work normally @@ -8359,7 +8634,7 @@ fn register_blocked_while_paused() { client.initialize(&admin, &None::
, &None::); client.pause_admin(&admin); assert!(client - .try_register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0) + .try_register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0) .is_err()); } @@ -8374,7 +8649,7 @@ fn report_blocked_while_paused() { let token = Address::generate(&env); let payout_asset = Address::generate(&env); client.initialize(&admin, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.pause_admin(&admin); assert!(client .try_report_revenue( @@ -8426,7 +8701,7 @@ fn blacklist_add_blocked_while_paused() { let investor = Address::generate(&env); client.initialize(&admin, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.pause_admin(&admin); assert!(client .try_blacklist_add(&admin, &issuer, &symbol_short!("def"), &token, &investor) @@ -8447,7 +8722,7 @@ fn blacklist_remove_blocked_while_paused() { let investor = Address::generate(&env); client.initialize(&admin, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.pause_admin(&admin); assert!(client .try_blacklist_remove(&admin, &issuer, &symbol_short!("def"), &token, &investor) @@ -8461,7 +8736,7 @@ fn large_period_range_sums_correctly_full() { let issuer = Address::generate(&env); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &payout_asset, &0, &symbol_short!(""), &0); for period in 1..=10 { client.report_revenue( &issuer, @@ -8525,7 +8800,7 @@ fn check_invariants_enhanced(env: &Env, client: &RevoraRevenueShareClient, issue if client.is_paused() { // Mutations should be blocked; verify by attempting a mutation let dummy_token = Address::generate(env); - let result = client.try_register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &dummy_token, &1000, &dummy_token, &0); + let result = client.try_register_offering(&issuer, &ns, &dummy_token, &1000, &dummy_token, &0, &symbol_short!(""), &0); assert!(result.is_err(), "Mutations allowed when paused"); } @@ -8561,7 +8836,7 @@ proptest! { for op in seq { match op { TestOperation::RegisterOffering((i, ns, t, bps, pa)) => { - client.register_offering(&i, &Vec::new(&env), &1u32, &ns, &t, &bps, &pa, &0); + client.register_offering(&i, &ns, &t, &bps, &pa, &0, &symbol_short!(""), &0); } TestOperation::ReportRevenue((i, ns, t, pa, amt, pid, ovr)) => { client.report_revenue(&i, &ns, &t, &pa, &amt, &pid, &ovr); @@ -8591,7 +8866,7 @@ proptest! { let ns = symbol_short!("def"); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1000, &token.clone(), &0); + client.register_offering(&issuer, &ns, &token, &1000, &token.clone(), &0, &symbol_short!(""), &0); // Execute background sequence for op in seq { @@ -8670,7 +8945,7 @@ proptest! { let token = Address::generate(&env); // Mutations panic post-pause let result = std::panic::catch_unwind(|| { - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token.clone(), &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token.clone(), &0, &symbol_short!(""), &0); }); prop_assert!(result.is_err()); } @@ -8691,7 +8966,7 @@ proptest! { ) { let (i, ns, t) = offering; let client = make_client(&env); - client.register_offering(&i, &Vec::new(&env), &1u32, &ns, &t, &1000, &t.clone(), &0); + client.register_offering(&i, &ns, &t, &1000, &t.clone(), &0, &symbol_short!(""), &0); // Blacklist holder client.blacklist_add(&i, &i, &ns, &t.clone(), &holder); @@ -8719,7 +8994,7 @@ proptest! { // Register exactly N offerings for _ in 0..n { let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1000, &token, &0); + client.register_offering(&issuer, &ns, &token, &1000, &token, &0, &symbol_short!(""), &0); } assert_eq!(client.get_offering_count(&issuer, &ns), n as u32); @@ -8791,7 +9066,7 @@ fn test_offerings_pagination_stress() { for _ in 0..num_offerings { let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1000, &token, &0); + client.register_offering(&issuer, &ns, &token, &1000, &token, &0, &symbol_short!(""), &0); } // 1. Verify MAX_PAGE_LIMIT enforcement @@ -8828,7 +9103,7 @@ fn test_blacklist_pagination_stress() { let ns = symbol_short!("def"); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1000, &token, &0); + client.register_offering(&issuer, &ns, &token, &1000, &token, &0, &symbol_short!(""), &0); let num_blacklisted = 45; for _ in 0..num_blacklisted { @@ -8865,7 +9140,7 @@ fn test_whitelist_pagination_stress() { let ns = symbol_short!("def"); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1000, &token, &0); + client.register_offering(&issuer, &ns, &token, &1000, &token, &0, &symbol_short!(""), &0); let num_whitelisted = 45; for _ in 0..num_whitelisted { @@ -8934,7 +9209,7 @@ fn calculate_distribution_bps_100_percent() { let holder = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &10_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &10_000, &token, &0, &symbol_short!(""), &0); let payout = client.calculate_distribution( &caller, @@ -8962,7 +9237,7 @@ fn calculate_distribution_bps_25_percent() { let holder = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &2_500, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &2_500, &token, &0, &symbol_short!(""), &0); let payout = client.calculate_distribution( &caller, @@ -9100,7 +9375,7 @@ fn calculate_distribution_rounds_down() { let holder = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &3_333, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &3_333, &token, &0, &symbol_short!(""), &0); let payout = client.calculate_distribution( &caller, @@ -9126,7 +9401,7 @@ fn calculate_distribution_rounds_down_exact() { let caller = Address::generate(&env); let holder = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &2_500, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &2_500, &token, &0, &symbol_short!(""), &0); let payout = client.calculate_distribution( &caller, @@ -9198,7 +9473,7 @@ fn calculate_distribution_multiple_holders_sum() { let caller = Address::generate(&env); let issuer = caller.clone(); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &token, &0, &symbol_short!(""), &0); let holder_a = Address::generate(&env); let holder_b = Address::generate(&env); @@ -9256,7 +9531,7 @@ fn calculate_distribution_requires_auth() { let holder = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &token, &0, &symbol_short!(""), &0); client.calculate_distribution( &caller, @@ -9288,7 +9563,7 @@ fn calculate_total_distributable_bps_100_percent() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &10_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &10_000, &token, &0, &symbol_short!(""), &0); let total = client.calculate_total_distributable(&issuer, &symbol_short!("def"), &token, &100_000); @@ -9304,7 +9579,7 @@ fn calculate_total_distributable_bps_25_percent() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &2_500, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &2_500, &token, &0, &symbol_short!(""), &0); let total = client.calculate_total_distributable(&issuer, &symbol_short!("def"), &token, &100_000); @@ -9329,7 +9604,7 @@ fn calculate_total_distributable_rounds_down() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &3_333, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &3_333, &token, &0, &symbol_short!(""), &0); let total = client.calculate_total_distributable(&issuer, &symbol_short!("def"), &token, &100); @@ -9370,7 +9645,7 @@ fn calculate_distribution_offering_isolation() { let holder = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_b, &8_000, &token_b, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token_b, &8_000, &token_b, &0, &symbol_short!(""), &0); let payout_a = client.calculate_distribution( &caller, @@ -9402,7 +9677,7 @@ fn calculate_total_distributable_offering_isolation() { let (env, client, issuer, token, _payment_token, _contract_id) = claim_setup(); let token_b = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_b, &8_000, &token_b, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token_b, &8_000, &token_b, &0, &symbol_short!(""), &0); let total_a = client.calculate_total_distributable(&issuer, &symbol_short!("def"), &token, &100_000); @@ -9503,7 +9778,7 @@ fn test_event_only_mode_register_and_report() { assert!(client.is_event_only()); // Register offering should emit event but NOT persist state - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &payout_asset, &0, &symbol_short!(""), &0); // Verify event emitted (skip checking EVENT_INIT) let events = legacy_events(&env); @@ -9594,7 +9869,7 @@ fn test_set_offering_metadata_success() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); let metadata = SdkString::from_str(&env, "ipfs://QmTest123"); let result = @@ -9610,7 +9885,7 @@ fn test_get_offering_metadata_returns_none_initially() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); let metadata = client.get_offering_metadata(&issuer, &symbol_short!("def"), &token); assert_eq!(metadata, None); @@ -9624,7 +9899,7 @@ fn test_update_offering_metadata_success() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); let metadata1 = SdkString::from_str(&env, "ipfs://QmFirst"); client.set_offering_metadata(&issuer, &symbol_short!("def"), &token, &metadata1); @@ -9643,7 +9918,7 @@ fn test_get_offering_metadata_after_set() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); let metadata = SdkString::from_str(&env, "https://example.com/metadata.json"); let r = client.try_set_offering_metadata(&issuer, &symbol_short!("def"), &token, &metadata); @@ -9661,7 +9936,7 @@ fn test_set_metadata_requires_auth() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); let metadata = SdkString::from_str(&env, "ipfs://QmTest"); client.set_offering_metadata(&issuer, &symbol_short!("def"), &token, &metadata); @@ -9693,7 +9968,7 @@ fn test_set_metadata_respects_freeze() { let token = Address::generate(&env); client.initialize(&admin, &None, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); client.freeze(); let metadata = SdkString::from_str(&env, "ipfs://QmTest"); @@ -9714,7 +9989,7 @@ fn test_set_metadata_respects_pause() { let token = Address::generate(&env); client.initialize(&admin, &None, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); client.pause_admin(&admin); let metadata = SdkString::from_str(&env, "ipfs://QmTest"); @@ -9731,7 +10006,7 @@ fn test_set_metadata_empty_string() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); let metadata = SdkString::from_str(&env, ""); let result = @@ -9750,7 +10025,7 @@ fn test_set_metadata_max_length() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); // Create a 256-byte string (max allowed) let max_str = "a".repeat(256); @@ -9768,7 +10043,7 @@ fn test_set_metadata_oversized_data() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); // Create a 257-byte string (exceeds max) let oversized_str = "a".repeat(257); @@ -9786,7 +10061,7 @@ fn test_set_metadata_repeated_updates() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); let metadata_values = ["ipfs://QmTest0", "ipfs://QmTest1", "ipfs://QmTest2", "ipfs://QmTest3", "ipfs://QmTest4"]; @@ -9811,8 +10086,8 @@ fn test_metadata_scoped_per_offering() { let token_a = Address::generate(&env); let token_b = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_a, &1000, &token_a, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_b, &2000, &token_b, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token_a, &1000, &token_a, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("def"), &token_b, &2000, &token_b, &0, &symbol_short!(""), &0); let metadata_a = SdkString::from_str(&env, "ipfs://QmTokenA"); let metadata_b = SdkString::from_str(&env, "ipfs://QmTokenB"); @@ -9836,7 +10111,7 @@ fn test_metadata_set_emits_event() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); let before = legacy_events(&env).len(); let metadata = SdkString::from_str(&env, "ipfs://QmTest"); @@ -9862,7 +10137,7 @@ fn test_metadata_update_emits_event() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); let metadata1 = SdkString::from_str(&env, "ipfs://QmFirst"); client.set_offering_metadata(&issuer, &symbol_short!("def"), &token, &metadata1); @@ -9891,7 +10166,7 @@ fn test_metadata_events_include_correct_data() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); let metadata = SdkString::from_str(&env, "ipfs://QmTest123"); client.set_offering_metadata(&issuer, &symbol_short!("def"), &token, &metadata); @@ -9925,9 +10200,9 @@ fn test_metadata_multiple_offerings_same_issuer() { let token2 = Address::generate(&env); let token3 = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token1, &1000, &token1, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token2, &2000, &token2, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token3, &3000, &token3, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token1, &1000, &token1, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("def"), &token2, &2000, &token2, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("def"), &token3, &3000, &token3, &0, &symbol_short!(""), &0); let meta1 = SdkString::from_str(&env, "ipfs://Qm1"); let meta2 = SdkString::from_str(&env, "ipfs://Qm2"); @@ -9951,7 +10226,7 @@ fn test_metadata_after_issuer_transfer() { let new_issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&old_issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&old_issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); let metadata = SdkString::from_str(&env, "ipfs://QmOriginal"); client.set_offering_metadata(&old_issuer, &symbol_short!("def"), &token, &metadata); @@ -9980,7 +10255,7 @@ fn test_set_metadata_requires_issuer() { let non_issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); let metadata = SdkString::from_str(&env, "ipfs://QmTest"); let result = @@ -9996,7 +10271,7 @@ fn test_metadata_ipfs_cid_format() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); // Test typical IPFS CID (46 characters) let ipfs_cid = SdkString::from_str(&env, "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG"); @@ -10016,7 +10291,7 @@ fn test_metadata_https_url_format() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); let https_url = SdkString::from_str(&env, "https://api.example.com/metadata/token123.json"); let result = @@ -10035,7 +10310,7 @@ fn test_metadata_content_hash_format() { let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1000, &token, &0, &symbol_short!(""), &0); // SHA256 hash as hex string let content_hash = SdkString::from_str( @@ -10131,7 +10406,7 @@ mod regression { let payout_asset = Address::generate(&env); // Act: Perform the operation - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // Assert: Verify correct behavior let offering = client.get_offering(&issuer, &symbol_short!("def"), &token); @@ -10392,7 +10667,8 @@ mod regression { &1_000, &payout_asset, &0, - &None); + &symbol_short!(""), + &0); (client, admin, token, payout_asset) } @@ -10834,10 +11110,10 @@ mod regression { let p1 = Address::generate(&env); let p2 = Address::generate(&env); let p3 = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &t0, &100, &p0, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &t1, &200, &p1, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &t2, &300, &p2, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &t3, &400, &p3, &0); + client.register_offering(&issuer, &symbol_short!("def"), &t0, &100, &p0, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("def"), &t1, &200, &p1, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("def"), &t2, &300, &p2, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("def"), &t3, &400, &p3, &0, &symbol_short!(""), &0); let (page, _) = client.get_offerings_page(&issuer, &symbol_short!("def"), &0, &10); assert_eq!(page.len(), 4); assert_eq!(page.get(0).clone().unwrap().token, t0); @@ -10856,10 +11132,10 @@ mod regression { let p1 = Address::generate(&env); let p2 = Address::generate(&env); let p3 = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &t0, &100, &p0, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &t1, &200, &p1, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &t2, &300, &p2, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &t3, &400, &p3, &0); + client.register_offering(&issuer, &symbol_short!("def"), &t0, &100, &p0, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("def"), &t1, &200, &p1, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("def"), &t2, &300, &p2, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("def"), &t3, &400, &p3, &0, &symbol_short!(""), &0); let (page, _) = client.get_offerings_page(&issuer, &symbol_short!("def"), &0, &10); assert_eq!(page.len(), 4); assert_eq!(page.get(0).clone().unwrap().token, t0); @@ -10953,7 +11229,7 @@ mod regression { let v0 = client.get_version(); let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); assert_eq!(client.get_version(), v0); } @@ -11096,7 +11372,7 @@ mod regression { let token = Address::generate(&env); let payout = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &500, &payout, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &500, &payout, &0, &symbol_short!(""), &0); let result = client.get_offering(&issuer, &symbol_short!("def"), &token); assert!(result.is_some()); @@ -11118,7 +11394,7 @@ mod regression { let mut target_token = Address::generate(&env); for i in 0..10u32 { let t = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &t, &(i * 100), &payout, &0); + client.register_offering(&issuer, &symbol_short!("def"), &t, &(i * 100), &payout, &0, &symbol_short!(""), &0); if i == 9 { target_token = t; } @@ -11148,7 +11424,8 @@ mod regression { &300, &payout, &0, - &None); + &symbol_short!(""), + &0); client.propose_issuer_transfer(&old_issuer, &symbol_short!("def"), &token, &new_issuer); client.accept_issuer_transfer(&new_issuer, &symbol_short!("def"), &token); @@ -11180,7 +11457,8 @@ mod regression { &300, &payout, &0, - &None); + &symbol_short!(""), + &0); client.propose_issuer_transfer(&old_issuer, &symbol_short!("def"), &token, &new_issuer); client.accept_issuer_transfer(&new_issuer, &symbol_short!("def"), &token); @@ -11448,7 +11726,7 @@ mod admin_rotation_edge { let payout_asset = Address::generate(&env); let new_admin = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.propose_admin_rotation(&new_admin); client.accept_admin_rotation(&new_admin); @@ -11527,7 +11805,7 @@ mod admin_rotation_integration { let investor = Address::generate(&env); let new_admin = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); client.blacklist_add(&issuer, &issuer, &symbol_short!("def"), &token, &investor); client.propose_admin_rotation(&new_admin); @@ -11916,7 +12194,7 @@ fn test_offerings_page_pagination_25_offerings() { for i in 0..25 { let token = Address::generate(&env); tokens.push_back(token.clone()); - client.register_offering(&issuer1, &Vec::new(&env), &1u32, &ns, &token, &(1000 + i * 100), &token, &0); + client.register_offering(&issuer1, &ns, &token, &(1000 + i * 100), &token, &0, &symbol_short!(""), &0); } // Test 1: Page through with limit=10 @@ -11955,7 +12233,7 @@ fn test_offerings_page_edge_cases() { // Register 10 offerings for i in 0..10 { let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1000, &token, &0); + client.register_offering(&issuer, &ns, &token, &1000, &token, &0, &symbol_short!(""), &0); } // Edge case 1: start == count (10 offerings, start at 10) @@ -11993,10 +12271,10 @@ fn test_offerings_page_ordering_deterministic() { let t2 = Address::generate(&env); let t3 = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &t0, &100, &t0, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &t1, &200, &t1, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &t2, &300, &t2, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &t3, &400, &t3, &0); + client.register_offering(&issuer, &ns, &t0, &100, &t0, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &ns, &t1, &200, &t1, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &ns, &t2, &300, &t2, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &ns, &t3, &400, &t3, &0, &symbol_short!(""), &0); // Retrieve all pages and verify ordering let (page1, cursor1) = client.get_offerings_page(&issuer, &ns, &0, &2); @@ -12048,9 +12326,9 @@ fn test_offerings_page_after_issuer_transfer() { let t2 = Address::generate(&env); let t3 = Address::generate(&env); - client.register_offering(&issuer1, &Vec::new(&env), &1u32, &ns, &t1, &100, &t1, &0); - client.register_offering(&issuer1, &Vec::new(&env), &1u32, &ns, &t2, &200, &t2, &0); - client.register_offering(&issuer1, &Vec::new(&env), &1u32, &ns, &t3, &300, &t3, &0); + client.register_offering(&issuer1, &ns, &t1, &100, &t1, &0, &symbol_short!(""), &0); + client.register_offering(&issuer1, &ns, &t2, &200, &t2, &0, &symbol_short!(""), &0); + client.register_offering(&issuer1, &ns, &t3, &300, &t3, &0, &symbol_short!(""), &0); // Verify issuer1 has 3 offerings let (page1_before, _) = client.get_offerings_page(&issuer1, &ns, &0, &20); @@ -12087,7 +12365,7 @@ fn test_issuer_transfer_migrates_all_configs() { let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&old_issuer, &Vec::new(&env), &1u32, &ns, &token, &1000, &payout_asset, &0); + client.register_offering(&old_issuer, &ns, &token, &1000, &payout_asset, &0, &symbol_short!(""), &0); // 1. Set concentration client.set_concentration_limit(&old_issuer, &ns, &token, &5000, &true); diff --git a/src/test_auth.rs b/src/test_auth.rs index 741b909c..93bf3eca 100644 --- a/src/test_auth.rs +++ b/src/test_auth.rs @@ -100,7 +100,7 @@ fn setup_offering(env: &Env, client: &RevoraRevenueShareClient) -> (Address, Add let issuer = Address::generate(env); let token = Address::generate(env); client.set_admin(&issuer); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); (issuer, token) } @@ -566,7 +566,8 @@ fn register_offering_missing_auth_no_mutation() { &1_000, &token, &0, - &None); + &symbol_short!(""), + &0); assert!(result.is_err()); assert_eq!(client.get_offering_count(&issuer, &symbol_short!("def")), 0); assert_eq!( @@ -621,7 +622,7 @@ fn blacklist_remove_wrong_caller_no_mutation() { let token = Address::generate(&env); let investor = Address::generate(&env); client.set_admin(&issuer); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); client.blacklist_add(&issuer, &issuer, &symbol_short!("def"), &token, &investor); let attacker = Address::generate(&env); // Any authenticated caller can remove; with mock_all_auths this succeeds. @@ -670,8 +671,8 @@ fn cross_offering_confusion_wrong_issuer_no_mutation() { let token_b = Address::generate(&env); let holder = Address::generate(&env); - client.register_offering(&issuer_a, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_a, &1_000, &token_a, &0); - client.register_offering(&issuer_b, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_b, &1_000, &token_b, &0); + client.register_offering(&issuer_a, &symbol_short!("def"), &token_a, &1_000, &token_a, &0, &symbol_short!(""), &0); + client.register_offering(&issuer_b, &symbol_short!("def"), &token_b, &1_000, &token_b, &0, &symbol_short!(""), &0); // Issuer B tries to set a share on Issuer A's token. let result = client.try_set_holder_share( @@ -700,8 +701,8 @@ fn cross_offering_concentration_limit_wrong_issuer() { let token_a = Address::generate(&env); let token_b = Address::generate(&env); - client.register_offering(&issuer_a, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_a, &1_000, &token_a, &0); - client.register_offering(&issuer_b, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_b, &1_000, &token_b, &0); + client.register_offering(&issuer_a, &symbol_short!("def"), &token_a, &1_000, &token_a, &0, &symbol_short!(""), &0); + client.register_offering(&issuer_b, &symbol_short!("def"), &token_b, &1_000, &token_b, &0, &symbol_short!(""), &0); let result = client.try_set_concentration_limit( &issuer_a, @@ -731,7 +732,7 @@ fn cross_namespace_confusion_wrong_namespace() { let holder = Address::generate(&env); // Register only in namespace "ns1". - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("ns1"), &token, &1_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("ns1"), &token, &1_000, &token, &0, &symbol_short!(""), &0); // Attempt to set a share in the unregistered namespace "ns2". let result = client.try_set_holder_share( @@ -828,7 +829,8 @@ fn register_offering_blocked_when_frozen() { &1_000, &token, &0, - &None); + &symbol_short!(""), + &0); assert_eq!(result, Err(Ok(RevoraError::ContractFrozen))); } @@ -979,7 +981,8 @@ fn register_offering_invalid_bps_returns_typed_error() { &10_001u32, &token, &0, - &None); + &symbol_short!(""), + &0); assert_eq!(result, Err(Ok(RevoraError::InvalidRevenueShareBps))); assert_eq!(client.get_offering_count(&issuer, &symbol_short!("def")), 0); } @@ -1077,8 +1080,8 @@ fn two_issuers_independent_settings() { let token_b = Address::generate(&env); let holder = Address::generate(&env); - client.register_offering(&issuer_a, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_a, &1_000, &token_a, &0); - client.register_offering(&issuer_b, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_b, &2_000, &token_b, &0); + client.register_offering(&issuer_a, &symbol_short!("def"), &token_a, &1_000, &token_a, &0, &symbol_short!(""), &0); + client.register_offering(&issuer_b, &symbol_short!("def"), &token_b, &2_000, &token_b, &0, &symbol_short!(""), &0); // Issuer A sets a holder share. client.set_holder_share(&issuer_a, &symbol_short!("def"), &token_a, &holder, &1_000u32); diff --git a/src/test_blacklist_batch_gas.rs b/src/test_blacklist_batch_gas.rs index 5bb801c4..86b7d4e4 100644 --- a/src/test_blacklist_batch_gas.rs +++ b/src/test_blacklist_batch_gas.rs @@ -21,7 +21,7 @@ fn blacklist_add_many_gas_bound_worst_case() { // Initialize and register offering client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1000u32, &token, &0_i128); + client.register_offering(&issuer, &ns, &token, &1000u32, &token, &0_i128, &symbol_short!(""), &0); // Prefill blacklist to half the default cap (MAX_BLACKLIST_SIZE = 200 -> 100) let mut prefilled: Vec
= Vec::new(&env); diff --git a/src/test_claim_transfer_fail.rs b/src/test_claim_transfer_fail.rs index 9a4dc614..8fd55751 100644 --- a/src/test_claim_transfer_fail.rs +++ b/src/test_claim_transfer_fail.rs @@ -230,8 +230,8 @@ fn setup_claim_fail() -> ( &10_000, &fail_token_id, &0, - &None, - ); + &symbol_short!(""), + &0); revora.set_holder_share(&issuer, &symbol_short!("def"), &offering_token, &holder, &10_000); // Mint to issuer and deposit — transfer direction is issuer→contract, not yet failing @@ -453,7 +453,8 @@ fn claim_transfer_fail_does_not_affect_sibling_offering() { &10_000, &payout_b_id, &0, - ); + &symbol_short!(""), + &0); revora.set_holder_share(&issuer, &symbol_short!("def"), &offering_token_b, &holder, &10_000); // Mint payout tokens to the issuer so they can deposit revenue diff --git a/src/test_close_period.rs b/src/test_close_period.rs index a2951514..b749d614 100644 --- a/src/test_close_period.rs +++ b/src/test_close_period.rs @@ -20,7 +20,8 @@ fn test_claim_on_deferred_fails() { &10_000, &payment_token, &0, - ); + &symbol_short!(""), + &0); (env, client, issuer, offering_token, payment_token) } diff --git a/src/test_cross_contract.rs b/src/test_cross_contract.rs index e88ca274..69c98a44 100644 --- a/src/test_cross_contract.rs +++ b/src/test_cross_contract.rs @@ -193,7 +193,7 @@ fn cross_contract_registry_check_before_offering() { // Step 3: Now register offering in Revora (after registry approval) // In production, register_offering would call registry.is_approved() internally assert!(registry.is_approved(&token)); - revora.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout_asset, &0); + revora.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout_asset, &0, &symbol_short!(""), &0); // Verify offering was created let offering = revora.get_offering(&issuer, &symbol_short!("def"), &token); @@ -285,7 +285,7 @@ fn cross_contract_oracle_revenue_valuation() { let payout_asset = Address::generate(&env); // Register offering - revora.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout_asset, &0); + revora.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout_asset, &0, &symbol_short!(""), &0); // Report revenue revora.report_revenue( @@ -356,7 +356,7 @@ fn cross_contract_full_workflow_registry_then_offering() { assert!(registry.is_approved(&token)); // Step 3: Register offering in Revora - revora.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &3_000, &payout_asset, &0); + revora.register_offering(&issuer, &symbol_short!("def"), &token, &3_000, &payout_asset, &0, &symbol_short!(""), &0); // Step 4: Report revenue revora.report_revenue( @@ -430,7 +430,7 @@ fn cross_contract_error_in_registry_does_not_affect_revora() { // Register token and offering registry.register_token(&admin, &token); - revora.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout_asset, &0); + revora.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout_asset, &0, &symbol_short!(""), &0); // Cause an error in registry (duplicate registration) let err = registry.try_register_token(&admin, &token); @@ -458,7 +458,7 @@ fn cross_contract_revora_operations_independent_of_oracle_state() { let payout_asset = Address::generate(&env); // Revora works fine without any oracle prices set - revora.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout_asset, &0); + revora.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout_asset, &0, &symbol_short!(""), &0); revora.report_revenue( &issuer, &symbol_short!("def"), @@ -502,13 +502,13 @@ fn cross_contract_concurrent_state_changes() { let payout_3 = Address::generate(&env); registry.register_token(&admin, &token_1); - revora.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_1, &1_000, &payout_1, &0); + revora.register_offering(&issuer, &symbol_short!("def"), &token_1, &1_000, &payout_1, &0, &symbol_short!(""), &0); registry.register_token(&admin, &token_2); - revora.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_2, &2_000, &payout_2, &0); + revora.register_offering(&issuer, &symbol_short!("def"), &token_2, &2_000, &payout_2, &0, &symbol_short!(""), &0); registry.register_token(&admin, &token_3); - revora.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_3, &3_000, &payout_3, &0); + revora.register_offering(&issuer, &symbol_short!("def"), &token_3, &3_000, &payout_3, &0, &symbol_short!(""), &0); // Verify both contracts have consistent state assert_eq!(registry.get_token_count(), 3); @@ -542,7 +542,7 @@ fn cross_contract_oracle_price_updates_across_revenue_reports() { let token = Address::generate(&env); let payout_asset = Address::generate(&env); - revora.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout_asset, &0); + revora.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout_asset, &0, &symbol_short!(""), &0); // Report revenue at $1.00 revora.report_revenue( @@ -626,7 +626,8 @@ fn cross_contract_stress_revora_with_registry_and_oracle() { &((i + 1) * 1_000), &payout, &0, - &None); + &symbol_short!(""), + &0); oracle.set_price(&admin, &payout, &((i as i128 + 1) * 1_000_000), &1000); revora.report_revenue( &issuer, diff --git a/src/test_cross_contract_transfer_fail.rs b/src/test_cross_contract_transfer_fail.rs index 520ff088..2c28f4d3 100644 --- a/src/test_cross_contract_transfer_fail.rs +++ b/src/test_cross_contract_transfer_fail.rs @@ -87,7 +87,8 @@ fn setup() -> (Env, RevoraRevenueShareClient<'static>, Address, Address, Address &5_000, &payment_token, &0, - &None); + &symbol_short!(""), + &0); (env, client, contract_id, issuer, offering_token, payment_token, pt_admin) } @@ -431,7 +432,8 @@ fn transfer_fail_in_one_offering_does_not_affect_sibling_offering() { &5_000, &payment_token_b, &0, - &None); + &symbol_short!(""), + &0); // Fund only offering B mint(&env, &payment_token_b, &issuer, 100_000); diff --git a/src/test_duplicates.rs b/src/test_duplicates.rs index 03c9855d..bed1075c 100644 --- a/src/test_duplicates.rs +++ b/src/test_duplicates.rs @@ -27,7 +27,7 @@ fn setup_offering() -> (Env, RevoraRevenueShareClient<'static>, Address, Address let payout_asset = Address::generate(&env); let namespace = symbol_short!("ns"); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &namespace, &token, &5000, &payout_asset, &0); + client.register_offering(&issuer, &namespace, &token, &5000, &payout_asset, &0, &symbol_short!(""), &0); (env, client, issuer, token, payout_asset) } @@ -52,14 +52,14 @@ fn test_register_duplicate_offering_is_idempotent() { let payout_asset = Address::generate(&env); // First registration - client.register_offering(&issuer, &Vec::new(&env), &1u32, &namespace, &token, &5000, &payout_asset, &0); + client.register_offering(&issuer, &namespace, &token, &5000, &payout_asset, &0, &symbol_short!(""), &0); assert_eq!(client.get_offering_count(&issuer, &namespace), 1); let offering1 = client.get_offering(&issuer, &namespace, &token).unwrap(); assert_eq!(offering1.revenue_share_bps, 5000); // Second registration (same identity, different bps) - client.register_offering(&issuer, &Vec::new(&env), &1u32, &namespace, &token, &6000, &payout_asset, &0); + client.register_offering(&issuer, &namespace, &token, &6000, &payout_asset, &0, &symbol_short!(""), &0); // Count should still be 1 assert_eq!(client.get_offering_count(&issuer, &namespace), 1); @@ -79,9 +79,9 @@ fn test_pagination_stability_with_idempotency() { let token_b = Address::generate(&env); // Register A, then B, then A again - client.register_offering(&issuer, &Vec::new(&env), &1u32, &namespace, &token_a, &1000, &payout_asset, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &namespace, &token_b, &2000, &payout_asset, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &namespace, &token_a, &3000, &payout_asset, &0); + client.register_offering(&issuer, &namespace, &token_a, &1000, &payout_asset, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &namespace, &token_b, &2000, &payout_asset, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &namespace, &token_a, &3000, &payout_asset, &0, &symbol_short!(""), &0); let (offerings, _) = client.get_offerings_page(&issuer, &namespace, &0, &10); @@ -98,8 +98,8 @@ fn test_get_offering_matches_first_registration() { let namespace = symbol_short!("ns"); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &namespace, &token, &1000, &payout_asset, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &namespace, &token, &2000, &payout_asset, &0); + client.register_offering(&issuer, &namespace, &token, &1000, &payout_asset, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &namespace, &token, &2000, &payout_asset, &0, &symbol_short!(""), &0); let offering = client.get_offering(&issuer, &namespace, &token).unwrap(); assert_eq!(offering.revenue_share_bps, 1000); diff --git a/src/test_event_indexed_v2.rs b/src/test_event_indexed_v2.rs index c7ed6781..49ece44c 100644 --- a/src/test_event_indexed_v2.rs +++ b/src/test_event_indexed_v2.rs @@ -38,7 +38,7 @@ fn setup() -> (Env, RevoraRevenueShareClient<'static>, Address, Symbol, Address, let token = Address::generate(&env); let payout = Address::generate(&env); client.initialize(&admin, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &2500, &payout, &0); + client.register_offering(&issuer, &ns, &token, &2500, &payout, &0, &symbol_short!(""), &0); (env, client, issuer, ns, token, payout) } @@ -206,7 +206,7 @@ fn event_indexed_v2_claim_topic_and_data_shape() { soroban_sdk::token::StellarAssetClient::new(&env, &payout).mint(&issuer, &1_000_000); client.initialize(&admin, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &2500, &payout, &0); + client.register_offering(&issuer, &ns, &token, &2500, &payout, &0, &symbol_short!(""), &0); let holder = Address::generate(&env); client.set_holder_share(&issuer, &ns, &token, &holder, &5_000); // 50% @@ -244,7 +244,7 @@ fn event_indexed_v2_claim_period_id_always_zero() { soroban_sdk::token::StellarAssetClient::new(&env, &payout).mint(&issuer, &1_000_000); client.initialize(&admin, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &2500, &payout, &0); + client.register_offering(&issuer, &ns, &token, &2500, &payout, &0, &symbol_short!(""), &0); let holder = Address::generate(&env); client.set_holder_share(&issuer, &ns, &token, &holder, &5_000); @@ -274,8 +274,8 @@ fn event_indexed_v2_payout_asset_bound_correctly_per_offering() { let payout_a = Address::generate(&env); let payout_b = Address::generate(&env); client.initialize(&admin, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token_a, &2500, &payout_a, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token_b, &2500, &payout_b, &0); + client.register_offering(&issuer, &ns, &token_a, &2500, &payout_a, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &ns, &token_b, &2500, &payout_b, &0, &symbol_short!(""), &0); let before_a = env.events().all().len(); client.report_revenue(&issuer, &ns, &token_a, &payout_a, &10_000, &1, &false); diff --git a/src/test_freeze_matrix.rs b/src/test_freeze_matrix.rs index 5ed0c68c..04a18db7 100644 --- a/src/test_freeze_matrix.rs +++ b/src/test_freeze_matrix.rs @@ -20,7 +20,436 @@ use soroban_sdk::{ // ── Helpers ─────────────────────────────────────────────────────────────────── -fn setup() -> (Env, RevoraRevenueShareClient<'static>, Address, Symbol, Address, Address, Address) { +// ─── Shared helpers ─────────────────────────────────────────────────────────── + +/// Assert that a `try_*` result is exactly `ContractFrozen` and nothing else. +/// +/// This is the single source of truth for the "frozen" assertion. All matrix +/// tests call this helper so that a future error-code change only needs to be +/// updated here. +fn assert_frozen_err( + result: Result>, +) { + match result { + Err(Ok(RevoraError::ContractFrozen)) => {} // expected + other => panic!("expected ContractFrozen, got {:?}", other), + } +} + +/// Build a fresh client, initialize with admin + safety, register one offering, +/// freeze the contract, and return everything needed by the tests. +fn frozen_setup( + env: &Env, +) -> ( + RevoraRevenueShareClient<'_>, + Address, // admin + Address, // issuer (== admin for simplicity) + Address, // token + Address, // payout_asset +) { + env.mock_all_auths(); + let contract_id = env.register_contract(None, RevoraRevenueShare); + let client = RevoraRevenueShareClient::new(env, &contract_id); + + let admin = Address::generate(env); + let safety = Address::generate(env); + client.initialize(&admin, &Some(safety.clone()), &None::); + + let issuer = admin.clone(); + let token = Address::generate(env); + let payout_asset = Address::generate(env); + client.register_offering(&issuer, &symbol_short!("ns"), &token, &1_000u32, &payout_asset, &0i128, &symbol_short!(""), &0); + + // Freeze the contract — all subsequent mutating calls must return ContractFrozen. + client.freeze(); + + (client, admin, issuer, token, payout_asset) +} + +// ─── 1. Issuer / offering registration ─────────────────────────────────────── + +#[test] +fn frozen_register_offering_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, _, payout_asset) = frozen_setup(&env); + let new_token = Address::generate(&env); + let result = client.try_register_offering( + &issuer, + &symbol_short!("ns2"), + &new_token, + &500u32, + &payout_asset, + &0i128, + &symbol_short!(""), + &0); + assert_frozen_err(result); + // Verify no partial write: offering must not exist. + assert!(client.get_offering(&issuer, &symbol_short!("ns2"), &new_token).is_none()); +} + +// ─── 2. Revenue reporting ───────────────────────────────────────────────────── + +#[test] +fn frozen_report_revenue_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, payout_asset) = frozen_setup(&env); + let result = client.try_report_revenue( + &issuer, + &symbol_short!("ns"), + &token, + &payout_asset, + &10_000i128, + &1u64, + &false, + ); + assert_frozen_err(result); + // No audit summary should have been written. + assert!(client.get_audit_summary(&issuer, &symbol_short!("ns"), &token).is_none()); +} + +// ─── 3. Revenue deposit ─────────────────────────────────────────────────────── + +#[test] +fn frozen_deposit_revenue_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, payout_asset) = frozen_setup(&env); + let result = client.try_deposit_revenue( + &issuer, + &symbol_short!("ns"), + &token, + &payout_asset, + &10_000i128, + &1u64, + ); + assert_frozen_err(result); + assert_eq!(client.get_period_count(&issuer, &symbol_short!("ns"), &token), 0); +} + +#[test] +fn frozen_deposit_revenue_with_snapshot_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, payout_asset) = frozen_setup(&env); + let result = client.try_deposit_revenue_with_snapshot( + &issuer, + &symbol_short!("ns"), + &token, + &payout_asset, + &10_000i128, + &1u64, + &1u64, + ); + assert_frozen_err(result); + assert_eq!(client.get_period_count(&issuer, &symbol_short!("ns"), &token), 0); +} + +// ─── 4. Holder share management ────────────────────────────────────────────── + +#[test] +fn frozen_set_holder_share_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let holder = Address::generate(&env); + let result = + client.try_set_holder_share(&issuer, &symbol_short!("ns"), &token, &holder, &500u32); + assert_frozen_err(result); + assert_eq!(client.get_holder_share(&issuer, &symbol_short!("ns"), &token, &holder), 0); +} + +// ─── 5. Blacklist management ────────────────────────────────────────────────── + +#[test] +fn frozen_blacklist_add_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let investor = Address::generate(&env); + let result = + client.try_blacklist_add(&issuer, &issuer, &symbol_short!("ns"), &token, &investor); + assert_frozen_err(result); + assert!(!client.is_blacklisted(&issuer, &symbol_short!("ns"), &token, &investor)); +} + +#[test] +fn frozen_blacklist_remove_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let investor = Address::generate(&env); + let result = + client.try_blacklist_remove(&issuer, &issuer, &symbol_short!("ns"), &token, &investor); + assert_frozen_err(result); +} + +// ─── 6. Whitelist management ────────────────────────────────────────────────── + +#[test] +fn frozen_whitelist_add_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let investor = Address::generate(&env); + let result = + client.try_whitelist_add(&issuer, &issuer, &symbol_short!("ns"), &token, &investor); + assert_frozen_err(result); + assert!(!client.is_whitelisted(&issuer, &symbol_short!("ns"), &token, &investor)); +} + +#[test] +fn frozen_whitelist_remove_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let investor = Address::generate(&env); + let result = + client.try_whitelist_remove(&issuer, &issuer, &symbol_short!("ns"), &token, &investor); + assert_frozen_err(result); +} + +// ─── 7. Concentration limit ─────────────────────────────────────────────────── + +#[test] +fn frozen_set_concentration_limit_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let result = client.try_set_concentration_limit( + &issuer, + &symbol_short!("ns"), + &token, + &5_000u32, + &true, + &0u64, + ); + assert_frozen_err(result); + assert!(client.get_concentration_limit(&issuer, &symbol_short!("ns"), &token).is_none()); +} + +#[test] +fn frozen_report_concentration_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let result = + client.try_report_concentration(&issuer, &symbol_short!("ns"), &token, &3_000u32); + assert_frozen_err(result); + assert_eq!(client.get_current_concentration(&issuer, &symbol_short!("ns"), &token), 0); +} + +// ─── 8. Rounding mode ──────────────────────────────────────────────────────── + +#[test] +fn frozen_set_rounding_mode_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let result = client.try_set_rounding_mode( + &issuer, + &symbol_short!("ns"), + &token, + &RoundingMode::RoundHalfUp, + ); + assert_frozen_err(result); + // Default rounding mode must be unchanged. + assert_eq!( + client.get_rounding_mode(&issuer, &symbol_short!("ns"), &token), + RoundingMode::Truncation + ); +} + +// ─── 9. Investment constraints ──────────────────────────────────────────────── + +#[test] +fn frozen_set_investment_constraints_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let result = client.try_set_investment_constraints( + &issuer, + &symbol_short!("ns"), + &token, + &100i128, + &10_000i128, + ); + assert_frozen_err(result); + assert!(client.get_investment_constraints(&issuer, &symbol_short!("ns"), &token).is_none()); +} + +// ─── 10. Minimum revenue threshold ─────────────────────────────────────────── + +#[test] +fn frozen_set_min_revenue_threshold_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let result = + client.try_set_min_revenue_threshold(&issuer, &symbol_short!("ns"), &token, &500i128); + assert_frozen_err(result); + assert_eq!(client.get_min_revenue_threshold(&issuer, &symbol_short!("ns"), &token), 0); +} + +// ─── 11. Claim delay ───────────────────────────────────────────────────────── + +#[test] +fn frozen_set_claim_delay_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let result = client.try_set_claim_delay(&issuer, &symbol_short!("ns"), &token, &3600u64); + assert_frozen_err(result); + assert_eq!(client.get_claim_delay(&issuer, &symbol_short!("ns"), &token), 0); +} + +// ─── 12. Report / claim windows ────────────────────────────────────────────── + +#[test] +fn frozen_set_report_window_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let result = + client.try_set_report_window(&issuer, &symbol_short!("ns"), &token, &100u64, &200u64); + assert_frozen_err(result); + assert!(client.get_report_window(&issuer, &symbol_short!("ns"), &token).is_none()); +} + +#[test] +fn frozen_set_claim_window_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let result = + client.try_set_claim_window(&issuer, &symbol_short!("ns"), &token, &100u64, &200u64); + assert_frozen_err(result); + assert!(client.get_claim_window(&issuer, &symbol_short!("ns"), &token).is_none()); +} + +// ─── 13. Snapshot configuration ────────────────────────────────────────────── + +#[test] +fn frozen_set_snapshot_config_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let result = client.try_set_snapshot_config(&issuer, &symbol_short!("ns"), &token, &true); + assert_frozen_err(result); + assert!(!client.get_snapshot_config(&issuer, &symbol_short!("ns"), &token)); +} + +#[test] +fn frozen_commit_snapshot_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let hash = BytesN::<32>::from_array(&env, &[0u8; 32]); + let result = + client.try_commit_snapshot(&issuer, &symbol_short!("ns"), &token, &1u64, &hash); + assert_frozen_err(result); + assert!(client.get_snapshot_entry(&issuer, &symbol_short!("ns"), &token, &1u64).is_none()); +} + +#[test] +fn frozen_apply_snapshot_shares_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let holder = Address::generate(&env); + let holders: Vec<(Address, u32)> = { + let mut v = Vec::new(&env); + v.push_back((holder.clone(), 1_000u32)); + v + }; + let result = client.try_apply_snapshot_shares( + &issuer, + &symbol_short!("ns"), + &token, + &1u64, + &0u32, + &holders, + ); + assert_frozen_err(result); + assert_eq!(client.get_holder_share(&issuer, &symbol_short!("ns"), &token, &holder), 0); +} + +// ─── 14. Meta-delegate ──────────────────────────────────────────────────────── + +#[test] +fn frozen_set_meta_delegate_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let delegate = Address::generate(&env); + let result = + client.try_set_meta_delegate(&issuer, &symbol_short!("ns"), &token, &delegate); + assert_frozen_err(result); + assert!(client.get_meta_delegate(&issuer, &symbol_short!("ns"), &token).is_none()); +} + +// ─── 15. Admin rotation ─────────────────────────────────────────────────────── + +#[test] +fn frozen_propose_admin_rotation_returns_contract_frozen() { + let env = Env::default(); + let (client, _, _, _, _) = frozen_setup(&env); + let new_admin = Address::generate(&env); + let result = client.try_propose_admin_rotation(&new_admin); + assert_frozen_err(result); + assert!(client.get_pending_admin_rotation().is_none()); +} + +#[test] +fn frozen_accept_admin_rotation_returns_contract_frozen() { + let env = Env::default(); + let (client, _, _, _, _) = frozen_setup(&env); + let new_admin = Address::generate(&env); + // accept_admin_rotation checks frozen before checking pending state + let result = client.try_accept_admin_rotation(&new_admin); + assert_frozen_err(result); +} + +#[test] +fn frozen_cancel_admin_rotation_returns_contract_frozen() { + let env = Env::default(); + let (client, _, _, _, _) = frozen_setup(&env); + let result = client.try_cancel_admin_rotation(); + assert_frozen_err(result); +} + +// ─── 16. Offering-scoped freeze controls ───────────────────────────────────── + +#[test] +fn frozen_freeze_offering_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + // freeze_offering itself checks global freeze first (fail-closed) + let result = + client.try_freeze_offering(&issuer, &issuer, &symbol_short!("ns"), &token); + assert_frozen_err(result); +} + +#[test] +fn frozen_unfreeze_offering_returns_contract_frozen() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); + let result = + client.try_unfreeze_offering(&issuer, &issuer, &symbol_short!("ns"), &token); + assert_frozen_err(result); +} + +// ─── 17. Audit repair ──────────────────────────────────────────────────────── + +#[test] +fn frozen_repair_audit_summary_returns_contract_frozen() { + let env = Env::default(); + let (client, admin, issuer, token, _) = frozen_setup(&env); + let result = client.try_repair_audit_summary( + &admin, + &issuer, + &symbol_short!("ns"), + &token, + ); + assert_frozen_err(result); +} + +// ─── 18. Migration ──────────────────────────────────────────────────────────── + +#[test] +fn frozen_migrate_returns_contract_frozen() { + let env = Env::default(); + let (client, _, _, _, _) = frozen_setup(&env); + let result = client.try_migrate(); + assert_frozen_err(result); +} + +// ─── 19. Intentional exceptions — claim is NOT blocked ─────────────────────── + +/// `claim` must succeed (or fail for a business reason, never ContractFrozen). +/// This test verifies the intentional exception: holders can always exit. +#[test] +fn frozen_claim_is_not_blocked() { let env = Env::default(); env.mock_all_auths(); let contract_id = env.register_contract(None, RevoraRevenueShare); @@ -29,7 +458,54 @@ fn setup() -> (Env, RevoraRevenueShareClient<'static>, Address, Symbol, Address, let issuer = Address::generate(&env); let ns = symbol_short!("test"); let token = Address::generate(&env); - let payout = env.register_stellar_asset_contract(admin.clone()); + let payout_asset = Address::generate(&env); + client.register_offering(&issuer, &symbol_short!("ns"), &token, &1_000u32, &payout_asset, &0i128, &symbol_short!(""), &0); + + let holder = Address::generate(&env); + client.set_holder_share(&issuer, &symbol_short!("ns"), &token, &holder, &1_000u32); + + // Freeze the contract. + client.freeze(); + assert!(client.is_frozen()); + + // claim must NOT return ContractFrozen — it should return NoPendingClaims + // (no periods deposited) rather than ContractFrozen. + let result = client.try_claim(&holder, &issuer, &symbol_short!("ns"), &token, &50u32); + match result { + Err(Ok(RevoraError::ContractFrozen)) => { + panic!("claim must not be blocked by global freeze") + } + _ => {} // any other result (including NoPendingClaims) is acceptable + } +} + +/// After a frozen `report_revenue` call, the audit summary must remain absent. +#[test] +fn frozen_report_revenue_no_partial_write() { + let env = Env::default(); + let (client, _, issuer, token, payout_asset) = frozen_setup(&env); + + let _ = client.try_report_revenue( + &issuer, + &symbol_short!("ns"), + &token, + &payout_asset, + &1_000i128, + &1u64, + &false, + ); + + // Audit summary must not have been created. + assert!(client.get_audit_summary(&issuer, &symbol_short!("ns"), &token).is_none()); + // Revenue index must be zero. + assert_eq!(client.get_revenue_by_period(&issuer, &symbol_short!("ns"), &token, &1u64), 0); +} + +/// After a frozen `set_holder_share`, the holder's share must remain 0. +#[test] +fn frozen_set_holder_share_no_partial_write() { + let env = Env::default(); + let (client, _, issuer, token, _) = frozen_setup(&env); let holder = Address::generate(&env); client.initialize(&admin, &None::
, &None::); diff --git a/src/test_indexer_fixtures.rs b/src/test_indexer_fixtures.rs index 99d65d8a..f3759df9 100644 --- a/src/test_indexer_fixtures.rs +++ b/src/test_indexer_fixtures.rs @@ -16,7 +16,7 @@ fn setup_with_offering(env: &Env) -> (RevoraRevenueShareClient, Address, Address let token = Address::generate(env); let payout_asset = Address::generate(env); client.initialize(&admin, &None::
, &None::); - client.register_offering(&admin, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&admin, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); (client, admin, token, payout_asset) } @@ -150,7 +150,7 @@ fn register_offering_emits_ofr_reg2_v2_event() { client.initialize(&admin, &None::
, &None::); let before = env.events().all().len(); - client.register_offering(&admin, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&admin, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); let events = env.events().all(); assert!(events.len() > before, "register_offering must emit at least one event"); @@ -176,7 +176,7 @@ fn register_offering_v2_event_data_starts_with_version_2() { client.initialize(&admin, &None::
, &None::); let before = env.events().all().len(); - client.register_offering(&admin, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&admin, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); let events = env.events().all(); let new_events = events.slice(before as u32..); diff --git a/src/test_min_revenue_threshold_boundary.rs b/src/test_min_revenue_threshold_boundary.rs index ca9a2fdc..6df72548 100644 --- a/src/test_min_revenue_threshold_boundary.rs +++ b/src/test_min_revenue_threshold_boundary.rs @@ -32,7 +32,7 @@ fn setup() -> (Env, Address, Address, Address, Address) { let token = Address::generate(&env); let payout = Address::generate(&env); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout, &0, &symbol_short!(""), &0); (env, contract_id, issuer, token, payout) } diff --git a/src/test_namespaces.rs b/src/test_namespaces.rs index 8f11cf17..9ac36558 100644 --- a/src/test_namespaces.rs +++ b/src/test_namespaces.rs @@ -25,9 +25,9 @@ fn test_namespace_isolation() { let ns_2 = symbol_short!("ns2"); // Issuer A registers in ns1 - client.register_offering(&issuer_a, &Vec::new(&env), &1u32, &ns_1, &token, &1000, &token, &0); + client.register_offering(&issuer_a, &ns_1, &token, &1000, &token, &0, &symbol_short!(""), &0); // Issuer B registers in ns2 with SAME token - client.register_offering(&issuer_b, &Vec::new(&env), &1u32, &ns_2, &token, &2000, &token, &0); + client.register_offering(&issuer_b, &ns_2, &token, &2000, &token, &0, &symbol_short!(""), &0); // Set holder shares differently let holder = Address::generate(&env); @@ -64,8 +64,8 @@ fn test_same_issuer_different_namespaces() { let ns_1 = symbol_short!("prod"); let ns_2 = symbol_short!("stg"); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns_1, &token, &1000, &token, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns_2, &token, &2000, &token, &0); + client.register_offering(&issuer, &ns_1, &token, &1000, &token, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &ns_2, &token, &2000, &token, &0, &symbol_short!(""), &0); client.set_snapshot_config(&issuer, &ns_1, &token, &true); client.set_snapshot_config(&issuer, &ns_2, &token, &false); @@ -88,8 +88,8 @@ fn test_cross_namespace_blacklist_isolation() { let investor = Address::generate(&env); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns_1, &token, &1000, &token, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns_2, &token, &1000, &token, &0); + client.register_offering(&issuer, &ns_1, &token, &1000, &token, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &ns_2, &token, &1000, &token, &0, &symbol_short!(""), &0); // Blacklist in NS 1 client.blacklist_add(&issuer, &issuer, &ns_1, &token, &investor); @@ -131,7 +131,7 @@ fn test_unauthorized_issuer_access_fails() { let token = Address::generate(&env); let ns_1 = symbol_short!("ns1"); - client.register_offering(&issuer_real, &Vec::new(&env), &1u32, &ns_1, &token, &1000, &token, &0); + client.register_offering(&issuer_real, &ns_1, &token, &1000, &token, &0, &symbol_short!(""), &0); // Attacker tries to blacklist for real issuer's offering // Note: mock_all_auths will allow the call to reach the contract, @@ -165,7 +165,7 @@ fn test_transfer_maintains_namespace_isolation() { let token_1 = Address::generate(&env); let ns_1 = symbol_short!("ns1"); - client.register_offering(&issuer_a, &Vec::new(&env), &1u32, &ns_1, &token_1, &1000, &token_1, &0); + client.register_offering(&issuer_a, &ns_1, &token_1, &1000, &token_1, &0, &symbol_short!(""), &0); client.set_claim_delay(&issuer_a, &ns_1, &token_1, &3600); // Transfer to Issuer B @@ -198,10 +198,10 @@ fn test_duplicate_registration_fails() { let ns = symbol_short!("ns1"); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1000, &token, &0); + client.register_offering(&issuer, &ns, &token, &1000, &token, &0, &symbol_short!(""), &0); // Exact same registration should fail - let res = client.try_register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1000, &token, &0); + let res = client.try_register_offering(&issuer, &ns, &token, &1000, &token, &0, &symbol_short!(""), &0); assert!(res.is_err()); } @@ -220,8 +220,8 @@ fn test_aggregation_across_namespaces() { let ns_2 = symbol_short!("stg"); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns_1, &token1, &1000, &token1, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns_2, &token2, &1000, &token2, &0); + client.register_offering(&issuer, &ns_1, &token1, &1000, &token1, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &ns_2, &token2, &1000, &token2, &0, &symbol_short!(""), &0); // Report revenue in both namespaces client.report_revenue(&issuer, &ns_1, &token1, &token1, &50000, &1, &false); @@ -252,7 +252,7 @@ fn test_blacklist_precedence_over_whitelist() { // Initialize and register offering client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &ns, &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // Add investor to whitelist first client.whitelist_add(&issuer, &issuer, &ns, &token, &investor); @@ -296,7 +296,7 @@ fn test_blacklist_unaffected_by_whitelist_removal() { let ns = symbol_short!("def"); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &ns, &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // Add to both lists client.whitelist_add(&issuer, &issuer, &ns, &token, &investor); @@ -325,7 +325,7 @@ fn test_blacklist_removal_doesnt_whitelist() { let ns = symbol_short!("def"); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &ns, &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // Blacklist investor client.blacklist_add(&issuer, &issuer, &ns, &token, &investor); @@ -353,7 +353,7 @@ fn test_blacklist_add_idempotent() { let ns = symbol_short!("def"); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &ns, &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // Add to blacklist multiple times client.blacklist_add(&issuer, &issuer, &ns, &token, &investor); @@ -379,7 +379,7 @@ fn test_blacklist_remove_idempotent() { let ns = symbol_short!("def"); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &ns, &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // Remove from empty blacklist multiple times (should not panic) client.blacklist_remove(&issuer, &issuer, &ns, &token, &investor); @@ -407,7 +407,7 @@ fn test_mixed_sequence_with_share_updates() { let ns = symbol_short!("def"); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &ns, &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // Set initial shares client.set_holder_share(&issuer, &ns, &token, &holder_a, &5000); @@ -476,7 +476,7 @@ fn test_whitelist_only_mode() { let ns = symbol_short!("def"); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &ns, &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // Add only one address to whitelist client.whitelist_add(&issuer, &issuer, &ns, &token, &whitelisted); @@ -532,7 +532,7 @@ fn test_blacklist_only_mode() { let ns = symbol_short!("def"); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &ns, &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // Add only one address to blacklist client.blacklist_add(&issuer, &issuer, &ns, &token, &blacklisted); @@ -587,7 +587,7 @@ fn test_complex_add_remove_sequence() { let ns = symbol_short!("def"); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &ns, &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // Complex sequence client.blacklist_add(&issuer, &issuer, &ns, &token, &investor); @@ -636,7 +636,7 @@ fn test_multiple_investors_precedence() { let ns = symbol_short!("def"); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &ns, &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // inv_a: whitelisted only client.whitelist_add(&issuer, &issuer, &ns, &token, &inv_a); @@ -711,7 +711,7 @@ fn test_whitelist_disable_changes_eligibility() { let ns = symbol_short!("def"); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &ns, &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // Enable whitelist client.whitelist_add(&issuer, &issuer, &ns, &token, &whitelisted); @@ -771,7 +771,7 @@ fn test_no_lists_all_eligible() { let ns = symbol_short!("def"); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &ns, &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); // No blacklist or whitelist entries assert!(!client.is_whitelist_enabled(&issuer, &ns, &token)); diff --git a/src/test_override_audit_trail.rs b/src/test_override_audit_trail.rs index ead30fe9..55de778e 100644 --- a/src/test_override_audit_trail.rs +++ b/src/test_override_audit_trail.rs @@ -46,7 +46,7 @@ fn setup() -> (Env, Address, Address, Address, Address) { let token = Address::generate(&env); let payout_asset = Address::generate(&env); client.initialize(&issuer, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &payout_asset, &0, &symbol_short!(""), &0); (env, contract_id, issuer, token, payout_asset) } diff --git a/src/test_pause_tiers.rs b/src/test_pause_tiers.rs index 1f83382b..63e69017 100644 --- a/src/test_pause_tiers.rs +++ b/src/test_pause_tiers.rs @@ -73,7 +73,8 @@ fn setup_with_offering( &10_000, &payment_token.address(), &0, - &None); + &symbol_short!(""), + &0); client.set_holder_share(&issuer, &symbol_short!("def"), &offering_token, &holder, &10_000); // Mint to issuer and deposit period 1 @@ -231,7 +232,7 @@ fn soft_pause_register_offering_blocked() { let issuer = Address::generate(&env); let token = Address::generate(&env); let result = - client.try_register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.try_register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); assert_eq!(result, Err(Ok(RevoraError::ContractPaused))); } @@ -306,7 +307,7 @@ fn hard_pause_register_offering_blocked() { let issuer = Address::generate(&env); let token = Address::generate(&env); let result = - client.try_register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.try_register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); assert_eq!(result, Err(Ok(RevoraError::ContractPaused))); } diff --git a/src/test_period_id_boundary.rs b/src/test_period_id_boundary.rs index aa32134c..d96d9cf7 100644 --- a/src/test_period_id_boundary.rs +++ b/src/test_period_id_boundary.rs @@ -68,7 +68,8 @@ fn setup_funded() -> (Env, RevoraRevenueShareClient<'static>, Address, Address, &1_000, &payment_token, &0, - &None); + &symbol_short!(""), + &0); mint(&env, &payment_token, &issuer, 1_000_000_000); (env, client, issuer, offering_token, payment_token) } @@ -84,7 +85,7 @@ fn report_revenue_zero_period_id_rejected() { let client = make_client(&env); let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); let result = client.try_report_revenue(&issuer, &symbol_short!("def"), &token, &token, &100, &0, &false); @@ -183,7 +184,7 @@ fn report_revenue_period_id_one_accepted() { let client = make_client(&env); let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); let result = client.try_report_revenue(&issuer, &symbol_short!("def"), &token, &token, &500, &1, &false); @@ -198,7 +199,7 @@ fn report_revenue_period_id_max_rejected() { let client = make_client(&env); let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); let result = client.try_report_revenue( &issuer, @@ -220,7 +221,7 @@ fn report_revenue_period_id_near_max_rejected() { let client = make_client(&env); let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); let result = client.try_report_revenue( &issuer, @@ -339,7 +340,7 @@ fn report_revenue_duplicate_without_override_no_state_change() { let client = make_client(&env); let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); client .report_revenue(&issuer, &symbol_short!("def"), &token, &token, &500, &7, &false) @@ -363,7 +364,7 @@ fn report_revenue_duplicate_with_override_updates_state() { let client = make_client(&env); let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); client .report_revenue(&issuer, &symbol_short!("def"), &token, &token, &500, &7, &false) @@ -390,7 +391,7 @@ fn negative_amount_rejected_before_period_id_check() { let client = make_client(&env); let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); // Negative amount with valid period_id let r = @@ -406,7 +407,7 @@ fn zero_amount_accepted_by_report_revenue() { let client = make_client(&env); let issuer = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); let r = client.try_report_revenue(&issuer, &symbol_short!("def"), &token, &token, &0, &3, &false); @@ -441,7 +442,7 @@ fn report_revenue_wrong_issuer_rejected() { let issuer = Address::generate(&env); let attacker = Address::generate(&env); let token = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); let r = client.try_report_revenue( &attacker, @@ -499,7 +500,8 @@ fn period_id_isolated_across_offerings() { &1_000, &payment_token, &0, - &None); + &symbol_short!(""), + &0); client.register_offering( &issuer_b, &Vec::new(&env), @@ -509,7 +511,8 @@ fn period_id_isolated_across_offerings() { &1_000, &payment_token, &0, - &None); + &symbol_short!(""), + &0); mint(&env, &payment_token, &issuer_a, 1_000_000); mint(&env, &payment_token, &issuer_b, 1_000_000); @@ -542,8 +545,8 @@ fn report_revenue_period_id_isolated_across_offerings() { let token_a = Address::generate(&env); let token_b = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_a, &1_000, &token_a, &0); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token_b, &1_000, &token_b, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token_a, &1_000, &token_a, &0, &symbol_short!(""), &0); + client.register_offering(&issuer, &symbol_short!("def"), &token_b, &1_000, &token_b, &0, &symbol_short!(""), &0); client .report_revenue(&issuer, &symbol_short!("def"), &token_a, &token_a, &100, &9, &false) @@ -571,7 +574,7 @@ fn frozen_contract_rejects_report_revenue() { let token = Address::generate(&env); client.initialize(&admin, &None::
, &None::); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &1_000, &token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &1_000, &token, &0, &symbol_short!(""), &0); client.freeze(); let r = @@ -600,7 +603,8 @@ fn frozen_contract_rejects_deposit_revenue() { &1_000, &payment_token, &0, - &None); + &symbol_short!(""), + &0); mint(&env, &payment_token, &issuer, 1_000_000); client.freeze(); diff --git a/src/test_prove_distribution.rs b/src/test_prove_distribution.rs index bf721fe9..4ad3d5fd 100644 --- a/src/test_prove_distribution.rs +++ b/src/test_prove_distribution.rs @@ -44,7 +44,8 @@ fn prove_distribution_normal_case() { &1_000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); let holder_a = Address::generate(&env); let holder_b = Address::generate(&env); @@ -111,7 +112,8 @@ fn prove_distribution_digest_is_deterministic() { &1_000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); let holder_a = Address::generate(&env); let holder_b = Address::generate(&env); @@ -169,7 +171,8 @@ fn prove_distribution_sorting_makes_order_invariant() { &1_000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); let holder_a = Address::generate(&env); let holder_b = Address::generate(&env); @@ -233,7 +236,8 @@ fn prove_distribution_identical_bps_tie_break_by_address() { &1_000u32, &payment_token, &0i128, - ); + &symbol_short!(""), + &0); // Generate addresses until we have two with the same BPS; the tie-break must be // by XDR address bytes ascending regardless of generation order. @@ -356,7 +360,8 @@ fn prove_distribution_unknown_period_id_returns_zero_payouts() { &1_000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); let holder_a = Address::generate(&env); client.set_holder_share(&issuer, &symbol_short!("def"), &token, &holder_a, &3_000u32); @@ -408,7 +413,8 @@ fn prove_distribution_zero_share_bps_yields_zero_payout() { &1_000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); mint(&env, &payment_token, &issuer, 10_000_000); client.deposit_revenue( @@ -459,7 +465,8 @@ fn prove_distribution_usdc_6_decimals_normalizes_correctly() { &1_000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); // Configure 6-decimal payment token (USDC-style) client.set_payment_token_decimals(&issuer, &symbol_short!("def"), &token, &6u32); @@ -516,7 +523,8 @@ fn prove_distribution_respects_round_half_up_mode() { &1_000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); client.set_rounding_mode(&issuer, &symbol_short!("def"), &token, &RoundingMode::RoundHalfUp); let holder = Address::generate(&env); @@ -561,7 +569,8 @@ fn prove_distribution_caps_at_max_chunk_periods() { &1_000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); mint(&env, &payment_token, &issuer, 1_000_000); client.deposit_revenue( @@ -610,7 +619,8 @@ fn prove_distribution_entry_fields_match() { &1_000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); let holder = Address::generate(&env); client.set_holder_share(&issuer, &symbol_short!("def"), &token, &holder, &10_000u32); @@ -662,7 +672,8 @@ fn prove_distribution_different_periods_produce_different_digests() { &1_000u32, &payment_token, &0i128, - &None); + &symbol_short!(""), + &0); let holder = Address::generate(&env); client.set_holder_share(&issuer, &symbol_short!("def"), &token, &holder, &5_000u32); diff --git a/src/test_reconciliation_bug.rs b/src/test_reconciliation_bug.rs index 28489350..bff71de1 100644 --- a/src/test_reconciliation_bug.rs +++ b/src/test_reconciliation_bug.rs @@ -48,7 +48,7 @@ fn setup_offering_with_payment_token( let (payment_token, _pt_admin) = create_payment_token(&env); // Register offering (5000 bps = 50% revenue share) - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payment_token, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payment_token, &0, &symbol_short!(""), &0); // Mint payment tokens to the issuer so they can deposit mint_tokens(&env, &payment_token, &issuer, 10_000_000); diff --git a/src/test_snapshot_finalization.rs b/src/test_snapshot_finalization.rs index 04c1fed1..c129ab46 100644 --- a/src/test_snapshot_finalization.rs +++ b/src/test_snapshot_finalization.rs @@ -18,7 +18,7 @@ fn setup_snapshot_test( let token = Address::generate(&env); let payout_asset = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout_asset, &0, &symbol_short!(""), &0); (env, client, issuer, token, payout_asset, contract_id) } diff --git a/src/test_snapshot_monotonicity_replay.rs b/src/test_snapshot_monotonicity_replay.rs index 044a37d4..95ce37e0 100644 --- a/src/test_snapshot_monotonicity_replay.rs +++ b/src/test_snapshot_monotonicity_replay.rs @@ -79,7 +79,8 @@ fn setup() -> (Env, RevoraRevenueShareClient<'static>, Address, Address) { &5_000, &payout_asset, &0, - &None); + &symbol_short!(""), + &0); // Enable snapshot distribution for this offering. client.set_snapshot_config(&issuer, &symbol_short!("def"), &token, &true); @@ -345,7 +346,7 @@ fn snapshot_replay_is_isolated_per_offering() { // Register a second offering (different token, same issuer/namespace). let token_b = Address::generate(&env); let payout_b = Address::generate(&env); - client.register_offering(&issuer, &Vec::new(&env), &1u32, &ns, &token_b, &5_000, &payout_b, &0); + client.register_offering(&issuer, &ns, &token_b, &5_000, &payout_b, &0, &symbol_short!(""), &0); client.set_snapshot_config(&issuer, &ns, &token_b, &true); // Advance offering A to ref 100. diff --git a/src/test_snapshot_negative_matrix.rs b/src/test_snapshot_negative_matrix.rs index 095fba58..d36f87c2 100644 --- a/src/test_snapshot_negative_matrix.rs +++ b/src/test_snapshot_negative_matrix.rs @@ -72,7 +72,7 @@ fn setup_snapshot_test() -> (Env, RevoraRevenueShareClient<'static>, Address, Ad let payout_asset = Address::generate(&env); // Register offering with payout_asset - client.register_offering(&issuer, &Vec::new(&env), &1u32, &symbol_short!("def"), &token, &5_000, &payout_asset, &0); + client.register_offering(&issuer, &symbol_short!("def"), &token, &5_000, &payout_asset, &0, &symbol_short!(""), &0); (env, client, issuer, token, payout_asset, contract_id) } diff --git a/src/test_time_windows.rs b/src/test_time_windows.rs index b10d6466..dc12fc0d 100644 --- a/src/test_time_windows.rs +++ b/src/test_time_windows.rs @@ -130,7 +130,8 @@ fn setup_with_holder( &10_000, // 100% share pool &payment_token, &0, - &None); + &symbol_short!(""), + &0); mint(&env, &payment_token, &issuer, 10_000_000); RevoraRevenueShareClient::new(&env, &cid).set_holder_share( &issuer, @@ -169,14 +170,7 @@ fn report_window_unset_always_open() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); // Verify no window is stored assert!(client.get_report_window(&issuer, &symbol_short!("ns"), &token).is_none()); @@ -205,14 +199,7 @@ fn report_window_before_start_is_closed() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); // Window: [1000, 2000] client.set_report_window(&issuer, &symbol_short!("ns"), &token, &1_000, &2_000); @@ -233,14 +220,7 @@ fn report_window_at_start_is_open_inclusive() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); client.set_report_window(&issuer, &symbol_short!("ns"), &token, &1_000, &2_000); @@ -259,14 +239,7 @@ fn report_window_inside_is_open() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); client.set_report_window(&issuer, &symbol_short!("ns"), &token, &1_000, &2_000); @@ -285,14 +258,7 @@ fn report_window_at_end_is_open_inclusive() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); client.set_report_window(&issuer, &symbol_short!("ns"), &token, &1_000, &2_000); @@ -311,14 +277,7 @@ fn report_window_after_end_is_closed() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); client.set_report_window(&issuer, &symbol_short!("ns"), &token, &1_000, &2_000); @@ -337,14 +296,7 @@ fn report_window_zero_width_open_at_exact_timestamp() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); // start == end: single-second window at T=5000 client.set_report_window(&issuer, &symbol_short!("ns"), &token, &5_000, &5_000); @@ -364,14 +316,7 @@ fn report_window_zero_width_closed_before() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); client.set_report_window(&issuer, &symbol_short!("ns"), &token, &5_000, &5_000); @@ -390,14 +335,7 @@ fn report_window_zero_width_closed_after() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); client.set_report_window(&issuer, &symbol_short!("ns"), &token, &5_000, &5_000); @@ -416,14 +354,7 @@ fn report_window_reconfigured_to_exclude_now_closes_reporting() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); // Initial window: [1000, 3000]; now = 2000 → open client.set_report_window(&issuer, &symbol_short!("ns"), &token, &1_000, &3_000); @@ -446,14 +377,7 @@ fn report_window_reconfigured_to_include_now_opens_reporting() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); // Initial window: [4000, 5000]; now = 2000 → closed client.set_report_window(&issuer, &symbol_short!("ns"), &token, &4_000, &5_000); @@ -657,14 +581,7 @@ fn set_report_window_valid_range_accepted() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); let r = client.try_set_report_window(&issuer, &symbol_short!("ns"), &token, &1_000, &2_000); assert!(r.is_ok()); @@ -683,14 +600,7 @@ fn set_report_window_zero_width_accepted() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); let r = client.try_set_report_window(&issuer, &symbol_short!("ns"), &token, &5_000, &5_000); assert!(r.is_ok(), "zero-width window must be accepted, got {r:?}"); @@ -705,14 +615,7 @@ fn set_report_window_inverted_range_rejected() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); let r = client.try_set_report_window(&issuer, &symbol_short!("ns"), &token, &2_000, &1_000); assert_eq!(r, Err(Ok(RevoraError::LimitReached))); @@ -730,14 +633,7 @@ fn set_claim_window_valid_range_accepted() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); let r = client.try_set_claim_window(&issuer, &symbol_short!("ns"), &token, &1_000, &2_000); assert!(r.is_ok()); @@ -756,14 +652,7 @@ fn set_claim_window_zero_width_accepted() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); let r = client.try_set_claim_window(&issuer, &symbol_short!("ns"), &token, &5_000, &5_000); assert!(r.is_ok(), "zero-width window must be accepted, got {r:?}"); @@ -778,14 +667,7 @@ fn set_claim_window_inverted_range_rejected() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); let r = client.try_set_claim_window(&issuer, &symbol_short!("ns"), &token, &2_000, &1_000); assert_eq!(r, Err(Ok(RevoraError::LimitReached))); @@ -895,22 +777,8 @@ fn report_window_is_scoped_per_offering() { let token_a = Address::generate(&env); let token_b = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token_a, - &1_000, - &token_a, - &0, - ); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token_b, - &1_000, - &token_b, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token_a, &1_000, &token_a, &0, &symbol_short!(""), &0); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token_b, &1_000, &token_b, &0, &symbol_short!(""), &0); // Close offering A's report window; leave B's unset (always open) client.set_report_window(&issuer, &symbol_short!("ns"), &token_a, &5_000, &6_000); @@ -956,21 +824,13 @@ fn claim_window_is_scoped_per_offering() { let holder = Address::generate(&env); RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token_a, - &10_000, - &payment_token, - &0, - ); + &issuer, &symbol_short!("ns"), &token_a, &10_000, &payment_token, &0, + &symbol_short!(""), + &0); RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token_b, - &10_000, - &payment_token, - &0, - ); + &issuer, &symbol_short!("ns"), &token_b, &10_000, &payment_token, &0, + &symbol_short!(""), + &0); mint(&env, &payment_token, &issuer, 10_000_000); RevoraRevenueShareClient::new(&env, &cid).set_holder_share( &issuer, @@ -1016,14 +876,7 @@ fn set_report_window_emits_event() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); let before = env.events().all().len(); client.set_report_window(&issuer, &symbol_short!("ns"), &token, &1_000, &2_000); @@ -1039,14 +892,7 @@ fn set_claim_window_emits_event() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); let before = env.events().all().len(); client.set_claim_window(&issuer, &symbol_short!("ns"), &token, &1_000, &2_000); @@ -1066,14 +912,7 @@ fn get_report_window_returns_none_when_unset() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); assert!(client.get_report_window(&issuer, &symbol_short!("ns"), &token).is_none()); } @@ -1087,14 +926,7 @@ fn get_claim_window_returns_none_when_unset() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); assert!(client.get_claim_window(&issuer, &symbol_short!("ns"), &token).is_none()); } @@ -1108,14 +940,7 @@ fn get_report_window_returns_correct_values() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); client.set_report_window(&issuer, &symbol_short!("ns"), &token, &1_234, &5_678); let w = client.get_report_window(&issuer, &symbol_short!("ns"), &token).unwrap(); @@ -1132,14 +957,7 @@ fn get_claim_window_returns_correct_values() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); client.set_claim_window(&issuer, &symbol_short!("ns"), &token, &9_000, &9_999); let w = client.get_claim_window(&issuer, &symbol_short!("ns"), &token).unwrap(); @@ -1156,14 +974,7 @@ fn set_report_window_overwrites_previous() { let client = RevoraRevenueShareClient::new(&env, &cid); let issuer = Address::generate(&env); let token = Address::generate(&env); - RevoraRevenueShareClient::new(&env, &cid).register_offering( - &issuer, - &symbol_short!("ns"), - &token, - &1_000, - &token, - &0, - ); + RevoraRevenueShareClient::new(&env, &cid).register_offering(&issuer, &symbol_short!("ns"), &token, &1_000, &token, &0, &symbol_short!(""), &0); client.set_report_window(&issuer, &symbol_short!("ns"), &token, &1_000, &2_000); client.set_report_window(&issuer, &symbol_short!("ns"), &token, &3_000, &4_000);