Withdraw unspent bid amount as part of claiming and remove it as independent command

pull/1784/head
David Núñez 2020-03-22 13:28:13 +01:00
parent ee7902cdae
commit 2d2be8f5b3
2 changed files with 60 additions and 64 deletions

View File

@ -212,14 +212,32 @@ def claim(general_config, worklock_options, registry_options, force, hw_wallet):
registry=registry,
show_balances=True)
# TODO: Show amount of tokens to claim
bidder = worklock_options.create_bidder(registry=registry, hw_wallet=hw_wallet)
unspent_bid = bidder.available_compensation
if unspent_bid:
emitter.echo(f"Before claiming your tokens, note that WorkLock didn't use your bid completely.\n"
f"An unspent amount of {prettify_eth_amount(unspent_bid)} is available for refund.")
if not force:
click.confirm(f"Collect unspent bid amount for bidder {worklock_options.bidder_address}?", abort=True)
emitter.echo("Requesting refund of unspent bid amount...")
receipt = bidder.withdraw_compensation()
paint_receipt_summary(receipt=receipt, emitter=emitter, chain_name=bidder.staking_agent.blockchain.client.chain_name)
has_claimed = bidder._has_claimed
if has_claimed:
emitter.echo("Claimed was already done", color='red')
return
tokens = NU.from_nunits(bidder.available_claim)
emitter.echo(f"\nYou have an available claim of {tokens} 🎉 \n", color='green', bold=True)
if not force:
emitter.echo("Note: Claiming WorkLock NU tokens will initialize a new stake.", color='blue')
click.confirm(f"Continue worklock claim for bidder {worklock_options.bidder_address}?", abort=True)
lock_duration = bidder.worklock_agent.worklock_parameters()[-2]
emitter.echo(f"Note: Claiming WorkLock NU tokens will initialize a new stake during {lock_duration} periods.",
color='blue')
click.confirm(f"Continue WorkLock claim for bidder {worklock_options.bidder_address}?", abort=True)
emitter.echo("Submitting Claim...")
bidder = worklock_options.create_bidder(registry=registry, hw_wallet=hw_wallet)
receipt = bidder.claim()
paint_receipt_summary(receipt=receipt, emitter=emitter, chain_name=bidder.staking_agent.blockchain.client.chain_name)
paint_worklock_claim(emitter=emitter,
@ -342,30 +360,3 @@ def enable_claiming(general_config, registry_options, worklock_options, force, h
return # Exit
@worklock.command()
@option_force
@option_hw_wallet
@group_registry_options
@group_worklock_options
@group_general_config
def withdraw_compensation(general_config, worklock_options, registry_options, force, hw_wallet):
"""Reclaim ETH that wasn't locked by WorkLock"""
emitter = _setup_emitter(general_config)
registry = registry_options.get_registry(emitter, general_config.debug)
if not worklock_options.bidder_address:
worklock_options.bidder_address = select_client_account(emitter=emitter,
provider_uri=registry_options.provider_uri,
poa=registry_options.poa,
network=registry_options.network,
registry=registry,
show_balances=True)
bidder = worklock_options.create_bidder(registry=registry, hw_wallet=hw_wallet)
if not force:
value = bidder.available_compensation
click.confirm(f"Collect {prettify_eth_amount(value)} compensation for bidder {worklock_options.bidder_address}?", abort=True)
emitter.echo("Submitting WorkLock compensation request...")
receipt = bidder.withdraw_compensation()
paint_receipt_summary(receipt=receipt, emitter=emitter, chain_name=bidder.staking_agent.blockchain.client.chain_name)
return # Exit

View File

@ -16,6 +16,7 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
import random
import pytest
from eth_utils import to_wei
from web3 import Web3
@ -35,6 +36,21 @@ from nucypher.utilities.sandbox.constants import (
)
@pytest.fixture(scope='module')
def bids(testerchain):
bids_distribution = dict()
min_bid_eth_value = 1
max_bid_eth_value = 10
whale = testerchain.client.accounts[0]
bids_distribution[whale] = 50_000
for bidder in testerchain.client.accounts[1:12]:
bids_distribution[bidder] = random.randrange(min_bid_eth_value, max_bid_eth_value)
return bids_distribution
def test_status(click_runner, testerchain, agency_local_registry, token_economics):
command = ('status',
'--registry-filepath', agency_local_registry.filepath,
@ -48,14 +64,11 @@ def test_status(click_runner, testerchain, agency_local_registry, token_economic
assert f"Min allowed bid ....... {Web3.fromWei(token_economics.worklock_min_allowed_bid, 'ether')} ETH" in result.output
def test_bid(click_runner, testerchain, agency_local_registry, token_economics):
def test_bid(click_runner, testerchain, agency_local_registry, token_economics, bids):
# Wait until biding window starts
testerchain.time_travel(seconds=90)
min_bid_eth_value = 4
max_bid_eth_value = 10
base_command = ('bid',
'--registry-filepath', agency_local_registry.filepath,
'--provider', TEST_PROVIDER_URI,
@ -65,8 +78,7 @@ def test_bid(click_runner, testerchain, agency_local_registry, token_economics):
worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=agency_local_registry)
total_bids = 0
# Multiple bidders
for bidder in testerchain.client.accounts[:12]:
bid_eth_value = random.randrange(min_bid_eth_value, max_bid_eth_value)
for bidder, bid_eth_value in bids.items():
pre_bid_balance = testerchain.client.get_balance(bidder)
assert pre_bid_balance > to_wei(bid_eth_value, 'ether')
@ -83,9 +95,11 @@ def test_bid(click_runner, testerchain, agency_local_registry, token_economics):
assert testerchain.client.get_balance(worklock_agent.contract_address) == total_bids
def test_cancel_bid(click_runner, testerchain, agency_local_registry, token_economics):
def test_cancel_bid(click_runner, testerchain, agency_local_registry, token_economics, bids):
bidder = testerchain.client.accounts[0]
bidders = list(bids.keys())
bidder = bidders[-1]
agent = ContractAgency.get_agent(WorkLockAgent, registry=agency_local_registry)
command = ('cancel-bid',
@ -103,7 +117,7 @@ def test_cancel_bid(click_runner, testerchain, agency_local_registry, token_econ
# Wait until the end of the bidding period
testerchain.time_travel(seconds=token_economics.bidding_duration + 2)
bidder = testerchain.client.accounts[1]
bidder = bidders[-2]
command = ('cancel-bid',
'--bidder-address', bidder,
'--registry-filepath', agency_local_registry.filepath,
@ -142,29 +156,8 @@ def test_post_initialization(click_runner, testerchain, agency_local_registry, t
assert agent.bidders_checked()
def test_withdraw_compensation(click_runner, testerchain, agency_local_registry, token_economics):
agent = ContractAgency.get_agent(WorkLockAgent, registry=agency_local_registry)
bidder = None
for address in testerchain.client.accounts[2:12]:
if agent.get_available_compensation(checksum_address=address) > 0:
bidder = address
break
command = ('withdraw-compensation',
'--bidder-address', bidder,
'--registry-filepath', agency_local_registry.filepath,
'--provider', TEST_PROVIDER_URI,
'--poa',
'--force')
user_input = f'{INSECURE_DEVELOPMENT_PASSWORD}\n' + 'Y\n'
result = click_runner.invoke(worklock, command, input=user_input, catch_exceptions=False)
assert result.exit_code == 0
assert agent.get_available_compensation(checksum_address=bidder) == 0
def test_claim(click_runner, testerchain, agency_local_registry, token_economics):
agent = ContractAgency.get_agent(WorkLockAgent, registry=agency_local_registry)
bidder = testerchain.client.accounts[2]
command = ('claim',
@ -178,6 +171,20 @@ def test_claim(click_runner, testerchain, agency_local_registry, token_economics
result = click_runner.invoke(worklock, command, input=user_input, catch_exceptions=False)
assert result.exit_code == 0
whale = testerchain.client.accounts[0]
assert agent.get_available_compensation(checksum_address=whale) > 0
command = ('claim',
'--bidder-address', whale,
'--registry-filepath', agency_local_registry.filepath,
'--provider', TEST_PROVIDER_URI,
'--poa',
'--force')
user_input = f'{INSECURE_DEVELOPMENT_PASSWORD}\n' + 'Y\n'
result = click_runner.invoke(worklock, command, input=user_input, catch_exceptions=False)
assert result.exit_code == 0
assert agent.get_available_compensation(checksum_address=whale) == 0
# TODO: Check successful new stake in StakingEscrow
@ -264,8 +271,6 @@ def test_participant_status(click_runner, testerchain, agency_local_registry, to
result = click_runner.invoke(worklock, command, catch_exceptions=False)
assert result.exit_code == 0
worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=agency_local_registry)
# Bidder-specific data is displayed
assert bidder.checksum_address in result.output
assert str(bidder.remaining_work) in result.output