diff --git a/nucypher/blockchain/eth/actors.py b/nucypher/blockchain/eth/actors.py index 555dac2dc..c64497bed 100644 --- a/nucypher/blockchain/eth/actors.py +++ b/nucypher/blockchain/eth/actors.py @@ -1396,7 +1396,7 @@ class Bidder(NucypherTokenActor): self.staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=self.registry) self.economics = EconomicsFactory.get_economics(registry=self.registry) - def _ensure_bidding_is_open(self): + def _ensure_bidding_is_open(self) -> None: highest_block = self.worklock_agent.blockchain.w3.eth.getBlock('latest') now = highest_block['timestamp'] start = self.worklock_agent.start_date @@ -1406,7 +1406,7 @@ class Bidder(NucypherTokenActor): if now > end: raise self.BiddingIsClosed(f'Bidding closed at {maya.MayaDT(end).slang_date()}') - def _ensure_bidding_is_closed(self, message: str = None): + def _ensure_bidding_is_closed(self, message: str = None) -> None: highest_block = self.worklock_agent.blockchain.w3.eth.getBlock('latest') now = highest_block['timestamp'] end = self.worklock_agent.end_date @@ -1419,7 +1419,6 @@ class Bidder(NucypherTokenActor): # def place_bid(self, value: int) -> dict: - # wei_bid = Web3.toWei(value, 'wei') # TODO: Consider default denomination on this layer self._ensure_bidding_is_open() receipt = self.worklock_agent.bid(checksum_address=self.checksum_address, value=value) return receipt @@ -1436,7 +1435,7 @@ class Bidder(NucypherTokenActor): raise self.BidderError(f"Bidder {self.checksum_address} already placed a claim.") # Require an active bid - if not self.current_bid: + if not self.get_deposited_eth: raise self.BidderError(f"No claims available for {self.checksum_address}") # Ensure the claim is at least large enough for min. stake @@ -1450,20 +1449,20 @@ class Bidder(NucypherTokenActor): def cancel_bid(self) -> dict: # Require an active bid - if not self.current_bid: + if not self.get_deposited_eth: self.BidderError(f"No bids available for {self.checksum_address}") # Ensure the claim was not already placed if self._has_claimed: - raise self.BidderError(f"Bidder {self.checksum_address} already claimed reward.") + raise self.BidderError(f"Bidder {self.checksum_address} already placed a claim.") receipt = self.worklock_agent.cancel_bid(checksum_address=self.checksum_address) return receipt - def refund_deposit(self): + def refund_deposit(self) -> dict: """Refund ethers for completed work""" - if self._has_claimed: - raise self.BidderError(f"Bidder {self.checksum_address} already claimed reward.") + if not self.available_refund: + raise self.BidderError(f'There is no refund available for {self.checksum_address}') receipt = self.worklock_agent.refund(checksum_address=self.checksum_address) return receipt @@ -1472,9 +1471,9 @@ class Bidder(NucypherTokenActor): # @property - def current_bid(self, denomination: str = 'wei') -> int: - bid = self.worklock_agent.get_bid(checksum_address=self.checksum_address) - ether_bid = Web3.toWei(bid, denomination) # TODO: Consider ether as the default denomination on this layer + def get_deposited_eth(self, denomination: str = 'wei') -> int: + bid = self.worklock_agent.get_deposited_eth(checksum_address=self.checksum_address) + ether_bid = Web3.toWei(bid, denomination) return ether_bid @property @@ -1492,7 +1491,7 @@ class Bidder(NucypherTokenActor): def remaining_work(self) -> int: try: work = self.worklock_agent.get_remaining_work(checksum_address=self.checksum_address) - except (TransactionFailed, ValueError): + except (TransactionFailed, ValueError): # TODO: Is his how we want to handle thid? work = 0 return work @@ -1504,9 +1503,13 @@ class Bidder(NucypherTokenActor): @property def available_refund(self) -> int: refund_eth = self.worklock_agent.get_available_refund(completed_work=self.completed_work) + bid = self.get_deposited_eth + if refund_eth > bid: + # Overachiever: This bidder has worked more than required. + refund_eth = bid return refund_eth @property def available_claim(self) -> int: - tokens = self.worklock_agent.eth_to_tokens(self.current_bid) + tokens = self.worklock_agent.eth_to_tokens(self.get_deposited_eth) return tokens diff --git a/nucypher/blockchain/eth/agents.py b/nucypher/blockchain/eth/agents.py index a1e4639d3..e93cbef57 100644 --- a/nucypher/blockchain/eth/agents.py +++ b/nucypher/blockchain/eth/agents.py @@ -1028,7 +1028,7 @@ class WorkLockAgent(EthereumContractAgent): # @validate_checksum_address - def get_bid(self, checksum_address: str) -> int: + def get_deposited_eth(self, checksum_address: str) -> int: current_bid = self.contract.functions.workInfo(checksum_address).call()[0] return current_bid @@ -1048,7 +1048,7 @@ class WorkLockAgent(EthereumContractAgent): return result def get_eth_supply(self) -> int: - supply = self.blockchain.client.get_balance(self.contract_address) + supply = self.contract.functions.ethSupply().call() return supply def get_refund_rate(self) -> int: diff --git a/nucypher/cli/commands/worklock.py b/nucypher/cli/commands/worklock.py index efe2b8ebf..a74e83407 100644 --- a/nucypher/cli/commands/worklock.py +++ b/nucypher/cli/commands/worklock.py @@ -123,7 +123,7 @@ def bid(general_config, worklock_options, registry_options, force, value): f"(Total must be worth at least {NU.from_nunits(minimum)})" emitter.echo(warning, color='yellow') else: - message = f'Current bid: {bidder.current_bid} | ' \ + message = f'Current bid: {bidder.get_deposited_eth} | ' \ f'Available Claim: {bidder.available_claim} |' \ f'Note that available claim value may fluctuate ' \ f'until bidding closes and claims are finalized.' @@ -146,7 +146,7 @@ def cancel_bid(general_config, registry_options, worklock_options, force): registry = registry_options.get_registry(emitter, general_config.debug) bidder = worklock_options.create_bidder(registry=registry) if not force: - value = bidder.current_bid + value = bidder.get_deposited_eth click.confirm(f"Confirm bid cancellation of {Web3.fromWei(value, 'ether')} ETH" f" for {worklock_options.bidder_address}?", abort=True) receipt = bidder.cancel_bid() diff --git a/nucypher/cli/painting.py b/nucypher/cli/painting.py index 476a345d4..4392ffb53 100644 --- a/nucypher/cli/painting.py +++ b/nucypher/cli/painting.py @@ -756,6 +756,8 @@ Time Remaining .... {remaining} Economics ====================================================== ETH Pool .......... {blockchain.client.get_balance(worklock_agent.contract_address)} +ETH Supply ........ {worklock_agent.get_eth_supply()} + Lot Size .......... {NU.from_nunits(worklock_agent.lot_value)} Unclaimed Tokens .. {worklock_agent.get_unclaimed_tokens()} @@ -772,7 +774,7 @@ def paint_bidder_status(emitter, bidder): message = f""" WorkLock Participant {bidder.checksum_address} ===================================================== -Total Bid ............ {bidder.current_bid} +Total Bid ............ {bidder.get_deposited_eth} Available Refund ..... {bidder.available_refund} Completed Work ....... {bidder.completed_work} Remaining Work ....... {bidder.remaining_work} diff --git a/tests/blockchain/eth/entities/actors/test_bidder.py b/tests/blockchain/eth/entities/actors/test_bidder.py index 74bc3fae3..59b0e4bcf 100644 --- a/tests/blockchain/eth/entities/actors/test_bidder.py +++ b/tests/blockchain/eth/entities/actors/test_bidder.py @@ -12,7 +12,7 @@ def test_create_bidder(testerchain, test_registry, agency, token_economics): assert bidder.checksum_address == bidder_address assert bidder.registry == test_registry - assert not bidder.current_bid + assert not bidder.get_deposited_eth assert not bidder.completed_work assert not bidder.remaining_work assert not bidder.refunded_work @@ -23,27 +23,27 @@ def test_bidding(testerchain, agency, token_economics, test_registry): big_bid = token_economics.maximum_allowed_locked // 100 bidder = Bidder(checksum_address=bidder_address, registry=test_registry) - assert bidder.current_bid == 0 + assert bidder.get_deposited_eth == 0 receipt = bidder.place_bid(value=big_bid) assert receipt['status'] == 1 - assert bidder.current_bid == big_bid + assert bidder.get_deposited_eth == big_bid another_bidder_address = testerchain.unassigned_accounts[1] another_bid = token_economics.maximum_allowed_locked // 50 another_bidder = Bidder(checksum_address=another_bidder_address, registry=test_registry) - assert another_bidder.current_bid == 0 + assert another_bidder.get_deposited_eth == 0 receipt = another_bidder.place_bid(value=another_bid) assert receipt['status'] == 1 - assert another_bidder.current_bid == another_bid + assert another_bidder.get_deposited_eth == another_bid def test_cancel_bid(testerchain, agency, token_economics, test_registry): bidder_address = testerchain.unassigned_accounts[1] bidder = Bidder(checksum_address=bidder_address, registry=test_registry) - assert bidder.current_bid # Bid + assert bidder.get_deposited_eth # Bid receipt = bidder.cancel_bid() # Cancel assert receipt['status'] == 1 - assert not bidder.current_bid # No more bid + assert not bidder.get_deposited_eth # No more bid # Can't cancel a bid twice in a row with pytest.raises((TransactionFailed, ValueError)): @@ -78,7 +78,7 @@ def test_claim(testerchain, agency, token_economics, test_registry): with pytest.raises(Bidder.BidderError): _receipt = bidder.claim() - assert bidder.current_bid == 40000000000000000000000 + assert bidder.get_deposited_eth == 40000000000000000000000 assert bidder.completed_work == 0 assert bidder.remaining_work == 500000000000000000000000 assert bidder.refunded_work == 0 diff --git a/tests/blockchain/eth/entities/agents/test_worklock_agent.py b/tests/blockchain/eth/entities/agents/test_worklock_agent.py index 8c270366c..217498772 100644 --- a/tests/blockchain/eth/entities/agents/test_worklock_agent.py +++ b/tests/blockchain/eth/entities/agents/test_worklock_agent.py @@ -30,13 +30,13 @@ def test_bidding(testerchain, agency, token_economics, test_registry): assert receipt['status'] == 1 -def test_get_bid(testerchain, agency, token_economics, test_registry): +def test_get_deposited_eth(testerchain, agency, token_economics, test_registry): big_bid = token_economics.maximum_allowed_locked // 10 big_bidder = testerchain.unassigned_accounts[-1] agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry) receipt = agent.bid(checksum_address=big_bidder, value=big_bid) assert receipt['status'] == 1 - bid = agent.get_bid(big_bidder) + bid = agent.get_deposited_eth(big_bidder) assert bid == big_bid @@ -44,10 +44,10 @@ def test_cancel_bid(testerchain, agency, token_economics, test_registry): bidder = testerchain.unassigned_accounts[1] agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry) - assert agent.get_bid(bidder) # Bid + assert agent.get_deposited_eth(bidder) # Bid receipt = agent.cancel_bid(bidder) # Cancel assert receipt['status'] == 1 - assert not agent.get_bid(bidder) # No more bid + assert not agent.get_deposited_eth(bidder) # No more bid # Can't cancel a bid twice in a row with pytest.raises((TransactionFailed, ValueError)): diff --git a/tests/cli/test_worklock_cli.py b/tests/cli/test_worklock_cli.py index 80b35c57e..8f72480f8 100644 --- a/tests/cli/test_worklock_cli.py +++ b/tests/cli/test_worklock_cli.py @@ -99,7 +99,7 @@ def test_cancel_bid(click_runner, testerchain, test_registry, agency, token_econ result = click_runner.invoke(worklock, command, catch_exceptions=False) assert result.exit_code == 0 - assert not agent.get_bid(bidder) # No more bid + assert not agent.get_deposited_eth(bidder) # No more bid def test_claim(click_runner, testerchain, agency, token_economics):