Fix getRemainingWork in worklock, worklock in intercontract test

pull/960/head
szotov 2019-05-24 16:11:04 +03:00
parent 75865a2388
commit 7c2e08872d
3 changed files with 124 additions and 30 deletions

View File

@ -136,7 +136,12 @@ contract WorkLock {
**/
function getRemainingWork(address _miner) public view returns (uint256) {
WorkInfo storage info = workInfo[_miner];
return info.depositedETH.mul(refundRate);
uint256 workDone = escrow.getWorkDone(_miner).sub(info.workDone);
uint256 remainingWork = info.depositedETH.mul(refundRate);
if (remainingWork <= workDone) {
return 0;
}
return remainingWork.sub(workDone);
}
}

View File

@ -132,6 +132,34 @@ def adjudicator(testerchain, escrow, slashing_economics):
return contract, dispatcher
@pytest.fixture()
def worklock(testerchain, token, escrow):
escrow, _ = escrow
creator = testerchain.interface.w3.eth.accounts[0]
# Creator deploys the worklock using test values
now = testerchain.interface.w3.eth.getBlock(block_identifier='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
deposit_rate = 2
refund_rate = deposit_rate
contract, _ = testerchain.interface.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=9
)
tx = escrow.functions.setWorkLock(contract.address).transact({'from': creator})
testerchain.wait_for_receipt(tx)
return contract
def mock_ursula(testerchain, account):
ursula_privkey = UmbralPrivateKey.gen_key()
ursula_stamp = SignatureStamp(verifying_key=ursula_privkey.pubkey,
@ -219,6 +247,7 @@ def test_all(testerchain,
escrow,
policy_manager,
adjudicator,
worklock,
user_escrow_proxy,
multisig,
slashing_economics,
@ -247,6 +276,9 @@ def test_all(testerchain,
tx = testerchain.client.send_transaction(
{'from': testerchain.client.coinbase, 'to': alice2, 'value': 10 ** 10})
testerchain.wait_for_receipt(tx)
tx = testerchain.interface.w3.eth.sendTransaction(
{'from': testerchain.interface.w3.eth.coinbase, 'to': ursula2, 'value': 10 ** 10})
testerchain.wait_for_receipt(tx)
# Give Ursula and Alice some coins
tx = token.functions.transfer(ursula1, 10000).transact({'from': creator})
@ -277,6 +309,74 @@ def test_all(testerchain,
tx = escrow.functions.initialize().buildTransaction({'from': multisig.address, 'gasPrice': 0})
execute_multisig_transaction(testerchain, multisig, [contracts_owners[0], contracts_owners[1]], tx)
# Initialize worklock
initial_supply = 1000
tx = token.functions.transfer(worklock.address, initial_supply).transact({'from': creator})
testerchain.wait_for_receipt(tx)
# Can't do anything before start date
deposit_rate = 2
refund_rate = 2
deposited_eth = 1000 // deposit_rate
with pytest.raises((TransactionFailed, ValueError)):
tx = worklock.functions.bid().transact({'from': ursula2, 'value': deposited_eth, 'gas_price': 0})
testerchain.wait_for_receipt(tx)
# Wait for the start of the bidding
testerchain.time_travel(hours=1)
# Can't bid with too low or too high ETH
with pytest.raises((TransactionFailed, ValueError)):
tx = worklock.functions.bid().transact({'from': ursula2, 'value': 1, 'gas_price': 0})
testerchain.wait_for_receipt(tx)
with pytest.raises((TransactionFailed, ValueError)):
tx = worklock.functions.bid().transact({'from': ursula2, 'value': 10**10, 'gas_price': 0})
testerchain.wait_for_receipt(tx)
# Ursula does bid
assert worklock.functions.allClaimedTokens().call() == 0
assert worklock.functions.workInfo(ursula2).call()[0] == 0
assert testerchain.interface.w3.eth.getBalance(worklock.address) == 0
tx = worklock.functions.bid().transact({'from': ursula2, 'value': deposited_eth, 'gas_price': 0})
testerchain.wait_for_receipt(tx)
assert worklock.functions.allClaimedTokens().call() == 1000
assert worklock.functions.workInfo(ursula2).call()[0] == deposited_eth
assert testerchain.interface.w3.eth.getBalance(worklock.address) == deposited_eth
# Can't claim while bidding phase
with pytest.raises((TransactionFailed, ValueError)):
tx = worklock.functions.claim().transact({'from': ursula2, 'gas_price': 0})
testerchain.wait_for_receipt(tx)
# Wait for the end of the bidding
testerchain.time_travel(hours=1)
# Can't bid after the enf of bidding
with pytest.raises((TransactionFailed, ValueError)):
tx = worklock.functions.bid().transact({'from': ursula2, 'value': 1, 'gas_price': 0})
testerchain.wait_for_receipt(tx)
# Ursula claims tokens
tx = worklock.functions.claim().transact({'from': ursula2, 'gas_price': 0})
testerchain.wait_for_receipt(tx)
assert worklock.functions.getRemainingWork(ursula2).call() == deposit_rate * deposited_eth
assert reward + 1000 == token.functions.balanceOf(escrow.address).call()
assert 1000 == escrow.functions.getAllTokens(ursula2).call()
assert 0 == escrow.functions.getLockedTokens(ursula2).call()
assert 1000 == escrow.functions.getLockedTokens(ursula2, 1).call()
assert 1000 == escrow.functions.getLockedTokens(ursula2, 9).call()
assert 0 == escrow.functions.getLockedTokens(ursula2, 10).call()
assert 0 == escrow.functions.getWorkDone(ursula2).call()
# Can't claim more than once
with pytest.raises((TransactionFailed, ValueError)):
tx = worklock.functions.claim().transact({'from': ursula2, 'gas_price': 0})
testerchain.wait_for_receipt(tx)
# Can't refund without work
with pytest.raises((TransactionFailed, ValueError)):
tx = worklock.functions.refund().transact({'from': ursula2, 'gas_price': 0})
testerchain.wait_for_receipt(tx)
# Create the first user escrow, set and lock re-stake parameter
user_escrow_1, _ = testerchain.deploy_contract(
'UserEscrow', user_escrow_linker.address, token.address)
@ -354,34 +454,6 @@ def test_all(testerchain,
tx = token.functions.approve(escrow.address, 10000).transact({'from': creator})
testerchain.wait_for_receipt(tx)
# Deposit tokens for 1 owner
tx = escrow.functions.preDeposit([ursula2], [1000], [9]).transact({'from': creator})
testerchain.wait_for_receipt(tx)
tx = escrow.functions.setWorker(ursula2).transact({'from': ursula2})
testerchain.wait_for_receipt(tx)
assert reward + 1000 == token.functions.balanceOf(escrow.address).call()
assert 1000 == escrow.functions.getAllTokens(ursula2).call()
assert 0 == escrow.functions.getLockedTokens(ursula2).call()
assert 1000 == escrow.functions.getLockedTokens(ursula2, 1).call()
assert 1000 == escrow.functions.getLockedTokens(ursula2, 9).call()
assert 0 == escrow.functions.getLockedTokens(ursula2, 10).call()
# Can't pre-deposit tokens again for the same owner
with pytest.raises((TransactionFailed, ValueError)):
tx = escrow.functions.preDeposit([ursula2], [1000], [9]).transact({'from': creator})
testerchain.wait_for_receipt(tx)
# Can't pre-deposit tokens with too low or too high value
with pytest.raises((TransactionFailed, ValueError)):
tx = escrow.functions.preDeposit([ursula3], [1], [10]).transact({'from': creator})
testerchain.wait_for_receipt(tx)
with pytest.raises((TransactionFailed, ValueError)):
tx = escrow.functions.preDeposit([ursula3], [10 ** 6], [10]).transact({'from': creator})
testerchain.wait_for_receipt(tx)
with pytest.raises((TransactionFailed, ValueError)):
tx = escrow.functions.preDeposit([ursula3], [500], [1]).transact({'from': creator})
testerchain.wait_for_receipt(tx)
# Ursula transfer some tokens to the escrow and lock them
tx = escrow.functions.deposit(1000, 10).transact({'from': ursula1})
testerchain.wait_for_receipt(tx)
@ -970,3 +1042,18 @@ def test_all(testerchain,
testerchain.wait_for_receipt(tx)
assert ursula3_balance < token.functions.balanceOf(ursula3).call()
assert ursula4_balance < token.functions.balanceOf(ursula4).call()
# Partial refund for Ursula
work_done = escrow.functions.getWorkDone(ursula2).call()
remaining_work = worklock.functions.getRemainingWork(ursula2).call()
assert 0 < remaining_work
assert 0 < work_done
ursula2_balance = testerchain.interface.w3.eth.getBalance(ursula2)
tx = worklock.functions.refund().transact({'from': ursula2, 'gas_price': 0})
testerchain.wait_for_receipt(tx)
refund = work_done // refund_rate
assert refund + ursula2_balance == testerchain.interface.w3.eth.getBalance(ursula2)
assert remaining_work - work_done == worklock.functions.getRemainingWork(ursula2).call()
assert deposited_eth - refund == testerchain.interface.w3.eth.getBalance(worklock.address)
assert 0 == escrow.functions.getWorkDone(ursula1).call()
assert 0 == escrow.functions.getWorkDone(user_escrow_1.address).call()

View File

@ -247,10 +247,11 @@ def test_worklock(testerchain, token_economics):
work_done = refund_rate * minimum_deposit_eth + refund_rate // 2
tx = escrow.functions.setWorkDone(ursula1, work_done).transact()
testerchain.wait_for_receipt(tx)
assert worklock.functions.getRemainingWork(ursula1).call() == minimum_deposit_eth * refund_rate - refund_rate // 2
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
assert worklock.functions.getRemainingWork(ursula1).call() == minimum_deposit_eth * refund_rate - refund_rate // 2
assert testerchain.interface.w3.eth.getBalance(ursula1) == ursula1_balance + minimum_deposit_eth
assert testerchain.interface.w3.eth.getBalance(worklock.address) == maximum_deposit_eth + minimum_deposit_eth
_value, measure_work, _work_done, _periods = escrow.functions.minerInfo(ursula1).call()
@ -268,6 +269,7 @@ def test_worklock(testerchain, token_economics):
work_done = refund_rate * 2 * minimum_deposit_eth
tx = escrow.functions.setWorkDone(ursula1, work_done).transact()
testerchain.wait_for_receipt(tx)
assert worklock.functions.getRemainingWork(ursula1).call() == 0
tx = worklock.functions.refund().transact({'from': ursula1, 'gas_price': 0})
testerchain.wait_for_receipt(tx)
assert worklock.functions.workInfo(ursula1).call()[0] == 0