From ead9ca168db2805b05fef318d7571920c87e034d Mon Sep 17 00:00:00 2001 From: Cesar Date: Thu, 18 Apr 2024 17:13:14 +0200 Subject: [PATCH 1/7] chore: gnosis chain works as expected --- autotx/cli.py | 6 ++++-- autotx/tests/integration/test_swap.py | 18 +++++++++++++++++- .../helpers/fill_dev_account_with_erc20.py | 11 ++++++----- autotx/utils/ethereum/helpers/swap_from_eoa.py | 6 +++--- autotx/utils/ethereum/lifi/swap.py | 3 ++- autotx/utils/ethereum/networks.py | 3 +++ 6 files changed, 35 insertions(+), 12 deletions(-) diff --git a/autotx/cli.py b/autotx/cli.py index ece9a5de..8e5eefd2 100644 --- a/autotx/cli.py +++ b/autotx/cli.py @@ -15,7 +15,7 @@ from autotx.agents.SwapTokensAgent import SwapTokensAgent from autotx.utils.constants import COINGECKO_API_KEY, OPENAI_API_KEY, OPENAI_MODEL_NAME -from autotx.utils.ethereum.networks import NetworkInfo +from autotx.utils.ethereum.networks import ChainId, NetworkInfo from autotx.utils.ethereum.helpers.get_dev_account import get_dev_account from autotx.AutoTx import AutoTx, Config from autotx.utils.ethereum.agent_account import get_or_create_agent_account @@ -92,7 +92,9 @@ def run(prompt: str | None, non_interactive: bool, verbose: bool, logs: str | No print(f"Smart account deployed: {manager.address}") if not is_safe_deployed: - send_native(dev_account, manager.address, 10, web3) + # XDAI or MATIC doesn't have the same value as ETH, so we need to fill more + amount_to_fill = 3000 if network_info.chain_id in [ChainId.POLYGON, ChainId.GNOSIS] else 10 + send_native(dev_account, manager.address, amount_to_fill, web3) fill_dev_account_with_erc20(client, dev_account, manager.address, network_info) print(f"Funds sent to smart account for testing purposes") diff --git a/autotx/tests/integration/test_swap.py b/autotx/tests/integration/test_swap.py index ca97624d..68e4c07c 100644 --- a/autotx/tests/integration/test_swap.py +++ b/autotx/tests/integration/test_swap.py @@ -1,5 +1,6 @@ from decimal import Decimal from autotx.utils.ethereum.eth_address import ETHAddress +from autotx.utils.ethereum.helpers.swap_from_eoa import swap from autotx.utils.ethereum.lifi.swap import build_swap_transaction from autotx.utils.ethereum.networks import NetworkInfo @@ -134,7 +135,7 @@ def test_swap_multiple_tokens(configuration): (_, _, client, manager) = configuration network_info = NetworkInfo(client.w3.eth.chain_id) - eth_address = ETHAddress(network_info.tokens["eth"]) + eth_address = ETHAddress(network_info.tokens["xdai"]) usdc_address = ETHAddress(network_info.tokens["usdc"]) wbtc_address = ETHAddress(network_info.tokens["wbtc"]) shib_address = ETHAddress(network_info.tokens["shib"]) @@ -142,6 +143,7 @@ def test_swap_multiple_tokens(configuration): usdc_balance = manager.balance_of(usdc_address) assert usdc_balance == 0 + sell_eth_for_usdc_transaction = build_swap_transaction( client, 1, @@ -195,3 +197,17 @@ def test_swap_multiple_tokens(configuration): shib_balance = manager.balance_of(shib_address) shib_balance = manager.balance_of(shib_address) assert shib_balance > 0 + + +# def test_swap_through_eoa(configuration): +# (user, _, client, _) = configuration +# network_info = NetworkInfo(client.w3.eth.chain_id) +# gno_address = ETHAddress(network_info.tokens["gno"]) +# swap( +# client, +# user, +# 3, +# ETHAddress(NATIVE_TOKEN_ADDRESS), +# gno_address, +# network_info.chain_id +# ) \ No newline at end of file diff --git a/autotx/utils/ethereum/helpers/fill_dev_account_with_erc20.py b/autotx/utils/ethereum/helpers/fill_dev_account_with_erc20.py index 27336727..456beb76 100644 --- a/autotx/utils/ethereum/helpers/fill_dev_account_with_erc20.py +++ b/autotx/utils/ethereum/helpers/fill_dev_account_with_erc20.py @@ -2,7 +2,7 @@ from autotx.utils.ethereum.constants import NATIVE_TOKEN_ADDRESS from autotx.utils.ethereum.eth_address import ETHAddress from autotx.utils.ethereum.helpers.swap_from_eoa import swap -from autotx.utils.ethereum.networks import NetworkInfo +from autotx.utils.ethereum.networks import ChainId, NetworkInfo from eth_account.signers.local import LocalAccount from gnosis.eth import EthereumClient @@ -14,6 +14,9 @@ def fill_dev_account_with_erc20( network_info: NetworkInfo, ) -> None: tokens_to_transfer = {"usdc": 3500, "dai": 3500, "wbtc": 0.1} + if network_info.chain_id is ChainId.GNOSIS: + tokens_to_transfer = {"usdc": 2000, "gno": 5, "cow": 4000 } + native_token_address = ETHAddress(NATIVE_TOKEN_ADDRESS) for token in network_info.tokens: if token in tokens_to_transfer: @@ -25,8 +28,6 @@ def fill_dev_account_with_erc20( amount, native_token_address, token_address, - network_info.chain_id - ) - transfer_erc20( - client.w3, token_address, dev_account, safe_address, amount + network_info.chain_id, ) + transfer_erc20(client.w3, token_address, dev_account, safe_address, amount) diff --git a/autotx/utils/ethereum/helpers/swap_from_eoa.py b/autotx/utils/ethereum/helpers/swap_from_eoa.py index cbc9c1c1..ea0953b9 100644 --- a/autotx/utils/ethereum/helpers/swap_from_eoa.py +++ b/autotx/utils/ethereum/helpers/swap_from_eoa.py @@ -28,7 +28,8 @@ def swap( transaction = user.sign_transaction( # type: ignore { **tx.tx, - "nonce": client.w3.eth.get_transaction_count(user.address) + "nonce": client.w3.eth.get_transaction_count(user.address), + "gas": 1500000 } ) @@ -37,5 +38,4 @@ def swap( receipt = client.w3.eth.wait_for_transaction_receipt(hash) if receipt["status"] == 0: - print(f"Transaction #{i} failed ") - break + raise Exception(f"Transaction to swap {from_token.hex} to {amount} {to_token.hex} failed") diff --git a/autotx/utils/ethereum/lifi/swap.py b/autotx/utils/ethereum/lifi/swap.py index a67dfdfb..43c0842d 100644 --- a/autotx/utils/ethereum/lifi/swap.py +++ b/autotx/utils/ethereum/lifi/swap.py @@ -87,9 +87,10 @@ def get_quote( "to": quote["transactionRequest"]["to"], "from": quote["transactionRequest"]["from"], "data": quote["transactionRequest"]["data"], - "gasPrice": quote["transactionRequest"]["gasPrice"], + "data": quote["transactionRequest"]["gasPrice"], "gas": quote["transactionRequest"]["gasLimit"], "value": Wei(int(quote["transactionRequest"]["value"], 0)), + "chainId": quote["transactionRequest"]["chainId"] } ) return QuoteInformation( diff --git a/autotx/utils/ethereum/networks.py b/autotx/utils/ethereum/networks.py index e2769556..ac5fceb8 100644 --- a/autotx/utils/ethereum/networks.py +++ b/autotx/utils/ethereum/networks.py @@ -113,6 +113,9 @@ class NetworkConfiguration: { "xdai": NATIVE_TOKEN_ADDRESS, "wxdai": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", + "usdc": "0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83", + "cow": "0x177127622c4A00F3d409B75571e12cB3c8973d3c", + "gno": "0x9C58BAcC331c9aa871AFD802DB6379a98e80CEdb" }, ), } From eed7484a6c58757dca29769cd69dc0659d3f61ba Mon Sep 17 00:00:00 2001 From: Cesar Date: Mon, 22 Apr 2024 17:09:05 +0200 Subject: [PATCH 2/7] chore: polygon swap works --- autotx/tests/integration/test_swap.py | 14 -------------- .../helpers/fill_dev_account_with_erc20.py | 2 ++ autotx/utils/ethereum/helpers/swap_from_eoa.py | 7 ++++--- autotx/utils/ethereum/lifi/swap.py | 1 + autotx/utils/ethereum/networks.py | 1 + 5 files changed, 8 insertions(+), 17 deletions(-) diff --git a/autotx/tests/integration/test_swap.py b/autotx/tests/integration/test_swap.py index 68e4c07c..5a19d564 100644 --- a/autotx/tests/integration/test_swap.py +++ b/autotx/tests/integration/test_swap.py @@ -197,17 +197,3 @@ def test_swap_multiple_tokens(configuration): shib_balance = manager.balance_of(shib_address) shib_balance = manager.balance_of(shib_address) assert shib_balance > 0 - - -# def test_swap_through_eoa(configuration): -# (user, _, client, _) = configuration -# network_info = NetworkInfo(client.w3.eth.chain_id) -# gno_address = ETHAddress(network_info.tokens["gno"]) -# swap( -# client, -# user, -# 3, -# ETHAddress(NATIVE_TOKEN_ADDRESS), -# gno_address, -# network_info.chain_id -# ) \ No newline at end of file diff --git a/autotx/utils/ethereum/helpers/fill_dev_account_with_erc20.py b/autotx/utils/ethereum/helpers/fill_dev_account_with_erc20.py index 456beb76..c799712f 100644 --- a/autotx/utils/ethereum/helpers/fill_dev_account_with_erc20.py +++ b/autotx/utils/ethereum/helpers/fill_dev_account_with_erc20.py @@ -16,6 +16,8 @@ def fill_dev_account_with_erc20( tokens_to_transfer = {"usdc": 3500, "dai": 3500, "wbtc": 0.1} if network_info.chain_id is ChainId.GNOSIS: tokens_to_transfer = {"usdc": 2000, "gno": 5, "cow": 4000 } + if network_info.chain_id is ChainId.POLYGON: + tokens_to_transfer = {"usdc": 2000, "wbtc": 0.01, "dai": 2000 } native_token_address = ETHAddress(NATIVE_TOKEN_ADDRESS) for token in network_info.tokens: diff --git a/autotx/utils/ethereum/helpers/swap_from_eoa.py b/autotx/utils/ethereum/helpers/swap_from_eoa.py index ea0953b9..77e732e9 100644 --- a/autotx/utils/ethereum/helpers/swap_from_eoa.py +++ b/autotx/utils/ethereum/helpers/swap_from_eoa.py @@ -16,7 +16,7 @@ def swap( ) -> None: txs = build_swap_transaction( client, - Decimal(amount), + Decimal(str(amount)), from_token, to_token, ETHAddress(user.address), @@ -24,12 +24,13 @@ def swap( chain ) - for i, tx in enumerate(txs): + for tx in txs: + gas = 1500000 if chain is ChainId.GNOSIS else int(tx.tx["gas"], 0) transaction = user.sign_transaction( # type: ignore { **tx.tx, "nonce": client.w3.eth.get_transaction_count(user.address), - "gas": 1500000 + "gas": gas } ) diff --git a/autotx/utils/ethereum/lifi/swap.py b/autotx/utils/ethereum/lifi/swap.py index 43c0842d..43410d01 100644 --- a/autotx/utils/ethereum/lifi/swap.py +++ b/autotx/utils/ethereum/lifi/swap.py @@ -89,6 +89,7 @@ def get_quote( "data": quote["transactionRequest"]["data"], "data": quote["transactionRequest"]["gasPrice"], "gas": quote["transactionRequest"]["gasLimit"], + "gasPrice": quote["transactionRequest"]["gasPrice"], "value": Wei(int(quote["transactionRequest"]["value"], 0)), "chainId": quote["transactionRequest"]["chainId"] } diff --git a/autotx/utils/ethereum/networks.py b/autotx/utils/ethereum/networks.py index ac5fceb8..01e0c3b0 100644 --- a/autotx/utils/ethereum/networks.py +++ b/autotx/utils/ethereum/networks.py @@ -80,6 +80,7 @@ class NetworkConfiguration: "usdc": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359", "dai": "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063", "usdt": "0xc2132d05d31c914a87c6611c10748aeb04b58e8f", + "wbtc": "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6" }, ), ChainId.BASE_MAINNET: NetworkConfiguration( From e0a2b1aca4e2fd52e28900f2b2e8adf53e4c2f45 Mon Sep 17 00:00:00 2001 From: Cesar Date: Tue, 23 Apr 2024 22:30:58 +0200 Subject: [PATCH 3/7] chore: filter token that are not addreses in token list --- autotx/utils/ethereum/lifi/__init__.py | 2 +- autotx/utils/ethereum/lifi/swap.py | 3 +-- autotx/utils/ethereum/networks.py | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/autotx/utils/ethereum/lifi/__init__.py b/autotx/utils/ethereum/lifi/__init__.py index 5db67b59..6a490f12 100644 --- a/autotx/utils/ethereum/lifi/__init__.py +++ b/autotx/utils/ethereum/lifi/__init__.py @@ -48,7 +48,7 @@ def get_quote_to_amount( # type: ignore _from: ETHAddress, chain: ChainId, slippage: float, - ) -> dict[str, Any]: + ) -> dict[str, Any]: params: dict[str, Any] = { "fromToken": from_token.hex, "toToken": to_token.hex, diff --git a/autotx/utils/ethereum/lifi/swap.py b/autotx/utils/ethereum/lifi/swap.py index 43410d01..b46a0946 100644 --- a/autotx/utils/ethereum/lifi/swap.py +++ b/autotx/utils/ethereum/lifi/swap.py @@ -87,9 +87,8 @@ def get_quote( "to": quote["transactionRequest"]["to"], "from": quote["transactionRequest"]["from"], "data": quote["transactionRequest"]["data"], - "data": quote["transactionRequest"]["gasPrice"], - "gas": quote["transactionRequest"]["gasLimit"], "gasPrice": quote["transactionRequest"]["gasPrice"], + "gas": quote["transactionRequest"]["gasLimit"], "value": Wei(int(quote["transactionRequest"]["value"], 0)), "chainId": quote["transactionRequest"]["chainId"] } diff --git a/autotx/utils/ethereum/networks.py b/autotx/utils/ethereum/networks.py index 01e0c3b0..20623ddb 100644 --- a/autotx/utils/ethereum/networks.py +++ b/autotx/utils/ethereum/networks.py @@ -32,7 +32,7 @@ def fetch_tokens_for_chain(self, chain_id: int) -> dict[str, str]: return { cast(str, token["symbol"]).lower(): Web3.to_checksum_address(cast(str, token["address"])) for token in token_list - if token["chainId"] == chain_id + if token["chainId"] == chain_id and Web3.is_checksum_address(cast(str, token["address"])) } From 1e2c690f3cc260b52fa64ebcd1b681ddef6f6c7f Mon Sep 17 00:00:00 2001 From: Cesar Date: Wed, 24 Apr 2024 12:34:54 +0200 Subject: [PATCH 4/7] chore: fix build --- autotx/utils/ethereum/helpers/swap_from_eoa.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autotx/utils/ethereum/helpers/swap_from_eoa.py b/autotx/utils/ethereum/helpers/swap_from_eoa.py index 77e732e9..0c57980f 100644 --- a/autotx/utils/ethereum/helpers/swap_from_eoa.py +++ b/autotx/utils/ethereum/helpers/swap_from_eoa.py @@ -25,7 +25,7 @@ def swap( ) for tx in txs: - gas = 1500000 if chain is ChainId.GNOSIS else int(tx.tx["gas"], 0) + gas = 1500000 if chain is ChainId.GNOSIS else tx.tx["gas"] transaction = user.sign_transaction( # type: ignore { **tx.tx, From d8d6e83899b724b896d5b905b6d3625aeede826b Mon Sep 17 00:00:00 2001 From: Cesar Date: Wed, 24 Apr 2024 14:02:32 +0200 Subject: [PATCH 5/7] chore: estimate gas manually in `swap_from_eoa` in gnosis and base --- autotx/utils/ethereum/helpers/swap_from_eoa.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/autotx/utils/ethereum/helpers/swap_from_eoa.py b/autotx/utils/ethereum/helpers/swap_from_eoa.py index 0c57980f..595f899b 100644 --- a/autotx/utils/ethereum/helpers/swap_from_eoa.py +++ b/autotx/utils/ethereum/helpers/swap_from_eoa.py @@ -1,4 +1,5 @@ from decimal import Decimal +import json from autotx.utils.ethereum.eth_address import ETHAddress from eth_account.signers.local import LocalAccount from gnosis.eth import EthereumClient @@ -25,12 +26,15 @@ def swap( ) for tx in txs: - gas = 1500000 if chain is ChainId.GNOSIS else tx.tx["gas"] + if chain in [ChainId.GNOSIS, ChainId.BASE_MAINNET]: + del tx.tx["gas"] + gas = client.w3.eth.estimate_gas(tx.tx) + tx.tx.update({"gas": gas}) + transaction = user.sign_transaction( # type: ignore { **tx.tx, "nonce": client.w3.eth.get_transaction_count(user.address), - "gas": gas } ) @@ -39,4 +43,4 @@ def swap( receipt = client.w3.eth.wait_for_transaction_receipt(hash) if receipt["status"] == 0: - raise Exception(f"Transaction to swap {from_token.hex} to {amount} {to_token.hex} failed") + print(f"Transaction to swap {from_token.hex} to {amount} {to_token.hex} failed") From 3d1882cf8beaa74be1d64b2fb9df292c9bd31bcd Mon Sep 17 00:00:00 2001 From: Cesar Date: Thu, 25 Apr 2024 14:38:43 +0200 Subject: [PATCH 6/7] chore: move `send_native` to `fill_dev_account_with_tokens` --- autotx/cli.py | 7 ++----- autotx/tests/integration/test_swap.py | 4 +--- ...ount_with_erc20.py => fill_dev_account_with_tokens.py} | 8 +++++++- 3 files changed, 10 insertions(+), 9 deletions(-) rename autotx/utils/ethereum/helpers/{fill_dev_account_with_erc20.py => fill_dev_account_with_tokens.py} (80%) diff --git a/autotx/cli.py b/autotx/cli.py index 8e5eefd2..1ec247cd 100644 --- a/autotx/cli.py +++ b/autotx/cli.py @@ -5,7 +5,7 @@ import os from autotx.utils.ethereum.cached_safe_address import get_cached_safe_address -from autotx.utils.ethereum.helpers.fill_dev_account_with_erc20 import fill_dev_account_with_erc20 +from autotx.utils.ethereum.helpers.fill_dev_account_with_tokens import fill_dev_account_with_tokens from autotx.utils.is_dev_env import is_dev_env load_dotenv() @@ -92,10 +92,7 @@ def run(prompt: str | None, non_interactive: bool, verbose: bool, logs: str | No print(f"Smart account deployed: {manager.address}") if not is_safe_deployed: - # XDAI or MATIC doesn't have the same value as ETH, so we need to fill more - amount_to_fill = 3000 if network_info.chain_id in [ChainId.POLYGON, ChainId.GNOSIS] else 10 - send_native(dev_account, manager.address, amount_to_fill, web3) - fill_dev_account_with_erc20(client, dev_account, manager.address, network_info) + fill_dev_account_with_tokens(client, dev_account, manager.address, network_info) print(f"Funds sent to smart account for testing purposes") print("=" * 50) diff --git a/autotx/tests/integration/test_swap.py b/autotx/tests/integration/test_swap.py index 5a19d564..ca97624d 100644 --- a/autotx/tests/integration/test_swap.py +++ b/autotx/tests/integration/test_swap.py @@ -1,6 +1,5 @@ from decimal import Decimal from autotx.utils.ethereum.eth_address import ETHAddress -from autotx.utils.ethereum.helpers.swap_from_eoa import swap from autotx.utils.ethereum.lifi.swap import build_swap_transaction from autotx.utils.ethereum.networks import NetworkInfo @@ -135,7 +134,7 @@ def test_swap_multiple_tokens(configuration): (_, _, client, manager) = configuration network_info = NetworkInfo(client.w3.eth.chain_id) - eth_address = ETHAddress(network_info.tokens["xdai"]) + eth_address = ETHAddress(network_info.tokens["eth"]) usdc_address = ETHAddress(network_info.tokens["usdc"]) wbtc_address = ETHAddress(network_info.tokens["wbtc"]) shib_address = ETHAddress(network_info.tokens["shib"]) @@ -143,7 +142,6 @@ def test_swap_multiple_tokens(configuration): usdc_balance = manager.balance_of(usdc_address) assert usdc_balance == 0 - sell_eth_for_usdc_transaction = build_swap_transaction( client, 1, diff --git a/autotx/utils/ethereum/helpers/fill_dev_account_with_erc20.py b/autotx/utils/ethereum/helpers/fill_dev_account_with_tokens.py similarity index 80% rename from autotx/utils/ethereum/helpers/fill_dev_account_with_erc20.py rename to autotx/utils/ethereum/helpers/fill_dev_account_with_tokens.py index c799712f..0ff8b49a 100644 --- a/autotx/utils/ethereum/helpers/fill_dev_account_with_erc20.py +++ b/autotx/utils/ethereum/helpers/fill_dev_account_with_tokens.py @@ -6,13 +6,19 @@ from eth_account.signers.local import LocalAccount from gnosis.eth import EthereumClient +from autotx.utils.ethereum.send_native import send_native -def fill_dev_account_with_erc20( + +def fill_dev_account_with_tokens( client: EthereumClient, dev_account: LocalAccount, safe_address: ETHAddress, network_info: NetworkInfo, ) -> None: + # XDAI or MATIC doesn't have the same value as ETH, so we need to fill more + amount_to_fill = 3000 if network_info.chain_id in [ChainId.POLYGON, ChainId.GNOSIS] else 10 + send_native(dev_account, safe_address, amount_to_fill, client.w3) + tokens_to_transfer = {"usdc": 3500, "dai": 3500, "wbtc": 0.1} if network_info.chain_id is ChainId.GNOSIS: tokens_to_transfer = {"usdc": 2000, "gno": 5, "cow": 4000 } From 37eef54c9b3ab6c187276b351ec29f16fbbb6522 Mon Sep 17 00:00:00 2001 From: Cesar Date: Thu, 25 Apr 2024 16:43:11 +0200 Subject: [PATCH 7/7] chore: estimate gas in `swap_from_eoa` for all chains --- autotx/utils/ethereum/helpers/swap_from_eoa.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/autotx/utils/ethereum/helpers/swap_from_eoa.py b/autotx/utils/ethereum/helpers/swap_from_eoa.py index 595f899b..78ff309a 100644 --- a/autotx/utils/ethereum/helpers/swap_from_eoa.py +++ b/autotx/utils/ethereum/helpers/swap_from_eoa.py @@ -26,10 +26,9 @@ def swap( ) for tx in txs: - if chain in [ChainId.GNOSIS, ChainId.BASE_MAINNET]: - del tx.tx["gas"] - gas = client.w3.eth.estimate_gas(tx.tx) - tx.tx.update({"gas": gas}) + del tx.tx["gas"] + gas = client.w3.eth.estimate_gas(tx.tx) + tx.tx.update({"gas": gas}) transaction = user.sign_transaction( # type: ignore {