def test_buy_all(chain, web3, crowdsale, token, finalizer, start_time, end_time, team_multisig, customer, cap, founder_allocation): """Buy all tokens and finalize crowdsale.""" # Buy on first week time_travel(chain, start_time + 1) assert crowdsale.call().getState() == CrowdsaleState.Funding # Buy all cap wei_value = cap print(from_wei(web3.eth.getBalance(customer), "ether")) crowdsale.transact({"from": customer, "value": wei_value}).buy() assert crowdsale.call().isCrowdsaleFull() # Close the deal time_travel(chain, end_time + 1) assert crowdsale.call().getState() == CrowdsaleState.Success crowdsale.transact({"from": team_multisig}).finalize() assert crowdsale.call().getState() == CrowdsaleState.Finalized # See that we counted bonus correctly team_bonus = token.call().totalSupply() * 7 / 10 assert abs(finalizer.call().allocatedBonus() - team_bonus) < 10 # We lose some in decimal rounding # Token is transferable assert token.call().released()
def test_cannot_mint(chain: TestRPCChain, web3: Web3, ico: Contract, uncapped_token: Contract, customer: str, preico_token_price, preico_starts_at, team_multisig): """Only crowdsale contract can mint new tokens.""" time_travel(chain, preico_starts_at + 1) with pytest.raises(TransactionFailed): uncapped_token.transact({"from": customer}).mint(customer, 1000)
def test_non_fractional_price(chain, milestone_pricing, customer, end_time): """We divide price correctly for integer only amount.""" time_travel(chain, end_time - 1) assert milestone_pricing.call().calculatePrice( to_wei("0.28", "ether"), 0, 0, customer, 0, ) == 2 assert milestone_pricing.call().calculatePrice( to_wei("0.281", "ether"), 0, 0, customer, 0, ) == 2 assert milestone_pricing.call().calculatePrice( to_wei("0.4199", "ether"), 0, 0, customer, 0, ) == 2 assert milestone_pricing.call().calculatePrice( to_wei("0.42", "ether"), 0, 0, customer, 0, ) == 3
def test_buy_early(chain: TestRPCChain, ico: Contract, customer: str, preico_starts_at, uncapped_token): """Cannot buy too early.""" time_travel(chain, preico_starts_at - 1) assert ico.call().getState() == CrowdsaleState.PreFunding with pytest.raises(TransactionFailed): ico.transact({"from": customer, "value": to_wei(1, "ether")}).buy()
def test_buy_some(chain, crowdsale, token, finalizer, start_time, end_time, team_multisig, customer, minimum_funding_goal, founder_allocation): """Buy some token and finalize crowdsale.""" # Buy on first week time_travel(chain, start_time + 1) assert crowdsale.call().getState() == CrowdsaleState.Funding # Buy minimum funding goal wei_value = minimum_funding_goal crowdsale.transact({"from": customer, "value": wei_value}).buy() assert crowdsale.call().isMinimumGoalReached() # Close the deal time_travel(chain, end_time + 1) assert crowdsale.call().getState() == CrowdsaleState.Success crowdsale.transact({"from": team_multisig}).finalize() assert crowdsale.call().getState() == CrowdsaleState.Finalized customer_tokens = 7500 / 0.10 # See that we counted bonus correctly assert finalizer.call().allocatedBonus() == customer_tokens * 0.2 # See that bounty tokens do not count against tokens sold assert crowdsale.call().tokensSold() == customer_tokens assert token.call().totalSupply() == customer_tokens * (1+founder_allocation) # See that customers get their tokens assert token.call().balanceOf(customer) == crowdsale.call().tokensSold() # See that team multisig got our bonus tokens assert token.call().balanceOf(team_multisig) == crowdsale.call().tokensSold() * founder_allocation # Token is transferable assert token.call().released()
def test_early_whitelist_only_owner(chain: TestRPCChain, ico: Contract, customer: str, preico_starts_at, team_multisig, uncapped_token): """Only owner can early whitelist.""" time_travel(chain, preico_starts_at - 1) assert ico.call().getState() == CrowdsaleState.PreFunding with pytest.raises(TransactionFailed): ico.transact({"from": customer}).setEarlyParicipantWhitelist(customer, True)
def test_buy_all(chain, crowdsale, token, finalizer, start_time, end_time, team_multisig, customer, cap, founder_allocation): """Buy all tokens and finalize crowdsale.""" # Buy on first week time_travel(chain, start_time + 1) assert crowdsale.call().getState() == CrowdsaleState.Funding # Buy all cap wei_value = cap * to_wei("0.10", "ether") crowdsale.transact({"from": customer, "value": wei_value}).buy() assert crowdsale.call().isCrowdsaleFull() # Close the deal time_travel(chain, end_time + 1) assert crowdsale.call().getState() == CrowdsaleState.Success crowdsale.transact({"from": team_multisig}).finalize() assert crowdsale.call().getState() == CrowdsaleState.Finalized customer_tokens = 4000000 # See that we counted bonus correctly assert finalizer.call().allocatedBonus() == 800000 # See that bounty tokens do not count against tokens sold assert crowdsale.call().tokensSold() == customer_tokens assert token.call().totalSupply() == customer_tokens * (1 + founder_allocation) # See that customers get their tokens assert token.call().balanceOf(customer) == crowdsale.call().tokensSold() # See that team multisig got our bonus tokens assert token.call().balanceOf(team_multisig) == crowdsale.call().tokensSold() * founder_allocation # Token is transferable assert token.call().released()
def test_deposit_default_payabl(chain: TestRPCChain, web3: Web3, ico: Contract, uncapped_token: Contract, customer: str, preico_token_price, preico_starts_at, team_multisig): """Cannot just send money to the contract address and expect getting tokens..""" wei_value = to_wei(100, "ether") time_travel(chain, preico_starts_at + 1) with pytest.raises(TransactionFailed): web3.eth.sendTransaction({"from": customer, "value": wei_value, "to": ico.address})
def test_buy_late_goal_reached(chain: TestRPCChain, uncapped_flatprice_goal_reached: Contract, customer: str, preico_ends_at): """Cannot buy after closing time when the goal was not reached.""" time_travel(chain, preico_ends_at + 1) assert uncapped_flatprice_goal_reached.call().getState() == CrowdsaleState.Success with pytest.raises(TransactionFailed): uncapped_flatprice_goal_reached.transact({"from": customer, "value": to_wei(1, "ether")}).buy()
def test_close_early(chain: TestRPCChain, ico: Contract, customer: str, preico_starts_at, preico_ends_at, team_multisig): """Soft cap triggered, close crowdsale early.""" # Close earlier than anticipated new_early = preico_starts_at + 1*3600 assert new_early < preico_ends_at time_travel(chain, preico_starts_at + 1) assert ico.call().getState() == CrowdsaleState.Funding ico.transact({"from": customer, "value": to_wei(1, "ether")}).buy() ico.transact({"from": team_multisig}).setEndsAt(new_early) # Here we try to switch the strategy, and buy again, 1 wei for 1 token args = [ 1, ] tx = { "from": team_multisig, } pricing_strategy, hash = chain.provider.deploy_contract('FlatPricing', deploy_args=args, deploy_transaction=tx) ico.transact({"from": team_multisig}).setPricingStrategy(pricing_strategy.address) assert ico.call().pricingStrategy() == pricing_strategy.address ico.transact({"from": customer, "value": 1}).buy() # Finally, here we travel in time to situation after the early closing: time_travel(chain, new_early + 1) assert ico.call().getState() == CrowdsaleState.Failure with pytest.raises(TransactionFailed): ico.transact({"from": customer, "value": to_wei(1, "ether")}).buy()
def test_buy_early_whitelisted(chain: TestRPCChain, ico: Contract, customer: str, preico_starts_at, team_multisig, uncapped_token): """Whitelisted participants can buy earliy.""" time_travel(chain, preico_starts_at - 1) assert ico.call().getState() == CrowdsaleState.PreFunding ico.transact({"from": team_multisig}).setEarlyParicipantWhitelist(customer, True) ico.transact({"from": customer, "value": to_wei(1, "ether")}).buy() assert uncapped_token.call().balanceOf(customer) > 0
def test_unlock_early(chain, token: Contract, team_multisig: str, vault: Contract, unlock_time: int): """Early unlock fails.""" assert token.call().balanceOf(team_multisig) == 0 assert token.call().balanceOf(vault.address) == 1000000 time_travel(chain, unlock_time - 1) with pytest.raises(TransactionFailed): vault.transact({"from": team_multisig}).unlock()
def test_participate_missing_customer_id(chain, crowdsale, customer, customer_id, token): """Cannot bypass customer id process.""" time_travel(chain, crowdsale.call().startsAt() + 1) wei_value = to_wei(1, "ether") assert crowdsale.call().getState() == CrowdsaleState.Funding with pytest.raises(TransactionFailed): crowdsale.transact({"from": customer, "value": wei_value}).buy()
def test_buy_dust(chain: TestRPCChain, web3: Web3, ico: Contract, uncapped_token: Contract, customer: str, preico_token_price, preico_starts_at, team_multisig): """Cannot buy with too small transaction.""" wei_value = 1 time_travel(chain, preico_starts_at + 1) with pytest.raises(TransactionFailed): ico.transact({"from": customer, "value": wei_value}).buy()
def test_buy_fail_goal(chain: TestRPCChain, ico: Contract, customer: str, preico_starts_at, preico_ends_at, preico_funding_goal): """Goal is not reached if there is not enough investment.""" time_travel(chain, preico_starts_at + 1) wei_value = preico_funding_goal // 2 ico.transact({"from": customer, "value": wei_value}).buy() time_travel(chain, preico_ends_at + 1) assert ico.call().getState() == CrowdsaleState.Failure
def test_claim_early(chain, loaded_token_vault, team_multisig, token, customer, customer_2): """Tokens cannot be claimed early.""" token.transact({"from": team_multisig}).transfer(loaded_token_vault.address, 3000) loaded_token_vault.transact({"from": team_multisig}).lock() time_travel(chain, loaded_token_vault.call().freezeEndsAt() - 1) with pytest.raises(TransactionFailed): loaded_token_vault.transact({"from": customer}).claim()
def distributing_token_vault(chain, loaded_token_vault, team_multisig, token, token_vault_balances): """Token vault set to distributing state.""" token.transact({"from": team_multisig}).transfer(loaded_token_vault.address, 3000) loaded_token_vault.transact({"from": team_multisig}).lock() assert loaded_token_vault.call().getState() == TokenVaultState.Holding time_travel(chain, loaded_token_vault.call().freezeEndsAt()+1) loaded_token_vault.call().getState() == TokenVaultState.Distributing return loaded_token_vault
def test_buy_all_plus_one(chain, web3, crowdsale, token, finalizer, start_time, end_time, team_multisig, customer, cap, founder_allocation): """Buy too many tokens.""" # Buy on first week time_travel(chain, start_time + 1) assert crowdsale.call().getState() == CrowdsaleState.Funding # Buy all cap wei_value = cap + 1 with pytest.raises(TransactionFailed): crowdsale.transact({"from": customer, "value": wei_value}).buy()
def test_unlock(chain, token: Contract, team_multisig: str, vault: Contract, unlock_time: int): """Unlock tokens.""" assert token.call().balanceOf(team_multisig) == 0 assert token.call().balanceOf(vault.address) == 1000000 time_travel(chain, unlock_time + 1) vault.transact({"from": team_multisig}).unlock() assert token.call().balanceOf(team_multisig) == 1000000 assert token.call().balanceOf(vault.address) == 0
def test_buy_one_investor(chain: TestRPCChain, web3: Web3, ico: Contract, uncapped_token: Contract, customer: str, preico_token_price, preico_starts_at, team_multisig): """Can buy when crowdsale is running.""" original_balance = web3.eth.getBalance(team_multisig) wei_value = to_wei(1, "ether") buys_tokens = wei_value // preico_token_price assert buys_tokens > 0 time_travel(chain, preico_starts_at + 1) assert ico.call().getState() == CrowdsaleState.Funding assert ico.call().investorCount() == 0 assert ico.call().investedAmountOf(customer) == 0 ico.transact({"from": customer, "value": wei_value}).buy() # # See everything was correctly credited # # Tokens on every account assert uncapped_token.call().balanceOf(customer) == buys_tokens assert uncapped_token.call().totalSupply() == buys_tokens assert ico.call().tokensSold() == buys_tokens assert ico.call().investorCount() == 1 # Ether on every account assert ico.call().weiRaised() == wei_value assert ico.call().investedAmountOf(customer) == wei_value balance_diff = web3.eth.getBalance(team_multisig) - original_balance assert balance_diff == wei_value # Investors assert ico.call().investorCount() == 1 # # Events # # Crowdsale events = ico.pastEvents("Invested").get() assert len(events) == 1 e = events[0] assert e["args"]["investor"] == customer assert e["args"]["weiAmount"] == wei_value assert e["args"]["tokenAmount"] == buys_tokens # ERC-20 events = uncapped_token.pastEvents("Transfer").get() assert len(events) == 1 e = events[0] assert e["args"]["from"] == "0x0000000000000000000000000000000000000000" assert e["args"]["to"] == customer assert e["args"]["value"] == buys_tokens
def test_finalize_fail_goal(chain: TestRPCChain, uncapped_flatprice_final: Contract, customer: str, preico_starts_at, preico_ends_at, preico_funding_goal): """Finalize can be done only for successful crowdsales.""" time_travel(chain, preico_starts_at + 1) wei_value = preico_funding_goal // 2 uncapped_flatprice_final.transact({"from": customer, "value": wei_value}).buy() time_travel(chain, preico_ends_at + 1) assert uncapped_flatprice_final.call().getState() == CrowdsaleState.Failure with pytest.raises(TransactionFailed): uncapped_flatprice_final.transact().finalize()
def test_finalize_fail_again(chain: TestRPCChain, uncapped_flatprice_final: Contract, team_multisig: str, customer: str, preico_starts_at, preico_ends_at, preico_funding_goal): """Finalize cannot be done again.""" time_travel(chain, preico_starts_at + 1) wei_value = preico_funding_goal uncapped_flatprice_final.transact({"from": customer, "value": wei_value}).buy() time_travel(chain, preico_ends_at + 1) assert uncapped_flatprice_final.call().getState() == CrowdsaleState.Success uncapped_flatprice_final.transact({"from": team_multisig}).finalize() with pytest.raises(TransactionFailed): uncapped_flatprice_final.transact({"from": team_multisig}).finalize()
def test_milestone_calculate_preico_price(chain, milestone_pricing, start_time, presale_fund_collector): """Preico contributors get their special price.""" # 1 week forward time_travel(chain, int((datetime.datetime(2017, 4, 22, 16, 0) - datetime.datetime(1970, 1, 1)).total_seconds())) # Pre-ico address always buys at the fixed price assert milestone_pricing.call().calculatePrice( to_wei("0.05", "ether"), 0, 0, presale_fund_collector.address, 0 ) == 1
def test_finalize_only_by_crowdsale(chain: TestRPCChain, uncapped_flatprice_final: Contract, team_multisig: str, customer: str, preico_starts_at, preico_ends_at, preico_funding_goal, default_finalize_agent): """Finalizer can be only triggered by crowdsale.""" time_travel(chain, preico_starts_at + 1) wei_value = preico_funding_goal uncapped_flatprice_final.transact({"from": customer, "value": wei_value}).buy() time_travel(chain, preico_ends_at + 1) assert uncapped_flatprice_final.call().getState() == CrowdsaleState.Success # Checks for the owner with pytest.raises(TransactionFailed): default_finalize_agent.transact({"from": team_multisig}).finalizeCrowdsale()
def test_halt(chain: TestRPCChain, web3: Web3, ico: Contract, uncapped_token: Contract, customer: str, preico_token_price, preico_starts_at, team_multisig): """Cannot buy tokens during the emergency pause mode.""" time_travel(chain, preico_starts_at + 1) wei_value = to_wei(1, "ether") ico.transact({"from": team_multisig}).halt() assert ico.call().halted() with pytest.raises(TransactionFailed): ico.transact({"from": customer, "value": wei_value}).buy() ico.transact({"from": team_multisig}).unhalt() assert not ico.call().halted() ico.transact({"from": customer, "value": wei_value}).buy()
def test_close_late(chain: TestRPCChain, ico: Contract, customer: str, preico_starts_at, preico_ends_at, team_multisig): """Extend crowdsale.""" new_end = preico_ends_at + 1*3600 assert new_end > preico_ends_at time_travel(chain, preico_starts_at + 1) assert ico.call().getState() == CrowdsaleState.Funding ico.transact({"from": customer, "value": to_wei(1, "ether")}).buy() ico.transact({"from": team_multisig}).setEndsAt(new_end) time_travel(chain, preico_ends_at + 1) assert ico.call().getState() == CrowdsaleState.Funding ico.transact({"from": customer, "value": to_wei(1, "ether")}).buy()
def test_rebuild_failed_crowdsale(chain, original_crowdsale, token, relaunched_crowdsale, sample_data, team_multisig, customer, customer_2): """Rebuild a crowdsale that is not going to reach its minimum goal.""" time_travel(chain, original_crowdsale.call().startsAt() + 1) assert original_crowdsale.call().getState() == CrowdsaleState.Funding assert relaunched_crowdsale.call().getState() == CrowdsaleState.Funding for data in sample_data: addr = data["Address"] wei = to_wei(data["Invested ETH"], "ether") original_crowdsale.transact({"from": addr, "value": wei}).buy() # We have a confirmation hash events = original_crowdsale.pastEvents("Invested").get() assert len(events) == 2 e = events[-1] for data in sample_data: addr = data["Address"] wei = to_wei(data["Invested ETH"], "ether") tokens = int(data["Received tokens"]) txid = int(data["Txid"], 16) relaunched_crowdsale.transact({"from": team_multisig}).setInvestorData(addr, wei, tokens, txid) assert original_crowdsale.call().tokensSold() == relaunched_crowdsale.call().tokensSold() assert original_crowdsale.call().investedAmountOf(customer) == relaunched_crowdsale.call().investedAmountOf(customer) assert original_crowdsale.call().investedAmountOf(customer_2) == relaunched_crowdsale.call().investedAmountOf(customer_2) assert token.call().balanceOf(customer) == relaunched_crowdsale.call().tokenAmountOf(customer) assert token.call().balanceOf(customer_2) == relaunched_crowdsale.call().tokenAmountOf(customer_2) time_travel(chain, original_crowdsale.call().endsAt() + 1) assert original_crowdsale.call().getState() == CrowdsaleState.Failure assert relaunched_crowdsale.call().getState() == CrowdsaleState.Failure relaunched_crowdsale.transact({"from": team_multisig, "value": to_wei(30, "ether")}).loadRefund() assert relaunched_crowdsale.call().getState() == CrowdsaleState.Refunding relaunched_crowdsale.transact({"from": customer}).refund() relaunched_crowdsale.transact({"from": customer_2}).refund() # No double refund with pytest.raises(TransactionFailed): relaunched_crowdsale.transact({"from": customer}).refund() with pytest.raises(TransactionFailed): original_crowdsale.transact({"from": customer}).refund()
def test_presale_move_to_tranche_based_crowdsale(chain, presale_fund_collector, tranche_ico, finalizer, token, start_time, team_multisig, customer, customer_2): """When pre-ico contract funds are moved to the crowdsale, the pre-sale investors gets tokens with a preferred price and not the current tranche price.""" value = to_wei(50, "ether") presale_fund_collector.transact({"from": customer, "value": value}).invest() # ICO begins, Link presale to an actual ICO presale_fund_collector.transact({"from": team_multisig}).setCrowdsale(tranche_ico.address) time_travel(chain, start_time) assert tranche_ico.call().getState() == CrowdsaleState.Funding # Load funds to ICO presale_fund_collector.transact().participateCrowdsaleAll() # Tokens received, paid by preico price tranche_ico.call().investedAmountOf(customer) == to_wei(50, "ether") token.call().balanceOf(customer) == 50 / 0.050
def test_participate_with_customer_id(chain, crowdsale, customer, customer_id, token): """Buy tokens with a proper customer id.""" time_travel(chain, crowdsale.call().startsAt() + 1) wei_value = to_wei(1, "ether") assert crowdsale.call().getState() == CrowdsaleState.Funding crowdsale.transact({"from": customer, "value": wei_value}).buyWithCustomerId(customer_id) # We got credited assert token.call().balanceOf(customer) > 0 # We have tracked the investor id events = crowdsale.pastEvents("Invested").get() assert len(events) == 1 e = events[0] assert e["args"]["investor"] == customer assert e["args"]["weiAmount"] == wei_value assert e["args"]["customerId"] == customer_id
def test_finalize_success(chain: TestRPCChain, uncapped_flatprice_final: Contract, uncapped_token: Contract, team_multisig: str, customer: str, preico_starts_at, preico_ends_at, preico_funding_goal, default_finalize_agent): """Finalize releases the token.""" time_travel(chain, preico_starts_at + 1) wei_value = preico_funding_goal uncapped_flatprice_final.transact({"from": customer, "value": wei_value}).buy() time_travel(chain, preico_ends_at + 1) assert uncapped_flatprice_final.call().getState() == CrowdsaleState.Success assert uncapped_flatprice_final.call().finalizeAgent() == default_finalize_agent.address # Release the tokens uncapped_flatprice_final.transact({"from": team_multisig}).finalize() assert uncapped_flatprice_final.call().getState() == CrowdsaleState.Finalized # Here we go assert uncapped_token.call().released() assert uncapped_token.call().mintingFinished()
def test_invest_presale_invest_too_late(chain, presale_fund_collector, presale_crowdsale, customer, customer_2, preico_starts_at, finalizer): """Cannot participate to presale after we have started to move funds to the actual crowdsale.""" value = to_wei(1, "ether") presale_fund_collector.transact({ "from": customer, "value": value }).invest() time_travel(chain, preico_starts_at + 1) presale_fund_collector.transact().participateCrowdsaleAll() # No more presales with pytest.raises(TransactionFailed): presale_fund_collector.transact({ "from": customer, "value": value }).invest()
def test_buy_all(chain, crowdsale, token, finalizer, start_time, end_time, team_multisig, customer, cap, founder_allocation): """Buy all tokens and finalize crowdsale.""" # Buy on first week time_travel(chain, start_time + 1) assert crowdsale.call().getState() == CrowdsaleState.Funding # Buy all cap wei_value = cap * to_wei("0.10", "ether") crowdsale.transact({"from": customer, "value": wei_value}).buy() assert crowdsale.call().isCrowdsaleFull() # Close the deal time_travel(chain, end_time + 1) assert crowdsale.call().getState() == CrowdsaleState.Success crowdsale.transact({"from": team_multisig}).finalize() assert crowdsale.call().getState() == CrowdsaleState.Finalized customer_tokens = 4000000 # See that we counted bonus correctly assert finalizer.call().allocatedBonus() == 800000 # See that bounty tokens do not count against tokens sold assert crowdsale.call().tokensSold() == customer_tokens assert token.call().totalSupply() == customer_tokens * (1 + founder_allocation) # See that customers get their tokens assert token.call().balanceOf(customer) == crowdsale.call().tokensSold() # See that team multisig got our bonus tokens assert token.call().balanceOf( team_multisig) == crowdsale.call().tokensSold() * founder_allocation # Token is transferable assert token.call().released()
def test_proxy_buy_claim_too_much(chain, web3, customer, customer_2, team_multisig, proxy_buyer, crowdsale, token): """You cannot claim more you got in the fair sahre""" assert proxy_buyer.call().getState() == 1 proxy_buyer.transact({ "value": to_wei(10000, "ether"), "from": customer }).invest() proxy_buyer.transact({ "value": to_wei(20000, "ether"), "from": customer_2 }).invest() # Move over assert crowdsale.call().getState() == CrowdsaleState.Funding proxy_buyer.transact({ "from": team_multisig }).setCrowdsale(crowdsale.address) assert proxy_buyer.call().crowdsale() == crowdsale.address proxy_buyer.transact({"from": customer}).buyForEverybody() # We got our tokens assert proxy_buyer.call().getState() == 2 assert proxy_buyer.call().getClaimAmount(customer) == 12000000 assert proxy_buyer.call().getClaimLeft(customer) == 12000000 assert proxy_buyer.call().tokensBought() == 36000000 # Tokens cannot be claimed before they are released time_travel(chain, crowdsale.call().endsAt() + 1) crowdsale.transact({"from": team_multisig}).finalize() assert token.call().released() # Claim too many tokens with pytest.raises(TransactionFailed): proxy_buyer.transact({"from": customer}).claim(12000000 + 1)
def test_buy_all(chain, crowdsale, token, finalizer, start_time, end_time, team_multisig, customer, early_investor_pool): """Buy all tokens and finalize crowdsale.""" multiplier = 10**8 assert crowdsale.call().getTokensLeft() == 100000 * multiplier assert token.call().balanceOf(early_investor_pool) == (33588888 - 100000) * multiplier assert crowdsale.call().weiRaised() == 8860000000000000 assert crowdsale.call().tokensSold() == (33588888 - 100000) * multiplier # Buy on first week time_travel(chain, start_time + 1) assert crowdsale.call().getState() == CrowdsaleState.Funding # Buy all cap wei_value = int(crowdsale.call().getTokensLeft() / 10**8) crowdsale.transact({"from": customer, "value": wei_value}).buy() assert crowdsale.call().isCrowdsaleFull() # Close the deal time_travel(chain, end_time + 1) assert crowdsale.call().getState() == CrowdsaleState.Success crowdsale.transact({"from": team_multisig}).finalize() assert crowdsale.call().getState() == CrowdsaleState.Finalized
def test_two_deposts(chain, web3, vault, depositor, vault_opens_at, team_multisig): """Vault accepts several deposits.""" # Money goes in test_value = to_wei(1000, "ether") test_value_2 = to_wei(3333, "ether") vault_balance = web3.eth.getBalance(vault.address) team_multisig_balance = web3.eth.getBalance(team_multisig) web3.eth.sendTransaction({"from": depositor, "value": test_value, "to": vault.address}) web3.eth.sendTransaction({"from": depositor, "value": test_value_2, "to": vault.address}) # Vault received ETH assert web3.eth.getBalance(vault.address) > vault_balance # Go to unlock date time_travel(chain, vault_opens_at+1) vault.transact({"from": depositor}).unlock() # Money was transferred to team multisig assert web3.eth.getBalance(team_multisig) - team_multisig_balance > (test_value + test_value_2) - 100000 # Vault is empty now assert web3.eth.getBalance(vault.address) == 0
def test_invest_presale_move_to_crowdsale(chain, presale_fund_collector, presale_crowdsale, preico_starts_at, customer, customer_2, finalizer): """Move loaded funds to crowdsale.""" value = to_wei(1, "ether") presale_fund_collector.functions.invest().transact({"from": customer, "value": value}) value = to_wei(1.5, "ether") presale_fund_collector.functions.invest().transact({"from": customer_2, "value": value}) # Crowdsale starts time_travel(chain, preico_starts_at) assert presale_crowdsale.functions.finalizeAgent().call() assert presale_crowdsale.functions.getState().call() == CrowdsaleState.Funding presale_fund_collector.functions.participateCrowdsaleAll().transact() # Presale balances zerod assert presale_fund_collector.functions.balances(customer).call() == 0 assert presale_fund_collector.functions.balances(customer_2).call() == 0 # Tokens received assert presale_crowdsale.functions.investedAmountOf(customer).call() == to_wei(1, "ether") assert presale_crowdsale.functions.investedAmountOf(customer_2).call() == to_wei(1.5, "ether")
def test_kyc_participate_bad_signature(chain, kyc_crowdsale, customer, customer_id, kyc_token, private_key, preico_starts_at, pricing, team_multisig): """Investment does not happen with a bad signature..""" # Check KYC crowdsale is good to go time_travel(chain, kyc_crowdsale.call().startsAt() + 1) # Do a test buy for 1 ETH and check it is good token wise wei_value = to_wei(1, "ether") # KYC limits for this participant: 0...1 ETH kyc_payload = pack_kyc_dataframe(customer, customer_id, 0, 1 * 10000) signed_data = sign(kyc_payload, private_key + "x") # Use bad private key with pytest.raises(TransactionFailed): kyc_crowdsale.transact({ "from": customer, "value": wei_value, "gas": 2222333 }).buyWithKYCData(kyc_payload, signed_data["v"], signed_data["r_bytes"], signed_data["s_bytes"])
def test_kyc_participate_whitelist(chain, kyc_presale, customer, customer_id, private_key, preico_starts_at, team_multisig, pricing_info): """Early whitelist buyer gets through despite time checks.""" # Check KYC crowdsale is closed, too early time_travel(chain, kyc_presale.call().startsAt() - 1) assert kyc_presale.call().getState() == CrowdsaleState.PreFunding # Do a test buy for 1 ETH and check it is good token wise wei_value = to_wei(1, "ether") # KYC limits for this participant: 0...1 ETH kyc_payload = pack_kyc_pricing_dataframe(customer, customer_id, 0, 1 * 10000, pricing_info) signed_data = sign(kyc_payload, private_key) with pytest.raises(TransactionFailed): kyc_presale.transact({ "from": customer, "value": wei_value, "gas": 2222333 }).buyWithKYCData(kyc_payload, signed_data["v"], signed_data["r_bytes"], signed_data["s_bytes"]) # Whitelist this participant kyc_presale.transact({ "from": team_multisig }).setEarlyParicipantWhitelist(customer, True) # Now we can buy despite the time limti kyc_presale.transact({ "from": customer, "value": wei_value, "gas": 2222333 }).buyWithKYCData(kyc_payload, signed_data["v"], signed_data["r_bytes"], signed_data["s_bytes"])
def test_non_fractional_price(chain, milestone_pricing, customer, end_time): """We divide price correctly for integer only amount.""" # FIXME: figure out a better way to time_travel # such that the time lies in the expected milestone range time_travel(chain, end_time - 5) assert milestone_pricing.functions.calculatePrice( to_wei("0.28", "ether"), 0, 0, customer, 0, ).call() == 2 assert milestone_pricing.functions.calculatePrice( to_wei("0.281", "ether"), 0, 0, customer, 0, ).call() == 2 assert milestone_pricing.functions.calculatePrice( to_wei("0.4199", "ether"), 0, 0, customer, 0, ).call() == 2 assert milestone_pricing.functions.calculatePrice( to_wei("0.42", "ether"), 0, 0, customer, 0, ).call() == 3
def test_kyc_participate_under_payment(chain, kyc_crowdsale, customer, customer_id, kyc_token, private_key, preico_starts_at, pricing, team_multisig): """KYC'ed participant does not fulfill his minimum limit.""" # Check KYC crowdsale is good to go time_travel(chain, kyc_crowdsale.call().startsAt() + 1) # Do a test buy for 1 ETH and check it is good token wise wei_value = to_wei(0.1, "ether") # KYC limits for this participant: 0...1 ETH kyc_payload = pack_kyc_pricing_dataframe(customer, customer_id, int(0.5 * 10000), 1 * 10000, 1) signed_data = sign(kyc_payload, private_key) # Use bad private key with pytest.raises(TransactionFailed): kyc_crowdsale.functions.buyWithKYCData( kyc_payload, signed_data["v"], signed_data["r_bytes"], signed_data["s_bytes"]).transact({ "from": customer, "value": wei_value })
def test_close_early(chain: TestRPCChain, ico: Contract, customer: str, preico_starts_at, preico_ends_at, team_multisig): """Soft cap triggered, close crowdsale early.""" # Close earlier than anticipated new_early = preico_starts_at + 1 * 3600 assert new_early < preico_ends_at time_travel(chain, preico_starts_at + 1) assert ico.call().getState() == CrowdsaleState.Funding ico.transact({"from": customer, "value": to_wei(1, "ether")}).buy() ico.transact({"from": team_multisig}).setEndsAt(new_early) # Here we try to switch the strategy, and buy again, 1 wei for 1 token args = [ 1, ] tx = { "from": team_multisig, } pricing_strategy, hash = chain.provider.deploy_contract( 'FlatPricing', deploy_args=args, deploy_transaction=tx) ico.transact({ "from": team_multisig }).setPricingStrategy(pricing_strategy.address) assert ico.call().pricingStrategy() == pricing_strategy.address ico.transact({"from": customer, "value": 1}).buy() # Finally, here we travel in time to situation after the early closing: time_travel(chain, new_early + 1) assert ico.call().getState() == CrowdsaleState.Failure with pytest.raises(TransactionFailed): ico.transact({"from": customer, "value": to_wei(1, "ether")}).buy()
def test_proxy_buy_refund(chain, web3, proxy_buyer, crowdsale, customer, customer_2): """We can refund""" value = to_wei(1, "ether") proxy_buyer.transact({ "value": to_wei(10000, "ether"), "from": customer }).invest() proxy_buyer.transact({ "value": to_wei(20000, "ether"), "from": customer_2 }).invest() time_travel(chain, proxy_buyer.call().freezeEndsAt() + 1) assert proxy_buyer.call().getState() == 3 # Refunding before_refund = web3.eth.getBalance(customer) proxy_buyer.transact({"from": customer}).refund() after_refund = web3.eth.getBalance(customer) assert from_wei(after_refund - before_refund, "ether") > 0.99 # gas cost epsilon assert proxy_buyer.call().balances(customer) == 0
def test_multi_vault_claim_early(chain, mysterium_multivault, preico_starts_at, mysterium_mv_token, team_multisig, customer, customer_2, mysterium_release_agent): """Somebody tries to claim his tokens early.""" assert mysterium_mv_token.call().released() assert mysterium_mv_token.call().balanceOf(customer) == 0 assert mysterium_mv_token.call().totalSupply() == 200 # Load all 100% tokens to the vault for the test mysterium_mv_token.transact({"from": team_multisig}).transfer(mysterium_multivault.address, mysterium_mv_token.call().totalSupply()) assert mysterium_mv_token.call().balanceOf(mysterium_multivault.address) == mysterium_mv_token.call().totalSupply() # Set the distribution balance mysterium_multivault.transact({"from": team_multisig}).fetchTokenBalance() # We do not pass the vault expiration date time_travel(chain, mysterium_multivault.call().freezeEndsAt() - 1) assert mysterium_multivault.call().getState() == MultiVaultState.Holding # We can see the balance even before the transfer kicks in assert mysterium_multivault.call().getClaimAmount(customer) == 60 # Early claim request fails with pytest.raises(TransactionFailed): mysterium_multivault.transact({"from": customer}).claim(1)
def test_buy_reach_goal(chain: TestRPCChain, flat_pricing, ico: Contract, customer: str, preico_starts_at, preico_ends_at, preico_funding_goal): """Goal can be reached with a sufficient investment.""" time_travel(chain, preico_starts_at + 1) wei_value = preico_funding_goal # Check that we don't have issues with our pricing assert flat_pricing.call().calculatePrice(wei_value, 0, 0, customer, 0) > 0 ico.transact({"from": customer, "value": wei_value}).buy() # We got investment event events = ico.pastEvents("Invested").get() assert len(events) == 1 e = events[0] assert e["args"]["investor"] == customer assert e["args"]["weiAmount"] == wei_value assert ico.call().weiRaised() == wei_value assert ico.call().weiRaised() == ico.call().minimumFundingGoal() assert ico.call().isMinimumGoalReached() time_travel(chain, preico_ends_at + 1) assert ico.call().getState() == CrowdsaleState.Success
def test_multi_vault_distribute(chain, mysterium_multivault, preico_starts_at, mysterium_mv_token, team_multisig, customer, customer_2, mysterium_release_agent): """Check that multivaut acts correctly.""" assert mysterium_mv_token.call().released() assert mysterium_mv_token.call().balanceOf(customer) == 0 assert mysterium_mv_token.call().totalSupply() == 200 # Load all 100% tokens to the vault for the test mysterium_mv_token.transact({"from": team_multisig}).transfer(mysterium_multivault.address, mysterium_mv_token.call().totalSupply()) assert mysterium_mv_token.call().balanceOf(mysterium_multivault.address) == mysterium_mv_token.call().totalSupply() # Set the distribution balance mysterium_multivault.transact({"from": team_multisig}).fetchTokenBalance() # We pass the vault expiration date time_travel(chain, mysterium_multivault.call().freezeEndsAt() + 1) assert mysterium_multivault.call().getState() == MultiVaultState.Distributing # Check we calculate claims correctly assert mysterium_multivault.call().getClaimAmount(customer) + mysterium_multivault.call().getClaimAmount(customer_2) == 200 assert mysterium_multivault.call().getClaimLeft(customer) + mysterium_multivault.call().getClaimLeft(customer_2) == 200 # First customer gets his tokens assert mysterium_multivault.call().getClaimAmount(customer) == 60 mysterium_multivault.transact({"from": customer}).claimAll() assert mysterium_mv_token.call().balanceOf(customer) == 60 # 200*3/10 assert mysterium_multivault.call().getClaimLeft(customer) == 0 # Then customer 2 claims his tokens in two batches mysterium_multivault.transact({"from": customer_2}).claim(20) assert mysterium_mv_token.call().balanceOf(customer_2) == 20 assert mysterium_multivault.call().getClaimLeft(customer_2) == 120 mysterium_multivault.transact({"from": customer_2}).claim(120) assert mysterium_mv_token.call().balanceOf(customer_2) == 140 assert mysterium_multivault.call().getClaimLeft(customer_2) == 0
def test_finalize_only_by_crowdsale(chain: TesterChain, uncapped_flatprice_final: Contract, team_multisig: str, customer: str, preico_starts_at, preico_ends_at, preico_funding_goal, default_finalize_agent): """Finalizer can be only triggered by crowdsale.""" time_travel(chain, preico_starts_at + 1) wei_value = preico_funding_goal uncapped_flatprice_final.transact({ "from": customer, "value": wei_value }).buy() time_travel(chain, preico_ends_at + 1) assert uncapped_flatprice_final.call().getState() == CrowdsaleState.Success # Checks for the owner with pytest.raises(TransactionFailed): default_finalize_agent.transact({ "from": team_multisig }).finalizeCrowdsale()
def test_tapped_claim(chain, token_vault_tapped, team_multisig, token, customer, customer_2, token_vault_balances): """Tokens can be claimed after freeze time is over.""" for address, balance in token_vault_balances: token_vault_tapped.functions.setInvestor(address, balance, 1).transact( {"from": team_multisig}) token.functions.transfer(token_vault_tapped.address, 3000).transact({"from": team_multisig}) token_vault_tapped.functions.lock().transact({"from": team_multisig}) assert token_vault_tapped.functions.getState().call( ) == TokenVaultState.Holding time_travel(chain, token_vault_tapped.functions.freezeEndsAt().call() + 2 - 1) assert token_vault_tapped.functions.getState().call( ) == TokenVaultState.Distributing assert token.functions.balanceOf(customer).call() == 0 token_vault_tapped.functions.claim().transact({"from": customer}) assert token.functions.balanceOf(customer).call() == 2 assert token_vault_tapped.functions.balances(customer).call() == 1000 time_travel(chain, token_vault_tapped.call().freezeEndsAt() + 400 - 1) token_vault_tapped.functions.claim().transact({"from": customer}) assert token_vault_tapped.functions.claimed(customer).call() == 400 time_travel(chain, token_vault_tapped.functions.freezeEndsAt().call() + 2000 - 1) assert token.functions.balanceOf(customer_2).call() == 0 token_vault_tapped.functions.claim().transact({"from": customer_2}) assert token.functions.balanceOf(customer_2).call() == 2000 assert token_vault_tapped.functions.totalClaimed().call() == 2400
def test_milestone_prices(chain, milestone_pricing, start_time, end_time, customer): """We get correct milestone prices for different dates.""" time_travel(chain, start_time - 1) with pytest.raises(TransactionFailed): # Div by zero, crowdsale has not begin yet assert milestone_pricing.call().getCurrentPrice() time_travel(chain, start_time) assert milestone_pricing.call().getCurrentPrice() == to_wei( "0.10", "ether") time_travel(chain, start_time + 1) assert milestone_pricing.call().getCurrentPrice() == to_wei( "0.10", "ether") # 1 week forward time_travel( chain, int((datetime.datetime(2017, 4, 22, 16, 0) - datetime.datetime(1970, 1, 1)).total_seconds())) assert milestone_pricing.call().getCurrentPrice() == to_wei( "0.12", "ether") # 2 week forward time_travel( chain, int((datetime.datetime(2017, 4, 29, 16, 0) - datetime.datetime(1970, 1, 1)).total_seconds())) assert milestone_pricing.call().getCurrentPrice() == to_wei( "0.13", "ether") # 3 week forward + last second time_travel(chain, end_time - 1) assert milestone_pricing.call().getCurrentPrice() == to_wei( "0.14", "ether")
def test_rebuild_failed_crowdsale(chain, original_crowdsale, token, relaunched_crowdsale, sample_data, team_multisig, customer, customer_2): """Rebuild a crowdsale that is not going to reach its minimum goal.""" time_travel(chain, original_crowdsale.functions.startsAt().call() + 1) assert original_crowdsale.functions.getState().call( ) == CrowdsaleState.Funding assert relaunched_crowdsale.functions.getState().call( ) == CrowdsaleState.Funding for data in sample_data: addr = data["Address"] wei = to_wei(data["Invested ETH"], "ether") original_crowdsale.functions.buy().transact({ "from": addr, "value": wei }) # We have a confirmation hash events = original_crowdsale.events.Invested().createFilter( fromBlock=0).get_all_entries() assert len(events) == 2 e = events[-1] for data in sample_data: addr = data["Address"] wei = to_wei(data["Invested ETH"], "ether") tokens = int(data["Received tokens"]) txid = int(data["Txid"], 16) relaunched_crowdsale.functions.setInvestorData( addr, wei, tokens, txid).transact({"from": team_multisig}) assert original_crowdsale.functions.tokensSold().call( ) == relaunched_crowdsale.functions.tokensSold().call() assert original_crowdsale.functions.investedAmountOf(customer).call( ) == relaunched_crowdsale.functions.investedAmountOf(customer).call() assert original_crowdsale.functions.investedAmountOf(customer_2).call( ) == relaunched_crowdsale.functions.investedAmountOf(customer_2).call() assert token.functions.balanceOf(customer).call( ) == relaunched_crowdsale.functions.tokenAmountOf(customer).call() assert token.functions.balanceOf(customer_2).call( ) == relaunched_crowdsale.functions.tokenAmountOf(customer_2).call() time_travel(chain, original_crowdsale.functions.endsAt().call() + 1) assert original_crowdsale.functions.getState().call( ) == CrowdsaleState.Failure assert relaunched_crowdsale.functions.getState().call( ) == CrowdsaleState.Failure relaunched_crowdsale.functions.loadRefund().transact({ "from": team_multisig, "value": to_wei(30, "ether") }) assert relaunched_crowdsale.functions.getState().call( ) == CrowdsaleState.Refunding relaunched_crowdsale.functions.refund().transact({"from": customer}) relaunched_crowdsale.functions.refund().transact({"from": customer_2}) # No double refund with pytest.raises(TransactionFailed): relaunched_crowdsale.functions.refund().transact({"from": customer}) with pytest.raises(TransactionFailed): original_crowdsale.functions.refund().transact({"from": customer})
def test_rebuild_failed_crowdsale_with_new_token(chain, original_crowdsale, token, new_token, relaunched_crowdsale, sample_data, team_multisig, customer, customer_2): """Rebuild a crowdsale that is not going to reach its minimum goal.""" time_travel(chain, original_crowdsale.call().startsAt() + 1) assert original_crowdsale.call().getState() == CrowdsaleState.Funding assert relaunched_crowdsale.call().getState() == CrowdsaleState.Funding for data in sample_data: addr = data["Address"] wei = to_wei(data["Invested ETH"], "ether") original_crowdsale.transact({"from": addr, "value": wei}).buy() # We have a confirmation hash events = original_crowdsale.pastEvents("Invested").get() assert len(events) == 2 e = events[-1] # Import old transactions from the multisig contract for data in sample_data: addr = data["Address"] wei = to_wei(data["Invested ETH"], "ether") tokens = int(data["Received tokens"]) orig_txid = int(data["Tx hash"], 16) orig_tx_index = int(data["Tx index"]) relaunched_crowdsale.transact({ "from": team_multisig }).setInvestorDataAndIssueNewToken(addr, wei, tokens, orig_txid) # No double issuance for the same tx data = sample_data[0] addr = data["Address"] wei = to_wei(data["Invested ETH"], "ether") tokens = int(data["Received tokens"]) orig_txid = int(data["Tx hash"], 16) orig_tx_index = int(data["Tx index"]) with pytest.raises(TransactionFailed): relaunched_crowdsale.transact({ "from": team_multisig }).setInvestorDataAndIssueNewToken(addr, wei, tokens, orig_txid) # Compare that both crowdsales and tokens look the same assert original_crowdsale.call().tokensSold() == relaunched_crowdsale.call( ).tokensSold() assert original_crowdsale.call().investedAmountOf( customer) == relaunched_crowdsale.call().investedAmountOf(customer) assert original_crowdsale.call().investedAmountOf( customer_2) == relaunched_crowdsale.call().investedAmountOf(customer_2) assert token.call().balanceOf( customer) == relaunched_crowdsale.call().tokenAmountOf(customer) assert token.call().balanceOf( customer_2) == relaunched_crowdsale.call().tokenAmountOf(customer_2) assert token.call().balanceOf(customer) == new_token.call().balanceOf( customer) assert token.call().balanceOf(customer_2) == new_token.call().balanceOf( customer_2) assert token.call().totalSupply() == new_token.call().totalSupply() time_travel(chain, original_crowdsale.call().endsAt() + 1) assert original_crowdsale.call().getState() == CrowdsaleState.Failure assert relaunched_crowdsale.call().getState() == CrowdsaleState.Failure relaunched_crowdsale.transact({ "from": team_multisig, "value": to_wei(30, "ether") }).loadRefund() assert relaunched_crowdsale.call().getState() == CrowdsaleState.Refunding relaunched_crowdsale.transact({"from": customer}).refund() relaunched_crowdsale.transact({"from": customer_2}).refund() # No double refund with pytest.raises(TransactionFailed): relaunched_crowdsale.transact({"from": customer}).refund() with pytest.raises(TransactionFailed): original_crowdsale.transact({"from": customer}).refund()
def test_deploy_all(chain, web3, everything_deployed, proxy_buyers, presale_investor_1, presale_investor_2, presale_investor_3, presale_investor_4, customer, customer_2, deploy_address): """Acceptance test to verify that token sale YAML example functions properly.""" crowdsale = everything_deployed["crowdsale"] pricing_strategy = everything_deployed["pricing_strategy"] token = everything_deployed["token"] team_multisig = everything_deployed["team_multisig"] decimals = 18 # Load in proxy buery money before ICO starts assert crowdsale.call().getState() == CrowdsaleState.PreFunding # See we have full stock to sell minus the test buy done in the script test_buy = 0.01 * 400 tokens_left = crowdsale.call().getTokensLeft() / (10**decimals) assert tokens_left == 70000000 - test_buy # Load proxy buyer money presale_total = 0 for proxy_buyer in proxy_buyers: assert proxy_buyer.call().getState() == 1 assert proxy_buyer.call().weiRaised() > 0 # Calculate how much all presales raise total wei = proxy_buyer.call().weiRaised() amount = pricing_strategy.call().calculatePrice( wei, 0, 0, proxy_buyer.address, decimals) / 10**decimals presale_total += amount proxy_buyer.transact({ "from": deploy_address }).setCrowdsale(crowdsale.address) assert pricing_strategy.call().isPresalePurchase(proxy_buyer.address) # Check that the proxy buyer contract receives tokens immediately balance_before = web3.eth.getBalance(team_multisig.address) proxy_buyer.transact({"from": deploy_address}).buyForEverybody() balance_after = web3.eth.getBalance(team_multisig.address) assert balance_after > balance_before, "{} {}".format( balance_before, balance_after) # Presale, token amount is from the spreadsheet assert math.isclose(presale_total, 7971776, rel_tol=0.01) # From spreadsheet, presale tokens # Both presale contracts moved in assert crowdsale.call().presaleWeiRaised() > to_wei(9000 * 2, "ether") # Now start the ICO time_travel(chain, crowdsale.call().startsAt()) assert crowdsale.call().getState() == CrowdsaleState.Funding # We should start with 400 tokens/ETH amount = pricing_strategy.call().calculatePrice(to_wei("1", "ether"), 0, 0, customer, decimals) amount_should_be = 400 # tokens / 1 eth assert math.isclose(amount / (10**decimals), round(amount_should_be, decimals)) == True # Fill to tier 2 with tier 1 cap - presale amount # arguments are from the spreadsheet tier_1_token_amount_in_eth = int(7500000 * 0.0025) crowdsale.transact({ "from": customer_2, "value": tier_1_token_amount_in_eth }).buy() # We should be tier 2 now assert crowdsale.call().weiRaised() > to_wei(18750, "ether") # Check tier 2 price amount = pricing_strategy.call().calculatePrice( to_wei("1", "ether"), crowdsale.call().weiRaised(), 0, customer, decimals) / 10**decimals amount_should_be = 366.666666 # tokens / 1 eth assert math.isclose(amount, amount_should_be, rel_tol=0.01) == True, "Got {} should {}".format( amount, amount_should_be) # Let's close it by reaching end of time time_travel(chain, crowdsale.call().endsAt() + 1) # Finalize the sale assert crowdsale.call().getState() == CrowdsaleState.Success assert token.call().balanceOf( team_multisig.address) == 0 # Company has no tokens yet crowdsale.transact({"from": deploy_address}).finalize() # Release the token token.transact({"from": deploy_address}).releaseTokenTransfer() assert token.call().released() # Presale investors can claim their tokens total_claimed_tokens = 0 investors = [ presale_investor_1, presale_investor_2, ] # In the simulation we have 1 investor address # on each proxy buyer contract for idx, proxy_buyer in enumerate(proxy_buyers): buyer_address = investors[idx] old_balance = token.call().balanceOf(buyer_address) / (10**decimals) assert old_balance == 0 proxy_buyer.transact({"from": buyer_address}).claimAll() new_balance = token.call().balanceOf(buyer_address) / (10**decimals) diff = Decimal(new_balance) - Decimal(old_balance) total_claimed_tokens += diff # From spreadsheet, presale tokens assert math.isclose(total_claimed_tokens, 7971776, rel_tol=0.0001)
def test_claim_amounts_by_time(chain, team_multisig, token_10000, customer, customer_2): """Vault vesting tokens per second tap is giving good numbers over time period and different claims.""" token = token_10000 tokens = 10**18 # Customers have different amount of tokens, but relative same vesting rate # so vault should be empty for the both of the customers at the same time tokens_per_second = int(3 * tokens) tokens_per_second_2 = int(3 * tokens / 2) customer_balance = 6000 * tokens # How many tokens this account will have in the end customer_2_balance = 3000 * tokens # How many tokens this account will have in the end total_balance = 9000 * tokens # All tokens kockjed up in the vault assert customer_balance / tokens_per_second == customer_2_balance / tokens_per_second_2 start_time = int(time.time() + 1000) end_time = start_time + int(customer_balance / tokens_per_second) # Load and lock the vault args = [ team_multisig, start_time, token.address, total_balance, ] token_vault_tapped, hash = chain.provider.deploy_contract('TokenVault', deploy_args=args) token.functions.transfer(token_vault_tapped.address, total_balance).transact({"from": team_multisig}) token_vault_tapped.functions.setInvestor(customer, customer_balance, tokens_per_second).transact( {"from": team_multisig}) token_vault_tapped.functions.setInvestor(customer_2, customer_2_balance, tokens_per_second_2).transact( {"from": team_multisig}) token_vault_tapped.functions.lock().transact({"from": team_multisig}) # Test claims before the vault unfreezes time_travel(chain, start_time - 300) assert token_vault_tapped.functions.getState().call( ) == TokenVaultState.Holding assert token_vault_tapped.functions.getCurrentlyClaimableAmount( customer).call() == 0 assert token_vault_tapped.functions.getMaxClaimByNow(customer).call() == 0 # After one second we should be able to claim tokens_per_second amount time_travel(chain, start_time + 1) assert token_vault_tapped.functions.getState().call( ) == TokenVaultState.Distributing assert token_vault_tapped.functions.getCurrentlyClaimableAmount( customer).call() == tokens_per_second assert token_vault_tapped.functions.getMaxClaimByNow( customer).call() == tokens_per_second # After two second we should be able to claim tokens_per_second amount time_travel(chain, start_time + 2) assert token_vault_tapped.functions.getCurrentlyClaimableAmount( customer).call() == tokens_per_second * 2 assert token_vault_tapped.functions.getMaxClaimByNow( customer).call() == tokens_per_second * 2 # Claiming tokens should clear the available tap # Note that claim() itself automatically advanced us to next block - so we get 9 tokens instead 6 # (testrpc runs 1 second per block) assert token.functions.balanceOf(customer).call() == 0 token_vault_tapped.functions.claim().transact({"from": customer}) assert token.functions.balanceOf(customer).call() == 9 * tokens assert token_vault_tapped.functions.getCurrentlyClaimableAmount( customer).call() == 0 assert token_vault_tapped.functions.getMaxClaimByNow(customer).call() == 0 # Moving forward after claim should give us more tokens to claim # We have claimed 9 tokens # 5 seconds has passed, total 15 tokens should be available by time # but because of previous claims we have only 6 left to claim now time_travel(chain, start_time + 2 + 3) assert token_vault_tapped.functions.getCurrentlyClaimableAmount( customer).call() == 6 * tokens assert token_vault_tapped.functions.getMaxClaimByNow( customer).call() == 6 * tokens assert token_vault_tapped.functions.claimed(customer).call() == 9 * tokens # Then travel and overshoot the end of vesting period -- all 6000 tokens should be unlocked time_travel(chain, end_time + 10) claimed = 9 * tokens assert token_vault_tapped.functions.getCurrentlyClaimableAmount( customer).call() == customer_balance - claimed assert token_vault_tapped.functions.getMaxClaimByNow(customer).call() == ( customer_balance + 10 * tokens_per_second) - claimed # This does not consider vault end time # Claim rest of the tokens token_vault_tapped.functions.claim().transact({"from": customer}) assert token.functions.balanceOf(customer).call() == customer_balance # Cannot claim anything anymore time_travel(chain, end_time + 12) with pytest.raises(TransactionFailed): token_vault_tapped.functions.claim().transact({"from": customer}) # Then claim all tokens for the customer_2 token_vault_tapped.functions.claim().transact({"from": customer_2}) assert token.functions.balanceOf(customer_2).call() == customer_2_balance # See that we are zeroed out time_travel(chain, end_time + 20) assert token_vault_tapped.functions.getCurrentlyClaimableAmount( customer).call() == 0 assert token_vault_tapped.functions.getCurrentlyClaimableAmount( customer_2).call() == 0 assert token.functions.balanceOf(token_vault_tapped.address).call() == 0 assert token_vault_tapped.functions.claimed( customer).call() == customer_balance assert token_vault_tapped.functions.claimed( customer_2).call() == customer_2_balance
def test_presale_update_counters(chain, presale_fund_collector, wei_tranche_ico, finalizer, token, start_time, team_multisig, customer, customer_2, wei_tranche_pricing): """Check that presale counters work correctly. Presale investments should not count against tranches giving in the retail, but they are only effective in the main sale. .. warn:: Use PreicoProxyBuyer contract instead of PrealeFundsCollector to handle this in meaningful way. """ # We have set up the contracts in the way the presale purchaser gets special pricing assert wei_tranche_ico.functions.pricingStrategy().call( ) == wei_tranche_pricing.address wei_tranche_pricing.functions.setPreicoAddress( customer, to_wei("0.05", "ether")).transact({"from": team_multisig}) assert wei_tranche_pricing.functions.isPresalePurchase( customer).call() == True value = to_wei(20000, "ether") presale_fund_collector.functions.invest().transact({ "from": customer, "value": value }) # ICO begins, Link presale to an actual ICO presale_fund_collector.functions.setCrowdsale( wei_tranche_ico.address).transact({"from": team_multisig}) time_travel(chain, start_time) assert wei_tranche_ico.functions.getState().call( ) == CrowdsaleState.Funding # Load funds to ICO presale_fund_collector.functions.participateCrowdsaleAll().transact() assert wei_tranche_ico.functions.weiRaised().call() == to_wei( 20000, "ether") assert wei_tranche_ico.functions.presaleWeiRaised().call() == to_wei( 20000, "ether") # Tokens received, paid by preico price assert wei_tranche_ico.functions.investedAmountOf( customer).call() == to_wei(20000, "ether") token.functions.balanceOf(customer).call() == 20000 / 0.040 # Do a normal investment, should go to tranche 1, as presale investment does not # count against tranches wei_tranche_ico.functions.buy().transact({ "from": customer_2, "value": to_wei(10, "ether") }) assert wei_tranche_ico.functions.presaleWeiRaised().call() == to_wei( 20000, "ether") assert wei_tranche_ico.functions.weiRaised().call() == to_wei( 20010, "ether") token.functions.balanceOf(customer).call() == 10 / 0.00666666
def test_set_rate_late(chain, crowdsale, mysterium_pricing, team_multisig): """"CHF rate cannot be set after the crowdsale starts..""" time_travel(chain, crowdsale.call().startsAt()+1) with pytest.raises(TransactionFailed): mysterium_pricing.transact({"from": team_multisig}).setConversionRate(130 * 10000)
def test_milestone_prices(chain, milestone_pricing, start_time, end_time, customer): """We get correct milestone prices for different dates.""" time_travel(chain, start_time - 1) with pytest.raises(TransactionFailed): # Div by zero, crowdsale has not begin yet assert milestone_pricing.functions.getCurrentPrice().call() time_travel(chain, start_time) assert milestone_pricing.functions.getCurrentPrice().call() == to_wei( "0.10", "ether") time_travel(chain, start_time + 1) assert milestone_pricing.functions.getCurrentPrice().call() == to_wei( "0.10", "ether") # 1 week forward time_travel( chain, chain.web3.eth.getBlock('pending').timestamp + 7 * 24 * 60 * 60) assert milestone_pricing.functions.getCurrentPrice().call() == to_wei( "0.12", "ether") # 2 week forward time_travel( chain, chain.web3.eth.getBlock('pending').timestamp + 7 * 24 * 60 * 60) assert milestone_pricing.functions.getCurrentPrice().call() == to_wei( "0.13", "ether") # 3 week forward + last second time_travel(chain, end_time - 1) assert milestone_pricing.functions.getCurrentPrice().call() == to_wei( "0.14", "ether")
def test_kyc_participate_with_different_price(chain, web3, kyc_crowdsale, customer, customer_id, kyc_token, private_key, preico_starts_at, pricing, team_multisig): """The same user buys token with two different prices (as given by the server).""" # Check KYC crowdsale is good to go whitelisted_address = customer time_travel(chain, kyc_crowdsale.call().startsAt() + 1) start_multisig_total = web3.eth.getBalance(team_multisig) # Check the setup looks good assert kyc_crowdsale.call().getState() == CrowdsaleState.Funding assert kyc_crowdsale.call().isFinalizerSane() assert kyc_crowdsale.call().isPricingSane() assert kyc_crowdsale.call().beneficiary() == team_multisig assert kyc_token.call().transferAgents(team_multisig) == True assert kyc_crowdsale.call().investedAmountOf(whitelisted_address) == 0 # Do a test buy for 1 ETH wei_value = to_wei(1, "ether") excepted_token_value = int(0.5 * 10**18) price = 2 * 10**18 # wei per token assert kyc_crowdsale.call().calculateTokens(wei_value, price) == excepted_token_value # Buy with price 1 token = 2 wei kyc_payload = pack_kyc_pricing_dataframe(whitelisted_address, customer_id, 0, 1 * 10000, price) signed_data = sign(kyc_payload, private_key) unpacked = unpack_kyc_pricing_dataframe(kyc_payload) assert unpacked["pricing_data"] == price kyc_crowdsale.transact({ "from": whitelisted_address, "value": wei_value, "gas": 2222333 }).buyWithKYCData(kyc_payload, signed_data["v"], signed_data["r_bytes"], signed_data["s_bytes"]) # We got credited assert kyc_token.call().balanceOf( whitelisted_address) == excepted_token_value assert kyc_crowdsale.call().investedAmountOf( whitelisted_address) == wei_value # We have tracked the investor id events = kyc_crowdsale.pastEvents("Invested").get() assert len(events) == 1 e = events[0] assert e["args"]["investor"].lower() == whitelisted_address.lower() assert e["args"]["weiAmount"] == wei_value assert e["args"]["customerId"] == customer_id.int assert e["args"]["tokenAmount"] == excepted_token_value # More tokens, different price this time wei_value = to_wei(1, "ether") new_excepted_token_value = int(0.25 * 10**18) price = 4 * 10**18 # wei per token # New transaction, increased per person cap to 2 ETH kyc_payload = pack_kyc_pricing_dataframe(whitelisted_address, customer_id, 0, 2 * 10000, price) signed_data = sign(kyc_payload, private_key) kyc_crowdsale.transact({ "from": whitelisted_address, "value": wei_value, "gas": 333444 }).buyWithKYCData(kyc_payload, signed_data["v"], signed_data["r_bytes"], signed_data["s_bytes"]) # We got credited total = wei_value * 2 assert kyc_token.call().balanceOf( whitelisted_address) == excepted_token_value + new_excepted_token_value assert kyc_crowdsale.call().investedAmountOf(whitelisted_address) == total assert web3.eth.getBalance(team_multisig) == start_multisig_total + total # We have another event, this time with new price events = kyc_crowdsale.pastEvents("Invested").get() assert len(events) == 2 e = events[-1] assert e["args"]["investor"].lower() == whitelisted_address.lower() assert e["args"]["weiAmount"] == wei_value assert e["args"]["customerId"] == customer_id.int assert e["args"]["tokenAmount"] == new_excepted_token_value
def test_proxy_timelock(chain, web3, customer, customer_2, team_multisig, proxy_buyer, crowdsale, token, unlock_time): """Try to claim after timeLock has passed.""" assert proxy_buyer.call().getState() == 1 assert proxy_buyer.call().isPresale() == True #Change owner to customer_2, and back to team_multisig proxy_buyer.transact({"from": team_multisig}).setTimeLock(unlock_time) proxy_buyer.transact({"from": team_multisig}).transferOwnership(customer_2) proxy_buyer.transact({"from": customer_2}).transferOwnership(team_multisig) proxy_buyer.transact({ "value": to_wei(10000, "ether"), "from": customer }).buy() proxy_buyer.transact({ "value": to_wei(20000, "ether"), "from": customer_2 }).buy() # Everything funder assert proxy_buyer.call().weiRaised() == to_wei(30000, "ether") assert web3.eth.getBalance(proxy_buyer.address) == to_wei(30000, "ether") assert proxy_buyer.call().balances(customer) == to_wei(10000, "ether") assert proxy_buyer.call().balances(customer_2) == to_wei(20000, "ether") # Change the owner again, in the middle, and run rest of the test as customer_2 proxy_buyer.transact({"from": team_multisig}).transferOwnership(customer_2) # Move over assert crowdsale.call().getState() == CrowdsaleState.Funding proxy_buyer.transact({"from": customer_2}).setCrowdsale(crowdsale.address) assert proxy_buyer.call().crowdsale() == crowdsale.address proxy_buyer.transact({"from": customer}).buyForEverybody() assert web3.eth.getBalance(proxy_buyer.address) == 0 # We got our tokens assert proxy_buyer.call().getState() == 2 assert proxy_buyer.call().tokensBought() == 36000000 assert proxy_buyer.call().getClaimAmount(customer) == 36000000 / 3 * 1 assert proxy_buyer.call().getClaimLeft(customer) == 36000000 / 3 * 1 assert proxy_buyer.call().getClaimAmount(customer_2) == 36000000 / 3 * 2 assert proxy_buyer.call().getClaimLeft(customer_2) == 36000000 / 3 * 2 # Tokens cannot be claimed before they are released time_travel(chain, crowdsale.call().endsAt() + 1) crowdsale.transact({"from": team_multisig}).finalize() assert token.call().released() time_travel(chain, unlock_time + 1) # Claim tokens proxy_buyer.transact({"from": customer}).claimAll() proxy_buyer.transact({"from": customer_2}).claimAll() # Check investors got their tokens assert proxy_buyer.call().totalClaimed() == 36000000 assert proxy_buyer.call().claimCount() == 2 assert proxy_buyer.call().claimed(customer) == 36000000 / 3 * 1 assert proxy_buyer.call().claimed(customer_2) == 36000000 / 3 * 2 assert token.call().balanceOf(customer) == 36000000 / 3 * 1 assert token.call().balanceOf(customer_2) == 36000000 / 3 * 2
def test_deploy_all(chain, web3, everything_deployed, proxy_buyer, deploy_address, bitcoin_suisse, customer, customer_2, fake_seed_investor): """Acceptance test to verify that token sale functions properly.""" crowdsale = everything_deployed["crowdsale"] pricing_strategy = everything_deployed["pricing_strategy"] token_distribution = everything_deployed["token_distribution"] intermediate_vault = everything_deployed["intermediate_vault"] seed_participant_vault = everything_deployed["seed_participant_vault"] seed_participant_vault_2 = everything_deployed["seed_participant_vault_2"] founders_vault = everything_deployed["founders_vault"] future_funding_vault = everything_deployed["future_funding_vault"] token = everything_deployed["token"] team_multisig_funds = everything_deployed["team_multisig_funds"] assert crowdsale.call().getState() == CrowdsaleState.PreFunding # Let's set the daily rate assert pricing_strategy.call().owner() == deploy_address assert pricing_strategy.call().crowdsale() == crowdsale.address pricing_strategy.transact({ "from": deploy_address }).setConversionRate(170 * 10000) # Bitcoinsuisse shows up crowdsale.transact({ "from": deploy_address }).setEarlyParicipantWhitelist(bitcoin_suisse, True) crowdsale.transact({ "from": bitcoin_suisse, "value": to_wei(500000 / 170, "ether") }).buy() assert token.call().balanceOf(bitcoin_suisse) > 0 # Set up proxy buyer crowdsale addresses proxy_buyer.transact({ "from": deploy_address }).setCrowdsale(crowdsale.address) # ICO starts time_travel(chain, crowdsale.call().startsAt() + 1) # Load proxy buyer money proxy_buyer.transact({"from": deploy_address}).buyForEverybody() assert token.call().balanceOf(proxy_buyer.address) > 0 # All current money is in the intermediate vault assert web3.eth.getBalance(intermediate_vault.address) > 0 # We are not yet in the soft cap assert not crowdsale.call().isSoftCapReached() one_chf_in_eth = to_wei(1 / 170, "ether") before_price = pricing_strategy.call().calculatePrice( one_chf_in_eth, crowdsale.call().weiRaised(), crowdsale.call().tokensSold(), '0x0000000000000000000000000000000000000000', 8) before_ends_at = crowdsale.call().endsAt() # Do a retail transaction that fills soft cap crowdsale.transact({ "from": customer_2, "value": one_chf_in_eth * 6000000 }).buy() assert crowdsale.call().isSoftCapReached() after_price = pricing_strategy.call().calculatePrice( one_chf_in_eth, crowdsale.call().weiRaised(), crowdsale.call().tokensSold(), '0x0000000000000000000000000000000000000000', 8) after_ends_at = crowdsale.call().endsAt() assert after_ends_at < before_ends_at # End date got moved assert after_price < before_price # We get less tokens per ETH # Let's close it by reaching end of time time_travel(chain, crowdsale.call().endsAt() + 1) # Check that we have distribution facts correct chf_raised, chf_rate = token_distribution.call().getDistributionFacts() assert chf_raised == 8199999 assert chf_rate == 170 # Finalize the sale assert crowdsale.call().getState() == CrowdsaleState.Success assert token_distribution.call().crowdsale() == crowdsale.address assert token_distribution.call().mysteriumPricing( ) == pricing_strategy.address crowdsale.transact({"from": deploy_address}).finalize() # # Finalize vaults # # Seed vault 1 assert seed_participant_vault.address != seed_participant_vault_2.address # Let's not mix vaults assert seed_participant_vault.call().getToken( ) == token.address # Vault 1 is set up seed_participant_vault.transact({ "from": deploy_address }).fetchTokenBalance() # Seed vault 2 assert token_distribution.call().seed_coins_vault2( ) > 0 # We did distribute vault 2 assert seed_participant_vault_2.call().getToken( ) == token.address # Vault 2 is set up assert token.call().balanceOf(seed_participant_vault_2.address) > 0 seed_participant_vault_2.transact({ "from": deploy_address }).fetchTokenBalance() # Future vault assert token.call().balanceOf(future_funding_vault.address) > 0 future_funding_vault.transact({"from": deploy_address}).fetchTokenBalance() # Founders vault assert token.call().balanceOf(founders_vault.address) > 0 founders_vault.transact({"from": deploy_address}).fetchTokenBalance() # # Long timeline # # Money moves to multisig after two weeks time_travel(chain, crowdsale.call().endsAt() + 14 * 24 * 3600) money_before = web3.eth.getBalance(team_multisig_funds.address) intermediate_vault.transact({ "from": deploy_address }).unlock() # Move from intermediate to team funds money_after = web3.eth.getBalance(team_multisig_funds.address) assert money_after > money_before # Token is released after we have money in the multisig token.transact({"from": deploy_address}).releaseTokenTransfer() assert token.call().released() # Participants can transfer the token assert token.call().mintingFinished() # No more tokens can be created # Do a test transaction with a single token token.transact({"from": customer_2}).transfer(customer, 1 * 10**8) # Claim tokens from a preico contract old_balance = token.call().balanceOf(customer) proxy_buyer.transact({"from": customer}).claimAll() new_balance = token.call().balanceOf(customer) assert new_balance > old_balance # After 12 months, claim vaults time_travel(chain, crowdsale.call().endsAt() + 365 * 24 * 3600) # Claim seed vault 1, get seed investor tokens seed_participant_vault.transact({"from": fake_seed_investor}).claimAll() assert token.call().balanceOf(fake_seed_investor) > 0 # Claim seed vault 2, get even more tokens old_balance = token.call().balanceOf(fake_seed_investor) seed_participant_vault_2.transact({"from": fake_seed_investor}).claimAll() new_balance = token.call().balanceOf(fake_seed_investor) assert new_balance > old_balance