def test_totalVestedBalance(self): alice, bob = fresh_accounts(2) time = block_time() self.havven.endow(MASTER, self.escrow.contract.address, 100 * UNIT) self.assertEqual(self.escrow.totalVestedBalance(), 0) self.escrow.appendVestingEntry(MASTER, bob, time + 100, UNIT) self.assertEqual(self.escrow.totalVestedBalance(), UNIT) self.escrow.appendVestingEntry(MASTER, alice, time + 100, UNIT) self.assertEqual(self.escrow.totalVestedBalance(), 2 * UNIT) self.escrow.purgeAccount(MASTER, alice) self.assertEqual(self.escrow.totalVestedBalance(), UNIT) k = 5 for n in [100 * 2**i for i in range(k)]: self.escrow.appendVestingEntry(MASTER, alice, time + n, n) self.assertEqual(self.escrow.totalVestedBalance(), UNIT + 100 * (2**k - 1)) fast_forward(110) self.escrow.vest(alice) self.assertEqual(self.escrow.totalVestedBalance(), UNIT + 100 * (2**k - 1) - 100)
def test_closeVote(self): owner = self.owner() voter, suspect = fresh_accounts(2) voting_period = self.votingPeriod() fee_period = self.havvenTargetFeePeriodDurationSeconds() # Give some havven tokens to our voter. self.havvenEndow(owner, voter, 1000) # Fast forward two fee periods to update the voter's weight. fast_forward(fee_period + 1) self.havvenCheckFeePeriodRollover(DUMMY) fast_forward(fee_period + 1) self.havvenCheckFeePeriodRollover(DUMMY) self.havvenAdjustFeeEntitlement(voter, voter, self.havvenBalance(voter)) self.beginConfiscationMotion(owner, suspect) # Should not be able to close vote in the voting period. self.assertReverts(self.closeVote, voter, suspect) fast_forward(voting_period) self.assertTrue(self.confirming(suspect)) tx_receipt = self.closeVote(voter, suspect) # Check that event is emitted properly. self.assertEqual( get_event_data_from_log(self.court_event_dict, tx_receipt.logs[0])['event'], "VoteClosed") # Start another confiscation motion. self.beginConfiscationMotion(owner, suspect) self.voteFor(voter, suspect) fast_forward(voting_period) # After vote has closed, voteStarTimes and votesFor/votesAgainst should be 0 and suspect should be waiting. self.closeVote(voter, suspect) self.assertEqual(self.votesFor(suspect), 0) self.assertEqual(self.voteStartTimes(suspect), 0) self.assertTrue(self.waiting(suspect))
def setUpClass(cls): addresses = fresh_accounts(6) cls.participantAddresses = addresses[0:] cls.contractOwner = MASTER cls.pausableContract = cls.deployContracts() cls.pausable = PausableInterface(cls.pausableContract, "TestablePausable") cls.pausableEventDict = cls.event_maps['TestablePausable']
def test_approve(self): owner = self.owner() voter, guilty = fresh_accounts(2) voting_period = self.votingPeriod() fee_period = self.havvenTargetFeePeriodDurationSeconds() controlling_share = self.havvenSupply() // 2 # Give 50% of all havven tokens to our voter. self.havvenEndow(owner, voter, controlling_share) # Fast forward two fee periods to update the voter's weight. fast_forward(fee_period + 1) self.havvenCheckFeePeriodRollover(DUMMY) fast_forward(fee_period + 1) self.havvenCheckFeePeriodRollover(DUMMY) self.havvenAdjustFeeEntitlement(voter, voter, self.havvenBalance(voter)) self.beginConfiscationMotion(owner, guilty) # Cast a vote in favour of confiscation. tx_receipt = self.voteFor(voter, guilty) # It should not be possible to approve in the voting state. self.assertReverts(self.approve, owner, guilty) fast_forward(voting_period) self.assertTrue(self.confirming(guilty)) # Only the owner can approve the confiscation of a balance. self.assertReverts(self.approve, voter, guilty) tx_receipt = self.approve(owner, guilty) # Check that event is emitted properly. # self.assertEqual(get_event_data_from_log(self.court_event_dict, tx_receipt.logs[0])['event'], "VoteClosed") # self.assertEqual(get_event_data_from_log(self.court_event_dict, tx_receipt.logs[1])['event'], "ConfiscationApproval") self.assertEqual(self.voteStartTimes(guilty), 0) self.assertEqual(self.votesFor(guilty), 0) # After confiscation, their nomin balance should be frozen. self.assertTrue(self.nominIsFrozen(guilty))
def test_voteFor(self): owner = self.owner() accounts = fresh_accounts(4) voter = accounts[0] no_tokens = accounts[1] suspects = accounts[2:] voting_period = self.votingPeriod() fee_period = self.havvenTargetFeePeriodDurationSeconds() # Give some havven tokens to our voter. self.havvenEndow(owner, voter, 1000) self.assertEqual(self.havvenBalance(voter), 1000) # Cannot vote unless there is a confiscation motion. self.assertReverts(self.voteFor, voter, suspects[0]) # Fast forward to update the voter's weight. fast_forward(fee_period + 1) self.havvenCheckFeePeriodRollover(DUMMY) fast_forward(fee_period + 1) self.havvenCheckFeePeriodRollover(DUMMY) self.havvenAdjustFeeEntitlement(voter, voter, self.havvenBalance(voter)) # Begin a confiscation motion against the suspect. self.beginConfiscationMotion(owner, suspects[0]) self.assertTrue(self.voting(suspects[0])) # Cast a vote in favour of confiscation. tx_receipt = self.voteFor(voter, suspects[0]) # Check that event is emitted properly. self.assertEqual( get_event_data_from_log(self.court_event_dict, tx_receipt.logs[0])['event'], "VoteFor") self.assertEqual(self.votesFor(suspects[0]), 1000) # Our voter should not be able to vote in more than one motion at a time. self.beginConfiscationMotion(owner, suspects[1]) self.assertReverts(self.voteFor, voter, suspects[1]) # It should not be possible to vote without any tokens. self.assertReverts(self.voteFor, no_tokens, suspects[0])
def test_donateToFeePool(self): donor, pauper = fresh_accounts(2) self.assertNotEqual(donor, pauper) self.transfer(self.initial_beneficiary, donor, 10 * UNIT) self.withdrawFee(self.fee_authority, self.initial_beneficiary, self.feePool()) # No donations by people with no money... self.assertReverts(self.donateToFeePool, pauper, 10 * UNIT) # ...even if they donate nothing. self.assertReverts(self.donateToFeePool, pauper, 0) # No donations more than you possess. self.assertReverts(self.donateToFeePool, donor, 11 * UNIT) self.assertEqual(self.feePool(), 0) self.assertEqual(self.balanceOf(donor), 10 * UNIT) self.assertTrue(self.donateToFeePool(donor, UNIT)) self.assertEqual(self.feePool(), UNIT) self.assertEqual(self.balanceOf(donor), 9 * UNIT) self.assertTrue(self.donateToFeePool(donor, 5 * UNIT)) self.assertEqual(self.feePool(), 6 * UNIT) self.assertEqual(self.balanceOf(donor), 4 * UNIT) # And it should emit the right event. tx_receipt = self.donateToFeePool(donor, UNIT) self.assertEqual(len(tx_receipt.logs), 1) self.assertEqual( get_event_data_from_log(self.erc20fee_event_dict, tx_receipt.logs[0])['event'], 'FeeDonation')
def test_hasVoted(self): owner = self.owner() voter, suspect = fresh_accounts(2) fee_period = self.havvenTargetFeePeriodDurationSeconds() # Give 1000 havven tokens to our voter. self.havvenEndow(owner, voter, 1000) self.assertEqual(self.havvenBalance(voter), 1000) # Fast forward to update the vote weight. fast_forward(fee_period + 1) self.havvenCheckFeePeriodRollover(DUMMY) self.havvenAdjustFeeEntitlement(voter, voter, self.havvenBalance(voter)) # This should fail because no confiscation motion has begun. self.assertFalse(self.hasVoted(voter)) self.beginConfiscationMotion(owner, suspect) # This should return false because the voter has not voted yet. self.assertFalse(self.hasVoted(voter)) self.voteFor(voter, suspect) # This should return true because the voter has voted. self.assertTrue(self.hasVoted(voter)) # And false when they cancel their vote. self.cancelVote(voter, suspect) self.assertFalse(self.hasVoted(voter)) # And true again if they vote against. self.voteFor(voter, suspect) self.assertTrue(self.hasVoted(voter))
def test_averageBalanceSum(self): alice, bob, carol = fresh_accounts(3) fee_period = self.targetFeePeriodDurationSeconds() self.endow(MASTER, alice, UNIT) self.start_new_fee_period() self.transfer(alice, bob, UNIT // 4) self.transfer(alice, carol, UNIT // 4) fast_forward(fee_period // 10) self.transfer(bob, carol, UNIT // 4) fast_forward(fee_period // 10) self.transfer(carol, bob, UNIT // 2) fast_forward(fee_period // 10) self.transfer(bob, alice, UNIT // 4) fast_forward(2 * fee_period // 10) self.transfer(alice, bob, UNIT // 3) self.transfer(alice, carol, UNIT // 3) fast_forward(3 * fee_period // 10) self.transfer(carol, bob, UNIT // 3) fast_forward(3 * fee_period // 10) self.recomputeLastAverageBalance(alice) self.recomputeLastAverageBalance(bob) self.recomputeLastAverageBalance(carol) total_average = self.lastAverageBalance(alice) + \ self.lastAverageBalance(bob) + \ self.lastAverageBalance(carol) self.assertClose(UNIT, total_average)
def test_transferFrom_locked_havvens(self): alice, bob, charlie = fresh_accounts(3) self.havven.approve(alice, charlie, 2**256 - 1) self.havven.endow(MASTER, alice, 500 * UNIT) self.havven.endow(MASTER, self.escrow.contract.address, 500 * UNIT) self.escrow.appendVestingEntry(MASTER, alice, block_time() + 10000000, 500 * UNIT) self.havven.setIssuer(MASTER, alice, True) self.havven_updatePrice(self.havven.oracle(), UNIT, self.havven.currentTime() + 1) self.havven.setIssuanceRatio(MASTER, UNIT) self.havven.issueNomins(alice, 400 * UNIT) self.havven.transferFrom(charlie, alice, bob, 500 * UNIT) self.havven.endow(MASTER, alice, 500 * UNIT) self.havven.issueNomins(alice, 100 * UNIT) self.havven.transferFrom(charlie, alice, bob, 500 * UNIT) self.havven.endow(MASTER, alice, 500 * UNIT) self.havven.issueNomins(alice, 100 * UNIT) self.assertReverts(self.havven.transferFrom, charlie, alice, bob, 500 * UNIT) self.havven.transferFrom(charlie, alice, bob, 400 * UNIT) self.havven.endow(MASTER, alice, 400 * UNIT) self.havven.issueNomins(alice, 100 * UNIT) self.assertReverts(self.havven.transferFrom, charlie, alice, bob, 300 * UNIT + 1) self.havven.transferFrom(charlie, alice, bob, 300 * UNIT) self.havven.endow(MASTER, alice, 300 * UNIT) self.havven.issueNomins(alice, 300 * UNIT) self.assertReverts(self.havven.transferFrom, charlie, alice, bob, 1)
def test_transferFrom(self): approver = MASTER spender, receiver = fresh_accounts(2) approver_balance = self.balanceOf(approver) spender_balance = self.balanceOf(spender) receiver_balance = self.balanceOf(receiver) value = 10 * UNIT total_supply = self.totalSupply() # This fails because there has been no approval yet self.assertReverts(self.transferFrom, spender, approver, receiver, value) tx_receipt = self.approve(approver, spender, 2 * value) # Check event is emitted properly. self.assertEqual( get_event_data_from_log(self.erc20_event_dict, tx_receipt.logs[0])['event'], "Approval") self.assertEqual(self.allowance(approver, spender), 2 * value) self.assertReverts(self.transferFrom, spender, approver, receiver, 2 * value + 1) tx_receipt = self.transferFrom(spender, approver, receiver, value) # Check event is emitted properly. self.assertEqual( get_event_data_from_log(self.erc20_event_dict, tx_receipt.logs[0])['event'], "Transfer") self.assertEqual(self.balanceOf(approver), approver_balance - value) self.assertEqual(self.balanceOf(spender), spender_balance) self.assertEqual(self.balanceOf(receiver), receiver_balance + value) self.assertEqual(self.allowance(approver, spender), value) self.assertEqual(self.totalSupply(), total_supply) # Empty the account tx_receipt = self.transferFrom(spender, approver, receiver, value) # Check event is emitted properly. self.assertEqual( get_event_data_from_log(self.erc20_event_dict, tx_receipt.logs[0])['event'], "Transfer") approver = fresh_account() # This account has no tokens approver_balance = self.balanceOf(approver) self.assertEqual(approver_balance, 0) self.assertEqual(self.allowance(approver, spender), 0) tx_receipt = self.approve(approver, spender, value) # Check event is emitted properly. self.assertEqual( get_event_data_from_log(self.erc20_event_dict, tx_receipt.logs[0])['event'], "Approval") self.assertEqual(self.allowance(approver, spender), value) # This should fail because the approver has no tokens. self.assertReverts(self.transferFrom, spender, approver, receiver, value)
def test_votePasses(self): owner = self.owner() accounts = fresh_accounts(11) suspect = accounts[0] voters = accounts[1:] required_participation = self.requiredParticipation() required_majority = self.requiredMajority() fee_period = self.havvenTargetFeePeriodDurationSeconds() tokens = self.havvenSupply() // 20 # Give 1/20th of the token supply to each of our 10 voters. In total 50% of tokens distributed. for voter in voters: self.havvenEndow(owner, voter, tokens) self.assertEqual(self.havvenBalance(voter), tokens) # Fast forward to update the vote weights. fast_forward(fee_period + 1) self.havvenCheckFeePeriodRollover(DUMMY) fast_forward(fee_period + 1) self.havvenCheckFeePeriodRollover(DUMMY) # Begin a confiscation motion against the suspect. self.beginConfiscationMotion(owner, suspect) self.assertFalse(self.votePasses(suspect)) # 100% in favour and 0% against (50% participation). for voter in voters: self.havvenAdjustFeeEntitlement(voter, voter, self.havvenBalance(voter)) self.voteFor(voter, suspect) self.assertTrue(self.votePasses(suspect)) self.assertEqual(self.votesFor(suspect), self.havvenSupply() // 2) # All cancel votes. for voter in voters: self.cancelVote(voter, suspect) self.assertFalse(self.votePasses(suspect)) self.assertEqual(self.votesFor(suspect), 0) # 100% against and 0% in favour (50% participation). for voter in voters: self.voteAgainst(voter, suspect) self.assertFalse(self.votePasses(suspect)) self.assertEqual(self.votesAgainst(suspect), self.havvenSupply() // 2) # All cancel votes. for voter in voters: self.cancelVote(voter, suspect) self.assertEqual(self.votesAgainst(suspect), 0) # 60% in favour and 0% against (30% participation) for voter in voters[:6]: self.voteFor(voter, suspect) # Required participation must be > than 30%. self.assertFalse(self.votePasses(suspect)) # But if another user votes in favour, participation = 35% which is sufficient for a vote to pass. self.voteFor(voters[7], suspect) self.assertTrue(self.votePasses(suspect)) # The last 3 vote against, 70% in favour and 30% against (required majority is 2/3). for voter in voters[8:]: self.voteAgainst(voter, suspect) self.assertTrue(self.votePasses(suspect)) # If one changes their vote for to against, should not pass since 60% in favour 40% against (less than the min required majority of 2/3). self.cancelVote(voters[7], suspect) self.voteAgainst(voters[7], suspect) self.assertFalse(self.votePasses(suspect))
def test_addRegularVestingSchedule(self): alice, bob, carol, tim, pim = fresh_accounts(5) self.h_endow(MASTER, self.escrow.address, 100 * UNIT) time = block_time() self.addRegularVestingSchedule(MASTER, alice, time + to_seconds(weeks=52), 100 * UNIT, 4) self.assertEqual(self.numVestingEntries(alice), 4) self.vest(alice) self.assertEqual(self.h_balanceOf(alice), 0) fast_forward(to_seconds(weeks=13) + 10) self.vest(alice) self.assertEqual(self.h_balanceOf(alice), 25 * UNIT) fast_forward(to_seconds(weeks=13) + 10) self.vest(alice) self.assertEqual(self.h_balanceOf(alice), 50 * UNIT) fast_forward(to_seconds(weeks=13) + 10) self.vest(alice) self.assertEqual(self.h_balanceOf(alice), 75 * UNIT) fast_forward(to_seconds(weeks=13) + 10) self.vest(alice) self.assertEqual(self.h_balanceOf(alice), 100 * UNIT) fast_forward(to_seconds(weeks=13) + 10) self.vest(alice) self.assertEqual(self.h_balanceOf(alice), 100 * UNIT) time = block_time() + 10000000 bob_periods = 7 self.addRegularVestingSchedule(MASTER, bob, time, UNIT, 7) q = sum(self.getVestingQuantity(bob, i) for i in range(bob_periods)) self.assertEqual(q, UNIT) self.assertEqual(self.getVestingTime(bob, bob_periods - 1), time, UNIT) self.assertReverts(self.addRegularVestingSchedule, MASTER, carol, block_time() - 1, UNIT, 5) self.assertReverts(self.addRegularVestingSchedule, MASTER, carol, 0, UNIT, 5) self.assertReverts(self.addRegularVestingSchedule, MASTER, carol, block_time() + 100000, UNIT, 0) time = block_time() + 10000 self.appendVestingEntry(MASTER, tim, time, UNIT) self.addRegularVestingSchedule(MASTER, pim, time, UNIT, 1) self.assertEqual(self.numVestingEntries(tim), self.numVestingEntries(pim)) self.assertEqual(self.getVestingTime(tim, 0), self.getVestingTime(pim, 0)) self.assertEqual(self.getVestingQuantity(tim, 0), self.getVestingQuantity(pim, 0))
def test_edge_issue_burn(self): havven, acc1, acc2 = fresh_accounts(3) self.nomin.setHavven(MASTER, havven) max_int = 2**256 - 1 txr = self.nomin.publicIssue(havven, acc1, 100 * UNIT) self.assertEventEquals( self.nomin_event_dict, txr.logs[0], 'Transfer', fields={'from': ZERO_ADDRESS, 'to': acc1, 'value': 100 * UNIT}, location=self.nomin_proxy.address ) self.assertEventEquals( self.nomin_event_dict, txr.logs[1], 'Issued', fields={'account': acc1, 'amount': 100 * UNIT}, location=self.nomin_proxy.address ) self.assertReverts(self.nomin.publicIssue, havven, acc1, max_int) self.assertReverts(self.nomin.publicIssue, havven, acc2, max_int) # there shouldn't be a way to burn towards a larger value by overflowing self.assertReverts(self.nomin.publicBurn, havven, acc1, max_int) txr = self.nomin.publicBurn(havven, acc1, 100 * UNIT) self.assertEventEquals( self.nomin_event_dict, txr.logs[0], 'Transfer', fields={'from': acc1, 'to': ZERO_ADDRESS, 'value': 100 * UNIT}, location=self.nomin_proxy.address ) self.assertEventEquals( self.nomin_event_dict, txr.logs[1], 'Burned', fields={'account': acc1, 'amount': 100 * UNIT}, location=self.nomin_proxy.address ) # as long as no nomins exist, its a valid action txr = self.nomin.publicIssue(havven, acc2, max_int) self.assertEventEquals( self.nomin_event_dict, txr.logs[0], 'Transfer', fields={'from': ZERO_ADDRESS, 'to': acc2, 'value': max_int}, location=self.nomin_proxy.address ) self.assertEventEquals( self.nomin_event_dict, txr.logs[1], 'Issued', fields={'account': acc2, 'amount': max_int}, location=self.nomin_proxy.address ) txr = self.nomin.publicBurn(havven, acc2, max_int) self.assertEventEquals( self.nomin_event_dict, txr.logs[0], 'Transfer', fields={'from': acc2, 'to': ZERO_ADDRESS, 'value': max_int}, location=self.nomin_proxy.address ) self.assertEventEquals( self.nomin_event_dict, txr.logs[1], 'Burned', fields={'account': acc2, 'amount': max_int}, location=self.nomin_proxy.address )
def test_setVotedNay(self): owner = self.owner() voter, suspect = fresh_accounts(2) self.beginConfiscationMotion(owner, suspect) # Test that internal function properly updates state self.setVotedNay(voter, voter, suspect) self.assertEqual(self.userVote(voter), 2) self.assertEqual(self.voteTarget(voter), suspect) # If already voted, cannot set again self.assertReverts(self.setVotedNay, voter, voter, suspect) self.assertReverts(self.setVotedYea, voter, voter, suspect)
def test_event_Approval(self): approver, approvee = fresh_accounts(2) txr = self.feetoken.approve(approver, approvee, UNIT) self.assertEventEquals(self.feetoken_event_dict, txr.logs[0], 'Approval', fields={ 'owner': approver, 'spender': approvee, 'value': UNIT }, location=self.proxy.address)
def test_appendVestingEntry(self): alice, bob = fresh_accounts(2) escrow_balance = 20 * UNIT amount = 10 self.havven.endow(MASTER, self.escrow.contract.address, escrow_balance) time = block_time() # Should not be able to add a vestingEntry > havven.totalSupply() self.assertReverts(self.escrow.appendVestingEntry, MASTER, alice, time + to_seconds(weeks=2), self.havven.totalSupply() + 1) # Should not be able to add a vestingEntry > balanceOf escrow account self.assertReverts(self.escrow.appendVestingEntry, MASTER, alice, time + to_seconds(weeks=2), escrow_balance + 1) # Should not be able to vest in the past self.assertReverts(self.escrow.appendVestingEntry, MASTER, alice, 0, UNIT) self.assertReverts(self.escrow.appendVestingEntry, MASTER, alice, time - 1, UNIT) self.assertReverts(self.escrow.appendVestingEntry, MASTER, alice, time, UNIT) # Vesting quantities should be nonzero self.assertReverts(self.escrow.appendVestingEntry, MASTER, alice, time + to_seconds(weeks=2), 0) self.escrow.appendVestingEntry(MASTER, alice, time + to_seconds(weeks=2), amount) self.escrow.vest(alice) self.assertEqual(self.havven.balanceOf(alice), 0) fast_forward(weeks=3) self.escrow.vest(alice) self.assertEqual(self.havven.balanceOf(alice), amount) self.havven.transfer(alice, MASTER, amount) time = block_time() t1 = time + to_seconds(weeks=1) t2 = time + to_seconds(weeks=2) self.escrow.appendVestingEntry(MASTER, alice, t1, amount) self.assertReverts(self.escrow.appendVestingEntry, MASTER, alice, time + to_seconds(days=1), amount) self.assertReverts(self.escrow.appendVestingEntry, MASTER, alice, time + to_seconds(weeks=1), amount) self.escrow.appendVestingEntry(MASTER, alice, t2, amount + 1) self.assertEqual(self.escrow.getVestingQuantity(alice, 1), amount) self.assertEqual(self.escrow.getVestingQuantity(alice, 2), amount + 1) self.assertEqual(self.escrow.getVestingTime(alice, 1), t1) self.assertEqual(self.escrow.getVestingTime(alice, 2), t2) self.assertEqual(self.escrow.numVestingEntries(alice), 3)
def test_collateral(self): alice, bob, charlie, debbie = fresh_accounts(4) self.havven.endow(MASTER, alice, UNIT) self.havven.endow(MASTER, bob, UNIT) self.havven.endow(MASTER, self.escrow.contract.address, 2 * UNIT) self.escrow.appendVestingEntry(MASTER, alice, block_time() + 10000000, UNIT) self.escrow.appendVestingEntry(MASTER, charlie, block_time() + 10000000, UNIT) self.assertEqual(self.havven.collateral(alice), 2 * UNIT) self.assertEqual(self.havven.collateral(bob), UNIT) self.assertEqual(self.havven.collateral(charlie), UNIT) self.assertEqual(self.havven.collateral(debbie), 0)
def test_getSetState(self): _, new_state = fresh_accounts(2) owner = self.owner() self.assertNotEqual(new_state, owner) # Only the owner is able to set the Fee Authority. self.assertReverts(self.setState, new_state, new_state) tx_receipt = self.setState(owner, new_state) # Check that event is emitted. self.assertEqual( get_event_data_from_log(self.feetoken_event_dict, tx_receipt.logs[0])['event'], "StateUpdated") self.assertEqual(self.state(), new_state)
def setUpClass(cls): addresses = fresh_accounts(6) cls.participantAddresses = addresses[2:] cls.contractOwner = MASTER cls.oracleAddress = addresses[0] cls.fundsWallet = addresses[1] cls.usdToEthPrice = 500 * (10 ** 18) cls.usdToHavPrice = int(0.65 * (10 ** 18)) cls.priceStalePeriod = 3 * 60 * 60 cls.havven_proxy, cls.proxied_havven, cls.nomin_proxy, cls.proxied_nomin, cls.havven_contract, cls.nomin_contract, cls.nomin_abi, cls.issuanceControllerContract = cls.deployContracts() cls.issuanceController = IssuanceControllerInterface(cls.issuanceControllerContract, "IssuanceController") cls.havven = PublicHavvenInterface(cls.havven_contract, "Havven") cls.nomin = PublicNominInterface(cls.nomin_contract, "Nomin") cls.issuanceControllerEventDict = cls.event_maps['IssuanceController']
def test_transferFrom(self): approver, spender, receiver, no_tokens = fresh_accounts(4) self.havven.endow(MASTER, approver, 50 * UNIT) approver_balance = self.havven.balanceOf(approver) spender_balance = self.havven.balanceOf(spender) receiver_balance = self.havven.balanceOf(receiver) value = 10 * UNIT total_supply = self.havven.totalSupply() # This fails because there has been no approval yet self.assertReverts(self.havven.transferFrom, spender, approver, receiver, value) self.havven.approve(approver, spender, 2 * value) self.assertEqual(self.havven.allowance(approver, spender), 2 * value) self.assertReverts(self.havven.transferFrom, spender, approver, receiver, 2 * value + 1) self.havven.transferFrom(spender, approver, receiver, value) self.assertEqual(self.havven.balanceOf(approver), approver_balance - value) self.assertEqual(self.havven.balanceOf(spender), spender_balance) self.assertEqual(self.havven.balanceOf(receiver), receiver_balance + value) self.assertEqual(self.havven.allowance(approver, spender), value) self.assertEqual(self.havven.totalSupply(), total_supply) # Empty the account self.havven.transferFrom(spender, approver, receiver, value) # This account has no tokens approver_balance = self.havven.balanceOf(no_tokens) self.assertEqual(approver_balance, 0) self.assertEqual(self.havven.allowance(no_tokens, spender), 0) self.havven.approve(no_tokens, spender, value) self.assertEqual(self.havven.allowance(no_tokens, spender), value) # This should fail because the approver has no tokens. self.assertReverts(self.havven.transferFrom, spender, no_tokens, receiver, value)
def test_beginConfiscationMotion(self): owner = self.owner() accounts = fresh_accounts(5) insufficient_standing = accounts[0] sufficient_standing = accounts[1] voter = accounts[2] suspects = accounts[3:] voting_period = self.votingPeriod() fee_period = self.havvenTargetFeePeriodDurationSeconds() controlling_share = self.havvenSupply() // 2 # Give 50% of the havven tokens to voter, enough to pass a confiscation motion on their own. self.havvenEndow(owner, voter, controlling_share) self.assertEqual(self.havvenBalance(voter), controlling_share) # Fast forward to update the voter's weight. fast_forward(fee_period + 1) self.havvenCheckFeePeriodRollover(DUMMY) fast_forward(fee_period + 1) self.havvenCheckFeePeriodRollover(DUMMY) self.havvenAdjustFeeEntitlement(voter, voter, self.havvenBalance(voter)) self.havvenEndow(owner, insufficient_standing, 99 * UNIT) self.havvenEndow(owner, sufficient_standing, 100 * UNIT) # Must have at least 100 havvens to begin a confiscsation motion. self.assertReverts(self.beginConfiscationMotion, insufficient_standing, suspects[0]) tx_receipt = self.beginConfiscationMotion(sufficient_standing, suspects[0]) # Check that event is emitted properly. self.assertEqual( get_event_data_from_log(self.court_event_dict, tx_receipt.logs[0])['event'], "ConfiscationVote") self.assertTrue(self.voting(suspects[0])) # The contract owner can also begin an motion, regardless of the token requirement. self.beginConfiscationMotion(owner, suspects[1]) # Cannot open multiple confiscation motions on one suspect. self.assertReverts(self.beginConfiscationMotion, owner, suspects[0]) self.voteFor(voter, suspects[0]) fast_forward(voting_period) self.approve(owner, suspects[0]) self.assertTrue(self.nominIsFrozen(suspects[0])) # Cannot open a vote on an account that has already been frozen. self.assertReverts(self.beginConfiscationMotion, owner, suspects[0])
def setUpClass(cls): addresses = fresh_accounts(6) cls.participantAddresses = addresses[2:] cls.contractOwner = MASTER cls.oracleAddress = addresses[0] cls.fundsWallet = addresses[1] cls.usdToEthPrice = 500 * UNIT cls.usdToHavPrice = int(0.65 * UNIT) cls.priceStalePeriod = 3 * 60 * 60 cls.havven_proxy, cls.proxied_havven, cls.nomin_proxy, cls.proxied_nomin, cls.havven_contract, cls.nomin_contract, cls.nomin_abi, cls.issuanceControllerContract = cls.deployContracts( ) cls.issuanceController = IssuanceControllerInterface( cls.issuanceControllerContract, "IssuanceController") cls.havven = PublicHavvenInterface(cls.havven_contract, "Havven") cls.nomin = PublicNominInterface(cls.nomin_contract, "Nomin") cls.issuanceControllerEventDict = cls.event_maps['IssuanceController'] fast_forward( 1 ) # Give the contract constructor a second between its execution and execution of the other functions.
def test_approve(self): approver, spender = fresh_accounts(2) approval_amount = 1 * UNIT tx_receipt = self.approve(approver, spender, approval_amount) # Check event is emitted properly. self.assertEqual( get_event_data_from_log(self.erc20_event_dict, tx_receipt.logs[0])['event'], "Approval") self.assertEqual(self.allowance(approver, spender), approval_amount) # Any positive approval amount is valid, even greater than total_supply. approval_amount = self.totalSupply() * 100 tx_receipt = self.approve(approver, spender, approval_amount) # Check event is emitted properly. self.assertEqual( get_event_data_from_log(self.erc20_event_dict, tx_receipt.logs[0])['event'], "Approval") self.assertEqual(self.allowance(approver, spender), approval_amount)
def test_veto(self): owner = self.owner() voter, acquitted = fresh_accounts(2) voting_period = self.votingPeriod() fee_period = self.havvenTargetFeePeriodDurationSeconds() controlling_share = self.havvenSupply() // 2 self.havvenEndow(owner, voter, controlling_share) # Fast forward two fee periods to update the voter's weight. fast_forward(fee_period + 1) self.havvenCheckFeePeriodRollover(DUMMY) fast_forward(fee_period + 1) self.havvenCheckFeePeriodRollover(DUMMY) self.havvenAdjustFeeEntitlement(voter, voter, self.havvenBalance(voter)) # Cannot veto when there is no vote in progress. self.assertReverts(self.veto, owner, acquitted) self.beginConfiscationMotion(owner, acquitted) # Only owner can veto. self.assertReverts(self.veto, DUMMY, acquitted) self.veto(owner, acquitted) # After veto motion, suspect should be back in the waiting stage. self.assertTrue(self.waiting(acquitted)) self.beginConfiscationMotion(owner, acquitted) self.voteFor(voter, acquitted) self.assertTrue(self.votePasses(acquitted)) fast_forward(voting_period) self.assertTrue(self.confirming(acquitted)) # Once a vote has been passed, the owner can veto it. tx_receipt = self.veto(owner, acquitted) # Check that event is emitted properly. self.assertEqual( get_event_data_from_log(self.court_event_dict, tx_receipt.logs[0])['event'], "VoteClosed") self.assertEqual( get_event_data_from_log(self.court_event_dict, tx_receipt.logs[1])['event'], "Veto") # After veto motion, suspect should be back in the waiting stage. self.assertTrue(self.waiting(acquitted)) # Votes should be reset. self.assertEqual(self.voteStartTimes(acquitted), 0) self.assertEqual(self.votesFor(acquitted), 0) self.assertEqual(self.votesAgainst(acquitted), 0) self.assertTrue(self.waiting(acquitted))
def test_averageBalanceSum(self): alice, bob, carol = fresh_accounts(3) fee_period = self.havven.feePeriodDuration() self.havven.endow(MASTER, alice, UNIT) self.havven.endow(MASTER, bob, UNIT) self.havven.endow(MASTER, carol, UNIT) self.havven.setIssuer(MASTER, alice, True) self.havven.setIssuer(MASTER, bob, True) self.havven.setIssuer(MASTER, carol, True) self.havven.setIssuanceRatio(MASTER, UNIT) fast_forward(fee_period + 1) self.havven.rolloverFeePeriodIfElapsed(DUMMY) for i in range(10): self.havven_updatePrice(MASTER, UNIT, block_time() + 1) a_weight = random.random() b_weight = random.random() c_weight = random.random() tot = a_weight + b_weight + c_weight self.havven.issueNomins(alice, max(1, int(UNIT * a_weight / tot))) self.havven.issueNomins(bob, max(1, int(UNIT * b_weight / tot))) self.havven.issueNomins(carol, max(1, int(UNIT * c_weight / tot))) fast_forward(fee_period // 10 - 1) self.havven.burnNomins(alice, max(1, int(UNIT * a_weight / tot))) self.havven.burnNomins(bob, max(1, int(UNIT * b_weight / tot))) self.havven.burnNomins(carol, max(1, int(UNIT * c_weight / tot))) fast_forward(11) self.havven.rolloverFeePeriodIfElapsed(MASTER) self.havven.recomputeLastAverageBalance(alice, alice) self.havven.recomputeLastAverageBalance(bob, bob) self.havven.recomputeLastAverageBalance(carol, carol) total_average = self.havven.issuanceLastAverageBalance(alice) + \ self.havven.issuanceLastAverageBalance(bob) + \ self.havven.issuanceLastAverageBalance(carol) self.assertClose(UNIT, total_average, precision=3)
def test_cancelVote(self): owner = self.owner() voter, suspect = fresh_accounts(2) voting_period = self.votingPeriod() confirmation_period = self.confirmationPeriod() fee_period = self.havvenTargetFeePeriodDurationSeconds() # Give some havven tokens to our voter. self.havvenEndow(owner, voter, 1000) self.assertEqual(self.havvenBalance(voter), 1000) fast_forward(fee_period + 1) fast_forward(fee_period + 1) self.havvenCheckFeePeriodRollover(DUMMY) self.havvenAdjustFeeEntitlement(voter, voter, self.havvenBalance(voter)) # Begin a confiscation motion against the suspect. self.beginConfiscationMotion(owner, suspect) # Cast a vote in favour of confiscation. self.voteFor(voter, suspect) self.assertEqual(self.votesFor(suspect), 1000) tx_receipt = self.cancelVote(voter, suspect) # Check that event is emitted properly. self.assertEqual( get_event_data_from_log(self.court_event_dict, tx_receipt.logs[0])['event'], "CancelledVote") self.assertEqual(self.votesFor(suspect), 0) self.assertEqual(self.userVote(voter), 0) # Cast a vote against confiscation. self.voteAgainst(voter, suspect) self.assertEqual(self.votesAgainst(suspect), 1000) self.cancelVote(voter, suspect) self.assertEqual(self.votesAgainst(suspect), 0) self.assertEqual(self.userVote(voter), 0) # Cannot cancel a vote during the confirmation period. self.voteFor(voter, suspect) fast_forward(voting_period) self.assertReverts(self.cancelVote, voter, suspect) self.assertEqual(self.userVote(voter), 1) # Can cancel it after the confirmation period. fast_forward(confirmation_period) self.cancelVote(voter, suspect) self.assertEqual(self.userVote(voter), 0)
def test_appendVestingEntry(self): alice, bob = fresh_accounts(2) amount = 16 * UNIT self.h_endow(MASTER, self.escrow.address, amount) time = block_time() # Should not be able to vest in the past self.assertReverts(self.appendVestingEntry, MASTER, alice, 0, UNIT) self.assertReverts(self.appendVestingEntry, MASTER, alice, time - 1, UNIT) self.assertReverts(self.appendVestingEntry, MASTER, alice, time, UNIT) # Vesting quantities should be nonzero self.assertReverts(self.appendVestingEntry, MASTER, alice, time + to_seconds(weeks=2), 0) self.appendVestingEntry(MASTER, alice, time + to_seconds(weeks=2), amount) self.vest(alice) self.assertEqual(self.h_balanceOf(alice), 0) fast_forward(weeks=3) self.vest(alice) self.assertEqual(self.h_balanceOf(alice), amount) self.h_transfer(alice, MASTER, amount) time = block_time() t1 = time + to_seconds(weeks=1) t2 = time + to_seconds(weeks=2) self.appendVestingEntry(MASTER, alice, t1, amount) self.assertReverts(self.appendVestingEntry, MASTER, alice, time + to_seconds(days=1), amount) self.assertReverts(self.appendVestingEntry, MASTER, alice, time + to_seconds(weeks=1), amount) self.appendVestingEntry(MASTER, alice, t2, amount + 1) self.assertEqual(self.getVestingQuantity(alice, 1), amount) self.assertEqual(self.getVestingQuantity(alice, 2), amount + 1) self.assertEqual(self.getVestingTime(alice, 1), t1) self.assertEqual(self.getVestingTime(alice, 2), t2) self.assertEqual(self.numVestingEntries(alice), 3)
def test_abuse_havven_balance(self): """Test whether repeatedly moving havvens between two parties will shift averages upwards""" alice, bob = fresh_accounts(2) amount = UNIT * 100000 a_sum = 0 b_sum = 0 self.endow(MASTER, alice, amount) time = block_time() self.assertEquals(self.balanceOf(alice), amount) self.assertEquals(self.currentBalanceSum(alice), 0) for i in range(20): self.transfer(alice, bob, amount) a_sum += (block_time() - time) * amount time = block_time() self.assertEquals(self.balanceOf(bob), amount) self.assertEquals(self.currentBalanceSum(alice), a_sum) self.transfer(bob, alice, amount) b_sum += (block_time() - time) * amount time = block_time() self.assertEquals(self.balanceOf(alice), amount) self.assertEquals(self.currentBalanceSum(bob), b_sum)
def test_addRegularVestingSchedule(self): alice, bob, carol, tim, pim = fresh_accounts(5) self.h_endow(MASTER, self.escrow.address, 1000 * UNIT) time = block_time() self.addRegularVestingSchedule(MASTER, alice, time + to_seconds(weeks=52), 100 * UNIT, 4) self.assertEqual(self.numVestingEntries(alice), 4) self.vest(alice) self.assertEqual(self.h_balanceOf(alice), 0) fast_forward(to_seconds(weeks=13) + 10) self.vest(alice) self.assertEqual(self.h_balanceOf(alice), 25 * UNIT) fast_forward(to_seconds(weeks=13) + 10) self.vest(alice) self.assertEqual(self.h_balanceOf(alice), 50 * UNIT) fast_forward(to_seconds(weeks=13) + 10)
def test_transfer(self): sender, receiver, no_tokens = fresh_accounts(3) self.havven.endow(MASTER, sender, 50 * UNIT) sender_balance = self.havven.balanceOf(sender) receiver_balance = self.havven.balanceOf(receiver) self.assertEqual(receiver_balance, 0) value = 10 * UNIT total_supply = self.havven.totalSupply() # This should fail because receiver has no tokens self.assertReverts(self.havven.transfer, receiver, sender, value) self.havven.transfer(sender, receiver, value) self.assertEqual(self.havven.balanceOf(receiver), receiver_balance + value) self.assertEqual(self.havven.balanceOf(sender), sender_balance - value) # transfers should leave the supply unchanged self.assertEqual(self.havven.totalSupply(), total_supply) value = 1001 * UNIT # This should fail because balance < value and balance > totalSupply self.assertReverts(self.havven.transfer, sender, receiver, value) # 0 value transfers are allowed. value = 0 pre_sender_balance = self.havven.balanceOf(sender) pre_receiver_balance = self.havven.balanceOf(receiver) self.havven.transfer(sender, receiver, value) self.assertEqual(self.havven.balanceOf(receiver), pre_receiver_balance) self.assertEqual(self.havven.balanceOf(sender), pre_sender_balance) # It is also possible to send 0 value transfer from an account with 0 balance. self.assertEqual(self.havven.balanceOf(no_tokens), 0) self.havven.transfer(no_tokens, receiver, value) self.assertEqual(self.havven.balanceOf(no_tokens), 0)