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_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 decimalize_token_amount(contract: Contract, amount: int) -> Decimal:
    """Convert raw fixed point token amount to decimal format.

    :param contract: ERC-20 token contract with decimals field
    :param amount: Raw token amount
    :return: The resultdroping :py:class:`decimal.Decimal` carries a correct decimal places.
    """
    val = Decimal(amount) / Decimal(10 ** contract.call().decimals())
    quantizer = Decimal(1) /  Decimal(10 ** contract.call().decimals())
    return val.quantize(quantizer)
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_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_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()
Exemple #8
0
def test_erc20_interface(token: Contract, token_owner: str, empty_address: str):
    """Token satisfies ERC-20 interface."""

    # https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20.sol

    assert token.call().balanceOf(empty_address) == 0
    assert token.call().allowance(token_owner, empty_address) == 0

    # Event
    # We follow OpenZeppelin - in the ERO20 issue names are _from, _to, _value
    transfer = token._find_matching_event_abi("Transfer", ["from", "to", "value"])
    assert transfer

    approval = token._find_matching_event_abi("Approval", ["owner", "spender", "value"])
    assert approval
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_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_signature_contract_verify_v_r_s(web3: Web3, signature_contract: Contract):
    """Test that our signature verification works in Solidity contract.

    """

    # Use random Ethereum address as payload for signing
    data = "0xda39147df55f6c51ad539a5e108adc5d7284b309"

    # Convert address to raw bytes
    data_bin = binascii.unhexlify(data[2:])
    assert type(data_bin) == bytes

    private_key_seed = "foobar"
    # Address is 0x58708390680239282143999941903085911172379991841

    signature_data = sign(data_bin, private_key_seed)

    # hash = big_endian_to_int(signature_data["hash"])
    hash = signature_data["hash"]
    v = signature_data["v"]
    r = signature_data["r_bytes"]
    s = signature_data["s_bytes"]

    # 0x0a489345f9e9bc5254e18dd14fa7ecfdb2ce5f21
    result = signature_contract.call().verify(hash, v, r, s)
    assert result == signature_data["address_ethereum"]
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 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_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_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()
Exemple #16
0
def test_sign_balance_proof_contract(channel_manager_contract: Contract):
    sig = sign_balance_proof(
        SENDER_PRIVATE_KEY, RECEIVER_ADDR, 37, 15, channel_manager_contract.address
    )
    sender_recovered = channel_manager_contract.call().extractBalanceProofSignature(
        RECEIVER_ADDR, 37, 15, sig
    )
    assert is_same_address(sender_recovered, SENDER_ADDR)
Exemple #17
0
def sweep_account(
        private_key: str,
        faucet_address: str,
        token_contract: Contract,
        web3: Web3,
        wait_for_transaction
):
    address = privkey_to_addr(private_key)
    log.info('Sweeping account {}'.format(address))
    token_balance = token_contract.call().balanceOf(address)
    if token_balance > 0:
        tx = create_signed_contract_transaction(
            private_key,
            token_contract,
            'transfer',
            [
                faucet_address,
                token_balance
            ]
        )
        try:
            tx_hash = web3.eth.sendRawTransaction(tx)
        except ValueError as e:
            if e.args[0]['message'].startswith('Insufficient funds.'):
                pass
            else:
                raise
        else:
            wait_for_transaction(tx_hash)
            assert token_contract.call().balanceOf(address) == 0

    balance = web3.eth.getBalance(address)
    if balance < NETWORK_CFG.POT_GAS_LIMIT * NETWORK_CFG.GAS_PRICE:
        return
    tx = create_signed_transaction(
        private_key,
        web3,
        to=faucet_address,
        value=balance - NETWORK_CFG.POT_GAS_LIMIT * NETWORK_CFG.GAS_PRICE,
        gas_limit=NETWORK_CFG.POT_GAS_LIMIT
    )
    tx_hash = web3.eth.sendRawTransaction(tx)
    wait_for_transaction(tx_hash)
    assert web3.eth.getBalance(address) == 0, (
        'Sweeping of account {} (private key {}) failed.'.format(address, private_key)
    )
Exemple #18
0
def test_sign_close_contract(channel_manager_contract: Contract):
    sig = sign_close(
        RECEIVER_PRIVATE_KEY, SENDER_ADDR, 315832, 13, channel_manager_contract.address
    )
    receiver_recovered = channel_manager_contract.call().extractClosingSignature(
        SENDER_ADDR, 315832, 13, sig
    )
    assert is_same_address(receiver_recovered, RECEIVER_ADDR)
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_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_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 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_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_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_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_upgrade_all(released_token: Contract, upgrade_agent: Contract, team_multisig, customer):
    """We can upgrade all tokens of two owners."""

    released_token.transact({"from": team_multisig}).setUpgradeAgent(upgrade_agent.address)
    assert released_token.call().balanceOf(team_multisig) == 9990000
    assert released_token.call().balanceOf(customer) == 10000
    assert released_token.call().totalSupply() == 10000000
    released_token.transact({"from": team_multisig}).upgrade(9990000)
    released_token.transact({"from": customer}).upgrade(10000)

    assert released_token.call().getUpgradeState() == UpgradeState.Upgrading
    assert released_token.call().totalSupply() == 0
    assert upgrade_agent.call().totalSupply() == 10000000
    assert released_token.call().totalUpgraded() == 10000000

    assert upgrade_agent.call().balanceOf(team_multisig) == 9990000
    assert upgrade_agent.call().balanceOf(customer) == 10000
def test_initialized(ico: Contract, uncapped_token: Contract, team_multisig, preico_starts_at, preico_ends_at, preico_funding_goal):
    """Is initialized with the parameters we want."""

    # We have owner
    assert ico.call().owner() == team_multisig

    # Crowdsale contract is in minters
    assert uncapped_token.call().mintAgents(ico.address) == True
    assert not uncapped_token.call().released()
    assert not ico.call().halted()
    assert ico.call().startsAt() == preico_starts_at
    assert ico.call().endsAt() == preico_ends_at
    assert ico.call().getState() == CrowdsaleState.PreFunding
    assert ico.call().minimumFundingGoal() == preico_funding_goal
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 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
Exemple #31
0
def test_no_transfer_before_close(open_crowdsale: Contract, token: Contract, customer: str, beneficiary: str, empty_address: str, web3: Web3, end: int):
    """Buyer cannot transfer tokens before ICO is over."""

    web3.eth.sendTransaction({
        "from": customer,
        "to": open_crowdsale.address,
        "value": to_wei(20, "ether"),
        "gas": 250000,
    })

    amount = 4000
    with pytest.raises(TransactionFailed):
        token.transact({"from": customer}).transfer(empty_address, amount)

    token.transact().setCurrent(end+1)
    token.transact({"from": customer}).transfer(empty_address, amount)

    assert token.call().balanceOf(empty_address) == amount
Exemple #32
0
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: TesterChain,
                            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()
Exemple #34
0
def test_finalize_fail_again(chain: TestRPCChain,
                             uncapped_flatprice_final: Contract, 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().finalize()
    with pytest.raises(TransactionFailed):
        uncapped_flatprice_final.transact().finalize()
Exemple #35
0
def reclaim_address(token: Contract, entry: Entry, tx_params: dict) -> Tuple[int, str]:
    """Reclsaim tokens for a single participant.

    :param token: Token contract we reclaim
    :param owner: Token owner account
    :param address: Etherereum address
    :param label: User notification label regarding this address
    :param tx_params: Ethereum transaction parameters to use
    :return: 1 on reclaim, 0 on skip
    """

    # Make sure we are not fed bad input, raises
    validate_ethereum_address(entry.address)

    if token.call().balanceOf(entry.address) == 0:
        logger.info("%s: looks like already reclaimed %s", entry.address, entry.label)
        return 0, None

    txid = token.transact(tx_params).transferToOwner(entry.address)
    logger.info("%s: reclaiming %s in txid %s", entry.address, entry.label, txid)
    return 1, txid
Exemple #36
0
def test_upgrade_partial(upgradeable_token: Contract, upgrade_agent: Contract, team_multisig, customer):
    """We can upgrade some of tokens."""

    upgradeable_token.transact({"from": team_multisig}).setUpgradeAgent(upgrade_agent.address)

    # Fiddle numbers so that we have some balance on other users too
    upgradeable_token.transact({"from": team_multisig}).transfer(customer, 1000)

    to_upgrade = 3000000
    begin_tokens = upgradeable_token.call().balanceOf(team_multisig)
    supply_start = upgradeable_token.call().totalSupply()
    assert begin_tokens > to_upgrade

    upgradeable_token.transact({"from": team_multisig}).upgrade(to_upgrade)

    assert upgradeable_token.call().getUpgradeState() == UpgradeState.Upgrading

    assert upgradeable_token.call().totalSupply() == supply_start - to_upgrade
    assert upgrade_agent.call().totalSupply() == to_upgrade
    assert upgradeable_token.call().totalUpgraded() == to_upgrade

    assert upgradeable_token.call().balanceOf(team_multisig) == begin_tokens - to_upgrade
    assert upgrade_agent.call().balanceOf(team_multisig) == to_upgrade
Exemple #37
0
def import_investor_data(contract: Contract, deploy_address: str, fname: str):
    """Load investor data to a MultiVault contract.

    Mysterium specific data loader.

    :return: List of unconfirmed transaction ids
    """

    assert fname.endswith(".csv")

    txs = []
    with open(fname, "rt") as inp:
        for line in inp:
            address, amount = line.split(",")
            address = address.strip()
            amount = amount.strip()
            assert address.startswith("0x")
            amount = int(float(amount) * 10000)  # Use this precision
            if contract.call().balances(address) == 0:
                contract.transact({
                    "from": deploy_address
                }).addInvestor(address, amount)
Exemple #38
0
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
Exemple #39
0
def test_check_burn(open_crowdsale: Contract, token: Contract, customer: str,
                    beneficiary: str, web3: Web3, end: int):
    """Extra tokens are burnt as described as the end of the ICO."""

    minimum_goal_value = open_crowdsale.call().fundingGoal(
    ) * open_crowdsale.call().getPrice()

    # Buy some tokens
    web3.eth.sendTransaction({
        "from": customer,
        "to": open_crowdsale.address,
        "value": minimum_goal_value,
        "gas": 250000,
    })

    # Close
    token.transact().setCurrent(end + 1)
    finished_token = token

    open_crowdsale.transact().setCurrent(end + 1)
    finished_crowdsale = open_crowdsale

    # Supply before burn
    supply_before_burn = token.call().totalSupply()
    owner_before_burn = token.call().balanceOf(beneficiary)
    assert not finished_token.call().burned()

    # Trigger goal check
    finished_crowdsale.transact().checkGoalReached()
    assert finished_crowdsale.call().fundingGoalReached()

    # We get crowdsale over event
    events = finished_crowdsale.pastEvents("GoalReached").get()
    assert len(events) == 1

    # We burned succesfully
    assert finished_token.call().burned()
    assert token.call().totalSupply() < supply_before_burn
    assert token.call().balanceOf(beneficiary) < owner_before_burn

    # Burned event gives us the diff
    events = finished_token.pastEvents("Burned").get()
    assert len(events) == 1
    e = events[0]
    assert e["args"]["amount"] == 390000000
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()
Exemple #41
0
def test_call_check_goal_reached_after_close(finished_crowdsale: Contract,
                                             token: Contract, customer: str,
                                             beneficiary: str, web3: Web3):
    """Checking goal reached closes crowdsale if we are the past end deadline."""
    finished_crowdsale.transact().checkGoalReached()
    assert finished_crowdsale.call().crowdsaleClosed() == True
Exemple #42
0
def test_call_check_goal_reached_too_early(open_crowdsale: Contract,
                                           token: Contract, customer: str,
                                           beneficiary: str, web3: Web3):
    """Checking goal reached does nothing unless ICO is over."""
    open_crowdsale.transact().checkGoalReached()
    assert open_crowdsale.call().crowdsaleClosed() == False
Exemple #43
0
def close_open_channels(
        private_key: str,
        state: ChannelManagerState,
        channel_manager_contract: Contract,
        repetitions=None,
        wait=lambda: gevent.sleep(1)
):
    web3 = channel_manager_contract.web3
    channels_with_balance_proof = [
        c for c in state.channels.values() if c.last_signature is not None
    ]
    n_channels = len(state.channels)
    n_no_balance_proof = len(state.channels) - len(channels_with_balance_proof)
    n_txs_sent = 0
    pending_txs = {}

    if repetitions:
        iterator = range(repetitions)
    else:
        iterator = count()
    for _ in iterator:
        n_non_existant = 0
        n_invalid_balance_proof = 0
        for channel in channels_with_balance_proof:
            # lookup channel on block chain
            channel_id = (channel.sender, channel.receiver, channel.open_block_number)
            try:
                channel_info = channel_manager_contract.call().getChannelInfo(*channel_id)
            except (BadFunctionCallOutput, TransactionFailed):
                n_non_existant += 1
                continue
            _, deposit, settle_block_number, closing_balance, transferred_tokens = channel_info

            is_valid = channel.balance <= deposit
            n_invalid_balance_proof += int(not is_valid)
            close_sent = (channel.sender, channel.open_block_number) in pending_txs

            # send close if open or settling with wrong balance, unless already done
            if not close_sent and is_valid:
                closing_sig = sign_close(
                    private_key,
                    channel.sender,
                    channel.open_block_number,
                    channel.balance,
                    channel_manager_contract.address
                )

                raw_tx = create_signed_contract_transaction(
                    private_key,
                    channel_manager_contract,
                    'cooperativeClose',
                    [
                        channel.receiver,
                        channel.open_block_number,
                        channel.balance,
                        decode_hex(channel.last_signature),
                        closing_sig
                    ]
                )
                tx_hash = web3.eth.sendRawTransaction(raw_tx)
                log.info('sending close tx (hash: {})'.format(tx_hash))
                pending_txs[channel.sender, channel.open_block_number] = tx_hash
                n_txs_sent += 1

        # print status
        msg_status = 'block: {}, pending txs: {}, total txs sent: {}'
        msg_progress = (
            'initial channels: {}, settled: {}, pending txs: {}, no BP: {}, invalid BP: {}'
        )
        log.info(msg_status.format(web3.eth.blockNumber, len(pending_txs), n_txs_sent))
        log.info(msg_progress.format(
            n_channels,
            n_non_existant,
            len(pending_txs),
            n_no_balance_proof,
            n_invalid_balance_proof
        ))

        # wait for next block
        block_before = web3.eth.blockNumber
        while web3.eth.blockNumber == block_before:
            wait()

        # update pending txs
        confirmed = []
        for channel_id, tx_hash in pending_txs.items():
            receipt = web3.eth.getTransactionReceipt(tx_hash)
            if receipt is None:
                continue
            tx = web3.eth.getTransaction(tx_hash)
            if receipt.gasUsed == tx.gas:
                raise ValueError('Transaction failed, out of gas (hash: {})'.format(tx_hash))
            confirmed.append(channel_id)
        for channel_id in confirmed:
            pending_txs.pop(channel_id)
Exemple #44
0
def test_cannot_upgrade_until_released(token: Contract):
    """Non-released tokens cannot be upgradeable."""

    assert not token.call().canUpgrade()
    assert token.call().getUpgradeState() == UpgradeState.NotAllowed
Exemple #45
0
def test_can_upgrade_released_token(released_token: Contract):
    """Released token is free to upgrade."""
    assert released_token.call().canUpgrade()
    assert released_token.call().getUpgradeState(
    ) == UpgradeState.WaitingForAgent
Exemple #46
0
def test_app_drain(monkeypatch: MonkeyPatch, keyfiles: None, client_app: App,
                   passwords: List[str], private_keys: List[PrivateKeyHex],
                   addresses: List[Address], web3: Web3,
                   token_contract: Contract, faucet_address: Address,
                   use_tester: bool, wait_for_transaction,
                   faucet_private_key: PrivateKeyHex):
    i = 6
    j = 3
    fund_account(addresses[i], WEI_ALLOWANCE, REI_ALLOWANCE, token_contract,
                 web3, wait_for_transaction, faucet_private_key)
    fund_account(addresses[j], WEI_ALLOWANCE, REI_ALLOWANCE, token_contract,
                 web3, wait_for_transaction, faucet_private_key)
    if use_tester:
        ethereum.tester.accounts.append(decode_hex(addresses[i]))
        ethereum.tester.keys.append(decode_hex(private_keys[i]))
        ethereum.tester.accounts.append(decode_hex(addresses[j]))
        ethereum.tester.keys.append(decode_hex(private_keys[j]))

    input_sequence = (
        value for value in
        [str(i), passwords[i], False, True,
         str(j), passwords[j], True])
    mock_prompt(monkeypatch, input_sequence)

    client_app.start()

    account_rei = token_contract.call().balanceOf(addresses[i])
    account_wei = web3.eth.getBalance(addresses[i])
    faucet_rei = token_contract.call().balanceOf(faucet_address)
    faucet_wei = web3.eth.getBalance(faucet_address)
    assert account_rei > 0
    assert account_wei > 0

    # Should drain nothing.
    client_app.drain(faucet_address)
    assert token_contract.call().balanceOf(addresses[i]) == account_rei
    assert web3.eth.getBalance(addresses[i]) == account_wei

    with pytest.raises(AssertionError):
        # Address not checksummed.
        client_app.drain(to_normalized_address(faucet_address), rdn=True)

    # Not confirmed.
    client_app.drain(faucet_address, rdn=True)
    assert token_contract.call().balanceOf(addresses[i]) == account_rei
    assert web3.eth.getBalance(addresses[i]) == account_wei

    # Confirmed.
    client_app.drain(faucet_address, rdn=True)
    assert token_contract.call().balanceOf(addresses[i]) == 0
    assert 0 < web3.eth.getBalance(addresses[i]) < account_wei
    assert token_contract.call().balanceOf(
        faucet_address) == faucet_rei + account_rei
    assert web3.eth.getBalance(faucet_address) == faucet_wei

    # Second round, different account.
    client_app.start()

    account_rei = token_contract.call().balanceOf(addresses[j])
    account_wei = web3.eth.getBalance(addresses[j])
    faucet_rei = token_contract.call().balanceOf(faucet_address)
    faucet_wei = web3.eth.getBalance(faucet_address)
    assert account_rei > 0
    assert account_wei > 0

    # Drain both ETH and RDN.
    client_app.drain(faucet_address, rdn_and_eth=True)
    assert token_contract.call().balanceOf(addresses[j]) == 0
    assert web3.eth.getBalance(addresses[j]) == 0
    assert token_contract.call().balanceOf(
        faucet_address) == faucet_rei + account_rei
    assert web3.eth.getBalance(faucet_address) > faucet_wei
 def get_length(self, account: Address, storage: Contract = None) -> int:
     if storage is None:
         storage = self.get_storage(account)
     return storage.call().length()
Exemple #48
0
def import_invoicing_address(contract: Contract, tieke_data: dict):
    """Sample importer for an invoicing address.

    Slow. Confirms each transaction in serial fashion.
    """

    vat_id = ytunnus_to_vat_id(tieke_data["Y-tunnus"])

    print("Importing {}".format(vat_id))

    # We have not imported this company yet
    if not contract.call().hasCompany(vat_id):
        # TODO: This demo creates a company record too, but all vatIds should be prepopulated
        txid = contract.transact().createCompany(vat_id)
        assert check_succesful_tx(contract, txid)

        # Create core company info

        data = {"name": tieke_data["Yrityksen nimi"]}

        data = json.dumps(data)  # Convert to UTF-8 string
        contract.transact().setCompanyData(vat_id,
                                           ContentType.TiekeCompanyData.value,
                                           data)

    address = tieke_data["Vastaanotto-osoite"]
    if not address:
        # Some old gappy data?
        address = "OVT:" + tieke_data["OVT-tunnus"]
    else:
        address = normalize_invoicing_address(address)

    assert address

    # We have not imported this address yet
    if contract.call().getVatIdByAddress(address) != "":
        print("Already exists: VAT id: {}, address: {}".format(
            vat_id, address))
        return

    # Create new OVT address
    txid = contract.transact().createInvoicingAddress(vat_id, address)
    assert check_succesful_tx(contract, txid, timeout=180)

    tieke_address_data = {
        "operatorName": tieke_data["Operaattori"],
        "operatorId": tieke_data["Välittäjän tunnus"],
        "permissionToSend": tieke_data["Lähetyslupa"] == "Kyllä",
        "sends": tieke_data["Lähettää"] == "Kyllä",
        "receives": tieke_data["Vastaanottaa"] == "Kyllä",
    }
    tieke_address_data = json.dumps(tieke_address_data)  # UTF-8 encoded string

    txid = contract.transact().setInvoicingAddressData(
        vat_id, address, ContentType.TiekeAddressData.value,
        tieke_address_data)
    assert check_succesful_tx(contract, txid)

    print("Done with {} {}".format(vat_id, address))

    return address
def get_price(contract: Contract, now: datetime.datetime):
    contract.transact().setNow(to_timestamp(now))
    return contract.call().getPrice()
def close_open_channels(private_key: str,
                        state: ChannelManagerState,
                        channel_manager_contract: Contract,
                        gas_price: int = None,
                        wait=lambda: gevent.sleep(1)):
    web3 = channel_manager_contract.web3
    pending_txs = {}

    for channel in state.channels.values():
        if not channel.last_signature:
            continue

        channel_id = (channel.sender, channel.receiver,
                      channel.open_block_number)
        try:
            channel_info = channel_manager_contract.call().getChannelInfo(
                *channel_id)
        except (BadFunctionCallOutput, TransactionFailed):
            continue
        _, deposit, settle_block_number, closing_balance, transferred_tokens = channel_info
        available_tokens = channel.balance - transferred_tokens

        if not channel.balance <= deposit:
            log.info('Invalid channel: balance %d > deposit %d',
                     channel.balance, deposit)
            continue
        closing_sig = utils.sign_close(private_key, channel.sender,
                                       channel.open_block_number,
                                       channel.balance,
                                       channel_manager_contract.address)

        raw_tx = utils.create_signed_contract_transaction(
            private_key,
            channel_manager_contract,
            'cooperativeClose',
            [
                channel.receiver, channel.open_block_number, channel.balance,
                decode_hex(channel.last_signature), closing_sig
            ],
            gas_price=gas_price,
        )
        tx_hash = web3.eth.sendRawTransaction(raw_tx)
        log.info('Sending cooperative close tx (hash: %s): %d from %r',
                 encode_hex(tx_hash), available_tokens, channel_id)
        pending_txs[channel_id] = (tx_hash, available_tokens)

    success = 0
    total_tokens = 0
    total_gas = 0
    gas_price = 0
    for channel_id, close_info in pending_txs.items():
        tx_hash, available_tokens = close_info
        receipt = None
        # wait for tx to be mined
        while True:
            receipt = web3.eth.getTransactionReceipt(tx_hash)
            if not receipt or not receipt.blockNumber:
                wait()
            else:
                break
        tx = web3.eth.getTransaction(tx_hash)
        total_gas += receipt.gasUsed
        gas_price = tx.gasPrice
        if receipt.gasUsed == tx.gas or getattr(receipt, 'status', None) == 0:
            log.error('Transaction failed (hash: %s, tokens: %d, channel: %r)',
                      encode_hex(tx_hash), available_tokens, channel_id)
        else:
            log.info('Transaction success (hash: %s, tokens: %d, channel: %r)',
                     encode_hex(tx_hash), available_tokens, channel_id)
            success += 1
            total_tokens += available_tokens
    log.info(
        'FINISHED Close all channels: total tokens recovered: %d, '
        'transactions succeeded: %d, total gas cost: %s ETH',
        total_tokens,
        success,
        web3.fromWei(total_gas * gas_price, 'ether'),
    )
Exemple #51
0
def test_sign_balance_proof_contract(channel_manager_contract: Contract):
    sig = sign_balance_proof(SENDER_PRIVATE_KEY, RECEIVER_ADDR, 37, 15,
                             channel_manager_contract.address)
    sender_recovered = channel_manager_contract.call(
    ).extractBalanceProofSignature(RECEIVER_ADDR, 37, 15, sig)
    assert is_same_address(sender_recovered, SENDER_ADDR)
Exemple #52
0
def test_sign_close_contract(channel_manager_contract: Contract):
    sig = sign_close(RECEIVER_PRIVATE_KEY, SENDER_ADDR, 315832, 13,
                     channel_manager_contract.address)
    receiver_recovered = channel_manager_contract.call(
    ).extractClosingSignature(SENDER_ADDR, 315832, 13, sig)
    assert is_same_address(receiver_recovered, RECEIVER_ADDR)
Exemple #53
0
def test_change_multisig(chain: TestRPCChain, ico: Contract, customer: str, preico_starts_at, preico_ends_at, team_multisig):
    """Owner can update the multisig address."""

    ico.transact({"from": team_multisig}).setMultisig(customer)
    assert ico.call().multisigWallet() == customer
Exemple #54
0
def load(chain, web3: Web3, address: str, csv_file: str, token: Contract,
         address_column: str, amount_column: str, vault_address: str):

    decimals = token.call().decimals()
    decimal_multiplier = 10**decimals
    transaction = {"from": address}

    TokenVault = chain.contract_factories.TokenVault
    token_vault = TokenVault(address=vault_address)

    # Check that our tokens are the same
    assert token_vault.call().token().lower() == token.address.lower()

    print("Starting to import investor data to ", token_vault.address)

    print("Reading data", csv_file)
    with open(csv_file, "rt") as inp:
        reader = csv.DictReader(inp)
        rows = [row for row in reader]

    # Check that we have unique addresses
    uniq_addresses = set()
    total = 0
    for row in rows:
        addr = row[address_column].strip()
        amount = row[amount_column].strip()
        if addr in uniq_addresses:
            raise RuntimeError("Address appears twice in input data", addr)
        uniq_addresses.add(addr)
        amount = Decimal(amount)
        total += amount
        if amount <= 0:
            raise RuntimeError("Invalid amount:".format(amount))

    if token_vault.call().tokensToBeAllocated() != total * decimal_multiplier:
        raise RuntimeError("Expected total amount {}, CSV sum is {}".format(
            token_vault.call().tokensToBeAllocated(), total))

    # Start distribution
    start_time = time.time()
    start_balance = from_wei(web3.eth.getBalance(address), "ether")

    tx_to_confirm = []  # List of txids to confirm
    tx_batch_size = 16  # How many transactions confirm once

    print("Total rows", len(rows))

    for i in range(len(rows)):
        data = rows[i]
        addr = data[address_column].strip()
        tokens = Decimal(data[amount_column].strip())

        tokens *= decimal_multiplier

        end_balance = from_wei(web3.eth.getBalance(address), "ether")
        spent = start_balance - end_balance

        # http://stackoverflow.com/a/19965088/315168
        if not tokens % 1 == 0:
            raise RuntimeError(
                "Could not issue tokens because after multiplication was not integer"
            )

        tokens = int(tokens)

        print("Row", i, "giving", tokens, "to", addr, "vault",
              token_vault.address, "time passed",
              time.time() - start_time, "ETH spent", spent)

        if token_vault.call().balances(addr) > 0:
            print("Already issued, skipping")
            continue

        txid = token_vault.transact(transaction).setInvestor(addr, tokens)

        tx_to_confirm.append(txid)

        # Confirm N transactions when batch max size is reached
        if len(tx_to_confirm) >= tx_batch_size:
            check_multiple_succesful_txs(web3, tx_to_confirm)
            tx_to_confirm = []

    # Confirm dangling transactions
    check_multiple_succesful_txs(web3, tx_to_confirm)

    end_balance = from_wei(web3.eth.getBalance(address), "ether")
    print("Deployment cost is", start_balance - end_balance, "ETH")