diff --git a/contracts/mixnet/src/contract.rs b/contracts/mixnet/src/contract.rs index 4af5435880..65784a60cb 100644 --- a/contracts/mixnet/src/contract.rs +++ b/contracts/mixnet/src/contract.rs @@ -29,10 +29,13 @@ pub const INITIAL_GATEWAY_DELEGATION_REWARD_RATE: u64 = 110; pub const INITIAL_MIXNODE_ACTIVE_SET_SIZE: u32 = 100; pub const INITIAL_GATEWAY_ACTIVE_SET_SIZE: u32 = 20; -// This is totally made up -pub const INITIAL_INFLATION_POOL: u32 = 1_000_000_000; +// This is totally made up, lets set the pool to billion nyms, so million billion micro nyms +pub const INITIAL_INFLATION_POOL: u64 = 1_000_000_000_000_000; // Sybil attack resistance parameter pub const ALPHA: f64 = 0.3; +// We'll be assuming a few more things, profit margin and cost function. Since we don't have relialable package measurement, we'll be using uptime. We'll also set the value of 1 Nym to 1 $, to be able to translate epoch costs to Nyms. We'll also assume a cost of 40$ per epoch(month), converting that to Nym at our 1$ rate translates to 40_000_000 uNyms +pub const DEFAULT_PROFIT_MARGIN: f64 = 0.1; // Assume operators want a 10 % profit +pub const DEFAULT_COST_PER_EPOCH: u32 = 40_000_000; fn default_initial_state(owner: Addr) -> State { let mixnode_bond_reward_rate = Decimal::percent(INITIAL_MIXNODE_BOND_REWARD_RATE); diff --git a/contracts/mixnet/src/storage.rs b/contracts/mixnet/src/storage.rs index 5032e3a9b3..7f23755670 100644 --- a/contracts/mixnet/src/storage.rs +++ b/contracts/mixnet/src/storage.rs @@ -61,11 +61,11 @@ pub fn mut_total_mix_stake(storage: &mut dyn Storage) -> Singleton { singleton(storage, TOTAL_MIX_STAKE_KEY) } -fn inflation_pool(storage: &dyn Storage) -> ReadonlySingleton { +fn inflation_pool(storage: &dyn Storage) -> ReadonlySingleton { singleton_read(storage, INFLATION_POOL_PREFIX) } -pub fn mut_inflation_pool(storage: &mut dyn Storage) -> Singleton { +pub fn mut_inflation_pool(storage: &mut dyn Storage) -> Singleton { singleton(storage, INFLATION_POOL_PREFIX) } @@ -91,7 +91,7 @@ pub fn total_gateway_stake_value(storage: &dyn Storage) -> Uint128 { } } -pub fn inflation_pool_value(storage: &dyn Storage) -> u32 { +pub fn inflation_pool_value(storage: &dyn Storage) -> u64 { match inflation_pool(storage).load() { Ok(value) => value, Err(_e) => INITIAL_INFLATION_POOL, @@ -135,18 +135,18 @@ pub fn decr_total_gateway_stake( } pub fn incr_inflation_pool( - amount: u32, + amount: u64, storage: &mut dyn Storage, -) -> Result { +) -> Result { let stake = inflation_pool_value(storage) + amount; mut_inflation_pool(storage).save(&stake)?; Ok(stake) } pub fn decr_inflation_pool( - amount: u32, + amount: u64, storage: &mut dyn Storage, -) -> Result { +) -> Result { // TODO: This could got to < 0 let stake = inflation_pool_value(storage) - amount; mut_inflation_pool(storage).save(&stake)?; diff --git a/contracts/mixnet/src/transactions.rs b/contracts/mixnet/src/transactions.rs index ee74222063..f19acbed1a 100644 --- a/contracts/mixnet/src/transactions.rs +++ b/contracts/mixnet/src/transactions.rs @@ -1,7 +1,9 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::contract::{ALPHA, INITIAL_MIXNODE_ACTIVE_SET_SIZE}; +use crate::contract::{ + ALPHA, DEFAULT_COST_PER_EPOCH, DEFAULT_PROFIT_MARGIN, INITIAL_MIXNODE_ACTIVE_SET_SIZE, +}; use crate::error::ContractError; use crate::helpers::{calculate_epoch_reward_rate, scale_reward_by_uptime, Delegations}; use crate::queries; @@ -457,6 +459,10 @@ pub(crate) fn try_reward_mixnode( }) } +fn price_for_uptime(uptime: u32) -> f64 { + uptime as f64 / 100. * DEFAULT_COST_PER_EPOCH as f64 +} + pub(crate) fn try_reward_mixnode_v2( deps: DepsMut, env: Env, @@ -520,9 +526,17 @@ pub(crate) fn try_reward_mixnode_v2( let sigma = stake_to_total_stake_ratio.min(one_over_k); let node_reward = - performance * income_global_mix * (sigma * omega_k + ALPHA * lambda * (sigma * k)) / (1. + ALPHA); + performance * income_global_mix * (sigma * omega_k + ALPHA * lambda * (sigma * k)) + / (1. + ALPHA); + + // Omitting the price per packet function now, it follows that base operator reward is the node_reward + let operator_profit = ((DEFAULT_PROFIT_MARGIN + + (1. - DEFAULT_PROFIT_MARGIN) * (lambda / sigma)) + * (node_reward - price_for_uptime(uptime))) + .max(0.); + let operator_base_reward = node_reward.min(price_for_uptime(uptime)); + let total_operator_reward = operator_base_reward + operator_profit; - // TODO: // Default profit margins and costs in order to determine owner and delegator shares.