def addLiquidity(w3, account, router_proxy, current_rate): max_tokens = get_token_balance(w3, account, WIZ_TOKEN) approve(w3, account, router_proxy.address, max_tokens.as_wei, WIZ_TOKEN) deadline = generateDeadline(w3) eth_amount = EthereumAmount(0.001) token_amount_desired = TokenAmount(eth_amount.value / current_rate.value, WIZ_TOKEN) transaction_params = { "from": account.address, "value": eth_amount.as_wei, "gas_price": w3.eth.generateGasPrice(), "gas": GAS_LIMIT, } tx_hash = send_raw_transaction( w3, account, router_proxy.functions.addLiquidityETH, WIZ_TOKEN.address, token_amount_desired.as_wei, int(token_amount_desired.as_wei * 0.8), int(eth_amount.as_wei * 0.8), account.address, deadline, **transaction_params, ) wait_for_transaction(w3, tx_hash)
def removeLiquidity(w3, account, router_proxy): pair_address = to_canonical_address(get_pair_address(w3, router_proxy)) liquidity_token = Erc20Token( ticker="UNI-V2", wei_ticker="UNI-V2 WEI", address=pair_address ) amount = get_token_balance(w3, account, liquidity_token) approve(w3, account, router_proxy.address, amount.as_wei, liquidity_token) min_eth = 1 min_tokens = 1 deadline = generateDeadline(w3) transaction_params = { "from": account.address, "gas_price": w3.eth.generateGasPrice(), "gas": GAS_LIMIT, } tx_hash = send_raw_transaction( w3, account, router_proxy.functions.removeLiquidityETH, WIZ_TOKEN.address, amount.as_wei, min_tokens, min_eth, account.address, deadline, **transaction_params, ) wait_for_transaction(w3, tx_hash)
def test_can_mint_tokens(self): self.network.fund(self.account) self.account.wait_for_ethereum_funds(self.w3, EthereumAmount(0.01)) tx_hash = mint_tokens(self.w3, self.account, self.svt_token) wait_for_transaction(self.w3, tx_hash) balance = get_token_balance(self.w3, self.account, self.svt_token) self.assertTrue(balance.as_wei >= self.svt_token.supply)
def approve(w3, account, allowed_address, allowance: Wei, token: Erc20Token): token_proxy = _make_token_proxy(w3=w3, token=token) old_allowance = token_proxy.functions.allowance(account.address, allowed_address).call() if old_allowance > 0: send_raw_transaction( w3, account, token_proxy.functions.approve, allowed_address, 0, gas=GAS_REQUIRED_FOR_APPROVE, ) tx_hash = send_raw_transaction( w3, account, token_proxy.functions.approve, allowed_address, allowance, gas=GAS_REQUIRED_FOR_APPROVE, ) wait_for_transaction(w3, tx_hash)
def approve(w3, account, allowed_address, allowance: Wei, token: Erc20Token): token_proxy = _make_token_proxy(w3=w3, token=token) old_allowance = token_proxy.functions.allowance(account.address, allowed_address).call() nonce = w3.eth.getTransactionCount(account.address) if old_allowance > 0: send_raw_transaction( w3, account, token_proxy.functions.approve, allowed_address, 0, gas=GAS_REQUIRED_FOR_APPROVE, nonce=nonce, ) nonce += 1 transaction_receipt = send_raw_transaction( w3, account, token_proxy.functions.approve, allowed_address, allowance, gas=GAS_REQUIRED_FOR_APPROVE, nonce=nonce, ) wait_for_transaction(w3, transaction_receipt)
def test_buy_tokens(funded_account, provide_liquidity, uniswap): w3 = uniswap.w3 wiz_balance_before = get_token_balance(w3, funded_account, WIZ_TOKEN) buy_amount = TokenAmount(1, WIZ_TOKEN) tx_hash = uniswap.buy_tokens(funded_account, buy_amount) wait_for_transaction(w3, tx_hash) wiz_balance_after = get_token_balance(w3, funded_account, WIZ_TOKEN) assert wiz_balance_after == wiz_balance_before + buy_amount
def test_udc_deposit(self): self.network.fund(self.account) self.account.wait_for_ethereum_funds(self.w3, EthereumAmount(0.01)) tx_hash = mint_tokens(self.w3, self.account, self.svt_token) wait_for_transaction(self.w3, tx_hash) amount = get_token_balance(self.w3, self.account, self.svt_token) tx_hash = deposit_service_tokens(self.w3, self.account, self.svt_token, amount.as_wei) wait_for_transaction(self.w3, tx_hash) deposited = get_token_deposit(self.w3, self.account, self.svt_token) self.assertEqual(deposited, amount)
def provide_liquidity(infura, create_account, uniswap): account = create_account() w3 = make_web3_provider(infura.url, account) fund_account(account, w3) tx_hash = mint_tokens(w3, account, WIZ_TOKEN) wait_for_transaction(w3, tx_hash) current_rate = uniswap.get_current_rate(TokenAmount(1000, WIZ_TOKEN)) router_proxy = w3.eth.contract( abi=uniswap_contracts.UNISWAP_ROUTER02_ABI, address=Uniswap.ROUTER02_ADDRESS, ) addLiquidity(w3, account, router_proxy, current_rate) yield removeLiquidity(w3, account, router_proxy) empty_account(w3, account)
def _deposit_to_udc(self, w3, account, service_token, deposit_amount): self._send_status_update( f"Making deposit of {deposit_amount.formatted} to the " "User Deposit Contract") self._send_status_update(f"This might take a few minutes") tx_hash = deposit_service_tokens( w3=w3, account=account, token=service_token, amount=deposit_amount.as_wei, ) wait_for_transaction(w3, tx_hash) service_token_deposited = get_token_deposit(w3=w3, account=account, token=service_token) self._send_status_update( f"Total amount deposited at UDC: {service_token_deposited.formatted}" )
def _run_track_transaction(self, **kw): try: configuration_file_name = kw.get("configuration_file_name") tx_hash = kw.get("tx_hash") configuration_file = RaidenConfigurationFile.get_by_filename( configuration_file_name) except Exception as exc: self._send_error_message(str(exc)) return configuration_file._initial_funding_txhash = tx_hash configuration_file.save() account = configuration_file.account w3 = make_web3_provider( configuration_file.ethereum_client_rpc_endpoint, account) self._send_txhash_message(["Waiting for confirmation of transaction"], tx_hash=tx_hash) try: wait_for_transaction(w3, decode_hex(tx_hash)) except TransactionTimeoutError: self._send_status_update( [f"Not confirmed after {WEB3_TIMEOUT} seconds!"], icon="error") self._send_txhash_message( "Funding took too long! " "Click the link below and restart the wizard, " "once it was confirmed:", tx_hash=tx_hash, ) time.sleep(10) sys.exit(1) else: configuration_file._initial_funding_txhash = None configuration_file.save() self._send_status_update("Transaction confirmed") service_token = configuration_file.settings.service_token self._send_redirect( self.reverse_url("swap", configuration_file.file_name, service_token.ticker))
def _run_swap(self, **kw): try: configuration_file_name = kw.get("configuration_file_name") exchange_name = kw["exchange"] token_amount = kw["amount"] token_ticker = kw["token"] except (ValueError, KeyError, TypeError) as exc: self._send_error_message(f"Invalid request: {exc}") return try: configuration_file = RaidenConfigurationFile.get_by_filename( configuration_file_name) network_name = configuration_file.network.name form = TokenExchangeForm({ "network": [network_name], "exchange": [exchange_name], "token_amount": [token_amount], "token_ticker": [token_ticker], }) if form.validate(): account = configuration_file.account try_unlock(account) w3 = make_web3_provider( configuration_file.ethereum_client_rpc_endpoint, account) token = Erc20Token.find_by_ticker(form.data["token_ticker"], network_name) token_amount = TokenAmount(Wei(form.data["token_amount"]), token) exchange = Exchange.get_by_name(form.data["exchange"])(w3=w3) self._send_status_update(f"Starting swap at {exchange.name}") costs = exchange.calculate_transaction_costs( token_amount, account) needed_funds = costs["total"] exchange_rate = costs["exchange_rate"] balance_before_swap = account.get_ethereum_balance(w3) if needed_funds > balance_before_swap: raise ValueError(( f"Not enough ETH. {balance_before_swap.formatted} available, but " f"{needed_funds.formatted} needed")) self._send_status_update( (f"Best exchange rate found at {exchange.name}: " f"{exchange_rate} / {token_amount.ticker}")) self._send_status_update( f"Trying to acquire {token_amount} at this rate") transaction_receipt = exchange.buy_tokens( account, token_amount, costs) wait_for_transaction(w3, transaction_receipt) token_balance = get_token_balance(w3, account, token) balance_after_swap = account.get_ethereum_balance(w3) actual_total_costs = balance_before_swap - balance_after_swap self._send_status_update( f"Swap complete. {token_balance.formatted} available") self._send_status_update(f"Actual costs: {actual_total_costs}") required = RequiredAmounts.for_network(network_name) service_token = Erc20Token.find_by_ticker( required.service_token.ticker, network_name) service_token_balance = get_token_balance( w3, account, service_token) total_service_token_balance = get_total_token_owned( w3, account, service_token) transfer_token = Erc20Token.find_by_ticker( required.transfer_token.ticker, network_name) transfer_token_balance = get_token_balance( w3, account, transfer_token) if total_service_token_balance < required.service_token: raise ExchangeError("Exchange was not successful") elif service_token_balance.as_wei > 0: self._send_status_update( f"Making deposit of {service_token_balance.formatted} to the User Deposit Contract" ) self._send_status_update(f"This might take a few minutes") transaction_receipt = deposit_service_tokens( w3=w3, account=account, token=service_token, amount=service_token_balance.as_wei, ) wait_for_transaction(w3, transaction_receipt) service_token_deposited = get_token_deposit( w3=w3, account=account, token=service_token) self._send_status_update( f"Total amount deposited at UDC: {service_token_deposited.formatted}" ) if transfer_token_balance < required.transfer_token: redirect_url = self.reverse_url( "swap", configuration_file.file_name, transfer_token.ticker) next_page = "Moving on to exchanging DAI ..." else: redirect_url = self.reverse_url( "launch", configuration_file.file_name) next_page = "You are ready to launch Raiden! ..." self._send_summary( ["Congratulations! Swap Successful!", next_page], icon=token_ticker) time.sleep(5) self._send_redirect(redirect_url) else: for key, error_list in form.errors.items(): error_message = f"{key}: {'/'.join(error_list)}" self._send_error_message(error_message) except (json.decoder.JSONDecodeError, KeyError, ExchangeError, ValueError) as exc: self._send_error_message(str(exc)) redirect_url = self.reverse_url("swap", configuration_file.file_name, token_ticker) next_page = f"Try again to exchange {token_ticker}..." self._send_summary(["Transaction failed", str(exc), next_page], icon="error") time.sleep(5) self._send_redirect(redirect_url)
def _run_funding(self, **kw): try: configuration_file_name = kw.get("configuration_file_name") configuration_file = RaidenConfigurationFile.get_by_filename( configuration_file_name) except Exception as exc: self._send_error_message(str(exc)) return network = configuration_file.network if not network.FAUCET_AVAILABLE: self._send_error_message( f"Can not run automatic funding for {network.capitalized_name}" ) return account = configuration_file.account try_unlock(account) if account.passphrase is None: self._send_error_message( "Failed to unlock account! Please reload page") return w3 = make_web3_provider( configuration_file.ethereum_client_rpc_endpoint, account) self._send_status_update( f"Obtaining {network.capitalized_name} ETH through faucet") network.fund(account) balance = account.wait_for_ethereum_funds( w3=w3, expected_amount=EthereumAmount(0.01)) self._send_status_update(f"Account funded with {balance.formatted}") service_token = Erc20Token.find_by_ticker( self.installer_settings.service_token.ticker, self.installer_settings.network) if self.installer_settings.service_token.mintable: self._send_next_step( f"Minting {service_token.ticker}", f"Fund Account with {service_token.ticker}", 3, ) tx_hash = mint_tokens(w3, account, service_token) wait_for_transaction(w3, tx_hash) service_token_balance = get_token_balance(w3, account, service_token) if service_token_balance.as_wei > 0: self._deposit_to_udc(w3, account, service_token, service_token_balance) if self.installer_settings.transfer_token.mintable: transfer_token = Erc20Token.find_by_ticker( self.installer_settings.transfer_token.ticker, self.installer_settings.network) self._send_next_step( f"Minting {transfer_token.ticker}", f"Fund Account with {transfer_token.ticker}", 4, ) tx_hash = mint_tokens(w3, account, transfer_token) wait_for_transaction(w3, tx_hash) self._send_redirect(self.reverse_url("launch", configuration_file_name))
def _run_swap(self, **kw): try: configuration_file_name = kw.get("configuration_file_name") exchange_name = kw["exchange"] token_amount = kw["amount"] token_ticker = kw["token"] except (ValueError, KeyError, TypeError) as exc: self._send_error_message(f"Invalid request: {exc}") return try: configuration_file = RaidenConfigurationFile.get_by_filename( configuration_file_name) network_name = configuration_file.network.name form = TokenExchangeForm({ "network": [network_name], "exchange": [exchange_name], "token_amount": [token_amount], "token_ticker": [token_ticker], }) if form.validate(): account = configuration_file.account try_unlock(account) w3 = make_web3_provider( configuration_file.ethereum_client_rpc_endpoint, account) token = Erc20Token.find_by_ticker(form.data["token_ticker"], network_name) token_amount = TokenAmount(Wei(form.data["token_amount"]), token) exchange = Exchange.get_by_name(form.data["exchange"])(w3=w3) self._send_status_update(f"Starting swap at {exchange.name}") costs = exchange.calculate_transaction_costs( token_amount, account) needed_funds = costs["total"] exchange_rate = costs["exchange_rate"] balance_before_swap = account.get_ethereum_balance(w3) if needed_funds > balance_before_swap: raise ValueError(( f"Not enough ETH. {balance_before_swap.formatted} available, but " f"{needed_funds.formatted} needed")) self._send_status_update( (f"Best exchange rate found at {exchange.name}: " f"{exchange_rate} / {token_amount.ticker}")) self._send_status_update( f"Trying to acquire {token_amount} at this rate") tx_hash = exchange.buy_tokens(account, token_amount, costs) wait_for_transaction(w3, tx_hash) token_balance = get_token_balance(w3, account, token) balance_after_swap = account.get_ethereum_balance(w3) actual_total_costs = balance_before_swap - balance_after_swap self._send_status_update( f"Swap complete. {token_balance.formatted} available") self._send_status_update(f"Actual costs: {actual_total_costs}") required = RequiredAmounts.from_settings( self.installer_settings) service_token = Erc20Token.find_by_ticker( required.service_token.ticker, network_name) service_token_balance = get_token_balance( w3, account, service_token) total_service_token_balance = get_total_token_owned( w3, account, service_token) transfer_token = Erc20Token.find_by_ticker( required.transfer_token.ticker, network_name) transfer_token_balance = get_token_balance( w3, account, transfer_token) if total_service_token_balance < required.service_token: raise ExchangeError("Exchange was not successful") elif token_ticker == service_token.ticker and service_token_balance > required.service_token: self._deposit_to_udc(w3, account, service_token, service_token_balance) self._redirect_transfer_swap(configuration_file, transfer_token_balance, required) else: for key, error_list in form.errors.items(): error_message = f"{key}: {'/'.join(error_list)}" self._send_error_message(error_message) except (json.decoder.JSONDecodeError, KeyError, ExchangeError, ValueError) as exc: self._redirect_after_swap_error(exc, configuration_file.file_name, token_ticker)