feat: cancellation fee, StreamInterface, role-based access control, sender collateral - #539
Merged
Conversation
…ollateral - SoroStream#288: Add admin-configurable cancellation fee (cancellation_fee_basis_points) - set_cancellation_fee / get_cancellation_fee_bps functions - Fee deducted from sender refund on early cancel_stream - No fee for naturally expired streams or fee-exempt senders - CancelFeeCollected event emitted on each fee deduction - FeeManager role (see SoroStream#292) may also configure the fee - SoroStream#291: Add ISoroStreamComposability trait for external contract integration - composability.rs: ISoroStreamComposability trait with #[contractclient] - Exposes composable_create_stream, composable_withdraw, composable_get_claimable, composable_get_stream, composable_get_streams_for, composable_has_claimable, composable_get_version - Full SoroStreamInterface trait in interface.rs as canonical integration target - Usage example documented in composability.rs doc-comment - SoroStream#292: Add role-based access control with four roles - roles.rs: AdminRole enum (SuperAdmin, FeeManager, EmergencyPause, Analytics) - Persistent storage helpers: get/set/revoke_* for each role - lib.rs: assign_fee_manager, revoke_fee_manager, get_fee_manager - lib.rs: assign_emergency_pause_role, revoke_emergency_pause_role - lib.rs: assign_analytics_role, revoke_analytics_role - Audit log entry + RoleAssigned / RoleRevoked events on each change - has_any_admin_role query function - SoroStream#293: Add sender collateral / stake mechanism - stake / initiate_unstake / complete_unstake with 24h cooldown - slash_stake: admin can forfeit bad-actor stake to any destination - set_min_stake_amount / get_min_stake_amount per token - check_sender_stake called in create_stream (no-op if min=0) - StakeDeposited, StakeSlashed, MinStakeSet, UnstakeInitiated, UnstakeCompleted events - Fix OptionalStreamStatus wrapper for StreamQueryFilter (Soroban contracttype does not support Option<EnumType> in struct fields) - Update integration_tests.rs and rate_limit_tests.rs to use CreateStreamParams - Fix clippy: remove always-false 0i128 < 0 guard in create_stream_with_federation closes SoroStream#288 closes SoroStream#291 closes SoroStream#292 closes SoroStream#293
|
@Me7858 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements four protocol enhancements as a single cohesive PR. All features are gated behind admin-configurable parameters and default to their existing (no-op) behaviour on existing deployments.
#288 — Cancellation Fee
set_cancellation_fee(callable by super-admin or FeeManager role)get_cancellation_fee_bpsreturns the current rate (0 by default)cancel_stream, a configurable percentage (up to 100%) is deducted from the sender's unstreamed refund and accumulated in the protocol treasuryend_time(natural expiry)CancelFeeCollectedevent emitted with(stream_id, sender, fee_amount, fee_bps)closes #288
#291 — StreamInterface / Composability Trait
composability.rsdefines theISoroStreamComposabilitytrait with#[contractclient]SoroStreamComposabilityClientstub enables external contracts (lending protocols, DAOs, vesting managers) to create, query, and withdraw from streams with minimal surface areacomposable_create_stream,composable_withdraw,composable_get_claimable,composable_get_stream,composable_get_streams_for,composable_has_claimable,composable_get_versionSoroStreamInterfaceininterface.rsremains the canonical reference for all functionscomposability.rsdoc-commentcloses #291
#292 — Role-Based Access Control
roles.rsimplements the role registry with four roles:SuperAdmin— full privileges, stored under existingADMIN_KEYFeeManager— may callset_protocol_fee,set_cancellation_fee,sweep_feesEmergencyPause— may callemergency_pause/emergency_resumeAnalytics— read-only access toget_stats,get_protocol_stats, audit logget/set/revoke_*) with instance-storage keysrfee,rpause,ranalassign_fee_manager,revoke_fee_manager,assign_emergency_pause_role,revoke_emergency_pause_role,assign_analytics_role,revoke_analytics_roleRoleAssigned/RoleRevokedevents and audit log entries on every changecloses #292
#293 — Sender Collateral / Stake Mechanism
stake(sender, token, amount)— sender deposits collateral; held in contract escrowinitiate_unstake(sender, token, amount)— begins 24-hour cooldown before withdrawalcomplete_unstake(sender, token)— finalises unstake after cooldown elapsesslash_stake(admin, sender, token, amount, destination)— super-admin only; forfeits collateral to any address (typically treasury) as penaltyset_min_stake_amount(admin, token, amount)/get_min_stake_amount(token)— per-token minimum thresholdcheck_sender_stakehelper called increate_stream; returnsInsufficientStakeif minimum is set and not met; no-op when minimum is 0 (default)StakeDeposited,UnstakeInitiated,UnstakeCompleted,StakeSlashed,MinStakeSetcloses #293
Technical Notes
OptionalStreamStatuswrapper enum intypes.rs— Soroban's#[contracttype]macro cannot serialiseOption<EnumType>directly inside a struct; replaced with an explicit enum variantintegration_tests.rsandrate_limit_tests.rsto use the refactoredCreateStreamParamsstruct signature0i128 < 0guard flagged by ClippyTesting