From 2468e3e075d33f3c334ba8e5fd3a1071f78f7447 Mon Sep 17 00:00:00 2001 From: Rahman Lawal Date: Fri, 29 May 2026 00:59:24 +0100 Subject: [PATCH] update fee config --- contracts/stream_contract/src/events.rs | 24 ++++++++++ contracts/stream_contract/src/lib.rs | 32 +++++++++++-- contracts/stream_contract/src/test.rs | 64 +++++++++++++++++++++++-- 3 files changed, 112 insertions(+), 8 deletions(-) diff --git a/contracts/stream_contract/src/events.rs b/contracts/stream_contract/src/events.rs index 767633a1..a3d35cde 100644 --- a/contracts/stream_contract/src/events.rs +++ b/contracts/stream_contract/src/events.rs @@ -70,6 +70,30 @@ pub struct FeeCollectedEvent { pub token: Address, } +/// Emitted once during one-time protocol initialization. +/// +/// Topic: `("initialized",)` +#[contracttype] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct InitializedEvent { + pub admin: Address, + pub treasury: Address, + pub fee_rate_bps: u32, +} + +/// Emitted when the fee configuration (treasury address or fee rate) is updated. +/// +/// Topic: `("fee_config_updated",)` +#[contracttype] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FeeConfigUpdatedEvent { + pub admin: Address, + pub old_treasury: Address, + pub new_treasury: Address, + pub old_fee_rate_bps: u32, + pub new_fee_rate_bps: u32, +} + /// Emitted when the protocol admin is transferred to a new address. /// /// Topic: `("admin_transferred",)` diff --git a/contracts/stream_contract/src/lib.rs b/contracts/stream_contract/src/lib.rs index 838c6320..d7c5aa64 100644 --- a/contracts/stream_contract/src/lib.rs +++ b/contracts/stream_contract/src/lib.rs @@ -12,9 +12,9 @@ use soroban_sdk::{contract, contractimpl, token, vec, Address, Env, InvokeError, use errors::StreamError; use events::{ - AdminTransferredEvent, FeeCollectedEvent, StreamCancelledEvent, StreamCreatedEvent, - FeeCollectedEvent, StreamCancelledEvent, StreamCompletedEvent, StreamCreatedEvent, - StreamPausedEvent, StreamResumedEvent, StreamToppedUpEvent, TokensWithdrawnEvent, + AdminTransferredEvent, FeeCollectedEvent, FeeConfigUpdatedEvent, InitializedEvent, + StreamCancelledEvent, StreamCompletedEvent, StreamCreatedEvent, StreamPausedEvent, + StreamResumedEvent, StreamToppedUpEvent, TokensWithdrawnEvent, }; use storage::{ config_exists, load_config, load_stream, next_stream_id, save_config, save_stream, @@ -55,11 +55,21 @@ impl StreamContract { save_config( &env, &ProtocolConfig { + admin: admin.clone(), + treasury: treasury.clone(), + fee_rate_bps, + }, + ); + + env.events().publish( + (Symbol::new(&env, "initialized"),), + InitializedEvent { admin, treasury, fee_rate_bps, }, ); + Ok(()) } @@ -88,11 +98,23 @@ impl StreamContract { save_config( &env, &ProtocolConfig { - admin: config.admin, - treasury, + admin: config.admin.clone(), + treasury: treasury.clone(), fee_rate_bps, }, ); + + env.events().publish( + (Symbol::new(&env, "fee_config_updated"),), + FeeConfigUpdatedEvent { + admin, + old_treasury: config.treasury, + new_treasury: treasury, + old_fee_rate_bps: config.fee_rate_bps, + new_fee_rate_bps: fee_rate_bps, + }, + ); + Ok(()) } diff --git a/contracts/stream_contract/src/test.rs b/contracts/stream_contract/src/test.rs index 073d2d8c..b8816c09 100644 --- a/contracts/stream_contract/src/test.rs +++ b/contracts/stream_contract/src/test.rs @@ -10,9 +10,9 @@ use soroban_sdk::{ use errors::StreamError; use events::{ - AdminTransferredEvent, FeeCollectedEvent, StreamCancelledEvent, StreamCreatedEvent, - FeeCollectedEvent, StreamCancelledEvent, StreamCompletedEvent, StreamCreatedEvent, - StreamPausedEvent, StreamResumedEvent, StreamToppedUpEvent, TokensWithdrawnEvent, + AdminTransferredEvent, FeeCollectedEvent, FeeConfigUpdatedEvent, InitializedEvent, + StreamCancelledEvent, StreamCompletedEvent, StreamCreatedEvent, StreamPausedEvent, + StreamResumedEvent, StreamToppedUpEvent, TokensWithdrawnEvent, }; use types::{DataKey, Stream, StreamStatus}; @@ -183,6 +183,64 @@ fn test_update_fee_config_rejects_invalid_fee_rate() { assert_eq!(result, Err(Ok(StreamError::InvalidFeeRate))); } +#[test] +fn test_initialize_emits_event() { + let env = Env::default(); + env.mock_all_auths(); + let client = create_contract(&env); + + let admin = Address::generate(&env); + let treasury = Address::generate(&env); + + client.initialize(&admin, &treasury, &100); + + let events = env.events().all(); + let ev = events + .iter() + .find(|e| { + Symbol::try_from_val(&env, &e.1.get(0).unwrap()).unwrap() + == Symbol::new(&env, "initialized") + }) + .expect("initialized event not found"); + + let payload: InitializedEvent = + InitializedEvent::try_from_val(&env, &ev.2).unwrap(); + assert_eq!(payload.admin, admin); + assert_eq!(payload.treasury, treasury); + assert_eq!(payload.fee_rate_bps, 100); +} + +#[test] +fn test_update_fee_config_emits_event() { + let env = Env::default(); + env.mock_all_auths(); + let client = create_contract(&env); + + let admin = Address::generate(&env); + let old_treasury = Address::generate(&env); + let new_treasury = Address::generate(&env); + + client.initialize(&admin, &old_treasury, &500); + client.update_fee_config(&admin, &new_treasury, &300); + + let events = env.events().all(); + let ev = events + .iter() + .find(|e| { + Symbol::try_from_val(&env, &e.1.get(0).unwrap()).unwrap() + == Symbol::new(&env, "fee_config_updated") + }) + .expect("fee_config_updated event not found"); + + let payload: FeeConfigUpdatedEvent = + FeeConfigUpdatedEvent::try_from_val(&env, &ev.2).unwrap(); + assert_eq!(payload.admin, admin); + assert_eq!(payload.old_treasury, old_treasury); + assert_eq!(payload.new_treasury, new_treasury); + assert_eq!(payload.old_fee_rate_bps, 500); + assert_eq!(payload.new_fee_rate_bps, 300); +} + // ─── create_stream ──────────────────────────────────────────────────────────── #[test]