mirror of https://github.com/nucypher/nucypher.git
Fixed small issues, added setWorker to UserEscrow
parent
8bc89805ff
commit
b545e3ec9b
|
@ -5,7 +5,7 @@ import "contracts/NuCypherToken.sol";
|
|||
import "zeppelin/math/SafeMath.sol";
|
||||
import "zeppelin/math/Math.sol";
|
||||
import "contracts/proxy/Upgradeable.sol";
|
||||
import "./lib/AdditionalMath.sol";
|
||||
import "contracts/lib/AdditionalMath.sol";
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -375,7 +375,8 @@ contract MinersEscrow is Issuer {
|
|||
"Not enough time has passed since the previous setting worker");
|
||||
require(_worker == address(0) || workerToMiner[_worker] == address(0),
|
||||
"Specified worker is already in use");
|
||||
require(minerInfo[_worker].value == 0, "Specified worker is a miner");
|
||||
require(minerInfo[_worker].value == 0 || _worker == msg.sender,
|
||||
"Specified worker is an another miner");
|
||||
|
||||
// remove relation between the old worker and the miner
|
||||
if (info.worker != address(0)) {
|
||||
|
@ -543,7 +544,7 @@ contract MinersEscrow is Issuer {
|
|||
if (info.confirmedPeriod1 != nextPeriod && info.confirmedPeriod2 != nextPeriod) {
|
||||
saveSubStake(info, nextPeriod, 0, _periods, _value);
|
||||
} else {
|
||||
// TODO check and add docs. maybe extract or rename event
|
||||
// next period is confirmed
|
||||
saveSubStake(info, nextPeriod, 0, _periods - 1, _value);
|
||||
lockedPerPeriod[nextPeriod] = lockedPerPeriod[nextPeriod].add(_value);
|
||||
emit ActivityConfirmed(_miner, nextPeriod, _value);
|
||||
|
@ -619,7 +620,6 @@ contract MinersEscrow is Issuer {
|
|||
// if the next period is confirmed and
|
||||
// old sub stake is finishing in the current period then update confirmation
|
||||
if (lastPeriod == currentPeriod && startPeriod > currentPeriod) {
|
||||
// TODO maybe extract or rename event
|
||||
lockedPerPeriod[startPeriod] = lockedPerPeriod[startPeriod].add(_newValue);
|
||||
emit ActivityConfirmed(msg.sender, startPeriod, _newValue);
|
||||
}
|
||||
|
@ -650,6 +650,8 @@ contract MinersEscrow is Issuer {
|
|||
* @notice Confirm activity for the next period and mine for the previous period
|
||||
**/
|
||||
function confirmActivity() external onlyMiner {
|
||||
require(getWorkerByMiner(msg.sender) == tx.origin, "Only worker can confirm activity");
|
||||
|
||||
uint16 lastActivePeriod = getLastActivePeriod(msg.sender);
|
||||
mint(msg.sender);
|
||||
MinerInfo storage info = minerInfo[msg.sender];
|
||||
|
@ -693,13 +695,16 @@ contract MinersEscrow is Issuer {
|
|||
* @notice Mint tokens for previous periods if miner locked their tokens and confirmed activity
|
||||
**/
|
||||
function mint() external onlyMiner {
|
||||
// save last active period to the storage if only one period is confirmed
|
||||
// because after this minting confirmed periods can be empty and can't calculate period from them
|
||||
// save last active period to the storage if both periods will be empty after minting
|
||||
// because we won't be able to calculate last active period
|
||||
// see getLastActivePeriod(address)
|
||||
MinerInfo storage info = minerInfo[msg.sender];
|
||||
// TODO recheck condition
|
||||
if (info.confirmedPeriod1 != EMPTY_CONFIRMED_PERIOD ||
|
||||
info.confirmedPeriod2 != EMPTY_CONFIRMED_PERIOD) {
|
||||
uint16 previousPeriod = getCurrentPeriod().sub16(1);
|
||||
if (info.confirmedPeriod1 <= previousPeriod &&
|
||||
info.confirmedPeriod2 <= previousPeriod &&
|
||||
(info.confirmedPeriod1 != EMPTY_CONFIRMED_PERIOD ||
|
||||
info.confirmedPeriod2 != EMPTY_CONFIRMED_PERIOD))
|
||||
{
|
||||
info.lastActivePeriod = AdditionalMath.max16(info.confirmedPeriod1, info.confirmedPeriod2);
|
||||
}
|
||||
mint(msg.sender);
|
||||
|
@ -1237,7 +1242,9 @@ contract MinersEscrow is Issuer {
|
|||
infoToCheck.confirmedPeriod2 == info.confirmedPeriod2 &&
|
||||
infoToCheck.reStake == info.reStake &&
|
||||
infoToCheck.lockReStakeUntilPeriod == info.lockReStakeUntilPeriod &&
|
||||
infoToCheck.lastActivePeriod == info.lastActivePeriod);
|
||||
infoToCheck.lastActivePeriod == info.lastActivePeriod &&
|
||||
infoToCheck.worker == info.worker &&
|
||||
infoToCheck.workerStartPeriod == info.workerStartPeriod);
|
||||
|
||||
require(delegateGet(_testTarget, "getPastDowntimeLength(address)", miner) ==
|
||||
info.pastDowntime.length);
|
||||
|
@ -1257,6 +1264,11 @@ contract MinersEscrow is Issuer {
|
|||
subStakeInfoToCheck.periods == subStakeInfo.periods &&
|
||||
subStakeInfoToCheck.lockedValue == subStakeInfo.lockedValue);
|
||||
}
|
||||
|
||||
if (info.worker != address(0)) {
|
||||
require(address(delegateGet(_testTarget, "workerToMiner(address)", bytes32(uint256(info.worker)))) ==
|
||||
workerToMiner[info.worker]);
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev the `onlyWhileUpgrading` modifier works through a call to the parent `finishUpgrade`
|
||||
|
|
|
@ -4,7 +4,7 @@ pragma solidity ^0.5.3;
|
|||
import "zeppelin/token/ERC20/SafeERC20.sol";
|
||||
import "zeppelin/math/SafeMath.sol";
|
||||
import "zeppelin/math/Math.sol";
|
||||
import "./lib/AdditionalMath.sol";
|
||||
import "contracts/lib/AdditionalMath.sol";
|
||||
import "contracts/MinersEscrow.sol";
|
||||
import "contracts/NuCypherToken.sol";
|
||||
import "contracts/proxy/Upgradeable.sol";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
pragma solidity ^0.5.3;
|
||||
|
||||
|
||||
import "./UserEscrow.sol";
|
||||
import "contracts/UserEscrow.sol";
|
||||
import "contracts/NuCypherToken.sol";
|
||||
import "contracts/MinersEscrow.sol";
|
||||
import "contracts/PolicyManager.sol";
|
||||
|
@ -14,16 +14,17 @@ import "contracts/PolicyManager.sol";
|
|||
**/
|
||||
contract UserEscrowProxy {
|
||||
|
||||
event DepositedAsMiner(address indexed owner, uint256 value, uint16 periods);
|
||||
event WithdrawnAsMiner(address indexed owner, uint256 value);
|
||||
event Locked(address indexed owner, uint256 value, uint16 periods);
|
||||
event Divided(address indexed owner, uint256 index, uint256 newValue, uint16 periods);
|
||||
event ActivityConfirmed(address indexed owner);
|
||||
event Mined(address indexed owner);
|
||||
event PolicyRewardWithdrawn(address indexed owner, uint256 value);
|
||||
event MinRewardRateSet(address indexed owner, uint256 value);
|
||||
event ReStakeSet(address indexed owner, bool reStake);
|
||||
event ReStakeLocked(address indexed owner, uint16 lockUntilPeriod);
|
||||
event DepositedAsMiner(address indexed sender, uint256 value, uint16 periods);
|
||||
event WithdrawnAsMiner(address indexed sender, uint256 value);
|
||||
event Locked(address indexed sender, uint256 value, uint16 periods);
|
||||
event Divided(address indexed sender, uint256 index, uint256 newValue, uint16 periods);
|
||||
event ActivityConfirmed(address indexed sender);
|
||||
event Mined(address indexed sender);
|
||||
event PolicyRewardWithdrawn(address indexed sender, uint256 value);
|
||||
event MinRewardRateSet(address indexed sender, uint256 value);
|
||||
event ReStakeSet(address indexed sender, bool reStake);
|
||||
event ReStakeLocked(address indexed sender, uint16 lockUntilPeriod);
|
||||
event WorkerSet(address indexed sender, address worker);
|
||||
|
||||
NuCypherToken public token;
|
||||
MinersEscrow public escrow;
|
||||
|
@ -60,6 +61,15 @@ contract UserEscrowProxy {
|
|||
return UserEscrowProxy(linker.target());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Set `worker` parameter in the miners escrow
|
||||
* @param _worker Worker address. Use zero address to set miner as worker
|
||||
**/
|
||||
function setWorker(address _worker) public {
|
||||
getStateContract().escrow().setWorker(_worker);
|
||||
emit WorkerSet(msg.sender, _worker);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Set `reStake` parameter in the miners escrow
|
||||
* @param _reStake Value for parameter
|
||||
|
|
|
@ -19,6 +19,7 @@ contract MinersEscrowForUserEscrowMock {
|
|||
uint256 public index;
|
||||
bool public reStake;
|
||||
uint16 public lockReStakeUntilPeriod;
|
||||
address public worker;
|
||||
|
||||
constructor(NuCypherToken _token) public {
|
||||
token = _token;
|
||||
|
@ -67,6 +68,10 @@ contract MinersEscrowForUserEscrowMock {
|
|||
function lockReStake(uint16 _lockReStakeUntilPeriod) public {
|
||||
lockReStakeUntilPeriod = _lockReStakeUntilPeriod;
|
||||
}
|
||||
|
||||
function setWorker(address _worker) public {
|
||||
worker = _worker;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -99,6 +99,8 @@ def test_upgrading(testerchain, token):
|
|||
testerchain.wait_for_receipt(tx)
|
||||
tx = contract.functions.lockReStake(contract.functions.getCurrentPeriod().call() + 1).transact({'from': miner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = contract.functions.setWorker(miner).transact({'from': miner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Upgrade to the second version
|
||||
tx = dispatcher.functions.upgrade(contract_library_v2.address, secret, secret2_hash).transact({'from': creator})
|
||||
|
@ -434,3 +436,8 @@ def test_re_stake(testerchain, token, escrow_contract):
|
|||
assert sub_stake == escrow.functions.getLockedTokensInPast(ursula, 1).call()
|
||||
assert sub_stake == escrow.functions.getLockedTokens(ursula).call()
|
||||
assert sub_stake == escrow.functions.lockedPerPeriod(period - 1).call()
|
||||
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_worker(testerchain, token, escrow_contract):
|
||||
pass
|
||||
|
|
|
@ -149,7 +149,7 @@ def test_miner(testerchain, token, escrow, user_escrow, user_escrow_proxy, proxy
|
|||
events = miner_deposits.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert user == event_args['owner']
|
||||
assert user == event_args['sender']
|
||||
assert 1500 == event_args['value']
|
||||
assert 5 == event_args['periods']
|
||||
|
||||
|
@ -180,6 +180,9 @@ def test_miner(testerchain, token, escrow, user_escrow, user_escrow_proxy, proxy
|
|||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = proxy.functions.lockReStake(0).transact({'from': user})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = proxy.functions.setWorker(user).transact({'from': user})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
locks = user_escrow_proxy.events.Locked.createFilter(fromBlock='latest')
|
||||
divides = user_escrow_proxy.events.Divided.createFilter(fromBlock='latest')
|
||||
|
@ -189,6 +192,7 @@ def test_miner(testerchain, token, escrow, user_escrow, user_escrow_proxy, proxy
|
|||
withdraws = user_escrow.events.TokensWithdrawn.createFilter(fromBlock='latest')
|
||||
re_stakes = user_escrow_proxy.events.ReStakeSet.createFilter(fromBlock='latest')
|
||||
re_stake_locks = user_escrow_proxy.events.ReStakeLocked.createFilter(fromBlock='latest')
|
||||
worker_logs = user_escrow_proxy.events.WorkerSet.createFilter(fromBlock='latest')
|
||||
|
||||
# Use miners methods through the user escrow
|
||||
tx = user_escrow_proxy.functions.lock(100, 1).transact({'from': user})
|
||||
|
@ -226,17 +230,22 @@ def test_miner(testerchain, token, escrow, user_escrow, user_escrow_proxy, proxy
|
|||
testerchain.wait_for_receipt(tx)
|
||||
assert 123 == escrow.functions.lockReStakeUntilPeriod().call()
|
||||
|
||||
# Test setting worker
|
||||
tx = user_escrow_proxy.functions.setWorker(user).transact({'from': user})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert user == escrow.functions.worker().call()
|
||||
|
||||
events = locks.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert user == event_args['owner']
|
||||
assert user == event_args['sender']
|
||||
assert 100 == event_args['value']
|
||||
assert 1 == event_args['periods']
|
||||
|
||||
events = divides.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert user == event_args['owner']
|
||||
assert user == event_args['sender']
|
||||
assert 1 == event_args['index']
|
||||
assert 100 == event_args['newValue']
|
||||
assert 1 == event_args['periods']
|
||||
|
@ -244,34 +253,40 @@ def test_miner(testerchain, token, escrow, user_escrow, user_escrow_proxy, proxy
|
|||
events = confirms.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert user == event_args['owner']
|
||||
assert user == event_args['sender']
|
||||
|
||||
events = mints.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert user == event_args['owner']
|
||||
assert user == event_args['sender']
|
||||
|
||||
events = miner_withdraws.get_all_entries()
|
||||
assert 2 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert user == event_args['owner']
|
||||
assert user == event_args['sender']
|
||||
assert 1500 == event_args['value']
|
||||
event_args = events[1]['args']
|
||||
assert user == event_args['owner']
|
||||
assert user == event_args['sender']
|
||||
assert 1000 == event_args['value']
|
||||
|
||||
events = re_stakes.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert user == event_args['owner']
|
||||
assert user == event_args['sender']
|
||||
assert event_args['reStake']
|
||||
|
||||
events = re_stake_locks.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert user == event_args['owner']
|
||||
assert user == event_args['sender']
|
||||
assert 123 == event_args['lockUntilPeriod']
|
||||
|
||||
events = worker_logs.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert user == event_args['sender']
|
||||
assert user == event_args['worker']
|
||||
|
||||
# User can withdraw reward for mining but no more than locked
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = user_escrow.functions.withdrawTokens(2500).transact({'from': user})
|
||||
|
@ -333,7 +348,7 @@ def test_policy(testerchain, policy_manager, user_escrow, user_escrow_proxy):
|
|||
events = miner_reward.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert user == event_args['owner']
|
||||
assert user == event_args['sender']
|
||||
assert 10000 == event_args['value']
|
||||
|
||||
events = rewards.get_all_entries()
|
||||
|
@ -351,5 +366,5 @@ def test_policy(testerchain, policy_manager, user_escrow, user_escrow_proxy):
|
|||
events = min_reward_sets.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert user == event_args['owner']
|
||||
assert user == event_args['sender']
|
||||
assert 222 == event_args['value']
|
||||
|
|
|
@ -243,6 +243,13 @@ def estimate_gas(analyzer: AnalyzeGas = None) -> None:
|
|||
tx = miner_functions.deposit(MIN_ALLOWED_LOCKED * 3, MIN_LOCKED_PERIODS).transact({'from': ursula3})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
tx = miner_functions.confirmActivity().transact({'from': ursula1})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = miner_functions.confirmActivity().transact({'from': ursula2})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = miner_functions.confirmActivity().transact({'from': ursula3})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
#
|
||||
# Wait 1 period and confirm activity
|
||||
#
|
||||
|
|
Loading…
Reference in New Issue