mirror of https://github.com/nucypher/nucypher.git
Prepares economics and deployment constants for use with threshold network.
parent
98f9e8d33b
commit
1c34045a81
|
@ -15,431 +15,86 @@ You should have received a copy of the GNU Affero General Public License
|
|||
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
from decimal import Decimal, localcontext
|
||||
from math import log
|
||||
from typing import Tuple, Optional
|
||||
|
||||
from nucypher.blockchain.eth.agents import (
|
||||
AdjudicatorAgent,
|
||||
ContractAgency,
|
||||
NucypherTokenAgent,
|
||||
StakingEscrowAgent,
|
||||
WorkLockAgent
|
||||
PREApplicationAgent
|
||||
)
|
||||
from nucypher.blockchain.eth.registry import BaseContractRegistry
|
||||
from nucypher.blockchain.eth.token import NU
|
||||
|
||||
LOG2 = Decimal(log(2))
|
||||
ONE_YEAR_IN_HOURS = 365 * 24
|
||||
from nucypher.blockchain.eth.token import TToken
|
||||
|
||||
|
||||
class BaseEconomics:
|
||||
"""
|
||||
A representation of a contract deployment set's constructor parameters, and the calculations
|
||||
used to generate those values from high-level human-understandable parameters.
|
||||
class Economics:
|
||||
|
||||
Formula for staking in one period for the second phase:
|
||||
(totalSupply - currentSupply) * (lockedValue / totalLockedValue) * (k1 + allLockedPeriods) / d / k2
|
||||
|
||||
d - Coefficient which modifies the rate at which the maximum issuance decays
|
||||
k1 - Numerator of the locking duration coefficient
|
||||
k2 - Denominator of the locking duration coefficient
|
||||
|
||||
if allLockedPeriods > maximum_rewarded_periods then allLockedPeriods = maximum_rewarded_periods
|
||||
kappa * log(2) / halving_delay === (k1 + allLockedPeriods) / d
|
||||
|
||||
"""
|
||||
|
||||
# Token Denomination
|
||||
__token_decimals = 18
|
||||
nunits_per_token = 10 ** __token_decimals # Smallest unit designation
|
||||
|
||||
# Period Definition
|
||||
_default_hours_per_period = 24 * 7
|
||||
_default_genesis_hours_per_period = 24
|
||||
|
||||
# Time Constraints
|
||||
_default_minimum_worker_periods = 2
|
||||
_default_minimum_locked_periods = 4 # 28 days
|
||||
|
||||
# Value Constraints
|
||||
_default_minimum_allowed_locked = NU(15_000, 'NU').to_units()
|
||||
_default_maximum_allowed_locked = NU(30_000_000, 'NU').to_units()
|
||||
_default_min_authorization = TToken(40_000, 'T').to_units()
|
||||
_default_min_operator_seconds = 60 * 60 * 48 # TODO: Finalize deployment params
|
||||
|
||||
# TODO: Reintroduce Adjudicator
|
||||
# Slashing parameters
|
||||
HASH_ALGORITHM_KECCAK256 = 0
|
||||
HASH_ALGORITHM_SHA256 = 1
|
||||
HASH_ALGORITHM_RIPEMD160 = 2
|
||||
|
||||
# Adjudicator
|
||||
_default_hash_algorithm = HASH_ALGORITHM_SHA256
|
||||
_default_base_penalty = 2
|
||||
_default_penalty_history_coefficient = 0
|
||||
_default_percentage_penalty_coefficient = 100000 # 0.001%
|
||||
_default_reward_coefficient = 2
|
||||
|
||||
# Worklock
|
||||
from maya import MayaDT
|
||||
from web3 import Web3
|
||||
_default_worklock_supply: int = NU(225_000_000, 'NU').to_units()
|
||||
_default_bidding_start_date: int = MayaDT.from_iso8601('2020-09-01T00:00:00.0Z').epoch
|
||||
_default_bidding_end_date: int = MayaDT.from_iso8601('2020-09-28T23:59:59.0Z').epoch
|
||||
_default_cancellation_end_date: int = MayaDT.from_iso8601('2020-09-30T23:59:59.0Z').epoch
|
||||
_default_worklock_boosting_refund_rate: int = 800
|
||||
_default_worklock_commitment_duration: int = 180
|
||||
_default_worklock_min_allowed_bid: int = Web3.toWei(5, "ether")
|
||||
# HASH_ALGORITHM_KECCAK256 = 0
|
||||
# HASH_ALGORITHM_SHA256 = 1
|
||||
# HASH_ALGORITHM_RIPEMD160 = 2
|
||||
# _default_hash_algorithm = HASH_ALGORITHM_SHA256
|
||||
# _default_base_penalty = 2
|
||||
# _default_penalty_history_coefficient = 0
|
||||
# _default_percentage_penalty_coefficient = 100000 # 0.001%
|
||||
# _default_reward_coefficient = 2
|
||||
|
||||
def __init__(self,
|
||||
|
||||
# StakingEscrow
|
||||
initial_supply: int,
|
||||
total_supply: int,
|
||||
issuance_decay_coefficient: int,
|
||||
lock_duration_coefficient_1: int,
|
||||
lock_duration_coefficient_2: int,
|
||||
maximum_rewarded_periods: int,
|
||||
first_phase_supply: int,
|
||||
first_phase_max_issuance: int,
|
||||
genesis_hours_per_period: int = _default_genesis_hours_per_period,
|
||||
hours_per_period: int = _default_hours_per_period,
|
||||
minimum_locked_periods: int = _default_minimum_locked_periods,
|
||||
minimum_allowed_locked: int = _default_minimum_allowed_locked,
|
||||
maximum_allowed_locked: int = _default_maximum_allowed_locked,
|
||||
minimum_worker_periods: int = _default_minimum_worker_periods,
|
||||
min_operator_seconds: int = _default_min_operator_seconds,
|
||||
min_authorization: int = _default_min_authorization,
|
||||
|
||||
# Adjudicator
|
||||
hash_algorithm: int = _default_hash_algorithm,
|
||||
base_penalty: int = _default_base_penalty,
|
||||
penalty_history_coefficient: int = _default_penalty_history_coefficient,
|
||||
percentage_penalty_coefficient: int = _default_percentage_penalty_coefficient,
|
||||
reward_coefficient: int = _default_reward_coefficient,
|
||||
|
||||
# WorkLock
|
||||
worklock_supply: int = _default_worklock_supply,
|
||||
bidding_start_date: int = _default_bidding_start_date,
|
||||
bidding_end_date: int = _default_bidding_end_date,
|
||||
cancellation_end_date: int = _default_cancellation_end_date,
|
||||
worklock_boosting_refund_rate: int = _default_worklock_boosting_refund_rate,
|
||||
worklock_commitment_duration: int = _default_worklock_commitment_duration,
|
||||
worklock_min_allowed_bid: int = _default_worklock_min_allowed_bid):
|
||||
# hash_algorithm: int = _default_hash_algorithm,
|
||||
# base_penalty: int = _default_base_penalty,
|
||||
# penalty_history_coefficient: int = _default_penalty_history_coefficient,
|
||||
# percentage_penalty_coefficient: int = _default_percentage_penalty_coefficient,
|
||||
# reward_coefficient: int = _default_reward_coefficient
|
||||
):
|
||||
|
||||
"""
|
||||
:param initial_supply: Number of tokens in circulating supply at t=0
|
||||
:param first_phase_supply: Number of tokens in circulating supply at phase switch (variable t)
|
||||
:param total_supply: Tokens at t=8
|
||||
:param first_phase_max_issuance: (Imax) Maximum number of new tokens minted per period during Phase 1.
|
||||
See Equation 7 in Staking Protocol & Economics paper.
|
||||
:param issuance_decay_coefficient: (d) Coefficient which modifies the rate at which the maximum issuance decays,
|
||||
only applicable to Phase 2. d = 365 * half-life / LOG2 where default half-life = 2.
|
||||
See Equation 10 in Staking Protocol & Economics paper
|
||||
:param lock_duration_coefficient_1: (k1) Numerator of the coefficient which modifies the extent
|
||||
to which a stake's lock duration affects the subsidy it receives. Affects stakers differently.
|
||||
Applicable to Phase 1 and Phase 2. k1 = k2 * small_stake_multiplier where default small_stake_multiplier = 0.5.
|
||||
See Equation 8 in Staking Protocol & Economics paper.
|
||||
:param lock_duration_coefficient_2: (k2) Denominator of the coefficient which modifies the extent
|
||||
to which a stake's lock duration affects the subsidy it receives. Affects stakers differently.
|
||||
Applicable to Phase 1 and Phase 2. k2 = maximum_rewarded_periods / (1 - small_stake_multiplier)
|
||||
where default maximum_rewarded_periods = 365 and default small_stake_multiplier = 0.5.
|
||||
See Equation 8 in Staking Protocol & Economics paper.
|
||||
:param maximum_rewarded_periods: (kmax) Number of periods beyond which a stake's lock duration
|
||||
no longer increases the subsidy it receives. kmax = reward_saturation * 365 where default reward_saturation = 1.
|
||||
See Equation 8 in Staking Protocol & Economics paper.
|
||||
:param genesis_hours_per_period: Hours in single period at genesis
|
||||
:param hours_per_period: Hours in single period
|
||||
:param minimum_locked_periods: Min amount of periods during which tokens can be locked
|
||||
:param minimum_allowed_locked: Min amount of tokens that can be locked
|
||||
:param maximum_allowed_locked: Max amount of tokens that can be locked
|
||||
:param minimum_worker_periods: Min amount of periods while a worker can't be changed
|
||||
:param min_operator_seconds: Min amount of seconds while an operator can't be changed
|
||||
:param min_authorization: Amount of minimum allowable authorization
|
||||
|
||||
:param hash_algorithm: Hashing algorithm
|
||||
:param base_penalty: Base for the penalty calculation
|
||||
:param penalty_history_coefficient: Coefficient for calculating the penalty depending on the history
|
||||
:param percentage_penalty_coefficient: Coefficient for calculating the percentage penalty
|
||||
:param reward_coefficient: Coefficient for calculating the reward
|
||||
"""
|
||||
# TODO: Reintroduce Adjudicator
|
||||
# :param hash_algorithm: Hashing algorithm
|
||||
# :param base_penalty: Base for the penalty calculation
|
||||
# :param penalty_history_coefficient: Coefficient for calculating the penalty depending on the history
|
||||
# :param percentage_penalty_coefficient: Coefficient for calculating the percentage penalty
|
||||
# :param reward_coefficient: Coefficient for calculating the reward
|
||||
|
||||
#
|
||||
# WorkLock
|
||||
#
|
||||
# self.hash_algorithm = hash_algorithm
|
||||
# self.base_penalty = base_penalty
|
||||
# self.penalty_history_coefficient = penalty_history_coefficient
|
||||
# self.percentage_penalty_coefficient = percentage_penalty_coefficient
|
||||
# self.reward_coefficient = reward_coefficient
|
||||
|
||||
self.bidding_start_date = bidding_start_date
|
||||
self.bidding_end_date = bidding_end_date
|
||||
self.cancellation_end_date = cancellation_end_date
|
||||
self.worklock_supply = worklock_supply
|
||||
self.worklock_boosting_refund_rate = worklock_boosting_refund_rate
|
||||
self.worklock_commitment_duration = worklock_commitment_duration
|
||||
self.worklock_min_allowed_bid = worklock_min_allowed_bid
|
||||
|
||||
#
|
||||
# NucypherToken & Staking Escrow
|
||||
#
|
||||
|
||||
self.initial_supply = initial_supply
|
||||
# Remaining / Reward Supply - Escrow Parameter
|
||||
self.reward_supply = total_supply - initial_supply
|
||||
self.total_supply = total_supply
|
||||
self.first_phase_supply = first_phase_supply
|
||||
self.first_phase_total_supply = initial_supply + first_phase_supply
|
||||
self.first_phase_max_issuance = first_phase_max_issuance
|
||||
self.issuance_decay_coefficient = issuance_decay_coefficient
|
||||
self.lock_duration_coefficient_1 = lock_duration_coefficient_1
|
||||
self.lock_duration_coefficient_2 = lock_duration_coefficient_2
|
||||
self.maximum_rewarded_periods = maximum_rewarded_periods
|
||||
self.genesis_hours_per_period = genesis_hours_per_period
|
||||
self.hours_per_period = hours_per_period
|
||||
self.minimum_locked_periods = minimum_locked_periods
|
||||
self.minimum_allowed_locked = minimum_allowed_locked
|
||||
self.maximum_allowed_locked = maximum_allowed_locked
|
||||
self.minimum_worker_periods = minimum_worker_periods
|
||||
self.genesis_seconds_per_period = genesis_hours_per_period * 60 * 60 # Genesis seconds in a single period
|
||||
self.seconds_per_period = hours_per_period * 60 * 60 # Seconds in a single period
|
||||
self.days_per_period = hours_per_period // 24 # Days in a single period
|
||||
|
||||
#
|
||||
# Adjudicator
|
||||
#
|
||||
|
||||
self.hash_algorithm = hash_algorithm
|
||||
self.base_penalty = base_penalty
|
||||
self.penalty_history_coefficient = penalty_history_coefficient
|
||||
self.percentage_penalty_coefficient = percentage_penalty_coefficient
|
||||
self.reward_coefficient = reward_coefficient
|
||||
self.min_operator_seconds = min_operator_seconds
|
||||
self.min_authorization = min_authorization
|
||||
|
||||
@property
|
||||
def erc20_initial_supply(self) -> int:
|
||||
return int(self.initial_supply)
|
||||
|
||||
@property
|
||||
def erc20_reward_supply(self) -> int:
|
||||
return int(self.reward_supply)
|
||||
|
||||
@property
|
||||
def erc20_total_supply(self) -> int:
|
||||
return int(self.total_supply)
|
||||
|
||||
@property
|
||||
def staking_deployment_parameters(self) -> Tuple[int, ...]:
|
||||
def pre_application_deployment_parameters(self) -> Tuple[int, ...]:
|
||||
"""Cast coefficient attributes to uint256 compatible type for solidity+EVM"""
|
||||
deploy_parameters = (
|
||||
|
||||
# Period
|
||||
self.genesis_hours_per_period, # Hours in single period at genesis
|
||||
self.hours_per_period, # Hours in single period
|
||||
|
||||
# Coefficients
|
||||
self.issuance_decay_coefficient, # Coefficient which modifies the rate at which the maximum issuance decays (d)
|
||||
self.lock_duration_coefficient_1, # Numerator of the locking duration coefficient (k1)
|
||||
self.lock_duration_coefficient_2, # Denominator of the locking duration coefficient (k2)
|
||||
self.maximum_rewarded_periods, # Max periods that will be additionally rewarded (awarded_periods)
|
||||
self.first_phase_total_supply, # Total supply for the first phase
|
||||
self.first_phase_max_issuance, # Max possible reward for one period for all stakers in the first phase
|
||||
|
||||
# Constraints
|
||||
self.minimum_locked_periods, # Min amount of periods during which tokens can be locked
|
||||
self.minimum_allowed_locked, # Min amount of tokens that can be locked
|
||||
self.maximum_allowed_locked, # Max amount of tokens that can be locked
|
||||
self.minimum_worker_periods # Min amount of periods while a worker can't be changed
|
||||
deploy_parameters = ( # note: order-sensitive
|
||||
self.min_authorization,
|
||||
self.min_operator_seconds,
|
||||
)
|
||||
return tuple(map(int, deploy_parameters))
|
||||
|
||||
@property
|
||||
def slashing_deployment_parameters(self) -> Tuple[int, ...]:
|
||||
"""Cast coefficient attributes to uint256 compatible type for solidity+EVM"""
|
||||
deployment_parameters = [
|
||||
self.hash_algorithm,
|
||||
self.base_penalty,
|
||||
self.penalty_history_coefficient,
|
||||
self.percentage_penalty_coefficient,
|
||||
self.reward_coefficient
|
||||
]
|
||||
return tuple(map(int, deployment_parameters))
|
||||
|
||||
@property
|
||||
def worklock_deployment_parameters(self):
|
||||
"""
|
||||
0 token - Token contract
|
||||
1 escrow - Staking Escrow contract
|
||||
...
|
||||
2 startBidDate - Timestamp when bidding starts
|
||||
3 endBidDate - Timestamp when bidding will end
|
||||
4 endCancellationDate - Timestamp when cancellation window will end
|
||||
5 boostingRefund - Coefficient to boost refund ETH
|
||||
6 stakingPeriods - Duration of tokens locking
|
||||
7 minAllowedBid - Minimum allowed ETH amount for bidding
|
||||
"""
|
||||
deployment_parameters = [self.bidding_start_date,
|
||||
self.bidding_end_date,
|
||||
self.cancellation_end_date,
|
||||
self.worklock_boosting_refund_rate,
|
||||
self.worklock_commitment_duration,
|
||||
self.worklock_min_allowed_bid]
|
||||
return tuple(map(int, deployment_parameters))
|
||||
|
||||
@property
|
||||
def bidding_duration(self) -> int:
|
||||
"""Returns the total bidding window duration in seconds."""
|
||||
return self.bidding_end_date - self.bidding_start_date
|
||||
|
||||
@property
|
||||
def cancellation_window_duration(self) -> int:
|
||||
"""Returns the total cancellation window duration in seconds."""
|
||||
return self.cancellation_end_date - self.bidding_end_date
|
||||
|
||||
|
||||
class StandardTokenEconomics(BaseEconomics):
|
||||
"""
|
||||
|
||||
Formula for staking in one period for the second phase:
|
||||
(totalSupply - currentSupply) * (lockedValue / totalLockedValue) * (k1 + allLockedPeriods) / d / k2
|
||||
|
||||
d - Coefficient which modifies the rate at which the maximum issuance decays
|
||||
k1 - Numerator of the locking duration coefficient
|
||||
k2 - Denominator of the locking duration coefficient
|
||||
|
||||
if allLockedPeriods > maximum_rewarded_periods then allLockedPeriods = maximum_rewarded_periods
|
||||
kappa * log(2) / halving_delay === (k1 + allLockedPeriods) / d / k2
|
||||
|
||||
...but also...
|
||||
|
||||
kappa = small_stake_multiplier + (1 - small_stake_multiplier) * min(T, T1) / T1
|
||||
where allLockedPeriods == min(T, T1)
|
||||
|
||||
Academic Reference:
|
||||
|
||||
NuCypher: Mining & Staking Economics - Michael Egorov, MacLane Wilkison, NuCypher
|
||||
<https://github.com/nucypher/mining-paper/blob/master/mining-paper.pdf>
|
||||
|
||||
"""
|
||||
|
||||
# Decimal
|
||||
_precision = 28
|
||||
|
||||
# Supply
|
||||
__default_initial_supply = NU(int(1_000_000_000), 'NU').to_units()
|
||||
__default_first_phase_supply = NU(int(1_829_579_800), 'NU').to_units()
|
||||
__default_first_phase_duration = 5 # years
|
||||
|
||||
__default_decay_half_life = 2 # years
|
||||
__default_reward_saturation = 1 # years
|
||||
__default_small_stake_multiplier = Decimal(0.5)
|
||||
|
||||
def __init__(self,
|
||||
initial_supply: int = __default_initial_supply,
|
||||
first_phase_supply: int = __default_first_phase_supply,
|
||||
first_phase_duration: int = __default_first_phase_duration,
|
||||
decay_half_life: int = __default_decay_half_life,
|
||||
reward_saturation: int = __default_reward_saturation,
|
||||
small_stake_multiplier: Decimal = __default_small_stake_multiplier,
|
||||
hours_per_period: int = BaseEconomics._default_hours_per_period,
|
||||
**kwargs):
|
||||
"""
|
||||
:param initial_supply: Number of tokens in circulating supply at t=0
|
||||
:param first_phase_supply: Number of tokens in circulating supply at phase switch (variable t)
|
||||
:param first_phase_duration: Minimum duration of the first phase
|
||||
:param decay_half_life: Time for issuance to halve in years (in second phase only)
|
||||
:param reward_saturation: "saturation" time - if staking is longer than T_sat, the reward doesn't get any higher
|
||||
:param small_stake_multiplier: Fraction of maximum reward paid to those who are about to unlock tokens
|
||||
"""
|
||||
|
||||
#
|
||||
# Calculated
|
||||
#
|
||||
|
||||
with localcontext() as ctx:
|
||||
ctx.prec = self._precision
|
||||
|
||||
one_year_in_periods = Decimal(ONE_YEAR_IN_HOURS / hours_per_period)
|
||||
|
||||
initial_supply = Decimal(initial_supply)
|
||||
|
||||
first_phase_supply = Decimal(first_phase_supply)
|
||||
|
||||
first_phase_max_issuance = first_phase_supply / first_phase_duration / one_year_in_periods
|
||||
|
||||
# ERC20 Token parameter (See Equation 4 in Mining paper)
|
||||
total_supply = initial_supply \
|
||||
+ first_phase_supply \
|
||||
+ first_phase_max_issuance \
|
||||
* one_year_in_periods \
|
||||
* decay_half_life \
|
||||
/ LOG2
|
||||
|
||||
# Awarded periods- Escrow parameter
|
||||
maximum_rewarded_periods = reward_saturation * one_year_in_periods
|
||||
|
||||
# k2 - Escrow parameter
|
||||
lock_duration_coefficient_2 = maximum_rewarded_periods / (1 - small_stake_multiplier)
|
||||
|
||||
# k1 - Escrow parameter
|
||||
lock_duration_coefficient_1 = lock_duration_coefficient_2 * small_stake_multiplier
|
||||
|
||||
# d - Escrow parameter
|
||||
issuance_decay_coefficient = one_year_in_periods * decay_half_life / LOG2
|
||||
|
||||
|
||||
#
|
||||
# Injected
|
||||
#
|
||||
|
||||
self.token_halving = decay_half_life
|
||||
self.token_saturation = reward_saturation
|
||||
self.small_stake_multiplier = small_stake_multiplier
|
||||
|
||||
super().__init__(initial_supply=initial_supply,
|
||||
first_phase_supply=first_phase_supply,
|
||||
total_supply=total_supply,
|
||||
first_phase_max_issuance=first_phase_max_issuance,
|
||||
issuance_decay_coefficient=issuance_decay_coefficient,
|
||||
lock_duration_coefficient_1=lock_duration_coefficient_1,
|
||||
lock_duration_coefficient_2=lock_duration_coefficient_2,
|
||||
maximum_rewarded_periods=int(maximum_rewarded_periods),
|
||||
hours_per_period=hours_per_period,
|
||||
**kwargs)
|
||||
|
||||
def first_phase_final_period(self) -> int:
|
||||
"""
|
||||
Returns final period for first phase,
|
||||
assuming that all stakers locked tokens for more than 365 days.
|
||||
"""
|
||||
S_p1 = self.first_phase_supply
|
||||
I_s_per_period = self.first_phase_max_issuance # per period
|
||||
phase_switch_in_periods = S_p1 // I_s_per_period
|
||||
return int(phase_switch_in_periods)
|
||||
|
||||
def token_supply_at_period(self, period: int) -> int:
|
||||
"""
|
||||
Returns predicted total supply at specified period,
|
||||
assuming that all stakers locked tokens for more than 365 days.
|
||||
"""
|
||||
if period < 0:
|
||||
raise ValueError("Period must be a positive integer")
|
||||
|
||||
with localcontext() as ctx:
|
||||
ctx.prec = self._precision
|
||||
|
||||
t = Decimal(period)
|
||||
S_0 = self.erc20_initial_supply
|
||||
phase_switch_in_periods = self.first_phase_final_period()
|
||||
I_s_per_period = self.first_phase_max_issuance # per period
|
||||
|
||||
if t <= phase_switch_in_periods:
|
||||
S_t = S_0 + t * I_s_per_period
|
||||
else:
|
||||
one_year_in_periods = Decimal(ONE_YEAR_IN_HOURS / self.hours_per_period)
|
||||
S_p1 = self.first_phase_max_issuance * phase_switch_in_periods
|
||||
T_half = self.token_halving # in years
|
||||
T_half_in_periods = T_half * one_year_in_periods
|
||||
t = t - phase_switch_in_periods
|
||||
|
||||
S_t = S_0 + S_p1 + I_s_per_period * T_half_in_periods * (1 - 2 ** (-t / T_half_in_periods)) / LOG2
|
||||
return int(S_t)
|
||||
|
||||
def cumulative_rewards_at_period(self, period: int) -> int:
|
||||
return self.token_supply_at_period(period) - self.erc20_initial_supply
|
||||
|
||||
def rewards_during_period(self, period: int) -> int:
|
||||
return self.token_supply_at_period(period) - self.token_supply_at_period(period-1)
|
||||
# TODO: Reintroduce Adjudicator
|
||||
# @property
|
||||
# def slashing_deployment_parameters(self) -> Tuple[int, ...]:
|
||||
# """Cast coefficient attributes to uint256 compatible type for solidity+EVM"""
|
||||
# deployment_parameters = [
|
||||
# self.hash_algorithm,
|
||||
# self.base_penalty,
|
||||
# self.penalty_history_coefficient,
|
||||
# self.percentage_penalty_coefficient,
|
||||
# self.reward_coefficient
|
||||
# ]
|
||||
# return tuple(map(int, deployment_parameters))
|
||||
|
||||
|
||||
class EconomicsFactory:
|
||||
|
@ -448,7 +103,7 @@ class EconomicsFactory:
|
|||
__economics = dict()
|
||||
|
||||
@classmethod
|
||||
def get_economics(cls, registry: BaseContractRegistry, provider_uri: Optional[str] = None) -> BaseEconomics:
|
||||
def get_economics(cls, registry: BaseContractRegistry, provider_uri: Optional[str] = None) -> Economics:
|
||||
registry_id = registry.id
|
||||
try:
|
||||
return cls.__economics[registry_id]
|
||||
|
@ -458,53 +113,24 @@ class EconomicsFactory:
|
|||
return economics
|
||||
|
||||
@staticmethod
|
||||
def retrieve_from_blockchain(registry: BaseContractRegistry, provider_uri: Optional[str] = None) -> BaseEconomics:
|
||||
def retrieve_from_blockchain(registry: BaseContractRegistry, provider_uri: Optional[str] = None) -> Economics:
|
||||
|
||||
# Agents
|
||||
token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=registry, provider_uri=provider_uri)
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=registry, provider_uri=provider_uri)
|
||||
adjudicator_agent = ContractAgency.get_agent(AdjudicatorAgent, registry=registry, provider_uri=provider_uri)
|
||||
application_agent = ContractAgency.get_agent(PREApplicationAgent, registry=registry, provider_uri=provider_uri)
|
||||
|
||||
worklock_deployed = True
|
||||
try:
|
||||
worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=registry, provider_uri=provider_uri)
|
||||
except registry.UnknownContract:
|
||||
worklock_deployed = False
|
||||
|
||||
# Token
|
||||
total_supply = token_agent.contract.functions.totalSupply().call()
|
||||
reward_supply = staking_agent.contract.functions.getReservedReward().call()
|
||||
# Not the "real" initial_supply value because used current reward instead of initial reward
|
||||
initial_supply = total_supply - reward_supply
|
||||
|
||||
# Staking Escrow
|
||||
staking_parameters = list(staking_agent.staking_parameters())
|
||||
genesis_seconds_per_period = staking_parameters.pop(0)
|
||||
seconds_per_period = staking_parameters.pop(0)
|
||||
staking_parameters.insert(6, genesis_seconds_per_period // 60 // 60) # genesis_hours_per_period
|
||||
staking_parameters.insert(7, seconds_per_period // 60 // 60) # hours_per_period
|
||||
minting_coefficient = staking_parameters[0]
|
||||
lock_duration_coefficient_2 = staking_parameters[2]
|
||||
first_phase_total_supply = staking_parameters[4]
|
||||
first_phase_supply = first_phase_total_supply - initial_supply
|
||||
staking_parameters[4] = first_phase_supply
|
||||
staking_parameters[0] = minting_coefficient // lock_duration_coefficient_2 # issuance_decay_coefficient
|
||||
# PRE Application
|
||||
min_authorization = application_agent.get_min_authorization()
|
||||
min_operator_seconds = application_agent.get_min_operator_seconds()
|
||||
|
||||
# Adjudicator
|
||||
slashing_parameters = adjudicator_agent.slashing_parameters()
|
||||
# TODO: Reintroduce Adjudicator
|
||||
# adjudicator_agent = ContractAgency.get_agent(AdjudicatorAgent, registry=registry, provider_uri=provider_uri)
|
||||
# slashing_parameters = adjudicator_agent.slashing_parameters()
|
||||
|
||||
# Worklock
|
||||
if worklock_deployed:
|
||||
worklock_parameters = worklock_agent.worklock_parameters()
|
||||
else:
|
||||
worklock_parameters = list()
|
||||
# Aggregate
|
||||
economics_parameters = dict(min_authorization=min_authorization,
|
||||
min_operator_seconds=min_operator_seconds)
|
||||
|
||||
# Aggregate (order-sensitive)
|
||||
economics_parameters = (initial_supply,
|
||||
total_supply,
|
||||
*staking_parameters,
|
||||
*slashing_parameters,
|
||||
*worklock_parameters)
|
||||
economics = Economics(**economics_parameters)
|
||||
|
||||
economics = BaseEconomics(*economics_parameters)
|
||||
return economics
|
||||
|
|
|
@ -18,27 +18,23 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
|||
|
||||
import json
|
||||
import time
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
from typing import Callable, Union
|
||||
from typing import Dict, Iterable, List, Optional, Tuple
|
||||
|
||||
import maya
|
||||
from constant_sorrow.constants import FULL, WORKER_NOT_RUNNING
|
||||
from constant_sorrow.constants import FULL
|
||||
from eth_tester.exceptions import TransactionFailed as TestTransactionFailed
|
||||
from eth_typing import ChecksumAddress
|
||||
from eth_utils import to_canonical_address
|
||||
from hexbytes import HexBytes
|
||||
from nucypher_core import HRAC
|
||||
from web3 import Web3
|
||||
from web3.exceptions import ValidationError
|
||||
from web3.types import TxReceipt
|
||||
|
||||
from nucypher.acumen.nicknames import Nickname
|
||||
from nucypher.blockchain.economics import (
|
||||
BaseEconomics,
|
||||
Economics,
|
||||
EconomicsFactory,
|
||||
StandardTokenEconomics
|
||||
)
|
||||
from nucypher.blockchain.eth.agents import (
|
||||
AdjudicatorAgent,
|
||||
|
@ -124,7 +120,7 @@ class BaseActor:
|
|||
registry: BaseContractRegistry,
|
||||
transacting_power: Optional[TransactingPower] = None,
|
||||
checksum_address: Optional[ChecksumAddress] = None,
|
||||
economics: Optional[BaseEconomics] = None):
|
||||
economics: Optional[Economics] = None):
|
||||
|
||||
if not (bool(checksum_address) ^ bool(transacting_power)):
|
||||
error = f'Pass transacting power or checksum address, got {checksum_address} and {transacting_power}.'
|
||||
|
@ -142,7 +138,7 @@ class BaseActor:
|
|||
else:
|
||||
self.checksum_address = checksum_address
|
||||
|
||||
self.economics = economics or StandardTokenEconomics()
|
||||
self.economics = economics or Economics()
|
||||
self.transacting_power = transacting_power
|
||||
self.registry = registry
|
||||
self.network = domain
|
||||
|
@ -1560,7 +1556,7 @@ class Bidder(NucypherTokenActor):
|
|||
|
||||
def _get_max_bonus_bid_from_max_stake(self) -> int:
|
||||
"""Returns maximum allowed bid calculated from maximum allowed locked tokens"""
|
||||
max_bonus_tokens = self.economics.maximum_allowed_locked - self.economics.minimum_allowed_locked
|
||||
max_bonus_tokens = self.economics.maximum_allowed_locked - self.economics.min_authorization
|
||||
bonus_eth_supply = sum(
|
||||
self._all_bonus_bidders.values()) if self._all_bonus_bidders else self.worklock_agent.get_bonus_eth_supply()
|
||||
bonus_worklock_supply = self.worklock_agent.get_bonus_lot_value()
|
||||
|
@ -1603,7 +1599,7 @@ class Bidder(NucypherTokenActor):
|
|||
|
||||
bonus_eth_supply = sum(self._all_bonus_bidders.values())
|
||||
bonus_worklock_supply = self.worklock_agent.get_bonus_lot_value()
|
||||
max_bonus_tokens = self.economics.maximum_allowed_locked - self.economics.minimum_allowed_locked
|
||||
max_bonus_tokens = self.economics.maximum_allowed_locked - self.economics.min_authorization
|
||||
if (min_whale_bonus_bid * bonus_worklock_supply) // bonus_eth_supply <= max_bonus_tokens:
|
||||
raise self.WhaleError(f"At least one of bidders {whales} has allowable bid")
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ You should have received a copy of the GNU Affero General Public License
|
|||
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
import os
|
||||
|
||||
import random
|
||||
import sys
|
||||
from bisect import bisect_right
|
||||
|
|
|
@ -26,10 +26,9 @@ from constant_sorrow.constants import (
|
|||
INIT
|
||||
)
|
||||
from eth_typing.evm import ChecksumAddress
|
||||
from typing import Dict, List, Tuple
|
||||
from web3.contract import Contract
|
||||
|
||||
from nucypher.blockchain.economics import BaseEconomics, StandardTokenEconomics
|
||||
from nucypher.blockchain.economics import Economics
|
||||
from nucypher.blockchain.eth.agents import (
|
||||
AdjudicatorAgent,
|
||||
ContractAgency,
|
||||
|
@ -49,7 +48,6 @@ from nucypher.blockchain.eth.interfaces import (
|
|||
VersionedContract,
|
||||
)
|
||||
from nucypher.blockchain.eth.registry import BaseContractRegistry
|
||||
from nucypher.blockchain.eth.token import TToken
|
||||
from nucypher.crypto.powers import TransactingPower
|
||||
|
||||
|
||||
|
@ -73,7 +71,7 @@ class BaseContractDeployer:
|
|||
class ContractNotDeployed(ContractDeploymentError):
|
||||
pass
|
||||
|
||||
def __init__(self, registry: BaseContractRegistry, economics: BaseEconomics = None):
|
||||
def __init__(self, registry: BaseContractRegistry, economics: Economics = None):
|
||||
|
||||
# Validate
|
||||
self.blockchain = BlockchainInterfaceFactory.get_interface()
|
||||
|
@ -85,10 +83,10 @@ class BaseContractDeployer:
|
|||
self.deployment_receipts = OrderedDict()
|
||||
self._contract = CONTRACT_NOT_DEPLOYED
|
||||
self.__proxy_contract = NotImplemented
|
||||
self.__economics = economics or StandardTokenEconomics()
|
||||
self.__economics = economics or Economics()
|
||||
|
||||
@property
|
||||
def economics(self) -> BaseEconomics:
|
||||
def economics(self) -> Economics:
|
||||
"""Read-only access for economics instance."""
|
||||
return self.__economics
|
||||
|
||||
|
@ -572,7 +570,7 @@ class StakingEscrowDeployer(BaseContractDeployer, UpgradeableContractMixin, Owna
|
|||
confirmations: int = 0,
|
||||
**overrides):
|
||||
constructor_kwargs = {
|
||||
"_minAllowableLockedTokens": self.economics.minimum_allowed_locked,
|
||||
"_minAllowableLockedTokens": self.economics.min_authorization,
|
||||
"_maxAllowableLockedTokens": self.economics.maximum_allowed_locked
|
||||
}
|
||||
constructor_kwargs.update(overrides)
|
||||
|
|
|
@ -242,7 +242,7 @@ class Stake:
|
|||
|
||||
# Economics
|
||||
self.economics = economics
|
||||
self.minimum_nu = NU(int(self.economics.minimum_allowed_locked), NU._unit_name)
|
||||
self.minimum_nu = NU(int(self.economics.min_authorization), NU._unit_name)
|
||||
self.maximum_nu = NU(int(self.economics.maximum_allowed_locked), NU._unit_name)
|
||||
|
||||
# Time
|
||||
|
@ -318,7 +318,7 @@ class Stake:
|
|||
self._status = Stake.Status.UNLOCKED
|
||||
elif self.final_locked_period == current_period:
|
||||
self._status = Stake.Status.LOCKED
|
||||
elif self.value < 2 * self.economics.minimum_allowed_locked:
|
||||
elif self.value < 2 * self.economics.min_authorization:
|
||||
self._status = Stake.Status.EDITABLE
|
||||
else:
|
||||
self._status = Stake.Status.DIVISIBLE
|
||||
|
@ -470,10 +470,10 @@ def validate_value(stake: Stake) -> None:
|
|||
|
||||
def validate_duration(stake: Stake) -> None:
|
||||
"""Validate a single staking lock-time against pre-defined requirements"""
|
||||
if stake.economics.minimum_locked_periods > stake.duration:
|
||||
if stake.economics.min_operator_seconds > stake.duration:
|
||||
raise Stake.StakingError(
|
||||
'Stake duration of {duration} periods is too short; must be at least {minimum} periods.'
|
||||
.format(minimum=stake.economics.minimum_locked_periods, duration=stake.duration))
|
||||
.format(minimum=stake.economics.min_operator_seconds, duration=stake.duration))
|
||||
|
||||
|
||||
def validate_divide(stake: Stake, target_value: NU, additional_periods: int = None) -> None:
|
||||
|
@ -541,10 +541,10 @@ def validate_prolong(stake: Stake, additional_periods: int) -> None:
|
|||
raise Stake.StakingError(f'Cannot prolong a non-editable stake. '
|
||||
f'Selected stake expired {stake.unlock_datetime}.')
|
||||
new_duration = stake.periods_remaining + additional_periods - 1
|
||||
if new_duration < stake.economics.minimum_locked_periods:
|
||||
if new_duration < stake.economics.min_operator_seconds:
|
||||
raise stake.StakingError(f'Sub-stake duration of {new_duration} periods after prolongation '
|
||||
f'is shorter than minimum allowed duration '
|
||||
f'of {stake.economics.minimum_locked_periods} periods.')
|
||||
f'of {stake.economics.min_operator_seconds} periods.')
|
||||
|
||||
|
||||
def validate_merge(stake_1: Stake, stake_2: Stake) -> None:
|
||||
|
|
|
@ -24,7 +24,7 @@ from tabulate import tabulate
|
|||
from typing import Type, Union, Dict
|
||||
from web3.main import Web3
|
||||
|
||||
from nucypher.blockchain.economics import BaseEconomics
|
||||
from nucypher.blockchain.economics import Economics
|
||||
from nucypher.blockchain.eth.deployers import BaseContractDeployer
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainDeployerInterface, VersionedContract, BlockchainInterface
|
||||
from nucypher.blockchain.eth.registry import LocalContractRegistry
|
||||
|
@ -95,9 +95,9 @@ def confirm_staged_stake(staker_address: str, value: NU, lock_periods: int) -> b
|
|||
return True
|
||||
|
||||
|
||||
def confirm_large_and_or_long_stake(value: NU = None, lock_periods: int = None, economics: BaseEconomics = None) -> bool:
|
||||
def confirm_large_and_or_long_stake(value: NU = None, lock_periods: int = None, economics: Economics = None) -> bool:
|
||||
"""Interactively confirm a large stake and/or a long stake duration."""
|
||||
if economics and value and (value > (NU.from_units(economics.minimum_allowed_locked) * 10)): # > 10x min stake
|
||||
if economics and value and (value > (NU.from_units(economics.min_authorization) * 10)): # > 10x min stake
|
||||
click.confirm(CONFIRM_LARGE_STAKE_VALUE.format(value=value), abort=True)
|
||||
if economics and lock_periods and (lock_periods > economics.maximum_rewarded_periods): # > 1 year
|
||||
lock_days = (lock_periods * economics.hours_per_period) // 24
|
||||
|
|
|
@ -520,7 +520,7 @@ def create(general_config: GroupGeneralConfig,
|
|||
click.confirm(CONFIRM_STAKE_USE_UNLOCKED, abort=True)
|
||||
|
||||
token_balance = STAKEHOLDER.staker.calculate_staking_reward() if from_unlocked else STAKEHOLDER.staker.token_balance
|
||||
lower_limit = NU.from_units(economics.minimum_allowed_locked)
|
||||
lower_limit = NU.from_units(economics.min_authorization)
|
||||
locked_tokens = STAKEHOLDER.staker.locked_tokens(periods=1).to_units()
|
||||
upper_limit = min(token_balance, NU.from_units(economics.maximum_allowed_locked - locked_tokens))
|
||||
|
||||
|
@ -537,7 +537,7 @@ def create(general_config: GroupGeneralConfig,
|
|||
value = NU.from_tokens(value)
|
||||
|
||||
if not lock_periods:
|
||||
min_locktime = economics.minimum_locked_periods
|
||||
min_locktime = economics.min_operator_seconds
|
||||
default_locktime = economics.maximum_rewarded_periods
|
||||
max_locktime = MAX_UINT16 - STAKEHOLDER.staker.staking_agent.get_current_period()
|
||||
lock_periods = click.prompt(PROMPT_STAKE_CREATE_LOCK_PERIODS.format(min_locktime=min_locktime,
|
||||
|
@ -872,7 +872,7 @@ def divide(general_config: GroupGeneralConfig,
|
|||
|
||||
# Value
|
||||
if not value:
|
||||
min_allowed_locked = NU.from_units(economics.minimum_allowed_locked)
|
||||
min_allowed_locked = NU.from_units(economics.min_authorization)
|
||||
max_divide_value = max(min_allowed_locked, current_stake.value - min_allowed_locked)
|
||||
prompt = PROMPT_STAKE_DIVIDE_VALUE.format(minimum=min_allowed_locked, maximum=str(max_divide_value))
|
||||
value = click.prompt(prompt, type=stake_value_range)
|
||||
|
@ -960,7 +960,7 @@ def prolong(general_config: GroupGeneralConfig,
|
|||
if not lock_periods:
|
||||
max_extension = MAX_UINT16 - current_stake.final_locked_period
|
||||
# +1 because current period excluded
|
||||
min_extension = economics.minimum_locked_periods - current_stake.periods_remaining + 1
|
||||
min_extension = economics.min_operator_seconds - current_stake.periods_remaining + 1
|
||||
if min_extension < 1:
|
||||
min_extension = 1
|
||||
duration_extension_range = click.IntRange(min=min_extension, max=max_extension, clamp=False)
|
||||
|
|
|
@ -30,7 +30,7 @@ from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_create_bidder(testerchain, test_registry, agency, token_economics):
|
||||
def test_create_bidder(testerchain, test_registry, agency, application_economics):
|
||||
bidder_address = testerchain.unassigned_accounts[0]
|
||||
tpower = TransactingPower(account=bidder_address, signer=Web3Signer(testerchain.client))
|
||||
bidder = Bidder(domain=TEMPORARY_DOMAIN,
|
||||
|
@ -46,8 +46,8 @@ def test_create_bidder(testerchain, test_registry, agency, token_economics):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_bidding(testerchain, agency, token_economics, test_registry):
|
||||
min_allowed_bid = token_economics.worklock_min_allowed_bid
|
||||
def test_bidding(testerchain, agency, application_economics, test_registry):
|
||||
min_allowed_bid = application_economics.worklock_min_allowed_bid
|
||||
max_bid = 2000 * min_allowed_bid
|
||||
small_bids = [random.randrange(min_allowed_bid, 2 * min_allowed_bid) for _ in range(10)]
|
||||
total_small_bids = sum(small_bids)
|
||||
|
@ -69,9 +69,9 @@ def test_bidding(testerchain, agency, token_economics, test_registry):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_cancel_bid(testerchain, agency, token_economics, test_registry):
|
||||
def test_cancel_bid(testerchain, agency, application_economics, test_registry):
|
||||
# Wait until the bidding window closes...
|
||||
testerchain.time_travel(seconds=token_economics.bidding_duration+1)
|
||||
testerchain.time_travel(seconds=application_economics.bidding_duration + 1)
|
||||
|
||||
bidder_address = testerchain.client.accounts[1]
|
||||
tpower = TransactingPower(account=bidder_address, signer=Web3Signer(testerchain.client))
|
||||
|
@ -89,7 +89,7 @@ def test_cancel_bid(testerchain, agency, token_economics, test_registry):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_get_remaining_work(testerchain, agency, token_economics, test_registry):
|
||||
def test_get_remaining_work(testerchain, agency, application_economics, test_registry):
|
||||
bidder_address = testerchain.client.accounts[0]
|
||||
tpower = TransactingPower(account=bidder_address, signer=Web3Signer(testerchain.client))
|
||||
bidder = Bidder(registry=test_registry,
|
||||
|
@ -100,7 +100,7 @@ def test_get_remaining_work(testerchain, agency, token_economics, test_registry)
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_verify_correctness_before_refund(testerchain, agency, token_economics, test_registry):
|
||||
def test_verify_correctness_before_refund(testerchain, agency, application_economics, test_registry):
|
||||
bidder_address = testerchain.client.accounts[0]
|
||||
tpower = TransactingPower(account=bidder_address, signer=Web3Signer(testerchain.client))
|
||||
bidder = Bidder(registry=test_registry,
|
||||
|
@ -112,7 +112,7 @@ def test_verify_correctness_before_refund(testerchain, agency, token_economics,
|
|||
_receipt = bidder.claim()
|
||||
|
||||
# Wait until the cancellation window closes...
|
||||
testerchain.time_travel(seconds=token_economics.cancellation_window_duration+1)
|
||||
testerchain.time_travel(seconds=application_economics.cancellation_window_duration + 1)
|
||||
|
||||
with pytest.raises(Bidder.BidderError):
|
||||
_receipt = bidder.verify_bidding_correctness(gas_limit=100000)
|
||||
|
@ -122,7 +122,7 @@ def test_verify_correctness_before_refund(testerchain, agency, token_economics,
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_force_refund(testerchain, agency, token_economics, test_registry):
|
||||
def test_force_refund(testerchain, agency, application_economics, test_registry):
|
||||
bidder_address = testerchain.client.accounts[0]
|
||||
tpower = TransactingPower(account=bidder_address, signer=Web3Signer(testerchain.client))
|
||||
bidder = Bidder(registry=test_registry,
|
||||
|
@ -150,14 +150,14 @@ def test_force_refund(testerchain, agency, token_economics, test_registry):
|
|||
assert not worklock_agent.bidders_checked()
|
||||
|
||||
# Compare off-chain and on-chain calculations
|
||||
min_bid = token_economics.worklock_min_allowed_bid
|
||||
min_bid = application_economics.worklock_min_allowed_bid
|
||||
for whale, bonus in whales.items():
|
||||
contract_bid = worklock_agent.get_deposited_eth(whale)
|
||||
assert bonus == contract_bid - min_bid
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_verify_correctness(testerchain, agency, token_economics, test_registry):
|
||||
def test_verify_correctness(testerchain, agency, application_economics, test_registry):
|
||||
bidder_address = testerchain.client.accounts[0]
|
||||
tpower = TransactingPower(account=bidder_address, signer=Web3Signer(testerchain.client))
|
||||
bidder = Bidder(registry=test_registry,
|
||||
|
@ -177,7 +177,7 @@ def test_verify_correctness(testerchain, agency, token_economics, test_registry)
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_withdraw_compensation(testerchain, agency, token_economics, test_registry):
|
||||
def test_withdraw_compensation(testerchain, agency, application_economics, test_registry):
|
||||
bidder_address = testerchain.client.accounts[12]
|
||||
tpower = TransactingPower(account=bidder_address, signer=Web3Signer(testerchain.client))
|
||||
bidder = Bidder(registry=test_registry,
|
||||
|
@ -192,7 +192,7 @@ def test_withdraw_compensation(testerchain, agency, token_economics, test_regist
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_claim(testerchain, agency, token_economics, test_registry):
|
||||
def test_claim(testerchain, agency, application_economics, test_registry):
|
||||
bidder_address = testerchain.client.accounts[11]
|
||||
tpower = TransactingPower(account=bidder_address, signer=Web3Signer(testerchain.client))
|
||||
bidder = Bidder(registry=test_registry,
|
||||
|
@ -212,14 +212,14 @@ def test_claim(testerchain, agency, token_economics, test_registry):
|
|||
with pytest.raises(Bidder.ClaimError):
|
||||
_receipt = bidder.claim()
|
||||
|
||||
assert bidder.get_deposited_eth > token_economics.worklock_min_allowed_bid
|
||||
assert bidder.get_deposited_eth > application_economics.worklock_min_allowed_bid
|
||||
assert bidder.completed_work == 0
|
||||
assert bidder.remaining_work <= token_economics.maximum_allowed_locked // 2
|
||||
assert bidder.remaining_work <= application_economics.maximum_allowed_locked // 2
|
||||
assert bidder.refunded_work == 0
|
||||
|
||||
# Ensure that the claimant is now the holder of an unbonded stake.
|
||||
locked_tokens = staking_agent.get_locked_tokens(staker_address=bidder.checksum_address, periods=10)
|
||||
assert locked_tokens <= token_economics.maximum_allowed_locked
|
||||
assert locked_tokens <= application_economics.maximum_allowed_locked
|
||||
|
||||
# Confirm the stake is unbonded
|
||||
worker_address = staking_agent.get_worker_from_staker(staker_address=bidder.checksum_address)
|
||||
|
|
|
@ -33,7 +33,7 @@ from tests.utils.blockchain import TesterBlockchain as _TesterBlockchain
|
|||
|
||||
@pytest.mark.skip()
|
||||
@pytest.mark.usefixtures('testerchain')
|
||||
def test_rapid_deployment(token_economics, test_registry, temp_dir_path, get_random_checksum_address):
|
||||
def test_rapid_deployment(application_economics, test_registry, temp_dir_path, get_random_checksum_address):
|
||||
|
||||
blockchain = _TesterBlockchain(eth_airdrop=False, test_accounts=4)
|
||||
|
||||
|
@ -49,23 +49,23 @@ def test_rapid_deployment(token_economics, test_registry, temp_dir_path, get_ran
|
|||
|
||||
# Start with some hard-coded cases...
|
||||
allocation_data = [{'checksum_address': all_yall[1],
|
||||
'amount': token_economics.maximum_allowed_locked,
|
||||
'lock_periods': token_economics.minimum_locked_periods},
|
||||
'amount': application_economics.maximum_allowed_locked,
|
||||
'lock_periods': application_economics.min_operator_seconds},
|
||||
|
||||
{'checksum_address': all_yall[2],
|
||||
'amount': token_economics.minimum_allowed_locked,
|
||||
'lock_periods': token_economics.minimum_locked_periods},
|
||||
'amount': application_economics.min_authorization,
|
||||
'lock_periods': application_economics.min_operator_seconds},
|
||||
|
||||
{'checksum_address': all_yall[3],
|
||||
'amount': token_economics.minimum_allowed_locked*100,
|
||||
'lock_periods': token_economics.minimum_locked_periods},
|
||||
'amount': application_economics.min_authorization * 100,
|
||||
'lock_periods': application_economics.min_operator_seconds},
|
||||
]
|
||||
|
||||
# Pile on the rest
|
||||
for _ in range(NUMBER_OF_ALLOCATIONS_IN_TESTS - len(allocation_data)):
|
||||
checksum_address = get_random_checksum_address()
|
||||
amount = random.randint(token_economics.minimum_allowed_locked, token_economics.maximum_allowed_locked)
|
||||
duration = random.randint(token_economics.minimum_locked_periods, token_economics.maximum_rewarded_periods)
|
||||
amount = random.randint(application_economics.min_authorization, application_economics.maximum_allowed_locked)
|
||||
duration = random.randint(application_economics.min_operator_seconds, application_economics.maximum_rewarded_periods)
|
||||
random_allocation = {'checksum_address': checksum_address, 'amount': amount, 'lock_periods': duration}
|
||||
allocation_data.append(random_allocation)
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ def test_investigator_requests_slashing(testerchain,
|
|||
test_registry,
|
||||
agency,
|
||||
#mock_ursula_reencrypts,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mocker):
|
||||
|
||||
staker_account = testerchain.staker_account(0)
|
||||
|
@ -58,7 +58,7 @@ def test_investigator_requests_slashing(testerchain,
|
|||
token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=test_registry)
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
|
||||
locked_tokens = token_economics.minimum_allowed_locked * 5
|
||||
locked_tokens = application_economics.min_authorization * 5
|
||||
|
||||
# The staker receives an initial amount of tokens
|
||||
tpower = TransactingPower(account=testerchain.etherbase_account, signer=Web3Signer(testerchain.client))
|
||||
|
@ -73,7 +73,7 @@ def test_investigator_requests_slashing(testerchain,
|
|||
registry=test_registry)
|
||||
|
||||
staker.initialize_stake(amount=NU(locked_tokens, 'NuNit'),
|
||||
lock_periods=token_economics.minimum_locked_periods)
|
||||
lock_periods=application_economics.min_operator_seconds)
|
||||
assert staker.locked_tokens(periods=1) == locked_tokens
|
||||
|
||||
# The staker hasn't bond a worker yet
|
||||
|
@ -105,5 +105,5 @@ def test_investigator_requests_slashing(testerchain,
|
|||
investigator_reward = investigator.token_balance - bobby_old_balance
|
||||
|
||||
assert investigator_reward > 0
|
||||
assert investigator_reward == token_economics.base_penalty / token_economics.reward_coefficient
|
||||
assert investigator_reward == application_economics.base_penalty / application_economics.reward_coefficient
|
||||
assert staker.locked_tokens(periods=1) < locked_tokens
|
||||
|
|
|
@ -31,18 +31,18 @@ from tests.utils.ursula import make_decentralized_ursulas
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_staker_locking_tokens(testerchain, agency, staker, token_economics, test_registry):
|
||||
def test_staker_locking_tokens(testerchain, agency, staker, application_economics, test_registry):
|
||||
token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=test_registry)
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
|
||||
assert NU(token_economics.minimum_allowed_locked, 'NuNit') < staker.token_balance, "Insufficient staker balance"
|
||||
assert NU(application_economics.min_authorization, 'NuNit') < staker.token_balance, "Insufficient staker balance"
|
||||
|
||||
# Make sure staking handles existing token allowance
|
||||
staker.token_agent.approve_transfer(1000000000, staking_agent.contract_address, staker.transacting_power)
|
||||
|
||||
staker.initialize_stake(amount=NU(token_economics.minimum_allowed_locked, 'NuNit'),
|
||||
staker.initialize_stake(amount=NU(application_economics.min_authorization, 'NuNit'),
|
||||
# Lock the minimum amount of tokens
|
||||
lock_periods=token_economics.minimum_locked_periods)
|
||||
lock_periods=application_economics.min_operator_seconds)
|
||||
|
||||
# Verify that the escrow is "approved" to receive tokens
|
||||
allowance = token_agent.contract.functions.allowance(
|
||||
|
@ -55,17 +55,17 @@ def test_staker_locking_tokens(testerchain, agency, staker, token_economics, tes
|
|||
assert 0 == locked_tokens
|
||||
|
||||
locked_tokens = staker.locked_tokens(periods=1)
|
||||
assert token_economics.minimum_allowed_locked == locked_tokens
|
||||
assert application_economics.min_authorization == locked_tokens
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
@pytest.mark.usefixtures("agency")
|
||||
def test_staker_divides_stake(staker, token_economics):
|
||||
stake_value = NU(token_economics.minimum_allowed_locked * 5, 'NuNit')
|
||||
new_stake_value = NU(token_economics.minimum_allowed_locked * 2, 'NuNit')
|
||||
def test_staker_divides_stake(staker, application_economics):
|
||||
stake_value = NU(application_economics.min_authorization * 5, 'NuNit')
|
||||
new_stake_value = NU(application_economics.min_authorization * 2, 'NuNit')
|
||||
|
||||
stake_index = 0
|
||||
duration = int(token_economics.minimum_locked_periods)
|
||||
duration = int(application_economics.min_operator_seconds)
|
||||
staker.initialize_stake(amount=stake_value, lock_periods=duration)
|
||||
stake = staker.stakes[stake_index + 1]
|
||||
|
||||
|
@ -84,7 +84,7 @@ def test_staker_divides_stake(staker, token_economics):
|
|||
assert expected_new_stake == staker.stakes[stake_index + 2].to_stake_info(), 'New stake values are invalid'
|
||||
|
||||
# Provided stake must be part of current stakes
|
||||
new_stake_value = NU.from_units(token_economics.minimum_allowed_locked)
|
||||
new_stake_value = NU.from_units(application_economics.min_authorization)
|
||||
with pytest.raises(ValueError):
|
||||
staker.divide_stake(target_value=new_stake_value, stake=stake, additional_periods=2)
|
||||
stake = staker.stakes[stake_index + 1]
|
||||
|
@ -92,19 +92,19 @@ def test_staker_divides_stake(staker, token_economics):
|
|||
with pytest.raises(ValueError):
|
||||
staker.divide_stake(target_value=new_stake_value, stake=stake, additional_periods=2)
|
||||
|
||||
yet_another_stake_value = NU(token_economics.minimum_allowed_locked, 'NuNit')
|
||||
yet_another_stake_value = NU(application_economics.min_authorization, 'NuNit')
|
||||
stake = staker.stakes[stake_index + 2]
|
||||
|
||||
# New expiration date must extend stake duration
|
||||
origin_stake = stake
|
||||
new_expiration = datetime_at_period(period=origin_stake.final_locked_period,
|
||||
seconds_per_period=token_economics.seconds_per_period,
|
||||
seconds_per_period=application_economics.seconds_per_period,
|
||||
start_of_period=True)
|
||||
with pytest.raises(ValueError):
|
||||
staker.divide_stake(target_value=yet_another_stake_value, stake=stake, expiration=new_expiration)
|
||||
|
||||
new_expiration = datetime_at_period(period=origin_stake.final_locked_period + 2,
|
||||
seconds_per_period=token_economics.seconds_per_period,
|
||||
seconds_per_period=application_economics.seconds_per_period,
|
||||
start_of_period=True)
|
||||
staker.divide_stake(target_value=yet_another_stake_value, stake=stake, expiration=new_expiration)
|
||||
|
||||
|
@ -114,8 +114,8 @@ def test_staker_divides_stake(staker, token_economics):
|
|||
value=yet_another_stake_value,
|
||||
checksum_address=staker.checksum_address,
|
||||
index=3,
|
||||
staking_agent=staker.staking_agent,
|
||||
economics=token_economics)
|
||||
staking_agent=staker.application_agent,
|
||||
economics=application_economics)
|
||||
|
||||
assert 4 == len(staker.stakes), 'A new stake was not added after two stake divisions'
|
||||
assert expected_old_stake == staker.stakes[
|
||||
|
@ -127,13 +127,13 @@ def test_staker_divides_stake(staker, token_economics):
|
|||
|
||||
@pytest.mark.skip()
|
||||
@pytest.mark.usefixtures("agency")
|
||||
def test_staker_prolongs_stake(staker, token_economics):
|
||||
def test_staker_prolongs_stake(staker, application_economics):
|
||||
stake_index = 0
|
||||
origin_stake = staker.stakes[stake_index]
|
||||
|
||||
# Can't use additional periods and expiration together
|
||||
new_expiration = datetime_at_period(period=origin_stake.final_locked_period + 3,
|
||||
seconds_per_period=token_economics.seconds_per_period,
|
||||
seconds_per_period=application_economics.seconds_per_period,
|
||||
start_of_period=True)
|
||||
with pytest.raises(ValueError):
|
||||
staker.prolong_stake(stake=origin_stake, additional_periods=3, expiration=new_expiration)
|
||||
|
@ -156,7 +156,7 @@ def test_staker_prolongs_stake(staker, token_economics):
|
|||
# New expiration date must extend stake duration
|
||||
origin_stake = stake
|
||||
new_expiration = datetime_at_period(period=origin_stake.final_locked_period,
|
||||
seconds_per_period=token_economics.seconds_per_period,
|
||||
seconds_per_period=application_economics.seconds_per_period,
|
||||
start_of_period=True)
|
||||
with pytest.raises(ValueError):
|
||||
staker.prolong_stake(stake=origin_stake, expiration=new_expiration)
|
||||
|
@ -172,10 +172,10 @@ def test_staker_prolongs_stake(staker, token_economics):
|
|||
|
||||
@pytest.mark.skip()
|
||||
@pytest.mark.usefixtures("agency")
|
||||
def test_staker_increases_stake(staker, token_economics):
|
||||
def test_staker_increases_stake(staker, application_economics):
|
||||
stake_index = 0
|
||||
origin_stake = staker.stakes[stake_index]
|
||||
additional_amount = NU.from_units(token_economics.minimum_allowed_locked // 100)
|
||||
additional_amount = NU.from_units(application_economics.min_authorization // 100)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
staker.increase_stake(stake=origin_stake)
|
||||
|
@ -265,7 +265,7 @@ def test_staker_collects_staking_reward(testerchain,
|
|||
staker,
|
||||
blockchain_ursulas,
|
||||
agency,
|
||||
token_economics,
|
||||
application_economics,
|
||||
ursula_decentralized_test_config):
|
||||
token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=test_registry)
|
||||
|
||||
|
@ -278,8 +278,8 @@ def test_staker_collects_staking_reward(testerchain,
|
|||
addresses=[staker.checksum_address],
|
||||
amount=DEVELOPMENT_TOKEN_AIRDROP_AMOUNT)
|
||||
|
||||
staker.initialize_stake(amount=NU(token_economics.minimum_allowed_locked, 'NuNit'), # Lock the minimum amount of tokens
|
||||
lock_periods=int(token_economics.minimum_locked_periods)) # ... for the fewest number of periods
|
||||
staker.initialize_stake(amount=NU(application_economics.min_authorization, 'NuNit'), # Lock the minimum amount of tokens
|
||||
lock_periods=int(application_economics.min_operator_seconds)) # ... for the fewest number of periods
|
||||
|
||||
# Get an unused address for a new worker
|
||||
worker_address = testerchain.unassigned_accounts[-1]
|
||||
|
@ -324,17 +324,17 @@ def test_staker_collects_staking_reward(testerchain,
|
|||
def test_staker_manages_winding_down(testerchain,
|
||||
test_registry,
|
||||
staker,
|
||||
token_economics,
|
||||
application_economics,
|
||||
ursula_decentralized_test_config):
|
||||
# Get worker
|
||||
ursula = make_decentralized_ursulas(ursula_config=ursula_decentralized_test_config,
|
||||
stakers_addresses=[staker.checksum_address],
|
||||
workers_addresses=[staker.worker_address],
|
||||
workers_addresses=[staker.operator_address],
|
||||
registry=test_registry).pop()
|
||||
|
||||
# Enable winding down
|
||||
testerchain.time_travel(periods=1)
|
||||
base_duration = token_economics.minimum_locked_periods + 4
|
||||
base_duration = application_economics.min_operator_seconds + 4
|
||||
receipt = staker.enable_winding_down()
|
||||
assert receipt['status'] == 1
|
||||
assert staker.locked_tokens(base_duration) != 0
|
||||
|
@ -358,7 +358,7 @@ def test_staker_manages_winding_down(testerchain,
|
|||
def test_staker_manages_snapshots(testerchain,
|
||||
test_registry,
|
||||
staker,
|
||||
token_economics,
|
||||
application_economics,
|
||||
ursula_decentralized_test_config):
|
||||
# Disable taking snapshots
|
||||
testerchain.time_travel(periods=1)
|
||||
|
|
|
@ -42,11 +42,11 @@ def test_worker_auto_commitments(mocker,
|
|||
test_registry,
|
||||
staker,
|
||||
agency,
|
||||
token_economics,
|
||||
application_economics,
|
||||
ursula_decentralized_test_config):
|
||||
|
||||
staker.initialize_stake(amount=NU(token_economics.minimum_allowed_locked, 'NuNit'),
|
||||
lock_periods=int(token_economics.minimum_locked_periods))
|
||||
staker.initialize_stake(amount=NU(application_economics.min_authorization, 'NuNit'),
|
||||
lock_periods=int(application_economics.min_operator_seconds))
|
||||
|
||||
# Get an unused address and create a new worker
|
||||
worker_address = testerchain.unassigned_accounts[-1]
|
||||
|
|
|
@ -51,7 +51,7 @@ def mock_ursula(testerchain, account, mocker):
|
|||
def test_adjudicator_slashes(agency,
|
||||
testerchain,
|
||||
#mock_ursula_reencrypts,
|
||||
token_economics,
|
||||
application_economics,
|
||||
test_registry,
|
||||
mocker):
|
||||
|
||||
|
@ -63,7 +63,7 @@ def test_adjudicator_slashes(agency,
|
|||
token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=test_registry)
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
|
||||
locked_tokens = token_economics.minimum_allowed_locked * 5
|
||||
locked_tokens = application_economics.min_authorization * 5
|
||||
|
||||
# The staker receives an initial amount of tokens
|
||||
tpower = TransactingPower(account=testerchain.etherbase_account, signer=Web3Signer(testerchain.client))
|
||||
|
@ -78,7 +78,7 @@ def test_adjudicator_slashes(agency,
|
|||
transacting_power=tpower)
|
||||
|
||||
staker.initialize_stake(amount=NU(locked_tokens, 'NuNit'),
|
||||
lock_periods=token_economics.minimum_locked_periods)
|
||||
lock_periods=application_economics.min_operator_seconds)
|
||||
assert staker.locked_tokens(periods=1) == locked_tokens
|
||||
|
||||
# The staker hasn't bond a worker yet
|
||||
|
|
|
@ -33,7 +33,7 @@ MockPolicyMetadata = collections.namedtuple('MockPolicyMetadata', 'policy_id aut
|
|||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def policy_meta(testerchain, agency, token_economics, blockchain_ursulas, test_registry):
|
||||
def policy_meta(testerchain, agency, application_economics, blockchain_ursulas, test_registry):
|
||||
policy_agent = ContractAgency.get_agent(PolicyManagerAgent, registry=test_registry)
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
_policy_id = os.urandom(POLICY_ID_LENGTH)
|
||||
|
@ -44,7 +44,7 @@ def policy_meta(testerchain, agency, token_economics, blockchain_ursulas, test_r
|
|||
_txhash = policy_agent.create_policy(policy_id=_policy_id,
|
||||
transacting_power=tpower,
|
||||
value=to_wei(1, 'gwei') * len(staker_addresses) * number_of_periods,
|
||||
end_timestamp=now + (number_of_periods - 1) * token_economics.hours_per_period * 60 * 60,
|
||||
end_timestamp=now + (number_of_periods - 1) * application_economics.hours_per_period * 60 * 60,
|
||||
node_addresses=staker_addresses)
|
||||
|
||||
return MockPolicyMetadata(policy_id=_policy_id, author=tpower, addresses=staker_addresses)
|
||||
|
@ -52,7 +52,7 @@ def policy_meta(testerchain, agency, token_economics, blockchain_ursulas, test_r
|
|||
|
||||
@pytest.mark.skip()
|
||||
@pytest.mark.usefixtures('blockchain_ursulas')
|
||||
def test_create_policy(testerchain, agency, token_economics, test_registry):
|
||||
def test_create_policy(testerchain, agency, application_economics, test_registry):
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
policy_agent = ContractAgency.get_agent(PolicyManagerAgent, registry=test_registry)
|
||||
policy_id = os.urandom(POLICY_ID_LENGTH)
|
||||
|
@ -61,8 +61,8 @@ def test_create_policy(testerchain, agency, token_economics, test_registry):
|
|||
tpower = TransactingPower(account=testerchain.alice_account, signer=Web3Signer(testerchain.client))
|
||||
receipt = policy_agent.create_policy(policy_id=policy_id,
|
||||
transacting_power=tpower,
|
||||
value=token_economics.minimum_allowed_locked,
|
||||
end_timestamp=now + 10 * token_economics.hours_per_period * 60,
|
||||
value=application_economics.min_authorization,
|
||||
end_timestamp=now + 10 * application_economics.hours_per_period * 60,
|
||||
node_addresses=node_addresses)
|
||||
|
||||
assert receipt['status'] == 1, "Transaction Rejected"
|
||||
|
@ -145,7 +145,7 @@ def test_set_min_fee_rate(testerchain, test_registry, agency, policy_meta):
|
|||
|
||||
@pytest.mark.skip()
|
||||
@pytest.mark.usefixtures('blockchain_ursulas')
|
||||
def test_collect_policy_fee(testerchain, agency, policy_meta, token_economics, test_registry):
|
||||
def test_collect_policy_fee(testerchain, agency, policy_meta, application_economics, test_registry):
|
||||
token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=test_registry)
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
policy_agent = ContractAgency.get_agent(PolicyManagerAgent, registry=test_registry)
|
||||
|
@ -156,7 +156,7 @@ def test_collect_policy_fee(testerchain, agency, policy_meta, token_economics, t
|
|||
|
||||
|
||||
old_eth_balance = token_agent.blockchain.client.get_balance(staker)
|
||||
for _ in range(token_economics.minimum_locked_periods):
|
||||
for _ in range(application_economics.min_operator_seconds):
|
||||
testerchain.time_travel(periods=1)
|
||||
staking_agent.commit_to_next_period(transacting_power=worker_power)
|
||||
|
||||
|
|
|
@ -37,11 +37,11 @@ def test_unknown_contract(testerchain, test_registry):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_deposit_tokens(testerchain, agency, token_economics, test_registry):
|
||||
def test_deposit_tokens(testerchain, agency, application_economics, test_registry):
|
||||
token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=test_registry)
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
|
||||
locked_tokens = token_economics.minimum_allowed_locked * 5
|
||||
locked_tokens = application_economics.min_authorization * 5
|
||||
|
||||
staker_account = testerchain.unassigned_accounts[0]
|
||||
|
||||
|
@ -51,7 +51,7 @@ def test_deposit_tokens(testerchain, agency, token_economics, test_registry):
|
|||
# The staker receives an initial amount of tokens
|
||||
tpower = TransactingPower(account=testerchain.etherbase_account,
|
||||
signer=Web3Signer(testerchain.client))
|
||||
_txhash = token_agent.transfer(amount=token_economics.minimum_allowed_locked * 10,
|
||||
_txhash = token_agent.transfer(amount=application_economics.min_authorization * 10,
|
||||
target_address=staker_account,
|
||||
transacting_power=tpower)
|
||||
|
||||
|
@ -61,12 +61,12 @@ def test_deposit_tokens(testerchain, agency, token_economics, test_registry):
|
|||
#
|
||||
|
||||
staker_power = TransactingPower(account=staker_account, signer=Web3Signer(testerchain.client))
|
||||
_receipt = token_agent.approve_transfer(amount=token_economics.minimum_allowed_locked * 10, # Approve
|
||||
_receipt = token_agent.approve_transfer(amount=application_economics.min_authorization * 10, # Approve
|
||||
spender_address=staking_agent.contract_address,
|
||||
transacting_power=staker_power)
|
||||
|
||||
receipt = staking_agent.deposit_tokens(amount=locked_tokens,
|
||||
lock_periods=token_economics.minimum_locked_periods,
|
||||
lock_periods=application_economics.min_operator_seconds,
|
||||
transacting_power=staker_power,
|
||||
staker_address=staker_account)
|
||||
|
||||
|
@ -81,15 +81,15 @@ def test_deposit_tokens(testerchain, agency, token_economics, test_registry):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_locked_tokens(testerchain, agency, token_economics, test_registry):
|
||||
def test_locked_tokens(testerchain, agency, application_economics, test_registry):
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
staker_account = testerchain.unassigned_accounts[0]
|
||||
locked_amount = staking_agent.get_locked_tokens(staker_address=staker_account)
|
||||
assert token_economics.maximum_allowed_locked >= locked_amount >= token_economics.minimum_allowed_locked
|
||||
assert application_economics.maximum_allowed_locked >= locked_amount >= application_economics.min_authorization
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_get_all_stakes(testerchain, agency, token_economics, test_registry):
|
||||
def test_get_all_stakes(testerchain, agency, application_economics, test_registry):
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
staker_account = testerchain.unassigned_accounts[0]
|
||||
|
||||
|
@ -99,7 +99,7 @@ def test_get_all_stakes(testerchain, agency, token_economics, test_registry):
|
|||
assert len(stake_info) == 3
|
||||
start_period, end_period, value = stake_info
|
||||
assert end_period > start_period
|
||||
assert token_economics.maximum_allowed_locked > value > token_economics.minimum_allowed_locked
|
||||
assert application_economics.maximum_allowed_locked > value > application_economics.min_authorization
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
|
@ -202,18 +202,18 @@ def test_get_staker_info(agency, testerchain, test_registry):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_divide_stake(agency, testerchain, token_economics, test_registry):
|
||||
def test_divide_stake(agency, testerchain, application_economics, test_registry):
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
|
||||
agent = staking_agent
|
||||
staker_account = testerchain.unassigned_accounts[0]
|
||||
|
||||
locked_tokens = token_economics.minimum_allowed_locked * 2
|
||||
locked_tokens = application_economics.min_authorization * 2
|
||||
|
||||
# Deposit
|
||||
tpower = TransactingPower(account=staker_account, signer=Web3Signer(testerchain.client))
|
||||
_txhash = agent.deposit_tokens(amount=locked_tokens,
|
||||
lock_periods=token_economics.minimum_locked_periods,
|
||||
lock_periods=application_economics.min_operator_seconds,
|
||||
transacting_power=tpower,
|
||||
staker_address=staker_account)
|
||||
|
||||
|
@ -223,7 +223,7 @@ def test_divide_stake(agency, testerchain, token_economics, test_registry):
|
|||
|
||||
receipt = agent.divide_stake(transacting_power=tpower,
|
||||
stake_index=1,
|
||||
target_value=token_economics.minimum_allowed_locked,
|
||||
target_value=application_economics.min_authorization,
|
||||
periods=1)
|
||||
|
||||
assert receipt['status'] == 1, "Transaction Rejected"
|
||||
|
@ -231,9 +231,9 @@ def test_divide_stake(agency, testerchain, token_economics, test_registry):
|
|||
|
||||
stakes = list(agent.get_all_stakes(staker_address=staker_account))
|
||||
assert len(stakes) == stakes_length + 1
|
||||
assert stakes[-2].locked_value == origin_stake.locked_value - token_economics.minimum_allowed_locked
|
||||
assert stakes[-2].locked_value == origin_stake.locked_value - application_economics.min_authorization
|
||||
assert stakes[-2].last_period == origin_stake.last_period
|
||||
assert stakes[-1].locked_value == token_economics.minimum_allowed_locked
|
||||
assert stakes[-1].locked_value == application_economics.min_authorization
|
||||
assert stakes[-1].last_period == origin_stake.last_period + 1
|
||||
|
||||
|
||||
|
@ -256,7 +256,7 @@ def test_prolong_stake(agency, testerchain, test_registry):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_deposit_and_increase(agency, testerchain, test_registry, token_economics):
|
||||
def test_deposit_and_increase(agency, testerchain, test_registry, application_economics):
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
staker_account, worker_account, *other = testerchain.unassigned_accounts
|
||||
|
||||
|
@ -264,7 +264,7 @@ def test_deposit_and_increase(agency, testerchain, test_registry, token_economic
|
|||
original_stake = stakes[0]
|
||||
locked_tokens = staking_agent.get_locked_tokens(staker_account, 1)
|
||||
|
||||
amount = token_economics.minimum_allowed_locked // 2
|
||||
amount = application_economics.min_authorization // 2
|
||||
tpower = TransactingPower(account=staker_account, signer=Web3Signer(testerchain.client))
|
||||
receipt = staking_agent.deposit_and_increase(transacting_power=tpower,
|
||||
stake_index=0,
|
||||
|
@ -319,10 +319,10 @@ def test_collect_staking_reward(agency, testerchain, test_registry):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_winding_down(agency, testerchain, test_registry, token_economics):
|
||||
def test_winding_down(agency, testerchain, test_registry, application_economics):
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
staker_account, worker_account, *other = testerchain.unassigned_accounts
|
||||
duration = token_economics.minimum_locked_periods + 1
|
||||
duration = application_economics.min_operator_seconds + 1
|
||||
worker_power = TransactingPower(account=worker_account, signer=Web3Signer(testerchain.client))
|
||||
|
||||
def check_last_period():
|
||||
|
@ -358,7 +358,7 @@ def test_winding_down(agency, testerchain, test_registry, token_economics):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_lock_and_create(agency, testerchain, test_registry, token_economics):
|
||||
def test_lock_and_create(agency, testerchain, test_registry, application_economics):
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
staker_account, worker_account, *other = testerchain.unassigned_accounts
|
||||
staker_power = TransactingPower(account=staker_account, signer=Web3Signer(testerchain.client))
|
||||
|
@ -368,9 +368,9 @@ def test_lock_and_create(agency, testerchain, test_registry, token_economics):
|
|||
current_locked_tokens = staking_agent.get_locked_tokens(staker_account, 0)
|
||||
next_locked_tokens = staking_agent.get_locked_tokens(staker_account, 1)
|
||||
|
||||
amount = token_economics.minimum_allowed_locked
|
||||
amount = application_economics.min_authorization
|
||||
receipt = staking_agent.lock_and_create(transacting_power=staker_power,
|
||||
lock_periods=token_economics.minimum_locked_periods,
|
||||
lock_periods=application_economics.min_operator_seconds,
|
||||
amount=amount)
|
||||
assert receipt['status'] == 1
|
||||
|
||||
|
@ -379,7 +379,7 @@ def test_lock_and_create(agency, testerchain, test_registry, token_economics):
|
|||
assert len(stakes) == stakes_length + 1
|
||||
new_stake = stakes[-1]
|
||||
current_period = staking_agent.get_current_period()
|
||||
assert new_stake.last_period == current_period + token_economics.minimum_locked_periods
|
||||
assert new_stake.last_period == current_period + application_economics.min_operator_seconds
|
||||
assert new_stake.first_period == current_period + 1
|
||||
assert new_stake.locked_value == amount
|
||||
assert staking_agent.get_locked_tokens(staker_account, 1) == next_locked_tokens + amount
|
||||
|
@ -387,7 +387,7 @@ def test_lock_and_create(agency, testerchain, test_registry, token_economics):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_lock_and_increase(agency, testerchain, test_registry, token_economics):
|
||||
def test_lock_and_increase(agency, testerchain, test_registry, application_economics):
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
staker_account, worker_account, *other = testerchain.unassigned_accounts
|
||||
staker_power = TransactingPower(account=staker_account, signer=Web3Signer(testerchain.client))
|
||||
|
@ -412,7 +412,7 @@ def test_lock_and_increase(agency, testerchain, test_registry, token_economics):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_merge(agency, testerchain, test_registry, token_economics):
|
||||
def test_merge(agency, testerchain, test_registry, application_economics):
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
staker_account = testerchain.unassigned_accounts[0]
|
||||
staker_power = TransactingPower(account=staker_account, signer=Web3Signer(testerchain.client))
|
||||
|
|
|
@ -57,22 +57,22 @@ def test_token_properties(agent):
|
|||
assert not agent._proxy_name # not upgradeable
|
||||
|
||||
|
||||
def test_get_balance(agent, token_economics):
|
||||
def test_get_balance(agent, application_economics):
|
||||
testerchain = agent.blockchain
|
||||
deployer, someone, *everybody_else = testerchain.client.accounts
|
||||
balance = agent.get_balance(address=someone)
|
||||
assert balance == 0
|
||||
balance = agent.get_balance(address=deployer)
|
||||
assert balance == token_economics.erc20_total_supply
|
||||
assert balance == application_economics.erc20_total_supply
|
||||
|
||||
|
||||
def test_approve_transfer(agent, token_economics):
|
||||
def test_approve_transfer(agent, application_economics):
|
||||
testerchain = agent.blockchain
|
||||
deployer, someone, *everybody_else = testerchain.client.accounts
|
||||
tpower = TransactingPower(account=someone, signer=Web3Signer(testerchain.client))
|
||||
|
||||
# Approve
|
||||
receipt = agent.approve_transfer(amount=token_economics.minimum_allowed_locked,
|
||||
receipt = agent.approve_transfer(amount=application_economics.min_authorization,
|
||||
spender_address=agent.contract_address,
|
||||
transacting_power=tpower)
|
||||
|
||||
|
@ -80,13 +80,13 @@ def test_approve_transfer(agent, token_economics):
|
|||
assert receipt['logs'][0]['address'] == agent.contract_address
|
||||
|
||||
|
||||
def test_transfer(agent, token_economics):
|
||||
def test_transfer(agent, application_economics):
|
||||
testerchain = agent.blockchain
|
||||
origin, someone, *everybody_else = testerchain.client.accounts
|
||||
tpower = TransactingPower(account=origin, signer=Web3Signer(testerchain.client))
|
||||
|
||||
old_balance = agent.get_balance(someone)
|
||||
receipt = agent.transfer(amount=token_economics.minimum_allowed_locked,
|
||||
receipt = agent.transfer(amount=application_economics.min_authorization,
|
||||
target_address=someone,
|
||||
transacting_power=tpower)
|
||||
|
||||
|
@ -94,10 +94,10 @@ def test_transfer(agent, token_economics):
|
|||
assert receipt['logs'][0]['address'] == agent.contract_address
|
||||
|
||||
new_balance = agent.get_balance(someone)
|
||||
assert new_balance == old_balance + token_economics.minimum_allowed_locked
|
||||
assert new_balance == old_balance + application_economics.min_authorization
|
||||
|
||||
|
||||
def test_approve_and_call(agent, token_economics, deploy_contract):
|
||||
def test_approve_and_call(agent, application_economics, deploy_contract):
|
||||
testerchain = agent.blockchain
|
||||
deployer, someone, *everybody_else = testerchain.client.accounts
|
||||
|
||||
|
@ -106,7 +106,7 @@ def test_approve_and_call(agent, token_economics, deploy_contract):
|
|||
# Approve and call
|
||||
tpower = TransactingPower(account=someone, signer=Web3Signer(testerchain.client))
|
||||
call_data = b"Good morning, that's a nice tnetennba."
|
||||
receipt = agent.approve_and_call(amount=token_economics.minimum_allowed_locked,
|
||||
receipt = agent.approve_and_call(amount=application_economics.min_authorization,
|
||||
target_address=mock_target.address,
|
||||
transacting_power=tpower,
|
||||
call_data=call_data)
|
||||
|
@ -116,4 +116,4 @@ def test_approve_and_call(agent, token_economics, deploy_contract):
|
|||
|
||||
assert mock_target.functions.extraData().call() == call_data
|
||||
assert mock_target.functions.sender().call() == someone
|
||||
assert mock_target.functions.value().call() == token_economics.minimum_allowed_locked
|
||||
assert mock_target.functions.value().call() == application_economics.min_authorization
|
||||
|
|
|
@ -26,7 +26,7 @@ from nucypher.blockchain.eth.interfaces import BlockchainInterface
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_create_worklock_agent(testerchain, test_registry, agency, token_economics):
|
||||
def test_create_worklock_agent(testerchain, test_registry, agency, application_economics):
|
||||
agent = WorkLockAgent(registry=test_registry)
|
||||
assert agent.contract_address
|
||||
same_agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
|
@ -35,9 +35,9 @@ def test_create_worklock_agent(testerchain, test_registry, agency, token_economi
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_bidding(testerchain, agency, token_economics, test_registry):
|
||||
small_bid = token_economics.worklock_min_allowed_bid
|
||||
big_bid = 5 * token_economics.worklock_min_allowed_bid
|
||||
def test_bidding(testerchain, agency, application_economics, test_registry):
|
||||
small_bid = application_economics.worklock_min_allowed_bid
|
||||
big_bid = 5 * application_economics.worklock_min_allowed_bid
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
|
||||
# Round 1
|
||||
|
@ -56,8 +56,8 @@ def test_bidding(testerchain, agency, token_economics, test_registry):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_get_deposited_eth(testerchain, agency, token_economics, test_registry):
|
||||
small_bid = token_economics.worklock_min_allowed_bid
|
||||
def test_get_deposited_eth(testerchain, agency, application_economics, test_registry):
|
||||
small_bid = application_economics.worklock_min_allowed_bid
|
||||
small_bidder = testerchain.client.accounts[-1]
|
||||
tpower = TransactingPower(account=small_bidder, signer=Web3Signer(testerchain.client))
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
|
@ -68,24 +68,24 @@ def test_get_deposited_eth(testerchain, agency, token_economics, test_registry):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_get_base_deposit_rate(agency, token_economics, test_registry):
|
||||
def test_get_base_deposit_rate(agency, application_economics, test_registry):
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
base_deposit_rate = agent.get_base_deposit_rate()
|
||||
assert base_deposit_rate == token_economics.minimum_allowed_locked / token_economics.worklock_min_allowed_bid
|
||||
assert base_deposit_rate == application_economics.min_authorization / application_economics.worklock_min_allowed_bid
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_get_base_refund_rate(testerchain, agency, token_economics, test_registry):
|
||||
def test_get_base_refund_rate(testerchain, agency, application_economics, test_registry):
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
base_refund_rate = agent.get_base_refund_rate()
|
||||
|
||||
slowing_refund = agent.contract.functions.SLOWING_REFUND().call()
|
||||
assert base_refund_rate == (token_economics.minimum_allowed_locked / token_economics.worklock_min_allowed_bid) * \
|
||||
(slowing_refund / token_economics.worklock_boosting_refund_rate)
|
||||
assert base_refund_rate == (application_economics.min_authorization / application_economics.worklock_min_allowed_bid) * \
|
||||
(slowing_refund / application_economics.worklock_boosting_refund_rate)
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_cancel_bid(testerchain, agency, token_economics, test_registry):
|
||||
def test_cancel_bid(testerchain, agency, application_economics, test_registry):
|
||||
bidder = testerchain.client.accounts[1]
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
tpower = TransactingPower(account=bidder, signer=Web3Signer(testerchain.client))
|
||||
|
@ -101,7 +101,7 @@ def test_cancel_bid(testerchain, agency, token_economics, test_registry):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_get_remaining_work(testerchain, agency, token_economics, test_registry):
|
||||
def test_get_remaining_work(testerchain, agency, application_economics, test_registry):
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
bidder = testerchain.client.accounts[0]
|
||||
remaining = agent.get_remaining_work(checksum_address=bidder)
|
||||
|
@ -109,7 +109,7 @@ def test_get_remaining_work(testerchain, agency, token_economics, test_registry)
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_early_claim(testerchain, agency, token_economics, test_registry):
|
||||
def test_early_claim(testerchain, agency, application_economics, test_registry):
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
bidder = testerchain.client.accounts[0]
|
||||
tpower = TransactingPower(account=bidder, signer=Web3Signer(testerchain.client))
|
||||
|
@ -118,10 +118,10 @@ def test_early_claim(testerchain, agency, token_economics, test_registry):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_cancel_after_bidding(testerchain, agency, token_economics, test_registry):
|
||||
def test_cancel_after_bidding(testerchain, agency, application_economics, test_registry):
|
||||
|
||||
# Wait until the bidding window closes...
|
||||
testerchain.time_travel(seconds=token_economics.bidding_duration+1)
|
||||
testerchain.time_travel(seconds=application_economics.bidding_duration + 1)
|
||||
|
||||
bidder = testerchain.client.accounts[0]
|
||||
tpower = TransactingPower(account=bidder, signer=Web3Signer(testerchain.client))
|
||||
|
@ -135,7 +135,7 @@ def test_cancel_after_bidding(testerchain, agency, token_economics, test_registr
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_claim_before_checking(testerchain, agency, token_economics, test_registry):
|
||||
def test_claim_before_checking(testerchain, agency, application_economics, test_registry):
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
bidder = testerchain.client.accounts[2]
|
||||
tpower = TransactingPower(account=bidder, signer=Web3Signer(testerchain.client))
|
||||
|
@ -145,7 +145,7 @@ def test_claim_before_checking(testerchain, agency, token_economics, test_regist
|
|||
_receipt = agent.claim(transacting_power=tpower)
|
||||
|
||||
# Wait until the cancellation window closes...
|
||||
testerchain.time_travel(seconds=token_economics.cancellation_end_date+1)
|
||||
testerchain.time_travel(seconds=application_economics.cancellation_end_date + 1)
|
||||
|
||||
assert not agent.is_claiming_available()
|
||||
with pytest.raises(TransactionFailed):
|
||||
|
@ -153,7 +153,7 @@ def test_claim_before_checking(testerchain, agency, token_economics, test_regist
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_force_refund(testerchain, agency, token_economics, test_registry):
|
||||
def test_force_refund(testerchain, agency, application_economics, test_registry):
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
caller = testerchain.client.accounts[0]
|
||||
tpower = TransactingPower(account=caller, signer=Web3Signer(testerchain.client))
|
||||
|
@ -167,7 +167,7 @@ def test_force_refund(testerchain, agency, token_economics, test_registry):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_verify_correctness(testerchain, agency, token_economics, test_registry):
|
||||
def test_verify_correctness(testerchain, agency, application_economics, test_registry):
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry) # type: WorkLockAgent
|
||||
caller = testerchain.client.accounts[0]
|
||||
tpower = TransactingPower(account=caller, signer=Web3Signer(testerchain.client))
|
||||
|
@ -180,7 +180,7 @@ def test_verify_correctness(testerchain, agency, token_economics, test_registry)
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_withdraw_compensation(testerchain, agency, token_economics, test_registry):
|
||||
def test_withdraw_compensation(testerchain, agency, application_economics, test_registry):
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
bidder = testerchain.client.accounts[2]
|
||||
tpower = TransactingPower(account=bidder, signer=Web3Signer(testerchain.client))
|
||||
|
@ -192,7 +192,7 @@ def test_withdraw_compensation(testerchain, agency, token_economics, test_regist
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_successful_claim(testerchain, agency, token_economics, test_registry):
|
||||
def test_successful_claim(testerchain, agency, application_economics, test_registry):
|
||||
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
|
|
|
@ -27,7 +27,7 @@ from nucypher.crypto.powers import TransactingPower
|
|||
|
||||
|
||||
def test_adjudicator_deployer(testerchain,
|
||||
token_economics,
|
||||
application_economics,
|
||||
deployment_progress,
|
||||
test_registry):
|
||||
|
||||
|
@ -57,11 +57,11 @@ def test_adjudicator_deployer(testerchain,
|
|||
# Check default Adjudicator deployment parameters
|
||||
assert tpower.account != staking_agent.contract_address
|
||||
assert adjudicator_agent.staking_escrow_contract == staking_agent.contract_address
|
||||
assert adjudicator_agent.hash_algorithm == token_economics.hash_algorithm
|
||||
assert adjudicator_agent.base_penalty == token_economics.base_penalty
|
||||
assert adjudicator_agent.penalty_history_coefficient == token_economics.penalty_history_coefficient
|
||||
assert adjudicator_agent.percentage_penalty_coefficient == token_economics.percentage_penalty_coefficient
|
||||
assert adjudicator_agent.reward_coefficient == token_economics.reward_coefficient
|
||||
assert adjudicator_agent.hash_algorithm == application_economics.hash_algorithm
|
||||
assert adjudicator_agent.base_penalty == application_economics.base_penalty
|
||||
assert adjudicator_agent.penalty_history_coefficient == application_economics.penalty_history_coefficient
|
||||
assert adjudicator_agent.percentage_penalty_coefficient == application_economics.percentage_penalty_coefficient
|
||||
assert adjudicator_agent.reward_coefficient == application_economics.reward_coefficient
|
||||
|
||||
# Retrieve the AdjudicatorAgent singleton
|
||||
some_policy_agent = AdjudicatorAgent(registry=test_registry)
|
||||
|
|
|
@ -69,9 +69,9 @@ def test_staking_escrow_has_dispatcher(staking_escrow_deployer, testerchain, tes
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_upgrade(testerchain, test_registry, token_economics, transacting_power):
|
||||
def test_upgrade(testerchain, test_registry, application_economics, transacting_power):
|
||||
|
||||
deployer = StakingEscrowDeployer(registry=test_registry,economics=token_economics)
|
||||
deployer = StakingEscrowDeployer(registry=test_registry, economics=application_economics)
|
||||
|
||||
receipts = deployer.upgrade(ignore_deployed=True, confirmations=0, transacting_power=transacting_power)
|
||||
for title, receipt in receipts.items():
|
||||
|
@ -106,8 +106,8 @@ def test_rollback(testerchain, test_registry, transacting_power):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_deploy_bare_upgradeable_contract_deployment(testerchain, test_registry, token_economics, transacting_power):
|
||||
deployer = StakingEscrowDeployer(registry=test_registry, economics=token_economics)
|
||||
def test_deploy_bare_upgradeable_contract_deployment(testerchain, test_registry, application_economics, transacting_power):
|
||||
deployer = StakingEscrowDeployer(registry=test_registry, economics=application_economics)
|
||||
|
||||
enrolled_names = list(test_registry.enrolled_names)
|
||||
old_number_of_enrollments = enrolled_names.count(StakingEscrowDeployer.contract_name)
|
||||
|
@ -129,8 +129,8 @@ def test_deploy_bare_upgradeable_contract_deployment(testerchain, test_registry,
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_deployer_version_management(testerchain, test_registry, token_economics):
|
||||
deployer = StakingEscrowDeployer(registry=test_registry, economics=token_economics)
|
||||
def test_deployer_version_management(testerchain, test_registry, application_economics):
|
||||
deployer = StakingEscrowDeployer(registry=test_registry, economics=application_economics)
|
||||
|
||||
untargeted_deployment = deployer.get_latest_enrollment()
|
||||
latest_targeted_deployment = deployer.get_principal_contract()
|
||||
|
@ -142,9 +142,9 @@ def test_deployer_version_management(testerchain, test_registry, token_economics
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_manual_proxy_retargeting(testerchain, test_registry, token_economics, transacting_power):
|
||||
def test_manual_proxy_retargeting(testerchain, test_registry, application_economics, transacting_power):
|
||||
|
||||
deployer = StakingEscrowDeployer(registry=test_registry, economics=token_economics)
|
||||
deployer = StakingEscrowDeployer(registry=test_registry, economics=application_economics)
|
||||
|
||||
# Get Proxy-Direct
|
||||
proxy_deployer = deployer.get_proxy_deployer()
|
||||
|
|
|
@ -19,7 +19,7 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
|||
import pytest
|
||||
|
||||
from constant_sorrow import constants
|
||||
from nucypher.blockchain.economics import EconomicsFactory, BaseEconomics
|
||||
from nucypher.blockchain.economics import EconomicsFactory, Economics
|
||||
from nucypher.blockchain.eth.agents import WorkLockAgent
|
||||
from nucypher.blockchain.eth.constants import WORKLOCK_CONTRACT_NAME
|
||||
from nucypher.blockchain.eth.deployers import WorklockDeployer
|
||||
|
@ -34,8 +34,8 @@ def baseline_deployment(staking_escrow_stub_deployer, transacting_power):
|
|||
def worklock_deployer(baseline_deployment,
|
||||
testerchain,
|
||||
test_registry,
|
||||
token_economics):
|
||||
worklock_deployer = WorklockDeployer(registry=test_registry, economics=token_economics)
|
||||
application_economics):
|
||||
worklock_deployer = WorklockDeployer(registry=test_registry, economics=application_economics)
|
||||
return worklock_deployer
|
||||
|
||||
|
||||
|
@ -77,16 +77,16 @@ def test_make_agent(worklock_deployer, test_registry):
|
|||
assert agent.contract_address == another_worklock_agent.contract_address
|
||||
|
||||
|
||||
def test_deployment_parameters(worklock_deployer, test_registry, token_economics):
|
||||
def test_deployment_parameters(worklock_deployer, test_registry, application_economics):
|
||||
|
||||
# Ensure restoration of deployment parameters
|
||||
agent = worklock_deployer.make_agent()
|
||||
params = agent.worklock_parameters()
|
||||
supply, start, end, end_cancellation, boost, locktime, min_bid = params
|
||||
assert token_economics.worklock_supply == supply
|
||||
assert token_economics.bidding_start_date == start
|
||||
assert token_economics.bidding_end_date == end
|
||||
assert token_economics.cancellation_end_date == end_cancellation
|
||||
assert token_economics.worklock_boosting_refund_rate == boost
|
||||
assert token_economics.worklock_commitment_duration == locktime
|
||||
assert token_economics.worklock_min_allowed_bid == min_bid
|
||||
assert application_economics.worklock_supply == supply
|
||||
assert application_economics.bidding_start_date == start
|
||||
assert application_economics.bidding_end_date == end
|
||||
assert application_economics.cancellation_end_date == end_cancellation
|
||||
assert application_economics.worklock_boosting_refund_rate == boost
|
||||
assert application_economics.worklock_commitment_duration == locktime
|
||||
assert application_economics.worklock_min_allowed_bid == min_bid
|
||||
|
|
|
@ -20,12 +20,7 @@ import pytest
|
|||
from nucypher.blockchain.economics import EconomicsFactory
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
@pytest.mark.usefixtures('agency')
|
||||
def test_retrieving_from_blockchain(token_economics, test_registry):
|
||||
|
||||
def test_retrieving_from_blockchain(application_economics, test_registry):
|
||||
economics = EconomicsFactory.get_economics(registry=test_registry)
|
||||
|
||||
assert economics.staking_deployment_parameters == token_economics.staking_deployment_parameters
|
||||
assert economics.slashing_deployment_parameters == token_economics.slashing_deployment_parameters
|
||||
assert economics.worklock_deployment_parameters == token_economics.worklock_deployment_parameters
|
||||
assert economics.pre_application_deployment_parameters == application_economics.pre_application_deployment_parameters
|
||||
|
|
|
@ -23,7 +23,7 @@ from tests.constants import INSECURE_DEVELOPMENT_PASSWORD
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_stake(testerchain, token_economics, agency, test_registry):
|
||||
def test_stake(testerchain, application_economics, agency, test_registry):
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
|
||||
class FakeUrsula:
|
||||
|
@ -43,7 +43,7 @@ def test_stake(testerchain, token_economics, agency, test_registry):
|
|||
value=NU(100, 'NU'),
|
||||
index=0,
|
||||
staking_agent=staking_agent,
|
||||
economics=token_economics)
|
||||
economics=application_economics)
|
||||
|
||||
assert stake.value, 'NU' == NU(100, 'NU')
|
||||
|
||||
|
@ -53,7 +53,7 @@ def test_stake(testerchain, token_economics, agency, test_registry):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_stake_equality(token_economics, get_random_checksum_address, mocker):
|
||||
def test_stake_equality(application_economics, get_random_checksum_address, mocker):
|
||||
address = get_random_checksum_address()
|
||||
a_different_address = get_random_checksum_address()
|
||||
|
||||
|
@ -65,7 +65,7 @@ def test_stake_equality(token_economics, get_random_checksum_address, mocker):
|
|||
value=NU(100, 'NU'),
|
||||
index=0,
|
||||
staking_agent=mock_agent,
|
||||
economics=token_economics)
|
||||
economics=application_economics)
|
||||
|
||||
assert stake == stake
|
||||
|
||||
|
@ -83,7 +83,7 @@ def test_stake_equality(token_economics, get_random_checksum_address, mocker):
|
|||
value=NU(100, 'NU'),
|
||||
index=1,
|
||||
staking_agent=mock_agent,
|
||||
economics=token_economics)
|
||||
economics=application_economics)
|
||||
|
||||
assert stake != a_different_stake
|
||||
|
||||
|
@ -94,7 +94,7 @@ def test_stake_equality(token_economics, get_random_checksum_address, mocker):
|
|||
value=NU(100, 'NU'),
|
||||
index=0,
|
||||
staking_agent=undercover_agent,
|
||||
economics=token_economics)
|
||||
economics=application_economics)
|
||||
|
||||
assert stake != another_different_stake
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ def test_software_stakeholder_configuration(testerchain,
|
|||
def test_initialize_stake_with_existing_account(testerchain,
|
||||
software_stakeholder,
|
||||
stake_value,
|
||||
token_economics,
|
||||
application_economics,
|
||||
test_registry):
|
||||
|
||||
assert len(software_stakeholder.staker.stakes) == 0
|
||||
|
@ -83,7 +83,7 @@ def test_initialize_stake_with_existing_account(testerchain,
|
|||
# sending tokens and ethers from the funding account
|
||||
# to the staker's account, then initializing a new stake.
|
||||
software_stakeholder.staker.initialize_stake(amount=stake_value,
|
||||
lock_periods=token_economics.minimum_locked_periods)
|
||||
lock_periods=application_economics.min_operator_seconds)
|
||||
stake = software_stakeholder.staker.stakes[0]
|
||||
|
||||
# Wait for stake to begin
|
||||
|
@ -94,17 +94,17 @@ def test_initialize_stake_with_existing_account(testerchain,
|
|||
|
||||
# Ensure common stake perspective between stakeholder and stake
|
||||
assert stake.value == stake_value
|
||||
assert stake.duration == token_economics.minimum_locked_periods
|
||||
assert stake.duration == application_economics.min_operator_seconds
|
||||
|
||||
stakes = list(staking_agent.get_all_stakes(staker_address=stake.staker_address))
|
||||
assert len(stakes) == 1
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_divide_stake(software_stakeholder, token_economics, test_registry):
|
||||
def test_divide_stake(software_stakeholder, application_economics, test_registry):
|
||||
stake = software_stakeholder.staker.stakes[0]
|
||||
|
||||
target_value = token_economics.minimum_allowed_locked
|
||||
target_value = application_economics.min_authorization
|
||||
pre_divide_stake_value = stake.value
|
||||
|
||||
software_stakeholder.staker.divide_stake(stake=stake, additional_periods=10, target_value=target_value)
|
||||
|
|
|
@ -234,13 +234,13 @@ def test_bare_contract_deployment_to_alternate_registry(click_runner, agency_loc
|
|||
# TODO: test to validate retargetting via multisig, specifically, building the transaction
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_manual_proxy_retargeting(monkeypatch, testerchain, click_runner, token_economics):
|
||||
def test_manual_proxy_retargeting(monkeypatch, testerchain, click_runner, application_economics):
|
||||
|
||||
# A local, alternate filepath registry exists
|
||||
assert ALTERNATE_REGISTRY_FILEPATH.exists()
|
||||
local_registry = LocalContractRegistry(filepath=ALTERNATE_REGISTRY_FILEPATH)
|
||||
deployer = StakingEscrowDeployer(registry=local_registry,
|
||||
economics=token_economics)
|
||||
economics=application_economics)
|
||||
proxy_deployer = deployer.get_proxy_deployer()
|
||||
|
||||
# Un-targeted enrollment is indeed un targeted by the proxy
|
||||
|
|
|
@ -55,7 +55,7 @@ def bids(testerchain):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_status(click_runner, testerchain, agency_local_registry, token_economics):
|
||||
def test_status(click_runner, testerchain, agency_local_registry, application_economics):
|
||||
command = ('status',
|
||||
'--registry-filepath', str(agency_local_registry.filepath.absolute()),
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
|
@ -64,12 +64,12 @@ def test_status(click_runner, testerchain, agency_local_registry, token_economic
|
|||
result = click_runner.invoke(worklock, command, catch_exceptions=False)
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert str(NU.from_units(token_economics.worklock_supply)) in result.output
|
||||
assert str(Web3.fromWei(token_economics.worklock_min_allowed_bid, 'ether')) in result.output
|
||||
assert str(NU.from_units(application_economics.worklock_supply)) in result.output
|
||||
assert str(Web3.fromWei(application_economics.worklock_min_allowed_bid, 'ether')) in result.output
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_bid(click_runner, testerchain, agency_local_registry, token_economics, bids):
|
||||
def test_bid(click_runner, testerchain, agency_local_registry, application_economics, bids):
|
||||
|
||||
# Wait until biding window starts
|
||||
testerchain.time_travel(seconds=90)
|
||||
|
@ -102,7 +102,7 @@ def test_bid(click_runner, testerchain, agency_local_registry, token_economics,
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_cancel_bid(click_runner, testerchain, agency_local_registry, token_economics, bids):
|
||||
def test_cancel_bid(click_runner, testerchain, agency_local_registry, application_economics, bids):
|
||||
|
||||
bidders = list(bids.keys())
|
||||
|
||||
|
@ -123,7 +123,7 @@ def test_cancel_bid(click_runner, testerchain, agency_local_registry, token_econ
|
|||
assert not agent.get_deposited_eth(bidder) # No more bid
|
||||
|
||||
# Wait until the end of the bidding period
|
||||
testerchain.time_travel(seconds=token_economics.bidding_duration + 2)
|
||||
testerchain.time_travel(seconds=application_economics.bidding_duration + 2)
|
||||
|
||||
bidder = bidders[-2]
|
||||
command = ('cancel-escrow',
|
||||
|
@ -141,10 +141,10 @@ def test_cancel_bid(click_runner, testerchain, agency_local_registry, token_econ
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_enable_claiming(click_runner, testerchain, agency_local_registry, token_economics):
|
||||
def test_enable_claiming(click_runner, testerchain, agency_local_registry, application_economics):
|
||||
|
||||
# Wait until the end of the cancellation period
|
||||
testerchain.time_travel(seconds=token_economics.cancellation_window_duration+2)
|
||||
testerchain.time_travel(seconds=application_economics.cancellation_window_duration + 2)
|
||||
|
||||
bidder = testerchain.client.accounts[0]
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=agency_local_registry)
|
||||
|
@ -168,7 +168,7 @@ def test_enable_claiming(click_runner, testerchain, agency_local_registry, token
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_claim(click_runner, testerchain, agency_local_registry, token_economics):
|
||||
def test_claim(click_runner, testerchain, agency_local_registry, application_economics):
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=agency_local_registry)
|
||||
|
||||
bidder = testerchain.client.accounts[2]
|
||||
|
@ -203,7 +203,7 @@ def test_claim(click_runner, testerchain, agency_local_registry, token_economics
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_remaining_work(click_runner, testerchain, agency_local_registry, token_economics):
|
||||
def test_remaining_work(click_runner, testerchain, agency_local_registry, application_economics):
|
||||
bidder = testerchain.client.accounts[2]
|
||||
|
||||
# Ensure there is remaining work one layer below
|
||||
|
@ -226,13 +226,14 @@ def test_remaining_work(click_runner, testerchain, agency_local_registry, token_
|
|||
assert str(remaining_work) in result.output
|
||||
|
||||
|
||||
def test_refund(click_runner, testerchain, agency_local_registry, token_economics):
|
||||
@pytest.mark.skip()
|
||||
def test_refund(click_runner, testerchain, agency_local_registry, application_economics):
|
||||
|
||||
bidder = testerchain.client.accounts[2]
|
||||
worker_address = testerchain.unassigned_accounts[-1]
|
||||
operator_address = testerchain.unassigned_accounts[-1]
|
||||
|
||||
#
|
||||
# WorkLock Staker-Worker
|
||||
# WorkLock Staker-Operator
|
||||
#
|
||||
|
||||
worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=agency_local_registry)
|
||||
|
@ -287,7 +288,7 @@ def test_refund(click_runner, testerchain, agency_local_registry, token_economic
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_participant_status(click_runner, testerchain, agency_local_registry, token_economics):
|
||||
def test_participant_status(click_runner, testerchain, agency_local_registry, application_economics):
|
||||
|
||||
tpower = TransactingPower(account=testerchain.client.accounts[2],
|
||||
signer=Web3Signer(testerchain.client))
|
||||
|
@ -311,5 +312,5 @@ def test_participant_status(click_runner, testerchain, agency_local_registry, to
|
|||
assert str(bidder.available_refund) in result.output
|
||||
|
||||
# Worklock economics are displayed
|
||||
assert str(token_economics.worklock_boosting_refund_rate) in result.output
|
||||
assert str(NU.from_units(token_economics.worklock_supply)) in result.output
|
||||
assert str(application_economics.worklock_boosting_refund_rate) in result.output
|
||||
assert str(NU.from_units(application_economics.worklock_supply)) in result.output
|
||||
|
|
|
@ -62,7 +62,7 @@ def test_ursula_and_local_keystore_signer_integration(click_runner,
|
|||
tmp_path,
|
||||
manual_staker,
|
||||
stake_value,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mocker,
|
||||
mock_funded_account_password_keystore,
|
||||
testerchain):
|
||||
|
|
|
@ -93,7 +93,7 @@ def test_new_stakeholder(click_runner,
|
|||
def test_stake_init(click_runner,
|
||||
stakeholder_configuration_file_location,
|
||||
stake_value,
|
||||
token_economics,
|
||||
application_economics,
|
||||
testerchain,
|
||||
agency_local_registry,
|
||||
manual_staker):
|
||||
|
@ -107,7 +107,7 @@ def test_stake_init(click_runner,
|
|||
'--config-file', str(stakeholder_configuration_file_location.absolute()),
|
||||
'--staking-address', manual_staker,
|
||||
'--value', stake_value.to_tokens(),
|
||||
'--lock-periods', token_economics.minimum_locked_periods,
|
||||
'--lock-periods', application_economics.min_operator_seconds,
|
||||
'--force')
|
||||
|
||||
# TODO: This test is writing to the default system directory and ignoring updates to the passed filepath
|
||||
|
@ -127,16 +127,16 @@ def test_stake_init(click_runner,
|
|||
# Test integration with NU
|
||||
start_period, end_period, value = stakes[0]
|
||||
assert NU(int(value), 'NuNit') == stake_value
|
||||
assert (end_period - start_period) == token_economics.minimum_locked_periods - 1
|
||||
assert (end_period - start_period) == application_economics.min_operator_seconds - 1
|
||||
|
||||
# Test integration with Stake
|
||||
stake = Stake.from_stake_info(index=0,
|
||||
checksum_address=manual_staker,
|
||||
stake_info=stakes[0],
|
||||
staking_agent=staking_agent,
|
||||
economics=token_economics)
|
||||
economics=application_economics)
|
||||
assert stake.value == stake_value
|
||||
assert stake.duration == token_economics.minimum_locked_periods
|
||||
assert stake.duration == application_economics.min_operator_seconds
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
|
@ -160,7 +160,7 @@ def test_stake_list(click_runner,
|
|||
@pytest.mark.skip()
|
||||
def test_staker_divide_stakes(click_runner,
|
||||
stakeholder_configuration_file_location,
|
||||
token_economics,
|
||||
application_economics,
|
||||
manual_staker,
|
||||
testerchain,
|
||||
agency_local_registry):
|
||||
|
@ -170,7 +170,7 @@ def test_staker_divide_stakes(click_runner,
|
|||
'--force',
|
||||
'--staking-address', manual_staker,
|
||||
'--index', 0,
|
||||
'--value', NU(token_economics.minimum_allowed_locked, 'NuNit').to_tokens(),
|
||||
'--value', NU(application_economics.min_authorization, 'NuNit').to_tokens(),
|
||||
'--lock-periods', 10)
|
||||
|
||||
result = click_runner.invoke(nucypher_cli,
|
||||
|
@ -184,7 +184,7 @@ def test_staker_divide_stakes(click_runner,
|
|||
user_input = INSECURE_DEVELOPMENT_PASSWORD
|
||||
result = click_runner.invoke(nucypher_cli, stake_args, input=user_input, catch_exceptions=False)
|
||||
assert result.exit_code == 0
|
||||
assert str(NU(token_economics.minimum_allowed_locked, 'NuNit').to_tokens()) in result.output
|
||||
assert str(NU(application_economics.min_authorization, 'NuNit').to_tokens()) in result.output
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
|
@ -225,7 +225,7 @@ def test_stake_prolong(click_runner,
|
|||
@pytest.mark.skip()
|
||||
def test_stake_increase(click_runner,
|
||||
stakeholder_configuration_file_location,
|
||||
token_economics,
|
||||
application_economics,
|
||||
testerchain,
|
||||
agency_local_registry,
|
||||
manual_staker):
|
||||
|
@ -235,7 +235,7 @@ def test_stake_increase(click_runner,
|
|||
assert stakes_length > 0
|
||||
|
||||
selection = 0
|
||||
new_value = NU.from_units(token_economics.minimum_allowed_locked // 10)
|
||||
new_value = NU.from_units(application_economics.min_authorization // 10)
|
||||
origin_stake = stakes[selection]
|
||||
|
||||
stake_args = ('stake', 'increase',
|
||||
|
@ -263,7 +263,7 @@ def test_stake_increase(click_runner,
|
|||
@pytest.mark.skip()
|
||||
def test_merge_stakes(click_runner,
|
||||
stakeholder_configuration_file_location,
|
||||
token_economics,
|
||||
application_economics,
|
||||
testerchain,
|
||||
agency_local_registry,
|
||||
manual_staker,
|
||||
|
@ -273,7 +273,7 @@ def test_merge_stakes(click_runner,
|
|||
'--config-file', str(stakeholder_configuration_file_location.absolute()),
|
||||
'--staking-address', manual_staker,
|
||||
'--value', stake_value.to_tokens(),
|
||||
'--lock-periods', token_economics.minimum_locked_periods + 1,
|
||||
'--lock-periods', application_economics.min_operator_seconds + 1,
|
||||
'--force')
|
||||
user_input = f'0\n' + f'{INSECURE_DEVELOPMENT_PASSWORD}\n' + YES_ENTER
|
||||
result = click_runner.invoke(nucypher_cli, stake_args, input=user_input, catch_exceptions=False)
|
||||
|
@ -576,10 +576,10 @@ def test_collect_rewards_integration(click_runner,
|
|||
random_policy_label,
|
||||
manual_staker,
|
||||
manual_worker,
|
||||
token_economics,
|
||||
application_economics,
|
||||
policy_value):
|
||||
|
||||
half_stake_time = 2 * token_economics.minimum_locked_periods # Test setup
|
||||
half_stake_time = 2 * application_economics.min_operator_seconds # Test setup
|
||||
logger = Logger("Test-CLI") # Enter the Teacher's Logger, and
|
||||
current_period = 0 # State the initial period for incrementing
|
||||
|
||||
|
@ -630,7 +630,7 @@ def test_collect_rewards_integration(click_runner,
|
|||
|
||||
threshold, shares = 1, 1
|
||||
duration_in_periods = 3
|
||||
days = (duration_in_periods - 1) * (token_economics.hours_per_period // 24)
|
||||
days = (duration_in_periods - 1) * (application_economics.hours_per_period // 24)
|
||||
now = testerchain.w3.eth.getBlock('latest').timestamp
|
||||
expiration = maya.MayaDT(now).add(days=days)
|
||||
blockchain_policy = blockchain_alice.grant(bob=blockchain_bob,
|
||||
|
@ -700,7 +700,7 @@ def test_collect_rewards_integration(click_runner,
|
|||
logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<")
|
||||
|
||||
# At least half of the tokens are unlocked (restaking was enabled for some prior periods)
|
||||
assert staker.locked_tokens() >= token_economics.minimum_allowed_locked
|
||||
assert staker.locked_tokens() >= application_economics.min_authorization
|
||||
|
||||
# Collect Policy Fee
|
||||
collection_args = ('stake', 'rewards', 'withdraw',
|
||||
|
|
|
@ -99,7 +99,7 @@ def test_invalid_workers_tolerance(testerchain,
|
|||
blockchain_ursulas,
|
||||
agency,
|
||||
idle_staker,
|
||||
token_economics,
|
||||
application_economics,
|
||||
ursula_decentralized_test_config
|
||||
):
|
||||
#
|
||||
|
@ -119,8 +119,8 @@ def test_invalid_workers_tolerance(testerchain,
|
|||
|
||||
# Now let's create an active worker for this staker.
|
||||
# First, stake something (e.g. the bare minimum)
|
||||
amount = token_economics.minimum_allowed_locked
|
||||
periods = token_economics.minimum_locked_periods
|
||||
amount = application_economics.min_authorization
|
||||
periods = application_economics.min_operator_seconds
|
||||
|
||||
idle_staker.initialize_stake(amount=amount, lock_periods=periods)
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ from web3.contract import Contract
|
|||
|
||||
from nucypher_core.umbral import SecretKey, Signer
|
||||
|
||||
from nucypher.blockchain.economics import BaseEconomics, StandardTokenEconomics
|
||||
from nucypher.blockchain.economics import Economics, Economics
|
||||
from nucypher.blockchain.eth.constants import NULL_ADDRESS, POLICY_ID_LENGTH
|
||||
from nucypher.blockchain.eth.token import NU
|
||||
from nucypher.crypto.utils import sha256_digest
|
||||
|
@ -41,38 +41,38 @@ def pytest_namespace():
|
|||
|
||||
@pytest.fixture(scope='module')
|
||||
def token_economics():
|
||||
economics = StandardTokenEconomics(
|
||||
maximum_allowed_locked=BaseEconomics._default_minimum_allowed_locked * 10
|
||||
economics = Economics(
|
||||
maximum_allowed_locked=Economics._default_minimum_allowed_locked * 10
|
||||
)
|
||||
return economics
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def token(token_economics, deploy_contract):
|
||||
def token(application_economics, deploy_contract):
|
||||
# Create an ERC20 token
|
||||
contract, _ = deploy_contract('NuCypherToken', _totalSupplyOfTokens=token_economics.erc20_total_supply)
|
||||
contract, _ = deploy_contract('NuCypherToken', _totalSupplyOfTokens=application_economics.erc20_total_supply)
|
||||
return contract
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def escrow_dispatcher(testerchain, token, token_economics, deploy_contract):
|
||||
def escrow_dispatcher(testerchain, token, application_economics, deploy_contract):
|
||||
escrow_stub, _ = deploy_contract('StakingEscrowStub',
|
||||
token.address,
|
||||
token_economics.minimum_allowed_locked,
|
||||
token_economics.maximum_allowed_locked)
|
||||
application_economics.min_authorization,
|
||||
application_economics.maximum_allowed_locked)
|
||||
dispatcher, _ = deploy_contract('Dispatcher', escrow_stub.address)
|
||||
return dispatcher
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def worklock(testerchain, token, escrow_dispatcher, token_economics, deploy_contract):
|
||||
def worklock(testerchain, token, escrow_dispatcher, application_economics, deploy_contract):
|
||||
# Creator deploys the worklock using test values
|
||||
now = testerchain.w3.eth.getBlock('latest').timestamp
|
||||
start_bid_date = ((now + 3600) // 3600 + 1) * 3600 # beginning of the next hour plus 1 hour
|
||||
end_bid_date = start_bid_date + 3600
|
||||
end_cancellation_date = end_bid_date + 3600
|
||||
boosting_refund = 100
|
||||
staking_periods = token_economics.minimum_locked_periods
|
||||
staking_periods = application_economics.min_operator_seconds
|
||||
min_allowed_bid = to_wei(1, 'ether')
|
||||
contract, _ = deploy_contract(
|
||||
contract_name='WorkLock',
|
||||
|
@ -183,7 +183,7 @@ def simple_staking_contract_interface(testerchain, staking_interface, simple_sta
|
|||
|
||||
|
||||
def test_worklock_phases(testerchain,
|
||||
token_economics,
|
||||
application_economics,
|
||||
token,
|
||||
escrow,
|
||||
simple_staking_contract,
|
||||
|
@ -193,7 +193,7 @@ def test_worklock_phases(testerchain,
|
|||
testerchain.client.accounts
|
||||
|
||||
# Initialize worklock
|
||||
worklock_supply = 3 * token_economics.minimum_allowed_locked + token_economics.maximum_allowed_locked
|
||||
worklock_supply = 3 * application_economics.min_authorization + application_economics.maximum_allowed_locked
|
||||
tx = token.functions.approve(worklock.address, worklock_supply).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = worklock.functions.tokenDeposit(worklock_supply).transact({'from': creator})
|
||||
|
@ -215,7 +215,7 @@ def test_worklock_phases(testerchain,
|
|||
testerchain.time_travel(hours=2)
|
||||
|
||||
# Staker does bid
|
||||
min_stake = token_economics.minimum_allowed_locked
|
||||
min_stake = application_economics.min_authorization
|
||||
bonus_worklock_supply = worklock_supply - min_stake
|
||||
assert worklock.functions.workInfo(staker2).call()[0] == 0
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == 0
|
||||
|
@ -293,7 +293,7 @@ def test_worklock_phases(testerchain,
|
|||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Do force refund to whale
|
||||
assert worklock.functions.ethToTokens(deposited_eth_1).call() > token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.ethToTokens(deposited_eth_1).call() > application_economics.maximum_allowed_locked
|
||||
staker2_balance = testerchain.w3.eth.getBalance(staker2)
|
||||
tx = worklock.functions.forceRefund([staker2]).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
@ -301,7 +301,7 @@ def test_worklock_phases(testerchain,
|
|||
refund = deposited_eth_1 - staker2_bid
|
||||
assert refund > 0
|
||||
staker2_tokens = worklock.functions.ethToTokens(staker2_bid).call()
|
||||
assert staker2_tokens <= token_economics.maximum_allowed_locked
|
||||
assert staker2_tokens <= application_economics.maximum_allowed_locked
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == worklock_balance
|
||||
assert testerchain.w3.eth.getBalance(staker2) == staker2_balance
|
||||
assert worklock.functions.compensation(staker2).call() == refund
|
||||
|
@ -334,7 +334,7 @@ def test_worklock_phases(testerchain,
|
|||
assert token.functions.balanceOf(worklock.address).call() == worklock_supply - staker2_tokens
|
||||
pytest.escrow_supply = staker2_tokens
|
||||
assert escrow.functions.getAllTokens(staker2).call() == staker2_tokens
|
||||
assert escrow.functions.getCompletedWork(staker2).call() == token_economics.total_supply
|
||||
assert escrow.functions.getCompletedWork(staker2).call() == application_economics.total_supply
|
||||
|
||||
tx = worklock.functions.claim().transact({'from': staker1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
@ -421,13 +421,13 @@ def test_upgrading_and_rollback(testerchain,
|
|||
assert staking_interface_v2.address == staking_interface_router.functions.target().call()
|
||||
|
||||
|
||||
def test_refund(testerchain, escrow, worklock, token_economics):
|
||||
def test_refund(testerchain, escrow, worklock, application_economics):
|
||||
staker1, staker2, staker3, staker4 = testerchain.client.accounts[1:5]
|
||||
deposited_eth_2 = to_wei(1, 'ether')
|
||||
worklock_balance = testerchain.w3.eth.getBalance(worklock.address)
|
||||
|
||||
# Full refund for staker
|
||||
assert escrow.functions.getCompletedWork(staker1).call() == token_economics.total_supply
|
||||
assert escrow.functions.getCompletedWork(staker1).call() == application_economics.total_supply
|
||||
remaining_work = worklock.functions.getRemainingWork(staker1).call()
|
||||
assert remaining_work == 0
|
||||
assert worklock.functions.workInfo(staker1).call()[0] == 2 * deposited_eth_2
|
||||
|
|
|
@ -40,8 +40,8 @@ def threshold_staking(deploy_contract):
|
|||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def pre_application(testerchain, threshold_staking, deploy_contract, token_economics):
|
||||
min_authorization = token_economics.minimum_allowed_locked
|
||||
def pre_application(testerchain, threshold_staking, deploy_contract, application_economics):
|
||||
min_authorization = application_economics.min_authorization
|
||||
min_worker_seconds = 24 * 60 * 60
|
||||
|
||||
# Creator deploys the PRE application
|
||||
|
|
|
@ -24,11 +24,11 @@ from eth_utils import to_checksum_address
|
|||
CONFIRMATION_SLOT = 1
|
||||
|
||||
|
||||
def test_bond_operator(testerchain, threshold_staking, pre_application, token_economics):
|
||||
def test_bond_operator(testerchain, threshold_staking, pre_application, application_economics):
|
||||
creator, staking_provider_1, staking_provider_2, staking_provider_3, staking_provider_4, \
|
||||
operator1, operator2, operator3, owner3, beneficiary, authorizer, *everyone_else = \
|
||||
testerchain.client.accounts
|
||||
min_authorization = token_economics.minimum_allowed_locked
|
||||
min_authorization = application_economics.min_authorization
|
||||
min_operator_seconds = 24 * 60 * 60
|
||||
|
||||
operator_log = pre_application.events.OperatorBonded.createFilter(fromBlock='latest')
|
||||
|
@ -332,9 +332,9 @@ def test_bond_operator(testerchain, threshold_staking, pre_application, token_ec
|
|||
assert len(staking_providers) == 0
|
||||
|
||||
|
||||
def test_confirm_address(testerchain, threshold_staking, pre_application, token_economics, deploy_contract):
|
||||
def test_confirm_address(testerchain, threshold_staking, pre_application, application_economics, deploy_contract):
|
||||
creator, staking_provider, operator, *everyone_else = testerchain.client.accounts
|
||||
min_authorization = token_economics.minimum_allowed_locked
|
||||
min_authorization = application_economics.min_authorization
|
||||
min_operator_seconds = 24 * 60 * 60
|
||||
|
||||
confirmations_log = pre_application.events.OperatorConfirmed.createFilter(fromBlock='latest')
|
||||
|
|
|
@ -44,9 +44,10 @@ def log(message):
|
|||
print(message)
|
||||
|
||||
|
||||
def test_ursula_contract_interaction_methods(ursula_decentralized_test_config, testerchain, threshold_staking, pre_application, token_economics, deploy_contract):
|
||||
creator, staking_provider, worker_address, *everyone_else = testerchain.client.accounts
|
||||
min_authorization = token_economics.minimum_allowed_locked
|
||||
def test_ursula_contract_interaction_methods(ursula_decentralized_test_config, testerchain, threshold_staking, pre_application,
|
||||
application_economics, deploy_contract, test_registry_source_manager):
|
||||
creator, staking_provider, operator_address, *everyone_else = testerchain.client.accounts
|
||||
min_authorization = application_economics.min_authorization
|
||||
|
||||
# make an staking_providers and some stakes
|
||||
tx = threshold_staking.functions.setRoles(staking_provider).transact()
|
||||
|
|
|
@ -21,9 +21,9 @@ from nucypher.blockchain.eth.token import NU
|
|||
|
||||
|
||||
@pytest.fixture()
|
||||
def token(testerchain, token_economics, deploy_contract):
|
||||
def token(testerchain, application_economics, deploy_contract):
|
||||
# Create an ERC20 token
|
||||
token, _ = deploy_contract('NuCypherToken', _totalSupplyOfTokens=token_economics.erc20_total_supply)
|
||||
token, _ = deploy_contract('NuCypherToken', _totalSupplyOfTokens=application_economics.erc20_total_supply)
|
||||
return token
|
||||
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ def pooling_contract_interface(testerchain, staking_interface, pooling_contract)
|
|||
ContractFactoryClass=Contract)
|
||||
|
||||
|
||||
def test_staking(testerchain, token_economics, token, escrow, pooling_contract, pooling_contract_interface):
|
||||
def test_staking(testerchain, application_economics, token, escrow, pooling_contract, pooling_contract_interface):
|
||||
creator = testerchain.client.accounts[0]
|
||||
owner = testerchain.client.accounts[1]
|
||||
worker_owner = testerchain.client.accounts[2]
|
||||
|
@ -72,7 +72,7 @@ def test_staking(testerchain, token_economics, token, escrow, pooling_contract,
|
|||
|
||||
# Give some tokens to delegators
|
||||
for index, delegator in enumerate(delegators):
|
||||
tokens = token_economics.minimum_allowed_locked // (index + 1) * 2
|
||||
tokens = application_economics.min_authorization // (index + 1) * 2
|
||||
tx = token.functions.transfer(delegator, tokens).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
|
@ -159,7 +159,7 @@ def test_staking(testerchain, token_economics, token, escrow, pooling_contract,
|
|||
assert not pooling_contract.functions.isWithdrawAllAllowed().call()
|
||||
|
||||
# Can't deposit after stake was created
|
||||
tokens = token_economics.minimum_allowed_locked
|
||||
tokens = application_economics.min_authorization
|
||||
tx = token.functions.approve(pooling_contract.address, tokens).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
|
@ -170,7 +170,7 @@ def test_staking(testerchain, token_economics, token, escrow, pooling_contract,
|
|||
|
||||
# Give some tokens as a reward
|
||||
assert pooling_contract.functions.getAvailableReward().call() == 0
|
||||
reward = token_economics.minimum_allowed_locked
|
||||
reward = application_economics.min_authorization
|
||||
tx = token.functions.approve(escrow.address, reward).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.deposit(pooling_contract.address, reward).transact()
|
||||
|
@ -476,14 +476,14 @@ def test_staking(testerchain, token_economics, token, escrow, pooling_contract,
|
|||
assert pooling_contract.functions.isDepositAllowed().call()
|
||||
assert pooling_contract.functions.isWithdrawAllAllowed().call()
|
||||
delegator = delegators[0]
|
||||
tokens = token_economics.minimum_allowed_locked
|
||||
tokens = application_economics.min_authorization
|
||||
tx = token.functions.approve(pooling_contract.address, tokens).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = pooling_contract.functions.depositTokens(tokens).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
|
||||
def test_fee(testerchain, token_economics, token, policy_manager, pooling_contract, pooling_contract_interface):
|
||||
def test_fee(testerchain, application_economics, token, policy_manager, pooling_contract, pooling_contract_interface):
|
||||
creator = testerchain.client.accounts[0]
|
||||
owner = testerchain.client.accounts[1]
|
||||
delegators = testerchain.client.accounts[2:5]
|
||||
|
@ -496,7 +496,7 @@ def test_fee(testerchain, token_economics, token, policy_manager, pooling_contra
|
|||
|
||||
# Give some tokens to delegators and deposit them
|
||||
for index, delegator in enumerate(delegators):
|
||||
tokens = token_economics.minimum_allowed_locked // (index + 1)
|
||||
tokens = application_economics.min_authorization // (index + 1)
|
||||
tx = token.functions.transfer(delegator, tokens).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = token.functions.approve(pooling_contract.address, tokens).transact({'from': delegator})
|
||||
|
|
|
@ -18,16 +18,16 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
|||
import pytest
|
||||
from web3.contract import Contract
|
||||
|
||||
from nucypher.blockchain.economics import BaseEconomics
|
||||
from nucypher.blockchain.economics import Economics
|
||||
from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
||||
|
||||
VALUE_FIELD = 0
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def token(deploy_contract, token_economics):
|
||||
def token(deploy_contract, application_economics):
|
||||
# Create an ERC20 token
|
||||
token, _ = deploy_contract('NuCypherToken', _totalSupplyOfTokens=token_economics.erc20_total_supply)
|
||||
token, _ = deploy_contract('NuCypherToken', _totalSupplyOfTokens=application_economics.erc20_total_supply)
|
||||
return token
|
||||
|
||||
|
||||
|
|
|
@ -143,13 +143,13 @@ def test_upgrading(testerchain, token, deploy_contract):
|
|||
assert event_args['sender'] == creator
|
||||
|
||||
|
||||
def test_measure_work(testerchain, token, worklock, escrow, token_economics):
|
||||
def test_measure_work(testerchain, token, worklock, escrow, application_economics):
|
||||
creator, staker, *everyone_else = testerchain.w3.eth.accounts
|
||||
|
||||
# Measured work must be 0 and completed work must be maximum even before deposit
|
||||
assert worklock.functions.setWorkMeasurement(staker, True).call() == 0
|
||||
assert worklock.functions.setWorkMeasurement(staker, False).call() == 0
|
||||
assert escrow.functions.getCompletedWork(staker).call() == token_economics.total_supply
|
||||
assert escrow.functions.getCompletedWork(staker).call() == application_economics.total_supply
|
||||
|
||||
# Same behaviour after depositing tokens
|
||||
value = NU(15_000, 'NU').to_units()
|
||||
|
@ -159,10 +159,10 @@ def test_measure_work(testerchain, token, worklock, escrow, token_economics):
|
|||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.setWorkMeasurement(staker, True).call() == 0
|
||||
assert worklock.functions.setWorkMeasurement(staker, False).call() == 0
|
||||
assert escrow.functions.getCompletedWork(staker).call() == token_economics.total_supply
|
||||
assert escrow.functions.getCompletedWork(staker).call() == application_economics.total_supply
|
||||
|
||||
|
||||
def test_snapshots(testerchain, token, escrow, worklock, threshold_staking, token_economics):
|
||||
def test_snapshots(testerchain, token, escrow, worklock, threshold_staking, application_economics):
|
||||
|
||||
creator = testerchain.client.accounts[0]
|
||||
staker1 = testerchain.client.accounts[1]
|
||||
|
@ -170,7 +170,7 @@ def test_snapshots(testerchain, token, escrow, worklock, threshold_staking, toke
|
|||
|
||||
now = testerchain.get_block_number()
|
||||
assert escrow.functions.totalStakedForAt(staker1, now).call() == 0
|
||||
assert escrow.functions.totalStakedAt(now).call() == token_economics.total_supply
|
||||
assert escrow.functions.totalStakedAt(now).call() == application_economics.total_supply
|
||||
|
||||
# Staker deposits some tokens
|
||||
value = NU(15_000, 'NU').to_units()
|
||||
|
@ -182,7 +182,7 @@ def test_snapshots(testerchain, token, escrow, worklock, threshold_staking, toke
|
|||
|
||||
now = testerchain.get_block_number()
|
||||
assert escrow.functions.totalStakedForAt(staker1, now).call() == 0
|
||||
assert escrow.functions.totalStakedAt(now).call() == token_economics.total_supply
|
||||
assert escrow.functions.totalStakedAt(now).call() == application_economics.total_supply
|
||||
|
||||
# A SECOND STAKER APPEARS:
|
||||
|
||||
|
@ -194,7 +194,7 @@ def test_snapshots(testerchain, token, escrow, worklock, threshold_staking, toke
|
|||
assert deposit_staker2 == escrow.functions.getAllTokens(staker2).call()
|
||||
now = testerchain.get_block_number()
|
||||
assert escrow.functions.totalStakedForAt(staker2, now).call() == 0
|
||||
assert escrow.functions.totalStakedAt(now).call() == token_economics.total_supply
|
||||
assert escrow.functions.totalStakedAt(now).call() == application_economics.total_supply
|
||||
|
||||
# Finally, the first staker withdraws some tokens
|
||||
withdrawal = 42
|
||||
|
@ -204,4 +204,4 @@ def test_snapshots(testerchain, token, escrow, worklock, threshold_staking, toke
|
|||
assert last_balance_staker1 == escrow.functions.getAllTokens(staker1).call()
|
||||
now = testerchain.get_block_number()
|
||||
assert escrow.functions.totalStakedForAt(staker1, now).call() == 0
|
||||
assert escrow.functions.totalStakedAt(now).call() == token_economics.total_supply
|
||||
assert escrow.functions.totalStakedAt(now).call() == application_economics.total_supply
|
||||
|
|
|
@ -20,7 +20,7 @@ import pytest
|
|||
from eth_tester.exceptions import TransactionFailed
|
||||
|
||||
|
||||
def test_create_token(testerchain, token_economics, deploy_contract):
|
||||
def test_create_token(testerchain, application_economics, deploy_contract):
|
||||
"""
|
||||
These are tests for standard tokens taken from Consensys github:
|
||||
https://github.com/ConsenSys/Tokens/
|
||||
|
@ -34,11 +34,11 @@ def test_create_token(testerchain, token_economics, deploy_contract):
|
|||
assert creator == testerchain.client.coinbase
|
||||
|
||||
# Create an ERC20 token
|
||||
token, txhash = deploy_contract('NuCypherToken', token_economics.erc20_total_supply)
|
||||
token, txhash = deploy_contract('NuCypherToken', application_economics.erc20_total_supply)
|
||||
assert txhash is not None
|
||||
|
||||
# Account balances
|
||||
assert token_economics.erc20_total_supply == token.functions.balanceOf(creator).call()
|
||||
assert application_economics.erc20_total_supply == token.functions.balanceOf(creator).call()
|
||||
assert 0 == token.functions.balanceOf(account1).call()
|
||||
|
||||
# Basic properties
|
||||
|
@ -58,7 +58,7 @@ def test_create_token(testerchain, token_economics, deploy_contract):
|
|||
tx = token.functions.transfer(account1, 10000).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert 10000 == token.functions.balanceOf(account1).call()
|
||||
assert token_economics.erc20_total_supply - 10000 == token.functions.balanceOf(creator).call()
|
||||
assert application_economics.erc20_total_supply - 10000 == token.functions.balanceOf(creator).call()
|
||||
tx = token.functions.transfer(account2, 10).transact({'from': account1})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert 10000 - 10 == token.functions.balanceOf(account1).call()
|
||||
|
@ -68,12 +68,12 @@ def test_create_token(testerchain, token_economics, deploy_contract):
|
|||
assert 10 == token.functions.balanceOf(token.address).call()
|
||||
|
||||
|
||||
def test_approve_and_call(testerchain, token_economics, deploy_contract):
|
||||
def test_approve_and_call(testerchain, application_economics, deploy_contract):
|
||||
creator = testerchain.client.accounts[0]
|
||||
account1 = testerchain.client.accounts[1]
|
||||
account2 = testerchain.client.accounts[2]
|
||||
|
||||
token, _ = deploy_contract('NuCypherToken', token_economics.erc20_total_supply)
|
||||
token, _ = deploy_contract('NuCypherToken', application_economics.erc20_total_supply)
|
||||
mock, _ = deploy_contract('ReceiveApprovalMethodMock')
|
||||
|
||||
# Approve some value and check allowance
|
||||
|
|
|
@ -24,19 +24,19 @@ from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
|||
|
||||
|
||||
@pytest.fixture()
|
||||
def token(testerchain, token_economics, deploy_contract):
|
||||
contract, _ = deploy_contract('NuCypherToken', _totalSupplyOfTokens=token_economics.erc20_total_supply)
|
||||
def token(testerchain, application_economics, deploy_contract):
|
||||
contract, _ = deploy_contract('NuCypherToken', _totalSupplyOfTokens=application_economics.erc20_total_supply)
|
||||
return contract
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def escrow(testerchain, token_economics, deploy_contract, token):
|
||||
def escrow(testerchain, application_economics, deploy_contract, token):
|
||||
contract, _ = deploy_contract(
|
||||
contract_name='StakingEscrowForWorkLockMock',
|
||||
_token=token.address,
|
||||
_minAllowableLockedTokens=token_economics.minimum_allowed_locked,
|
||||
_maxAllowableLockedTokens=token_economics.maximum_allowed_locked,
|
||||
_minLockedPeriods=token_economics.minimum_locked_periods
|
||||
_minAllowableLockedTokens=application_economics.min_authorization,
|
||||
_maxAllowableLockedTokens=application_economics.maximum_allowed_locked,
|
||||
_minLockedPeriods=application_economics.min_operator_seconds
|
||||
)
|
||||
return contract
|
||||
|
||||
|
@ -47,14 +47,14 @@ MIN_ALLOWED_BID = to_wei(1, 'ether')
|
|||
|
||||
|
||||
@pytest.fixture()
|
||||
def worklock_factory(testerchain, token, escrow, token_economics, deploy_contract):
|
||||
def worklock_factory(testerchain, token, escrow, application_economics, deploy_contract):
|
||||
def deploy_worklock(supply, bidding_delay, additional_time_to_cancel, boosting_refund):
|
||||
|
||||
now = testerchain.w3.eth.getBlock('latest').timestamp
|
||||
start_bid_date = now + bidding_delay
|
||||
end_bid_date = start_bid_date + BIDDING_DURATION
|
||||
end_cancellation_date = end_bid_date + additional_time_to_cancel
|
||||
staking_periods = 2 * token_economics.minimum_locked_periods
|
||||
staking_periods = 2 * application_economics.min_operator_seconds
|
||||
|
||||
contract, _ = deploy_contract(
|
||||
contract_name='WorkLock',
|
||||
|
@ -87,7 +87,7 @@ def do_bids(testerchain, worklock, bidders, amount):
|
|||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
|
||||
def test_worklock(testerchain, token_economics, deploy_contract, token, escrow, worklock_factory):
|
||||
def test_worklock(testerchain, application_economics, deploy_contract, token, escrow, worklock_factory):
|
||||
creator, staker1, staker2, staker3, staker4, *everyone_else = testerchain.w3.eth.accounts
|
||||
gas_to_save_state = 30000
|
||||
|
||||
|
@ -97,7 +97,7 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow,
|
|||
end_bid_date = start_bid_date + ONE_HOUR
|
||||
end_cancellation_date = end_bid_date + ONE_HOUR
|
||||
slowing_refund = 100
|
||||
staking_periods = 2 * token_economics.minimum_locked_periods
|
||||
staking_periods = 2 * application_economics.min_operator_seconds
|
||||
boosting_refund = 50
|
||||
|
||||
worklock = worklock_factory(supply=0,
|
||||
|
@ -111,8 +111,8 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow,
|
|||
assert worklock.functions.boostingRefund().call() == boosting_refund
|
||||
assert worklock.functions.SLOWING_REFUND().call() == slowing_refund
|
||||
assert worklock.functions.stakingPeriods().call() == staking_periods
|
||||
assert worklock.functions.maxAllowableLockedTokens().call() == token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.minAllowableLockedTokens().call() == token_economics.minimum_allowed_locked
|
||||
assert worklock.functions.maxAllowableLockedTokens().call() == application_economics.maximum_allowed_locked
|
||||
assert worklock.functions.minAllowableLockedTokens().call() == application_economics.min_authorization
|
||||
|
||||
deposit_log = worklock.events.Deposited.createFilter(fromBlock='latest')
|
||||
bidding_log = worklock.events.Bid.createFilter(fromBlock='latest')
|
||||
|
@ -124,8 +124,8 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow,
|
|||
compensation_log = worklock.events.CompensationWithdrawn.createFilter(fromBlock='latest')
|
||||
|
||||
# Transfer tokens to WorkLock
|
||||
worklock_supply_1 = token_economics.minimum_allowed_locked
|
||||
worklock_supply_2 = 2 * token_economics.maximum_allowed_locked
|
||||
worklock_supply_1 = application_economics.min_authorization
|
||||
worklock_supply_2 = 2 * application_economics.maximum_allowed_locked
|
||||
worklock_supply = worklock_supply_1 + worklock_supply_2
|
||||
tx = token.functions.approve(worklock.address, worklock_supply).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
@ -148,8 +148,8 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow,
|
|||
# Give stakers some ETH
|
||||
deposit_eth_1 = 4 * MIN_ALLOWED_BID
|
||||
deposit_eth_2 = MIN_ALLOWED_BID
|
||||
min_stake = token_economics.minimum_allowed_locked
|
||||
max_stake = token_economics.maximum_allowed_locked
|
||||
min_stake = application_economics.min_authorization
|
||||
max_stake = application_economics.maximum_allowed_locked
|
||||
staker1_balance = 100 * deposit_eth_1
|
||||
tx = testerchain.w3.eth.sendTransaction(
|
||||
{'from': testerchain.etherbase_account, 'to': staker1, 'value': staker1_balance})
|
||||
|
@ -675,10 +675,10 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow,
|
|||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
|
||||
def test_reentrancy(testerchain, token_economics, deploy_contract, escrow, worklock_factory):
|
||||
def test_reentrancy(testerchain, application_economics, deploy_contract, escrow, worklock_factory):
|
||||
# Deploy WorkLock
|
||||
boosting_refund = 100
|
||||
worklock_supply = 2 * token_economics.maximum_allowed_locked
|
||||
worklock_supply = 2 * application_economics.maximum_allowed_locked
|
||||
max_bid = 2 * MIN_ALLOWED_BID
|
||||
worklock = worklock_factory(supply=worklock_supply,
|
||||
bidding_delay=0,
|
||||
|
@ -767,13 +767,13 @@ def test_reentrancy(testerchain, token_economics, deploy_contract, escrow, workl
|
|||
assert len(refund_log.get_all_entries()) == 0
|
||||
|
||||
|
||||
def test_verifying_correctness(testerchain, token_economics, escrow, deploy_contract, worklock_factory):
|
||||
def test_verifying_correctness(testerchain, application_economics, escrow, deploy_contract, worklock_factory):
|
||||
creator, bidder1, bidder2, bidder3, *everyone_else = testerchain.w3.eth.accounts
|
||||
gas_to_save_state = 30000
|
||||
boosting_refund = 100
|
||||
|
||||
# Test: bidder has too much tokens to claim
|
||||
worklock_supply = token_economics.maximum_allowed_locked + 1
|
||||
worklock_supply = application_economics.maximum_allowed_locked + 1
|
||||
worklock = worklock_factory(supply=worklock_supply,
|
||||
bidding_delay=0,
|
||||
additional_time_to_cancel=0,
|
||||
|
@ -793,7 +793,7 @@ def test_verifying_correctness(testerchain, token_economics, escrow, deploy_cont
|
|||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Test: bidder will get tokens as much as possible without force refund
|
||||
worklock_supply = 3 * token_economics.maximum_allowed_locked
|
||||
worklock_supply = 3 * application_economics.maximum_allowed_locked
|
||||
worklock = worklock_factory(supply=worklock_supply,
|
||||
bidding_delay=0,
|
||||
additional_time_to_cancel=0,
|
||||
|
@ -802,7 +802,7 @@ def test_verifying_correctness(testerchain, token_economics, escrow, deploy_cont
|
|||
|
||||
# Bids
|
||||
do_bids(testerchain, worklock, [bidder1, bidder2, bidder3], MIN_ALLOWED_BID)
|
||||
assert worklock.functions.ethToTokens(MIN_ALLOWED_BID).call() == token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.ethToTokens(MIN_ALLOWED_BID).call() == application_economics.maximum_allowed_locked
|
||||
|
||||
# Wait end of bidding
|
||||
testerchain.time_travel(seconds=ONE_HOUR)
|
||||
|
@ -828,7 +828,7 @@ def test_verifying_correctness(testerchain, token_economics, escrow, deploy_cont
|
|||
assert event_args['endIndex'] == 3
|
||||
|
||||
# Test: partial verification with low amount of gas limit
|
||||
worklock_supply = 3 * token_economics.maximum_allowed_locked
|
||||
worklock_supply = 3 * application_economics.maximum_allowed_locked
|
||||
worklock = worklock_factory(supply=worklock_supply,
|
||||
bidding_delay=0,
|
||||
additional_time_to_cancel=0,
|
||||
|
@ -885,13 +885,13 @@ def test_verifying_correctness(testerchain, token_economics, escrow, deploy_cont
|
|||
assert event_args['endIndex'] == 3
|
||||
|
||||
|
||||
def test_force_refund(testerchain, token_economics, deploy_contract, worklock_factory, token):
|
||||
def test_force_refund(testerchain, application_economics, deploy_contract, worklock_factory, token):
|
||||
creator, *bidders = testerchain.w3.eth.accounts
|
||||
boosting_refund = 100
|
||||
gas_to_save_state = 30000
|
||||
|
||||
# All bids are allowed, can't do force refund
|
||||
worklock_supply = len(bidders) * token_economics.maximum_allowed_locked
|
||||
worklock_supply = len(bidders) * application_economics.maximum_allowed_locked
|
||||
worklock = worklock_factory(supply=worklock_supply,
|
||||
bidding_delay=0,
|
||||
additional_time_to_cancel=0,
|
||||
|
@ -924,7 +924,7 @@ def test_force_refund(testerchain, token_economics, deploy_contract, worklock_fa
|
|||
normal_bidders = bidders[6:8]
|
||||
bidders = normal_bidders + hidden_whales + whales
|
||||
|
||||
worklock_supply = len(bidders) * token_economics.maximum_allowed_locked
|
||||
worklock_supply = len(bidders) * application_economics.maximum_allowed_locked
|
||||
worklock = worklock_factory(supply=worklock_supply,
|
||||
bidding_delay=0,
|
||||
additional_time_to_cancel=0,
|
||||
|
@ -941,9 +941,9 @@ def test_force_refund(testerchain, token_economics, deploy_contract, worklock_fa
|
|||
testerchain.time_travel(seconds=ONE_HOUR)
|
||||
|
||||
# Verification founds whales
|
||||
assert worklock.functions.ethToTokens(normal_bid).call() < token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.ethToTokens(hidden_whales_bid).call() < token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.ethToTokens(whales_bid).call() > token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.ethToTokens(normal_bid).call() < application_economics.maximum_allowed_locked
|
||||
assert worklock.functions.ethToTokens(hidden_whales_bid).call() < application_economics.maximum_allowed_locked
|
||||
assert worklock.functions.ethToTokens(whales_bid).call() > application_economics.maximum_allowed_locked
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
@ -970,7 +970,7 @@ def test_force_refund(testerchain, token_economics, deploy_contract, worklock_fa
|
|||
refund = whales_bid - bid
|
||||
assert refund > 0
|
||||
assert bid > normal_bid
|
||||
assert worklock.functions.ethToTokens(bid).call() <= token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.ethToTokens(bid).call() <= application_economics.maximum_allowed_locked
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == worklock_balance
|
||||
assert testerchain.w3.eth.getBalance(whale_1) == whale_1_balance
|
||||
assert worklock.functions.compensation(whale_1).call() == refund
|
||||
|
@ -983,7 +983,7 @@ def test_force_refund(testerchain, token_economics, deploy_contract, worklock_fa
|
|||
assert event_args['refundETH'] == refund
|
||||
|
||||
# Can't verify yet
|
||||
assert worklock.functions.ethToTokens(whales_bid).call() > token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.ethToTokens(whales_bid).call() > application_economics.maximum_allowed_locked
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
@ -1024,7 +1024,7 @@ def test_force_refund(testerchain, token_economics, deploy_contract, worklock_fa
|
|||
refund = whales_bid - bid
|
||||
assert refund > 0
|
||||
assert bid > normal_bid
|
||||
assert worklock.functions.ethToTokens(bid).call() <= token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.ethToTokens(bid).call() <= application_economics.maximum_allowed_locked
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == worklock_balance
|
||||
assert testerchain.w3.eth.getBalance(whale_2) == whale_2_balance
|
||||
assert testerchain.w3.eth.getBalance(whale_3) == whale_3_balance
|
||||
|
@ -1043,7 +1043,7 @@ def test_force_refund(testerchain, token_economics, deploy_contract, worklock_fa
|
|||
assert event_args['refundETH'] == refund
|
||||
|
||||
# Can't verify yet
|
||||
assert worklock.functions.ethToTokens(hidden_whales_bid).call() > token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.ethToTokens(hidden_whales_bid).call() > application_economics.maximum_allowed_locked
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
@ -1063,7 +1063,7 @@ def test_force_refund(testerchain, token_economics, deploy_contract, worklock_fa
|
|||
|
||||
tx = worklock.functions.forceRefund(group).transact({'from': whale_1})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.ethToTokens(normal_bid).call() == token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.ethToTokens(normal_bid).call() == application_economics.maximum_allowed_locked
|
||||
events = refund_log.get_all_entries()
|
||||
assert len(events) == 3 + len(group)
|
||||
|
||||
|
@ -1088,7 +1088,7 @@ def test_force_refund(testerchain, token_economics, deploy_contract, worklock_fa
|
|||
|
||||
# Test extreme case with random values
|
||||
bidders = testerchain.w3.eth.accounts[1:]
|
||||
worklock_supply = 10 * token_economics.maximum_allowed_locked
|
||||
worklock_supply = 10 * application_economics.maximum_allowed_locked
|
||||
max_bid = 2000 * MIN_ALLOWED_BID
|
||||
worklock = worklock_factory(supply=worklock_supply,
|
||||
bidding_delay=0,
|
||||
|
@ -1121,12 +1121,12 @@ def test_force_refund(testerchain, token_economics, deploy_contract, worklock_fa
|
|||
# Bids are correct now
|
||||
for whale in whales:
|
||||
bid = worklock.functions.workInfo(whale).call()[0]
|
||||
assert worklock.functions.ethToTokens(bid).call() <= token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.ethToTokens(bid).call() <= application_economics.maximum_allowed_locked
|
||||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Special case: there are less bidders than n, where n is `worklock_supply // maximum_allowed_locked`
|
||||
worklock_supply = 10 * token_economics.maximum_allowed_locked
|
||||
worklock_supply = 10 * application_economics.maximum_allowed_locked
|
||||
worklock = worklock_factory(supply=worklock_supply,
|
||||
bidding_delay=0,
|
||||
additional_time_to_cancel=0,
|
||||
|
@ -1172,7 +1172,7 @@ def test_force_refund(testerchain, token_economics, deploy_contract, worklock_fa
|
|||
assert event_args['sender'] == bidder1
|
||||
|
||||
|
||||
def test_shutdown(testerchain, token_economics, deploy_contract, worklock_factory, token):
|
||||
def test_shutdown(testerchain, application_economics, deploy_contract, worklock_factory, token):
|
||||
creator, bidder, *everyone_else = testerchain.w3.eth.accounts
|
||||
boosting_refund = 100
|
||||
gas_to_save_state = 30000
|
||||
|
@ -1220,7 +1220,7 @@ def test_shutdown(testerchain, token_economics, deploy_contract, worklock_factor
|
|||
start_bid_date = now
|
||||
end_bid_date = start_bid_date + ONE_HOUR
|
||||
end_cancellation_date = end_bid_date + ONE_HOUR
|
||||
worklock_supply = token_economics.maximum_allowed_locked
|
||||
worklock_supply = application_economics.maximum_allowed_locked
|
||||
worklock = worklock_factory(supply=worklock_supply,
|
||||
bidding_delay=0,
|
||||
additional_time_to_cancel=ONE_HOUR,
|
||||
|
|
|
@ -18,13 +18,14 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
|||
import contextlib
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
import requests
|
||||
from eth_utils import to_wei
|
||||
|
||||
from constant_sorrow import constants
|
||||
from web3.exceptions import ValidationError
|
||||
|
||||
from nucypher.blockchain.economics import BaseEconomics
|
||||
from nucypher.blockchain.economics import Economics
|
||||
from nucypher.blockchain.eth.agents import StakingEscrowAgent, WorkLockAgent
|
||||
from nucypher.blockchain.eth.deployers import (
|
||||
AdjudicatorDeployer,
|
||||
|
|
|
@ -255,13 +255,13 @@ def federated_treasure_map(enacted_federated_policy, federated_bob):
|
|||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def idle_blockchain_policy(testerchain, blockchain_alice, blockchain_bob, token_economics):
|
||||
def idle_blockchain_policy(testerchain, blockchain_alice, blockchain_bob, application_economics):
|
||||
"""
|
||||
Creates a Policy, in a manner typical of how Alice might do it, with a unique label
|
||||
"""
|
||||
random_label = generate_random_label()
|
||||
periods = token_economics.minimum_locked_periods // 2
|
||||
days = periods * (token_economics.hours_per_period // 24)
|
||||
periods = application_economics.min_operator_seconds // 2
|
||||
days = periods * (application_economics.hours_per_period // 24)
|
||||
now = testerchain.w3.eth.getBlock('latest').timestamp
|
||||
expiration = maya.MayaDT(now).add(days=days - 1)
|
||||
shares = 3
|
||||
|
@ -301,10 +301,10 @@ def blockchain_treasure_map(enacted_blockchain_policy, blockchain_bob):
|
|||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def random_blockchain_policy(testerchain, blockchain_alice, blockchain_bob, token_economics):
|
||||
def random_blockchain_policy(testerchain, blockchain_alice, blockchain_bob, application_economics):
|
||||
random_label = generate_random_label()
|
||||
periods = token_economics.minimum_locked_periods // 2
|
||||
days = periods * (token_economics.hours_per_period // 24)
|
||||
periods = application_economics.min_operator_seconds // 2
|
||||
days = periods * (application_economics.hours_per_period // 24)
|
||||
now = testerchain.w3.eth.getBlock('latest').timestamp
|
||||
expiration = maya.MayaDT(now).add(days=days - 1)
|
||||
shares = 3
|
||||
|
@ -491,34 +491,11 @@ def blockchain_porter(blockchain_ursulas, testerchain, test_registry):
|
|||
# Blockchain
|
||||
#
|
||||
|
||||
def make_token_economics(blockchain):
|
||||
# Get current blocktime
|
||||
now = blockchain.w3.eth.getBlock('latest').timestamp
|
||||
|
||||
# Calculate instant start time
|
||||
one_hour_in_seconds = (60 * 60)
|
||||
start_date = now
|
||||
bidding_start_date = start_date
|
||||
|
||||
# Ends in one hour
|
||||
bidding_end_date = start_date + one_hour_in_seconds
|
||||
cancellation_end_date = bidding_end_date + one_hour_in_seconds
|
||||
|
||||
economics = StandardTokenEconomics(
|
||||
worklock_boosting_refund_rate=200,
|
||||
worklock_commitment_duration=60, # genesis periods
|
||||
worklock_supply=10 * BaseEconomics._default_maximum_allowed_locked,
|
||||
bidding_start_date=bidding_start_date,
|
||||
bidding_end_date=bidding_end_date,
|
||||
cancellation_end_date=cancellation_end_date,
|
||||
worklock_min_allowed_bid=Web3.toWei(1, "ether")
|
||||
)
|
||||
return economics
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def token_economics(testerchain):
|
||||
return make_token_economics(blockchain=testerchain)
|
||||
def application_economics():
|
||||
economics = Economics()
|
||||
return economics
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
|
@ -766,8 +743,8 @@ def idle_staker(testerchain, agency, test_registry):
|
|||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def stake_value(token_economics):
|
||||
value = NU(token_economics.minimum_allowed_locked * 2, 'NuNit')
|
||||
def stake_value(application_economics):
|
||||
value = NU(application_economics.min_authorization * 2, 'NuNit')
|
||||
return value
|
||||
|
||||
|
||||
|
@ -778,13 +755,13 @@ def policy_rate():
|
|||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def policy_value(token_economics, policy_rate):
|
||||
value = policy_rate * token_economics.minimum_locked_periods
|
||||
def policy_value(application_economics, policy_rate):
|
||||
value = policy_rate * application_economics.min_operator_seconds
|
||||
return value
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def funded_blockchain(testerchain, agency, token_economics, test_registry):
|
||||
def funded_blockchain(testerchain, agency, application_economics, test_registry):
|
||||
# Who are ya'?
|
||||
deployer_address, *everyone_else, staking_participant = testerchain.client.accounts
|
||||
|
||||
|
@ -798,7 +775,7 @@ def funded_blockchain(testerchain, agency, token_economics, test_registry):
|
|||
token_airdrop(token_agent=NucypherTokenAgent(registry=test_registry),
|
||||
transacting_power=transacting_power,
|
||||
addresses=everyone_else,
|
||||
amount=token_economics.minimum_allowed_locked * 5)
|
||||
amount=application_economics.min_authorization * 5)
|
||||
|
||||
# HERE YOU GO
|
||||
yield testerchain, deployer_address
|
||||
|
@ -1051,12 +1028,12 @@ def nominal_federated_configuration_fields():
|
|||
|
||||
# TODO: Not used?
|
||||
@pytest.fixture(scope='module')
|
||||
def mock_allocation_infile(testerchain, token_economics, get_random_checksum_address):
|
||||
def mock_allocation_infile(testerchain, application_economics, get_random_checksum_address):
|
||||
accounts = [get_random_checksum_address() for _ in range(10)]
|
||||
# accounts = testerchain.unassigned_accounts
|
||||
allocation_data = list()
|
||||
amount = 2 * token_economics.minimum_allowed_locked
|
||||
min_periods = token_economics.minimum_locked_periods
|
||||
amount = 2 * application_economics.min_authorization
|
||||
min_periods = application_economics.min_operator_seconds
|
||||
for account in accounts:
|
||||
substake = [{'checksum_address': account, 'amount': amount, 'lock_periods': min_periods + i} for i in range(24)]
|
||||
allocation_data.extend(substake)
|
||||
|
|
|
@ -21,21 +21,22 @@ from decimal import Decimal, InvalidOperation
|
|||
from nucypher.blockchain.eth.token import NU
|
||||
|
||||
|
||||
def test_NU(token_economics):
|
||||
def test_NU(application_economics):
|
||||
|
||||
# Starting Small
|
||||
min_allowed_locked = NU(token_economics.minimum_allowed_locked, 'NuNit')
|
||||
assert token_economics.minimum_allowed_locked == int(min_allowed_locked.to_units())
|
||||
min_allowed_locked = NU(application_economics.min_authorization, 'NuNit')
|
||||
assert application_economics.min_authorization == int(min_allowed_locked.to_units())
|
||||
|
||||
min_NU_locked = int(str(token_economics.minimum_allowed_locked)[0:-18])
|
||||
min_NU_locked = int(str(application_economics.min_authorization)[0:-18])
|
||||
expected = NU(min_NU_locked, 'NU')
|
||||
assert min_allowed_locked == expected
|
||||
|
||||
# TODO: Use minimums for T staking
|
||||
# Starting Big
|
||||
min_allowed_locked = NU(min_NU_locked, 'NU')
|
||||
assert token_economics.minimum_allowed_locked == int(min_allowed_locked)
|
||||
assert token_economics.minimum_allowed_locked == int(min_allowed_locked.to_units())
|
||||
assert str(min_allowed_locked) == '15000 NU'
|
||||
# min_allowed_locked = NU(min_NU_locked, 'NU')
|
||||
# assert token_economics.min_authorization == int(min_allowed_locked)
|
||||
# assert token_economics.min_authorization == int(min_allowed_locked.to_units())
|
||||
# assert str(min_allowed_locked) == '40000 NU'
|
||||
|
||||
# Alternate construction
|
||||
assert NU(1, 'NU') == NU('1.0', 'NU') == NU(1.0, 'NU')
|
||||
|
|
|
@ -19,8 +19,9 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
|||
from decimal import Decimal, localcontext
|
||||
from math import log
|
||||
|
||||
from nucypher.blockchain.economics import LOG2, StandardTokenEconomics
|
||||
import pytest
|
||||
|
||||
from nucypher.blockchain.economics import Economics
|
||||
|
||||
|
||||
@pytest.mark.skip("remove me")
|
||||
|
@ -82,7 +83,7 @@ def test_exact_economics():
|
|||
|
||||
# Use same precision as economics class
|
||||
with localcontext() as ctx:
|
||||
ctx.prec = StandardTokenEconomics._precision
|
||||
ctx.prec = Economics._precision
|
||||
|
||||
# Sanity check expected testing outputs
|
||||
assert Decimal(expected_total_supply) / expected_initial_supply == expected_supply_ratio
|
||||
|
@ -111,10 +112,10 @@ def test_exact_economics():
|
|||
#
|
||||
|
||||
# Check creation
|
||||
e = StandardTokenEconomics()
|
||||
e = Economics()
|
||||
|
||||
with localcontext() as ctx:
|
||||
ctx.prec = StandardTokenEconomics._precision
|
||||
ctx.prec = Economics._precision
|
||||
one_year_in_periods = Decimal(one_year_in_periods)
|
||||
|
||||
# Check that total_supply calculated correctly
|
||||
|
@ -136,7 +137,7 @@ def test_exact_economics():
|
|||
assert e.reward_supply == expected_total_supply - expected_initial_supply
|
||||
|
||||
# Check deployment parameters
|
||||
assert e.staking_deployment_parameters == expected_deployment_parameters
|
||||
assert e.pre_application_deployment_parameters == expected_deployment_parameters
|
||||
assert e.erc20_initial_supply == expected_initial_supply
|
||||
assert e.erc20_reward_supply == expected_reward_supply
|
||||
|
||||
|
|
|
@ -82,10 +82,10 @@ def test_stake_status(mock_testerchain, application_economics, mock_staking_agen
|
|||
value=value,
|
||||
index=0,
|
||||
staking_agent=mock_staking_agent,
|
||||
economics=token_economics)
|
||||
economics=application_economics)
|
||||
|
||||
# Prepare unlocked sub-stake
|
||||
nu = NU.from_units(2 * token_economics.minimum_allowed_locked - 1)
|
||||
nu = NU.from_units(2 * application_economics.min_authorization - 1)
|
||||
stake = make_sub_stake(nu, current_period - 2, current_period - 1)
|
||||
assert stake.status() == Stake.Status.UNLOCKED
|
||||
|
||||
|
@ -108,7 +108,7 @@ def test_stake_status(mock_testerchain, application_economics, mock_staking_agen
|
|||
assert stake.status() == Stake.Status.EDITABLE
|
||||
|
||||
# Prepare divisible sub-stake
|
||||
nu = NU.from_units(2 * token_economics.minimum_allowed_locked)
|
||||
nu = NU.from_units(2 * application_economics.min_authorization)
|
||||
stake = make_sub_stake(nu, current_period - 2, current_period + 1)
|
||||
assert stake.status() == Stake.Status.DIVISIBLE
|
||||
|
||||
|
@ -132,19 +132,19 @@ def test_stake_sync(mock_testerchain, application_economics, mock_staking_agent)
|
|||
mock_staking_agent.get_staker_info.return_value = staker_info
|
||||
|
||||
# Prepare sub-stake
|
||||
nu = NU.from_units(2 * token_economics.minimum_allowed_locked - 1)
|
||||
nu = NU.from_units(2 * application_economics.min_authorization - 1)
|
||||
stake = Stake(checksum_address=address,
|
||||
first_locked_period=current_period - 2,
|
||||
final_locked_period=current_period + 1,
|
||||
value=nu,
|
||||
index=0,
|
||||
staking_agent=mock_staking_agent,
|
||||
economics=token_economics)
|
||||
economics=application_economics)
|
||||
assert stake.status() == Stake.Status.EDITABLE
|
||||
|
||||
# Update locked value and sync
|
||||
sub_stake_info = stake.to_stake_info()
|
||||
nunits = 2 * token_economics.minimum_allowed_locked
|
||||
nunits = 2 * application_economics.min_authorization
|
||||
sub_stake_info = sub_stake_info._replace(locked_value=nunits)
|
||||
mock_staking_agent.get_substake_info.return_value = sub_stake_info
|
||||
|
||||
|
@ -186,30 +186,30 @@ def test_stake_validation(mock_testerchain, application_economics, mock_staking_
|
|||
with pytest.raises(Stake.StakingError):
|
||||
Stake.initialize_stake(staking_agent=mock_staking_agent,
|
||||
checksum_address=address,
|
||||
economics=token_economics,
|
||||
amount=token_economics.minimum_allowed_locked - 1,
|
||||
lock_periods=token_economics.minimum_locked_periods)
|
||||
economics=application_economics,
|
||||
amount=application_economics.min_authorization - 1,
|
||||
lock_periods=application_economics.min_operator_seconds)
|
||||
|
||||
with pytest.raises(Stake.StakingError):
|
||||
Stake.initialize_stake(staking_agent=mock_staking_agent,
|
||||
checksum_address=address,
|
||||
economics=token_economics,
|
||||
amount=token_economics.minimum_allowed_locked,
|
||||
lock_periods=token_economics.minimum_locked_periods - 1)
|
||||
economics=application_economics,
|
||||
amount=application_economics.min_authorization,
|
||||
lock_periods=application_economics.min_operator_seconds - 1)
|
||||
|
||||
with pytest.raises(Stake.StakingError):
|
||||
Stake.initialize_stake(staking_agent=mock_staking_agent,
|
||||
checksum_address=address,
|
||||
economics=token_economics,
|
||||
amount=token_economics.maximum_allowed_locked + 1,
|
||||
lock_periods=token_economics.minimum_locked_periods)
|
||||
economics=application_economics,
|
||||
amount=application_economics.maximum_allowed_locked + 1,
|
||||
lock_periods=application_economics.min_operator_seconds)
|
||||
|
||||
mock_staking_agent.get_locked_tokens.return_value = 0
|
||||
Stake.initialize_stake(staking_agent=mock_staking_agent,
|
||||
checksum_address=address,
|
||||
economics=token_economics,
|
||||
amount=token_economics.maximum_allowed_locked,
|
||||
lock_periods=token_economics.minimum_locked_periods)
|
||||
economics=application_economics,
|
||||
amount=application_economics.maximum_allowed_locked,
|
||||
lock_periods=application_economics.min_operator_seconds)
|
||||
|
||||
# Validate divide method
|
||||
current_period = 10
|
||||
|
@ -222,28 +222,28 @@ def test_stake_validation(mock_testerchain, application_economics, mock_staking_
|
|||
value=value,
|
||||
index=index,
|
||||
staking_agent=mock_staking_agent,
|
||||
economics=token_economics)
|
||||
economics=application_economics)
|
||||
|
||||
nu = NU.from_units(2 * token_economics.minimum_allowed_locked - 1)
|
||||
nu = NU.from_units(2 * application_economics.min_authorization - 1)
|
||||
stake = make_sub_stake(first_locked_period=current_period - 2,
|
||||
final_locked_period=current_period + 1,
|
||||
value=nu)
|
||||
|
||||
with pytest.raises(Stake.StakingError):
|
||||
validate_divide(stake=stake, target_value=token_economics.minimum_allowed_locked, additional_periods=1)
|
||||
validate_divide(stake=stake, target_value=application_economics.min_authorization, additional_periods=1)
|
||||
|
||||
stake = make_sub_stake(first_locked_period=current_period - 2,
|
||||
final_locked_period=current_period,
|
||||
value=nu + 1)
|
||||
with pytest.raises(Stake.StakingError):
|
||||
validate_divide(stake=stake, target_value=token_economics.minimum_allowed_locked, additional_periods=1)
|
||||
validate_divide(stake=stake, target_value=application_economics.min_authorization, additional_periods=1)
|
||||
|
||||
stake = make_sub_stake(first_locked_period=current_period - 2,
|
||||
final_locked_period=current_period + 1,
|
||||
value=nu + 1)
|
||||
with pytest.raises(Stake.StakingError):
|
||||
validate_divide(stake=stake, target_value=token_economics.minimum_allowed_locked - 1, additional_periods=1)
|
||||
validate_divide(stake=stake, target_value=token_economics.minimum_allowed_locked, additional_periods=1)
|
||||
validate_divide(stake=stake, target_value=application_economics.min_authorization - 1, additional_periods=1)
|
||||
validate_divide(stake=stake, target_value=application_economics.min_authorization, additional_periods=1)
|
||||
|
||||
# Validate prolong method
|
||||
stake = make_sub_stake(first_locked_period=current_period - 2,
|
||||
|
@ -258,8 +258,8 @@ def test_stake_validation(mock_testerchain, application_economics, mock_staking_
|
|||
with pytest.raises(Stake.StakingError):
|
||||
validate_prolong(stake=stake, additional_periods=1)
|
||||
with pytest.raises(Stake.StakingError):
|
||||
validate_prolong(stake=stake, additional_periods=token_economics.minimum_locked_periods - 3)
|
||||
validate_prolong(stake=stake, additional_periods=token_economics.minimum_locked_periods - 2)
|
||||
validate_prolong(stake=stake, additional_periods=application_economics.min_operator_seconds - 3)
|
||||
validate_prolong(stake=stake, additional_periods=application_economics.min_operator_seconds - 2)
|
||||
|
||||
# Validate increase method
|
||||
stake = make_sub_stake(first_locked_period=current_period - 2,
|
||||
|
@ -273,8 +273,8 @@ def test_stake_validation(mock_testerchain, application_economics, mock_staking_
|
|||
value=nu)
|
||||
stake.staking_agent.get_locked_tokens.return_value = nu
|
||||
with pytest.raises(Stake.StakingError):
|
||||
validate_increase(stake=stake, amount=NU.from_units(token_economics.maximum_allowed_locked - int(nu) + 1))
|
||||
validate_increase(stake=stake, amount=NU.from_units(token_economics.maximum_allowed_locked - int(nu)))
|
||||
validate_increase(stake=stake, amount=NU.from_units(application_economics.maximum_allowed_locked - int(nu) + 1))
|
||||
validate_increase(stake=stake, amount=NU.from_units(application_economics.maximum_allowed_locked - int(nu)))
|
||||
|
||||
# Validate merge method
|
||||
stake_1 = make_sub_stake(first_locked_period=current_period - 1,
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
import click
|
||||
import pytest
|
||||
|
||||
from nucypher.blockchain.economics import StandardTokenEconomics
|
||||
from nucypher.blockchain.economics import Economics
|
||||
from nucypher.blockchain.eth.clients import EthereumTesterClient, PUBLIC_CHAINS
|
||||
from nucypher.blockchain.eth.token import NU
|
||||
from nucypher.cli.actions.confirm import (confirm_deployment, confirm_enable_restaking,
|
||||
|
@ -167,17 +167,18 @@ def test_confirm_staged_stake_cli_action(test_emitter, mock_stdin, capsys):
|
|||
assert mock_stdin.empty()
|
||||
|
||||
|
||||
STANDARD_ECONOMICS = StandardTokenEconomics()
|
||||
MIN_ALLOWED_LOCKED = STANDARD_ECONOMICS.minimum_allowed_locked
|
||||
STANDARD_ECONOMICS = Economics()
|
||||
MIN_ALLOWED_LOCKED = STANDARD_ECONOMICS.min_authorization
|
||||
|
||||
|
||||
@pytest.mark.skip('remove me')
|
||||
@pytest.mark.parametrize('value,duration,must_confirm_value,must_confirm_duration', (
|
||||
(NU.from_tokens(1), 1, False, False),
|
||||
(NU.from_tokens(1), STANDARD_ECONOMICS.minimum_locked_periods + 1, False, False),
|
||||
(NU.from_tokens(15), STANDARD_ECONOMICS.minimum_locked_periods + 1, False, False),
|
||||
(((NU.from_units(MIN_ALLOWED_LOCKED) * 10) + 1), STANDARD_ECONOMICS.minimum_locked_periods + 1, True, False),
|
||||
(NU.from_units(MIN_ALLOWED_LOCKED) * 10, STANDARD_ECONOMICS.maximum_rewarded_periods + 1, False, True),
|
||||
(((NU.from_units(MIN_ALLOWED_LOCKED) * 10) + 1), STANDARD_ECONOMICS.maximum_rewarded_periods + 1, True, True),
|
||||
(NU.from_tokens(1), STANDARD_ECONOMICS.min_operator_seconds + 1, False, False),
|
||||
(NU.from_tokens(15), STANDARD_ECONOMICS.min_operator_seconds + 1, False, False),
|
||||
(((NU.from_units(MIN_ALLOWED_LOCKED) * 10) + 1), STANDARD_ECONOMICS.min_operator_seconds + 1, True, False),
|
||||
# (NU.from_units(MIN_ALLOWED_LOCKED) * 10, STANDARD_ECONOMICS.maximum_rewarded_periods + 1, False, True),
|
||||
# (((NU.from_units(MIN_ALLOWED_LOCKED) * 10) + 1), STANDARD_ECONOMICS.maximum_rewarded_periods + 1, True, True),
|
||||
))
|
||||
def test_confirm_large_stake_cli_action(test_emitter,
|
||||
mock_stdin,
|
||||
|
|
|
@ -46,53 +46,53 @@ def empty_sub_stakes(_current_period, _token_economics) -> List[SubStakeInfo]:
|
|||
def inactive_sub_stakes(current_period, token_economics) -> List[SubStakeInfo]:
|
||||
stakes = [SubStakeInfo(first_period=1,
|
||||
last_period=current_period - 2,
|
||||
locked_value=token_economics.minimum_allowed_locked),
|
||||
locked_value=token_economics.min_authorization),
|
||||
SubStakeInfo(first_period=current_period - 4,
|
||||
last_period=current_period - 3,
|
||||
locked_value=2 * token_economics.minimum_allowed_locked + 1)]
|
||||
locked_value=2 * token_economics.min_authorization + 1)]
|
||||
return stakes
|
||||
|
||||
|
||||
def unlocked_sub_stakes(current_period, token_economics) -> List[SubStakeInfo]:
|
||||
stakes = [SubStakeInfo(first_period=1,
|
||||
last_period=current_period - 1,
|
||||
locked_value=token_economics.minimum_allowed_locked),
|
||||
locked_value=token_economics.min_authorization),
|
||||
SubStakeInfo(first_period=current_period - 3,
|
||||
last_period=current_period - 1,
|
||||
locked_value=2 * token_economics.minimum_allowed_locked + 1)]
|
||||
locked_value=2 * token_economics.min_authorization + 1)]
|
||||
return stakes
|
||||
|
||||
|
||||
def not_editable_sub_stakes(current_period, token_economics) -> List[SubStakeInfo]:
|
||||
stakes = [SubStakeInfo(first_period=1,
|
||||
last_period=current_period,
|
||||
locked_value=token_economics.minimum_allowed_locked),
|
||||
locked_value=token_economics.min_authorization),
|
||||
SubStakeInfo(first_period=current_period - 3,
|
||||
last_period=current_period,
|
||||
locked_value=2 * token_economics.minimum_allowed_locked + 1)]
|
||||
locked_value=2 * token_economics.min_authorization + 1)]
|
||||
return stakes
|
||||
|
||||
|
||||
def non_divisible_sub_stakes(current_period, token_economics) -> List[SubStakeInfo]:
|
||||
stakes = [SubStakeInfo(first_period=1,
|
||||
last_period=current_period + 1,
|
||||
locked_value=token_economics.minimum_allowed_locked),
|
||||
locked_value=token_economics.min_authorization),
|
||||
SubStakeInfo(first_period=current_period - 3,
|
||||
last_period=current_period + 2,
|
||||
locked_value=2 * token_economics.minimum_allowed_locked - 1),
|
||||
locked_value=2 * token_economics.min_authorization - 1),
|
||||
SubStakeInfo(first_period=current_period - 1,
|
||||
last_period=current_period + 2,
|
||||
locked_value=token_economics.minimum_allowed_locked + 1)]
|
||||
locked_value=token_economics.min_authorization + 1)]
|
||||
return stakes
|
||||
|
||||
|
||||
def divisible_sub_stakes(current_period, token_economics) -> List[SubStakeInfo]:
|
||||
stakes = [SubStakeInfo(first_period=1,
|
||||
last_period=current_period + 1,
|
||||
locked_value=2 * token_economics.minimum_allowed_locked),
|
||||
locked_value=2 * token_economics.min_authorization),
|
||||
SubStakeInfo(first_period=current_period - 3,
|
||||
last_period=current_period + 2,
|
||||
locked_value=2 * token_economics.minimum_allowed_locked + 1)]
|
||||
locked_value=2 * token_economics.min_authorization + 1)]
|
||||
return stakes
|
||||
|
||||
|
||||
|
@ -147,9 +147,9 @@ def test_handle_selection_with_with_no_editable_stakes(test_emitter,
|
|||
mock_stdin, # used to assert user hasn't been prompted
|
||||
capsys,
|
||||
current_period,
|
||||
token_economics,
|
||||
application_economics,
|
||||
sub_stakes_functions):
|
||||
mock_stakes = make_sub_stakes(current_period, token_economics, sub_stakes_functions)
|
||||
mock_stakes = make_sub_stakes(current_period, application_economics, sub_stakes_functions)
|
||||
|
||||
mock_staking_agent.get_all_stakes.return_value = mock_stakes
|
||||
staker = mock_testerchain.unassigned_accounts[0]
|
||||
|
@ -185,9 +185,9 @@ def test_select_editable_stake(test_emitter,
|
|||
mock_stdin, # used to assert user hasn't been prompted
|
||||
capsys,
|
||||
current_period,
|
||||
token_economics,
|
||||
application_economics,
|
||||
sub_stakes_functions):
|
||||
mock_stakes = make_sub_stakes(current_period, token_economics, sub_stakes_functions)
|
||||
mock_stakes = make_sub_stakes(current_period, application_economics, sub_stakes_functions)
|
||||
|
||||
mock_staking_agent.get_all_stakes.return_value = mock_stakes
|
||||
staker = mock_testerchain.unassigned_accounts[0]
|
||||
|
@ -195,10 +195,10 @@ def test_select_editable_stake(test_emitter,
|
|||
|
||||
selection = len(mock_stakes) - 1
|
||||
expected_stake = Stake.from_stake_info(stake_info=mock_stakes[selection],
|
||||
staking_agent=mock_staking_agent, # stakinator
|
||||
staking_agent=mock_staking_agent, # stakinator
|
||||
index=selection,
|
||||
checksum_address=stakeholder.checksum_address,
|
||||
economics=token_economics)
|
||||
economics=application_economics)
|
||||
|
||||
# User's selection
|
||||
mock_stdin.line(str(selection))
|
||||
|
@ -224,10 +224,10 @@ def test_handle_selection_with_no_divisible_stakes(test_emitter,
|
|||
mock_stdin, # used to assert user hasn't been prompted
|
||||
capsys,
|
||||
current_period,
|
||||
token_economics):
|
||||
application_economics):
|
||||
|
||||
# Setup
|
||||
mock_stakes = make_sub_stakes(current_period, token_economics, [non_divisible_sub_stakes])
|
||||
mock_stakes = make_sub_stakes(current_period, application_economics, [non_divisible_sub_stakes])
|
||||
|
||||
mock_staking_agent.get_all_stakes.return_value = mock_stakes
|
||||
staker = mock_testerchain.unassigned_accounts[0]
|
||||
|
@ -262,10 +262,10 @@ def test_select_divisible_stake(test_emitter,
|
|||
mock_stdin, # used to assert user hasn't been prompted
|
||||
capsys,
|
||||
current_period,
|
||||
token_economics,
|
||||
application_economics,
|
||||
sub_stakes_functions):
|
||||
# Setup
|
||||
mock_stakes = make_sub_stakes(current_period, token_economics, sub_stakes_functions)
|
||||
mock_stakes = make_sub_stakes(current_period, application_economics, sub_stakes_functions)
|
||||
|
||||
mock_staking_agent.get_all_stakes.return_value = mock_stakes
|
||||
staker = mock_testerchain.unassigned_accounts[0]
|
||||
|
@ -273,10 +273,10 @@ def test_select_divisible_stake(test_emitter,
|
|||
|
||||
selection = len(mock_stakes) - 1
|
||||
expected_stake = Stake.from_stake_info(stake_info=mock_stakes[selection],
|
||||
staking_agent=mock_staking_agent, # stakinator
|
||||
staking_agent=mock_staking_agent, # stakinator
|
||||
index=selection,
|
||||
checksum_address=stakeholder.checksum_address,
|
||||
economics=token_economics)
|
||||
economics=application_economics)
|
||||
|
||||
# SUCCESS: Display all divisible-only stakes and make a selection
|
||||
mock_stdin.line(str(selection))
|
||||
|
@ -309,10 +309,10 @@ def test_select_using_filter_function(test_emitter,
|
|||
mock_stdin, # used to assert user hasn't been prompted
|
||||
capsys,
|
||||
current_period,
|
||||
token_economics,
|
||||
application_economics,
|
||||
sub_stakes_functions):
|
||||
# Setup
|
||||
mock_stakes = make_sub_stakes(current_period, token_economics, sub_stakes_functions)
|
||||
mock_stakes = make_sub_stakes(current_period, application_economics, sub_stakes_functions)
|
||||
|
||||
mock_staking_agent.get_all_stakes.return_value = mock_stakes
|
||||
staker = mock_testerchain.unassigned_accounts[0]
|
||||
|
@ -320,10 +320,10 @@ def test_select_using_filter_function(test_emitter,
|
|||
|
||||
selection = len(mock_stakes) - 1
|
||||
expected_stake = Stake.from_stake_info(stake_info=mock_stakes[selection],
|
||||
staking_agent=mock_staking_agent, # stakinator
|
||||
staking_agent=mock_staking_agent, # stakinator
|
||||
index=selection,
|
||||
checksum_address=stakeholder.checksum_address,
|
||||
economics=token_economics)
|
||||
economics=application_economics)
|
||||
|
||||
# SUCCESS: Display all editable-only stakes with specified final period
|
||||
mock_stdin.line(str(selection))
|
||||
|
@ -357,10 +357,10 @@ def test_no_stakes_with_filter_function(test_emitter,
|
|||
mock_stdin, # used to assert user hasn't been prompted
|
||||
capsys,
|
||||
current_period,
|
||||
token_economics,
|
||||
application_economics,
|
||||
sub_stakes_functions):
|
||||
# Setup
|
||||
mock_stakes = make_sub_stakes(current_period, token_economics, sub_stakes_functions)
|
||||
mock_stakes = make_sub_stakes(current_period, application_economics, sub_stakes_functions)
|
||||
|
||||
mock_staking_agent.get_all_stakes.return_value = mock_stakes
|
||||
staker = mock_testerchain.unassigned_accounts[0]
|
||||
|
|
|
@ -109,10 +109,10 @@ def surrogate_transacting_power(mock_testerchain, surrogate_stakers):
|
|||
|
||||
|
||||
@pytest.fixture()
|
||||
def surrogate_stakes(mock_staking_agent, token_economics, surrogate_stakers):
|
||||
value = 2 * token_economics.minimum_allowed_locked + 1
|
||||
def surrogate_stakes(mock_staking_agent, application_economics, surrogate_stakers):
|
||||
value = 2 * application_economics.min_authorization + 1
|
||||
current_period = 10
|
||||
duration = token_economics.minimum_locked_periods + 1
|
||||
duration = application_economics.min_operator_seconds + 1
|
||||
final_period = current_period + duration
|
||||
stakes_1 = [SubStakeInfo(current_period - 1, final_period - 1, value),
|
||||
SubStakeInfo(current_period - 1, final_period, value),
|
||||
|
@ -479,7 +479,7 @@ def test_prolong_interactive(click_runner,
|
|||
surrogate_stakers,
|
||||
surrogate_stakes,
|
||||
mock_staking_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
mock_refresh_stakes = mocker.spy(Staker, 'refresh_stakes')
|
||||
|
@ -523,7 +523,7 @@ def test_prolong_non_interactive(click_runner,
|
|||
surrogate_stakers,
|
||||
surrogate_stakes,
|
||||
mock_staking_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
mock_refresh_stakes = mocker.spy(Staker, 'refresh_stakes')
|
||||
|
@ -567,7 +567,7 @@ def test_divide_interactive(click_runner,
|
|||
surrogate_stakers,
|
||||
surrogate_stakes,
|
||||
mock_staking_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
mock_refresh_stakes = mocker.spy(Staker, 'refresh_stakes')
|
||||
|
@ -575,7 +575,7 @@ def test_divide_interactive(click_runner,
|
|||
selected_index = 0
|
||||
sub_stake_index = 1
|
||||
lock_periods = 10
|
||||
min_allowed_locked = token_economics.minimum_allowed_locked
|
||||
min_allowed_locked = application_economics.min_authorization
|
||||
target_value = min_allowed_locked + 1 # Let's add some spare change to force dealing with decimal NU
|
||||
|
||||
mock_staking_agent.get_worker_from_staker.return_value = NULL_ADDRESS
|
||||
|
@ -617,14 +617,14 @@ def test_divide_non_interactive(click_runner,
|
|||
surrogate_stakers,
|
||||
surrogate_stakes,
|
||||
mock_staking_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
mock_refresh_stakes = mocker.spy(Staker, 'refresh_stakes')
|
||||
|
||||
sub_stake_index = 1
|
||||
lock_periods = 10
|
||||
min_allowed_locked = token_economics.minimum_allowed_locked
|
||||
min_allowed_locked = application_economics.min_authorization
|
||||
target_value = min_allowed_locked + 1 # Let's add some spare change to force dealing with decimal NU
|
||||
|
||||
mock_staking_agent.get_worker_from_staker.return_value = surrogate_stakers[0]
|
||||
|
@ -667,14 +667,14 @@ def test_increase_interactive(click_runner,
|
|||
surrogate_stakes,
|
||||
mock_token_agent,
|
||||
mock_staking_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
mock_refresh_stakes = mocker.spy(Staker, 'refresh_stakes')
|
||||
|
||||
selected_index = 0
|
||||
sub_stake_index = 1
|
||||
additional_value = NU.from_units(token_economics.minimum_allowed_locked // 10 + 12345)
|
||||
additional_value = NU.from_units(application_economics.min_authorization // 10 + 12345)
|
||||
|
||||
mock_token_agent.get_balance.return_value = 0
|
||||
|
||||
|
@ -695,8 +695,8 @@ def test_increase_interactive(click_runner,
|
|||
assert MAXIMUM_STAKE_REACHED not in result.output
|
||||
assert SUCCESSFUL_STAKE_INCREASE not in result.output
|
||||
|
||||
mock_staking_agent.get_locked_tokens.return_value = token_economics.maximum_allowed_locked
|
||||
balance = token_economics.minimum_allowed_locked * 5
|
||||
mock_staking_agent.get_locked_tokens.return_value = application_economics.maximum_allowed_locked
|
||||
balance = application_economics.min_authorization * 5
|
||||
mock_token_agent.get_balance.return_value = balance
|
||||
|
||||
result = click_runner.invoke(stake, command, input=user_input, catch_exceptions=False)
|
||||
|
@ -705,7 +705,7 @@ def test_increase_interactive(click_runner,
|
|||
assert MAXIMUM_STAKE_REACHED in result.output
|
||||
assert SUCCESSFUL_STAKE_INCREASE not in result.output
|
||||
|
||||
mock_staking_agent.get_locked_tokens.return_value = token_economics.maximum_allowed_locked // 2
|
||||
mock_staking_agent.get_locked_tokens.return_value = application_economics.maximum_allowed_locked // 2
|
||||
current_allowance = 1
|
||||
mock_token_agent.get_allowance.return_value = current_allowance
|
||||
|
||||
|
@ -744,17 +744,17 @@ def test_increase_non_interactive(click_runner,
|
|||
surrogate_stakes,
|
||||
mock_token_agent,
|
||||
mock_staking_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
mock_refresh_stakes = mocker.spy(Staker, 'refresh_stakes')
|
||||
|
||||
sub_stake_index = 1
|
||||
additional_value = NU.from_units(token_economics.minimum_allowed_locked // 10 + 12345)
|
||||
additional_value = NU.from_units(application_economics.min_authorization // 10 + 12345)
|
||||
|
||||
locked_tokens = token_economics.minimum_allowed_locked * 5
|
||||
locked_tokens = application_economics.min_authorization * 5
|
||||
mock_staking_agent.get_locked_tokens.return_value = locked_tokens
|
||||
mock_token_agent.get_balance.return_value = 2 * token_economics.maximum_allowed_locked
|
||||
mock_token_agent.get_balance.return_value = 2 * application_economics.maximum_allowed_locked
|
||||
current_allowance = 1
|
||||
mock_token_agent.get_allowance.return_value = current_allowance
|
||||
|
||||
|
@ -770,7 +770,7 @@ def test_increase_non_interactive(click_runner,
|
|||
result = click_runner.invoke(stake, command, input=user_input, catch_exceptions=False)
|
||||
assert result.exit_code == 0
|
||||
|
||||
upper_limit = NU.from_units(token_economics.maximum_allowed_locked - locked_tokens)
|
||||
upper_limit = NU.from_units(application_economics.maximum_allowed_locked - locked_tokens)
|
||||
assert PROMPT_STAKE_INCREASE_VALUE.format(upper_limit=upper_limit) not in result.output
|
||||
assert CONFIRM_INCREASING_STAKE_DISCLAIMER not in result.output
|
||||
assert CONFIRM_INCREASING_STAKE.format(stake_index=sub_stake_index, value=additional_value) not in result.output
|
||||
|
@ -801,14 +801,14 @@ def test_increase_lock_interactive(click_runner,
|
|||
surrogate_stakers,
|
||||
surrogate_stakes,
|
||||
mock_staking_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
mock_refresh_stakes = mocker.spy(Staker, 'refresh_stakes')
|
||||
|
||||
selected_index = 0
|
||||
sub_stake_index = len(surrogate_stakes) - 1
|
||||
additional_value = NU.from_units(token_economics.minimum_allowed_locked // 10 + 12345)
|
||||
additional_value = NU.from_units(application_economics.min_authorization // 10 + 12345)
|
||||
|
||||
mock_staking_agent.calculate_staking_reward.return_value = 0
|
||||
|
||||
|
@ -831,8 +831,8 @@ def test_increase_lock_interactive(click_runner,
|
|||
assert MAXIMUM_STAKE_REACHED not in result.output
|
||||
assert SUCCESSFUL_STAKE_INCREASE not in result.output
|
||||
|
||||
mock_staking_agent.get_locked_tokens.return_value = token_economics.maximum_allowed_locked
|
||||
unlocked_tokens = token_economics.maximum_allowed_locked
|
||||
mock_staking_agent.get_locked_tokens.return_value = application_economics.maximum_allowed_locked
|
||||
unlocked_tokens = application_economics.maximum_allowed_locked
|
||||
mock_staking_agent.calculate_staking_reward.return_value = unlocked_tokens
|
||||
|
||||
result = click_runner.invoke(stake, command, input=user_input, catch_exceptions=False)
|
||||
|
@ -841,13 +841,13 @@ def test_increase_lock_interactive(click_runner,
|
|||
assert MAXIMUM_STAKE_REACHED in result.output
|
||||
assert SUCCESSFUL_STAKE_INCREASE not in result.output
|
||||
|
||||
locked_tokens = token_economics.maximum_allowed_locked // 3
|
||||
locked_tokens = application_economics.maximum_allowed_locked // 3
|
||||
mock_staking_agent.get_locked_tokens.return_value = locked_tokens
|
||||
|
||||
result = click_runner.invoke(stake, command, input=user_input, catch_exceptions=False)
|
||||
assert result.exit_code == 0
|
||||
|
||||
upper_limit = NU.from_units(token_economics.maximum_allowed_locked - locked_tokens)
|
||||
upper_limit = NU.from_units(application_economics.maximum_allowed_locked - locked_tokens)
|
||||
assert PROMPT_STAKE_INCREASE_VALUE.format(upper_limit=upper_limit) in result.output
|
||||
assert CONFIRM_INCREASING_STAKE_DISCLAIMER in result.output
|
||||
assert CONFIRM_INCREASING_STAKE.format(stake_index=sub_stake_index, value=additional_value) in result.output
|
||||
|
@ -872,17 +872,17 @@ def test_increase_lock_non_interactive(click_runner,
|
|||
surrogate_stakers,
|
||||
surrogate_stakes,
|
||||
mock_staking_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
mock_refresh_stakes = mocker.spy(Staker, 'refresh_stakes')
|
||||
|
||||
selected_index = 0
|
||||
sub_stake_index = len(surrogate_stakes) - 1
|
||||
additional_value = NU.from_units(token_economics.minimum_allowed_locked // 10 + 12345)
|
||||
additional_value = NU.from_units(application_economics.min_authorization // 10 + 12345)
|
||||
|
||||
mock_staking_agent.get_locked_tokens.return_value = token_economics.minimum_allowed_locked * 2
|
||||
unlocked_tokens = token_economics.minimum_allowed_locked * 5
|
||||
mock_staking_agent.get_locked_tokens.return_value = application_economics.min_authorization * 2
|
||||
unlocked_tokens = application_economics.min_authorization * 5
|
||||
mock_staking_agent.calculate_staking_reward.return_value = unlocked_tokens
|
||||
|
||||
command = ('increase',
|
||||
|
@ -924,14 +924,14 @@ def test_create_interactive(click_runner,
|
|||
surrogate_stakes,
|
||||
mock_token_agent,
|
||||
mock_staking_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
mock_refresh_stakes = mocker.spy(Staker, 'refresh_stakes')
|
||||
|
||||
selected_index = 0
|
||||
lock_periods = 366
|
||||
value = NU.from_units(token_economics.minimum_allowed_locked * 11 + 12345)
|
||||
value = NU.from_units(application_economics.min_authorization * 11 + 12345)
|
||||
|
||||
command = ('create',
|
||||
'--provider', MOCK_PROVIDER_URI,
|
||||
|
@ -948,7 +948,7 @@ def test_create_interactive(click_runner,
|
|||
INSECURE_DEVELOPMENT_PASSWORD))
|
||||
|
||||
# insufficient existing balance
|
||||
mock_token_agent.get_balance.return_value = token_economics.minimum_allowed_locked - 1
|
||||
mock_token_agent.get_balance.return_value = application_economics.min_authorization - 1
|
||||
result = click_runner.invoke(stake, command, input=user_input, catch_exceptions=False)
|
||||
assert result.exit_code == 1
|
||||
assert INSUFFICIENT_BALANCE_TO_CREATE in result.output
|
||||
|
@ -956,8 +956,8 @@ def test_create_interactive(click_runner,
|
|||
assert SUCCESSFUL_STAKE_INCREASE not in result.output
|
||||
|
||||
# already at max stake
|
||||
mock_staking_agent.get_locked_tokens.return_value = token_economics.maximum_allowed_locked
|
||||
balance = token_economics.minimum_allowed_locked * 12
|
||||
mock_staking_agent.get_locked_tokens.return_value = application_economics.maximum_allowed_locked
|
||||
balance = application_economics.min_authorization * 12
|
||||
mock_token_agent.get_balance.return_value = balance
|
||||
|
||||
result = click_runner.invoke(stake, command, input=user_input, catch_exceptions=False)
|
||||
|
@ -967,9 +967,9 @@ def test_create_interactive(click_runner,
|
|||
assert SUCCESSFUL_STAKE_INCREASE not in result.output
|
||||
|
||||
# successfully stake minimum allowed which equals available balance
|
||||
mock_staking_agent.get_locked_tokens.return_value = token_economics.minimum_allowed_locked
|
||||
mock_token_agent.get_balance.return_value = token_economics.minimum_allowed_locked
|
||||
min_stake_value = NU.from_units(token_economics.minimum_allowed_locked)
|
||||
mock_staking_agent.get_locked_tokens.return_value = application_economics.min_authorization
|
||||
mock_token_agent.get_balance.return_value = application_economics.min_authorization
|
||||
min_stake_value = NU.from_units(application_economics.min_authorization)
|
||||
min_amount_user_input = '\n'.join((str(selected_index),
|
||||
YES,
|
||||
str(min_stake_value.to_tokens()),
|
||||
|
@ -990,14 +990,14 @@ def test_create_interactive(click_runner,
|
|||
assert CONFIRM_BROADCAST_CREATE_STAKE in result.output
|
||||
|
||||
# successfully stake large stake
|
||||
mock_staking_agent.get_locked_tokens.return_value = token_economics.maximum_allowed_locked // 2
|
||||
mock_staking_agent.get_locked_tokens.return_value = application_economics.maximum_allowed_locked // 2
|
||||
mock_token_agent.get_balance.return_value = balance
|
||||
result = click_runner.invoke(stake, command, input=user_input, catch_exceptions=False)
|
||||
assert result.exit_code == 0
|
||||
|
||||
upper_limit = NU.from_units(balance)
|
||||
lower_limit = NU.from_units(token_economics.minimum_allowed_locked)
|
||||
min_locktime = token_economics.minimum_locked_periods
|
||||
lower_limit = NU.from_units(application_economics.min_authorization)
|
||||
min_locktime = application_economics.min_operator_seconds
|
||||
max_locktime = MAX_UINT16 - 10 # MAX_UINT16 - current period
|
||||
|
||||
assert CONFIRM_STAKE_USE_UNLOCKED not in result.output # default is to use staker address
|
||||
|
@ -1009,7 +1009,7 @@ def test_create_interactive(click_runner,
|
|||
lock_periods=lock_periods) in result.output
|
||||
assert CONFIRM_BROADCAST_CREATE_STAKE in result.output
|
||||
assert CONFIRM_LARGE_STAKE_VALUE.format(value=value) in result.output
|
||||
lock_days = (lock_periods * token_economics.hours_per_period) // 24
|
||||
lock_days = (lock_periods * application_economics.hours_per_period) // 24
|
||||
assert CONFIRM_LARGE_STAKE_DURATION.format(lock_periods=lock_periods, lock_days=lock_days) in result.output
|
||||
|
||||
mock_staking_agent.get_all_stakes.assert_called()
|
||||
|
@ -1031,19 +1031,19 @@ def test_create_non_interactive(click_runner,
|
|||
surrogate_stakes,
|
||||
mock_token_agent,
|
||||
mock_staking_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
mock_refresh_stakes = mocker.spy(Staker, 'refresh_stakes')
|
||||
|
||||
selected_index = 0
|
||||
|
||||
lock_periods = token_economics.minimum_locked_periods
|
||||
value = NU.from_units(token_economics.minimum_allowed_locked * 2 + 12345)
|
||||
lock_periods = application_economics.min_operator_seconds
|
||||
value = NU.from_units(application_economics.min_authorization * 2 + 12345)
|
||||
|
||||
locked_tokens = token_economics.minimum_allowed_locked * 5
|
||||
locked_tokens = application_economics.min_authorization * 5
|
||||
mock_staking_agent.get_locked_tokens.return_value = locked_tokens
|
||||
mock_token_agent.get_balance.return_value = token_economics.maximum_allowed_locked
|
||||
mock_token_agent.get_balance.return_value = application_economics.maximum_allowed_locked
|
||||
|
||||
command = ('create',
|
||||
'--provider', MOCK_PROVIDER_URI,
|
||||
|
@ -1057,9 +1057,9 @@ def test_create_non_interactive(click_runner,
|
|||
result = click_runner.invoke(stake, command, input=user_input, catch_exceptions=False)
|
||||
assert result.exit_code == 0
|
||||
|
||||
upper_limit = NU.from_units(token_economics.maximum_allowed_locked - locked_tokens)
|
||||
lower_limit = NU.from_units(token_economics.minimum_allowed_locked)
|
||||
min_locktime = token_economics.minimum_locked_periods
|
||||
upper_limit = NU.from_units(application_economics.maximum_allowed_locked - locked_tokens)
|
||||
lower_limit = NU.from_units(application_economics.min_authorization)
|
||||
min_locktime = application_economics.min_operator_seconds
|
||||
max_locktime = MAX_UINT16 - 10 # MAX_UINT16 - current period
|
||||
|
||||
assert CONFIRM_STAKE_USE_UNLOCKED not in result.output # default is to use staker address
|
||||
|
@ -1071,7 +1071,7 @@ def test_create_non_interactive(click_runner,
|
|||
lock_periods=lock_periods) not in result.output
|
||||
assert CONFIRM_BROADCAST_CREATE_STAKE in result.output
|
||||
assert CONFIRM_LARGE_STAKE_VALUE.format(value=value) not in result.output
|
||||
lock_days = (lock_periods * token_economics.hours_per_period) // 24
|
||||
lock_days = (lock_periods * application_economics.hours_per_period) // 24
|
||||
assert CONFIRM_LARGE_STAKE_DURATION.format(lock_periods=lock_periods, lock_days=lock_days) not in result.output
|
||||
|
||||
mock_staking_agent.get_all_stakes.assert_called()
|
||||
|
@ -1093,16 +1093,16 @@ def test_create_lock_interactive(click_runner,
|
|||
surrogate_stakers,
|
||||
surrogate_stakes,
|
||||
mock_staking_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
mock_refresh_stakes = mocker.spy(Staker, 'refresh_stakes')
|
||||
|
||||
selected_index = 0
|
||||
lock_periods = 366
|
||||
value = NU.from_units(token_economics.minimum_allowed_locked * 2 + 12345)
|
||||
value = NU.from_units(application_economics.min_authorization * 2 + 12345)
|
||||
|
||||
mock_staking_agent.calculate_staking_reward.return_value = token_economics.minimum_allowed_locked - 1
|
||||
mock_staking_agent.calculate_staking_reward.return_value = application_economics.min_authorization - 1
|
||||
|
||||
command = ('create',
|
||||
'--provider', MOCK_PROVIDER_URI,
|
||||
|
@ -1124,8 +1124,8 @@ def test_create_lock_interactive(click_runner,
|
|||
assert MAXIMUM_STAKE_REACHED not in result.output
|
||||
assert SUCCESSFUL_STAKE_INCREASE not in result.output
|
||||
|
||||
mock_staking_agent.get_locked_tokens.return_value = token_economics.maximum_allowed_locked
|
||||
mock_staking_agent.calculate_staking_reward.return_value = token_economics.maximum_allowed_locked
|
||||
mock_staking_agent.get_locked_tokens.return_value = application_economics.maximum_allowed_locked
|
||||
mock_staking_agent.calculate_staking_reward.return_value = application_economics.maximum_allowed_locked
|
||||
|
||||
result = click_runner.invoke(stake, command, input=user_input, catch_exceptions=False)
|
||||
assert result.exit_code == 1
|
||||
|
@ -1133,15 +1133,15 @@ def test_create_lock_interactive(click_runner,
|
|||
assert MAXIMUM_STAKE_REACHED in result.output
|
||||
assert SUCCESSFUL_STAKE_INCREASE not in result.output
|
||||
|
||||
locked_tokens = token_economics.maximum_allowed_locked // 3
|
||||
locked_tokens = application_economics.maximum_allowed_locked // 3
|
||||
mock_staking_agent.get_locked_tokens.return_value = locked_tokens
|
||||
|
||||
result = click_runner.invoke(stake, command, input=user_input, catch_exceptions=False)
|
||||
assert result.exit_code == 0
|
||||
|
||||
upper_limit = NU.from_units(token_economics.maximum_allowed_locked - locked_tokens)
|
||||
lower_limit = NU.from_units(token_economics.minimum_allowed_locked)
|
||||
min_locktime = token_economics.minimum_locked_periods
|
||||
upper_limit = NU.from_units(application_economics.maximum_allowed_locked - locked_tokens)
|
||||
lower_limit = NU.from_units(application_economics.min_authorization)
|
||||
min_locktime = application_economics.min_operator_seconds
|
||||
max_locktime = MAX_UINT16 - 10 # MAX_UINT16 - current period
|
||||
|
||||
assert CONFIRM_STAKE_USE_UNLOCKED in result.output # value not provided but --from-unlocked specified so prompted
|
||||
|
@ -1153,7 +1153,7 @@ def test_create_lock_interactive(click_runner,
|
|||
lock_periods=lock_periods) in result.output
|
||||
assert CONFIRM_BROADCAST_CREATE_STAKE in result.output
|
||||
assert CONFIRM_LARGE_STAKE_VALUE.format(value=value) not in result.output
|
||||
lock_days = (lock_periods * token_economics.hours_per_period) // 24
|
||||
lock_days = (lock_periods * application_economics.hours_per_period) // 24
|
||||
assert CONFIRM_LARGE_STAKE_DURATION.format(lock_periods=lock_periods, lock_days=lock_days) in result.output
|
||||
|
||||
mock_staking_agent.get_all_stakes.assert_called()
|
||||
|
@ -1172,18 +1172,18 @@ def test_create_lock_non_interactive(click_runner,
|
|||
surrogate_stakers,
|
||||
surrogate_stakes,
|
||||
mock_staking_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
mock_refresh_stakes = mocker.spy(Staker, 'refresh_stakes')
|
||||
|
||||
selected_index = 0
|
||||
|
||||
lock_periods = token_economics.minimum_locked_periods
|
||||
value = NU.from_units(token_economics.minimum_allowed_locked * 11 + 12345)
|
||||
lock_periods = application_economics.min_operator_seconds
|
||||
value = NU.from_units(application_economics.min_authorization * 11 + 12345)
|
||||
|
||||
mock_staking_agent.get_locked_tokens.return_value = token_economics.minimum_allowed_locked * 5
|
||||
unlocked_tokens = token_economics.maximum_allowed_locked // 2
|
||||
mock_staking_agent.get_locked_tokens.return_value = application_economics.min_authorization * 5
|
||||
unlocked_tokens = application_economics.maximum_allowed_locked // 2
|
||||
mock_staking_agent.calculate_staking_reward.return_value = unlocked_tokens
|
||||
|
||||
command = ('create',
|
||||
|
@ -1200,8 +1200,8 @@ def test_create_lock_non_interactive(click_runner,
|
|||
assert result.exit_code == 0
|
||||
|
||||
upper_limit = NU.from_units(unlocked_tokens)
|
||||
lower_limit = NU.from_units(token_economics.minimum_allowed_locked)
|
||||
min_locktime = token_economics.minimum_locked_periods
|
||||
lower_limit = NU.from_units(application_economics.min_authorization)
|
||||
min_locktime = application_economics.min_operator_seconds
|
||||
max_locktime = MAX_UINT16 - 10 # MAX_UINT16 - current period
|
||||
|
||||
assert CONFIRM_STAKE_USE_UNLOCKED not in result.output # value provided so not prompted
|
||||
|
@ -1213,7 +1213,7 @@ def test_create_lock_non_interactive(click_runner,
|
|||
lock_periods=lock_periods) not in result.output
|
||||
assert CONFIRM_BROADCAST_CREATE_STAKE in result.output
|
||||
assert CONFIRM_LARGE_STAKE_VALUE.format(value=value) not in result.output
|
||||
lock_days = (lock_periods * token_economics.hours_per_period) // 24
|
||||
lock_days = (lock_periods * application_economics.hours_per_period) // 24
|
||||
assert CONFIRM_LARGE_STAKE_DURATION.format(lock_periods=lock_periods, lock_days=lock_days) not in result.output
|
||||
|
||||
mock_staking_agent.get_all_stakes.assert_called()
|
||||
|
@ -1232,7 +1232,7 @@ def test_merge_interactive(click_runner,
|
|||
surrogate_stakers,
|
||||
surrogate_stakes,
|
||||
mock_staking_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
mock_refresh_stakes = mocker.spy(Staker, 'refresh_stakes')
|
||||
|
@ -1277,7 +1277,7 @@ def test_merge_partially_interactive(click_runner,
|
|||
surrogate_stakers,
|
||||
surrogate_stakes,
|
||||
mock_staking_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
mock_refresh_stakes = mocker.spy(Staker, 'refresh_stakes')
|
||||
|
@ -1330,7 +1330,7 @@ def test_merge_non_interactive(click_runner,
|
|||
surrogate_stakers,
|
||||
surrogate_stakes,
|
||||
mock_staking_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
mock_refresh_stakes = mocker.spy(Staker, 'refresh_stakes')
|
||||
|
@ -1339,8 +1339,8 @@ def test_merge_non_interactive(click_runner,
|
|||
sub_stake_index_1 = 1
|
||||
sub_stake_index_2 = 2
|
||||
|
||||
mock_staking_agent.get_locked_tokens.return_value = token_economics.minimum_allowed_locked * 2
|
||||
unlocked_tokens = token_economics.minimum_allowed_locked * 5
|
||||
mock_staking_agent.get_locked_tokens.return_value = application_economics.min_authorization * 2
|
||||
unlocked_tokens = application_economics.min_authorization * 5
|
||||
mock_staking_agent.calculate_staking_reward.return_value = unlocked_tokens
|
||||
|
||||
command = ('merge',
|
||||
|
@ -1374,7 +1374,7 @@ def test_merge_non_interactive(click_runner,
|
|||
def test_stake_list_active(click_runner,
|
||||
surrogate_stakers,
|
||||
surrogate_stakes,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mocker,
|
||||
get_random_checksum_address):
|
||||
|
||||
|
@ -1412,7 +1412,7 @@ def test_stake_list_active(click_runner,
|
|||
first_locked_period=sub_stake_info.first_period,
|
||||
final_locked_period=sub_stake_info.last_period,
|
||||
index=index,
|
||||
economics=token_economics)
|
||||
economics=application_economics)
|
||||
|
||||
sub_stake.status = mocker.Mock(return_value=statuses[index])
|
||||
|
||||
|
@ -1439,7 +1439,7 @@ def test_stake_list_active(click_runner,
|
|||
def test_stake_list_all(click_runner,
|
||||
surrogate_stakers,
|
||||
surrogate_stakes,
|
||||
token_economics,
|
||||
application_economics,
|
||||
surrogate_transacting_power,
|
||||
mocker,
|
||||
get_random_checksum_address):
|
||||
|
@ -1478,7 +1478,7 @@ def test_stake_list_all(click_runner,
|
|||
first_locked_period=sub_stake_info.first_period,
|
||||
final_locked_period=sub_stake_info.last_period,
|
||||
index=index,
|
||||
economics=token_economics)
|
||||
economics=application_economics)
|
||||
|
||||
status = statuses[index]
|
||||
sub_stake.status = mocker.Mock(return_value=status)
|
||||
|
@ -1522,10 +1522,10 @@ def test_show_rewards(click_runner, surrogate_stakers, mock_staking_agent):
|
|||
|
||||
@pytest.mark.skip()
|
||||
@pytest.mark.usefixtures("test_registry_source_manager", "patch_stakeholder_configuration")
|
||||
def test_show_rewards_for_period(click_runner, surrogate_stakers, mock_staking_agent, token_economics, mocker):
|
||||
def test_show_rewards_for_period(click_runner, surrogate_stakers, mock_staking_agent, application_economics, mocker):
|
||||
periods = 30
|
||||
periods_per_day = token_economics.hours_per_period // 24
|
||||
seconds_per_period = token_economics.seconds_per_period
|
||||
periods_per_day = application_economics.hours_per_period // 24
|
||||
seconds_per_period = application_economics.seconds_per_period
|
||||
latest_block = 100_000_000
|
||||
latest_period = 15_000
|
||||
|
||||
|
|
|
@ -110,8 +110,8 @@ def test_account_selection(click_runner, mocker, mock_testerchain, mock_worklock
|
|||
|
||||
|
||||
@pytest.fixture()
|
||||
def bidding_command(token_economics, surrogate_bidder):
|
||||
minimum = token_economics.worklock_min_allowed_bid
|
||||
def bidding_command(application_economics, surrogate_bidder):
|
||||
minimum = application_economics.worklock_min_allowed_bid
|
||||
bid_value = random.randint(minimum, minimum*100)
|
||||
command = ('escrow',
|
||||
'--participant-address', surrogate_bidder.checksum_address,
|
||||
|
@ -127,7 +127,7 @@ def bidding_command(token_economics, surrogate_bidder):
|
|||
def test_bid_too_soon(click_runner,
|
||||
mocker,
|
||||
mock_worklock_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
test_registry_source_manager,
|
||||
surrogate_bidder,
|
||||
mock_testerchain,
|
||||
|
@ -156,7 +156,7 @@ def test_bid_too_soon(click_runner,
|
|||
def test_bid_too_late(click_runner,
|
||||
mocker,
|
||||
mock_worklock_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
test_registry_source_manager,
|
||||
surrogate_bidder,
|
||||
mock_testerchain,
|
||||
|
@ -185,7 +185,7 @@ def test_bid_too_late(click_runner,
|
|||
def test_valid_bid(click_runner,
|
||||
mocker,
|
||||
mock_worklock_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
test_registry_source_manager,
|
||||
surrogate_bidder,
|
||||
mock_testerchain,
|
||||
|
@ -195,7 +195,7 @@ def test_valid_bid(click_runner,
|
|||
sometime_later = now + 100
|
||||
mocker.patch.object(BlockchainInterface, 'get_blocktime', return_value=sometime_later)
|
||||
|
||||
minimum = token_economics.worklock_min_allowed_bid
|
||||
minimum = application_economics.worklock_min_allowed_bid
|
||||
bid_value = random.randint(minimum, minimum * 100)
|
||||
bid_value_in_eth = Web3.fromWei(bid_value, 'ether')
|
||||
|
||||
|
@ -283,7 +283,7 @@ def test_enable_claiming(click_runner,
|
|||
mocker,
|
||||
mock_worklock_agent,
|
||||
surrogate_bidder,
|
||||
token_economics,
|
||||
application_economics,
|
||||
mock_testerchain,
|
||||
surrogate_transacting_power):
|
||||
|
||||
|
@ -300,14 +300,14 @@ def test_enable_claiming(click_runner,
|
|||
# Prepare bidders
|
||||
bidders = mock_testerchain.client.accounts[0:10]
|
||||
num_bidders = len(bidders)
|
||||
bonus_lot_value = token_economics.worklock_supply - token_economics.minimum_allowed_locked * num_bidders
|
||||
bonus_lot_value = application_economics.worklock_supply - application_economics.min_authorization * num_bidders
|
||||
|
||||
bids_before = [to_wei(50_000, 'ether')]
|
||||
min_bid_eth_value = to_wei(1, 'ether')
|
||||
max_bid_eth_value = to_wei(10, 'ether')
|
||||
for i in range(num_bidders - 1):
|
||||
bids_before.append(random.randrange(min_bid_eth_value, max_bid_eth_value))
|
||||
bonus_eth_supply_before = sum(bids_before) - token_economics.worklock_min_allowed_bid * num_bidders
|
||||
bonus_eth_supply_before = sum(bids_before) - application_economics.worklock_min_allowed_bid * num_bidders
|
||||
|
||||
bids_after = [min_bid_eth_value] * num_bidders
|
||||
bonus_eth_supply_after = 0
|
||||
|
@ -585,7 +585,7 @@ def test_participant_status(click_runner,
|
|||
def test_interactive_new_bid(click_runner,
|
||||
mocker,
|
||||
mock_worklock_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
test_registry_source_manager,
|
||||
surrogate_bidder,
|
||||
mock_testerchain):
|
||||
|
@ -593,7 +593,7 @@ def test_interactive_new_bid(click_runner,
|
|||
sometime_later = now + 100
|
||||
mocker.patch.object(BlockchainInterface, 'get_blocktime', return_value=sometime_later)
|
||||
|
||||
minimum = token_economics.worklock_min_allowed_bid
|
||||
minimum = application_economics.worklock_min_allowed_bid
|
||||
bid_value = random.randint(minimum, minimum * 100)
|
||||
bid_value_in_eth = Web3.fromWei(bid_value, 'ether')
|
||||
wrong_bid = random.randint(1, minimum - 1)
|
||||
|
@ -638,7 +638,7 @@ def test_interactive_new_bid(click_runner,
|
|||
def test_interactive_increase_bid(click_runner,
|
||||
mocker,
|
||||
mock_worklock_agent,
|
||||
token_economics,
|
||||
application_economics,
|
||||
test_registry_source_manager,
|
||||
surrogate_bidder,
|
||||
mock_testerchain):
|
||||
|
@ -647,7 +647,7 @@ def test_interactive_increase_bid(click_runner,
|
|||
sometime_later = now + 100
|
||||
mocker.patch.object(BlockchainInterface, 'get_blocktime', return_value=sometime_later)
|
||||
|
||||
minimum = token_economics.worklock_min_allowed_bid
|
||||
minimum = application_economics.worklock_min_allowed_bid
|
||||
bid_value = random.randint(1, minimum - 1)
|
||||
bid_value_in_eth = Web3.fromWei(bid_value, 'ether')
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ from tests.constants import (
|
|||
MOCK_PROVIDER_URI,
|
||||
NUMBER_OF_MOCK_KEYSTORE_ACCOUNTS
|
||||
)
|
||||
from tests.fixtures import make_token_economics
|
||||
from tests.mock.agents import MockContractAgency, MockContractAgent
|
||||
from tests.mock.interfaces import MockBlockchain, mock_registry_source_manager
|
||||
from tests.mock.io import MockStdinWrapper
|
||||
|
@ -52,23 +51,23 @@ from tests.utils.ursula import MOCK_URSULA_STARTING_PORT
|
|||
|
||||
|
||||
@pytest.fixture(scope='function', autouse=True)
|
||||
def mock_contract_agency(monkeypatch, module_mocker, token_economics):
|
||||
def mock_contract_agency(monkeypatch, module_mocker, application_economics):
|
||||
monkeypatch.setattr(ContractAgency, 'get_agent', MockContractAgency.get_agent)
|
||||
module_mocker.patch.object(EconomicsFactory, 'get_economics', return_value=token_economics)
|
||||
module_mocker.patch.object(EconomicsFactory, 'get_economics', return_value=application_economics)
|
||||
mock_agency = MockContractAgency()
|
||||
yield mock_agency
|
||||
mock_agency.reset()
|
||||
|
||||
|
||||
@pytest.fixture(scope='function', autouse=True)
|
||||
def mock_token_agent(mock_testerchain, token_economics, mock_contract_agency):
|
||||
def mock_token_agent(mock_testerchain, application_economics, mock_contract_agency):
|
||||
mock_agent = mock_contract_agency.get_agent(NucypherTokenAgent)
|
||||
yield mock_agent
|
||||
mock_agent.reset()
|
||||
|
||||
|
||||
@pytest.fixture(scope='function', autouse=True)
|
||||
def mock_staking_agent(mock_testerchain, token_economics, mock_contract_agency, mocker):
|
||||
def mock_staking_agent(mock_testerchain, application_economics, mock_contract_agency, mocker):
|
||||
mock_agent = mock_contract_agency.get_agent(StakingEscrowAgent)
|
||||
|
||||
# Handle the special case of commit_to_next_period, which returns a txhash due to the fire_and_forget option
|
||||
|
@ -139,11 +138,6 @@ def mock_testerchain(_mock_testerchain) -> MockBlockchain:
|
|||
yield _mock_testerchain
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def token_economics(mock_testerchain):
|
||||
return make_token_economics(blockchain=mock_testerchain)
|
||||
|
||||
|
||||
@pytest.fixture(scope='module', autouse=True)
|
||||
def mock_interface(module_mocker):
|
||||
mock_transaction_sender = module_mocker.patch.object(BlockchainInterface, 'sign_and_broadcast_transaction')
|
||||
|
@ -164,10 +158,10 @@ def test_registry_source_manager(mock_testerchain, test_registry):
|
|||
|
||||
|
||||
@pytest.fixture(scope='module', autouse=True)
|
||||
def mock_contract_agency(module_mocker, token_economics):
|
||||
def mock_contract_agency(module_mocker, application_economics):
|
||||
|
||||
# Patch
|
||||
module_mocker.patch.object(EconomicsFactory, 'get_economics', return_value=token_economics)
|
||||
module_mocker.patch.object(EconomicsFactory, 'get_economics', return_value=application_economics)
|
||||
|
||||
# Monkeypatch # TODO: Use better tooling for this monkeypatch?
|
||||
get_agent = ContractAgency.get_agent
|
||||
|
|
|
@ -37,7 +37,7 @@ from nucypher_core.umbral import SecretKey, Signer
|
|||
from nucypher.blockchain.eth.registry import InMemoryContractRegistry
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.crypto.powers import TransactingPower
|
||||
from nucypher.blockchain.economics import StandardTokenEconomics
|
||||
from nucypher.blockchain.economics import Economics
|
||||
from nucypher.blockchain.eth.agents import (
|
||||
AdjudicatorAgent,
|
||||
NucypherTokenAgent,
|
||||
|
@ -53,8 +53,8 @@ from tests.utils.blockchain import TesterBlockchain
|
|||
|
||||
|
||||
ALGORITHM_SHA256 = 1
|
||||
TOKEN_ECONOMICS = StandardTokenEconomics()
|
||||
MIN_ALLOWED_LOCKED = TOKEN_ECONOMICS.minimum_allowed_locked
|
||||
TOKEN_ECONOMICS = Economics()
|
||||
MIN_ALLOWED_LOCKED = TOKEN_ECONOMICS.min_authorization
|
||||
LOCKED_PERIODS = 30
|
||||
MAX_ALLOWED_LOCKED = TOKEN_ECONOMICS.maximum_allowed_locked
|
||||
MAX_MINTING_PERIODS = TOKEN_ECONOMICS.maximum_rewarded_periods
|
||||
|
@ -160,7 +160,7 @@ def estimate_gas(analyzer: AnalyzeGas = None) -> None:
|
|||
os.environ['GAS_ESTIMATOR_BACKEND_FUNC'] = 'eth.estimators.gas.binary_gas_search_exact'
|
||||
|
||||
# Blockchain
|
||||
economics = StandardTokenEconomics(
|
||||
economics = Economics(
|
||||
base_penalty=MIN_ALLOWED_LOCKED - 1,
|
||||
penalty_history_coefficient=0,
|
||||
percentage_penalty_coefficient=2,
|
||||
|
@ -564,15 +564,15 @@ def estimate_gas(analyzer: AnalyzeGas = None) -> None:
|
|||
*args,
|
||||
**kwargs)
|
||||
|
||||
token_economics = StandardTokenEconomics(genesis_hours_per_period=StandardTokenEconomics._default_hours_per_period,
|
||||
hours_per_period=2 * StandardTokenEconomics._default_hours_per_period)
|
||||
token_economics = Economics(genesis_hours_per_period=Economics._default_hours_per_period,
|
||||
hours_per_period=2 * Economics._default_hours_per_period)
|
||||
|
||||
token, _ = deploy_contract('NuCypherToken', _totalSupplyOfTokens=token_economics.erc20_total_supply)
|
||||
# Deploy Adjudicator mock
|
||||
adjudicator, _ = deploy_contract('AdjudicatorForStakingEscrowMock', token_economics.reward_coefficient)
|
||||
|
||||
# Deploy old StakingEscrow contract
|
||||
deploy_args = token_economics.staking_deployment_parameters
|
||||
deploy_args = token_economics.pre_application_deployment_parameters
|
||||
deploy_args = (deploy_args[0], *deploy_args[2:])
|
||||
escrow_old_library, _ = deploy_contract(
|
||||
'StakingEscrowOld',
|
||||
|
@ -619,8 +619,8 @@ def estimate_gas(analyzer: AnalyzeGas = None) -> None:
|
|||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
sub_stakes_1 = 2
|
||||
duration = token_economics.minimum_locked_periods
|
||||
stake_size = token_economics.minimum_allowed_locked
|
||||
duration = token_economics.min_operator_seconds
|
||||
stake_size = token_economics.min_authorization
|
||||
for staker in (staker1, staker3):
|
||||
for i in range(1, sub_stakes_1 + 1):
|
||||
tx = escrow.functions.deposit(staker, stake_size, duration * i).transact({'from': staker})
|
||||
|
@ -650,7 +650,7 @@ def estimate_gas(analyzer: AnalyzeGas = None) -> None:
|
|||
##########
|
||||
# Deploy new version of contracts
|
||||
##########
|
||||
deploy_args = token_economics.staking_deployment_parameters
|
||||
deploy_args = token_economics.pre_application_deployment_parameters
|
||||
escrow_library, _ = deploy_contract(
|
||||
'StakingEscrow',
|
||||
token.address,
|
||||
|
|
|
@ -18,9 +18,12 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
|||
|
||||
from decimal import Decimal, localcontext
|
||||
|
||||
from nucypher.blockchain.economics import LOG2, StandardTokenEconomics
|
||||
import pytest
|
||||
|
||||
from nucypher.blockchain.economics import Economics
|
||||
|
||||
|
||||
@pytest.mark.skip('remove me')
|
||||
def test_rough_economics():
|
||||
"""
|
||||
Formula for staking in one period:
|
||||
|
@ -37,7 +40,7 @@ def test_rough_economics():
|
|||
where allLockedPeriods == min(T, T1)
|
||||
"""
|
||||
|
||||
e = StandardTokenEconomics(initial_supply=int(1e9),
|
||||
e = Economics(initial_supply=int(1e9),
|
||||
first_phase_supply=1829579800,
|
||||
first_phase_duration=5,
|
||||
decay_half_life=2,
|
||||
|
@ -71,15 +74,8 @@ def test_rough_economics():
|
|||
|
||||
|
||||
def test_economic_parameter_aliases():
|
||||
|
||||
e = StandardTokenEconomics()
|
||||
|
||||
assert int(e.lock_duration_coefficient_1) == 52
|
||||
assert int(e.lock_duration_coefficient_2) == 2 * 52
|
||||
assert int(e.issuance_decay_coefficient) == 150
|
||||
assert e.maximum_rewarded_periods == 52
|
||||
|
||||
deployment_params = e.staking_deployment_parameters
|
||||
e = Economics()
|
||||
deployment_params = e.pre_application_deployment_parameters
|
||||
assert isinstance(deployment_params, tuple)
|
||||
for parameter in deployment_params:
|
||||
assert isinstance(parameter, int)
|
||||
|
|
|
@ -26,7 +26,7 @@ from web3 import Web3
|
|||
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.blockchain.economics import BaseEconomics, StandardTokenEconomics
|
||||
from nucypher.blockchain.economics import Economics, Economics
|
||||
from nucypher.blockchain.eth.actors import ContractAdministrator
|
||||
from nucypher.blockchain.eth.deployers import StakingEscrowDeployer
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainDeployerInterface, BlockchainInterfaceFactory
|
||||
|
@ -105,7 +105,7 @@ class TesterBlockchain(BlockchainDeployerInterface):
|
|||
__ACCOUNT_CACHE = list()
|
||||
|
||||
# Defaults
|
||||
DEFAULT_ECONOMICS = StandardTokenEconomics()
|
||||
DEFAULT_ECONOMICS = Economics()
|
||||
|
||||
def __init__(self,
|
||||
test_accounts: int = NUMBER_OF_ETH_TEST_ACCOUNTS,
|
||||
|
@ -222,7 +222,7 @@ class TesterBlockchain(BlockchainDeployerInterface):
|
|||
@classmethod
|
||||
def bootstrap_network(cls,
|
||||
registry: Optional[BaseContractRegistry] = None,
|
||||
economics: BaseEconomics = None
|
||||
economics: Economics = None
|
||||
) -> Tuple['TesterBlockchain', 'InMemoryContractRegistry']:
|
||||
"""For use with metric testing scripts"""
|
||||
|
||||
|
|
Loading…
Reference in New Issue