mirror of https://github.com/nucypher/nucypher.git
Update test_worklock
parent
c57a4d8f16
commit
acd8f50e16
|
@ -8,6 +8,7 @@ import "contracts/NuCypherToken.sol";
|
|||
import "contracts/StakingEscrow.sol";
|
||||
//import "contracts/UserEscrow.sol";
|
||||
//import "contracts/UserEscrowLibraryLinker.sol";
|
||||
import "contracts/lib/AdditionalMath.sol";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -16,6 +17,7 @@ import "contracts/StakingEscrow.sol";
|
|||
contract WorkLock {
|
||||
using SafeERC20 for NuCypherToken;
|
||||
using SafeMath for uint256;
|
||||
using AdditionalMath for uint256;
|
||||
// using Address for address payable;
|
||||
|
||||
event Deposited(address indexed sender, uint256 value);
|
||||
|
@ -23,7 +25,7 @@ contract WorkLock {
|
|||
event Claimed(address indexed staker, uint256 claimedTokens);
|
||||
event Refund(address indexed staker, uint256 refundETH, uint256 completedWork);
|
||||
event Burnt(address indexed sender, uint256 value);
|
||||
event Canceled(address indexed sender, uint256 value);
|
||||
event Canceled(address indexed staker, uint256 value);
|
||||
|
||||
struct WorkInfo {
|
||||
uint256 depositedETH;
|
||||
|
@ -44,7 +46,7 @@ contract WorkLock {
|
|||
uint256 public tokenSupply;
|
||||
uint256 public ethSupply;
|
||||
uint256 public unclaimedTokens;
|
||||
uint16 public lockedDuration;
|
||||
// uint16 public lockedDuration;
|
||||
mapping(address => WorkInfo) public workInfo;
|
||||
|
||||
/**
|
||||
|
@ -54,7 +56,7 @@ contract WorkLock {
|
|||
* @param _startBidDate Timestamp when bidding starts
|
||||
* @param _endBidDate Timestamp when bidding will end
|
||||
* @param _boostingRefund Coefficient to boost refund ETH
|
||||
* @param _lockedDuration Duration of tokens locking
|
||||
* @dev _lockedDuration Duration of tokens locking
|
||||
*/
|
||||
constructor(
|
||||
NuCypherToken _token,
|
||||
|
@ -62,8 +64,8 @@ contract WorkLock {
|
|||
// UserEscrowLibraryLinker _linker,
|
||||
uint256 _startBidDate,
|
||||
uint256 _endBidDate,
|
||||
uint256 _boostingRefund,
|
||||
uint16 _lockedDuration
|
||||
uint256 _boostingRefund//,
|
||||
// uint16 _lockedDuration
|
||||
)
|
||||
public
|
||||
{
|
||||
|
@ -72,15 +74,15 @@ contract WorkLock {
|
|||
// _linker.target().isContract() &&
|
||||
_endBidDate > _startBidDate &&
|
||||
_endBidDate > block.timestamp &&
|
||||
_boostingRefund > 0 &&
|
||||
_lockedDuration > 0);
|
||||
_boostingRefund > 0);// &&
|
||||
// _lockedDuration > 0);
|
||||
token = _token;
|
||||
escrow = _escrow;
|
||||
// linker = _linker;
|
||||
startBidDate = _startBidDate;
|
||||
endBidDate = _endBidDate;
|
||||
boostingRefund = _boostingRefund;
|
||||
lockedDuration = _lockedDuration;
|
||||
// lockedDuration = _lockedDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,7 +109,7 @@ contract WorkLock {
|
|||
* @dev This value will be fixed only after end of bidding
|
||||
**/
|
||||
function ethToWork(uint256 _ethAmount) public view returns (uint256) {
|
||||
return _ethAmount.mul(tokenSupply).mul(SLOWING_REFUND).div(ethSupply).div(boostingRefund);
|
||||
return _ethAmount.mul(tokenSupply).mul(SLOWING_REFUND).divCeil(ethSupply.mul(boostingRefund));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,7 +117,20 @@ contract WorkLock {
|
|||
* @dev This value will be fixed only after end of bidding
|
||||
**/
|
||||
function workToETH(uint256 _completedWork) public view returns (uint256) {
|
||||
return _completedWork.mul(ethSupply).mul(boostingRefund).div(tokenSupply).div(SLOWING_REFUND);
|
||||
return _completedWork.mul(ethSupply).mul(boostingRefund).div(tokenSupply.mul(SLOWING_REFUND));
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Get remaining work to full refund
|
||||
*/
|
||||
function getRemainingWork(address _staker) public view returns (uint256) {
|
||||
WorkInfo storage info = workInfo[_staker];
|
||||
uint256 completedWork = escrow.getCompletedWork(_staker).sub(info.completedWork);
|
||||
uint256 remainingWork = ethToWork(info.depositedETH);
|
||||
if (remainingWork <= completedWork) {
|
||||
return 0;
|
||||
}
|
||||
return remainingWork.sub(completedWork);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -159,6 +174,7 @@ contract WorkLock {
|
|||
require(!info.claimed, "Tokens are already claimed");
|
||||
info.claimed = true;
|
||||
claimedTokens = ethToTokens(info.depositedETH); // TODO check for overflow before
|
||||
info.completedWork = escrow.setWorkMeasurement(msg.sender, true);
|
||||
token.safeTransfer(msg.sender, claimedTokens);
|
||||
emit Claimed(msg.sender, claimedTokens);
|
||||
|
||||
|
@ -214,19 +230,6 @@ contract WorkLock {
|
|||
msg.sender.sendValue(refundETH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Get remaining work to full refund
|
||||
*/
|
||||
function getRemainingWork(address _staker) public view returns (uint256) {
|
||||
WorkInfo storage info = workInfo[_staker];
|
||||
uint256 completedWork = escrow.getCompletedWork(_staker).sub(info.completedWork);
|
||||
uint256 remainingWork = ethToWork(info.depositedETH);
|
||||
if (remainingWork <= completedWork) {
|
||||
return 0;
|
||||
}
|
||||
return remainingWork.sub(completedWork);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Burn unclaimed tokens
|
||||
**/
|
||||
|
|
|
@ -15,8 +15,10 @@ 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 pytest
|
||||
from eth_tester.exceptions import TransactionFailed
|
||||
from eth_utils import to_wei
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
|
@ -45,43 +47,40 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow):
|
|||
now = testerchain.w3.eth.getBlock(block_identifier='latest').timestamp
|
||||
start_bid_date = now + (60 * 60) # 1 Hour
|
||||
end_bid_date = start_bid_date + (60 * 60)
|
||||
deposit_rate = 100
|
||||
refund_rate = 200
|
||||
boosting_refund = 50
|
||||
slowing_refund = 100
|
||||
worklock, _ = deploy_contract(
|
||||
contract_name='WorkLock',
|
||||
_token=token.address,
|
||||
_escrow=escrow.address,
|
||||
_startBidDate=start_bid_date,
|
||||
_endBidDate=end_bid_date,
|
||||
_depositRate=deposit_rate,
|
||||
_refundRate=refund_rate,
|
||||
_lockedPeriods=2 * token_economics.minimum_locked_periods
|
||||
_boostingRefund=boosting_refund
|
||||
)
|
||||
assert worklock.functions.startBidDate().call() == start_bid_date
|
||||
assert worklock.functions.endBidDate().call() == end_bid_date
|
||||
assert worklock.functions.minAllowableLockedTokens().call() == token_economics.minimum_allowed_locked
|
||||
assert worklock.functions.maxAllowableLockedTokens().call() == token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.depositRate().call() == deposit_rate
|
||||
assert worklock.functions.refundRate().call() == refund_rate
|
||||
assert worklock.functions.boostingRefund().call() == boosting_refund
|
||||
assert worklock.functions.SLOWING_REFUND().call() == slowing_refund
|
||||
|
||||
deposit_log = worklock.events.Deposited.createFilter(fromBlock='latest')
|
||||
bidding_log = worklock.events.Bid.createFilter(fromBlock='latest')
|
||||
claim_log = worklock.events.Claimed.createFilter(fromBlock='latest')
|
||||
refund_log = worklock.events.Refund.createFilter(fromBlock='latest')
|
||||
burning_log = worklock.events.Burnt.createFilter(fromBlock='latest')
|
||||
canceling_log = worklock.events.Canceled.createFilter(fromBlock='latest')
|
||||
|
||||
# Transfer tokens to WorkLock
|
||||
worklock_supply_1 = 2 * token_economics.maximum_allowed_locked
|
||||
worklock_supply_1 = 2 * token_economics.maximum_allowed_locked + 1
|
||||
worklock_supply_2 = token_economics.maximum_allowed_locked - 1
|
||||
worklock_supply = worklock_supply_1 + worklock_supply_2
|
||||
tx = token.functions.approve(worklock.address, worklock_supply).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = worklock.functions.deposit(worklock_supply_1).transact({'from': creator})
|
||||
tx = worklock.functions.tokenDeposit(worklock_supply_1).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.remainingTokens().call() == worklock_supply_1
|
||||
tx = worklock.functions.deposit(worklock_supply_2).transact({'from': creator})
|
||||
assert worklock.functions.tokenSupply().call() == worklock_supply_1
|
||||
tx = worklock.functions.tokenDeposit(worklock_supply_2).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.remainingTokens().call() == worklock_supply
|
||||
assert worklock.functions.tokenSupply().call() == worklock_supply
|
||||
|
||||
events = deposit_log.get_all_entries()
|
||||
assert 2 == len(events)
|
||||
|
@ -93,24 +92,24 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow):
|
|||
assert event_args['value'] == worklock_supply_2
|
||||
|
||||
# Give Ursulas some ETH
|
||||
minimum_deposit_eth = token_economics.minimum_allowed_locked // deposit_rate
|
||||
maximum_deposit_eth = token_economics.maximum_allowed_locked // deposit_rate
|
||||
ursula1_balance = 2 * maximum_deposit_eth
|
||||
deposit_eth_1 = to_wei(4, 'ether')
|
||||
deposit_eth_2 = deposit_eth_1 // 4
|
||||
ursula1_balance = 10 * deposit_eth_1
|
||||
tx = testerchain.w3.eth.sendTransaction(
|
||||
{'from': testerchain.etherbase_account, 'to': ursula1, 'value': ursula1_balance})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
ursula2_balance = 2 * maximum_deposit_eth
|
||||
ursula2_balance = ursula1_balance
|
||||
tx = testerchain.w3.eth.sendTransaction(
|
||||
{'from': testerchain.etherbase_account, 'to': ursula2, 'value': ursula2_balance})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
ursula3_balance = maximum_deposit_eth
|
||||
ursula3_balance = ursula1_balance
|
||||
tx = testerchain.w3.eth.sendTransaction(
|
||||
{'from': testerchain.etherbase_account, 'to': ursula3, 'value': ursula3_balance})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Can't do anything before start date
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.bid().transact({'from': ursula1, 'value': minimum_deposit_eth, 'gas_price': 0})
|
||||
tx = worklock.functions.bid().transact({'from': ursula1, 'value': deposit_eth_1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.claim().transact({'from': ursula1, 'gas_price': 0})
|
||||
|
@ -119,99 +118,70 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow):
|
|||
tx = worklock.functions.refund().transact({'from': ursula1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.burnRemaining().transact({'from': ursula1, 'gas_price': 0})
|
||||
tx = worklock.functions.burnUnclaimed().transact({'from': ursula1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.cancelBid().transact({'from': ursula1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Wait for the start of bidding
|
||||
testerchain.time_travel(seconds=3600) # Wait exactly 1 hour
|
||||
|
||||
# Can't bid with too low or too high ETH
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.bid().transact({'from': ursula1, 'value': minimum_deposit_eth - 1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.bid().transact({'from': ursula1, 'value': maximum_deposit_eth + 1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Ursula does first bid
|
||||
assert worklock.functions.remainingTokens().call() == worklock_supply
|
||||
assert worklock.functions.workInfo(ursula1).call()[0] == 0
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == 0
|
||||
tx = worklock.functions.bid().transact({'from': ursula1, 'value': minimum_deposit_eth, 'gas_price': 0})
|
||||
tx = worklock.functions.bid().transact({'from': ursula1, 'value': deposit_eth_1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
remaining_tokens = worklock_supply - token_economics.minimum_allowed_locked
|
||||
assert worklock.functions.remainingTokens().call() == remaining_tokens
|
||||
assert worklock.functions.workInfo(ursula1).call()[0] == minimum_deposit_eth
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == minimum_deposit_eth
|
||||
assert worklock.functions.workInfo(ursula1).call()[0] == deposit_eth_1
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == deposit_eth_1
|
||||
assert worklock.functions.ethToTokens(deposit_eth_1).call() == worklock_supply
|
||||
|
||||
events = bidding_log.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert event_args['staker'] == ursula1
|
||||
assert event_args['depositedETH'] == minimum_deposit_eth
|
||||
assert event_args['claimedTokens'] == token_economics.minimum_allowed_locked
|
||||
assert event_args['depositedETH'] == deposit_eth_1
|
||||
|
||||
# Second Ursula does first bid
|
||||
assert worklock.functions.workInfo(ursula2).call()[0] == 0
|
||||
tx = worklock.functions.bid().transact({'from': ursula2, 'value': maximum_deposit_eth, 'gas_price': 0})
|
||||
tx = worklock.functions.bid().transact({'from': ursula2, 'value': deposit_eth_2, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
remaining_tokens -= token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.remainingTokens().call() == remaining_tokens
|
||||
assert worklock.functions.workInfo(ursula2).call()[0] == maximum_deposit_eth
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == maximum_deposit_eth + minimum_deposit_eth
|
||||
assert worklock.functions.workInfo(ursula2).call()[0] == deposit_eth_2
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == deposit_eth_1 + deposit_eth_2
|
||||
assert worklock.functions.ethToTokens(deposit_eth_2).call() == worklock_supply // 5
|
||||
|
||||
events = bidding_log.get_all_entries()
|
||||
assert 2 == len(events)
|
||||
event_args = events[1]['args']
|
||||
assert event_args['staker'] == ursula2
|
||||
assert event_args['depositedETH'] == maximum_deposit_eth
|
||||
assert event_args['claimedTokens'] == token_economics.maximum_allowed_locked
|
||||
assert event_args['depositedETH'] == deposit_eth_2
|
||||
|
||||
# Third Ursula does first bid
|
||||
assert worklock.functions.workInfo(ursula3).call()[0] == 0
|
||||
tx = worklock.functions.bid().transact({'from': ursula3, 'value': maximum_deposit_eth, 'gas_price': 0})
|
||||
tx = worklock.functions.bid().transact({'from': ursula3, 'value': deposit_eth_2, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
remaining_tokens -= token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.remainingTokens().call() == remaining_tokens
|
||||
assert worklock.functions.workInfo(ursula3).call()[0] == maximum_deposit_eth
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == 2 * maximum_deposit_eth + minimum_deposit_eth
|
||||
assert worklock.functions.workInfo(ursula3).call()[0] == deposit_eth_2
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == deposit_eth_1 + 2 * deposit_eth_2
|
||||
assert worklock.functions.ethToTokens(deposit_eth_2).call() == worklock_supply // 6
|
||||
|
||||
events = bidding_log.get_all_entries()
|
||||
assert 3 == len(events)
|
||||
event_args = events[2]['args']
|
||||
assert event_args['staker'] == ursula3
|
||||
assert event_args['depositedETH'] == maximum_deposit_eth
|
||||
assert event_args['claimedTokens'] == token_economics.maximum_allowed_locked
|
||||
|
||||
# Can't bid again with too high ETH
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.bid().transact(
|
||||
{'from': ursula1, 'value': maximum_deposit_eth-minimum_deposit_eth+1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.bid().transact({'from': ursula2, 'value': 1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert event_args['depositedETH'] == deposit_eth_2
|
||||
|
||||
# Ursula does second bid
|
||||
tx = worklock.functions.bid().transact({'from': ursula1, 'value': minimum_deposit_eth, 'gas_price': 0})
|
||||
tx = worklock.functions.bid().transact({'from': ursula1, 'value': deposit_eth_1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
remaining_tokens -= token_economics.minimum_allowed_locked
|
||||
assert worklock.functions.remainingTokens().call() == remaining_tokens
|
||||
assert worklock.functions.workInfo(ursula1).call()[0] == 2 * minimum_deposit_eth
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == 2 * maximum_deposit_eth + 2 * minimum_deposit_eth
|
||||
assert worklock.functions.workInfo(ursula1).call()[0] == 2 * deposit_eth_1
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == 2 * deposit_eth_1 + 2 * deposit_eth_2
|
||||
assert worklock.functions.ethToTokens(deposit_eth_2).call() == worklock_supply // 10
|
||||
|
||||
events = bidding_log.get_all_entries()
|
||||
assert 4 == len(events)
|
||||
event_args = events[3]['args']
|
||||
assert event_args['staker'] == ursula1
|
||||
assert event_args['depositedETH'] == minimum_deposit_eth
|
||||
assert event_args['claimedTokens'] == token_economics.minimum_allowed_locked
|
||||
|
||||
# Can't bid again: not enough tokens in worklock
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.bid().transact(
|
||||
{'from': ursula1, 'value': maximum_deposit_eth - 2 * minimum_deposit_eth, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert event_args['depositedETH'] == deposit_eth_1
|
||||
|
||||
# Can't claim, refund or burn while bidding phase
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
|
@ -221,91 +191,139 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow):
|
|||
tx = worklock.functions.refund().transact({'from': ursula1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.burnRemaining().transact({'from': ursula1, 'gas_price': 0})
|
||||
tx = worklock.functions.burnUnclaimed().transact({'from': ursula1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# But can cancel bid
|
||||
ursula3_balance = testerchain.w3.eth.getBalance(ursula3)
|
||||
tx = worklock.functions.cancelBid().transact({'from': ursula3, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.workInfo(ursula3).call()[0] == 0
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == 2 * deposit_eth_1 + deposit_eth_2
|
||||
assert worklock.functions.ethToTokens(deposit_eth_2).call() == worklock_supply // 9
|
||||
assert testerchain.w3.eth.getBalance(ursula3) == ursula3_balance + deposit_eth_2
|
||||
|
||||
events = canceling_log.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert event_args['staker'] == ursula3
|
||||
assert event_args['value'] == deposit_eth_2
|
||||
|
||||
# Can't cancel twice in a row
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.cancelBid().transact({'from': ursula3, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Third Ursula does second bid
|
||||
assert worklock.functions.workInfo(ursula3).call()[0] == 0
|
||||
tx = worklock.functions.bid().transact({'from': ursula3, 'value': deposit_eth_2, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.workInfo(ursula3).call()[0] == deposit_eth_2
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == 2 * deposit_eth_1 + 2 * deposit_eth_2
|
||||
assert worklock.functions.ethToTokens(deposit_eth_2).call() == worklock_supply // 10
|
||||
|
||||
events = bidding_log.get_all_entries()
|
||||
assert 5 == len(events)
|
||||
event_args = events[4]['args']
|
||||
assert event_args['staker'] == ursula3
|
||||
assert event_args['depositedETH'] == deposit_eth_2
|
||||
|
||||
# Wait for the end of bidding
|
||||
testerchain.time_travel(seconds=3600) # Wait exactly 1 hour
|
||||
|
||||
# Can't bid after the end of bidding
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.bid().transact({'from': ursula1, 'value': minimum_deposit_eth, 'gas_price': 0})
|
||||
tx = worklock.functions.bid().transact({'from': ursula1, 'value': deposit_eth_1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Can't refund without claim
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.refund().transact({'from': ursula1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Ursula claims tokens
|
||||
value, measure_work, _completed_work, periods = escrow.functions.stakerInfo(ursula1).call()
|
||||
assert value == 0
|
||||
_value, measure_work, _completed_work, _periods = escrow.functions.stakerInfo(ursula1).call()
|
||||
assert not measure_work
|
||||
assert periods == 0
|
||||
tx = worklock.functions.claim().transact({'from': ursula1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.getRemainingWork(ursula1).call() == 2 * minimum_deposit_eth * refund_rate
|
||||
value, measure_work, completed_work, periods = escrow.functions.stakerInfo(ursula1).call()
|
||||
assert value == 2 * token_economics.minimum_allowed_locked
|
||||
ursula1_tokens = 8 * worklock_supply // 10
|
||||
assert token.functions.balanceOf(ursula1).call() == ursula1_tokens
|
||||
ursula1_remaining_work = int(-(-8 * worklock_supply * slowing_refund // (boosting_refund * 10))) # div ceil
|
||||
assert worklock.functions.ethToWork(2 * deposit_eth_1).call() == ursula1_remaining_work
|
||||
assert worklock.functions.workToETH(ursula1_remaining_work).call() == 2 * deposit_eth_1
|
||||
assert worklock.functions.getRemainingWork(ursula1).call() == ursula1_remaining_work
|
||||
assert token.functions.balanceOf(worklock.address).call() == worklock_supply - ursula1_tokens
|
||||
_value, measure_work, _completed_work, _periods = escrow.functions.stakerInfo(ursula1).call()
|
||||
assert measure_work
|
||||
assert periods == 2 * token_economics.minimum_locked_periods
|
||||
assert token.functions.balanceOf(worklock.address).call() == \
|
||||
worklock_supply - 2 * token_economics.minimum_allowed_locked
|
||||
assert token.functions.balanceOf(escrow.address).call() == 2 * token_economics.minimum_allowed_locked
|
||||
|
||||
events = claim_log.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert event_args['staker'] == ursula1
|
||||
assert event_args['claimedTokens'] == 2 * token_economics.minimum_allowed_locked
|
||||
assert event_args['claimedTokens'] == ursula1_tokens
|
||||
|
||||
# Can't claim more than once
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.claim().transact({'from': ursula1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Can't refund without work
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.refund().transact({'from': ursula1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
# Can't cancel after claim
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.cancelBid().transact({'from': ursula1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# One of Ursulas cancel bid
|
||||
ursula3_balance = testerchain.w3.eth.getBalance(ursula3)
|
||||
ursula3_tokens = worklock_supply // 10
|
||||
assert worklock.functions.ethToTokens(deposit_eth_2).call() == ursula3_tokens
|
||||
tx = worklock.functions.cancelBid().transact({'from': ursula3, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.ethToTokens(deposit_eth_2).call() == ursula3_tokens
|
||||
assert worklock.functions.workInfo(ursula3).call()[0] == 0
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == 2 * deposit_eth_1 + deposit_eth_2
|
||||
assert testerchain.w3.eth.getBalance(ursula3) == ursula3_balance + deposit_eth_2
|
||||
assert worklock.functions.unclaimedTokens().call() == ursula3_tokens
|
||||
assert token.functions.balanceOf(worklock.address).call() == worklock_supply - ursula1_tokens
|
||||
|
||||
# Second Ursula claims tokens
|
||||
value, measure_work, _completed_work, periods = escrow.functions.stakerInfo(ursula2).call()
|
||||
assert value == 0
|
||||
_value, measure_work, _completed_work, _periods = escrow.functions.stakerInfo(ursula2).call()
|
||||
assert not measure_work
|
||||
assert periods == 0
|
||||
tx = escrow.functions.setCompletedWork(ursula2, refund_rate * minimum_deposit_eth).transact()
|
||||
ursula2_tokens = ursula3_tokens
|
||||
# ursula2_tokens * slowing_refund / boosting_refund
|
||||
ursula2_remaining_work = int(-(-worklock_supply * slowing_refund // (boosting_refund * 10))) # div ceil
|
||||
assert worklock.functions.ethToWork(deposit_eth_2).call() == ursula2_remaining_work
|
||||
assert worklock.functions.workToETH(ursula2_remaining_work).call() == deposit_eth_2
|
||||
tx = escrow.functions.setCompletedWork(ursula2, ursula2_remaining_work // 2).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = worklock.functions.claim().transact({'from': ursula2, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.getRemainingWork(ursula2).call() == maximum_deposit_eth * refund_rate
|
||||
value, measure_work, completed_work, periods = escrow.functions.stakerInfo(ursula2).call()
|
||||
assert value == token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.getRemainingWork(ursula2).call() == ursula2_remaining_work
|
||||
assert token.functions.balanceOf(worklock.address).call() == worklock_supply - ursula1_tokens - ursula2_tokens
|
||||
assert token.functions.balanceOf(ursula2).call() == ursula2_tokens
|
||||
_value, measure_work, _completed_work, _periods = escrow.functions.stakerInfo(ursula2).call()
|
||||
assert measure_work
|
||||
assert periods == 2 * token_economics.minimum_locked_periods
|
||||
assert token.functions.balanceOf(worklock.address).call() == \
|
||||
remaining_tokens + token_economics.maximum_allowed_locked
|
||||
assert token.functions.balanceOf(escrow.address).call() == \
|
||||
2 * token_economics.minimum_allowed_locked + token_economics.maximum_allowed_locked
|
||||
|
||||
events = claim_log.get_all_entries()
|
||||
assert 2 == len(events)
|
||||
event_args = events[1]['args']
|
||||
assert event_args['staker'] == ursula2
|
||||
assert event_args['claimedTokens'] == token_economics.maximum_allowed_locked
|
||||
assert event_args['claimedTokens'] == ursula2_tokens
|
||||
|
||||
# "Do" some work and partial refund
|
||||
ursula1_balance = testerchain.w3.eth.getBalance(ursula1)
|
||||
completed_work = refund_rate * minimum_deposit_eth + refund_rate // 2
|
||||
completed_work = ursula1_remaining_work // 2 + 1
|
||||
remaining_work = ursula1_remaining_work - completed_work
|
||||
tx = escrow.functions.setCompletedWork(ursula1, completed_work).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.getRemainingWork(ursula1).call() == minimum_deposit_eth * refund_rate - refund_rate // 2
|
||||
assert worklock.functions.getRemainingWork(ursula1).call() == remaining_work
|
||||
tx = worklock.functions.refund().transact({'from': ursula1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.workInfo(ursula1).call()[0] == minimum_deposit_eth
|
||||
assert worklock.functions.getRemainingWork(ursula1).call() == minimum_deposit_eth * refund_rate - refund_rate // 2
|
||||
assert testerchain.w3.eth.getBalance(ursula1) == ursula1_balance + minimum_deposit_eth
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == 2 * maximum_deposit_eth + minimum_deposit_eth
|
||||
assert worklock.functions.workInfo(ursula1).call()[0] == deposit_eth_1
|
||||
assert worklock.functions.getRemainingWork(ursula1).call() == remaining_work
|
||||
assert testerchain.w3.eth.getBalance(ursula1) == ursula1_balance + deposit_eth_1
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == deposit_eth_1 + deposit_eth_2
|
||||
_value, measure_work, _completed_work, _periods = escrow.functions.stakerInfo(ursula1).call()
|
||||
assert measure_work
|
||||
|
||||
|
@ -313,12 +331,12 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow):
|
|||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert event_args['staker'] == ursula1
|
||||
assert event_args['refundETH'] == minimum_deposit_eth
|
||||
assert event_args['completedWork'] == minimum_deposit_eth * refund_rate
|
||||
assert event_args['refundETH'] == deposit_eth_1
|
||||
assert event_args['completedWork'] == ursula1_remaining_work // 2
|
||||
|
||||
# "Do" more work and full refund
|
||||
ursula1_balance = testerchain.w3.eth.getBalance(ursula1)
|
||||
completed_work = refund_rate * 2 * minimum_deposit_eth
|
||||
completed_work = ursula1_remaining_work
|
||||
tx = escrow.functions.setCompletedWork(ursula1, completed_work).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.getRemainingWork(ursula1).call() == 0
|
||||
|
@ -326,8 +344,8 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow):
|
|||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.workInfo(ursula1).call()[0] == 0
|
||||
assert worklock.functions.getRemainingWork(ursula1).call() == 0
|
||||
assert testerchain.w3.eth.getBalance(ursula1) == ursula1_balance + minimum_deposit_eth
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == 2 * maximum_deposit_eth
|
||||
assert testerchain.w3.eth.getBalance(ursula1) == ursula1_balance + deposit_eth_1
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == deposit_eth_2
|
||||
_value, measure_work, _completed_work, _periods = escrow.functions.stakerInfo(ursula1).call()
|
||||
assert not measure_work
|
||||
|
||||
|
@ -335,8 +353,8 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow):
|
|||
assert 2 == len(events)
|
||||
event_args = events[1]['args']
|
||||
assert event_args['staker'] == ursula1
|
||||
assert event_args['refundETH'] == minimum_deposit_eth
|
||||
assert event_args['completedWork'] == minimum_deposit_eth * refund_rate
|
||||
assert event_args['refundETH'] == deposit_eth_1
|
||||
assert event_args['completedWork'] == ursula1_remaining_work // 2
|
||||
|
||||
# Can't refund more tokens
|
||||
tx = escrow.functions.setCompletedWork(ursula1, 2 * completed_work).transact()
|
||||
|
@ -346,23 +364,23 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow):
|
|||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Now burn remaining tokens
|
||||
assert worklock.functions.remainingTokens().call() == remaining_tokens
|
||||
tx = worklock.functions.burnRemaining().transact({'from': ursula1, 'gas_price': 0})
|
||||
assert worklock.functions.unclaimedTokens().call() == ursula3_tokens
|
||||
tx = worklock.functions.burnUnclaimed().transact({'from': ursula1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.remainingTokens().call() == 0
|
||||
assert token.functions.balanceOf(worklock.address).call() == token_economics.maximum_allowed_locked
|
||||
assert token.functions.balanceOf(escrow.address).call() == worklock_supply - token_economics.maximum_allowed_locked
|
||||
assert worklock.functions.unclaimedTokens().call() == 0
|
||||
assert token.functions.balanceOf(worklock.address).call() == 0
|
||||
assert token.functions.balanceOf(escrow.address).call() == ursula3_tokens
|
||||
|
||||
# Can't burn twice
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.burnRemaining().transact({'from': ursula1, 'gas_price': 0})
|
||||
tx = worklock.functions.burnUnclaimed().transact({'from': ursula1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
events = burning_log.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert event_args['sender'] == ursula1
|
||||
assert event_args['value'] == remaining_tokens
|
||||
assert event_args['value'] == ursula3_tokens
|
||||
|
||||
|
||||
@pytest.mark.slow
|
||||
|
|
Loading…
Reference in New Issue