def transferERCToken(fromAddr, toAddr, amt, key, symbol):
    try:
        w3 = getW3()

        availableBalance = getWalletTokenBalance(fromAddr, symbol)
        if amt > availableBalance:
            return 'Error: Not enough funds.'

        contract_address = getTokenAddress(symbol)
        abi_json = getContractAbiJson('ERC20')
        abi = abi_json
        erc20_token_contract = getContract(w3, abi, contract_address)

        nonce = w3.eth.getTransactionCount(fromAddr)
        amount = convertAmountToWei(symbol, amt)
        transfer_tx = erc20_token_contract.functions.transfer(
            toAddr, int(amount)).buildTransaction({
                'chainId':
                getChainId(),  # 1 for mainnet, 3 for ropsten
                'gas':
                220920,
                'gasPrice':
                w3.toWei(150, 'gwei'),
                'nonce':
                nonce
            })
        signed_txn = w3.eth.account.sign_transaction(transfer_tx, key)
        try:
            tx_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction)
            return w3.toHex(tx_hash)
        except ValueError as err:
            return 'Error: ' + str(err)

    except Exception as ex:
        return 'Error: ' + str(ex)
def approve(userAddress,
            tokenSymbol,
            smartContractAddress,
            amountToApprove,
            key,
            protocol=''):
    try:
        if int(
                amountToApprove
        ) < 1000000000:  #avoid multiple approve charges but up to 1000 USDC
            amountToApprove = 1000000000
        w3 = getW3()
        contract_address = getTokenAddress(tokenSymbol, protocol)
        abi_json = getContractAbiJson('ERC20')
        abi = abi_json
        erc20_contract = getContract(w3, abi, contract_address)
        nonce = w3.eth.getTransactionCount(userAddress)

        appr_tx = erc20_contract.functions.approve(
            Web3.toChecksumAddress(smartContractAddress),
            int(amountToApprove)).buildTransaction({
                'chainId':
                getChainId(),
                'gas':
                2209200,
                'gasPrice':
                w3.toWei(150, 'gwei'),
                'nonce':
                nonce
            })
        signed_tx = w3.eth.account.signTransaction(appr_tx, key)
        tx_hash = w3.eth.sendRawTransaction(signed_tx.rawTransaction)
        return w3.toHex(tx_hash)
    except Exception as ex:
        return str(ex)
def getWalletTokenBalance(addr, erc20Token):
    w3 = getW3()
    contract_address = getTokenAddress(erc20Token)
    abi_json = getContractAbiJson('ERC20')
    abi = abi_json
    erc20_token_contract = getContract(w3, abi, contract_address)

    raw_balance = erc20_token_contract.functions.balanceOf(addr).call()
    return convertAmountFromWei(erc20Token, raw_balance)
def isApproved(userAddress,
               tokenSymbol,
               smartContractAddress,
               amount,
               protocol=''):
    w3 = getW3()
    contract_address = getTokenAddress(tokenSymbol, protocol)
    abi_json = getContractAbiJson('ERC20')
    abi = abi_json
    erc20_contract = getContract(w3, abi, contract_address)

    approved_amount = erc20_contract.functions.allowance(
        userAddress, smartContractAddress).call()
    return approved_amount >= amount
Example #5
0
    def getAmountsOut(self, token_symbol, token_amount):

        # function getAmountsOut(uint amountIn, address[] memory path) internal view returns (uint[] memory amounts)
        userToken = app.config['SYMB']  # token user owns

        amount = convertAmountToWei(userToken, token_amount)

        w3 = getW3()
        abi_json = getContractAbiJson('UNI')
        abi = abi_json['abi']
        uniswap_contract = getContract(w3, abi, self.UNISWAP_CONTRACT_ADDR)

        addressPaths = [Web3.toChecksumAddress(getTokenAddress(userToken, 'UNI')),
                        Web3.toChecksumAddress(getTokenAddress('WETH', 'UNI')),
                        Web3.toChecksumAddress(getTokenAddress(token_symbol, 'UNI'))]

        amountsOut = uniswap_contract.functions.getAmountsOut(
            int(amount), addressPaths).call()

        return convertAmountFromWei(token_symbol, amountsOut[2])
Example #6
0
    def tradeToken(self, token_symbol, token_amount):

        userToken = app.config['SYMB']  # token user owns

        availableBalance = getWalletTokenBalance(self.userWallet.address,
                                                 userToken)
        if (availableBalance < token_amount):
            return "Insuficent amount in your wallet"

        uni_contract_address = self.UNISWAP_CONTRACT_ADDR
        # convert in underlying token balance
        amount = convertAmountToWei(userToken, token_amount)

        if not isApproved(self.userWallet.address, userToken,
                          uni_contract_address, amount, 'UNI'):
            approve(userWall.address, userToken, uni_contract_address, amount,
                    self.userWallet.privateKey, 'UNI')

        w3 = getW3()
        abi_json = getContractAbiJson('UNI')
        abi = abi_json['abi']
        uniswap_contract = getContract(w3, abi, uni_contract_address)
        nonce = w3.eth.getTransactionCount(self.userWallet.address)

        # function swapExactTokensForTokens
        # uint amountIn,
        # uint amountOutMin,
        # address[] calldata path,
        # address to,
        # uint deadline
        # ) external returns (uint[] memory amounts);

        amountOutMin = int(
            amount) * 0.0098  # __convertAmountToWei('DAI', amt/2)
        addressPaths = [
            Web3.toChecksumAddress(getTokenAddress(userToken, 'UNI')),
            Web3.toChecksumAddress(getTokenAddress(token_symbol, 'UNI'))
        ]

        # current_time = datetime.datetime.now(datetime.timezone.utc)
        # unix_timestamp = current_time.timestamp() # works if Python >= 3.3
        # deadline = int(unix_timestamp + (20 * 60)) # 20 minutes
        deadline = int(time.time()) + 10000

        trade_tx = uniswap_contract.functions.swapExactTokensForTokens(
            int(amount), int(amountOutMin), addressPaths,
            self.userWallet.address, deadline).buildTransaction({
                'chainId':
                getChainId(),
                'gas':
                5000000,
                'gasPrice':
                w3.toWei('20', 'gwei'),
                'nonce':
                nonce
            })
        signed_txn = w3.eth.account.sign_transaction(
            trade_tx, self.userWallet.privateKey)
        try:
            tx = w3.eth.sendRawTransaction(signed_txn.rawTransaction)
            # return tx.hex()
            try:
                txn_receipt = w3.eth.waitForTransactionReceipt(tx, timeout=300)
            except Exception:
                return {'status': 'failed', 'error': 'timeout'}
            else:
                return {'status': 'success', 'receipt': txn_receipt}

        except ValueError as err:
            # return (json.loads(str(err).replace("'", '"')), 402, {'Content-Type': 'application/json'})
            return 'Error: ' + str(err)