diff --git a/allways/cli/swap_commands/admin.py b/allways/cli/swap_commands/admin.py index 1f446b1..ebc08df 100644 --- a/allways/cli/swap_commands/admin.py +++ b/allways/cli/swap_commands/admin.py @@ -112,13 +112,13 @@ def set_reservation_ttl(blocks: int): @admin_group.command('set-fee-divisor') @click.argument('divisor', type=int) def set_fee_divisor(divisor: int): - """Set the fee divisor (100 = 1% fee, 50 = 2% fee, 200 = 0.5% fee). + """Set the fee divisor (100 = 1% fee, 50 = 2% fee, 20 = 5% fee max). Example: alw admin set-fee-divisor 100 """ - if divisor < 2: - console.print('[red]Divisor must be at least 2[/red]') + if divisor < 20: + console.print('[red]Divisor must be at least 20 (max 5% fee)[/red]') return _, wallet, _, client = get_cli_context() diff --git a/allways/constants.py b/allways/constants.py index 8176128..1f20ec8 100644 --- a/allways/constants.py +++ b/allways/constants.py @@ -52,6 +52,7 @@ # via `alw admin` commands and read from the contract at runtime. DEFAULT_FEE_DIVISOR = 100 # tao_amount / fee_divisor — read from contract, fallback here SWAP_FEE_PERCENT = 0.01 # display only — derived from DEFAULT_FEE_DIVISOR +MAX_FEE_PERCENT = 0.05 # contract enforces divisor >= 20 (max 5% fee) MIN_COLLATERAL_TAO = 1.2 # Must be > max swap amount DEFAULT_FULFILLMENT_TIMEOUT_BLOCKS = 30 # ~5 min — `alw admin set-timeout` DEFAULT_MIN_SWAP_AMOUNT_RAO = 100_000_000 # 0.1 TAO — `alw admin set-min-swap` diff --git a/smart-contracts/ink/lib.rs b/smart-contracts/ink/lib.rs index b57edf6..703cafb 100644 --- a/smart-contracts/ink/lib.rs +++ b/smart-contracts/ink/lib.rs @@ -86,6 +86,9 @@ mod allways_swap_manager { const REQ_EXTEND: u8 = 3; const REQ_EXTEND_TIMEOUT: u8 = 4; + // Fee cap: divisor >= 20 means fee can never exceed 5% + const MIN_FEE_DIVISOR: u128 = 20; + // ========================================================================= // Internal helpers // ========================================================================= @@ -719,7 +722,7 @@ mod allways_swap_manager { swap.status = SwapStatus::Completed; swap.completed_block = self.env().block_number(); - // Fee from miner collateral -> accumulated_fees (fee_divisor >= 2 enforced by setter) + // Fee from miner collateral -> accumulated_fees (divisor >= 20 enforced, max 5%) #[allow(clippy::arithmetic_side_effects)] let fee = swap.tao_amount.saturating_div(self.fee_divisor); let miner_collateral = self.collateral.get(swap.miner).unwrap_or(0); @@ -1100,7 +1103,7 @@ mod allways_swap_manager { #[ink(message)] pub fn set_fee_divisor(&mut self, divisor: u128) -> Result<(), Error> { self.ensure_owner()?; - if divisor < 2 { + if divisor < MIN_FEE_DIVISOR { return Err(Error::InvalidAmount); } self.fee_divisor = divisor;