mirror of https://github.com/nucypher/nucypher.git
commit
37e0d22d61
|
@ -417,7 +417,7 @@ class StakingEscrowAgent(EthereumContractAgent):
|
|||
@validate_checksum_address
|
||||
def is_restaking(self, staker_address: str) -> bool:
|
||||
staker_info = self.get_staker_info(staker_address)
|
||||
restake_flag = bool(staker_info[3]) # TODO: #1348 Use constant or enum
|
||||
restake_flag = not bool(staker_info[3]) # TODO: #1348 Use constant or enum
|
||||
return restake_flag
|
||||
|
||||
@validate_checksum_address
|
||||
|
|
|
@ -33,7 +33,7 @@ contract WorkLockInterface {
|
|||
/**
|
||||
* @notice Contract holds and locks stakers tokens.
|
||||
* Each staker that locks their tokens will receive some compensation
|
||||
* @dev |v1.5.1|
|
||||
* @dev |v2.1.1|
|
||||
*/
|
||||
contract StakingEscrow is Issuer {
|
||||
using AdditionalMath for uint256;
|
||||
|
@ -82,7 +82,7 @@ contract StakingEscrow is Issuer {
|
|||
*/
|
||||
uint16 confirmedPeriod1;
|
||||
uint16 confirmedPeriod2;
|
||||
bool reStake;
|
||||
bool reStakeDisabled;
|
||||
uint16 lockReStakeUntilPeriod;
|
||||
address worker;
|
||||
// period when worker was set
|
||||
|
@ -468,10 +468,10 @@ contract StakingEscrow is Issuer {
|
|||
function setReStake(bool _reStake) public isInitialized {
|
||||
require(!isReStakeLocked(msg.sender));
|
||||
StakerInfo storage info = stakerInfo[msg.sender];
|
||||
if (info.reStake == _reStake) {
|
||||
if (info.reStakeDisabled == !_reStake) {
|
||||
return;
|
||||
}
|
||||
info.reStake = _reStake;
|
||||
info.reStakeDisabled = !_reStake;
|
||||
emit ReStakeSet(msg.sender, _reStake);
|
||||
}
|
||||
|
||||
|
@ -837,7 +837,7 @@ contract StakingEscrow is Issuer {
|
|||
lockedPerPeriod[mintingPeriod],
|
||||
lastPeriod.sub16(mintingPeriod));
|
||||
reward += subStakeReward;
|
||||
if (_info.reStake) {
|
||||
if (!_info.reStakeDisabled) {
|
||||
subStake.lockedValue += subStakeReward;
|
||||
}
|
||||
}
|
||||
|
@ -848,7 +848,7 @@ contract StakingEscrow is Issuer {
|
|||
} else {
|
||||
_info.confirmedPeriod2 = EMPTY_CONFIRMED_PERIOD;
|
||||
}
|
||||
if (!_info.reStake) {
|
||||
if (_info.reStakeDisabled) {
|
||||
return reward;
|
||||
}
|
||||
if (_confirmedPeriodNumber == 1 &&
|
||||
|
@ -1239,7 +1239,7 @@ contract StakingEscrow is Issuer {
|
|||
require(infoToCheck.value == info.value &&
|
||||
infoToCheck.confirmedPeriod1 == info.confirmedPeriod1 &&
|
||||
infoToCheck.confirmedPeriod2 == info.confirmedPeriod2 &&
|
||||
infoToCheck.reStake == info.reStake &&
|
||||
infoToCheck.reStakeDisabled == info.reStakeDisabled &&
|
||||
infoToCheck.lockReStakeUntilPeriod == info.lockReStakeUntilPeriod &&
|
||||
infoToCheck.lastActivePeriod == info.lastActivePeriod &&
|
||||
infoToCheck.measureWork == info.measureWork &&
|
||||
|
|
|
@ -44,6 +44,7 @@ def test_reward(testerchain, agency, token_economics, mock_transacting_power_act
|
|||
lock_periods=100 * token_economics.maximum_rewarded_periods,
|
||||
sender_address=ursula)
|
||||
_txhash = staking_agent.set_worker(staker_address=ursula, worker_address=ursula)
|
||||
_txhash = staking_agent.set_restaking(staker_address=ursula, value=False)
|
||||
|
||||
# Get a reward for one period
|
||||
_txhash = staking_agent.confirm_activity(worker_address=ursula)
|
||||
|
|
|
@ -31,7 +31,7 @@ from nucypher.crypto.api import sha256_digest
|
|||
from nucypher.crypto.signing import SignatureStamp
|
||||
|
||||
|
||||
RE_STAKE_FIELD = 3
|
||||
DISABLE_RE_STAKE_FIELD = 3
|
||||
|
||||
DISABLED_FIELD = 5
|
||||
|
||||
|
@ -467,13 +467,11 @@ def test_all(testerchain,
|
|||
# Set and lock re-stake parameter in first preallocation escrow
|
||||
tx = preallocation_escrow_1.functions.transferOwnership(ursula3).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert not escrow.functions.stakerInfo(preallocation_escrow_1.address).call()[RE_STAKE_FIELD]
|
||||
tx = preallocation_escrow_interface_1.functions.setReStake(True).transact({'from': ursula3})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert not escrow.functions.stakerInfo(preallocation_escrow_1.address).call()[DISABLE_RE_STAKE_FIELD]
|
||||
current_period = escrow.functions.getCurrentPeriod().call()
|
||||
tx = preallocation_escrow_interface_1.functions.lockReStake(current_period + 22).transact({'from': ursula3})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert escrow.functions.stakerInfo(preallocation_escrow_1.address).call()[RE_STAKE_FIELD]
|
||||
assert not escrow.functions.stakerInfo(preallocation_escrow_1.address).call()[DISABLE_RE_STAKE_FIELD]
|
||||
# Can't unlock re-stake parameter now
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = preallocation_escrow_interface_1.functions.setReStake(False).transact({'from': ursula3})
|
||||
|
@ -529,6 +527,8 @@ def test_all(testerchain,
|
|||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.setWorker(ursula1).transact({'from': ursula1})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.setReStake(False).transact({'from': ursula1})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.confirmActivity().transact({'from': ursula1})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
escrow_balance += 1000
|
||||
|
@ -586,10 +586,10 @@ def test_all(testerchain,
|
|||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Turn on re-stake for Ursula1
|
||||
assert not escrow.functions.stakerInfo(ursula1).call()[RE_STAKE_FIELD]
|
||||
assert escrow.functions.stakerInfo(ursula1).call()[DISABLE_RE_STAKE_FIELD]
|
||||
tx = escrow.functions.setReStake(True).transact({'from': ursula1})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert escrow.functions.stakerInfo(ursula1).call()[RE_STAKE_FIELD]
|
||||
assert not escrow.functions.stakerInfo(ursula1).call()[DISABLE_RE_STAKE_FIELD]
|
||||
|
||||
testerchain.time_travel(hours=1)
|
||||
tx = escrow.functions.confirmActivity().transact({'from': ursula1})
|
||||
|
@ -689,10 +689,10 @@ def test_all(testerchain,
|
|||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Turn off re-stake for Ursula1
|
||||
assert escrow.functions.stakerInfo(ursula1).call()[RE_STAKE_FIELD]
|
||||
assert not escrow.functions.stakerInfo(ursula1).call()[DISABLE_RE_STAKE_FIELD]
|
||||
tx = escrow.functions.setReStake(False).transact({'from': ursula1})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert not escrow.functions.stakerInfo(ursula1).call()[RE_STAKE_FIELD]
|
||||
assert escrow.functions.stakerInfo(ursula1).call()[DISABLE_RE_STAKE_FIELD]
|
||||
|
||||
testerchain.time_travel(hours=1)
|
||||
tx = escrow.functions.confirmActivity().transact({'from': ursula1})
|
||||
|
@ -1068,7 +1068,7 @@ def test_all(testerchain,
|
|||
# Now can turn off re-stake
|
||||
tx = preallocation_escrow_interface_1.functions.setReStake(False).transact({'from': ursula3})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert not escrow.functions.stakerInfo(preallocation_escrow_1.address).call()[RE_STAKE_FIELD]
|
||||
assert escrow.functions.stakerInfo(preallocation_escrow_1.address).call()[DISABLE_RE_STAKE_FIELD]
|
||||
|
||||
tx = escrow.functions.mint().transact({'from': ursula1})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
|
|
@ -82,12 +82,16 @@ def test_mining(testerchain, token, escrow_contract, token_economics):
|
|||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.setWorker(ursula1).transact({'from': ursula1})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.setReStake(False).transact({'from': ursula1})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.confirmActivity().transact({'from': ursula1})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.deposit(ursula2_stake, 2).transact({'from': ursula2})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.setWorker(ursula2).transact({'from': ursula2})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.setReStake(False).transact({'from': ursula2})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert 0 == escrow.functions.findIndexOfPastDowntime(ursula2, 0).call()
|
||||
assert 0 == escrow.functions.findIndexOfPastDowntime(ursula2, current_period + 1).call()
|
||||
tx = escrow.functions.confirmActivity().transact({'from': ursula2})
|
||||
|
@ -380,6 +384,8 @@ def test_slashing(testerchain, token, escrow_contract, token_economics, deploy_c
|
|||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.setWorker(ursula).transact({'from': ursula})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.setReStake(False).transact({'from': ursula})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.confirmActivity().transact({'from': ursula})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
testerchain.time_travel(hours=1)
|
||||
|
@ -681,6 +687,8 @@ def test_slashing(testerchain, token, escrow_contract, token_economics, deploy_c
|
|||
testerchain.time_travel(hours=1)
|
||||
tx = escrow.functions.deposit(100, 2).transact({'from': ursula2})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.setReStake(False).transact({'from': ursula2})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.confirmActivity().transact({'from': ursula2})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
testerchain.time_travel(hours=2)
|
||||
|
|
|
@ -24,7 +24,7 @@ from web3.contract import Contract
|
|||
from nucypher.blockchain.eth.interfaces import BlockchainInterface
|
||||
from nucypher.blockchain.eth.token import NU
|
||||
|
||||
RE_STAKE_FIELD = 3
|
||||
DISABLE_RE_STAKE_FIELD = 3
|
||||
LOCK_RE_STAKE_UNTIL_PERIOD_FIELD = 4
|
||||
|
||||
secret = (123456).to_bytes(32, byteorder='big')
|
||||
|
@ -228,27 +228,30 @@ def test_re_stake(testerchain, token, escrow_contract):
|
|||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Set re-stake parameter even before initialization
|
||||
assert not escrow.functions.stakerInfo(ursula).call()[RE_STAKE_FIELD]
|
||||
assert not escrow.functions.stakerInfo(ursula).call()[DISABLE_RE_STAKE_FIELD]
|
||||
tx = escrow.functions.setReStake(False).transact({'from': ursula})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert not escrow.functions.stakerInfo(ursula).call()[RE_STAKE_FIELD]
|
||||
assert escrow.functions.stakerInfo(ursula).call()[DISABLE_RE_STAKE_FIELD]
|
||||
tx = escrow.functions.setReStake(True).transact({'from': ursula})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert escrow.functions.stakerInfo(ursula).call()[RE_STAKE_FIELD]
|
||||
assert not escrow.functions.stakerInfo(ursula).call()[DISABLE_RE_STAKE_FIELD]
|
||||
tx = escrow.functions.setReStake(True).transact({'from': ursula})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert escrow.functions.stakerInfo(ursula).call()[RE_STAKE_FIELD]
|
||||
assert not escrow.functions.stakerInfo(ursula).call()[DISABLE_RE_STAKE_FIELD]
|
||||
tx = escrow.functions.setReStake(False).transact({'from': ursula})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert not escrow.functions.stakerInfo(ursula).call()[RE_STAKE_FIELD]
|
||||
assert escrow.functions.stakerInfo(ursula).call()[DISABLE_RE_STAKE_FIELD]
|
||||
|
||||
events = re_stake_log.get_all_entries()
|
||||
assert 2 == len(events)
|
||||
assert 3 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert ursula == event_args['staker']
|
||||
assert event_args['reStake']
|
||||
assert not event_args['reStake']
|
||||
event_args = events[1]['args']
|
||||
assert ursula == event_args['staker']
|
||||
assert event_args['reStake']
|
||||
event_args = events[2]['args']
|
||||
assert ursula == event_args['staker']
|
||||
assert not event_args['reStake']
|
||||
|
||||
# Lock re-stake parameter during 1 period
|
||||
|
@ -311,7 +314,7 @@ def test_re_stake(testerchain, token, escrow_contract):
|
|||
# Set re-stake and lock parameter
|
||||
tx = escrow.functions.setReStake(True).transact({'from': ursula})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert escrow.functions.stakerInfo(ursula).call()[RE_STAKE_FIELD]
|
||||
assert not escrow.functions.stakerInfo(ursula).call()[DISABLE_RE_STAKE_FIELD]
|
||||
tx = escrow.functions.lockReStake(period + 6).transact({'from': ursula})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
# Can't set re-stake parameter during 6 periods
|
||||
|
@ -320,8 +323,8 @@ def test_re_stake(testerchain, token, escrow_contract):
|
|||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
events = re_stake_log.get_all_entries()
|
||||
assert 3 == len(events)
|
||||
event_args = events[2]['args']
|
||||
assert 4 == len(events)
|
||||
event_args = events[3]['args']
|
||||
assert ursula == event_args['staker']
|
||||
assert event_args['reStake']
|
||||
events = re_stake_lock_log.get_all_entries()
|
||||
|
@ -385,6 +388,8 @@ def test_re_stake(testerchain, token, escrow_contract):
|
|||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.setWorker(ursula2).transact({'from': ursula2})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.setReStake(False).transact({'from': ursula2})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = escrow.functions.confirmActivity().transact({'from': ursula2})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
testerchain.time_travel(hours=1)
|
||||
|
@ -450,11 +455,11 @@ def test_re_stake(testerchain, token, escrow_contract):
|
|||
# Now turn off re-stake
|
||||
tx = escrow.functions.setReStake(False).transact({'from': ursula})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert not escrow.functions.stakerInfo(ursula).call()[RE_STAKE_FIELD]
|
||||
assert escrow.functions.stakerInfo(ursula).call()[DISABLE_RE_STAKE_FIELD]
|
||||
|
||||
events = re_stake_log.get_all_entries()
|
||||
assert 4 == len(events)
|
||||
event_args = events[3]['args']
|
||||
assert 6 == len(events)
|
||||
event_args = events[5]['args']
|
||||
assert ursula == event_args['staker']
|
||||
assert not event_args['reStake']
|
||||
|
||||
|
|
|
@ -227,14 +227,14 @@ def test_divide_stake(agency, token_economics):
|
|||
|
||||
|
||||
@pytest.mark.slow()
|
||||
def test_enable_restaking(agency, testerchain, test_registry):
|
||||
def test_disable_restaking(agency, testerchain, test_registry):
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
staker_account, worker_account, *other = testerchain.unassigned_accounts
|
||||
|
||||
assert not staking_agent.is_restaking(staker_account)
|
||||
receipt = staking_agent.set_restaking(staker_account, value=True)
|
||||
assert receipt['status'] == 1
|
||||
assert staking_agent.is_restaking(staker_account)
|
||||
receipt = staking_agent.set_restaking(staker_account, value=False)
|
||||
assert receipt['status'] == 1
|
||||
assert not staking_agent.is_restaking(staker_account)
|
||||
|
||||
|
||||
@pytest.mark.slow()
|
||||
|
|
|
@ -276,10 +276,10 @@ def test_stake_restake(click_runner,
|
|||
checksum_address=beneficiary,
|
||||
registry=test_registry,
|
||||
individual_allocation=individual_allocation)
|
||||
assert not staker.is_restaking
|
||||
assert staker.is_restaking
|
||||
|
||||
restake_args = ('stake', 'restake',
|
||||
'--enable',
|
||||
'--disable',
|
||||
'--config-file', stakeholder_configuration_file_location,
|
||||
'--allocation-filepath', MOCK_INDIVIDUAL_ALLOCATION_FILEPATH,
|
||||
'--force')
|
||||
|
@ -289,8 +289,8 @@ def test_stake_restake(click_runner,
|
|||
input=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
catch_exceptions=False)
|
||||
assert result.exit_code == 0
|
||||
assert staker.is_restaking
|
||||
assert "Successfully enabled" in result.output
|
||||
assert not staker.is_restaking
|
||||
assert "Successfully disabled" in result.output
|
||||
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
current_period = staking_agent.get_current_period()
|
||||
|
@ -307,8 +307,8 @@ def test_stake_restake(click_runner,
|
|||
catch_exceptions=False)
|
||||
assert result.exit_code == 0
|
||||
|
||||
# Still staking and the lock is enabled
|
||||
assert staker.is_restaking
|
||||
# Still not staking and the lock is enabled
|
||||
assert not staker.is_restaking
|
||||
assert staker.restaking_lock_enabled
|
||||
|
||||
# CLI Output includes success message
|
||||
|
@ -318,10 +318,10 @@ def test_stake_restake(click_runner,
|
|||
# Wait until release period
|
||||
testerchain.time_travel(periods=1)
|
||||
assert not staker.restaking_lock_enabled
|
||||
assert staker.is_restaking
|
||||
assert not staker.is_restaking
|
||||
|
||||
disable_args = ('stake', 'restake',
|
||||
'--disable',
|
||||
'--enable',
|
||||
'--config-file', stakeholder_configuration_file_location,
|
||||
'--allocation-filepath', MOCK_INDIVIDUAL_ALLOCATION_FILEPATH,
|
||||
'--force')
|
||||
|
@ -333,14 +333,14 @@ def test_stake_restake(click_runner,
|
|||
assert result.exit_code == 0
|
||||
|
||||
allocation_contract_address = preallocation_escrow_agent.principal_contract.address
|
||||
assert not staking_agent.is_restaking(allocation_contract_address)
|
||||
assert staking_agent.is_restaking(allocation_contract_address)
|
||||
|
||||
staker = Staker(is_me=True,
|
||||
checksum_address=beneficiary,
|
||||
registry=test_registry,
|
||||
individual_allocation=individual_allocation)
|
||||
assert not staker.is_restaking
|
||||
assert "Successfully disabled" in result.output
|
||||
assert staker.is_restaking
|
||||
assert "Successfully enabled" in result.output
|
||||
|
||||
|
||||
def test_ursula_init(click_runner,
|
||||
|
|
|
@ -261,10 +261,10 @@ def test_stake_restake(click_runner,
|
|||
stakeholder_configuration_file_location):
|
||||
|
||||
staker = Staker(is_me=True, checksum_address=manual_staker, registry=test_registry)
|
||||
assert not staker.is_restaking
|
||||
assert staker.is_restaking
|
||||
|
||||
restake_args = ('stake', 'restake',
|
||||
'--enable',
|
||||
'--disable',
|
||||
'--config-file', stakeholder_configuration_file_location,
|
||||
'--staking-address', manual_staker,
|
||||
'--force')
|
||||
|
@ -274,8 +274,8 @@ def test_stake_restake(click_runner,
|
|||
input=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
catch_exceptions=False)
|
||||
assert result.exit_code == 0
|
||||
assert staker.is_restaking
|
||||
assert "Successfully enabled" in result.output
|
||||
assert not staker.is_restaking
|
||||
assert "Successfully disabled" in result.output
|
||||
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
current_period = staking_agent.get_current_period()
|
||||
|
@ -292,8 +292,8 @@ def test_stake_restake(click_runner,
|
|||
catch_exceptions=False)
|
||||
assert result.exit_code == 0
|
||||
|
||||
# Still staking and the lock is enabled
|
||||
assert staker.is_restaking
|
||||
# Still not staking and the lock is enabled
|
||||
assert not staker.is_restaking
|
||||
assert staker.restaking_lock_enabled
|
||||
|
||||
# CLI Output includes success message
|
||||
|
@ -303,10 +303,10 @@ def test_stake_restake(click_runner,
|
|||
# Wait until release period
|
||||
testerchain.time_travel(periods=1)
|
||||
assert not staker.restaking_lock_enabled
|
||||
assert staker.is_restaking
|
||||
assert not staker.is_restaking
|
||||
|
||||
disable_args = ('stake', 'restake',
|
||||
'--disable',
|
||||
'--enable',
|
||||
'--config-file', stakeholder_configuration_file_location,
|
||||
'--staking-address', manual_staker,
|
||||
'--force')
|
||||
|
@ -316,8 +316,8 @@ def test_stake_restake(click_runner,
|
|||
input=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
catch_exceptions=False)
|
||||
assert result.exit_code == 0
|
||||
assert not staker.is_restaking
|
||||
assert "Successfully disabled" in result.output
|
||||
assert staker.is_restaking
|
||||
assert "Successfully enabled" in result.output
|
||||
|
||||
|
||||
def test_collect_rewards_integration(click_runner,
|
||||
|
|
|
@ -228,6 +228,8 @@ def estimate_gas(analyzer: AnalyzeGas = None) -> None:
|
|||
|
||||
transact(staker_functions.setWorker(ursula1), {'from': ursula1})
|
||||
transact(staker_functions.setWorker(ursula2), {'from': ursula2})
|
||||
transact(staker_functions.setReStake(False), {'from': ursula1})
|
||||
transact(staker_functions.setReStake(False), {'from': ursula2})
|
||||
transact(staker_functions.confirmActivity(), {'from': ursula1})
|
||||
transact(staker_functions.confirmActivity(), {'from': ursula2})
|
||||
|
||||
|
|
Loading…
Reference in New Issue