This implementation transitions the protocol fee from a hardcoded constant to a dynamically governed variable with the following key features:
- DAO-controlled: Only authorized DAO members can propose fee changes
- Maximum cap: Hardcoded maximum of 500 bps (5%) to prevent predatory fees
- 7-day timelock: Fee increases require a 7-day timelock, decreases are immediate
- Multi-sig consensus: Requires minimum 3 DAO member votes for execution
- Transparent events: Emits
ProtocolFeeUpdateScheduledandProtocolFeeUpdateExecutedevents - Precise math: Uses basis points for accurate fee calculation without dust issues
-
Constants and Data Structures
PROTOCOL_FEE_MAX_BPS: 500 bps maximumPROTOCOL_FEE_TIMELOCK_DURATION: 7 days for increasesDEFAULT_PROTOCOL_FEE_BPS: 200 bps default feeProtocolFeeConfig: Stores current fee configurationProtocolFeeUpdateProposal: Manages fee change proposals
-
Core Functions
initialize(): Sets up default protocol fee configurationget_protocol_fee_config(): Returns current fee settingspropose_protocol_fee_update(): Creates new fee change proposalsvote_protocol_fee_update(): Allows DAO members to voteexecute_protocol_fee_update(): Executes approved proposals
-
Events
ProtocolFeeUpdateScheduled: Emitted when proposal is createdProtocolFeeUpdateExecuted: Emitted when proposal is executed
-
Comprehensive Tests
- Fee initialization verification
- Proposal creation for increases/decreases
- Maximum fee enforcement
- Timelock mechanism testing
- Mathematical precision verification
- Event emission validation
- Distribution Logic Integration
- Need to update
distribute_and_collect()function to deduct protocol fees - Calculate fees using current configuration
- Transfer fees to treasury (contract admin)
- Update creator payout calculations
- Need to update
-
Helper Functions
- Complete
is_authorized_dao_member()implementation - Add DAO member management functions
- Implement proposal cancellation mechanism
- Complete
-
Integration Testing
- End-to-end fee collection testing
- Mid-cycle fee update scenarios
- Treasury balance verification
let protocol_fee = (amount_to_payout_tokens * fee_config.current_fee_bps as i128) / 10000;
let amount_for_creators = amount_to_payout_tokens - protocol_fee;- Fee increases: 7-day timelock (
proposed_at + PROTOCOL_FEE_TIMELOCK_DURATION) - Fee decreases: Immediate execution (
proposed_at)
- Minimum
DAO_MULTISIG_THRESHOLD(3) votes required - Votes tracked in
ProtocolFeeUpdateProposal.votes_for - Auto-execution when threshold reached and timelock expired
All fee changes emit detailed events including:
- Proposal ID and proposer
- Old and new fee rates
- Execution timestamps
- Whether it's a fee increase (triggers timelock)
The distribute_and_collect() function needs to be modified to:
// Get current protocol fee configuration
let fee_config: ProtocolFeeConfig = env.storage().persistent()
.get(&DataKey::ProtocolFeeConfig)
.unwrap_or(/* default config */);
// Calculate protocol fee
let protocol_fee = (amount_to_payout_tokens * fee_config.current_fee_bps as i128) / 10000;
let amount_for_creators = amount_to_payout_tokens - protocol_fee;
// Send protocol fee to treasury
if protocol_fee > 0 {
let treasury: Address = env.storage().persistent()
.get(&DataKey::ContractAdmin)
.expect("contract admin not found");
token_client.transfer(&env.current_contract_address(), &treasury, &protocol_fee);
}
// Distribute remaining amount to creators (with updated referral rebate calculation)Implement proper DAO member verification:
fn is_authorized_dao_member(env: &Env, dao_member: &Address) -> bool {
// Check if address is in authorized DAO member list
// This could be stored in SecurityCouncilMember or similar
env.storage().persistent()
.get(&DataKey::SecurityCouncilMember(dao_member.clone()))
.map(|member: SecurityCouncilMember| member.is_active)
.unwrap_or(false)
}Ensure all necessary imports are included:
use soroban_sdk::token::Client as TokenClient;
use soroban_sdk::{contract, contractevent, contractimpl, contracttype, vec, Address, Env, Symbol, Vec};- Maximum 500 bps prevents excessive fees
- Validated in
propose_protocol_fee_update()
- 7-day delay for fee increases allows merchant evaluation
- Immediate decreases for rapid response to issues
- Requires minimum 3 DAO member approvals
- Prevents unilateral fee changes
- Uses basis points (1/100 of 1%) for accurate calculations
- Integer division prevents floating-point errors
- Dust handling for small amounts
- ✅ Fee initialization
- ✅ Proposal creation and validation
- ✅ Timelock enforcement
- ✅ Maximum fee limits
- ✅ Mathematical precision
- 🔄 End-to-end fee collection
- 🔄 Mid-cycle fee updates
- 🔄 Treasury balance tracking
- 🔄 Event verification
- ✅ Small amounts (dust handling)
- ✅ Maximum fee scenarios
- ✅ Multiple concurrent proposals
- 🔄 Contract upgrade scenarios
- DAO can propose and vote on fee changes
- Multi-sig consensus prevents unilateral control
- Events provide full transparency
- 500 bps maximum fee cap enforced
- 7-day timelock for fee increases
- Merchants can evaluate economics during timelock
- Mathematical precision verified in tests
- No dust issues with basis point calculations
- Proper treasury and creator distribution
- Complete Distribution Integration: Update the duplicate
distribute_and_collect()functions - Implement DAO Authorization: Complete member verification logic
- Run Integration Tests: Verify end-to-end functionality
- Audit Security Review: Validate all security measures
- Deploy and Monitor: Track fee changes and treasury accumulation
src/lib.rs: Added protocol fee data structures and functionssrc/test_protocol_fee.rs: Comprehensive test suitePROTOCOL_FEE_IMPLEMENTATION.md: This documentation
The implementation handles the core requirements but requires completion of the distribution logic integration and DAO authorization system to be fully functional. The mathematical foundation and governance structure are solid and tested.