def test_multiple_contributors_crowdsourcer_fees(localFixture, universe, market, cash, reputationToken): feeWindow = localFixture.applySignature('FeeWindow', market.getFeeWindow()) # We'll make the window active localFixture.contracts["Time"].setTimestamp(feeWindow.getStartTime() + 1) # generate some fees generateFees(localFixture, universe, market) # We'll have testers push markets into the next round by funding dispute crowdsourcers amount = market.getTotalStake() with TokenDelta(reputationToken, -amount, tester.a1, "Disputing did not reduce REP balance correctly"): assert market.contribute([0, market.getNumTicks()], False, amount, sender=tester.k1, startgas=long(6.7 * 10**6)) with TokenDelta(reputationToken, -amount, tester.a2, "Disputing did not reduce REP balance correctly"): assert market.contribute([0, market.getNumTicks()], False, amount, sender=tester.k2, startgas=long(6.7 * 10**6)) newFeeWindowAddress = market.getFeeWindow() assert newFeeWindowAddress != feeWindow.address # fast forward time to the fee new window and generate additional fees feeWindow = localFixture.applySignature('FeeWindow', newFeeWindowAddress) localFixture.contracts["Time"].setTimestamp(feeWindow.getStartTime() + 1) # Fast forward time until the new fee window is over and we can redeem our winning stake, and dispute bond tokens and receive fees localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1) assert market.finalize() marketDisputeCrowdsourcer = localFixture.applySignature( 'DisputeCrowdsourcer', market.getReportingParticipant(1)) # The dispute crowdsourcer contributors locked in REP for 2 rounds and staked twice the initial reporter so they split 2/3 of the total stake expectedFees = cash.balanceOf(feeWindow.address) + cash.balanceOf( universe.getOrCreateFeeWindowBefore(feeWindow.address)) expectedFees = expectedFees / 3 * 2 expectedRep = long(amount + amount / 2) with TokenDelta(reputationToken, expectedRep, tester.a1, "Redeeming didn't refund REP"): with EtherDelta(expectedFees / 2, tester.a1, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert marketDisputeCrowdsourcer.redeem(tester.a1) with TokenDelta(reputationToken, expectedRep + 1, tester.a2, "Redeeming didn't refund REP"): with EtherDelta(expectedFees - expectedFees / 2, tester.a2, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert marketDisputeCrowdsourcer.redeem(tester.a2)
def test_participation_tokens(kitchenSinkFixture, universe, market, cash): reputationToken = kitchenSinkFixture.applySignature( "ReputationToken", universe.getReputationToken()) disputeWindow = kitchenSinkFixture.applySignature( "DisputeWindow", universe.getOrCreateNextDisputeWindow(False)) # Generate Fees generateFees(kitchenSinkFixture, universe, market) # We can't buy participation tokens until the window starts with raises(TransactionFailed): disputeWindow.buy(300) # Fast forward time until the new dispute window starts and we can buy some tokens assert reputationToken.transfer(kitchenSinkFixture.accounts[1], 100) kitchenSinkFixture.contracts["Time"].setTimestamp( disputeWindow.getStartTime() + 1) with TokenDelta(reputationToken, -300, kitchenSinkFixture.accounts[0], "Buying sisnt take REP"): with TokenDelta(disputeWindow, 300, kitchenSinkFixture.accounts[0], "Buying didnt give PTs"): assert disputeWindow.buy(300) with TokenDelta(reputationToken, -100, kitchenSinkFixture.accounts[1], "Buying sisnt take REP"): with TokenDelta(disputeWindow, 100, kitchenSinkFixture.accounts[1], "Buying didnt give PTs"): assert disputeWindow.buy(100, sender=kitchenSinkFixture.accounts[1]) # We can't redeem until the window is over with raises(TransactionFailed): disputeWindow.redeem(kitchenSinkFixture.accounts[0]) # Fast forward time until the new dispute window is over and we can redeem kitchenSinkFixture.contracts["Time"].setTimestamp( disputeWindow.getEndTime() + 1) totalFees = cash.balanceOf(disputeWindow.address) with TokenDelta(reputationToken, 300, kitchenSinkFixture.accounts[0], "Redeeming didn't refund REP"): with TokenDelta(cash, totalFees * 3 / 4, kitchenSinkFixture.accounts[0], "Redeeming didn't give fees"): with TokenDelta(disputeWindow, -300, kitchenSinkFixture.accounts[0], "Redeeming didn't burn PTs"): assert disputeWindow.redeem(kitchenSinkFixture.accounts[0]) with TokenDelta(reputationToken, 100, kitchenSinkFixture.accounts[1], "Redeeming didn't refund REP"): with TokenDelta(cash, totalFees * 1 / 4, kitchenSinkFixture.accounts[1], "Redeeming didn't give fees"): with TokenDelta(disputeWindow, -100, kitchenSinkFixture.accounts[1], "Redeeming didn't burn PTs"): assert disputeWindow.redeem(kitchenSinkFixture.accounts[1])
def test_one_round_crowdsourcer_fees(localFixture, universe, market, cash, reputationToken): feeWindow = localFixture.applySignature('FeeWindow', market.getFeeWindow()) constants = localFixture.contracts["Constants"] # We'll make the window active localFixture.contracts["Time"].setTimestamp(feeWindow.getStartTime() + 1) # generate some fees generateFees(localFixture, universe, market) # We'll have testers push markets into the next round by funding dispute crowdsourcers amount = 2 * market.getParticipantStake() with TokenDelta(reputationToken, -amount, tester.a1, "Disputing did not reduce REP balance correctly"): assert market.contribute([0, market.getNumTicks()], False, amount, "", sender=tester.k1) newFeeWindowAddress = market.getFeeWindow() assert newFeeWindowAddress != feeWindow.address # fast forward time to the fee new window and generate additional fees feeWindow = localFixture.applySignature('FeeWindow', newFeeWindowAddress) localFixture.contracts["Time"].setTimestamp(feeWindow.getStartTime() + 1) # Fast forward time until the new fee window is over and we can redeem our winning stake, and dispute bond tokens and receive fees localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1) assert market.finalize() initialReporter = localFixture.applySignature('InitialReporter', market.getReportingParticipant(0)) marketDisputeCrowdsourcer = localFixture.applySignature('DisputeCrowdsourcer', market.getReportingParticipant(1)) # The dispute crowdsourcer contributor locked in REP for 2 rounds, as did the Initial Reporter expectedTotalFees = cash.balanceOf(feeWindow.address) + cash.balanceOf(universe.getOrCreateFeeWindowBefore(feeWindow.address)) expectedFees = expectedTotalFees * 2 / 3 expectedRep = market.getParticipantStake() assert expectedRep == long(marketDisputeCrowdsourcer.getStake() + marketDisputeCrowdsourcer.getStake() / 2) disputeCrowdsourcerRedeemedLog = { "reporter": bytesToHexString(tester.a1), "disputeCrowdsourcer": marketDisputeCrowdsourcer.address, "amountRedeemed": marketDisputeCrowdsourcer.getStake(), "repReceived": expectedRep, "reportingFeesReceived": expectedFees, "payoutNumerators": [0, market.getNumTicks()], "universe": universe.address, "market": market.address } with AssertLog(localFixture, "DisputeCrowdsourcerRedeemed", disputeCrowdsourcerRedeemedLog): with TokenDelta(reputationToken, expectedRep, tester.a1, "Redeeming didn't refund REP"): with EtherDelta(expectedFees, tester.a1, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert marketDisputeCrowdsourcer.redeem(tester.a1, sender=tester.k1) # The initial reporter gets fees even though they were not correct. They do not get their REP back though expectedFees = cash.balanceOf(feeWindow.address) + cash.balanceOf(universe.getOrCreateFeeWindowBefore(feeWindow.address)) with TokenDelta(reputationToken, 0, tester.a0, "Redeeming didn't refund REP"): with EtherDelta(expectedFees, tester.a0, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert initialReporter.redeem(tester.a0)
def test_one_round_crowdsourcer_fees(localFixture, universe, market, cash, reputationToken): feeWindow = localFixture.applySignature('FeeWindow', market.getFeeWindow()) constants = localFixture.contracts["Constants"] # We'll make the window active localFixture.contracts["Time"].setTimestamp(feeWindow.getStartTime() + 1) # generate some fees generateFees(localFixture, universe, market) # We'll have testers push markets into the next round by funding dispute crowdsourcers amount = 2 * market.getParticipantStake() with TokenDelta(reputationToken, -amount, tester.a1, "Disputing did not reduce REP balance correctly"): assert market.contribute([0, market.getNumTicks()], False, amount, sender=tester.k1) newFeeWindowAddress = market.getFeeWindow() assert newFeeWindowAddress != feeWindow.address # fast forward time to the fee new window and generate additional fees feeWindow = localFixture.applySignature('FeeWindow', newFeeWindowAddress) localFixture.contracts["Time"].setTimestamp(feeWindow.getStartTime() + 1) # Fast forward time until the new fee window is over and we can redeem our winning stake, and dispute bond tokens and receive fees localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1) assert market.finalize() initialReporter = localFixture.applySignature('InitialReporter', market.getReportingParticipant(0)) marketDisputeCrowdsourcer = localFixture.applySignature('DisputeCrowdsourcer', market.getReportingParticipant(1)) # The dispute crowdsourcer contributor locked in REP for 2 rounds, as did the Initial Reporter expectedTotalFees = cash.balanceOf(feeWindow.address) + cash.balanceOf(universe.getOrCreateFeeWindowBefore(feeWindow.address)) expectedFees = expectedTotalFees * 2 / 3 expectedRep = market.getParticipantStake() assert expectedRep == long(marketDisputeCrowdsourcer.getStake() + marketDisputeCrowdsourcer.getStake() / 2) disputeCrowdsourcerRedeemedLog = { "reporter": bytesToHexString(tester.a1), "disputeCrowdsourcer": marketDisputeCrowdsourcer.address, "amountRedeemed": marketDisputeCrowdsourcer.getStake(), "repReceived": expectedRep, "reportingFeesReceived": expectedFees, "payoutNumerators": [0, market.getNumTicks()], "universe": universe.address, "market": market.address } with AssertLog(localFixture, "DisputeCrowdsourcerRedeemed", disputeCrowdsourcerRedeemedLog): with TokenDelta(reputationToken, expectedRep, tester.a1, "Redeeming didn't refund REP"): with EtherDelta(expectedFees, tester.a1, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert marketDisputeCrowdsourcer.redeem(tester.a1, sender=tester.k1) # The initial reporter gets fees even though they were not correct. They do not get their REP back though expectedFees = cash.balanceOf(feeWindow.address) + cash.balanceOf(universe.getOrCreateFeeWindowBefore(feeWindow.address)) with TokenDelta(reputationToken, 0, tester.a0, "Redeeming didn't refund REP"): with EtherDelta(expectedFees, tester.a0, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert initialReporter.redeem(tester.a0)
def test_failed_crowdsourcer_fees(finalize, localFixture, universe, market, cash, reputationToken): feeWindow = localFixture.applySignature('FeeWindow', market.getFeeWindow()) # generate some fees generateFees(localFixture, universe, market) # We'll make the window active localFixture.contracts["Time"].setTimestamp(feeWindow.getStartTime() + 1) # generate some fees generateFees(localFixture, universe, market) # We'll have testers contribute to a dispute but not reach the target amount = market.getParticipantStake() # confirm we can contribute 0 assert market.contribute([1, market.getNumTicks()-1], False, 0, "", sender=tester.k1) with TokenDelta(reputationToken, -amount + 1, tester.a1, "Disputing did not reduce REP balance correctly"): assert market.contribute([1, market.getNumTicks()-1], False, amount - 1, "", sender=tester.k1) with TokenDelta(reputationToken, -amount + 1, tester.a2, "Disputing did not reduce REP balance correctly"): assert market.contribute([1, market.getNumTicks()-1], False, amount - 1, "", sender=tester.k2) assert market.getFeeWindow() == feeWindow.address payoutDistributionHash = market.derivePayoutDistributionHash([1, market.getNumTicks()-1], False) failedCrowdsourcer = localFixture.applySignature("DisputeCrowdsourcer", market.getCrowdsourcer(payoutDistributionHash)) # confirm we cannot contribute directly to a crowdsourcer without going through the market with raises(TransactionFailed): failedCrowdsourcer.contribute(tester.a0, 1) if finalize: # Fast forward time until the fee window is over and we can redeem to recieve the REP back and fees localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1) expectedTotalFees = getExpectedFees(localFixture, cash, failedCrowdsourcer, 1) else: # Continue to the next round which will disavow failed crowdsourcers and let us redeem once the window is over market.contribute([0, market.getNumTicks()], False, amount * 2, "") assert market.getFeeWindow() != feeWindow.address localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1) expectedTotalFees = getExpectedFees(localFixture, cash, failedCrowdsourcer, 1) with TokenDelta(reputationToken, amount - 1, tester.a1, "Redeeming did not refund REP"): with EtherDelta(expectedTotalFees / 2, tester.a1, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert failedCrowdsourcer.redeem(tester.a1) with TokenDelta(reputationToken, amount - 1, tester.a2, "Redeeming did not refund REP"): with EtherDelta(cash.balanceOf(failedCrowdsourcer.address), tester.a2, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert failedCrowdsourcer.redeem(tester.a2)
def test_failed_crowdsourcer_fees(finalize, localFixture, universe, market, cash, reputationToken): feeWindow = localFixture.applySignature('FeeWindow', market.getFeeWindow()) # generate some fees generateFees(localFixture, universe, market) # We'll make the window active localFixture.contracts["Time"].setTimestamp(feeWindow.getStartTime() + 1) # generate some fees generateFees(localFixture, universe, market) # We'll have testers contribute to a dispute but not reach the target amount = market.getParticipantStake() # confirm we can contribute 0 assert market.contribute([1, market.getNumTicks()-1], False, 0, sender=tester.k1) with TokenDelta(reputationToken, -amount + 1, tester.a1, "Disputing did not reduce REP balance correctly"): assert market.contribute([1, market.getNumTicks()-1], False, amount - 1, sender=tester.k1) with TokenDelta(reputationToken, -amount + 1, tester.a2, "Disputing did not reduce REP balance correctly"): assert market.contribute([1, market.getNumTicks()-1], False, amount - 1, sender=tester.k2) assert market.getFeeWindow() == feeWindow.address payoutDistributionHash = market.derivePayoutDistributionHash([1, market.getNumTicks()-1], False) failedCrowdsourcer = localFixture.applySignature("DisputeCrowdsourcer", market.getCrowdsourcer(payoutDistributionHash)) # confirm we cannot contribute directly to a crowdsourcer without going through the market with raises(TransactionFailed): failedCrowdsourcer.contribute(tester.a0, 1) if finalize: # Fast forward time until the fee window is over and we can redeem to recieve the REP back and fees localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1) expectedTotalFees = getExpectedFees(localFixture, cash, failedCrowdsourcer, 1) else: # Continue to the next round which will disavow failed crowdsourcers and let us redeem once the window is over market.contribute([0, market.getNumTicks()], False, amount * 2) assert market.getFeeWindow() != feeWindow.address localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1) expectedTotalFees = getExpectedFees(localFixture, cash, failedCrowdsourcer, 1) with TokenDelta(reputationToken, amount - 1, tester.a1, "Redeeming did not refund REP"): with EtherDelta(expectedTotalFees / 2, tester.a1, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert failedCrowdsourcer.redeem(tester.a1) with TokenDelta(reputationToken, amount - 1, tester.a2, "Redeeming did not refund REP"): with EtherDelta(cash.balanceOf(failedCrowdsourcer.address), tester.a2, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert failedCrowdsourcer.redeem(tester.a2)
def test_multiple_contributors_crowdsourcer_fees(localFixture, universe, market, cash, reputationToken): feeWindow = localFixture.applySignature('FeeWindow', market.getFeeWindow()) # We'll make the window active localFixture.contracts["Time"].setTimestamp(feeWindow.getStartTime() + 1) # generate some fees generateFees(localFixture, universe, market) # We'll have testers push markets into the next round by funding dispute crowdsourcers amount = market.getParticipantStake() with TokenDelta(reputationToken, -amount, tester.a1, "Disputing did not reduce REP balance correctly"): assert market.contribute([0, market.getNumTicks()], False, amount, sender=tester.k1) with TokenDelta(reputationToken, -amount, tester.a2, "Disputing did not reduce REP balance correctly"): assert market.contribute([0, market.getNumTicks()], False, amount, sender=tester.k2) newFeeWindowAddress = market.getFeeWindow() assert newFeeWindowAddress != feeWindow.address # fast forward time to the fee new window and generate additional fees feeWindow = localFixture.applySignature('FeeWindow', newFeeWindowAddress) localFixture.contracts["Time"].setTimestamp(feeWindow.getStartTime() + 1) # Fast forward time until the new fee window is over and we can redeem our winning stake, and dispute bond tokens and receive fees localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1) assert market.finalize() marketDisputeCrowdsourcer = localFixture.applySignature('DisputeCrowdsourcer', market.getReportingParticipant(1)) # The dispute crowdsourcer contributors locked in REP for 2 rounds and staked twice the initial reporter so they split 2/3 of the total stake expectedFees = cash.balanceOf(feeWindow.address) + cash.balanceOf(universe.getOrCreateFeeWindowBefore(feeWindow.address)) expectedFees = expectedFees / 3 * 2 expectedRep = long(amount + amount / 2) with TokenDelta(reputationToken, expectedRep, tester.a1, "Redeeming didn't refund REP"): with EtherDelta(expectedFees / 2, tester.a1, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert marketDisputeCrowdsourcer.redeem(tester.a1) with TokenDelta(reputationToken, expectedRep + 1, tester.a2, "Redeeming didn't refund REP"): with EtherDelta(expectedFees - expectedFees / 2, tester.a2, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert marketDisputeCrowdsourcer.redeem(tester.a2)
def test_buyback_from_reporting_fees(localFixture, universe, auction, reputationToken, time, market, cash): # We'll quickly do the bootstrap auction and seed it with some ETH startTime = auction.getAuctionStartTime() assert time.setTimestamp(startTime) # Buy 5000 REP repSalePrice = auction.getRepSalePriceInAttoEth() repAmount = 5000 * 10 ** 18 cost = repAmount * repSalePrice / 10 ** 18 with BuyWithCash(cash, cost, tester.k0, "trade eth for rep"): assert auction.tradeEthForRep(repAmount) # Now we'll go to the first real auction endTime = auction.getAuctionEndTime() assert time.setTimestamp(endTime + 1) startTime = auction.getAuctionStartTime() assert time.setTimestamp(startTime) # Generate some fees generateFees(localFixture, universe, market) feesGenerated = auction.feeBalance() # Now we'll sell some REP and we can see that the fees that were collected were used and that the REP provided was burned ethSalePrice = auction.getEthSalePriceInAttoRep() ethAmount = feesGenerated / 2 cost = ethAmount * ethSalePrice / 10 ** 18 totalRepSupply = reputationToken.totalSupply() assert auction.tradeRepForEth(ethAmount) assert totalRepSupply - reputationToken.totalSupply() == cost assert auction.feeBalance() == feesGenerated / 2 # If we now sell some REP again but do so by selling more than could be covered by remaining fees only a proportional amount of REP is actually burned ethAmount = feesGenerated cost = ethAmount * ethSalePrice / 10 ** 18 totalRepSupply = reputationToken.totalSupply() assert auction.tradeRepForEth(ethAmount) assert totalRepSupply - reputationToken.totalSupply() == cost / 2 assert auction.feeBalance() == 0
def test_initial_report_and_participation_fee_collection( localFixture, universe, market, categoricalMarket, scalarMarket, cash, reputationToken): feeWindow = localFixture.applySignature('FeeWindow', market.getFeeWindow()) constants = localFixture.contracts["Constants"] # We cannot purchase participation tokens yet since the window isn't active with raises(TransactionFailed): feeWindow.buy(1) # generate some fees generateFees(localFixture, universe, market) # We'll make the window active then purchase some participation tokens localFixture.contracts["Time"].setTimestamp(feeWindow.getStartTime() + 1) feeWindowAmount = 100 with TokenDelta(reputationToken, -feeWindowAmount, tester.a0, "Buying participation tokens didn't deduct REP correctly"): with TokenDelta( feeWindow, feeWindowAmount, tester.a0, "Buying participation tokens didn't increase participation token balance correctly" ): assert feeWindow.buy(feeWindowAmount) # As other testers we'll buy some more assert feeWindow.buy(feeWindowAmount, sender=tester.k1) assert feeWindow.buy(feeWindowAmount, sender=tester.k2) assert feeWindow.buy(feeWindowAmount, sender=tester.k3) # We can't redeem the participation tokens yet since the window isn't over with raises(TransactionFailed): feeWindow.redeem(False) # Now end the window and finalize localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1) assert market.finalize() assert categoricalMarket.finalize() assert scalarMarket.finalize() marketInitialReport = localFixture.applySignature( 'InitialReporter', market.getInitialReporter()) categoricalInitialReport = localFixture.applySignature( 'InitialReporter', categoricalMarket.getInitialReporter()) scalarInitialReport = localFixture.applySignature( 'InitialReporter', scalarMarket.getInitialReporter()) reporterFees = 1000 * market.getNumTicks( ) / universe.getOrCacheReportingFeeDivisor() totalStake = feeWindow.getTotalFeeStake() assert cash.balanceOf(feeWindow.address) == reporterFees expectedParticipationFees = reporterFees * feeWindowAmount / totalStake # Cashing out Participation tokens will awards fees proportional to the total winning stake in the window with TokenDelta(reputationToken, feeWindowAmount, tester.a0, "Redeeming participation tokens didn't refund REP"): with TokenDelta( feeWindow, -feeWindowAmount, tester.a0, "Redeeming participation tokens didn't decrease participation token balance correctly" ): with EtherDelta( expectedParticipationFees, tester.a0, localFixture.chain, "Redeeming participation tokens didn't increase ETH correctly" ): assert feeWindow.redeem(tester.a0) with TokenDelta(reputationToken, feeWindowAmount, tester.a1, "Redeeming participation tokens didn't refund REP"): with TokenDelta( feeWindow, -feeWindowAmount, tester.a1, "Redeeming participation tokens didn't decrease participation token balance correctly" ): with EtherDelta( expectedParticipationFees, tester.a1, localFixture.chain, "Redeeming participation tokens didn't increase ETH correctly" ): assert feeWindow.redeem(tester.a1) with TokenDelta(reputationToken, feeWindowAmount, tester.a2, "Redeeming participation tokens didn't refund REP"): with TokenDelta( feeWindow, -feeWindowAmount, tester.a2, "Redeeming participation tokens didn't decrease participation token balance correctly" ): with EtherDelta( expectedParticipationFees, tester.a2, localFixture.chain, "Redeeming participation tokens didn't increase ETH correctly" ): assert feeWindow.redeem(tester.a2) logs = [] captureFilteredLogs(localFixture.chain.head_state, localFixture.contracts['Augur'], logs) marketStake = marketInitialReport.getStake() expectedFees = reporterFees * marketStake / totalStake winningsRedeemedLog = { "reporter": bytesToHexString(tester.a0), "reportingParticipant": marketInitialReport.address, "amountRedeemed": marketStake, "reportingFeesReceived": expectedFees, "payoutNumerators": [market.getNumTicks(), 0], "universe": universe.address, "market": market.address } with AssertLog(localFixture, "WinningsRedeemed", winningsRedeemedLog): with TokenDelta(reputationToken, marketStake, tester.a0, "Redeeming didn't refund REP"): with EtherDelta(expectedFees, tester.a0, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert marketInitialReport.redeem(tester.a0) categoricalMarketStake = categoricalInitialReport.getStake() expectedFees = reporterFees * categoricalMarketStake / totalStake with TokenDelta(reputationToken, categoricalMarketStake, tester.a0, "Redeeming didn't refund REP"): with EtherDelta(expectedFees, tester.a0, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert categoricalInitialReport.redeem(tester.a0)
def test_initial_report_and_participation_fee_collection(localFixture, universe, market, categoricalMarket, scalarMarket, cash, reputationToken): feeWindow = localFixture.applySignature('FeeWindow', market.getFeeWindow()) constants = localFixture.contracts["Constants"] # We cannot purchase participation tokens yet since the window isn't active with raises(TransactionFailed): feeWindow.buy(1) # generate some fees generateFees(localFixture, universe, market) # We'll make the window active then purchase some participation tokens localFixture.contracts["Time"].setTimestamp(feeWindow.getStartTime() + 1) feeWindowAmount = 100 with TokenDelta(reputationToken, -feeWindowAmount, tester.a0, "Buying participation tokens didn't deduct REP correctly"): with TokenDelta(feeWindow, feeWindowAmount, tester.a0, "Buying participation tokens didn't increase participation token balance correctly"): assert feeWindow.buy(feeWindowAmount) # As other testers we'll buy some more assert feeWindow.buy(feeWindowAmount, sender=tester.k1) assert feeWindow.buy(feeWindowAmount, sender=tester.k2) assert feeWindow.buy(feeWindowAmount, sender=tester.k3) # We can't redeem the participation tokens yet since the window isn't over with raises(TransactionFailed): feeWindow.redeem(False) # Now end the window and finalize localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1) assert market.finalize() assert categoricalMarket.finalize() assert scalarMarket.finalize() marketInitialReport = localFixture.applySignature('InitialReporter', market.getInitialReporter()) categoricalInitialReport = localFixture.applySignature('InitialReporter', categoricalMarket.getInitialReporter()) scalarInitialReport = localFixture.applySignature('InitialReporter', scalarMarket.getInitialReporter()) reporterFees = 1000 * market.getNumTicks() / universe.getOrCacheReportingFeeDivisor() totalStake = feeWindow.getTotalFeeStake() assert cash.balanceOf(feeWindow.address) == reporterFees expectedParticipationFees = reporterFees * feeWindowAmount / totalStake # Cashing out Participation tokens will awards fees proportional to the total winning stake in the window with TokenDelta(reputationToken, feeWindowAmount, tester.a0, "Redeeming participation tokens didn't refund REP"): with TokenDelta(feeWindow, -feeWindowAmount, tester.a0, "Redeeming participation tokens didn't decrease participation token balance correctly"): with EtherDelta(expectedParticipationFees, tester.a0, localFixture.chain, "Redeeming participation tokens didn't increase ETH correctly"): assert feeWindow.redeem(tester.a0) with TokenDelta(reputationToken, feeWindowAmount, tester.a1, "Redeeming participation tokens didn't refund REP"): with TokenDelta(feeWindow, -feeWindowAmount, tester.a1, "Redeeming participation tokens didn't decrease participation token balance correctly"): with EtherDelta(expectedParticipationFees, tester.a1, localFixture.chain, "Redeeming participation tokens didn't increase ETH correctly"): assert feeWindow.redeem(tester.a1) with TokenDelta(reputationToken, feeWindowAmount, tester.a2, "Redeeming participation tokens didn't refund REP"): with TokenDelta(feeWindow, -feeWindowAmount, tester.a2, "Redeeming participation tokens didn't decrease participation token balance correctly"): with EtherDelta(expectedParticipationFees, tester.a2, localFixture.chain, "Redeeming participation tokens didn't increase ETH correctly"): assert feeWindow.redeem(tester.a2) marketStake = marketInitialReport.getStake() expectedFees = reporterFees * marketStake / totalStake initialReporterRedeemedLog = { "reporter": bytesToHexString(tester.a0), "amountRedeemed": marketStake, "repReceived": marketStake, "reportingFeesReceived": expectedFees, "payoutNumerators": [market.getNumTicks(), 0], "universe": universe.address, "market": market.address } with AssertLog(localFixture, "InitialReporterRedeemed", initialReporterRedeemedLog): with TokenDelta(reputationToken, marketStake, tester.a0, "Redeeming didn't refund REP"): with EtherDelta(expectedFees, tester.a0, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert marketInitialReport.redeem(tester.a0) categoricalMarketStake = categoricalInitialReport.getStake() expectedFees = reporterFees * categoricalMarketStake / totalStake with TokenDelta(reputationToken, categoricalMarketStake, tester.a0, "Redeeming didn't refund REP"): with EtherDelta(expectedFees, tester.a0, localFixture.chain, "Redeeming didn't increase ETH correctly"): assert categoricalInitialReport.redeem(tester.a0)