def test_invalid_first_report(localFixture, universe, cash, market): reportingWindow = localFixture.applySignature('ReportingWindow', market.getReportingWindow()) reputationToken = localFixture.applySignature('ReputationToken', universe.getReputationToken()) expectedReportingWindowFeePayout = universe.getOrCacheValidityBond() # Proceed to the FIRST REPORTING phase proceedToFirstReporting(localFixture, universe, market, False, 1, [0,market.getNumTicks()], [market.getNumTicks(),0]) # We make an invalid report stakeTokenInvalid = localFixture.getOrCreateStakeToken(market, [long(0.5 * market.getNumTicks()), long(0.5 * market.getNumTicks())], True) stakeTokenInvalid.buy(1, sender=tester.k2) assert stakeTokenInvalid.balanceOf(tester.a2) == 1 + universe.getOrCacheDesignatedReportNoShowBond() tentativeWinner = market.getTentativeWinningPayoutDistributionHash() assert tentativeWinner == stakeTokenInvalid.getPayoutDistributionHash() assert not stakeTokenInvalid.isValid() # If we finalize the market it will be recorded as an invalid result initialReportingWindowCashBalance = cash.balanceOf(reportingWindow.address) localFixture.chain.head_state.timestamp = reportingWindow.getEndTime() + 1 assert market.tryFinalize() assert not market.isValid() assert reportingWindow.getNumInvalidMarkets() == 1 # Since the market resolved with an invalid outcome the validity bond is paid out to the reporting window in Cash increaseInReportingWindowBalance = cash.balanceOf(reportingWindow.address) - initialReportingWindowCashBalance assert increaseInReportingWindowBalance == expectedReportingWindowFeePayout
def test_firstReportingHappyPath(makeReport, localFixture, universe, market): reportingWindow = localFixture.applySignature('ReportingWindow', market.getReportingWindow()) reputationToken = localFixture.applySignature('ReputationToken', universe.getReputationToken()) # Proceed to the FIRST REPORTING phase proceedToFirstReporting(localFixture, universe, market, makeReport, 1, [0,market.getNumTicks()], [market.getNumTicks(),0]) logs = [] captureFilteredLogs(localFixture.chain.head_state, localFixture.contracts['Augur'], logs) # We make one report by Tester 2 stakeTokenYes = localFixture.getOrCreateStakeToken(market, [0,market.getNumTicks()]) stakeTokenYes.buy(1, sender=tester.k2) # If there ws no designated report he first reporter gets the no-show REP bond auto-staked on the outcome they're purchasing expectedStakeTokenBalance = 1 if (not makeReport): expectedStakeTokenBalance += universe.getOrCacheDesignatedReportNoShowBond() assert stakeTokenYes.balanceOf(tester.a2) == expectedStakeTokenBalance # Confirm the report logging works log = logs[2] if not makeReport: log = logs[3] assert len(logs) == 4 else: assert len(logs) == 3 assert log['_event_type'] == 'ReportSubmitted' assert log['amountStaked'] == expectedStakeTokenBalance assert log['reporter'] == bytesToHexString(tester.a2) assert log['stakeToken'] == localFixture.getOrCreateStakeToken(market, [0,market.getNumTicks()]).address assert log['market'] == market.address assert log['payoutNumerators'] == [0,market.getNumTicks()] assert reputationToken.balanceOf(tester.a2) == 1 * 10 ** 6 * 10 ** 18 - 1 tentativeWinner = market.getTentativeWinningPayoutDistributionHash() if (makeReport): # The tentative winner will be the No outcome at first since we disputed Yes and have to stake on an outcome in that case stakeTokenNo = localFixture.getOrCreateStakeToken(market, [market.getNumTicks(),0]) assert tentativeWinner == stakeTokenNo.getPayoutDistributionHash() # If we buy the full designated bond amount we will be back to the YES outcome winning stakeTokenYes.buy(localFixture.contracts['Constants'].DESIGNATED_REPORTER_DISPUTE_BOND_AMOUNT(), sender=tester.k2) tentativeWinner = market.getTentativeWinningPayoutDistributionHash() assert tentativeWinner == stakeTokenYes.getPayoutDistributionHash() # To progress into the FIRST DISPUTE phase we move time forward localFixture.chain.head_state.timestamp = reportingWindow.getDisputeStartTime() + 1 assert market.getReportingState() == localFixture.contracts['Constants'].FIRST_DISPUTE() # If time passes and no dispute bond is placed the market can be finalized localFixture.chain.head_state.timestamp = reportingWindow.getDisputeEndTime() + 1 # The market is awaiting finalization now assert market.getReportingState() == localFixture.contracts['Constants'].AWAITING_FINALIZATION() # We can finalize it assert market.tryFinalize() assert market.getReportingState() == localFixture.contracts['Constants'].FINALIZED()
def test_target_reporter_gas_costs(numReports, gasPrice, reportingFixture, universe, market): # The target reporter gas cost is an attempt to charge the market creator for the estimated cost of reporting that may occur for their market. It will use the previous reporting window's data to estimate costs if it is available reportingWindow = reportingFixture.applySignature('ReportingWindow', market.getReportingWindow()) # We'll have a market go through basic reporting and then make its reporting window over. proceedToFirstReporting(reportingFixture, universe, market, False, 1, [0,10**18], [10**18,0]) stakeTokenYes = reportingFixture.getStakeToken(market, [0,10**18]) for i in range(0,numReports): assert stakeTokenYes.buy(1, sender=getattr(tester, 'k%i' % i), gasprice=gasPrice) # Now we'll skip ahead in time and finalzie the market reportingFixture.chain.head_state.timestamp = reportingWindow.getEndTime() + 1 assert market.tryFinalize() actualAvgGasPrice = reportingWindow.getAvgReportingGasPrice() expectedAvgReportingGasCost = (reportingFixture.contracts['Constants'].DEFAULT_REPORTING_GAS_PRICE() + gasPrice * numReports) / (numReports + 1) assert actualAvgGasPrice == expectedAvgReportingGasCost # Confirm our estimated gas cost is caluclated as expected expectedTargetReporterGasCost = reportingFixture.contracts['Constants'].GAS_TO_REPORT() expectedTargetReporterGasCost *= expectedAvgReportingGasCost expectedTargetReporterGasCost *= 2 targetReporterGasCosts = universe.getTargetReporterGasCosts() assert targetReporterGasCosts == expectedTargetReporterGasCost
def test_lastReportingHappyPath(localFixture, makeReport, universe, market, cash): newMarket = localFixture.createReasonableBinaryMarket(universe, cash) completeSets = localFixture.contracts['CompleteSets'] reputationToken = localFixture.applySignature('ReputationToken', universe.getReputationToken()) reportingWindow = localFixture.applySignature('ReportingWindow', market.getReportingWindow()) # Generate some fees to confirm the market migration also migrates proportional fees cost = 10 * market.getNumTicks() assert completeSets.publicBuyCompleteSets(market.address, 10, sender=tester.k1, value=cost) assert completeSets.publicSellCompleteSets(market.address, 10, sender=tester.k1) fees = cash.balanceOf(newMarket.getReportingWindow()) assert fees > 0 # We'll proceed to the designated reporting phase so that there is also stake from a market that does not migrate proceedToFirstReporting(localFixture, universe, newMarket, makeReport, 1, [0,market.getNumTicks()], [market.getNumTicks(),0]) newMarketStakeToken = localFixture.getOrCreateStakeToken(newMarket, [0,market.getNumTicks()]) firstDisputeStake = localFixture.contracts["Constants"].FIRST_REPORTERS_DISPUTE_BOND_AMOUNT() assert newMarketStakeToken.buy(firstDisputeStake) # Proceed to the LAST REPORTING phase for the main market originalReportingWindowStake = reportingWindow.getTotalStake() assert originalReportingWindowStake > 0 proceedToLastReporting(localFixture, universe, market, makeReport, 1, 3, [0,market.getNumTicks()], [market.getNumTicks(),0], 2, [market.getNumTicks(),0], [0,market.getNumTicks()]) # Confirm that fees have moved proportionally when the market migrated from the first dispute reportingWindow = localFixture.applySignature('ReportingWindow', market.getReportingWindow()) expectedMigratedFees = fees / 2 assert cash.balanceOf(market.getReportingWindow()) == expectedMigratedFees stakeTokenNo = localFixture.getOrCreateStakeToken(market, [market.getNumTicks(),0]) stakeTokenYes = localFixture.getOrCreateStakeToken(market, [0,market.getNumTicks()]) # When disputing the FIRST REPORT outcome enough was staked on the other outcome that it is now the winner tentativeWinner = market.getTentativeWinningPayoutDistributionHash() assert tentativeWinner == stakeTokenYes.getPayoutDistributionHash() # If we buy the delta between outcome stakes that will be sufficient to make the outcome win noStake = market.getPayoutDistributionHashStake(stakeTokenNo.getPayoutDistributionHash()) yesStake = market.getPayoutDistributionHashStake(stakeTokenYes.getPayoutDistributionHash()) stakeDelta = yesStake - noStake stakeTokenNo.buy(stakeDelta + 1, sender=tester.k3) tentativeWinner = market.getTentativeWinningPayoutDistributionHash() assert tentativeWinner == stakeTokenNo.getPayoutDistributionHash() # To progress into the LAST DISPUTE phase we move time forward localFixture.chain.head_state.timestamp = reportingWindow.getDisputeStartTime() + 1 assert market.getReportingState() == localFixture.contracts['Constants'].LAST_DISPUTE() # If time passes and no dispute bond is placed the market can be finalized localFixture.chain.head_state.timestamp = reportingWindow.getDisputeEndTime() + 1 # The market is awaiting finalization now assert market.getReportingState() == localFixture.contracts['Constants'].AWAITING_FINALIZATION() # We can finalize it assert market.tryFinalize() assert market.getReportingState() == localFixture.contracts['Constants'].FINALIZED()
def test_report(localFixture, universe, cash, market): proceedToFirstReporting(localFixture, universe, market, False, 1, [0, 10**18], [10**18, 0]) stakeTokenYes = localFixture.getStakeToken(market, [0, 10**18]) with PrintGasUsed(localFixture, "FIRST StakeToken:buy", FIRST_REPORT): stakeTokenYes.buy(0, sender=tester.k2) with PrintGasUsed(localFixture, "SECOND StakeToken:buy", SECOND_REPORT): stakeTokenYes.buy(1, sender=tester.k2)
def test_disputeFirst(localFixture, universe, cash, market): proceedToFirstReporting(localFixture, universe, market, True, 1, [0, 10**18], [10**18, 0]) reportingWindow = localFixture.applySignature("ReportingWindow", market.getReportingWindow()) localFixture.chain.head_state.timestamp = reportingWindow.getDisputeStartTime( ) + 1 with PrintGasUsed(localFixture, "Market:disputeFirstReporters", FIRST_DISPUTE): assert market.disputeFirstReporters([1, market.getNumTicks() - 1], 1, False, sender=tester.k2)
def test_stake_token_redemption(localFixture, universe, market, numReports, numCorrect): reportingWindow = localFixture.applySignature('ReportingWindow', market.getReportingWindow()) reputationToken = localFixture.applySignature( 'ReputationToken', reportingWindow.getReputationToken()) # Proceed to FIRST REPORTING proceedToFirstReporting(localFixture, universe, market, False, 1, [0, 10**18], [10**18, 0]) noShowBond = universe.getDesignatedReportNoShowBond() doReports(localFixture, market, numReports, numCorrect) confirmPayouts(localFixture, market, numCorrect, noShowBond)
def test_noReports(localFixture, pastDisputePhase, universe, market): # Proceed to the FIRST REPORTING phase proceedToFirstReporting(localFixture, universe, market, False, 1, [0,market.getNumTicks()], [market.getNumTicks(),0]) reportingWindow = localFixture.applySignature('ReportingWindow', market.getReportingWindow()) if (pastDisputePhase): localFixture.chain.head_state.timestamp = reportingWindow.getEndTime() + 1 else: localFixture.chain.head_state.timestamp = reportingWindow.getDisputeStartTime() + 1 # If we receive no reports by the time Limited Reporting is finished we will be in the AWAITING NO REPORT MIGRATION phase assert market.getReportingState() == localFixture.contracts['Constants'].AWAITING_NO_REPORT_MIGRATION() # We can try to report on the market, which will move it to the next reporting window where it will be back in FIRST REPORTING stakeToken = localFixture.getOrCreateStakeToken(market, [0,market.getNumTicks()]) assert stakeToken.buy(1, sender=tester.k2) assert market.getReportingState() == localFixture.contracts['Constants'].FIRST_REPORTING() assert market.getReportingWindow() != reportingWindow.address