def test_redeem_reporting_participants(kitchenSinkFixture, market, categoricalMarket, scalarMarket, universe, cash):
    reputationToken = kitchenSinkFixture.applySignature("ReputationToken", universe.getReputationToken())
    constants = kitchenSinkFixture.contracts["Constants"]

    # Initial Report
    proceedToNextRound(kitchenSinkFixture, market, doGenerateFees = True)
    # Initial Report Losing
    proceedToNextRound(kitchenSinkFixture, market, doGenerateFees = True)
    # Initial Report Winning
    proceedToNextRound(kitchenSinkFixture, market, doGenerateFees = True)
    # Initial Report Losing
    proceedToNextRound(kitchenSinkFixture, market, doGenerateFees = True)
    # Initial Report Winning
    proceedToNextRound(kitchenSinkFixture, market, doGenerateFees = True)

    # Get the winning reporting participants
    initialReporter = kitchenSinkFixture.applySignature('InitialReporter', market.getReportingParticipant(0))
    winningDisputeCrowdsourcer1 = kitchenSinkFixture.applySignature('DisputeCrowdsourcer', market.getReportingParticipant(2))
    winningDisputeCrowdsourcer2 = kitchenSinkFixture.applySignature('DisputeCrowdsourcer', market.getReportingParticipant(4))

    # Fast forward time until the new fee window is over and we can redeem
    feeWindow = kitchenSinkFixture.applySignature("FeeWindow", market.getFeeWindow())
    kitchenSinkFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1)
    assert market.finalize()

    expectedFees = getExpectedFees(kitchenSinkFixture, cash, winningDisputeCrowdsourcer1, 4)
    expectedFees += getExpectedFees(kitchenSinkFixture, cash, winningDisputeCrowdsourcer2, 2)
    expectedFees += getExpectedFees(kitchenSinkFixture, cash, initialReporter, 5)
    expectedRep = long(winningDisputeCrowdsourcer2.getStake() + winningDisputeCrowdsourcer1.getStake())
    expectedRep = long(expectedRep + expectedRep / 2)
    expectedRep += long(initialReporter.getStake() + initialReporter.getStake() / 2)
    with TokenDelta(reputationToken, expectedRep, tester.a0, "Redeeming didn't refund REP"):
        with PrintGasUsed(kitchenSinkFixture, "Universe Redeem:", 0):
            assert universe.redeemStake([initialReporter.address, winningDisputeCrowdsourcer1.address, winningDisputeCrowdsourcer2.address], [])
Пример #2
0
def test_redeem_reporting_participants(kitchenSinkFixture, market,
                                       categoricalMarket, scalarMarket,
                                       universe, cash):
    reputationToken = kitchenSinkFixture.applySignature(
        "ReputationToken", universe.getReputationToken())
    constants = kitchenSinkFixture.contracts["Constants"]

    # Initial Report
    proceedToNextRound(kitchenSinkFixture, market, doGenerateFees=True)
    # Initial Report Losing
    proceedToNextRound(kitchenSinkFixture, market, doGenerateFees=True)
    # Initial Report Winning
    proceedToNextRound(kitchenSinkFixture, market, doGenerateFees=True)
    # Initial Report Losing
    proceedToNextRound(kitchenSinkFixture, market, doGenerateFees=True)
    # Initial Report Winning
    proceedToNextRound(kitchenSinkFixture, market, doGenerateFees=True)

    # Get the winning reporting participants
    initialReporter = kitchenSinkFixture.applySignature(
        'InitialReporter', market.getReportingParticipant(0))
    winningDisputeCrowdsourcer1 = kitchenSinkFixture.applySignature(
        'DisputeCrowdsourcer', market.getReportingParticipant(2))
    winningDisputeCrowdsourcer2 = kitchenSinkFixture.applySignature(
        'DisputeCrowdsourcer', market.getReportingParticipant(4))

    # Fast forward time until the new fee window is over and we can redeem
    feeWindow = kitchenSinkFixture.applySignature("FeeWindow",
                                                  market.getFeeWindow())
    kitchenSinkFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() +
                                                      1)
    assert market.finalize()

    expectedFees = getExpectedFees(kitchenSinkFixture, cash,
                                   winningDisputeCrowdsourcer1, 4)
    expectedFees += getExpectedFees(kitchenSinkFixture, cash,
                                    winningDisputeCrowdsourcer2, 2)
    expectedFees += getExpectedFees(kitchenSinkFixture, cash, initialReporter,
                                    5)
    expectedRep = long(winningDisputeCrowdsourcer2.getStake() +
                       winningDisputeCrowdsourcer1.getStake())
    expectedRep = long(expectedRep + expectedRep / 2)
    expectedRep += long(initialReporter.getStake() +
                        initialReporter.getStake() / 2)
    expectedGasBond = 2 * constants.GAS_TO_REPORT(
    ) * constants.DEFAULT_REPORTING_GAS_PRICE()
    with TokenDelta(reputationToken, expectedRep, tester.a0,
                    "Redeeming didn't refund REP"):
        with PrintGasUsed(kitchenSinkFixture, "Universe Redeem:", 0):
            assert universe.redeemStake([
                initialReporter.address, winningDisputeCrowdsourcer1.address,
                winningDisputeCrowdsourcer2.address
            ], [])
Пример #3
0
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_forking(localFixture, universe, market, categoricalMarket, cash, reputationToken):
    # Let's do some initial disputes for the categorical market
    proceedToNextRound(localFixture, categoricalMarket, tester.k1, moveTimeForward = False)

    # Get to a fork
    testers = [tester.k0, tester.k1, tester.k2, tester.k3]
    testerIndex = 1
    while (market.getForkingMarket() == longToHexString(0)):
        proceedToNextRound(localFixture, market, testers[testerIndex], True)
        testerIndex += 1
        testerIndex = testerIndex % len(testers)

    # Have the participants fork and create new child universes
    reportingParticipant = localFixture.applySignature("DisputeCrowdsourcer", market.getReportingParticipant(0))
    ReportingParticipantDisavowedLog = {
        "universe": universe.address,
        "market": market.address,
        "reportingParticipant": reportingParticipant.address,
    }
    with AssertLog(localFixture, "ReportingParticipantDisavowed", ReportingParticipantDisavowedLog):
        reportingParticipant.fork()

    for i in range(1, market.getNumParticipants()):
        reportingParticipant = localFixture.applySignature("DisputeCrowdsourcer", market.getReportingParticipant(i))
        reportingParticipant.fork()

    # Finalize the fork
    finalizeFork(localFixture, market, universe)

    categoricalDisputeCrowdsourcer = localFixture.applySignature("DisputeCrowdsourcer", categoricalMarket.getReportingParticipant(1))

    # Migrate the categorical market into the winning universe. This will disavow the dispute crowdsourcer on it, letting us redeem for original universe rep and eth
    assert categoricalMarket.migrateThroughOneFork()

    expectedRep = categoricalDisputeCrowdsourcer.getStake()
    expectedEth = getExpectedFees(localFixture, cash, categoricalDisputeCrowdsourcer, 2)
    with EtherDelta(expectedEth, tester.a1, localFixture.chain, "Redeeming didn't increase ETH correctly"):
        with TokenDelta(reputationToken, expectedRep, tester.a1, "Redeeming didn't increase REP correctly"):
            categoricalDisputeCrowdsourcer.redeem(tester.a1)

    # Now we'll redeem the forked reporting participants
    testers = [tester.a0, tester.a1, tester.a2, tester.a3]
    for i in range(market.getNumParticipants()):
        account = testers[i % 4]
        reportingParticipant = localFixture.applySignature("DisputeCrowdsourcer", market.getReportingParticipant(i))
        expectedRep = reportingParticipant.getStake()
        expectedRep += expectedRep / localFixture.contracts["Constants"].FORK_MIGRATION_PERCENTAGE_BONUS_DIVISOR()
        expectedRep += reportingParticipant.getStake() / 2
        expectedEth = cash.balanceOf(reportingParticipant.address)
        newReputationToken = localFixture.applySignature("ReputationToken", reportingParticipant.getReputationToken())
        with EtherDelta(expectedEth, account, localFixture.chain, "Redeeming didn't increase ETH correctly"):
            with TokenDelta(newReputationToken, expectedRep, account, "Redeeming didn't increase REP correctly"):
                reportingParticipant.redeem(account)
def test_forkAndRedeem(localFixture, universe, market, categoricalMarket, cash, reputationToken):
    # Let's do some initial disputes for the categorical market
    proceedToNextRound(localFixture, categoricalMarket, tester.k1, moveTimeForward = False)

    # Get to a fork
    testers = [tester.k0, tester.k1, tester.k2, tester.k3]
    testerIndex = 1
    while (market.getForkingMarket() == longToHexString(0)):
        proceedToNextRound(localFixture, market, testers[testerIndex], True)
        testerIndex += 1
        testerIndex = testerIndex % len(testers)

    # Have the participants fork and create new child universes
    for i in range(market.getNumParticipants()):
        reportingParticipant = localFixture.applySignature("DisputeCrowdsourcer", market.getReportingParticipant(i))

    # Finalize the fork
    finalizeFork(localFixture, market, universe)

    categoricalDisputeCrowdsourcer = localFixture.applySignature("DisputeCrowdsourcer", categoricalMarket.getReportingParticipant(1))

    # Migrate the categorical market into the winning universe. This will disavow the dispute crowdsourcer on it, letting us redeem for original universe rep and eth
    assert categoricalMarket.migrateThroughOneFork()

    expectedRep = categoricalDisputeCrowdsourcer.getStake()
    expectedEth = getExpectedFees(localFixture, cash, categoricalDisputeCrowdsourcer, 2)
    with EtherDelta(expectedEth, tester.a1, localFixture.chain, "Redeeming didn't increase ETH correctly"):
        with TokenDelta(reputationToken, expectedRep, tester.a1, "Redeeming didn't increase REP correctly"):
            categoricalDisputeCrowdsourcer.redeem(tester.a1)

    noPayoutNumerators = [0] * market.getNumberOfOutcomes()
    noPayoutNumerators[0] = market.getNumTicks()
    yesPayoutNumerators = noPayoutNumerators[::-1]
    noUniverse =  localFixture.applySignature('Universe', universe.createChildUniverse(noPayoutNumerators, False))
    yesUniverse =  localFixture.applySignature('Universe', universe.createChildUniverse(yesPayoutNumerators, False))
    noUniverseReputationToken = localFixture.applySignature('ReputationToken', noUniverse.getReputationToken())
    yesUniverseReputationToken = localFixture.applySignature('ReputationToken', yesUniverse.getReputationToken())

    # Now we'll fork and redeem the reporting participants
    for i in range(market.getNumParticipants()):
        account = localFixture.testerAddress[i % 4]
        key = localFixture.testerKey[i % 4]
        reportingParticipant = localFixture.applySignature("DisputeCrowdsourcer", market.getReportingParticipant(i))
        expectedRep = reportingParticipant.getStake()
        expectedRep += expectedRep / localFixture.contracts["Constants"].FORK_MIGRATION_PERCENTAGE_BONUS_DIVISOR()
        expectedRep += reportingParticipant.getStake() / 2
        repToken = noUniverseReputationToken if i % 2 == 0 else yesUniverseReputationToken
        with TokenDelta(repToken, expectedRep, account, "Redeeming didn't increase REP correctly for " + str(i)):
            assert reportingParticipant.forkAndRedeem(sender=key)
Пример #7
0
def test_forkAndRedeem(localFixture, universe, market, categoricalMarket, cash, reputationToken):
    # Let's do some initial disputes for the categorical market
    proceedToNextRound(localFixture, categoricalMarket, tester.k1, moveTimeForward = False)

    # Get to a fork
    testers = [tester.k0, tester.k1, tester.k2, tester.k3]
    testerIndex = 1
    while (market.getForkingMarket() == longToHexString(0)):
        proceedToNextRound(localFixture, market, testers[testerIndex], True)
        testerIndex += 1
        testerIndex = testerIndex % len(testers)

    # Have the participants fork and create new child universes
    for i in range(market.getNumParticipants()):
        reportingParticipant = localFixture.applySignature("DisputeCrowdsourcer", market.getReportingParticipant(i))

    # Finalize the fork
    finalizeFork(localFixture, market, universe)

    categoricalDisputeCrowdsourcer = localFixture.applySignature("DisputeCrowdsourcer", categoricalMarket.getReportingParticipant(1))

    # Migrate the categorical market into the winning universe. This will disavow the dispute crowdsourcer on it, letting us redeem for original universe rep and eth
    assert categoricalMarket.migrateThroughOneFork([0,0,categoricalMarket.getNumTicks()], False, "")

    expectedRep = categoricalDisputeCrowdsourcer.getStake()
    expectedEth = getExpectedFees(localFixture, cash, categoricalDisputeCrowdsourcer, 1)
    with EtherDelta(expectedEth, tester.a1, localFixture.chain, "Redeeming didn't increase ETH correctly"):
        with TokenDelta(reputationToken, expectedRep, tester.a1, "Redeeming didn't increase REP correctly"):
            categoricalDisputeCrowdsourcer.redeem(tester.a1)

    noPayoutNumerators = [0] * market.getNumberOfOutcomes()
    noPayoutNumerators[0] = market.getNumTicks()
    yesPayoutNumerators = noPayoutNumerators[::-1]
    noUniverse =  localFixture.applySignature('Universe', universe.createChildUniverse(noPayoutNumerators, False))
    yesUniverse =  localFixture.applySignature('Universe', universe.createChildUniverse(yesPayoutNumerators, False))
    noUniverseReputationToken = localFixture.applySignature('ReputationToken', noUniverse.getReputationToken())
    yesUniverseReputationToken = localFixture.applySignature('ReputationToken', yesUniverse.getReputationToken())

    # Now we'll fork and redeem the reporting participants
    for i in range(market.getNumParticipants()):
        account = localFixture.testerAddress[i % 4]
        key = localFixture.testerKey[i % 4]
        reportingParticipant = localFixture.applySignature("DisputeCrowdsourcer", market.getReportingParticipant(i))
        expectedRep = reportingParticipant.getStake()
        expectedRep += reportingParticipant.getStake() / 2
        repToken = noUniverseReputationToken if i % 2 == 0 else yesUniverseReputationToken
        with TokenDelta(repToken, expectedRep, account, "Redeeming didn't increase REP correctly for " + str(i)):
            assert reportingParticipant.forkAndRedeem(sender=key)
def test_forking(localFixture, universe, market, categoricalMarket, cash,
                 reputationToken):
    # Let's do some initial disputes for the categorical market
    proceedToNextRound(localFixture,
                       categoricalMarket,
                       tester.k1,
                       moveTimeForward=False)

    # Get to a fork
    testers = [tester.k0, tester.k1, tester.k2, tester.k3]
    testerIndex = 1
    while (market.getForkingMarket() == longToHexString(0)):
        proceedToNextRound(localFixture, market, testers[testerIndex], True)
        testerIndex += 1
        testerIndex = testerIndex % len(testers)

    # Have the participants fork and create new child universes
    for i in range(market.getNumParticipants()):
        reportingParticipant = localFixture.applySignature(
            "DisputeCrowdsourcer", market.getReportingParticipant(i))
        with PrintGasUsed(localFixture, "Fork:", 0):
            reportingParticipant.fork(startgas=long(6.7 * 10**6))

    # Finalize the fork
    finalizeFork(localFixture, market, universe)

    categoricalDisputeCrowdsourcer = localFixture.applySignature(
        "DisputeCrowdsourcer", categoricalMarket.getReportingParticipant(1))

    # Migrate the categorical market into the winning universe. This will disavow the dispute crowdsourcer on it, letting us redeem for original universe rep and eth
    assert categoricalMarket.migrateThroughOneFork()

    expectedRep = categoricalDisputeCrowdsourcer.getStake()
    expectedEth = getExpectedFees(localFixture, cash,
                                  categoricalDisputeCrowdsourcer, 2)
    with EtherDelta(expectedEth, tester.a1, localFixture.chain,
                    "Redeeming didn't increase ETH correctly"):
        with TokenDelta(reputationToken, expectedRep, tester.a1,
                        "Redeeming didn't increase REP correctly"):
            categoricalDisputeCrowdsourcer.redeem(tester.a1,
                                                  startgas=long(6.7 * 10**6))

    # Now we'll redeem the forked reporting participants
    testers = [tester.a0, tester.a1, tester.a2, tester.a3]
    for i in range(market.getNumParticipants()):
        account = testers[i % 4]
        reportingParticipant = localFixture.applySignature(
            "DisputeCrowdsourcer", market.getReportingParticipant(i))
        expectedRep = reportingParticipant.getStake()
        expectedRep += expectedRep / localFixture.contracts[
            "Constants"].FORK_MIGRATION_PERCENTAGE_BONUS_DIVISOR()
        expectedRep += reportingParticipant.getStake() / 2
        expectedEth = cash.balanceOf(reportingParticipant.address)
        newReputationToken = localFixture.applySignature(
            "ReputationToken", reportingParticipant.getReputationToken())
        with EtherDelta(expectedEth, account, localFixture.chain,
                        "Redeeming didn't increase ETH correctly"):
            with TokenDelta(newReputationToken, expectedRep, account,
                            "Redeeming didn't increase REP correctly"):
                reportingParticipant.redeem(account,
                                            startgas=long(6.7 * 10**6))
def test_multiple_round_crowdsourcer_fees(localFixture, universe, market, cash,
                                          reputationToken):
    constants = localFixture.contracts["Constants"]

    # Initial Report disputed
    proceedToNextRound(localFixture, market, tester.k1, True)
    # Initial Report winning
    proceedToNextRound(localFixture, market, tester.k2, True)
    # Initial Report disputed
    proceedToNextRound(localFixture,
                       market,
                       tester.k1,
                       True,
                       randomPayoutNumerators=True)
    # Initial Report winning
    proceedToNextRound(localFixture, market, tester.k3, True)

    # Get all the winning Reporting Participants
    initialReporter = localFixture.applySignature(
        'InitialReporter', market.getReportingParticipant(0))
    winningDisputeCrowdsourcer1 = localFixture.applySignature(
        'DisputeCrowdsourcer', market.getReportingParticipant(2))
    winningDisputeCrowdsourcer2 = localFixture.applySignature(
        'DisputeCrowdsourcer', market.getReportingParticipant(4))

    # Get losing Reporting Participants
    losingDisputeCrowdsourcer1 = localFixture.applySignature(
        'DisputeCrowdsourcer', market.getReportingParticipant(1))
    losingDisputeCrowdsourcer2 = localFixture.applySignature(
        'DisputeCrowdsourcer', market.getReportingParticipant(3))

    # We can't redeem yet as the market isn't finalized
    with raises(TransactionFailed):
        initialReporter.redeem(tester.a0)

    with raises(TransactionFailed):
        winningDisputeCrowdsourcer1.redeem(tester.a2)

    # Fast forward time until the new fee window is over and we can receive fees
    feeWindow = localFixture.applySignature("FeeWindow", market.getFeeWindow())
    localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1)
    assert market.finalize()

    # The initial reporter locked in REP for 5 rounds.
    expectedInitialReporterFees = getExpectedFees(localFixture, cash,
                                                  initialReporter, 5)
    expectedRep = long(initialReporter.getStake() +
                       initialReporter.getStake() / 2)
    with TokenDelta(reputationToken, expectedRep, tester.a0,
                    "Redeeming didn't refund REP"):
        with EtherDelta(expectedInitialReporterFees, tester.a0,
                        localFixture.chain,
                        "Redeeming didn't increase ETH correctly"):
            assert initialReporter.redeem(tester.a0)

    # The first winning dispute crowdsourcer will get fees for 4 rounds
    expectedWinningDisputeCrowdsourcer1Fees = getExpectedFees(
        localFixture, cash, winningDisputeCrowdsourcer1, 4)
    expectedRep = long(winningDisputeCrowdsourcer1.getStake() +
                       winningDisputeCrowdsourcer1.getStake() / 2)
    with TokenDelta(reputationToken, expectedRep, tester.a2,
                    "Redeeming didn't refund REP"):
        with EtherDelta(expectedWinningDisputeCrowdsourcer1Fees, tester.a2,
                        localFixture.chain,
                        "Redeeming didn't increase ETH correctly"):
            assert winningDisputeCrowdsourcer1.redeem(tester.a2)

    # The final winning dispute crowdsourcer will get fees for 2 rounds
    expectedWinningDisputeCrowdsourcer2Fees = getExpectedFees(
        localFixture, cash, winningDisputeCrowdsourcer2, 2)
    expectedRep = long(winningDisputeCrowdsourcer2.getStake() +
                       winningDisputeCrowdsourcer2.getStake() / 2)
    with TokenDelta(reputationToken, expectedRep, tester.a3,
                    "Redeeming didn't refund REP"):
        with EtherDelta(expectedWinningDisputeCrowdsourcer2Fees, tester.a3,
                        localFixture.chain,
                        "Redeeming didn't increase ETH correctly"):
            assert winningDisputeCrowdsourcer2.redeem(tester.a3)

    # The losing reports get fees as well but no REP
    # The first losing bond has fees from 5 rounds
    expectedLosingDisputeCrowdsourcer1Fees = getExpectedFees(
        localFixture, cash, losingDisputeCrowdsourcer1, 5)
    with TokenDelta(reputationToken, 0, tester.a1, "Redeeming refunded REP"):
        with EtherDelta(expectedLosingDisputeCrowdsourcer1Fees, tester.a1,
                        localFixture.chain,
                        "Redeeming didn't increase ETH correctly"):
            assert losingDisputeCrowdsourcer1.redeem(tester.a1)

    # The second losing bond has fees from 3 rounds
    expectedLosingDisputeCrowdsourcer2Fees = getExpectedFees(
        localFixture, cash, losingDisputeCrowdsourcer2, 3)
    with TokenDelta(reputationToken, 0, tester.a1, "Redeeming refunded REP"):
        with EtherDelta(expectedLosingDisputeCrowdsourcer2Fees, tester.a1,
                        localFixture.chain,
                        "Redeeming didn't increase ETH correctly"):
            assert losingDisputeCrowdsourcer2.redeem(tester.a1)
def test_multiple_round_crowdsourcer_fees(localFixture, universe, market, cash, reputationToken):
    constants = localFixture.contracts["Constants"]

    # Initial Report disputed
    proceedToNextRound(localFixture, market, tester.k1, True)
    # Initial Report winning
    proceedToNextRound(localFixture, market, tester.k2, True)
    # Initial Report disputed
    proceedToNextRound(localFixture, market, tester.k1, True, randomPayoutNumerators=True)
    # Initial Report winning
    proceedToNextRound(localFixture, market, tester.k3, True)

    # Get all the winning Reporting Participants
    initialReporter = localFixture.applySignature('InitialReporter', market.getReportingParticipant(0))
    winningDisputeCrowdsourcer1 = localFixture.applySignature('DisputeCrowdsourcer', market.getReportingParticipant(2))
    winningDisputeCrowdsourcer2 = localFixture.applySignature('DisputeCrowdsourcer', market.getReportingParticipant(4))

    # Get losing Reporting Participants
    losingDisputeCrowdsourcer1 = localFixture.applySignature('DisputeCrowdsourcer', market.getReportingParticipant(1))
    losingDisputeCrowdsourcer2 = localFixture.applySignature('DisputeCrowdsourcer', market.getReportingParticipant(3))

    # We can't redeem yet as the market isn't finalized
    with raises(TransactionFailed):
        initialReporter.redeem(tester.a0)

    with raises(TransactionFailed):
        winningDisputeCrowdsourcer1.redeem(tester.a2)

    # Fast forward time until the new fee window is over and we can receive fees
    feeWindow = localFixture.applySignature("FeeWindow", market.getFeeWindow())
    localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1)
    assert market.finalize()

    # The initial reporter locked in REP for 5 rounds.
    expectedInitialReporterFees = getExpectedFees(localFixture, cash, initialReporter, 5)
    expectedRep = long(initialReporter.getStake() + initialReporter.getStake() / 2)
    with TokenDelta(reputationToken, expectedRep, tester.a0, "Redeeming didn't refund REP"):
        with EtherDelta(expectedInitialReporterFees, tester.a0, localFixture.chain, "Redeeming didn't increase ETH correctly"):
            assert initialReporter.redeem(tester.a0)

    # The first winning dispute crowdsourcer will get fees for 4 rounds
    expectedWinningDisputeCrowdsourcer1Fees = getExpectedFees(localFixture, cash, winningDisputeCrowdsourcer1, 4)
    expectedRep = long(winningDisputeCrowdsourcer1.getStake() + winningDisputeCrowdsourcer1.getStake() / 2)
    with TokenDelta(reputationToken, expectedRep, tester.a2, "Redeeming didn't refund REP"):
        with EtherDelta(expectedWinningDisputeCrowdsourcer1Fees, tester.a2, localFixture.chain, "Redeeming didn't increase ETH correctly"):
            assert winningDisputeCrowdsourcer1.redeem(tester.a2)

    # The final winning dispute crowdsourcer will get fees for 2 rounds
    expectedWinningDisputeCrowdsourcer2Fees = getExpectedFees(localFixture, cash, winningDisputeCrowdsourcer2, 2)
    expectedRep = long(winningDisputeCrowdsourcer2.getStake() + winningDisputeCrowdsourcer2.getStake() / 2)
    with TokenDelta(reputationToken, expectedRep, tester.a3, "Redeeming didn't refund REP"):
        with EtherDelta(expectedWinningDisputeCrowdsourcer2Fees, tester.a3, localFixture.chain, "Redeeming didn't increase ETH correctly"):
            assert winningDisputeCrowdsourcer2.redeem(tester.a3)

    # The losing reports get fees as well but no REP
    # The first losing bond has fees from 5 rounds
    expectedLosingDisputeCrowdsourcer1Fees = getExpectedFees(localFixture, cash, losingDisputeCrowdsourcer1, 5)
    with TokenDelta(reputationToken, 0, tester.a1, "Redeeming refunded REP"):
        with EtherDelta(expectedLosingDisputeCrowdsourcer1Fees, tester.a1, localFixture.chain, "Redeeming didn't increase ETH correctly"):
            assert losingDisputeCrowdsourcer1.redeem(tester.a1)

    # The second losing bond has fees from 3 rounds
    expectedLosingDisputeCrowdsourcer2Fees = getExpectedFees(localFixture, cash, losingDisputeCrowdsourcer2, 3)
    with TokenDelta(reputationToken, 0, tester.a1, "Redeeming refunded REP"):
        with EtherDelta(expectedLosingDisputeCrowdsourcer2Fees, tester.a1, localFixture.chain, "Redeeming didn't increase ETH correctly"):
            assert losingDisputeCrowdsourcer2.redeem(tester.a1)