diff --git a/eth_defi/abi/uniswap-swap-contracts/README.md b/eth_defi/abi/uniswap-swap-contracts/README.md index a0f7d825..aaafc53a 100644 --- a/eth_defi/abi/uniswap-swap-contracts/README.md +++ b/eth_defi/abi/uniswap-swap-contracts/README.md @@ -1,2 +1,5 @@ Added here so that SwapRouter02 can be deployed on Base. +See + +- https://github.com/tradingstrategy-ai/swap-router-contracts \ No newline at end of file diff --git a/eth_defi/uniswap_v3/swap_router_02.py b/eth_defi/uniswap_v3/swap_router_02.py deleted file mode 100644 index 28e0fcc6..00000000 --- a/eth_defi/uniswap_v3/swap_router_02.py +++ /dev/null @@ -1,30 +0,0 @@ -"""Uniswap legacy compatibility SwapRouter02""" -import os - -from eth_defi.provider.multi_provider import create_multi_provider_web3 -from eth_defi.uniswap_v2.constants import UNISWAP_V2_DEPLOYMENTS -from eth_defi.uniswap_v3.constants import UNISWAP_V3_DEPLOYMENTS -from eth_defi.uniswap_v3.deployment import fetch_deployment - -JSON_RPC_BASE = os.environ["JSON_RPC_BASE"] - - -def deploy_swap_router_02(): - """Deploy SwapRouter02 on base. - - - Because Uniswap did not do it themselves - - - Allows us to run the legacy code - """ - - web3 = create_multi_provider_web3(JSON_RPC_BASE) - - uniswap_v2 = fetch_deployment( - web3, - factory_address=UNISWAP_V2_DEPLOYMENTS["base"]["factory"], - router_address=UNISWAP_V2_DEPLOYMENTS["base"]["router"], - init_code_hash=UNISWAP_V2_DEPLOYMENTS["base"]["init_code_hash"], - ) - - uniswap_v3_factory = UNISWAP_V3_DEPLOYMENTS["base"]["factory"] - uniswap_v3_position_manager = UNISWAP_V3_DEPLOYMENTS["base"]["position_manager"] \ No newline at end of file diff --git a/eth_defi/vault/valuation.py b/eth_defi/vault/valuation.py index 4cd9ae87..41ceed5e 100644 --- a/eth_defi/vault/valuation.py +++ b/eth_defi/vault/valuation.py @@ -21,13 +21,11 @@ from multicall import Call, Multicall from web3 import Web3 from web3.contract import Contract -from web3.contract.contract import ContractFunction from eth_defi.event_reader.multicall_batcher import get_multicall_contract, call_multicall_batched_single_thread, MulticallWrapper, call_multicall_debug_single_thread from eth_defi.provider.anvil import is_mainnet_fork from eth_defi.provider.broken_provider import get_almost_latest_block_number from eth_defi.token import TokenDetails, fetch_erc20_details, TokenAddress -from eth_defi.abi import ZERO_ADDRESS from eth_defi.uniswap_v3.utils import encode_path from eth_defi.vault.base import VaultPortfolio @@ -762,8 +760,11 @@ def do_multicall( self, calls: list[MulticallWrapper] ): + """Multicall mess untangling.""" if self.legacy_multicall: - # Old bantg path + # Old bantg path. + # Do not use. + # Only headche. multicall = Multicall( calls=[c.create_multicall() for c in calls], block_id=self.block_identifier, @@ -812,7 +813,7 @@ def fetch_onchain_valuations( raw_balances = portfolio.get_raw_spot_balances(self.web3) logger.info("fetch_onchain_valuations(), %d routes, multicall is %s", len(routes), multicall) - calls = [r.quoter.create_multicall_wrapper(r, raw_balances[r.source_token.address]).create_multicall() for r in routes] + calls = [r.quoter.create_multicall_wrapper(r, raw_balances[r.source_token.address]) for r in routes] logger.info("Processing %d Multicall Calls", len(calls)) @@ -946,6 +947,7 @@ def find_swap_routes(self, portfolio: VaultPortfolio, buy=True) -> SwapMatrix: logger.info("Resolving total %d routes", len(routes)) all_route_results = self.try_swap_paths(routes, portfolio) results_by_token = defaultdict(list) + for r, amount in all_route_results.items(): results_by_token[r.target_token].append((r, amount)) @@ -953,12 +955,12 @@ def _get_route_priorisation_sort_key(route_amount_tuple): amount = route_amount_tuple[1] if amount is None: # router failed, sort to end - return Decimal(9999999 * 10**18) + return Decimal(0) return amount # Make so that the best result (most tokens bought) is the first of all tried results - results_by_token = {token: sorted(routes, key=_get_route_priorisation_sort_key) for token, routes in results_by_token.items()} + results_by_token = {token: sorted(routes, key=_get_route_priorisation_sort_key, reverse=True) for token, routes in results_by_token.items()} return SwapMatrix( results=all_route_results, diff --git a/tests/lagoon/test_lagoon_valuation.py b/tests/lagoon/test_lagoon_valuation.py index a253f45d..43af4711 100644 --- a/tests/lagoon/test_lagoon_valuation.py +++ b/tests/lagoon/test_lagoon_valuation.py @@ -1,7 +1,6 @@ """NAV calcualtion and valuation commitee tests.""" from decimal import Decimal -from shlex import quote import pytest from eth_typing import HexAddress @@ -46,6 +45,7 @@ def uniswap_v3(web3): position_manager_address=deployment_data["position_manager"], quoter_address=deployment_data["quoter"], quoter_v2=deployment_data["quoter_v2"], + router_v2=deployment_data["router_v2"], ) return uniswap_v3_on_base @@ -484,7 +484,13 @@ def test_valuation_mixed_routes( ): """Value a portfolio with mixed Uniswap v2/v3 routes. - - Use lagoon, but the valuation itself does not care abut Lagoon + - Buy some random tokens, on the top of the existing tokens the address already helds + + - See that the valuation of bought tokens match what was the buy price + + - Do miked two leg/three leg/uniswap v2/uniswap v3 routing + + - Use lagoon, but the valuation itself does not care about Lagoon - This test is very slow due to high number of Multicalls made """ @@ -510,7 +516,7 @@ def test_valuation_mixed_routes( ) latest_block = get_almost_latest_block_number(web3) portfolio = vault.fetch_portfolio(universe, latest_block) - assert portfolio.get_position_count() == 6 + assert portfolio.get_position_count() == 7 uniswap_v2_quoter = UniswapV2Router02Quoter(uniswap_v2.router) uniswap_v3_quoter = UniswapV3Quoter(uniswap_v3.quoter) @@ -523,9 +529,11 @@ def test_valuation_mixed_routes( debug=True, ) + # We bought using 5 USD, so all token holding valuations should be in ballpark portfolio_valuation = nav_calculator.calculate_market_sell_nav(portfolio) - assert portfolio_valuation.spot_valuations["0x9a26f5433671751c3276a065f57e5a02d2817973"] > 4.9 # Keycat - assert portfolio_valuation.spot_valuations["0x7484a9fb40b16c4dfe9195da399e808aa45e9bb9"] > 4.9 # AGNT + import ipdb ; ipdb.set_trace() + assert portfolio_valuation.spot_valuations["0x9a26f5433671751c3276a065f57e5a02d2817973"] > 4.5 # Keycat + assert portfolio_valuation.spot_valuations["0x7484a9fb40b16c4dfe9195da399e808aa45e9bb9"] > 4.5 # AGNT # Check routes routes = nav_calculator.create_route_diagnostics(portfolio)