Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
def test_market_escape_hatch_partial_fees(localFixture, market,
                                          reputationToken, reportingWindow,
                                          constants, controller):
    # We'll skip to Limited reporting and make a report
    localFixture.chain.head_state.timestamp = reportingWindow.getStartTime(
    ) + 1

    stakeToken = localFixture.getStakeToken(market,
                                            [0, market.getNumTicks()], False)
    MarketEtherDelta = constants.DEFAULT_VALIDITY_BOND(
    ) - localFixture.chain.head_state.get_balance(market.address)
    with EtherDelta(MarketEtherDelta, market.address, localFixture.chain,
                    "First reporter gas fee was not given to first reporter"):
        with TokenDelta(reputationToken,
                        -reputationToken.balanceOf(market.address),
                        market.address,
                        "REP balance was not given to the first reporter"):
            stakeToken.buy(0, sender=tester.k1)

    # Emergency Stop
    assert controller.emergencyStop()

    # We will only get back the validity bond since our REP bond and first reporter bond were forfeit already
    with EtherDelta(constants.DEFAULT_VALIDITY_BOND(), market.getOwner(),
                    localFixture.chain,
                    "Remaining ETH balance was not given to the market owner"):
        with TokenDelta(reputationToken, 0, market.getOwner(),
                        "REP balance was somehow given to the market owner"):
            assert market.withdrawInEmergency()
Ejemplo n.º 3
0
def test_mailbox_eth_happy_path(localFixture, mailbox):
    # We can send some ETH to the mailbox
    with EtherDelta(100, mailbox.address, localFixture.chain,
                    "Deposit did not work"):
        assert mailbox.depositEther(value=100)

    # We can also withdraw the ETH balance of the mailbox
    with EtherDelta(100, tester.a0, localFixture.chain,
                    "Withdraw did not work"):
        assert mailbox.withdrawEther()
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
def test_take_best_order_with_shares_escrowed_buy_with_shares_categorical(contractsFixture, cash, categoricalMarket, universe):
    market = categoricalMarket
    createOrder = contractsFixture.contracts['CreateOrder']
    trade = contractsFixture.contracts['Trade']
    orders = contractsFixture.contracts['Orders']
    completeSets = contractsFixture.contracts['CompleteSets']
    firstShareToken = contractsFixture.applySignature('ShareToken', market.getShareToken(0))
    secondShareToken = contractsFixture.applySignature('ShareToken', market.getShareToken(1))
    thirdShareToken = contractsFixture.applySignature('ShareToken', market.getShareToken(2))

    # buy complete sets for both users
    numTicks = market.getNumTicks()
    assert completeSets.publicBuyCompleteSets(market.address, fix(1), sender=tester.k1, value=fix('1', numTicks))
    assert completeSets.publicBuyCompleteSets(market.address, fix(1), sender=tester.k2, value=fix('1', numTicks))
    assert firstShareToken.balanceOf(tester.a1) == firstShareToken.balanceOf(tester.a2) == fix(1)
    assert secondShareToken.balanceOf(tester.a1) == secondShareToken.balanceOf(tester.a2) == fix(1)
    assert thirdShareToken.balanceOf(tester.a1) == thirdShareToken.balanceOf(tester.a2) == fix(1)

    # create order with shares
    orderID = createOrder.publicCreateOrder(ASK, fix(1), 6000, market.address, 0, longTo32Bytes(0), longTo32Bytes(0), "42", sender=tester.k1)
    assert orderID

    # fill order with shares using on-chain matcher
    totalProceeds = fix(1, numTicks)
    totalProceeds -= fix(1, numTicks) / market.getMarketCreatorSettlementFeeDivisor()
    totalProceeds -= fix(1, numTicks) / universe.getOrCacheReportingFeeDivisor()
    expectedTester1Payout = totalProceeds * 6000 / numTicks
    expectedTester2Payout = totalProceeds * (numTicks - 6000) / numTicks
    with EtherDelta(expectedTester1Payout, tester.a1, contractsFixture.chain, "Tester 1 ETH delta wrong"):
        with EtherDelta(expectedTester2Payout, tester.a2, contractsFixture.chain, "Tester 2 ETH delta wrong"):
            with PrintGasUsed(contractsFixture, "categoricalFill", 0):
                assert trade.publicFillBestOrder(BID, market.address, 0, fix(1), 6000, "43", sender=tester.k2) == 0

    assert firstShareToken.balanceOf(tester.a1) == 0
    assert secondShareToken.balanceOf(tester.a1) == fix(1)
    assert thirdShareToken.balanceOf(tester.a1) == fix(1)

    assert firstShareToken.balanceOf(tester.a2) == fix(1)
    assert secondShareToken.balanceOf(tester.a2) == 0
    assert thirdShareToken.balanceOf(tester.a2) == 0

    assert orders.getAmount(orderID) == 0
    assert orders.getPrice(orderID) == 0
    assert orders.getOrderCreator(orderID) == longToHexString(0)
    assert orders.getOrderMoneyEscrowed(orderID) == 0
    assert orders.getOrderSharesEscrowed(orderID) == 0
    assert orders.getBetterOrderId(orderID) == longTo32Bytes(0)
    assert orders.getWorseOrderId(orderID) == longTo32Bytes(0)
Ejemplo n.º 7
0
def generateFees(fixture, universe, market):
    completeSets = fixture.contracts['CompleteSets']
    cash = fixture.contracts['Cash']
    mailbox = fixture.applySignature('Mailbox',
                                     market.getMarketCreatorMailbox())
    assert mailbox.withdrawEther()

    cost = 1000 * market.getNumTicks()
    marketCreatorFees = cost / market.getMarketCreatorSettlementFeeDivisor()
    completeSets.publicBuyCompleteSets(market.address,
                                       1000,
                                       sender=tester.k1,
                                       value=cost)
    with TokenDelta(
            cash, marketCreatorFees, mailbox.address,
            "The market creator mailbox didn't get their share of fees from complete set sale"
    ):
        completeSets.publicSellCompleteSets(market.address,
                                            1000,
                                            sender=tester.k1)
    with EtherDelta(
            marketCreatorFees, market.getOwner(), fixture.chain,
            "The market creator did not get their fees when withdrawing ETH from the mailbox"
    ):
        assert mailbox.withdrawEther()
    fees = cash.balanceOf(universe.getNextFeeWindow())
    reporterFees = cost / universe.getOrCacheReportingFeeDivisor()
    assert fees == reporterFees, "Cash balance of window higher by: " + str(
        fees - reporterFees)
Ejemplo n.º 8
0
def test_duplicate_creation_transaction(contractsFixture, cash, market):
    orders = contractsFixture.contracts['Orders']
    createOrder = contractsFixture.contracts['CreateOrder']

    with EtherDelta(-fix(1, 4000), tester.a0, contractsFixture.chain):
        orderID = createOrder.publicCreateOrder(BID,
                                                fix(1),
                                                4000,
                                                market.address,
                                                1,
                                                longTo32Bytes(0),
                                                longTo32Bytes(0),
                                                "7",
                                                value=fix(1, 4000))

    assert orderID

    with raises(TransactionFailed):
        createOrder.publicCreateOrder(BID,
                                      fix(1),
                                      4000,
                                      market.address,
                                      1,
                                      longTo32Bytes(0),
                                      longTo32Bytes(0),
                                      "7",
                                      value=fix(1, 4000))
Ejemplo n.º 9
0
def test_market_escape_hatch_all_fees(localFixture, controller, market,
                                      reputationToken):
    # We can't call the Market escape hatch when things are alright
    with raises(TransactionFailed):
        market.withdrawInEmergency()

    # Emergency Stop
    escapeHatchChangedLog = {
        "isOn": True,
    }
    with AssertLog(localFixture, "EscapeHatchChanged", escapeHatchChangedLog):
        assert controller.emergencyStop()

    # Now we can call the market escape hatch and get back all the fees paid in creation
    with EtherDelta(localFixture.chain.head_state.get_balance(market.address),
                    market.getOwner(), localFixture.chain,
                    "ETH balance was not given to the market owner"):
        with TokenDelta(reputationToken,
                        reputationToken.balanceOf(market.address),
                        market.getOwner(),
                        "REP balance was not given to the market owner"):
            assert market.withdrawInEmergency()

    escapeHatchChangedLog = {
        "isOn": False,
    }
    with AssertLog(localFixture, "EscapeHatchChanged", escapeHatchChangedLog):
        assert controller.release()
Ejemplo n.º 10
0
def test_mailbox_eth_failure(localFixture, mailbox):
    # We send some ETH to the mailbox
    with EtherDelta(100, mailbox.address, localFixture.chain,
                    "Deposit did not work"):
        assert mailbox.depositEther(value=100)

    # Withdrawing as someone other than the owner will fail
    with raises(TransactionFailed):
        mailbox.withdrawEther(sender=tester.k1)
Ejemplo n.º 11
0
def test_mailbox_cash_happy_path(localFixture, mailbox, cash):
    # We can send some Cash to the mailbox
    assert cash.depositEther(value=100)
    assert cash.balanceOf(tester.a0) == 100

    with TokenDelta(cash, 100, mailbox.address, "Deposit did not work"):
        assert cash.transfer(mailbox.address, 100)

    # We can withdraw "Ether" and the Cash balance in the mailbox will be given to the owner as Ether
    with EtherDelta(100, tester.a0, localFixture.chain,
                    "Withdraw did not work"):
        assert mailbox.withdrawEther()
Ejemplo n.º 12
0
def test_initialReport_transfer_ownership(localFixture, universe, market, cash,
                                          constants):
    reputationToken = localFixture.applySignature(
        "ReputationToken", universe.getReputationToken())

    # proceed to the initial reporting period
    proceedToInitialReporting(localFixture, market)

    # do an initial report as someone other than the designated reporter
    assert market.doInitialReport([0, market.getNumTicks()],
                                  False,
                                  sender=tester.k1)

    # the market is now assigned a fee window
    newFeeWindowAddress = market.getFeeWindow()
    assert newFeeWindowAddress
    feeWindow = localFixture.applySignature('FeeWindow', newFeeWindowAddress)

    # time marches on and the market can be finalized
    localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1)
    assert market.finalize()

    # We can see that the market reports the designated reporter did not show
    assert not market.designatedReporterShowed()

    # Let's get a reference to the Initial Reporter bond and transfer it to the original designated reporter account
    initialReporter = localFixture.applySignature("InitialReporter",
                                                  market.getInitialReporter())
    transferLog = {
        "universe": universe.address,
        "market": market.address,
        "from": bytesToHexString(tester.a1),
        "to": initialReporter.getDesignatedReporter(),
    }
    with AssertLog(localFixture, "InitialReporterTransfered", transferLog):
        assert initialReporter.transferOwnership(
            initialReporter.getDesignatedReporter(), sender=tester.k1)

    # The market still correctly indicates the designated reporter did not show up
    assert not market.designatedReporterShowed()

    # When we redeem the initialReporter it goes to the correct party as well
    expectedRep = initialReporter.getStake()
    owner = initialReporter.getOwner()

    expectedGasBond = 2 * constants.GAS_TO_REPORT(
    ) * constants.DEFAULT_REPORTING_GAS_PRICE()
    with EtherDelta(
            expectedGasBond, owner, localFixture.chain,
            "Initial reporter did not get the reporting gas cost bond"):
        with TokenDelta(reputationToken, expectedRep, owner,
                        "Redeeming didn't refund REP"):
            assert initialReporter.redeem(owner)
Ejemplo n.º 13
0
def localSnapshot(fixture, kitchenSinkSnapshot):
    fixture.resetToSnapshot(kitchenSinkSnapshot)
    universe = ABIContract(fixture.chain,
                           kitchenSinkSnapshot['universe'].translator,
                           kitchenSinkSnapshot['universe'].address)
    market = ABIContract(fixture.chain,
                         kitchenSinkSnapshot['binaryMarket'].translator,
                         kitchenSinkSnapshot['binaryMarket'].address)
    categoricalMarket = ABIContract(
        fixture.chain, kitchenSinkSnapshot['categoricalMarket'].translator,
        kitchenSinkSnapshot['categoricalMarket'].address)
    scalarMarket = ABIContract(fixture.chain,
                               kitchenSinkSnapshot['scalarMarket'].translator,
                               kitchenSinkSnapshot['scalarMarket'].address)
    cash = ABIContract(fixture.chain, kitchenSinkSnapshot['cash'].translator,
                       kitchenSinkSnapshot['cash'].address)
    completeSets = fixture.contracts['CompleteSets']
    mailbox = fixture.applySignature('Mailbox',
                                     market.getMarketCreatorMailbox())

    # Generate the fees in our initial reporting window
    cost = 1000 * market.getNumTicks()
    marketCreatorFees = cost / market.getMarketCreatorSettlementFeeDivisor()
    completeSets.publicBuyCompleteSets(market.address,
                                       1000,
                                       sender=tester.k1,
                                       value=cost)
    with TokenDelta(
            cash, marketCreatorFees, mailbox.address,
            "The market creator mailbox didn't get their share of fees from complete set sale"
    ):
        completeSets.publicSellCompleteSets(market.address,
                                            1000,
                                            sender=tester.k1)
    with EtherDelta(
            marketCreatorFees, market.getOwner(), fixture.chain,
            "The market creator did not get their fees when withdrawing ETH from the mailbox"
    ):
        assert mailbox.withdrawEther()
    fees = cash.balanceOf(market.getReportingWindow())
    reporterFees = cost / universe.getOrCacheReportingFeeDivisor()
    assert fees == reporterFees

    # Distribute REP
    reputationToken = fixture.applySignature('ReputationToken',
                                             universe.getReputationToken())
    for testAccount in [tester.a1, tester.a2, tester.a3, tester.a4, tester.a5]:
        reputationToken.transfer(testAccount, 1 * 10**6 * 10**18)

    return fixture.createSnapshot()
Ejemplo n.º 14
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)
Ejemplo n.º 15
0
def test_market_escape_hatch_partial_fees(localFixture, market,
                                          reputationToken, constants,
                                          controller):
    reputationToken.transfer(tester.a1, 1 * 10**6 * 10**18)

    proceedToNextRound(localFixture, market, contributor=tester.k1)

    # Emergency Stop
    assert controller.emergencyStop()

    # We will only get back the validity bond since our REP bond and first reporter bond were forfeit already
    with EtherDelta(constants.DEFAULT_VALIDITY_BOND(), market.getOwner(),
                    localFixture.chain,
                    "Remaining ETH balance was not given to the market owner"):
        with TokenDelta(reputationToken, 0, market.getOwner(),
                        "REP balance was somehow given to the market owner"):
            assert market.withdrawInEmergency()
def test_market_escape_hatch_all_fees(localFixture, controller, market,
                                      reputationToken):
    # We can't call the Market escape hatch when things are alright
    with raises(TransactionFailed):
        market.withdrawInEmergency()

    # Emergency Stop
    assert controller.registerContract("EmergencyStop", 1, "0", "0")

    # Now we can call the market escape hatch and get back all the fees paid in creation
    with EtherDelta(localFixture.chain.head_state.get_balance(market.address),
                    market.getOwner(), localFixture.chain,
                    "ETH balance was not given to the market owner"):
        with TokenDelta(reputationToken,
                        reputationToken.balanceOf(market.address),
                        market.getOwner(),
                        "REP balance was not given to the market owner"):
            assert market.withdrawInEmergency()
Ejemplo n.º 17
0
def test_variable_validity_bond(invalid, contractsFixture, universe, cash):
    # We can't make a market with less than the minimum required validity bond
    minimumValidityBond = universe.getOrCacheMarketCreationCost()

    with raises(TransactionFailed):
        contractsFixture.createReasonableYesNoMarket(
            universe, cash, validityBond=minimumValidityBond - 1)

    # But we can make one with a greater bond
    higherValidityBond = minimumValidityBond + 1
    market = contractsFixture.createReasonableYesNoMarket(
        universe, cash, validityBond=higherValidityBond)
    assert market.getValidityBondAttoEth() == higherValidityBond

    # If we resolve the market the bond in it's entirety will go to the fee pool or to the market creator if the resolution was not invalid
    proceedToDesignatedReporting(contractsFixture, market)

    if invalid:
        market.doInitialReport(
            [market.getNumTicks() / 2,
             market.getNumTicks() / 2], True, "")
    else:
        market.doInitialReport([0, market.getNumTicks()], False, "")

    # Move time forward so we can finalize and see the bond move
    feeWindow = contractsFixture.applySignature('FeeWindow',
                                                market.getFeeWindow())
    assert contractsFixture.contracts["Time"].setTimestamp(
        feeWindow.getEndTime() + 1)

    if invalid:
        with TokenDelta(cash, higherValidityBond, universe.getAuction(),
                        "Validity bond did not go to the auction"):
            market.finalize()
    else:
        with EtherDelta(higherValidityBond, market.getMarketCreatorMailbox(),
                        contractsFixture.chain,
                        "Validity bond did not go to the market creator"):
            market.finalize()
Ejemplo n.º 18
0
def test_redeem_participation_tokens(kitchenSinkFixture, universe, market,
                                     cash):
    reputationToken = kitchenSinkFixture.applySignature(
        "ReputationToken", universe.getReputationToken())

    # proceed to the next round and buy some more fee window tokens
    proceedToNextRound(kitchenSinkFixture, market, doGenerateFees=True)

    feeWindow = kitchenSinkFixture.applySignature('FeeWindow',
                                                  market.getFeeWindow())

    # We'll make the window active then purchase some participation tokens
    kitchenSinkFixture.contracts["Time"].setTimestamp(
        feeWindow.getStartTime() + 1)
    feeWindowAmount = 100

    # Distribute REP
    for testAccount in [tester.a1, tester.a2, tester.a3]:
        reputationToken.transfer(testAccount, 1 * 10**6 * 10**18)

    assert feeWindow.buy(feeWindowAmount, sender=tester.k1)
    assert feeWindow.buy(feeWindowAmount, sender=tester.k2)
    assert feeWindow.buy(feeWindowAmount, sender=tester.k3)

    # proceed to the next round and buy some more fee window tokens
    proceedToNextRound(kitchenSinkFixture, market, doGenerateFees=True)

    newFeeWindow = kitchenSinkFixture.applySignature('FeeWindow',
                                                     market.getFeeWindow())

    assert newFeeWindow.buy(feeWindowAmount, sender=tester.k1)
    assert newFeeWindow.buy(feeWindowAmount, sender=tester.k2)
    assert newFeeWindow.buy(feeWindowAmount, sender=tester.k3)

    # Now end the window
    kitchenSinkFixture.contracts["Time"].setTimestamp(
        newFeeWindow.getEndTime() + 1)

    reporterFees = 1000 * market.getNumTicks(
    ) / universe.getOrCacheReportingFeeDivisor()
    totalStake = feeWindow.getTotalFeeStake() + newFeeWindow.getTotalFeeStake()
    assert cash.balanceOf(feeWindow.address) == reporterFees
    assert cash.balanceOf(newFeeWindow.address) == reporterFees

    expectedParticipationFees = reporterFees * feeWindowAmount * 2 / totalStake

    # Cashing out Participation tokens will awards fees proportional to the total winning stake in the window
    with TokenDelta(reputationToken, feeWindowAmount * 2, tester.a3,
                    "Redeeming participation tokens didn't refund REP"):
        with TokenDelta(
                feeWindow, -feeWindowAmount, tester.a3,
                "Redeeming participation tokens didn't decrease participation token balance correctly"
        ):
            with EtherDelta(
                    expectedParticipationFees, tester.a3,
                    kitchenSinkFixture.chain,
                    "Redeeming participation tokens didn't increase ETH correctly"
            ):
                with PrintGasUsed(kitchenSinkFixture, "Universe Redeem:", 0):
                    assert universe.redeemStake(
                        [], [feeWindow.address, newFeeWindow.address],
                        sender=tester.k3)

    with TokenDelta(reputationToken, feeWindowAmount * 2, 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,
                    kitchenSinkFixture.chain,
                    "Redeeming participation tokens didn't increase ETH correctly"
            ):
                assert universe.redeemStake(
                    [], [feeWindow.address, newFeeWindow.address],
                    sender=tester.k1)

    with TokenDelta(reputationToken, feeWindowAmount * 2, 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,
                    kitchenSinkFixture.chain,
                    "Redeeming participation tokens didn't increase ETH correctly"
            ):
                assert universe.redeemStake(
                    [], [feeWindow.address, newFeeWindow.address],
                    sender=tester.k2)
Ejemplo n.º 19
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)
Ejemplo n.º 20
0
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))
Ejemplo n.º 21
0
def test_bootstrap(localFixture, universe, reputationToken, auction, time,
                   cash):
    # Lets confirm the auction is in the dormant state initially and also in bootstrap mode
    assert auction.getRoundType() == 0
    assert auction.bootstrapMode()
    assert not auction.isActive()

    # If we move time forward to the next auction start time we can see that the auction is now active.
    startTime = auction.getAuctionStartTime()
    assert time.setTimestamp(startTime)
    assert auction.getRoundType() == 2
    assert auction.bootstrapMode()
    assert auction.isActive()

    # We can get the price of ETH in REP
    assert auction.getRepSalePriceInAttoEth() == auction.initialRepSalePrice()

    # However since we're in bootstrap mode we cannot yet sell REP for ETH.
    with raises(TransactionFailed):
        auction.getEthSalePriceInAttoRep()

    # If we move time forward but stay in the auction the sale price of the REP will drop accordingly. We'll move forward an hour and confirm the price is 1/24th less
    repSalePrice = auction.initialRepSalePrice() * 23 / 24
    assert time.incrementTimestamp(60 * 60)
    assert auction.getRepSalePriceInAttoEth() == repSalePrice

    # Before we do any trading lets confirm the contract balances are as expected
    repAuctionToken = localFixture.applySignature("AuctionToken",
                                                  auction.repAuctionToken())
    assert auction.initialAttoRepBalance() == reputationToken.balanceOf(
        repAuctionToken.address)
    assert auction.initialAttoRepBalance() == 11 * 10**6 * 10**18 / 400
    assert localFixture.chain.head_state.get_balance(auction.address) == 0

    # We can purchase some of the REP now. We'll send some extra ETH to confirm it just gets returned too
    repAmount = 10**18
    cost = repAmount * repSalePrice / 10**18
    with TokenDelta(cash, cost, auction.address,
                    "ETH was not transfered to auction correctly"):
        with TokenDelta(
                repAuctionToken, cost, tester.a0,
                "REP auction token was not transferred to the user correctly"):
            assert auction.tradeEthForRep(repAmount, value=cost + 20)

    # Lets purchase the remaining REP in the auction
    repAmount = auction.getCurrentAttoRepBalance()
    cost = repAmount * repSalePrice / 10**18
    with TokenDelta(cash, cost, auction.address,
                    "ETH was not transfered to auction correctly"):
        with TokenDelta(
                repAuctionToken, cost, tester.a0,
                "REP auction token was not transferred to the user correctly"):
            assert auction.tradeEthForRep(repAmount, value=cost)

    # If we try to purchase any more the transaction will fail
    with raises(TransactionFailed):
        auction.tradeEthForRep(repAmount, value=cost)

    # Lets end this auction then move time to the next auction
    endTime = auction.getAuctionEndTime()
    assert time.setTimestamp(endTime + 1)

    assert auction.getRoundType() == 3
    assert auction.bootstrapMode()
    assert not auction.isActive()

    # Now we can redeem the tokens we received for the amount of REP we purchased
    expectedREP = reputationToken.balanceOf(repAuctionToken.address)
    with TokenDelta(
            reputationToken, expectedREP, tester.a0,
            "REP was not distributed correctly from auction token redemption"):
        repAuctionToken.redeem()

    startTime = auction.getAuctionStartTime()
    assert time.setTimestamp(startTime)

    # We can see that the ETH and REP auctions are active
    assert auction.getRoundType() == 6
    assert auction.isActive()

    assert auction.getRepSalePriceInAttoEth() == auction.initialRepSalePrice()
    assert auction.getEthSalePriceInAttoRep() == auction.initialEthSalePrice()

    assert not auction.bootstrapMode()

    ethAuctionToken = localFixture.applySignature("AuctionToken",
                                                  auction.ethAuctionToken())
    ethSalePrice = auction.initialEthSalePrice()
    ethAmount = 10**18
    cost = ethAmount * ethSalePrice / 10**18
    with TokenDelta(
            ethAuctionToken, cost, tester.a0,
            "ETH auction token was not transferred to the user correctly"):
        with TokenDelta(reputationToken, cost, auction.address,
                        "REP was not transferred to the auction correctly"):
            assert auction.tradeRepForEth(ethAmount)

    endTime = auction.getAuctionEndTime()
    assert time.setTimestamp(endTime + 1)

    # We can redeem the eth auction tokens for ETH. Since the auction ended with no other bids we get all the ETH
    with EtherDelta(
            cash.balanceOf(ethAuctionToken.address), tester.a0,
            localFixture.chain,
            "ETH redemption from eth auction token did not work correctly"):
        assert ethAuctionToken.redeem()
Ejemplo n.º 22
0
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)
Ejemplo n.º 23
0
def test_dispute_bond_fee_collection(localFixture, universe, market,
                                     categoricalMarket, scalarMarket, cash,
                                     reputationToken, reportingWindow):
    # We'll have testers put up dispute bonds against the designated reports and place stake in other outcomes
    disputeStake = localFixture.contracts[
        "Constants"].DESIGNATED_REPORTER_DISPUTE_BOND_AMOUNT()
    otherOutcomeStake = 10**18
    totalCost = disputeStake + otherOutcomeStake
    with TokenDelta(reputationToken, -totalCost, tester.a1,
                    "Disputing did not reduce REP balance correctly"):
        with StakeDelta(totalCost, totalCost, 0, market, reportingWindow,
                        "Disputing is not adjust stake accounting correctly"):
            assert market.disputeDesignatedReport([market.getNumTicks(), 0],
                                                  otherOutcomeStake,
                                                  False,
                                                  sender=tester.k1)

    with StakeDelta(totalCost, totalCost, 0, categoricalMarket,
                    reportingWindow,
                    "Disputing is not adjust stake accounting correctly"):
        with TokenDelta(reputationToken, -totalCost, tester.a2,
                        "Disputing did not reduce REP balance correctly"):
            assert categoricalMarket.disputeDesignatedReport(
                [categoricalMarket.getNumTicks(), 0, 0],
                otherOutcomeStake,
                False,
                sender=tester.k2)

    with TokenDelta(reputationToken, -totalCost, tester.a3,
                    "Disputing did not reduce REP balance correctly"):
        with StakeDelta(totalCost, totalCost, 0, scalarMarket, reportingWindow,
                        "Disputing is not adjust stake accounting correctly"):
            assert scalarMarket.disputeDesignatedReport(
                [scalarMarket.getNumTicks(), 0],
                otherOutcomeStake,
                False,
                sender=tester.k3)

    # Fast forward time until the window is over and we can redeem our winning stake, and dispute bond tokens and receive fees
    localFixture.chain.head_state.timestamp = reportingWindow.getEndTime() + 1
    assert market.tryFinalize()
    assert categoricalMarket.tryFinalize()
    assert scalarMarket.tryFinalize()

    marketDesignatedStake = localFixture.getOrCreateStakeToken(
        market, [market.getNumTicks(), 0])
    categoricalMarketDesignatedStake = localFixture.getOrCreateStakeToken(
        categoricalMarket, [categoricalMarket.getNumTicks(), 0, 0])
    scalarMarketDesignatedStake = localFixture.getOrCreateStakeToken(
        scalarMarket, [scalarMarket.getNumTicks(), 0])

    reporterFees = 1000 * market.getNumTicks(
    ) / universe.getOrCacheReportingFeeDivisor()
    totalWinningStake = reportingWindow.getTotalWinningStake()
    assert cash.balanceOf(reportingWindow.address) == reporterFees

    # Tester 0 placed losing designated reports so that stake is worthless. The other testers have both stake and bonds that can be redeemed for a share of fees
    marketStake = marketDesignatedStake.balanceOf(tester.a1)
    expectedFees = reporterFees * marketStake / totalWinningStake
    with EtherDelta(expectedFees, tester.a1, localFixture.chain,
                    "Redeeming Stake tokens didn't increase ETH correctly"):
        with TokenDelta(
                marketDesignatedStake, -marketStake, tester.a1,
                "Redeeming Stake tokens didn't decrease Stake token balance correctly"
        ):
            assert marketDesignatedStake.redeemWinningTokens(False,
                                                             sender=tester.k1)

    categoricalMarketStake = categoricalMarketDesignatedStake.balanceOf(
        tester.a2)
    expectedFees = reporterFees * categoricalMarketStake / totalWinningStake
    with EtherDelta(expectedFees, tester.a2, localFixture.chain,
                    "Redeeming Stake tokens didn't increase ETH correctly"):
        with TokenDelta(
                categoricalMarketDesignatedStake, -categoricalMarketStake,
                tester.a2,
                "Redeeming Stake tokens didn't decrease Stake token balance correctly"
        ):
            assert categoricalMarketDesignatedStake.redeemWinningTokens(
                False, sender=tester.k2)

    scalarMarketStake = scalarMarketDesignatedStake.balanceOf(tester.a3)
    expectedFees = reporterFees * scalarMarketStake / totalWinningStake
    with EtherDelta(expectedFees, tester.a3, localFixture.chain,
                    "Redeeming Stake tokens didn't increase ETH correctly"):
        with TokenDelta(
                scalarMarketDesignatedStake, -scalarMarketStake, tester.a3,
                "Redeeming Stake tokens didn't decrease Stake token balance correctly"
        ):
            assert scalarMarketDesignatedStake.redeemWinningTokens(
                False, sender=tester.k3)

    # Now we'll redeem the dispute bonds
    marketDisputeBond = localFixture.applySignature(
        "DisputeBond", market.getDesignatedReporterDisputeBond())
    categoricalMarketDisputeBond = localFixture.applySignature(
        "DisputeBond", categoricalMarket.getDesignatedReporterDisputeBond())
    scalarMarketDisputeBond = localFixture.applySignature(
        "DisputeBond", scalarMarket.getDesignatedReporterDisputeBond())

    expectedDisputeFees = reporterFees * disputeStake / totalWinningStake

    with EtherDelta(
            expectedDisputeFees, tester.a1, localFixture.chain,
            "Redeeming Dispute Bond token didn't increase ETH correctly"):
        assert marketDisputeBond.withdraw(False, sender=tester.k1)
    with EtherDelta(
            expectedDisputeFees, tester.a2, localFixture.chain,
            "Redeeming Dispute Bond token didn't increase ETH correctly"):
        assert categoricalMarketDisputeBond.withdraw(False, sender=tester.k2)
    remainingFees = cash.balanceOf(reportingWindow.address)
    with EtherDelta(
            remainingFees, tester.a3, localFixture.chain,
            "Redeeming Dispute Bond token didn't increase ETH correctly"):
        assert scalarMarketDisputeBond.withdraw(False, sender=tester.k3)
Ejemplo n.º 24
0
def test_token_fee_collection(localFixture, universe, market,
                              categoricalMarket, scalarMarket, cash,
                              reputationToken, reportingWindow):
    # We'll progress past the designated dispute phase and finalize all the markets
    localFixture.chain.head_state.timestamp = market.getEndTime(
    ) + localFixture.contracts[
        "Constants"].DESIGNATED_REPORTING_DURATION_SECONDS() + 1

    assert market.tryFinalize()
    assert categoricalMarket.tryFinalize()
    assert scalarMarket.tryFinalize()

    # We can't redeem the stake used to do the designated report for fees yet since the window is not yet over
    marketDesignatedStake = localFixture.getOrCreateStakeToken(
        market, [0, market.getNumTicks()])
    categoricalMarketDesignatedStake = localFixture.getOrCreateStakeToken(
        categoricalMarket, [0, 0, categoricalMarket.getNumTicks()])
    scalarMarketDesignatedStake = localFixture.getOrCreateStakeToken(
        scalarMarket, [0, scalarMarket.getNumTicks()])

    with raises(TransactionFailed):
        marketDesignatedStake.redeemWinningTokens(False)

    # If we forgo fees we can redeem however. We'll do this for the scalar market. Note that the market total stake isn't decreased. Market total stake only decreases once it is finalized at which point it can no longer migrate so the value doesn't matter
    scalarStake = scalarMarketDesignatedStake.balanceOf(tester.a0)
    with TokenDelta(reputationToken, scalarStake, tester.a0,
                    "Forgoing fees resulting in an incorrect REP refund"):
        with EtherDelta(0, tester.a0, localFixture.chain,
                        "Forgoing fees gave fees incorrectly"):
            with StakeDelta(
                    0, -scalarStake, -scalarStake, scalarMarket,
                    reportingWindow,
                    "Forgoing fees incorrectly updated stake accounting"):
                assert scalarMarketDesignatedStake.redeemWinningTokens(True)

    # We cannot purchase participation tokens yet since the window isn't active
    participationToken = localFixture.applySignature(
        "ParticipationToken", reportingWindow.getParticipationToken())
    with raises(TransactionFailed):
        participationToken.buy(1)

    # We'll progress to the start of the window and purchase some participation tokens
    localFixture.chain.head_state.timestamp = reportingWindow.getStartTime(
    ) + 1
    participationTokenAmount = 100
    with TokenDelta(reputationToken, -participationTokenAmount, tester.a0,
                    "Buying participation tokens didn't deduct REP correctly"):
        with TokenDelta(
                participationToken, participationTokenAmount, tester.a0,
                "Buying participation tokens didn't increase participation token balance correctly"
        ):
            with StakeDelta(
                    0, participationTokenAmount, participationTokenAmount,
                    market, reportingWindow,
                    "Buying participation tokens din't adjust stake accounting correctly"
            ):
                assert participationToken.buy(participationTokenAmount)

    # As other testers we'll buy some more
    with StakeDelta(
            0, participationTokenAmount * 3, participationTokenAmount * 3,
            market, reportingWindow,
            "Buying participation tokens din't adjust stake accounting correctly"
    ):
        with TokenDelta(
                participationToken, participationTokenAmount, tester.a1,
                "Buying participation tokens didn't increase participation token balance correctly"
        ):
            assert participationToken.buy(participationTokenAmount,
                                          sender=tester.k1)
        with TokenDelta(
                participationToken, participationTokenAmount, tester.a2,
                "Buying participation tokens didn't increase participation token balance correctly"
        ):
            assert participationToken.buy(participationTokenAmount,
                                          sender=tester.k2)
        with TokenDelta(
                participationToken, participationTokenAmount, tester.a3,
                "Buying participation tokens didn't increase participation token balance correctly"
        ):
            assert participationToken.buy(participationTokenAmount,
                                          sender=tester.k3)

    # We can't redeem the participation tokens for fees yet since the window isn't over
    with raises(TransactionFailed):
        participationToken.redeem(False)

    # We can redeem them to just get back REP. We'll have tester 3 do this
    participationValue = participationToken.balanceOf(tester.a3)
    with TokenDelta(reputationToken, participationValue, tester.a3,
                    "Forgoing fees resulting in an incorrect REP refund"):
        with TokenDelta(
                participationToken, -participationTokenAmount, tester.a3,
                "Redeeming participation tokens didn't decrease participation token balance correctly"
        ):
            with EtherDelta(0, tester.a0, localFixture.chain,
                            "Forgoing fees gave fees incorrectly"):
                with StakeDelta(
                        0, -participationValue, -participationValue, market,
                        reportingWindow,
                        "Forgoing fees incorrectly updated stake accounting"):
                    assert participationToken.redeem(True, sender=tester.k3)

    # Fast forward time until the window is over and we can redeem our winning stake and participation tokens and receive fees
    localFixture.chain.head_state.timestamp = reportingWindow.getEndTime() + 1

    reporterFees = 1000 * market.getNumTicks(
    ) / universe.getOrCacheReportingFeeDivisor()
    totalWinningStake = reportingWindow.getTotalWinningStake()
    assert cash.balanceOf(reportingWindow.address) == reporterFees

    expectedParticipationFees = reporterFees * participationTokenAmount / totalWinningStake

    # Cashing out Participation tokens or Stake tokens will awards fees proportional to the total winning stake in the window
    with TokenDelta(
            participationToken, -participationTokenAmount, 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 participationToken.redeem(False)

    with TokenDelta(
            participationToken, -participationTokenAmount, 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 participationToken.redeem(False, sender=tester.k1)

    with TokenDelta(
            participationToken, -participationTokenAmount, 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 participationToken.redeem(False, sender=tester.k2)

    logs = []
    captureFilteredLogs(localFixture.chain.head_state,
                        localFixture.contracts['Augur'], logs)

    marketStake = marketDesignatedStake.balanceOf(tester.a0)
    expectedFees = reporterFees * marketStake / totalWinningStake + 1  # Rounding error
    with EtherDelta(expectedFees, tester.a0, localFixture.chain,
                    "Redeeming Stake tokens didn't increase ETH correctly"):
        with TokenDelta(
                marketDesignatedStake, -marketStake, tester.a0,
                "Redeeming Stake tokens didn't decrease Stake token balance correctly"
        ):
            assert marketDesignatedStake.redeemWinningTokens(False)

    # Confirm redeeming stake tokens logs appropriately
    assert len(logs) == 3
    assert logs[2]['_event_type'] == 'WinningTokensRedeemed'
    assert logs[2]['reporter'] == bytesToHexString(tester.a0)
    assert logs[2]['reportingFeesReceived'] == expectedFees
    assert logs[2]['stakeToken'] == marketDesignatedStake.address
    assert logs[2]['market'] == market.address
    assert logs[2]['amountRedeemed'] == marketStake
    assert logs[2]['payoutNumerators'] == [0, market.getNumTicks()]

    categoricalMarketStake = categoricalMarketDesignatedStake.balanceOf(
        tester.a0)
    expectedFees = reporterFees * categoricalMarketStake / totalWinningStake + 1  # Rounding error
    with EtherDelta(expectedFees, tester.a0, localFixture.chain,
                    "Redeeming Stake tokens didn't increase ETH correctly"):
        with TokenDelta(
                categoricalMarketDesignatedStake, -categoricalMarketStake,
                tester.a0,
                "Redeeming Stake tokens didn't decrease Stake token balance correctly"
        ):
            assert categoricalMarketDesignatedStake.redeemWinningTokens(False)
Ejemplo n.º 25
0
def test_redeem_shares_in_binary_market(kitchenSinkFixture, universe, cash,
                                        market):
    claimTradingProceeds = kitchenSinkFixture.contracts['ClaimTradingProceeds']
    yesShareToken = kitchenSinkFixture.applySignature(
        'ShareToken', market.getShareToken(YES))
    noShareToken = kitchenSinkFixture.applySignature('ShareToken',
                                                     market.getShareToken(NO))
    expectedValue = 1 * market.getNumTicks()
    expectedReporterFees = expectedValue / universe.getReportingFeeDivisor()
    expectedMarketCreatorFees = expectedValue / market.getMarketCreatorSettlementFeeDivisor(
    )
    expectedSettlementFees = expectedReporterFees + expectedMarketCreatorFees
    expectedPayout = long(expectedValue - expectedSettlementFees)

    assert universe.getOpenInterestInAttoEth() == 0

    # get YES shares with a1
    acquireLongShares(kitchenSinkFixture,
                      cash,
                      market,
                      YES,
                      1,
                      claimTradingProceeds.address,
                      sender=tester.k1)
    assert universe.getOpenInterestInAttoEth() == 1 * market.getNumTicks()
    # get NO shares with a2
    acquireShortShareSet(kitchenSinkFixture,
                         cash,
                         market,
                         YES,
                         1,
                         claimTradingProceeds.address,
                         sender=tester.k2)
    assert universe.getOpenInterestInAttoEth() == 2 * market.getNumTicks()
    finalizeMarket(kitchenSinkFixture, market, [0, 10**18])

    logs = []
    captureFilteredLogs(kitchenSinkFixture.chain.head_state,
                        kitchenSinkFixture.contracts['Augur'], logs)

    with EtherDelta(expectedMarketCreatorFees, tester.a0,
                    kitchenSinkFixture.chain, "Market creator fees not paid"):
        with TokenDelta(cash, expectedReporterFees,
                        market.getReportingWindow(), "Reporter fees not paid"):
            # redeem shares with a1
            initialLongHolderETH = kitchenSinkFixture.chain.head_state.get_balance(
                tester.a1)
            claimTradingProceeds.claimTradingProceeds(market.address,
                                                      sender=tester.k1)
            # redeem shares with a2
            initialShortHolderETH = kitchenSinkFixture.chain.head_state.get_balance(
                tester.a2)
            claimTradingProceeds.claimTradingProceeds(market.address,
                                                      sender=tester.k2)

    # Confirm claim proceeds logging works correctly
    assert len(logs) == 4
    assert logs[1]['_event_type'] == 'TradingProceedsClaimed'
    assert logs[1]['market'] == market.address
    assert logs[1]['shareToken'] == yesShareToken.address
    assert logs[1]['numPayoutTokens'] == expectedPayout
    assert logs[1]['numShares'] == 1
    assert logs[1]['sender'] == bytesToHexString(tester.a1)
    assert logs[1][
        'finalTokenBalance'] == initialLongHolderETH + expectedPayout

    # assert a1 ends up with cash (minus fees) and a2 does not
    assert kitchenSinkFixture.chain.head_state.get_balance(
        tester.a1) == initialLongHolderETH + expectedPayout
    assert kitchenSinkFixture.chain.head_state.get_balance(
        tester.a2) == initialShortHolderETH
    assert yesShareToken.balanceOf(tester.a1) == 0
    assert yesShareToken.balanceOf(tester.a2) == 0
    assert noShareToken.balanceOf(tester.a1) == 0
    assert noShareToken.balanceOf(tester.a2) == 0
    assert universe.getOpenInterestInAttoEth() == 1 * market.getNumTicks(
    )  # The corresponding share for tester2's complete set has not been redeemed