コード例 #1
0
def test_auction_start(chain, web3, owner, get_bidders,
                       auction_contract_fast_decline, token_contract,
                       auction_bid_tested, auction_end_tests, event_handler):
    auction = auction_contract_fast_decline
    token = token_contract(auction.address)
    ev_handler = event_handler(auction)
    (A, B) = get_bidders(2)

    # Should not be able to start auction before setup
    with pytest.raises(tester.TransactionFailed):
        auction.transact({'from': owner}).startAuction()

    txn_hash = auction.transact({'from': owner}).setup(token.address)
    ev_handler.add(txn_hash, 'Setup')
    assert auction.call().stage() == 1

    token_multiplier = auction.call().token_multiplier()

    # Should not be able to start auction if not owner
    with pytest.raises(tester.TransactionFailed):
        auction.transact({'from': A}).startAuction()

    txn_hash = auction.transact({'from': owner}).startAuction()
    receipt = chain.wait.for_receipt(txn_hash)
    timestamp = web3.eth.getBlock(receipt['blockNumber'])['timestamp']
    assert auction.call().stage() == 2
    assert auction.call().start_time() == timestamp
    assert auction.call().start_block() == receipt['blockNumber']
    ev_handler.add(txn_hash, 'AuctionStarted',
                   checkAuctionStartedEvent(timestamp, receipt['blockNumber']))

    # Should not be able to call start auction after it has already started
    with pytest.raises(tester.TransactionFailed):
        auction.transact({'from': owner}).startAuction()

    amount = web3.eth.getBalance(A) - 10000000
    missing_funds = auction.call().missingFundsToEndAuction()

    # Fails if amount is > missing_funds
    if (missing_funds < amount):
        with pytest.raises(tester.TransactionFailed):
            auction_bid_tested(auction, A, amount)

    missing_funds = auction.call().missingFundsToEndAuction()
    auction_bid_tested(auction, A, missing_funds)

    # Finalize auction
    assert auction.call().missingFundsToEndAuction() == 0
    txn_hash = auction.transact({'from': owner}).finalizeAuction()
    final_price = auction.call().final_price()
    ev_handler.add(txn_hash, 'AuctionEnded',
                   checkAuctionEndedEvent(final_price))
    auction_end_tests(auction, B)

    with pytest.raises(tester.TransactionFailed):
        auction.transact({'from': owner}).startAuction()

    ev_handler.check()
コード例 #2
0
ファイル: test_auction.py プロジェクト: ulope/raiden-token
def test_price(
    web3,
    owner,
    wallet_address,
    auction_contract,
    token_contract,
    auction_bid_tested,
    auction_end_tests,
    price,
    event_handler):
    auction = auction_contract
    token = token_contract(auction.address)
    ev_handler = event_handler(auction)
    (A, B) = web3.eth.accounts[2:4]

    # Auction price after deployment; token_multiplier is 0 at this point
    assert auction.call().price() == auction.call().price_start()

    txn_hash = auction.transact({'from': owner}).setup(token.address)
    ev_handler.add(txn_hash, 'Setup')

    token_multiplier = auction.call().token_multiplier()

    # Auction price before auction start
    price_start = auction.call().price_start()
    price_constant = auction.call().price_constant()
    assert auction.call().price() == price_start

    txn_hash = auction.transact({'from': owner}).startAuction()
    ev_handler.add(txn_hash, 'AuctionStarted')
    start_time = auction.call().start_time()

    elapsed = 33
    web3.testing.timeTravel(start_time + elapsed)
    new_price = price(elapsed)
    assert new_price == auction.call().price()

    missing_funds = auction.call().missingFundsToEndAuction()
    auction_bid_tested(auction, A, missing_funds)

    txn_hash = auction.transact({'from': owner}).finalizeAuction()
    final_price = auction.call().final_price()
    ev_handler.add(txn_hash, 'AuctionEnded', checkAuctionEndedEvent(final_price))
    auction_end_tests(auction, B)

    # Calculate final price
    received_wei = auction.call().received_wei()
    num_tokens_auctioned = auction.call().num_tokens_auctioned()
    final_price = received_wei // (num_tokens_auctioned // token_multiplier)

    assert auction.call().price() == 0
    assert auction.call().final_price() == final_price

    ev_handler.check()
コード例 #3
0
def test_auction_simulation(chain, web3, owner, get_bidders, auction_contract,
                            token_contract, contract_params,
                            auction_bid_tested, auction_end_tests,
                            auction_post_distributed_tests,
                            auction_claim_tokens_tested, create_accounts,
                            txnCost, event_handler):
    eth = web3.eth
    auction = auction_contract
    ev_handler = event_handler(auction)
    bidders = get_bidders(12)

    # Initialize token
    token = token_contract(auction.address)

    # Initial Auction state
    assert auction.call().stage() == 0  # AuctionDeployed
    assert eth.getBalance(auction.address) == 0
    assert auction.call().received_wei() == 0

    # Auction setup without being the owner should fail
    with pytest.raises(tester.TransactionFailed):
        auction.transact({'from': bidders[1]}).setup(token.address)

    txn_hash = auction.transact({'from': owner}).setup(token.address)
    ev_handler.add(txn_hash, 'Setup')

    assert auction.call().stage() == 1  # AuctionSetUp

    token_multiplier = auction.call().token_multiplier()

    # We want to revert to these, because we set them in the fixtures
    initial_args = [
        auction.call().price_start(),
        auction.call().price_constant(),
        auction.call().price_exponent()
    ]

    # changeSettings is a private method
    with pytest.raises(ValueError):
        auction.transact({'from': owner}).changeSettings(1000, 556, 322)

    # startAuction without being the owner should fail
    with pytest.raises(tester.TransactionFailed):
        auction.transact({'from': bidders[1]}).startAuction()

    auction.transact({'from': owner}).startAuction()
    assert auction.call().stage() == 2  # AuctionStarted

    # transferFundsToToken should fail (private)
    with pytest.raises(ValueError):
        auction.transact({'from': bidders[1]}).transferFundsToToken()

    # finalizeAuction should fail (missing funds not 0)
    with pytest.raises(tester.TransactionFailed):
        auction.transact({'from': bidders[1]}).finalizeAuction()
    with pytest.raises(tester.TransactionFailed):
        auction.transact({'from': owner}).finalizeAuction()

    # Set maximum amount for a bid - we don't want 1 account draining the auction
    missing_funds = auction.call().missingFundsToEndAuction()
    maxBid = missing_funds / 4

    # TODO Test multiple orders from 1 buyer

    # Bidders start ordering tokens
    bidders_len = len(bidders) - 1
    bidded = 0  # Total bidded amount
    index = 0  # bidders index

    # Make some bids with 1 wei to be sure we test rounding errors
    txn_hash = auction_bid_tested(auction, bidders[0], 1)
    ev_handler.add(txn_hash, 'BidSubmission',
                   checkBidEvent(bidders[0], 1, missing_funds))

    missing_funds = auction.call().missingFundsToEndAuction()
    txn_hash = auction_bid_tested(auction, bidders[1], 1)
    ev_handler.add(txn_hash, 'BidSubmission',
                   checkBidEvent(bidders[1], 1, missing_funds))

    index = 2
    bidded = 2
    approx_bid_txn_cost = 4000000

    while auction.call().missingFundsToEndAuction() > 0:
        if bidders_len < index:
            new_account = create_accounts(1)[0]
            bidders.append(new_account)
            bidders_len += 1
            print('Creating 1 additional bidder account', new_account)

        bidder = bidders[index]

        bidder_balance = eth.getBalance(bidder)
        assert auction.call().bids(bidder) == 0

        missing_funds = auction.call().missingFundsToEndAuction()
        amount = int(min(bidder_balance - approx_bid_txn_cost, maxBid))

        if amount <= missing_funds:
            txn_hash = auction.transact({
                'from': bidder,
                "value": amount
            }).bid()
        else:
            # Fail if we bid more than missing_funds
            with pytest.raises(tester.TransactionFailed):
                auction.transact({'from': bidder, "value": amount}).bid()

            # Bid exactly the amount needed in order to end the auction
            amount = missing_funds
            txn_hash = auction.transact({
                'from': bidder,
                "value": amount
            }).bid()

        assert auction.call().bids(bidder) == amount
        ev_handler.add(txn_hash, 'BidSubmission',
                       checkBidEvent(bidder, amount, missing_funds))

        txn_cost = txnCost(txn_hash)
        post_balance = bidder_balance - amount - txn_cost
        bidded += min(amount, missing_funds)

        assert eth.getBalance(bidder) == post_balance
        index += 1

    print('NO OF BIDDERS', index)

    # Auction ended, no more orders possible
    if bidders_len < index:
        print(
            '!! Not enough accounts to simulate bidders. 1 additional account needed'
        )

    # Finalize Auction
    txn_hash = auction.transact({'from': owner}).finalizeAuction()

    # Final price per TKN (Tei * token_multiplier)
    final_price = auction.call().final_price()

    # Make sure events are issued correctly
    ev_handler.add(txn_hash, 'AuctionEnded',
                   checkAuctionEndedEvent(final_price))

    with pytest.raises(tester.TransactionFailed):
        auction.transact({'from': owner}).finalizeAuction()

    assert auction.call().received_wei() == bidded
    auction_end_tests(auction, bidders[index])

    # Claim all tokens

    funds_at_price = auction.call().num_tokens_auctioned(
    ) * final_price // token_multiplier
    received_wei = auction.call().received_wei()
    # FIXME sometimes: assert 5000000002 == 5000000000
    assert received_wei == funds_at_price

    # Total Tei claimable
    total_tokens_claimable = auction.call().received_wei(
    ) * token_multiplier // final_price
    print('FINAL PRICE', final_price)
    print('TOTAL TOKENS CLAIMABLE', int(total_tokens_claimable))
    # FIXME assert 5000000002000000000000000 == 5000000000000000000000000
    assert int(total_tokens_claimable) == auction.call().num_tokens_auctioned()

    rounding_error_tokens = 0

    end_time = auction.call().end_time()
    elapsed = auction.call().token_claim_waiting_period()
    claim_ok_timestamp = end_time + elapsed + 1

    # We cannot claim tokens before waiting period has passed
    if claim_ok_timestamp > web3.eth.getBlock('latest')['timestamp']:
        with pytest.raises(tester.TransactionFailed):
            auction_claim_tokens_tested(token, auction, bidders[0])

        # Simulate time travel
        web3.testing.timeTravel(claim_ok_timestamp)

    for i in range(0, index):
        bidder = bidders[i]

        tokens_expected = token_multiplier * auction.call().bids(
            bidder) // final_price
        txn_hash = auction_claim_tokens_tested(token, auction, bidder)

        ev_handler.add(txn_hash, 'ClaimedTokens',
                       checkClaimedTokensEvent(bidder, tokens_expected))

        # If auction funds not transferred to owner (last claimTokens)
        # we test for a correct claimed tokens calculation
        balance_auction = auction.call().received_wei()
        if balance_auction > 0:

            # Auction supply = unclaimed tokens, including rounding errors
            unclaimed_token_supply = token.call().balanceOf(auction.address)

            # Calculated unclaimed tokens
            unclaimed_funds = balance_auction - auction.call().funds_claimed()
            unclaimed_tokens = token_multiplier * unclaimed_funds // auction.call(
            ).final_price()

            # Adding previous rounding errors
            unclaimed_tokens += rounding_error_tokens

            # Token's auction balance should be the same as
            # the unclaimed tokens calculation based on the final_price
            # We assume a rounding error of 1
            if unclaimed_token_supply != unclaimed_tokens:
                rounding_error_tokens += 1
                unclaimed_tokens += 1

            # FIXME assert 4999999999000000000000000 == 5000000001000000000000001
            assert unclaimed_token_supply == unclaimed_tokens

    # Auction balance might be > 0 due to rounding errors
    assert token.call().balanceOf(auction.address) == rounding_error_tokens
    print('FINAL UNCLAIMED TOKENS', rounding_error_tokens)

    # Last claimTokens also triggers a TokensDistributed event
    ev_handler.add(txn_hash, 'TokensDistributed')

    auction_post_distributed_tests(auction)

    # Check if all registered events have been triggered
    ev_handler.check()