def proxy_contract(chain, create_contract): AuctionProxy = chain.provider.get_contract_factory('Proxy') proxy_contract = create_contract(AuctionProxy, []) print_logs(proxy_contract, 'Payable', 'Proxy') return proxy_contract
def test_auction_init(chain, web3, owner, wallet_address, whitelister_address, create_contract, contract_params): Auction = chain.provider.get_contract_factory('DutchAuction') args = [wallet_address, whitelister_address] with pytest.raises(TypeError): auction_contract = create_contract(Auction, args) with pytest.raises(TypeError): auction_contract = create_contract(Auction, args + [10000, -3, 2]) with pytest.raises(TypeError): auction_contract = create_contract(Auction, args + [10000, 3, -2]) with pytest.raises(TypeError): auction_contract = create_contract(Auction, args + [-1, 3, 2]) with pytest.raises(tester.TransactionFailed): auction_contract = create_contract(Auction, args + [10000, 0, 2]) with pytest.raises(tester.TransactionFailed): auction_contract = create_contract(Auction, args + [0, 3, 2]) create_contract(Auction, args + contract_params['args'], {'from': owner})
def proxy_erc223_contract(chain, create_contract): AuctionProxy = chain.provider.get_contract_factory('ProxyERC223') proxy_erc223_contract = create_contract(AuctionProxy, []) return proxy_erc223_contract
def test_distributor_distribute(chain, web3, wallet_address, owner, get_bidders, create_contract, token_contract, auction_contract_fast_decline, auction_bid_tested, auction_claim_tokens_tested, auction_post_distributed_tests): bidders = get_bidders(10) auction = auction_contract_fast_decline token = token_contract(auction.address) auction.transact({'from': owner}).setup(token.address) auction.transact({'from': owner}).startAuction() Distributor = chain.provider.get_contract_factory('Distributor') distributor = create_contract(Distributor, [auction.address]) # Retrieve bidder addresses from contract bid events def get_bidders_addresses(event): address = event['args']['_sender'] if address not in addresses: addresses.append(address) values.append(0) index = len(addresses) - 1 else: index = addresses.index(address) values[index] += event['args']['_amount'] def verify_claim(event): addr = event['args']['_recipient'] sent_amount = event['args']['_sent_amount'] # Check for double claiming assert addr not in verified_claim assert auction.call().bids(addr) == 0 assert sent_amount == token.call().balanceOf(addr) verified_claim.append(address) for bidder in bidders: missing = auction.call().missingFundsToEndAuction() balance = web3.eth.getBalance(bidder) amount = min(missing, balance - 500000) if (amount > 0): print('-- BIDDING', amount, missing, balance) auction_bid_tested(auction, bidder, amount) assert auction.call().missingFundsToEndAuction() == 0 auction.transact({'from': owner}).finalizeAuction() addresses = [] values = [] claimed = [] verified_claim = [] handle_logs(contract=auction, event='BidSubmission', callback=get_bidders_addresses) with pytest.raises(tester.TransactionFailed): distributor.transact({'from': owner}).distribute(addresses[0:2]) end_time = auction.call().end_time() elapsed = auction.call().token_claim_waiting_period() web3.testing.timeTravel(end_time + elapsed + 1) # Send 5 claiming transactions in a single batch to not run out of gas safe_distribution_no = 5 steps = math.ceil(len(addresses) / safe_distribution_no) # Call the distributor contract with batches of bidder addresses for i in range(0, steps): start = i * safe_distribution_no end = (i + 1) * safe_distribution_no auction_claim_tokens_tested(token, auction, addresses[start:end], distributor) # distributor.transact({'from': owner}).distribute(addresses[start:end]) auction_post_distributed_tests(auction) # Verify that a single "ClaimedTokens" event has been issued by the auction contract # for each address for j in range(0, len(addresses) - 1): address = addresses[j] assert auction.call().bids(address) == 0 # check if auction event was triggered for this user handle_logs(contract=auction, event='ClaimedTokens', params={'filter': { '_recipient': address }}, callback=verify_claim)
def test_distributor_init(chain, web3, wallet_address, owner, get_bidders, create_contract, contract_params): A = get_bidders(1)[0] Distributor = chain.provider.get_contract_factory('Distributor') Auction = chain.provider.get_contract_factory('DutchAuction') auction = create_contract(Auction, [wallet_address] + contract_params['args'], {'from': owner}) other_auction_params = [wallet_address] + contract_params['args'] other_owner_auction = create_contract(Auction, other_auction_params, {'from': A}) other_contract_type = create_contract(Distributor, [auction.address]) assert owner != A # Fail if no auction address is provided with pytest.raises(TypeError): create_contract(Distributor, []) # Fail if non address-type auction address is provided with pytest.raises(TypeError): create_contract(Distributor, [fake_address]) with pytest.raises(TypeError): create_contract(Distributor, [0x0]) # Fail if auction has another owner with pytest.raises(tester.TransactionFailed): create_contract(Distributor, [other_owner_auction.address]) distributor_contract = create_contract(Distributor, [auction.address])
def test_distributor_distribute(chain, web3, wallet_address, owner, get_bidders, create_contract, token_contract, auction_contract_fast_decline, auction_bid_tested, auction_claim_tokens_tested, auction_post_distributed_tests, event_handler): bidders = get_bidders(10) auction = auction_contract_fast_decline token = token_contract(auction.address) ev_handler = event_handler(auction) auction.transact({'from': owner}).setup(token.address) auction.transact({'from': owner}).startAuction() Distributor = chain.provider.get_contract_factory('Distributor') distributor = create_contract(Distributor, [auction.address]) collector = ClaimsCollector(auction, token) bidders_number = 0 # Simulate some bids and collect the addresses from the events for bidder in bidders[:-1]: missing = auction.call().missingFundsToEndAuction() balance = web3.eth.getBalance(bidder) cap = (balance - 500000) // 1000000000000000000 amount = min(missing, cap) # print('-- BIDDING', bidder, amount, missing, balance, cap) if (amount > 0): tx_hash = auction_bid_tested(auction, bidder, amount) ev_handler.add(tx_hash, 'BidSubmission', collector.add) ev_handler.check() bidders_number += 1 missing = auction.call().missingFundsToEndAuction() if missing > 0: tx_hash = auction_bid_tested(auction, bidders[-1], missing) ev_handler.add(tx_hash, 'BidSubmission', collector.add) ev_handler.check() bidders_number += 1 assert auction.call().missingFundsToEndAuction() == 0 auction.transact({'from': owner}).finalizeAuction() assert len(collector.addresses) == bidders_number end_time = auction.call().end_time() elapsed = auction.call().token_claim_waiting_period() claim_ok_timestamp = end_time + elapsed + 1 if claim_ok_timestamp > web3.eth.getBlock('latest')['timestamp']: # We cannot claim tokens before waiting period has passed with pytest.raises(tester.TransactionFailed): distributor.transact({ 'from': owner }).distribute(collector.addresses[0:2]) # Simulate time travel web3.testing.timeTravel(claim_ok_timestamp) # Send 5 claiming transactions in a single batch to not run out of gas safe_distribution_no = 5 steps = math.ceil(len(collector.addresses) / safe_distribution_no) # Call the distributor contract with batches of bidder addresses for i in range(0, steps): start = i * safe_distribution_no end = (i + 1) * safe_distribution_no tx_hash = auction_claim_tokens_tested(token, auction, collector.addresses[start:end], distributor) ev_handler.add(tx_hash, 'ClaimedTokens', collector.verify) ev_handler.check() # distributor.transact({'from': owner}).distribute(collector.addresses[start:end]) auction_post_distributed_tests(auction)
def test_auction_whitelist( chain, web3, owner, wallet_address, whitelister_address, get_bidders, create_contract, token_contract, contract_params, event_handler): eth = web3.eth (A, B, C, D, E, F) = get_bidders(6) Auction = chain.provider.get_contract_factory('DutchAuction') args = [wallet_address, whitelister_address, 2 * 10 ** 18, 1574640000, 3] auction = create_contract(Auction, args, {'from': owner}) # Initialize token token = token_contract(auction.address) bid_threshold = auction.call().bid_threshold() assert auction.call().whitelist(A) == False assert auction.call().whitelist(B) == False assert auction.call().whitelist(C) == False assert auction.call().whitelist(D) == False assert auction.call().whitelist(E) == False # Only the whitelister_address can add addresses to the whitelist with pytest.raises(tester.TransactionFailed): auction.transact({'from': owner}).addToWhitelist([A, B]) with pytest.raises(tester.TransactionFailed): auction.transact({'from': wallet_address}).addToWhitelist([A, B]) with pytest.raises(tester.TransactionFailed): auction.transact({'from': A}).addToWhitelist([A, B]) with pytest.raises(tester.TransactionFailed): auction.transact({'from': C}).addToWhitelist([A, B]) # We should be able to whitelist at this point auction.transact({'from': whitelister_address}).addToWhitelist([A, B]) assert auction.call().whitelist(A) == True assert auction.call().whitelist(B) == True auction.transact({'from': owner}).setup(token.address) auction.transact({'from': whitelister_address}).addToWhitelist([D]) assert auction.call().whitelist(D) == True auction.transact({'from': owner}).startAuction() # Bid more than bid_threshold should fail for E value = bid_threshold + 1 with pytest.raises(tester.TransactionFailed): eth.sendTransaction({ 'from': E, 'to': auction.address, 'value': value }) with pytest.raises(tester.TransactionFailed): auction.transact({'from': E, "value": value}).bid() auction.transact({'from': whitelister_address}).addToWhitelist([E]) assert auction.call().whitelist(E) == True print('--- web3.eth.getBalance(E)-- ', web3.eth.getBalance(E)) print('--- value -- ', value) print('--- bids -- ', auction.call().bids(E)) assert web3.eth.getBalance(E) > value # Bid more than bid_threshold should be ok for E eth.sendTransaction({ 'from': E, 'to': auction.address, 'value': value }) auction.transact({'from': A, "value": value}).bid() # Test whitelist removal auction.transact({'from': B, "value": value}).bid() # Only the whitelister_address can add addresses to the whitelist with pytest.raises(tester.TransactionFailed): auction.transact({'from': owner}).removeFromWhitelist([B]) with pytest.raises(tester.TransactionFailed): auction.transact({'from': wallet_address}).removeFromWhitelist([B]) with pytest.raises(tester.TransactionFailed): auction.transact({'from': A}).removeFromWhitelist([B]) with pytest.raises(tester.TransactionFailed): auction.transact({'from': C}).removeFromWhitelist([B]) auction.transact({'from': whitelister_address}).removeFromWhitelist([B]) assert auction.call().whitelist(B) == False with pytest.raises(tester.TransactionFailed): auction.transact({'from': B, "value": value}).bid()