Exemple #1
0
def test_rep_migration_convenience_function(localFixture, universe, market):
    proceedToFork(localFixture, market, universe)

    payoutNumerators = [0, 1, market.getNumTicks() - 1]
    payoutDistributionHash = market.derivePayoutDistributionHash(
        payoutNumerators)

    # Initially child universes don't exist
    assert universe.getChildUniverse(
        payoutDistributionHash) == longToHexString(0)

    # We'll use the convenience function for migrating REP instead of manually creating a child universe
    reputationToken = localFixture.applySignature(
        "ReputationToken", universe.getReputationToken())

    with raises(TransactionFailed):
        reputationToken.migrateOutByPayout(payoutNumerators, 0)

    assert reputationToken.migrateOutByPayout(payoutNumerators, 10)

    # We can see that the child universe was created
    newUniverse = localFixture.applySignature(
        "Universe", universe.getChildUniverse(payoutDistributionHash))
    newReputationToken = localFixture.applySignature(
        "ReputationToken", newUniverse.getReputationToken())
    assert newReputationToken.balanceOf(localFixture.accounts[0]) == 10
Exemple #2
0
def test_fork_migration_no_report(localFixture, universe, market):
    # Proceed to Forking for the yesNo market but don't go all the way so that we can create the new market still
    for i in range(10):
        proceedToNextRound(localFixture, market)

    # Create a market before the fork occurs which has an end date past the forking window
    endTime = localFixture.contracts["Time"].getTimestamp() + timedelta(
        days=90).total_seconds()
    longMarket = localFixture.createYesNoMarket(universe, endTime, 1, 0,
                                                localFixture.accounts[0])

    # Go to the forking period
    proceedToFork(localFixture, market, universe)

    # Now finalize the fork so migration can occur
    finalize(localFixture, market, universe)

    # Now when we migrate the market through the fork we'll place a new bond in the winning universe's REP
    oldReputationToken = localFixture.applySignature(
        "ReputationToken", universe.getReputationToken())
    oldBalance = oldReputationToken.balanceOf(longMarket.address)
    newUniverse = localFixture.applySignature(
        "Universe",
        universe.getChildUniverse(market.getWinningPayoutDistributionHash()))
    newReputationToken = localFixture.applySignature(
        "ReputationToken", newUniverse.getReputationToken())
    with TokenDelta(oldReputationToken, 0, longMarket.address,
                    "Migrating didn't disavow old no show bond"):
        with TokenDelta(newReputationToken, oldBalance, longMarket.address,
                        "Migrating didn't place new no show bond"):
            assert longMarket.migrateThroughOneFork([], "")
Exemple #3
0
def test_warp_sync_in_fork(contractsFixture, augur, universe, reputationToken,
                           warpSync, market):
    account = contractsFixture.accounts[0]
    time = contractsFixture.contracts["Time"]

    # Get warp sync market
    warpSync.initializeUniverse(universe.address)
    warpMarket = contractsFixture.applySignature(
        "Market", warpSync.markets(universe.address))

    # Fork the standard market
    proceedToFork(contractsFixture, market, universe)
    finalize(contractsFixture, market, universe)

    # See that we cannot migrate the warp sync market
    numTicks = market.getNumTicks()
    with raises(TransactionFailed):
        assert warpMarket.migrateThroughOneFork([0, 0, numTicks], "")

    # Instead we just create a new warp sync market as usual for the new universe
    winningUniverse = universe.getChildUniverse(
        market.getWinningPayoutDistributionHash())
    warpSync.initializeUniverse(winningUniverse)

    # The market now exists
    assert not warpSync.markets(winningUniverse) == nullAddress
Exemple #4
0
def test_rep_migration_convenience_function(localFixture, universe, market):
    proceedToFork(localFixture, market, universe)

    payoutNumerators = [1, market.getNumTicks() - 1]
    payoutDistributionHash = market.derivePayoutDistributionHash(
        payoutNumerators, False)

    # Initially child universes don't exist
    assert universe.getChildUniverse(
        payoutDistributionHash) == longToHexString(0)

    # We'll use the convenience function for migrating REP instead of manually creating a child universe
    reputationToken = localFixture.applySignature(
        "ReputationToken", universe.getReputationToken())

    assert reputationToken.migrateOutByPayout(payoutNumerators, False, 10)

    # We can see that the child universe was created
    newUniverse = localFixture.applySignature(
        "Universe", universe.getChildUniverse(payoutDistributionHash))
    newReputationToken = localFixture.applySignature(
        "ReputationToken", newUniverse.getReputationToken())
    bonus = 10 / localFixture.contracts[
        "Constants"].FORK_MIGRATION_PERCENTAGE_BONUS_DIVISOR()
    assert newReputationToken.balanceOf(tester.a0) == 10 + bonus
Exemple #5
0
def kitchenSinkSnapshot(fixture, augurInitializedSnapshot):
    fixture.resetToSnapshot(augurInitializedSnapshot)
    # TODO: remove assignments to the fixture as they don't get rolled back, so can bleed across tests.  We should be accessing things via `fixture.contracts[...]`
    legacyReputationToken = fixture.contracts['LegacyReputationToken']
    legacyReputationToken.faucet(11 * 10**6 * 10**18)
    universe = fixture.createUniverse()
    cash = fixture.getSeededCash()
    augur = fixture.contracts['Augur']
    fixture.distributeRep(universe)

    if fixture.subFork:
        forkingMarket = fixture.createReasonableYesNoMarket(universe)
        proceedToFork(fixture, forkingMarket, universe)
        fixture.contracts["Time"].setTimestamp(universe.getForkEndTime() + 1)
        reputationToken = fixture.applySignature('ReputationToken', universe.getReputationToken())
        yesPayoutNumerators = [0, 0, forkingMarket.getNumTicks()]
        reputationToken.migrateOutByPayout(yesPayoutNumerators, reputationToken.balanceOf(tester.a0))
        universe = fixture.applySignature('Universe', universe.createChildUniverse(yesPayoutNumerators))

    yesNoMarket = fixture.createReasonableYesNoMarket(universe)
    startingGas = fixture.chain.head_state.gas_used
    categoricalMarket = fixture.createReasonableCategoricalMarket(universe, 3)
    print 'Gas Used: %s' % (fixture.chain.head_state.gas_used - startingGas)
    scalarMarket = fixture.createReasonableScalarMarket(universe, 30, -10, 400000)
    fixture.uploadAndAddToAugur("solidity_test_helpers/Constants.sol")
    snapshot = fixture.createSnapshot()
    snapshot['universe'] = universe
    snapshot['cash'] = cash
    snapshot['augur'] = augur
    snapshot['yesNoMarket'] = yesNoMarket
    snapshot['categoricalMarket'] = categoricalMarket
    snapshot['scalarMarket'] = scalarMarket
    snapshot['auction'] = fixture.applySignature('Auction', universe.getAuction())
    snapshot['reputationToken'] = fixture.applySignature('ReputationToken', universe.getReputationToken())
    return snapshot
def test_finalized_fork_migration(localFixture, universe, market,
                                  categoricalMarket):
    # Make the categorical market finalized
    proceedToNextRound(localFixture, categoricalMarket)
    feeWindow = localFixture.applySignature('FeeWindow',
                                            categoricalMarket.getFeeWindow())

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

    # Proceed to Forking for the yesNo market and finalize it
    proceedToFork(localFixture, market, universe)
    finalizeFork(localFixture, market, universe)

    # The categorical market is finalized and cannot be migrated to the new universe
    with raises(TransactionFailed):
        categoricalMarket.migrateThroughOneFork()

    # We also can't disavow the crowdsourcers for this market
    with raises(TransactionFailed):
        categoricalMarket.disavowCrowdsourcers()

    # The forking market may not migrate or disavow crowdsourcers either
    with raises(TransactionFailed):
        market.migrateThroughOneFork()

    with raises(TransactionFailed):
        market.disavowCrowdsourcers()
def test_finalized_fork_migration(localFixture, universe, market, categoricalMarket):
    # Make the categorical market finalized
    proceedToNextRound(localFixture, categoricalMarket)
    feeWindow = localFixture.applySignature('FeeWindow', categoricalMarket.getFeeWindow())

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

    # Proceed to Forking for the binary market and finalize it
    proceedToFork(localFixture, market, universe)
    finalizeFork(localFixture, market, universe)

    # The categorical market is finalized and cannot be migrated to the new universe
    with raises(TransactionFailed):
        categoricalMarket.migrateThroughOneFork()

    # We also can't disavow the crowdsourcers for this market
    with raises(TransactionFailed):
        categoricalMarket.disavowCrowdsourcers()

    # The forking market may not migrate or disavow crowdsourcers either
    with raises(TransactionFailed):
        market.migrateThroughOneFork()

    with raises(TransactionFailed):
        market.disavowCrowdsourcers()
Exemple #8
0
def test_warp_sync_gets_forked(contractsFixture, augur, universe,
                               reputationToken, warpSync):
    account = contractsFixture.accounts[0]
    time = contractsFixture.contracts["Time"]

    # See warp sync market
    warpSync.initializeUniverse(universe.address)
    market = contractsFixture.applySignature(
        "Market", warpSync.markets(universe.address))

    # Fork warp sync market
    proceedToFork(contractsFixture, market, universe)
    finalize(contractsFixture, market, universe)

    # See that market finalizes but no new warp sync market exists
    assert market.isFinalized()
    assert market.address == warpSync.markets(universe.address)

    # See warp sync markets dont exists for child universes initially until initialization
    shortPayoutNumerators = [0] * market.getNumberOfOutcomes()
    shortPayoutNumerators[1] = market.getNumTicks()
    longPayoutNumerators = [0] * market.getNumberOfOutcomes()
    longPayoutNumerators[2] = market.getNumTicks()
    shortUniverse = contractsFixture.applySignature(
        'Universe', universe.createChildUniverse(shortPayoutNumerators))
    longUniverse = contractsFixture.applySignature(
        'Universe', universe.createChildUniverse(longPayoutNumerators))

    warpSync.initializeUniverse(shortUniverse.address)
    warpSync.initializeUniverse(longUniverse.address)
    shortUniverseMarket = contractsFixture.applySignature(
        "Market", warpSync.markets(shortUniverse.address))
    longUniverseMarket = contractsFixture.applySignature(
        "Market", warpSync.markets(longUniverse.address))

    assert shortUniverseMarket.address != nullAddress
    assert longUniverseMarket.address != nullAddress

    # Initially there is no warp sync data for the child universe
    assert warpSync.data(shortUniverseMarket.address) == [0, 0]

    # Finalize the warp sync market with some value
    proceedToInitialReporting(contractsFixture, shortUniverseMarket)
    numTicks = shortUniverseMarket.getNumTicks()
    assert shortUniverseMarket.doInitialReport([0, 0, numTicks], "", 0)
    disputeWindow = contractsFixture.applySignature(
        "DisputeWindow", shortUniverseMarket.getDisputeWindow())

    time.setTimestamp(disputeWindow.getEndTime())
    assert shortUniverseMarket.finalize()

    # Check Warp Sync contract for universe and see existing value
    assert warpSync.data(
        shortUniverse.address) == [numTicks,
                                   shortUniverseMarket.getEndTime()]

    # See new warp sync market
    newWarpSyncMarket = contractsFixture.applySignature(
        "Market", warpSync.markets(shortUniverse.address))
    assert newWarpSyncMarket.address != shortUniverseMarket.address
Exemple #9
0
def test_forking_values(localFixture, universe, market):
    reputationToken = localFixture.applySignature("ReputationToken", universe.getReputationToken())

    # Give some REP to another account
    reputationToken.transfer(localFixture.accounts[1], 100)

    # proceed to forking
    proceedToFork(localFixture, market, universe)

    # finalize the fork
    finalize(localFixture, market, universe)

    # We can see that the theoretical total REP supply in the winning child universe is a lower total to account for sibling migrations
    winningPayoutHash = market.getWinningPayoutDistributionHash()
    childUniverse = localFixture.applySignature("Universe", universe.getChildUniverse(winningPayoutHash))
    childUniverseReputationToken = localFixture.applySignature("ReputationToken", childUniverse.getReputationToken())
    childUniverseTheoreticalSupply = childUniverseReputationToken.getTotalTheoreticalSupply()
    assert childUniverseReputationToken.getTotalTheoreticalSupply() <= childUniverseTheoreticalSupply

    # If we migrate some REP to another Universe we can see that amount deducted from the theoretical supply
    losingPayoutNumerators = [0, 0, market.getNumTicks()]
    losingUniverse =  localFixture.applySignature('Universe', universe.createChildUniverse(losingPayoutNumerators))
    losingUniverseReputationToken = localFixture.applySignature('ReputationToken', losingUniverse.getReputationToken())
    assert reputationToken.migrateOutByPayout(losingPayoutNumerators, 100, sender=localFixture.accounts[1])
    lowerChildUniverseTheoreticalSupply = childUniverseReputationToken.getTotalTheoreticalSupply()
    assert lowerChildUniverseTheoreticalSupply == childUniverseTheoreticalSupply - 100

    # If we move past the forking window end time however we will see that some REP was trapped in the parent and deducted from the supply
    localFixture.contracts["Time"].setTimestamp(universe.getForkEndTime() + 1)
    childUniverseTheoreticalSupply = childUniverseReputationToken.getTotalTheoreticalSupply()
    assert childUniverseTheoreticalSupply < lowerChildUniverseTheoreticalSupply

    # In a forked universe the total supply will be different so its childrens goals will not be the same initially
    childUniverse.updateForkValues()
    assert childUniverse.getForkReputationGoal() == int(Decimal(childUniverseTheoreticalSupply) / 2)
    assert childUniverse.getDisputeThresholdForFork() == int(Decimal(childUniverseTheoreticalSupply) / 40)
    assert childUniverse.getInitialReportMinValue() == int(Decimal(childUniverse.getDisputeThresholdForFork()) / 3 / 2**18 + 1)

    # Now we'll fork again and confirm it still takes only 20 dispute rounds in the worst case
    newMarket = localFixture.createReasonableYesNoMarket(childUniverse)
    proceedToFork(localFixture, newMarket, childUniverse)
    assert newMarket.getNumParticipants() == 21

    # finalize the fork
    finalize(localFixture, newMarket, childUniverse)

    # The total theoretical supply is the total supply of the token plus that of the parent
    childWinningPayoutHash = newMarket.getWinningPayoutDistributionHash()
    leafUniverse = localFixture.applySignature("Universe", childUniverse.getChildUniverse(childWinningPayoutHash))
    leafUniverseReputationToken = localFixture.applySignature("ReputationToken", leafUniverse.getReputationToken())
    leafUniverseTheoreticalSupply = leafUniverseReputationToken.getTotalTheoreticalSupply()
    assert leafUniverseTheoreticalSupply == leafUniverseReputationToken.totalSupply() + childUniverseReputationToken.totalSupply()

    # After the fork window ends however we can again recalculate
    localFixture.contracts["Time"].setTimestamp(childUniverse.getForkEndTime() + 1)
    leafUniverseTheoreticalSupply = leafUniverseReputationToken.getTotalTheoreticalSupply()
    assert leafUniverseTheoreticalSupply == leafUniverseReputationToken.totalSupply()
def test_forking(finalizeByMigration, manuallyDisavow, localFixture, universe,
                 market, categoricalMarket):
    # Let's go into the one dispute round for the categorical market
    proceedToNextRound(localFixture, categoricalMarket)
    proceedToNextRound(localFixture, categoricalMarket)

    # proceed to forking
    proceedToFork(localFixture, market, universe)

    with raises(TransactionFailed,
                message="We cannot migrate until the fork is finalized"):
        categoricalMarket.migrateThroughOneFork()

    # confirm that we can manually create a child universe from an outcome no one asserted was true during dispute
    numTicks = market.getNumTicks()
    childUniverse = universe.createChildUniverse(
        [numTicks / 4, numTicks * 3 / 4], False)

    # confirm that before the fork is finalized we can redeem stake in other markets crowdsourcers, which are disavowable
    categoricalDisputeCrowdsourcer = localFixture.applySignature(
        "DisputeCrowdsourcer", categoricalMarket.getReportingParticipant(1))

    if manuallyDisavow:
        assert categoricalMarket.disavowCrowdsourcers()
        # We can redeem before the fork finalizes since disavowal has occured
        assert categoricalDisputeCrowdsourcer.redeem(tester.a0)

    # finalize the fork
    finalizeFork(localFixture, market, universe, finalizeByMigration)

    # The categorical market can be migrated to the winning universe
    assert categoricalMarket.migrateThroughOneFork()

    # The dispute crowdsourcer has been disavowed
    newUniverse = localFixture.applySignature("Universe",
                                              categoricalMarket.getUniverse())
    assert newUniverse.address != universe.address
    assert categoricalDisputeCrowdsourcer.isDisavowed()
    assert not universe.isContainerForReportingParticipant(
        categoricalDisputeCrowdsourcer.address)
    assert not newUniverse.isContainerForReportingParticipant(
        categoricalDisputeCrowdsourcer.address)

    # The initial report is still present however
    categoricalInitialReport = localFixture.applySignature(
        "InitialReporter", categoricalMarket.getReportingParticipant(0))
    assert categoricalMarket.getReportingParticipant(
        0) == categoricalInitialReport.address
    assert not categoricalInitialReport.isDisavowed()
    assert not universe.isContainerForReportingParticipant(
        categoricalInitialReport.address)
    assert newUniverse.isContainerForReportingParticipant(
        categoricalInitialReport.address)
def test_rep_migration_convenience_function(localFixture, universe, market):
    proceedToFork(localFixture, market, universe)

    payoutNumerators = [1, market.getNumTicks()-1]
    payoutDistributionHash = market.derivePayoutDistributionHash(payoutNumerators, False)

    # Initially child universes don't exist
    assert universe.getChildUniverse(payoutDistributionHash) == longToHexString(0)

    # We'll use the convenience function for migrating REP instead of manually creating a child universe
    reputationToken = localFixture.applySignature("ReputationToken", universe.getReputationToken())

    with raises(TransactionFailed):
        reputationToken.migrateOutByPayout(payoutNumerators, False, 0)

    assert reputationToken.migrateOutByPayout(payoutNumerators, False, 10)

    # We can see that the child universe was created
    newUniverse = localFixture.applySignature("Universe", universe.getChildUniverse(payoutDistributionHash))
    newReputationToken = localFixture.applySignature("ReputationToken", newUniverse.getReputationToken())
    bonus = 10 / localFixture.contracts["Constants"].FORK_MIGRATION_PERCENTAGE_BONUS_DIVISOR()
    assert newReputationToken.balanceOf(tester.a0) == 10 + bonus
Exemple #12
0
def test_completeSets_fork(contractsFixture, augur, universe, cash, market,
                           scalarMarket):
    if not contractsFixture.paraAugur:
        return

    shareToken = contractsFixture.getShareToken()
    openInterestCashAddress = getOpenInterestCashAddress(
        contractsFixture, universe)
    openInterestCash = contractsFixture.applySignature(
        "ParaOICash", openInterestCashAddress)

    account1 = contractsFixture.accounts[0]

    depositAmount = 10 * 10**18
    assert cash.faucet(depositAmount)

    with TokenDelta(cash, -depositAmount, account1):
        assert openInterestCash.deposit(depositAmount)

    # Now we'll cause a fork and migrate the market
    paraAugur = contractsFixture.contracts["ParaAugur"]
    proceedToFork(contractsFixture, scalarMarket, universe)
    finalize(contractsFixture, scalarMarket, universe, True)
    market.migrateThroughOneFork([0, 0, market.getNumTicks()], "")
    paraAugur.generateParaUniverse(market.getUniverse())

    # We are still able to purchase complete sets in a child universe's market
    numCompleteSets = 10**14
    initialFeesPaid = openInterestCash.feesPaid()
    assert openInterestCash.buyCompleteSets(market.address, numCompleteSets)

    for i in range(0, 3):
        assert shareToken.balanceOfMarketOutcome(market.address, i,
                                                 account1) == numCompleteSets

    assert openInterestCash.feesPaid() == initialFeesPaid
Exemple #13
0
def test_forked_symbol(contractsFixture, universe, market, scalarMarket):
    account0 = contractsFixture.accounts[0]
    endTime = contractsFixture.contracts["Time"].getTimestamp() + 1000
    categoricalMarket = contractsFixture.createCategoricalMarket(
        universe, 3, endTime, 0, 0, account0, ["Trump", "Warren", "Yang"])

    # proceed to forking
    proceedToFork(contractsFixture, market, universe)

    # finalize the fork
    finalize(contractsFixture, market, universe)

    # Migrate the markets
    assert scalarMarket.migrateThroughOneFork(
        [0, 0, scalarMarket.getNumTicks()], "")
    assert categoricalMarket.migrateThroughOneFork(
        [0, 0, 0, categoricalMarket.getNumTicks()], "")
    newUniverse = contractsFixture.applySignature("Universe",
                                                  scalarMarket.getUniverse())
    fork1ReputationToken = contractsFixture.applySignature(
        "ReputationToken", newUniverse.getReputationToken())

    assert fork1ReputationToken.symbol() == "REPv2_NO_1"

    # Fork the scalar market
    proceedToFork(contractsFixture, scalarMarket, newUniverse)

    # finalize the fork
    finalize(contractsFixture, scalarMarket, newUniverse)

    # Migrate the cat market
    assert categoricalMarket.migrateThroughOneFork(
        [0, 0, 0, categoricalMarket.getNumTicks()], "")
    newUniverse = contractsFixture.applySignature(
        "Universe", categoricalMarket.getUniverse())
    fork2ReputationToken = contractsFixture.applySignature(
        "ReputationToken", newUniverse.getReputationToken())

    assert fork2ReputationToken.symbol() == "REPv2_0_2"

    # Fork the categorical market
    proceedToFork(contractsFixture, categoricalMarket, newUniverse)

    # Create a child universe and check its REP symbol:
    newUniverse = contractsFixture.applySignature(
        "Universe", newUniverse.createChildUniverse([0, 100, 0, 0]))
    fork3ReputationToken = contractsFixture.applySignature(
        "ReputationToken", newUniverse.getReputationToken())

    assert fork3ReputationToken.symbol() == "REPv2_Trump_3"
Exemple #14
0
def test_forking(finalizeByMigration, manuallyDisavow, localFixture, universe,
                 market, categoricalMarket, scalarMarket):
    # Let's go into the one dispute round for the categorical market
    proceedToNextRound(localFixture, categoricalMarket)
    proceedToNextRound(localFixture, categoricalMarket)

    # proceed to forking
    proceedToFork(localFixture, market, universe)

    with raises(TransactionFailed,
                message="We cannot migrate until the fork is finalized"):
        categoricalMarket.migrateThroughOneFork()

    # confirm that we can manually create a child universe from an outcome no one asserted was true during dispute
    numTicks = market.getNumTicks()
    childUniverse = universe.createChildUniverse(
        [numTicks / 4, numTicks * 3 / 4], False)

    # confirm that before the fork is finalized we can redeem stake in other markets crowdsourcers, which are disavowable
    categoricalDisputeCrowdsourcer = localFixture.applySignature(
        "DisputeCrowdsourcer", categoricalMarket.getReportingParticipant(1))

    if manuallyDisavow:
        assert categoricalMarket.disavowCrowdsourcers()
        # We can redeem before the fork finalizes since disavowal has occured
        assert categoricalDisputeCrowdsourcer.redeem(tester.a0)

    # We cannot contribute to a crowdsourcer during a fork
    with raises(TransactionFailed):
        categoricalMarket.contribute(
            [2, 2, categoricalMarket.getNumTicks() - 4], False, 1)

    # We cannot purchase new Participation Tokens during a fork
    feeWindowAddress = universe.getCurrentFeeWindow()
    feeWindow = localFixture.applySignature("FeeWindow", feeWindowAddress)
    with raises(TransactionFailed):
        feeWindow.buy(1)

    # finalize the fork
    finalizeFork(localFixture, market, universe, finalizeByMigration)

    # We cannot contribute to a crowdsourcer in a forked universe
    with raises(TransactionFailed):
        categoricalMarket.contribute(
            [2, 2, categoricalMarket.getNumTicks() - 4], False, 1)

    # The categorical market can be migrated to the winning universe
    assert categoricalMarket.migrateThroughOneFork()

    # The dispute crowdsourcer has been disavowed
    newUniverse = localFixture.applySignature("Universe",
                                              categoricalMarket.getUniverse())
    assert newUniverse.address != universe.address
    assert categoricalDisputeCrowdsourcer.isDisavowed()
    assert not universe.isContainerForReportingParticipant(
        categoricalDisputeCrowdsourcer.address)
    assert not newUniverse.isContainerForReportingParticipant(
        categoricalDisputeCrowdsourcer.address)

    # The initial report is still present however
    categoricalInitialReport = localFixture.applySignature(
        "InitialReporter", categoricalMarket.getReportingParticipant(0))
    assert categoricalMarket.getReportingParticipant(
        0) == categoricalInitialReport.address
    assert not categoricalInitialReport.isDisavowed()
    assert not universe.isContainerForReportingParticipant(
        categoricalInitialReport.address)
    assert newUniverse.isContainerForReportingParticipant(
        categoricalInitialReport.address)

    # The categorical market has a new fee window since it was initially reported on and may be disputed now
    categoricalMarketFeeWindowAddress = categoricalMarket.getFeeWindow()
    categoricalMarketFeeWindow = localFixture.applySignature(
        "FeeWindow", categoricalMarketFeeWindowAddress)

    proceedToNextRound(localFixture, categoricalMarket, moveTimeForward=False)

    # We can also purchase Participation Tokens in this fee window
    assert categoricalMarketFeeWindow.buy(1)

    # We will finalize the categorical market in the new universe
    feeWindow = localFixture.applySignature('FeeWindow',
                                            categoricalMarket.getFeeWindow())
    localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1)

    assert categoricalMarket.finalize()

    # We can migrate a market that has not had its initial reporting completed as well, and confirm its REP no show bond is in the new universe REP
    reputationToken = localFixture.applySignature(
        "ReputationToken", universe.getReputationToken())
    previousREPBalance = reputationToken.balanceOf(scalarMarket.address)
    assert previousREPBalance > 0
    bonus = previousREPBalance / localFixture.contracts[
        "Constants"].FORK_MIGRATION_PERCENTAGE_BONUS_DIVISOR(
        ) if finalizeByMigration else 0
    assert scalarMarket.migrateThroughOneFork()
    newUniverseREP = localFixture.applySignature(
        "ReputationToken", newUniverse.getReputationToken())
    assert newUniverseREP.balanceOf(
        scalarMarket.address) == previousREPBalance + bonus

    # We can finalize this market as well
    proceedToNextRound(localFixture, scalarMarket)
    feeWindow = localFixture.applySignature('FeeWindow',
                                            scalarMarket.getFeeWindow())
    localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1)

    assert scalarMarket.finalize()
def test_universe_fork_goal_freeze(contractsFixture, universe, market):
    proceedToFork(contractsFixture, market, universe)

    with raises(TransactionFailed):
        universe.updateForkValues()
Exemple #16
0
def test_universe_creation(localFixture, augur, market, universe):
    proceedToFork(localFixture, market, universe)
    finalize(localFixture, market, universe)

    with PrintGasUsed(localFixture, "UNIVERSE_CREATE", UNIVERSE_CREATE):
        universe.createChildUniverse([0, 1, market.getNumTicks() - 1])
Exemple #17
0
def test_forking(finalizeByMigration, manuallyDisavow, localFixture, universe, market, categoricalMarket, scalarMarket):
    # Let's go into the one dispute round for the categorical market
    proceedToNextRound(localFixture, categoricalMarket)
    proceedToNextRound(localFixture, categoricalMarket)

    # proceed to forking
    proceedToFork(localFixture, market, universe)

    with raises(TransactionFailed):
        universe.fork()

    with raises(TransactionFailed, message="We cannot migrate until the fork is finalized"):
        categoricalMarket.migrateThroughOneFork([0,0,0,categoricalMarket.getNumTicks()], "")

    with raises(TransactionFailed, message="We cannot create markets during a fork"):
        time = localFixture.contracts["Time"].getTimestamp()
        localFixture.createYesNoMarket(universe, time + 1000, 1, tester.a0)

    # confirm that we can manually create a child universe from an outcome no one asserted was true during dispute
    numTicks = market.getNumTicks()
    childUniverse = universe.createChildUniverse([0, numTicks/ 4, numTicks * 3 / 4])

    # confirm that before the fork is finalized we can redeem stake in other markets crowdsourcers, which are disavowable
    categoricalDisputeCrowdsourcer = localFixture.applySignature("DisputeCrowdsourcer", categoricalMarket.getReportingParticipant(1))

    # confirm we cannot liquidate it
    with raises(TransactionFailed):
        categoricalDisputeCrowdsourcer.liquidateLosing()

    # confirm we cannot fork it
    with raises(TransactionFailed):
        categoricalDisputeCrowdsourcer.forkAndRedeem()

    if manuallyDisavow:
        marketParticipantsDisavowedLog = {
            "universe": universe.address,
            "market": categoricalMarket.address,
        }
        with AssertLog(localFixture, "MarketParticipantsDisavowed", marketParticipantsDisavowedLog):
            assert categoricalMarket.disavowCrowdsourcers()
        # We can redeem before the fork finalizes since disavowal has occured
        assert categoricalDisputeCrowdsourcer.redeem(tester.a0)

    # We cannot contribute to a crowdsourcer during a fork
    with raises(TransactionFailed):
        categoricalMarket.contribute([0,2,2,categoricalMarket.getNumTicks()-4], 1, "")

    # We cannot purchase new Participation Tokens during a fork
    disputeWindowAddress = universe.getCurrentDisputeWindow()
    disputeWindow = localFixture.applySignature("DisputeWindow", disputeWindowAddress)

    # finalize the fork
    marketFinalizedLog = {
        "universe": universe.address,
        "market": market.address,
    }
    with AssertLog(localFixture, "MarketFinalized", marketFinalizedLog):
        finalizeFork(localFixture, market, universe, finalizeByMigration)

    # We cannot contribute to a crowdsourcer in a forked universe
    with raises(TransactionFailed):
        categoricalMarket.contribute([0,2,2,categoricalMarket.getNumTicks()-4], 1, "")

    newUniverseAddress = universe.getWinningChildUniverse()

    # buy some complete sets to change OI
    completeSets = localFixture.contracts['CompleteSets']
    numSets = 10
    cost = categoricalMarket.getNumTicks() * numSets
    assert completeSets.publicBuyCompleteSets(categoricalMarket.address, 10, sender=tester.k1, value=cost)
    assert universe.getOpenInterestInAttoEth() == cost

    marketMigratedLog = {
        "market": categoricalMarket.address,
        "newUniverse": newUniverseAddress,
        "originalUniverse": universe.address,
    }
    with AssertLog(localFixture, "MarketMigrated", marketMigratedLog):
        assert categoricalMarket.migrateThroughOneFork([0,0,0,categoricalMarket.getNumTicks()], "")

    assert universe.getOpenInterestInAttoEth() == 0


    # The dispute crowdsourcer has been disavowed
    newUniverse = localFixture.applySignature("Universe", categoricalMarket.getUniverse())
    assert newUniverse.address != universe.address
    assert categoricalDisputeCrowdsourcer.isDisavowed()
    assert not universe.isContainerForReportingParticipant(categoricalDisputeCrowdsourcer.address)
    assert not newUniverse.isContainerForReportingParticipant(categoricalDisputeCrowdsourcer.address)
    assert newUniverse.getOpenInterestInAttoEth() == cost

    # The initial report is still present however
    categoricalInitialReport = localFixture.applySignature("InitialReporter", categoricalMarket.getReportingParticipant(0))
    assert categoricalMarket.getReportingParticipant(0) == categoricalInitialReport.address
    assert not categoricalInitialReport.isDisavowed()
    assert not universe.isContainerForReportingParticipant(categoricalInitialReport.address)
    assert newUniverse.isContainerForReportingParticipant(categoricalInitialReport.address)

    # The categorical market has a new dispute window since it was initially reported on and may be disputed now
    categoricalMarketDisputeWindowAddress = categoricalMarket.getDisputeWindow()
    categoricalMarketDisputeWindow = localFixture.applySignature("DisputeWindow", categoricalMarketDisputeWindowAddress)

    proceedToNextRound(localFixture, categoricalMarket)

    # We will finalize the categorical market in the new universe
    disputeWindow = localFixture.applySignature('DisputeWindow', categoricalMarket.getDisputeWindow())
    localFixture.contracts["Time"].setTimestamp(disputeWindow.getEndTime() + 1)

    assert categoricalMarket.finalize()

    # We can migrate a market that has not had its initial reporting completed as well, and confirm that the report is now made in the new universe
    reputationToken = localFixture.applySignature("ReputationToken", universe.getReputationToken())
    previousREPBalance = reputationToken.balanceOf(scalarMarket.address)
    assert previousREPBalance > 0
    assert scalarMarket.migrateThroughOneFork([0,0,scalarMarket.getNumTicks()], "")
    newUniverseREP = localFixture.applySignature("ReputationToken", newUniverse.getReputationToken())
    initialReporter = localFixture.applySignature('InitialReporter', scalarMarket.getInitialReporter())
    assert newUniverseREP.balanceOf(initialReporter.address) == newUniverse.getOrCacheDesignatedReportNoShowBond()

    # We can finalize this market as well
    proceedToNextRound(localFixture, scalarMarket)
    disputeWindow = localFixture.applySignature('DisputeWindow', scalarMarket.getDisputeWindow())
    localFixture.contracts["Time"].setTimestamp(disputeWindow.getEndTime() + 1)

    assert scalarMarket.finalize()
Exemple #18
0
def test_forking(finalizeByMigration, manuallyDisavow, localFixture, universe, market, cash, categoricalMarket, scalarMarket):
    claimTradingProceeds = localFixture.contracts["ClaimTradingProceeds"]

    # Let's go into the one dispute round for the categorical market
    proceedToNextRound(localFixture, categoricalMarket)
    proceedToNextRound(localFixture, categoricalMarket)

    # proceed to forking
    proceedToFork(localFixture, market, universe)

    with raises(TransactionFailed):
        universe.fork()

    with raises(TransactionFailed):
        categoricalMarket.migrateThroughOneFork([0,0,0,categoricalMarket.getNumTicks()], "")

    with raises(TransactionFailed):
        time = localFixture.contracts["Time"].getTimestamp()
        localFixture.createYesNoMarket(universe, time + 1000, 1, 0, localFixture.accounts[0])

    # confirm that we can manually create a child universe from an outcome no one asserted was true during dispute
    numTicks = market.getNumTicks()
    childUniverse = universe.createChildUniverse([0, numTicks/ 4, numTicks * 3 / 4])

    # confirm that before the fork is finalized we can redeem stake in other markets crowdsourcers, which are disavowable
    categoricalDisputeCrowdsourcer = localFixture.applySignature("DisputeCrowdsourcer", categoricalMarket.getReportingParticipant(1))

    # confirm we cannot liquidate it
    with raises(TransactionFailed):
        categoricalDisputeCrowdsourcer.liquidateLosing()

    # confirm we cannot fork it
    with raises(TransactionFailed):
        categoricalDisputeCrowdsourcer.forkAndRedeem()

    if manuallyDisavow:
        marketParticipantsDisavowedLog = {
            "universe": universe.address,
            "market": categoricalMarket.address,
        }
        with AssertLog(localFixture, "MarketParticipantsDisavowed", marketParticipantsDisavowedLog):
            assert categoricalMarket.disavowCrowdsourcers()
        # We can redeem before the fork finalizes since disavowal has occured
        assert categoricalDisputeCrowdsourcer.redeem(localFixture.accounts[0])

    # We cannot contribute to a crowdsourcer during a fork
    with raises(TransactionFailed):
        categoricalMarket.contribute([0,2,2,categoricalMarket.getNumTicks()-4], 1, "")

    # We cannot purchase new Participation Tokens during a fork
    disputeWindowAddress = universe.getOrCreateCurrentDisputeWindow(False)
    disputeWindow = localFixture.applySignature("DisputeWindow", disputeWindowAddress)

    # finalize the fork
    finalize(localFixture, market, universe, finalizeByMigration)

    # We cannot contribute to a crowdsourcer in a forked universe
    with raises(TransactionFailed):
        categoricalMarket.contribute([0,2,2,categoricalMarket.getNumTicks()-4], 1, "")

    newUniverseAddress = universe.getWinningChildUniverse()
    newUniverse = localFixture.applySignature("Universe", newUniverseAddress)

    # Let's make sure fork payouts work correctly for the forking market
    completeSets = localFixture.contracts['CompleteSets']
    numSets = 10
    cost = market.getNumTicks() * numSets
    with BuyWithCash(cash, cost, localFixture.accounts[0], "buy complete set"):
        assert completeSets.publicBuyCompleteSets(market.address, numSets)

    yesShare = localFixture.applySignature("ShareToken", market.getShareToken(YES))
    noShare = localFixture.applySignature("ShareToken", market.getShareToken(NO))

    noShare.transfer(localFixture.accounts[1], noShare.balanceOf(localFixture.accounts[0]))

    expectedYesOutcomePayout = newUniverse.payoutNumerators(YES)
    expectedNoOutcomePayout = newUniverse.payoutNumerators(NO)

    expectedYesPayout = expectedYesOutcomePayout * yesShare.balanceOf(localFixture.accounts[0]) * .99 # to account for fees (creator fee goes to the claimer in this case)
    with TokenDelta(cash, expectedYesPayout, localFixture.accounts[0], "Payout for Yes Shares was wrong in forking market"):
        claimTradingProceeds.claimTradingProceeds(market.address, localFixture.accounts[0], nullAddress)

    expectedNoPayout = expectedNoOutcomePayout * noShare.balanceOf(localFixture.accounts[1]) * .98 # to account for fees
    with TokenDelta(cash, expectedNoPayout, localFixture.accounts[1], "Payout for No Shares was wrong in forking market"):
        claimTradingProceeds.claimTradingProceeds(market.address, localFixture.accounts[1], nullAddress)

    # buy some complete sets to change OI of the cat market
    numSets = 10
    cost = categoricalMarket.getNumTicks() * numSets
    with BuyWithCash(cash, cost, localFixture.accounts[0], "buy complete set"):
        assert completeSets.publicBuyCompleteSets(categoricalMarket.address, numSets)
    assert universe.getOpenInterestInAttoCash() == cost

    marketMigratedLog = {
        "market": categoricalMarket.address,
        "newUniverse": newUniverseAddress,
        "originalUniverse": universe.address,
    }
    with AssertLog(localFixture, "MarketMigrated", marketMigratedLog):
        assert categoricalMarket.migrateThroughOneFork([0,0,0,categoricalMarket.getNumTicks()], "")

    assert universe.getOpenInterestInAttoCash() == 0

    # The dispute crowdsourcer has been disavowed
    newUniverse = localFixture.applySignature("Universe", categoricalMarket.getUniverse())
    assert newUniverse.address != universe.address
    assert categoricalDisputeCrowdsourcer.isDisavowed()
    assert not universe.isContainerForReportingParticipant(categoricalDisputeCrowdsourcer.address)
    assert not newUniverse.isContainerForReportingParticipant(categoricalDisputeCrowdsourcer.address)
    assert newUniverse.getOpenInterestInAttoCash() == cost

    # The initial report is still present however
    categoricalInitialReport = localFixture.applySignature("InitialReporter", categoricalMarket.getReportingParticipant(0))
    assert categoricalMarket.getReportingParticipant(0) == categoricalInitialReport.address
    assert not categoricalInitialReport.isDisavowed()
    assert not universe.isContainerForReportingParticipant(categoricalInitialReport.address)
    assert newUniverse.isContainerForReportingParticipant(categoricalInitialReport.address)

    # The categorical market has a new dispute window since it was initially reported on and may be disputed now
    categoricalMarketDisputeWindowAddress = categoricalMarket.getDisputeWindow()
    categoricalMarketDisputeWindow = localFixture.applySignature("DisputeWindow", categoricalMarketDisputeWindowAddress)

    proceedToNextRound(localFixture, categoricalMarket)

    # We will finalize the categorical market in the new universe
    disputeWindow = localFixture.applySignature('DisputeWindow', categoricalMarket.getDisputeWindow())
    localFixture.contracts["Time"].setTimestamp(disputeWindow.getEndTime() + 1)

    assert categoricalMarket.finalize()

    # We can migrate a market that has not had its initial reporting completed as well, and confirm that the report is now made in the new universe
    reputationToken = localFixture.applySignature("ReputationToken", universe.getReputationToken())
    previousREPBalance = reputationToken.balanceOf(scalarMarket.address)
    assert previousREPBalance > 0
    newReputationToken = localFixture.applySignature("ReputationToken", newUniverse.getReputationToken())
    with TokenDelta(reputationToken, previousREPBalance, scalarMarket.repBondOwner(), "Market did not transfer rep balance to rep bond owner"):
        with TokenDelta(newReputationToken, -newUniverse.getOrCacheMarketRepBond(), localFixture.accounts[0], "Migrator did not pay new REP bond"):
            assert scalarMarket.migrateThroughOneFork([0,0,scalarMarket.getNumTicks()], "")
    newUniverseREP = localFixture.applySignature("ReputationToken", newUniverse.getReputationToken())
    initialReporter = localFixture.applySignature('InitialReporter', scalarMarket.getInitialReporter())
    assert newUniverseREP.balanceOf(initialReporter.address) == newUniverse.getOrCacheDesignatedReportNoShowBond()

    # We cannot migrate legacy REP to the new Universe REP
    legacyRepToken = localFixture.applySignature('LegacyReputationToken', newUniverseREP.getLegacyRepToken())
    assert legacyRepToken.faucet(500)
    totalSupply = legacyRepToken.balanceOf(localFixture.accounts[0])
    legacyRepToken.approve(newUniverseREP.address, totalSupply)
    with raises(TransactionFailed):
        newUniverseREP.migrateFromLegacyReputationToken()

    # We can finalize this market as well
    proceedToNextRound(localFixture, scalarMarket)
    disputeWindow = localFixture.applySignature('DisputeWindow', scalarMarket.getDisputeWindow())
    localFixture.contracts["Time"].setTimestamp(disputeWindow.getEndTime() + 1)

    assert scalarMarket.finalize()
def test_forking_values(localFixture, universe, market, cash):
    reputationToken = localFixture.applySignature("ReputationToken", universe.getReputationToken())

    # proceed to forking
    proceedToFork(localFixture, market, universe)

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

    # We can see that the theoretical total REP supply in the winning child universe is higher than the initial REP supply
    winningPayoutHash = market.getWinningPayoutDistributionHash()
    childUniverse = localFixture.applySignature("Universe", universe.getChildUniverse(winningPayoutHash))
    childUniverseReputationToken = localFixture.applySignature("ReputationToken", childUniverse.getReputationToken())
    childUniverseTheoreticalSupply = childUniverseReputationToken.getTotalTheoreticalSupply()
    assert childUniverseTheoreticalSupply > reputationToken.getTotalTheoreticalSupply()

    # In fact it will be approximately the bonus REP migrated into the new universe more.
    delta = childUniverseTheoreticalSupply - reputationToken.getTotalTheoreticalSupply()
    migrationBonus = long(childUniverseReputationToken.getTotalMigrated() / 20L)
    participantIndex = 0
    while True:
        try:
            reportingParticipant = localFixture.applySignature("DisputeCrowdsourcer", market.getReportingParticipant(participantIndex))
            participantIndex += 1
            if reportingParticipant.getPayoutDistributionHash() != winningPayoutHash:
                continue
            migrationBonus += long(reportingParticipant.getSize() / 2L)
        except TransactionFailed:
            break
    assert delta == migrationBonus - 5 # rounding error dust buildup

    # The universe needs to be nudged to actually update values since there are potentially unbounded universes and updating the values derived by this total is not essential as a matter of normal procedure
    assert childUniverse.getForkReputationGoal() == universe.getForkReputationGoal()
    assert childUniverse.getDisputeThresholdForFork() == universe.getDisputeThresholdForFork()
    assert childUniverse.getInitialReportMinValue() == universe.getInitialReportMinValue()

    # The universe uses this theoretical total to calculate values such as the fork goal, fork dispute threshhold and the initial reporting defaults and floors
    assert childUniverse.updateForkValues()
    assert childUniverse.getForkReputationGoal() == childUniverseTheoreticalSupply / 2
    assert childUniverse.getDisputeThresholdForFork() == long(childUniverseTheoreticalSupply / 40L)
    assert childUniverse.getInitialReportMinValue() == long(childUniverse.getDisputeThresholdForFork() / 3L / 2**18 + 1)

    # Now we'll fork again and confirm it still takes only 20 dispute rounds in the worst case
    newMarket = localFixture.createReasonableBinaryMarket(childUniverse, cash)
    proceedToFork(localFixture, newMarket, childUniverse)
    assert newMarket.getNumParticipants() == 21

    # finalize the fork
    finalizeFork(localFixture, newMarket, childUniverse)

    # The total theoretical supply is again larger.
    childWinningPayoutHash = newMarket.getWinningPayoutDistributionHash()
    leafUniverse = localFixture.applySignature("Universe", childUniverse.getChildUniverse(childWinningPayoutHash))
    leafUniverseReputationToken = localFixture.applySignature("ReputationToken", leafUniverse.getReputationToken())
    leafUniverseTheoreticalSupply = leafUniverseReputationToken.getTotalTheoreticalSupply()
    assert leafUniverseTheoreticalSupply > childUniverseReputationToken.getTotalTheoreticalSupply()

    # We can make the child universe theoretical total more accurate by asking for a recomputation given a specific sibling universe to deduct from
    losingPayoutHash = market.derivePayoutDistributionHash([0, market.getNumTicks()], False)
    siblingUniverse = localFixture.applySignature("Universe", universe.getChildUniverse(losingPayoutHash))
    siblingReputationToken = localFixture.applySignature("ReputationToken", siblingUniverse.getReputationToken())
    assert childUniverseReputationToken.updateSiblingMigrationTotal(siblingReputationToken.address)
    newChildTheoreticalSupply = childUniverseReputationToken.getTotalTheoreticalSupply()
    siblingMigrationAmount = siblingReputationToken.getTotalMigrated()
    assert childUniverseTheoreticalSupply - newChildTheoreticalSupply == siblingMigrationAmount

    # Now that the child universe has been updated we can ask the leaf universe to recompute based on its parent's new theoretical total supply
    assert leafUniverseReputationToken.updateParentTotalTheoreticalSupply()
    newLeafTheoreticalSupply = leafUniverseReputationToken.getTotalTheoreticalSupply()
    assert leafUniverseTheoreticalSupply - newLeafTheoreticalSupply == siblingMigrationAmount
Exemple #20
0
def test_forking_values(localFixture, universe, market, cash):
    reputationToken = localFixture.applySignature(
        "ReputationToken", universe.getReputationToken())

    # proceed to forking
    proceedToFork(localFixture, market, universe)

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

    # We can see that the theoretical total REP supply in the winning child universe is higher than the initial REP supply
    winningPayoutHash = market.getWinningPayoutDistributionHash()
    childUniverse = localFixture.applySignature(
        "Universe", universe.getChildUniverse(winningPayoutHash))
    childUniverseReputationToken = localFixture.applySignature(
        "ReputationToken", childUniverse.getReputationToken())
    childUniverseTheoreticalSupply = childUniverseReputationToken.getTotalTheoreticalSupply(
    )
    assert childUniverseTheoreticalSupply > reputationToken.getTotalTheoreticalSupply(
    )

    # In fact it will be approximately the bonus REP migrated into the new universe more.
    delta = childUniverseTheoreticalSupply - reputationToken.getTotalTheoreticalSupply(
    )
    migrationBonus = long(childUniverseReputationToken.getTotalMigrated() /
                          20L)
    participantIndex = 0
    while True:
        try:
            reportingParticipant = localFixture.applySignature(
                "DisputeCrowdsourcer",
                market.getReportingParticipant(participantIndex))
            participantIndex += 1
            if reportingParticipant.getPayoutDistributionHash(
            ) != winningPayoutHash:
                continue
            migrationBonus += long(reportingParticipant.getSize() / 2L)
        except TransactionFailed:
            break
    assert delta == migrationBonus - 5  # rounding error dust buildup

    # The universe needs to be nudged to actually update values since there are potentially unbounded universes and updating the values derived by this total is not essential as a matter of normal procedure
    assert childUniverse.getForkReputationGoal(
    ) == universe.getForkReputationGoal()
    assert childUniverse.getDisputeThresholdForFork(
    ) == universe.getDisputeThresholdForFork()
    assert childUniverse.getInitialReportMinValue(
    ) == universe.getInitialReportMinValue()

    # The universe uses this theoretical total to calculate values such as the fork goal, fork dispute threshhold and the initial reporting defaults and floors
    assert childUniverse.updateForkValues()
    assert childUniverse.getForkReputationGoal(
    ) == childUniverseTheoreticalSupply / 2
    assert childUniverse.getDisputeThresholdForFork() == long(
        childUniverseTheoreticalSupply / 40L)
    assert childUniverse.getInitialReportMinValue() == long(
        childUniverse.getDisputeThresholdForFork() / 3L / 2**18 + 1)

    # Now we'll fork again and confirm it still takes only 20 dispute rounds in the worst case
    newMarket = localFixture.createReasonableBinaryMarket(childUniverse, cash)
    proceedToFork(localFixture, newMarket, childUniverse)
    assert newMarket.getNumParticipants() == 21

    # finalize the fork
    finalizeFork(localFixture, newMarket, childUniverse)

    # The total theoretical supply is again larger.
    childWinningPayoutHash = newMarket.getWinningPayoutDistributionHash()
    leafUniverse = localFixture.applySignature(
        "Universe", childUniverse.getChildUniverse(childWinningPayoutHash))
    leafUniverseReputationToken = localFixture.applySignature(
        "ReputationToken", leafUniverse.getReputationToken())
    leafUniverseTheoreticalSupply = leafUniverseReputationToken.getTotalTheoreticalSupply(
    )
    assert leafUniverseTheoreticalSupply > childUniverseReputationToken.getTotalTheoreticalSupply(
    )

    # We can make the child universe theoretical total more accurate by asking for a recomputation given a specific sibling universe to deduct from
    losingPayoutHash = market.derivePayoutDistributionHash(
        [0, market.getNumTicks()], False)
    siblingUniverse = localFixture.applySignature(
        "Universe", universe.getChildUniverse(losingPayoutHash))
    siblingReputationToken = localFixture.applySignature(
        "ReputationToken", siblingUniverse.getReputationToken())
    assert childUniverseReputationToken.updateSiblingMigrationTotal(
        siblingReputationToken.address)
    newChildTheoreticalSupply = childUniverseReputationToken.getTotalTheoreticalSupply(
    )
    siblingMigrationAmount = siblingReputationToken.getTotalMigrated()
    assert childUniverseTheoreticalSupply - newChildTheoreticalSupply == siblingMigrationAmount

    # Now that the child universe has been updated we can ask the leaf universe to recompute based on its parent's new theoretical total supply
    assert leafUniverseReputationToken.updateParentTotalTheoreticalSupply()
    newLeafTheoreticalSupply = leafUniverseReputationToken.getTotalTheoreticalSupply(
    )
    assert leafUniverseTheoreticalSupply - newLeafTheoreticalSupply == siblingMigrationAmount
Exemple #21
0
def test_forking_values(localFixture, universe, market):
    reputationToken = localFixture.applySignature("ReputationToken", universe.getReputationToken())

    # Give some REP to another account
    reputationToken.transfer(tester.a1, 100)

    # proceed to forking
    proceedToFork(localFixture, market, universe)

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

    # We can see that the theoretical total REP supply in the winning child universe is equal to the parent supply
    winningPayoutHash = market.getWinningPayoutDistributionHash()
    childUniverse = localFixture.applySignature("Universe", universe.getChildUniverse(winningPayoutHash))
    childUniverseReputationToken = localFixture.applySignature("ReputationToken", childUniverse.getReputationToken())
    childUniverseTheoreticalSupply = childUniverseReputationToken.getTotalTheoreticalSupply()
    assert childUniverseTheoreticalSupply == reputationToken.getTotalTheoreticalSupply()

    # If we nudge the reputation token to update its theoretical balance we can see a lower total to account for sibling migrations
    assert childUniverseReputationToken.updateTotalTheoreticalSupply()
    assert childUniverseReputationToken.getTotalTheoreticalSupply() <= childUniverseTheoreticalSupply
    childUniverseTheoreticalSupply = childUniverseReputationToken.getTotalTheoreticalSupply()

    # If we migrate some REP to another Universe we can recalculate and see that amount deducted from the theoretical supply
    losingPayoutNumerators = [0, 0, market.getNumTicks()]
    losingUniverse =  localFixture.applySignature('Universe', universe.createChildUniverse(losingPayoutNumerators))
    losingUniverseReputationToken = localFixture.applySignature('ReputationToken', losingUniverse.getReputationToken())
    assert reputationToken.migrateOut(losingUniverseReputationToken.address, 100, sender=tester.k1)
    assert childUniverseReputationToken.updateTotalTheoreticalSupply()
    lowerChildUniverseTheoreticalSupply = childUniverseReputationToken.getTotalTheoreticalSupply()
    assert lowerChildUniverseTheoreticalSupply == childUniverseTheoreticalSupply - 100

    # If we move past the forking window end time and we update the theoretical supply however we will see that some REP was trapped in the parent and deducted from the supply
    localFixture.contracts["Time"].setTimestamp(universe.getForkEndTime() + 1)
    assert childUniverseReputationToken.updateTotalTheoreticalSupply()
    childUniverseTheoreticalSupply = childUniverseReputationToken.getTotalTheoreticalSupply()
    assert childUniverseTheoreticalSupply < lowerChildUniverseTheoreticalSupply

    # The universe needs to be nudged to actually update values since there are potentially unbounded universes and updating the values derived by this total is not essential as a matter of normal procedure
    # In a forked universe the total supply will be different so its childrens goals will not be the same initially
    if not localFixture.subFork:
        assert childUniverse.getForkReputationGoal() == universe.getForkReputationGoal()
        assert childUniverse.getDisputeThresholdForFork() == universe.getDisputeThresholdForFork()
        assert childUniverse.getInitialReportMinValue() == universe.getInitialReportMinValue()

    # The universe uses this theoretical total to calculate values such as the fork goal, fork dispute threshhold and the initial reporting defaults and floors
    assert childUniverse.updateForkValues()
    assert childUniverse.getForkReputationGoal() == childUniverseTheoreticalSupply / 2
    assert childUniverse.getDisputeThresholdForFork() == long(childUniverseTheoreticalSupply / 40L)
    assert childUniverse.getInitialReportMinValue() == long(childUniverse.getDisputeThresholdForFork() / 3L / 2**18 + 1)

    # Now we'll fork again and confirm it still takes only 20 dispute rounds in the worst case
    newMarket = localFixture.createReasonableYesNoMarket(childUniverse)
    proceedToFork(localFixture, newMarket, childUniverse)
    assert newMarket.getNumParticipants() == 21

    # finalize the fork
    finalizeFork(localFixture, newMarket, childUniverse)

    # The total theoretical supply is again the same as the parents during the fork
    childWinningPayoutHash = newMarket.getWinningPayoutDistributionHash()
    leafUniverse = localFixture.applySignature("Universe", childUniverse.getChildUniverse(childWinningPayoutHash))
    leafUniverseReputationToken = localFixture.applySignature("ReputationToken", leafUniverse.getReputationToken())
    leafUniverseTheoreticalSupply = leafUniverseReputationToken.getTotalTheoreticalSupply()
    assert leafUniverseTheoreticalSupply == childUniverseReputationToken.getTotalTheoreticalSupply()

    # After the fork window ends however we can again recalculate
    localFixture.contracts["Time"].setTimestamp(childUniverse.getForkEndTime() + 1)
    assert leafUniverseReputationToken.updateTotalTheoreticalSupply()
    leafUniverseTheoreticalSupply = leafUniverseReputationToken.getTotalTheoreticalSupply()
    assert leafUniverseTheoreticalSupply < childUniverseReputationToken.getTotalTheoreticalSupply()
def test_forking(finalizeByMigration, manuallyDisavow, localFixture, universe, cash, market, categoricalMarket, scalarMarket):
    # Let's go into the one dispute round for the categorical market
    proceedToNextRound(localFixture, categoricalMarket)
    proceedToNextRound(localFixture, categoricalMarket)

    # proceed to forking
    proceedToFork(localFixture, market, universe)

    with raises(TransactionFailed):
        universe.fork()

    with raises(TransactionFailed, message="We cannot migrate until the fork is finalized"):
        categoricalMarket.migrateThroughOneFork()

    with raises(TransactionFailed, message="We cannot create markets during a fork"):
        time = localFixture.contracts["Time"].getTimestamp()
        localFixture.createBinaryMarket(universe, time + 1000, 1, cash, tester.a0)

    # confirm that we can manually create a child universe from an outcome no one asserted was true during dispute
    numTicks = market.getNumTicks()
    childUniverse = universe.createChildUniverse([numTicks/ 4, numTicks * 3 / 4], False)

    # confirm that before the fork is finalized we can redeem stake in other markets crowdsourcers, which are disavowable
    categoricalDisputeCrowdsourcer = localFixture.applySignature("DisputeCrowdsourcer", categoricalMarket.getReportingParticipant(1))

    # confirm we cannot migrate it
    with raises(TransactionFailed):
        categoricalDisputeCrowdsourcer.migrate()

    # confirm we cannot liquidate it
    with raises(TransactionFailed):
        categoricalDisputeCrowdsourcer.liquidateLosing()

    # confirm we cannot fork it
    with raises(TransactionFailed):
        categoricalDisputeCrowdsourcer.fork()

    if manuallyDisavow:
        marketParticipantsDisavowedLog = {
            "universe": universe.address,
            "market": categoricalMarket.address,
        }
        with AssertLog(localFixture, "MarketParticipantsDisavowed", marketParticipantsDisavowedLog):
            assert categoricalMarket.disavowCrowdsourcers()
        # We can redeem before the fork finalizes since disavowal has occured
        assert categoricalDisputeCrowdsourcer.redeem(tester.a0)

    # We cannot contribute to a crowdsourcer during a fork
    with raises(TransactionFailed):
        categoricalMarket.contribute([2,2,categoricalMarket.getNumTicks()-4], False, 1)

    # We cannot purchase new Participation Tokens during a fork
    feeWindowAddress = universe.getCurrentFeeWindow()
    feeWindow = localFixture.applySignature("FeeWindow", feeWindowAddress)
    with raises(TransactionFailed):
        feeWindow.buy(1)

    # finalize the fork
    marketFinalizedLog = {
        "universe": universe.address,
        "market": market.address,
    }
    with AssertLog(localFixture, "MarketFinalized", marketFinalizedLog):
        finalizeFork(localFixture, market, universe, finalizeByMigration)

    # We cannot contribute to a crowdsourcer in a forked universe
    with raises(TransactionFailed):
        categoricalMarket.contribute([2,2,categoricalMarket.getNumTicks()-4], False, 1)

    # The categorical market can be migrated to the winning universe
    newUniverseAddress = universe.getWinningChildUniverse()
    marketMigratedLog = {
        "market": categoricalMarket.address,
        "newUniverse": newUniverseAddress,
        "originalUniverse": universe.address,
    }
    with AssertLog(localFixture, "MarketMigrated", marketMigratedLog):
        assert categoricalMarket.migrateThroughOneFork()

    # The dispute crowdsourcer has been disavowed
    newUniverse = localFixture.applySignature("Universe", categoricalMarket.getUniverse())
    assert newUniverse.address != universe.address
    assert categoricalDisputeCrowdsourcer.isDisavowed()
    assert not universe.isContainerForReportingParticipant(categoricalDisputeCrowdsourcer.address)
    assert not newUniverse.isContainerForReportingParticipant(categoricalDisputeCrowdsourcer.address)

    # The initial report is still present however
    categoricalInitialReport = localFixture.applySignature("InitialReporter", categoricalMarket.getReportingParticipant(0))
    assert categoricalMarket.getReportingParticipant(0) == categoricalInitialReport.address
    assert not categoricalInitialReport.isDisavowed()
    assert not universe.isContainerForReportingParticipant(categoricalInitialReport.address)
    assert newUniverse.isContainerForReportingParticipant(categoricalInitialReport.address)

    # The categorical market has a new fee window since it was initially reported on and may be disputed now
    categoricalMarketFeeWindowAddress = categoricalMarket.getFeeWindow()
    categoricalMarketFeeWindow = localFixture.applySignature("FeeWindow", categoricalMarketFeeWindowAddress)

    proceedToNextRound(localFixture, categoricalMarket, moveTimeForward = False)

    # We can also purchase Participation Tokens in this fee window
    assert categoricalMarketFeeWindow.buy(1)

    # We will finalize the categorical market in the new universe
    feeWindow = localFixture.applySignature('FeeWindow', categoricalMarket.getFeeWindow())
    localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1)

    assert categoricalMarket.finalize()

    # We can migrate a market that has not had its initial reporting completed as well, and confirm its REP no show bond is in the new universe REP
    reputationToken = localFixture.applySignature("ReputationToken", universe.getReputationToken())
    previousREPBalance = reputationToken.balanceOf(scalarMarket.address)
    assert previousREPBalance > 0
    bonus = previousREPBalance / localFixture.contracts["Constants"].FORK_MIGRATION_PERCENTAGE_BONUS_DIVISOR() if finalizeByMigration else 0
    assert scalarMarket.migrateThroughOneFork()
    newUniverseREP = localFixture.applySignature("ReputationToken", newUniverse.getReputationToken())
    assert newUniverseREP.balanceOf(scalarMarket.address) == previousREPBalance + bonus

    # We can finalize this market as well
    proceedToNextRound(localFixture, scalarMarket)
    feeWindow = localFixture.applySignature('FeeWindow', scalarMarket.getFeeWindow())
    localFixture.contracts["Time"].setTimestamp(feeWindow.getEndTime() + 1)

    assert scalarMarket.finalize()