Ejemplo n.º 1
0
    def get_transaction(cls, tx_hash):
        tx = web3.eth.getTransaction(tx_hash)

        contract_instance = cls.erc20_contracts.get(tx.to, None)
        if contract_instance == None:
            raise Exception('Not supported contract address for swap:%s' %
                            tx.to)

        contract = ConciseContract(contract_instance)
        func, paras = contract_instance.decode_function_input(tx.input)

        if str(func) != '<Function transfer(address,uint256)>':
            raise Exception('Unexpect contract method for %s' % tx_hash)

        if paras['_to'].lower() != config.ETHEREUM_SCAN_ADDRESS.lower():
            raise Exception('Unexpect reveive address for %s' % tx_hash)

        amount, decimals = cls.Wei2Satoshi(paras['_value'],
                                           contract.decimals())
        totalSupply, _ = cls.Wei2Satoshi(contract.totalSupply(),
                                         contract.decimals())
        if totalSupply > 0xFFFFFFFFFFFFFFFF:
            totalSupply = 0xFFFFFFFFFFFFFFFF

        return contract.symbol(), tx['from'], (amount, totalSupply, decimals)
Ejemplo n.º 2
0
    def send_asset(self, contract_name, to_addr, amount, memo=None):
        contract_instance = self.erc20_contracts.get(contract_name, None)
        if contract_instance == None:
            raise Exception('Not supported contract name for swap:%s' %
                            contract_name)

        if not web3.isChecksumAddress(to_addr):
            to_addr = web3.toChecksumAddress(to_addr)
        contract = ConciseContract(contract_instance)

        if not web3.personal.unlockAccount(config.ETHEREUM_SCAN_ADDRESS,
                                           config.ETHEREUM_SCAN_PASSWD):
            raise Exception('Failed to unlcok account:' %
                            config.ETHEREUM_SCAN_ADDRESS)

        amountInWei = self.Satoshi2Wei(amount, contract.decimals())[0]

        gas_price = web3.eth.gasPrice
        transact = contract_instance.functions.transferFrom(
            config.ETHEREUM_SCAN_ADDRESS, to_addr, amountInWei)
        gas = transact.estimateGas()
        ret = transact.transact(
            transaction={
                'from': config.ETHEREUM_SCAN_ADDRESS,
                'gas': gas,
                'gasPrice': gas_price
            })
        if not ret:
            raise Exception('Failed to send_asset:[%s, %s, %s]' %
                            (contract_name, to_addr, amount))
        return ret.hex()
Ejemplo n.º 3
0
def test_factory(w3, exchange_template, HAY_token, factory, pad_bytes32,
                 exchange_abi, assert_fail):
    a0, a1 = w3.eth.accounts[:2]
    # Can't call initializeFactory on factory twice
    with raises(TransactionFailed):
        factory.initializeFactory(HAY_token.address)
    # Factory initial state
    assert factory.exchangeTemplate() == exchange_template.address
    assert factory.getExchange(HAY_token.address) == None
    # Create Exchange for MRS Token
    factory.createExchange(HAY_token.address, transact={})
    HAY_exchange_address = factory.getExchange(HAY_token.address)
    assert HAY_exchange_address != None
    HAY_exchange = ConciseContract(
        w3.eth.contract(address=HAY_exchange_address, abi=exchange_abi))
    assert factory.getToken(HAY_exchange.address) == HAY_token.address
    assert factory.tokenCount() == 1
    assert factory.getTokenWithId(1) == HAY_token.address
    # Exchange already exists
    with raises(TransactionFailed):
        factory.createExchange(HAY_token.address)
    # Can't call setup on exchange
    assert_fail(lambda: HAY_exchange.setup(factory.address))
    # Exchange initial state
    assert HAY_exchange.name() == pad_bytes32('Marswap V1')
    assert HAY_exchange.symbol() == pad_bytes32('MRS-V1')
    assert HAY_exchange.decimals() == 18
    assert HAY_exchange.totalSupply() == 0
    assert HAY_exchange.tokenAddress() == HAY_token.address
    assert HAY_exchange.factoryAddress() == factory.address
    assert w3.eth.getBalance(HAY_exchange.address) == 0
    assert HAY_token.balanceOf(HAY_exchange.address) == 0
Ejemplo n.º 4
0
def test_factory(w3, exchange_template, HAY_token, exchange_factory, pad_bytes32, exchange_abi):
    a0, a1 = w3.eth.accounts[:2]
    # Factory initial state
    assert exchange_factory.exchangeTemplate() == exchange_template.address
    assert exchange_factory.getExchange(HAY_token.address) == None
    # Create Exchange for UNI Token
    exchange_factory.createExchange(HAY_token.address, transact={})
    HAY_exchange_address = exchange_factory.getExchange(HAY_token.address)
    assert HAY_exchange_address != None
    HAY_exchange = ConciseContract(w3.eth.contract(address=HAY_exchange_address, abi=exchange_abi))
    assert exchange_factory.getToken(HAY_exchange.address) == HAY_token.address
    assert exchange_factory.tokenCount() == 1
    assert exchange_factory.getTokenWithId(1) == HAY_token.address
    # # Can't call initializeFactory on factory twice
    # assert_tx_failed(lambda: exchange_factory.initializeFactory(HAY_token.address))
    # # Exchange already exists
    # assert_tx_failed(lambda: exchange_factory.createExchange(HAY_token.address))
    # # Can't call setup on exchange
    # assert_tx_failed(lambda: HAY_exchange.setup(exchange_factory.address))
    # # Exchange initial state
    assert HAY_exchange.name() == pad_bytes32('Uniswap V1')
    assert HAY_exchange.symbol() == pad_bytes32('UNI-V1')
    assert HAY_exchange.decimals() == 18
    assert HAY_exchange.totalSupply() == 0
    assert HAY_exchange.tokenAddress() == HAY_token.address
    assert HAY_exchange.factoryAddress() == exchange_factory.address
    assert w3.eth.getBalance(HAY_exchange.address) == 0
    assert HAY_token.balanceOf(HAY_exchange.address) == 0
Ejemplo n.º 5
0
 def get_asset_balance(cls, contract_name):
     contract = cls.erc20_contracts.get(contract_name, None)
     if contract == None:
         raise Exception('Not supported contract name for swap:%s' %
                         contract_name)
     concise = ConciseContract(contract)
     return cls.Wei2Satoshi(concise.balanceOf(config.ETHEREUM_SCAN_ADDRESS),
                            concise.decimals())[0]
Ejemplo n.º 6
0
 def get_token_precision(self, token_address):
     token_contract = ConciseContract(
         self.network.web3.eth.contract(
             address=Web3.toChecksumAddress(token_address),
             abi=ERC20_BASIC_ABI,
         )
     )
     time.sleep(0.5)  # we don't want to spam the API
     try:
         return token_contract.decimals()
     except (OverflowError, BadFunctionCallOutput):
         return
Ejemplo n.º 7
0
 def get_token_from_token_contract(self, token_address: str) -> Optional[Token]:
     """ Getting information from token contract and creating Token.
         Smart contract is taken based on provided address """
     token_address = self.unify_address(token_address)
     token_contract = self.web3.eth.contract(address=token_address, abi=ERC20_BASIC_ABI)
     concise = ConciseContract(token_contract)
     try:
         name = concise.name()
         symbol = concise.symbol()
         decimals = concise.decimals()
         logger.debug(f'Token get from contract with success')
     except (OverflowError, BadFunctionCallOutput):
         logger.warning(f'Unable to take token from address: {token_address}')
         return
     return Token(name, symbol, token_address, decimals)
Ejemplo n.º 8
0
    def get_token_from_token_contract(self,
                                      token_address: str) -> Optional[Token]:
        '''
        Getting information from token contract (remote)

        Args:
            token_address (str): address of the token contract

        Returns:
            Token, None: Ethereum Token namedtuple or None if there is something goes wrong

        Raises:
            RuntimeError: if name or symbol of the token is not defined.

        Example:
            >>> from clove.network import EthereumTestnet
            >>> network = EthereumTestnet()
            >>> network.get_token_from_token_contract('0x2c76B98079Bb5520FF4BDBC1bf5012AC3E87ddF6')
            Token(name='PrettyGoodToken', symbol='PGT', address='0x2c76B98079Bb5520FF4BDBC1bf5012AC3E87ddF6', decimals=18)  # noqa: E501
        '''
        token_address = self.unify_address(token_address)
        token_contract = self.web3.eth.contract(address=token_address,
                                                abi=ERC20_BASIC_ABI)
        concise = ConciseContract(token_contract)
        try:
            name = concise.name()
            symbol = concise.symbol()
            decimals = concise.decimals()
            if name == '' or symbol == '':
                raise RuntimeError(
                    'Unable to extract token details from token contract')
            logger.debug(f'Token get from contract with success')
        except (OverflowError, BadFunctionCallOutput):
            logger.warning(
                f'Unable to take token from address: {token_address}')
            return
        return Token(name, symbol, token_address, decimals)
Ejemplo n.º 9
0
def test_deploy(
        pack_deploy,
        instantiate,
        accounts,
        assert_tx_failed,
        pack_types,
        pack_prices,
        get_receipt,
        get_logs_for_event,
        w3,
        #Parameters
        bundle_sizes,
        bundle_caps):

    BLOCK_GAS_LIMIT = 8e6  # Well over double this now, but a possible concern.

    # Deploy an oracle and a Link Token
    (pack, processor, referrals, cards, vault, pack_r, processor_r, referrals_r, cards_r, vault_r) = pack_deploy()

    receipts = {
        "pack": (pack, pack_r),
        "processor": (processor, processor_r),
        "referrals": (referrals, referrals_r),
        "cards": (cards, cards_r),
        "vault": (vault, vault_r)
    }

    if DEBUG:
        print("")  # new line
    for name, r in receipts.items():
        if DEBUG:
            print("Gas used to deploy {}:\t{}".format(name, r[1]['gasUsed']))
        assert r[1]['gasUsed'] < BLOCK_GAS_LIMIT, "{} uses more gas than block_gas_limit!".format(name)
        assert r[0].address != 0, "Address returned not expected for {}".format(name)

    addPack = cards.functions.addPack(pack.address)
    assert_tx_failed(addPack, {'from': accounts[1]})
    addPack.transact({'from': accounts[0]})

    tokens = {}


    # Now each of the bundle tokens need to be deployed
    # For each, the pack has to be set to point to the bundle and stipulate it's price and size.
    for i, (rarity, rarity_value) in enumerate(pack_types.items()):

        setPack = pack.functions.setPack(
            rarity_value,
            pack_prices[rarity],
            "Genesis {} Bundle".format(rarity),
            "BND{}".format(rarity[0]),
            bundle_sizes[i],
            bundle_caps[i],
        )
        assert_tx_failed(setPack, {'from': accounts[1]})
        tx_hash = setPack.transact({'from': accounts[0]})
        rcpt = get_receipt(tx_hash)

        assert len(rcpt['logs']) == 1, "Should have one event emitted."
        assert rcpt['gasUsed'] < BLOCK_GAS_LIMIT, "Too much gas for block!"

        logs = get_logs_for_event(pack.events.PackAdded, tx_hash)

        tokens[rarity] = instantiate(logs[0]['args']['bundle'], abi=None, contract="Bundle")
        processor.functions.setCanSell(tokens[rarity].address, True).transact({'from': accounts[0]})

        if DEBUG:
            print("Created {} Bundles: Size: {}, Cap: {}, Gas: {}".format(
                rarity,
                bundle_sizes[i],
                bundle_caps[i],
                rcpt['gasUsed'])
            )

    print("Approval Statuses:")
    for address in accounts[:5]:
        print("{}: {}".format(address, processor.functions.approvedSellers(accounts[0]).call()))

    # For each of the tokens, check their variables and try to purchase a bunch of them,
    # making sure we can't purchase too many
    for i, (rarity, token) in enumerate(tokens.items()):
        c = ConciseContract(token)
        assert c.totalSupply() == 0, "{} tokens should start with supply of zero".format(rarity)
        assert c.balanceOf(accounts[0]) == 0, "No user should have balance before mint."
        assert c.balanceOf(accounts[1]) == 0, "No user should have balance before mint."
        assert c.name() == "Genesis {} Bundle".format(rarity), "Incorrect token name"
        assert c.symbol() == "BND{}".format(rarity[0]), "Incorrect token symbol"
        assert c.decimals() == 0, "Incorrect token decimals"
        assert c.cap() == bundle_caps[i], "Incorrect cap for token"
        assert c.packType() == pack_types[rarity], "Incorrect packType for token"

        BUNDLES_TO_BUY = 6

        for _ in range(bundle_caps[i] if bundle_caps[i] > 0 else BUNDLES_TO_BUY):
            # Shouldn't be able to buy if we send no money
            assert_tx_failed(
                token.functions.purchaseFor(accounts[0], 1, accounts[1]),
                {'from': accounts[0]}
            )
            assert processor.functions.approvedSellers(token.address).call(), "Bundle should be approved to sell."
            tx_hash = token.functions.purchaseFor(accounts[0], 1, accounts[1])\
                .transact({'from': accounts[0], 'value': pack_prices[rarity] * bundle_sizes[i]})
            rcpt = get_receipt(tx_hash)
            assert rcpt['gasUsed'] < BLOCK_GAS_LIMIT, "Too much gas for block!"
            if DEBUG:
                print("Account0 {} tokens: {}, vault: {} ({})".format(
                    rarity,
                    token.functions.balanceOf(accounts[0]).call(),
                    (vault.functions.total().call())/10**18,
                    w3.eth.getBalance(vault.address)/10**18))

        # Now there shouldn't be any more bundles available to buy
        if bundle_caps[i] > 0:
            assert_tx_failed(
                token.functions.purchaseFor(accounts[0], 1, accounts[1]),
                {'from': accounts[0]}
            )