def test_change_multisig_only_owner(chain: TestRPCChain, ico: Contract, customer: str, preico_starts_at, preico_ends_at, team_multisig): """Only own can change the multisig address.""" with pytest.raises(TransactionFailed): ico.transact({"from": customer}).setMultisig(customer)
def test_token_rename(token: Contract, team_multisig, token_new_name, token_new_symbol): """We will update token's information here""" token.transact({"from": team_multisig}).setTokenInformation(token_new_name, token_new_symbol) assert token.call().name() == token_new_name assert token.call().symbol() == token_new_symbol
def test_finalize_success(chain: TesterChain, 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( ) == chain.web3.toChecksumAddress(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_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_malicious_transfer_agent_set(token: Contract, malicious_address): """Externals cannot whitelist transfer agents.""" with pytest.raises(TransactionFailed): token.transact({ "from": malicious_address }).setTransferAgent(malicious_address, True)
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_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_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_send_invoice(web3: Web3, registry_contract: Contract, sample_company: dict): """Test send invoice function.""" invoice_id = "00001" payload = "<xml></xml>" registry_contract.transact().sendInvoice("FI24303727", "FI23486648", invoice_id, payload)
def failed_ico_ready_to_refund(chain: TestRPCChain, failed_ico: Contract, team_multisig) -> Contract: """An ICO that did not reach a goal, but has participants. The team has moved funds back from the multisig wallet on the crowdsale contract. Note that due to transaction fees you need to pay a minimal transaction cost out of your own pocket. """ failed_ico.transact({"from" : team_multisig, "value": failed_ico.call().weiRaised()}).loadRefund() return failed_ico
def test_change_end_at_only_owner(chain: TestRPCChain, ico: Contract, customer: str, preico_starts_at, preico_ends_at, team_multisig): """Only own can change end date.""" new_early = preico_starts_at + 1*3600 with pytest.raises(TransactionFailed): ico.transact({"from": customer}).setEndsAt(new_early)
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_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_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_cannot_upgrade_too_many(released_token: Contract, upgrade_agent: Contract, team_multisig, customer): """We cannot upgrade more tokens than we have.""" released_token.transact({"from": team_multisig}).setUpgradeAgent(upgrade_agent.address) assert released_token.call().balanceOf(customer) == 10000 with pytest.raises(TransactionFailed): released_token.transact({"from": customer}).upgrade(20000)
def test_cannot_refund_twice(failed_ico_ready_to_refund: Contract, customer: str): """Customer can reclaim refund only once.""" assert failed_ico_ready_to_refund.call().getState() == CrowdsaleState.Refunding failed_ico_ready_to_refund.transact({"from": customer}).refund() with pytest.raises(TransactionFailed): failed_ico_ready_to_refund.transact({"from": customer}).refund()
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_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_malicious_set_upgrade_agent(released_token: Contract, upgrade_agent: Contract, malicious_address): """Only owner can set the upgrade agent can be set on a released token.""" with pytest.raises(TransactionFailed): released_token.transact({ "from": malicious_address }).setUpgradeAgent(upgrade_agent.address)
def test_change_upgrade_master(released_token: Contract, upgrade_agent: Contract, team_multisig, customer): """Owner can change the upgrade master.""" released_token.transact({"from": team_multisig}).setUpgradeMaster(customer) released_token.transact({ "from": customer }).setUpgradeAgent(upgrade_agent.address)
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_token_rename(token: Contract, team_multisig, token_new_name, token_new_symbol): """We will update token's information here""" token.transact({ "from": team_multisig }).setTokenInformation(token_new_name, token_new_symbol) assert token.call().name() == token_new_name assert token.call().symbol() == token_new_symbol
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_bad_released(token: Contract, team_multisig: str, malicious_address: str, empty_address: str): """Only release agent can make token transferable.""" assert not token.call().released() with pytest.raises(TransactionFailed): token.transact({"from": malicious_address}).releaseTokenTransfer() # Even owner cannot release, need to go through release agent process with pytest.raises(TransactionFailed): token.transact({"from": team_multisig}).releaseTokenTransfer()
def test_cannot_upgrade_too_many(released_token: Contract, upgrade_agent: Contract, team_multisig, customer): """We cannot upgrade more tokens than we have.""" released_token.transact({ "from": team_multisig }).setUpgradeAgent(upgrade_agent.address) assert released_token.call().balanceOf(customer) == 10000 with pytest.raises(TransactionFailed): released_token.transact({"from": customer}).upgrade(20000)
def test_set_upgrade_agent(released_token: Contract, upgrade_agent: Contract, team_multisig): """Upgrade agent can be set on a released token.""" # Preconditions are met assert upgrade_agent.call().isUpgradeAgent() assert released_token.call().canUpgrade() assert released_token.call().upgradeMaster() == team_multisig assert upgrade_agent.call().oldToken() == released_token.address assert upgrade_agent.call().originalSupply() == released_token.call().totalSupply() released_token.transact({"from": team_multisig}).setUpgradeAgent(upgrade_agent.address) assert released_token.call().getUpgradeState() == UpgradeState.ReadyToUpgrade
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_set_upgrade_agent(upgradeable_token: Contract, upgrade_agent: Contract, team_multisig): """Upgrade agent can be set on a released token.""" # Preconditions are met assert upgrade_agent.call().isUpgradeAgent() assert upgradeable_token.call().canUpgrade() assert upgradeable_token.call().upgradeMaster() == team_multisig assert upgrade_agent.call().oldToken() == upgradeable_token.address assert upgrade_agent.call().originalSupply() == upgradeable_token.call().totalSupply() assert upgradeable_token.call().getUpgradeState() == UpgradeState.WaitingForAgent upgradeable_token.transact({"from": team_multisig}).setUpgradeAgent(upgrade_agent.address) assert upgradeable_token.call().getUpgradeState() == UpgradeState.ReadyToUpgrade
def test_get_price_tiers(crowdsale: Contract, token: Contract, customer: str, web3: Web3): """Price tiers match given dates.""" deadlines = [1488297600, 1488902400, 1489507200, 1490112000] prices = [833333333333333, 909090909090909, 952380952380952, 1000000000000000] for idx, deadline in enumerate(deadlines): crowdsale.transact().setCurrent(deadline-1) assert crowdsale.call().getPrice() == prices[idx] # Post last deadline prcie crowdsale.transact().setCurrent(deadlines[-1] + 1) assert crowdsale.call().getPrice() == 1000000000000000
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_cannot_transfer(token: Contract, team_multisig, customer: str, customer_2: str): """Tokens cannot be transferred before they are released.""" assert not token.call().released() # team_multisig is on the whitelisted transfer agent list assert token.call().transferAgents(team_multisig) == False with pytest.raises(TransactionFailed): token.transact({"from": team_multisig}).transfer(customer, 10000) # customer cannot transfer to customer 2 before release assert token.call().transferAgents(customer) == False with pytest.raises(TransactionFailed): token.transact({"from": customer}).transfer(customer_2, 10000)
def test_check_goal_not_reached(open_crowdsale: Contract, token: Contract, customer: str, beneficiary: str, web3: Web3, end: int): """Crowdsale may not reach its minimum funding goal.""" # Buy some tokens web3.eth.sendTransaction({ "from": customer, "to": open_crowdsale.address, "value": to_wei(20, "ether"), "gas": 250000, }) open_crowdsale.transact().setCurrent(end + 1) finished_crowdsale = open_crowdsale finished_crowdsale.transact().checkGoalReached() assert finished_crowdsale.call().fundingGoalReached() == False
def test_upgrade_partial(released_token: Contract, upgrade_agent: Contract, team_multisig, customer): """We can upgrade some of tokens.""" released_token.transact({"from": team_multisig}).setUpgradeAgent(upgrade_agent.address) assert released_token.call().balanceOf(team_multisig) == 9990000 assert released_token.call().totalSupply() == 10000000 released_token.transact({"from": team_multisig}).upgrade(3000000) assert released_token.call().getUpgradeState() == UpgradeState.Upgrading assert released_token.call().totalSupply() == 7000000 assert upgrade_agent.call().totalSupply() == 3000000 assert released_token.call().totalUpgraded() == 3000000 assert released_token.call().balanceOf(team_multisig) == 6990000 assert upgrade_agent.call().balanceOf(team_multisig) == 3000000
def test_cannot_change_agent_in_fly(upgradeable_token: Contract, upgrade_agent: Contract, team_multisig, customer, upgrade_agent_2): """Upgrade agent cannot be changed after the ugprade has begun.""" upgradeable_token.transact({"from": team_multisig}).setUpgradeAgent(upgrade_agent.address) upgradeable_token.transact({"from": team_multisig}).transfer(customer, 10000) upgradeable_token.transact({"from": customer}).upgrade(10000) with pytest.raises(TransactionFailed): upgradeable_token.transact({"from": team_multisig}).setUpgradeAgent(upgrade_agent_2.address)
def test_buy_two_investors(chain: TestRPCChain, web3: Web3, ico: Contract, uncapped_token: Contract, customer: str, customer_2, preico_token_price, preico_starts_at, team_multisig): """Two different customers buy in.""" 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) # Buy twice ico.transact({"from": customer, "value": wei_value}).buy() ico.transact({"from": customer_2, "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 * 2 assert ico.call().tokensSold() == buys_tokens * 2 # Ether on every account assert ico.call().weiRaised() == wei_value * 2 assert ico.call().investedAmountOf(customer) == wei_value balance_diff = web3.eth.getBalance(team_multisig) - original_balance assert balance_diff == wei_value * 2 # Investors assert ico.call().investorCount() == 2 # # Events # # Crowdsale events = ico.pastEvents("Invested").get() assert len(events) == 2 # ERC-20 events = uncapped_token.pastEvents("Transfer").get() assert len(events) == 2
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_refund(failed_ico_ready_to_refund: Contract, web3: Web3, customer: str, customer_2: str): """Customers can claim their refunds.""" assert failed_ico_ready_to_refund.call().loadedRefund() == to_wei(120, "ether") assert failed_ico_ready_to_refund.call().getState() == CrowdsaleState.Refunding # Check that the customer gets money back invested_amount = failed_ico_ready_to_refund.call().investedAmountOf(customer) begin_balance = web3.eth.getBalance(customer) failed_ico_ready_to_refund.transact({"from": customer}).refund() end_balance = web3.eth.getBalance(customer) eth = from_wei(end_balance - begin_balance, "ether") # Decimal('49.999999999999954693') assert (end_balance - begin_balance) >= eth - TRANSACTION_COST_ETH_EPSILON failed_ico_ready_to_refund.transact({"from": customer_2}).refund() # Everything has been refunded assert failed_ico_ready_to_refund.call().weiRefunded() == to_wei(120, "ether")
def failed_ico(chain: TestRPCChain, web3, uncapped_flatprice: Contract, team_multisig, customer, customer_2, preico_starts_at, preico_ends_at, uncapped_flatprice_finalizer) -> Contract: """An ICO that did not reach a goal, but has participants. Both ``customer`` and ``customer_2`` had bought token. * customer: 50 ether * customer_2: 70 ether * total: 120 ether * minimum funding goal: 1200 ether """ time_travel(chain, preico_starts_at + 1) uncapped_flatprice.transact({"from": customer, "value": to_wei(50, "ether")}).buy() uncapped_flatprice.transact({"from": customer_2, "value": to_wei(70, "ether")}).buy() assert not uncapped_flatprice.call().isMinimumGoalReached() # Make sure customer 1 has some token balance time_travel(chain, uncapped_flatprice.call().endsAt() + 1) return uncapped_flatprice
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_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()