diff --git a/.github/workflows/release-and-pypi-publish.yml b/.github/workflows/release-and-pypi-publish.yml index 2893f5056..057dd4798 100644 --- a/.github/workflows/release-and-pypi-publish.yml +++ b/.github/workflows/release-and-pypi-publish.yml @@ -83,6 +83,7 @@ jobs: id: bump_version_and_set_output run: | poetry version patch + echo new_version=$(poetry version | cut -d' ' -f2) >> $GITHUB_OUTPUT git checkout main git config --local user.email "action@github.com" git config --local user.name "GitHub Action" diff --git a/.gitignore b/.gitignore index 5e3d05b03..a35a7e42a 100644 --- a/.gitignore +++ b/.gitignore @@ -73,3 +73,5 @@ logs/* missing_tokens_df.csv tokens_and_fee_df.csv fastlane_bot/tests/nbtest/* + +.python-version diff --git a/fastlane_bot/bot.py b/fastlane_bot/bot.py index 0a153d6c9..5fe5800d5 100644 --- a/fastlane_bot/bot.py +++ b/fastlane_bot/bot.py @@ -144,19 +144,19 @@ def get_curves(self) -> CPCContainer: ADDRDEC = {t.address: (t.address, int(t.decimals)) for t in tokens} for p in pools_and_tokens: + p.ADDRDEC = ADDRDEC try: - p.ADDRDEC = ADDRDEC curves += [ curve for curve in p.to_cpc() if all(curve.params[tkn] not in self.ConfigObj.TAX_TOKENS for tkn in ['tknx_addr', 'tkny_addr']) ] except SolidlyV2StablePoolsNotSupported as e: self.ConfigObj.logger.debug( - f"[bot.get_curves] SolidlyV2StablePoolsNotSupported: {e}\n" + f"[bot.get_curves] Solidly V2 stable pools not supported: {e}\n" ) except NotImplementedError as e: self.ConfigObj.logger.error( - f"[bot.get_curves] Pool type not yet supported, error: {e}\n" + f"[bot.get_curves] Not supported: {e}\n" ) except ZeroDivisionError as e: self.ConfigObj.logger.error( @@ -241,36 +241,17 @@ def _convert_trade_instructions( List[Dict[str, Any]] The trade instructions. """ - errorless_trade_instructions_dicts = [ - {k: v for k, v in trade_instructions_dic[i].items() if k != "error"} - for i in range(len(trade_instructions_dic)) - ] - result = ( - { - **ti, + return [ + TradeInstruction(**{ + **{k: v for k, v in ti.items() if k != "error"}, "raw_txs": "[]", "pair_sorting": "", "ConfigObj": self.ConfigObj, "db": self.db, - } - for ti in errorless_trade_instructions_dicts - if ti is not None - ) - result = self._add_strategy_id_to_trade_instructions_dic(result) - result = [TradeInstruction(**ti) for ti in result] - return result - - def _add_strategy_id_to_trade_instructions_dic( - self, trade_instructions_dic: Generator - ) -> List[Dict[str, Any]]: - lst = [] - for ti in trade_instructions_dic: - cid = ti["cid"].split('-')[0] - ti["strategy_id"] = self.db.get_pool( - cid=cid - ).strategy_id - lst.append(ti) - return lst + "strategy_id": self.db.get_pool(cid=ti["cid"].split('-')[0]).strategy_id + }) + for ti in trade_instructions_dic if ti["error"] is None + ] def _get_deadline(self, block_number) -> int: """ diff --git a/fastlane_bot/config/__init__.py b/fastlane_bot/config/__init__.py index a49c6ee0b..cd0646ca5 100644 --- a/fastlane_bot/config/__init__.py +++ b/fastlane_bot/config/__init__.py @@ -10,15 +10,6 @@ - ``ConfigProvider`` (``provider``; provider for network access) - ``Config`` (``config``; main configuration class, integrates the above) -Submodules provide the following - -- Constants (``constants`` and ``selectors``; various constants) -- ``MultiCaller`` and related (``multicaller``; TODO: what is this?) -- ``NetworkBase`` and ``EthereumNetwork`` (``connect``; network/chain connection code TODO: details) -- ``Cloaker`` (``cloaker``; deprecated) - - - --- (c) Copyright Bprotocol foundation 2023-24. All rights reserved. diff --git a/fastlane_bot/config/constants.py b/fastlane_bot/config/constants.py index 0c6357ce0..787129492 100644 --- a/fastlane_bot/config/constants.py +++ b/fastlane_bot/config/constants.py @@ -19,6 +19,8 @@ } ETHEREUM = "ethereum" +UNISWAP_V2_NAME = "uniswap_v2" +UNISWAP_V3_NAME = "uniswap_v3" PANCAKESWAP_V2_NAME = "pancakeswap_v2" PANCAKESWAP_V3_NAME = "pancakeswap_v3" BUTTER_V3_NAME = "butter_v3" @@ -31,3 +33,16 @@ ECHODEX_V3_NAME = "echodex_v3" SECTA_V3_NAME = "secta_v3" METAVAULT_V3_NAME = "metavault_v3" +ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" + +BLOCK_CHUNK_SIZE_MAP = { + "ethereum": 0, + "polygon": 0, + "polygon_zkevm": 0, + "arbitrum_one": 0, + "optimism": 0, + "coinbase_base": 0, + "fantom": 5000, + "mantle": 0, + "linea": 0, +} diff --git a/fastlane_bot/config/multicaller.py b/fastlane_bot/config/multicaller.py index 9687db79c..76b031bf6 100644 --- a/fastlane_bot/config/multicaller.py +++ b/fastlane_bot/config/multicaller.py @@ -1,34 +1,19 @@ """ -This is the multicaller module. TODO: BETTER NAME - -TODO-MIKE: What exactly does this do and is it a bona fide config module? +MultiCaller class --- (c) Copyright Bprotocol foundation 2023-24. All rights reserved. Licensed under MIT. """ -from functools import partial -from typing import List, Callable, ContextManager, Any, Dict +from typing import Any, List, Dict -import web3 from eth_abi import decode -from web3 import Web3 +from web3.contract.contract import ContractFunction from fastlane_bot.data.abi import MULTICALL_ABI -def cast(typ, val): - """Cast a value to a type. - - This returns the value unchanged. To the type checker this - signals that the return value has the designated type, but at - runtime we intentionally don't check anything (we want this - to be as fast as possible). - """ - return val - - def collapse_if_tuple(abi: Dict[str, Any]) -> str: """ Converts a tuple from a dict to a parenthesized list of its types. @@ -46,141 +31,38 @@ def collapse_if_tuple(abi: Dict[str, Any]) -> str: ... ) '(address,uint256,bytes)' """ - typ = abi["type"] - if not isinstance(typ, str): - raise TypeError( - "The 'type' must be a string, but got %r of type %s" % (typ, type(typ)) - ) - elif not typ.startswith("tuple"): - return typ - - delimited = ",".join(collapse_if_tuple(c) for c in abi["components"]) - # Whatever comes after "tuple" is the array dims. The ABI spec states that - # this will have the form "", "[]", or "[k]". - array_dim = typ[5:] - collapsed = "({}){}".format(delimited, array_dim) - - return collapsed - - -def get_output_types_from_abi(abi: List[Dict[str, Any]], function_name: str) -> List[str]: - """ - Get the output types from an ABI. - - Parameters - ---------- - abi : List[Dict[str, Any]] - The ABI - function_name : str - The function name - - Returns - ------- - List[str] - The output types - - """ - for item in abi: - if item['type'] == 'function' and item['name'] == function_name: - return [collapse_if_tuple(cast(Dict[str, Any], item)) for item in item['outputs']] - raise ValueError(f"No function named {function_name} found in ABI.") + if abi["type"].startswith("tuple"): + delimited = ",".join(collapse_if_tuple(c) for c in abi["components"]) + return "({}){}".format(delimited, abi["type"][len("tuple"):]) + return abi["type"] -class ContractMethodWrapper: - """ - Wraps a contract method to be used with multicall. - """ - __DATE__ = "2022-09-26" - __VERSION__ = "0.0.2" - - def __init__(self, original_method, multicaller): - self.original_method = original_method - self.multicaller = multicaller - - def __call__(self, *args, **kwargs): - contract_call = self.original_method(*args, **kwargs) - self.multicaller.add_call(contract_call) - return contract_call - - -class MultiCaller(ContextManager): +class MultiCaller: """ Context manager for multicalls. """ __DATE__ = "2022-09-26" __VERSION__ = "0.0.2" + def __init__(self, web3: Any, multicall_contract_address: str): + self.multicall_contract = web3.eth.contract(abi=MULTICALL_ABI, address=multicall_contract_address) + self.contract_calls: List[ContractFunction] = [] + self.output_types_list: List[List[str]] = [] - def __init__(self, contract: web3.contract.Contract, - web3: Web3, - block_identifier: Any = 'latest', multicall_address = "0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696"): - self._contract_calls: List[Callable] = [] - self.contract = contract - self.block_identifier = block_identifier - self.web3 = web3 - self.MULTICALL_CONTRACT_ADDRESS = self.web3.to_checksum_address(multicall_address) - - def __enter__(self) -> 'MultiCaller': - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - pass - - def add_call(self, fn: Callable, *args, **kwargs) -> None: - self._contract_calls.append(partial(fn, *args, **kwargs)) - - def multicall(self) -> List[Any]: - calls_for_aggregate = [] - output_types_list = [] - _calls_for_aggregate = {} - _output_types_list = {} - for fn in self._contract_calls: - fn_name = str(fn).split('functools.partial(')[0] - output_types = get_output_types_from_abi(self.contract.abi, fn_name) - if fn_name in _calls_for_aggregate: - _calls_for_aggregate[fn_name].append({ - 'target': self.contract.address, - 'callData': fn()._encode_transaction_data() - }) - _output_types_list[fn_name].append(output_types) - else: - _calls_for_aggregate[fn_name] = [{ - 'target': self.contract.address, - 'callData': fn()._encode_transaction_data() - }] - _output_types_list[fn_name] = [output_types] - - for fn_list in _calls_for_aggregate.keys(): - calls_for_aggregate += (_calls_for_aggregate[fn_list]) - output_types_list += (_output_types_list[fn_list]) - - encoded_data = self.web3.eth.contract( - abi=MULTICALL_ABI, - address=self.MULTICALL_CONTRACT_ADDRESS - ).functions.aggregate(calls_for_aggregate).call(block_identifier=self.block_identifier) - - if not isinstance(encoded_data, list): - raise TypeError(f"Expected encoded_data to be a list, got {type(encoded_data)} instead.") - - encoded_data = encoded_data[1] - decoded_data_list = [] - for output_types, encoded_output in zip(output_types_list, encoded_data): - decoded_data = decode(output_types, encoded_output) - decoded_data_list.append(decoded_data) - - return_data = [i[0] for i in decoded_data_list if len(i) == 1] - return_data += [i[1] for i in decoded_data_list if len(i) > 1] + def add_call(self, call: ContractFunction): + self.contract_calls.append({'target': call.address, 'callData': call._encode_transaction_data()}) + self.output_types_list.append([collapse_if_tuple(item) for item in call.abi['outputs']]) - # Handling for Bancor POL - combine results into a Tuple - if "tokenPrice" in _calls_for_aggregate and "amountAvailableForTrading" in _calls_for_aggregate: - new_return = [] - returned_items = int(len(return_data)) - total_pools = int(returned_items / 2) - assert returned_items % 2 == 0, f"[multicaller.py multicall] non-even number of returned calls for Bancor POL {returned_items}" - total_pools = int(total_pools) + def run_calls(self, block_identifier: Any = 'latest') -> List[Any]: + encoded_data = self.multicall_contract.functions.tryAggregate( + False, + self.contract_calls + ).call(block_identifier=block_identifier) - for idx in range(total_pools): - new_return.append((return_data[idx][0], return_data[idx][1], return_data[idx + total_pools])) - return_data = new_return + result_list = [ + decode(output_types, encoded_output[1]) if encoded_output[0] else (None,) + for output_types, encoded_output in zip(self.output_types_list, encoded_data) + ] - return return_data + # Convert every single-value tuple into a single value + return [result if len(result) > 1 else result[0] for result in result_list] diff --git a/fastlane_bot/config/network.py b/fastlane_bot/config/network.py index 0bed6b542..90ddc59cc 100644 --- a/fastlane_bot/config/network.py +++ b/fastlane_bot/config/network.py @@ -194,7 +194,7 @@ class ConfigNetwork(ConfigBase): USDT_ADDRESS = "0xdAC17F958D2ee523a2206206994597C13D831ec7" WETH_ADDRESS = WETH9_ADDRESS = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" - TAX_TOKENS = [] + TAX_TOKENS = set([]) # BNT_KEY = "BNT-FF1C" # ETH_KEY = "ETH-EEeE" @@ -279,7 +279,6 @@ class ConfigNetwork(ConfigBase): # FLAGS ####################################################################################### - GAS_TKN_IN_FLASHLOAN_TOKENS = None IS_NO_FLASHLOAN_AVAILABLE = False # HOOKS @@ -317,7 +316,7 @@ def new(cls, network=None): elif network == cls.NETWORK_MANTLE: return _ConfigNetworkMantle(_direct=False) elif network == cls.NETWORK_LINEA: - return _ConfigNetworkLinea(_direct=False) + return _ConfigNetworkLinea(_direct=False) elif network == cls.NETWORK_TENDERLY: return _ConfigNetworkTenderly(_direct=False) else: @@ -426,7 +425,7 @@ class _ConfigNetworkMainnet(ConfigNetwork): RPC_ENDPOINT = "https://eth-mainnet.alchemyapi.io/v2/" WEB3_ALCHEMY_PROJECT_ID = os.environ.get("WEB3_ALCHEMY_PROJECT_ID") - MULTICALL_CONTRACT_ADDRESS = "0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696" + MULTICALL_CONTRACT_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11" # NATIVE_GAS_TOKEN_KEY = "ETH-EEeE" # WRAPPED_GAS_TOKEN_KEY = "WETH-6Cc2" # STABLECOIN_KEY = "USDC-eB48" @@ -437,13 +436,19 @@ class _ConfigNetworkMainnet(ConfigNetwork): WRAPPED_GAS_TOKEN_SYMBOL = "WETH" STABLECOIN_ADDRESS = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" - TAX_TOKENS = [ + TAX_TOKENS = set([ "0x5a3e6A77ba2f983eC0d371ea3B475F8Bc0811AD5", # 0x0 "0x72e4f9F808C49A2a61dE9C5896298920Dc4EEEa9", # BITCOIN + "0x40E64405F18e4FB01c6fc39f4F0c78df5eF9D0E0", # COSMIC + "0xae41b275aaAF484b541A5881a2dDED9515184CCA", # CSWAP "0xf94e7d0710709388bCe3161C32B4eEA56d3f91CC", # DSync + "0x69420E3A3aa9E17Dea102Bb3a9b3B73dcDDB9528", # ELON "0x1258D60B224c0C5cD888D37bbF31aa5FCFb7e870", # GPU + "0x292fcDD1B104DE5A00250fEBbA9bC6A5092A0076", # HASHAI + "0xaa95f26e30001251fb905d264Aa7b00eE9dF6C18", # KENDU "0x6A7eFF1e2c355AD6eb91BEbB5ded49257F3FED98", # OPSEC - ] + "0x14feE680690900BA0ccCfC76AD70Fd1b95D10e16", # PAAL + ]) # FACTORY, CONVERTER, AND CONTROLLER ADDRESSES ####################################################################################### @@ -762,9 +767,9 @@ class _ConfigNetworkLinea(ConfigNetwork): WRAPPED_GAS_TOKEN_SYMBOL = "WETH" STABLECOIN_ADDRESS = "0x176211869ca2b568f2a7d4ee941e073a821ee1ff" - TAX_TOKENS = [ + TAX_TOKENS = set([ "0x1bE3735Dd0C0Eb229fB11094B6c277192349EBbf", # LUBE - ] + ]) IS_INJECT_POA_MIDDLEWARE = True # Balancer @@ -810,7 +815,7 @@ class _ConfigNetworkTenderly(ConfigNetwork): FASTLANE_CONTRACT_ADDRESS = "0x41Eeba3355d7D6FF628B7982F3F9D055c39488cB" CARBON_CONTROLLER_ADDRESS = "0xC537e898CD774e2dCBa3B14Ea6f34C93d5eA45e1" CARBON_CONTROLLER_VOUCHER = "0x3660F04B79751e31128f6378eAC70807e38f554E" - MULTICALL_CONTRACT_ADDRESS = "0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696" + MULTICALL_CONTRACT_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11" # Uniswap UNISWAP_V2_ROUTER_ADDRESS = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D" diff --git a/fastlane_bot/data/abi.py b/fastlane_bot/data/abi.py index 4d0d9f788..3c98f7000 100644 --- a/fastlane_bot/data/abi.py +++ b/fastlane_bot/data/abi.py @@ -164,6 +164,13 @@ "name": "PairCreated", "anonymous": False, "inputs": [{"indexed": True, "internalType": "address", "name": "token0", "type": "address"}, {"indexed": True, "internalType": "address", "name": "token1", "type": "address"}, {"indexed": False, "internalType": "address", "name": "pair", "type": "address"}, {"indexed": False, "internalType": "uint256", "name": "", "type": "uint256"}] + }, + { + "type": "function", + "name": "getPair", + "stateMutability": "view", + "inputs": [{"internalType": "address", "name": "", "type": "address"}, {"internalType": "address", "name": "", "type": "address"}], + "outputs": [{"internalType": "address", "name": "", "type": "address"}] } ] @@ -173,6 +180,13 @@ "name": "PoolCreated", "anonymous": False, "inputs": [{"indexed": True, "internalType": "address", "name": "token0", "type": "address"}, {"indexed": True, "internalType": "address", "name": "token1", "type": "address"}, {"indexed": True, "internalType": "uint24", "name": "fee", "type": "uint24"}, {"indexed": False, "internalType": "int24", "name": "tickSpacing", "type": "int24"}, {"indexed": False, "internalType": "address", "name": "pool", "type": "address"}] + }, + { + "type": "function", + "name": "getPool", + "stateMutability": "view", + "inputs": [{"internalType": "address", "name": "", "type": "address"}, {"internalType": "address", "name": "", "type": "address"}, {"internalType": "uint24", "name": "", "type": "uint24"}], + "outputs": [{"internalType": "address", "name": "", "type": "address"}], } ] @@ -189,6 +203,13 @@ "stateMutability": "view", "inputs": [{"internalType": "address", "name": "pool", "type": "address"}, {"internalType": "bool", "name": "_stable", "type": "bool"}], "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}] + }, + { + "type": "function", + "name": "getPool", + "stateMutability": "view", + "inputs": [{"internalType": "address", "name": "tokenA", "type": "address"}, {"internalType": "address", "name": "tokenB", "type": "address"}, {"internalType": "bool", "name": "stable", "type": "bool"}], + "outputs": [{"internalType": "address", "name": "", "type": "address"}], } ] @@ -205,6 +226,13 @@ "stateMutability": "view", "inputs": [{"internalType": "address", "name": "_pair", "type": "address"}], "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}] + }, + { + "type": "function", + "name": "getPair", + "stateMutability": "view", + "inputs": [{"internalType": "address", "name": "", "type": "address"}, {"internalType": "address", "name": "", "type": "address"}, {"internalType": "bool", "name": "", "type": "bool"}], + "outputs": [{"internalType": "address", "name": "", "type": "address"}] } ] @@ -221,6 +249,13 @@ "stateMutability": "view", "inputs": [{"internalType": "address", "name": "_pair", "type": "address"}], "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}] + }, + { + "type": "function", + "name": "getPair", + "stateMutability": "view", + "inputs": [{"internalType": "address", "name": "", "type": "address"}, {"internalType": "address", "name": "", "type": "address"}, {"internalType": "bool", "name": "", "type": "bool"}], + "outputs": [{"internalType": "address", "name": "", "type": "address"}] } ] @@ -237,6 +272,13 @@ "stateMutability": "view", "inputs": [{"type": "address", "name": "_pair", "internalType": "address"}, {"type": "bool", "name": "_stable", "internalType": "bool"}], "outputs": [{"type": "uint256", "name": "", "internalType": "uint256"}] + }, + { + "type": "function", + "name": "getPair", + "stateMutability": "view", + "inputs": [{"internalType": "address", "name": "", "type": "address"}, {"internalType": "address", "name": "", "type": "address"}, {"internalType": "bool", "name": "", "type": "bool"}], + "outputs": [{"internalType": "address", "name": "", "type": "address"}] } ] @@ -253,6 +295,13 @@ "stateMutability": "view", "inputs": [{"internalType": "bool", "name": "_stable", "type": "bool"}], "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}] + }, + { + "type": "function", + "name": "getPair", + "stateMutability": "view", + "inputs": [{"internalType": "address", "name": "", "type": "address"}, {"internalType": "address", "name": "", "type": "address"}, {"internalType": "bool", "name": "", "type": "bool"}], + "outputs": [{"internalType": "address", "name": "", "type": "address"}] } ] @@ -269,6 +318,13 @@ "stateMutability": "view", "inputs": [{"internalType": "address", "name": "_pool", "type": "address"}], "outputs": [{"internalType": "uint256", "name": "fee", "type": "uint256"}] + }, + { + "type": "function", + "name": "getPair", + "stateMutability": "view", + "inputs": [{"internalType": "address", "name": "", "type": "address"}, {"internalType": "address", "name": "", "type": "address"}, {"internalType": "bool", "name": "", "type": "bool"}], + "outputs": [{"internalType": "address", "name": "", "type": "address"}] } ] @@ -285,6 +341,13 @@ "stateMutability": "view", "inputs": [], "outputs": [{"internalType": "address", "name": "", "type": "address"}] + }, + { + "type": "function", + "name": "getPool", + "stateMutability": "view", + "inputs": [{"internalType": "address", "name": "_token", "type": "address"}], + "outputs": [{"internalType": "address", "name": "pool", "type": "address"}], } ] @@ -676,10 +739,10 @@ MULTICALL_ABI = [ { "type": "function", - "name": "aggregate", + "name": "tryAggregate", "stateMutability": "view", - "inputs": [{"components": [{"internalType": "address", "name": "target", "type": "address"}, {"internalType": "bytes", "name": "callData", "type": "bytes"}], "internalType": "struct Multicall2.Call[]", "name": "calls", "type": "tuple[]"}], - "outputs": [{"internalType": "uint256", "name": "blockNumber", "type": "uint256"}, {"internalType": "bytes[]", "name": "returnData", "type": "bytes[]"}] + "inputs": [{"internalType": "bool", "name": "requireSuccess", "type": "bool"}, {"components": [{"internalType": "address", "name": "target", "type": "address"}, {"internalType": "bytes", "name": "callData", "type": "bytes"}], "internalType": "struct Multicall3.Call[]", "name": "calls", "type": "tuple[]"}], + "outputs": [{"components": [{"internalType": "bool", "name": "success", "type": "bool"}, {"internalType": "bytes", "name": "returnData", "type": "bytes"}], "internalType": "struct Multicall3.Result[]", "name": "returnData", "type": "tuple[]"}] } ] diff --git a/fastlane_bot/data/blockchain_data/coinbase_base/solidly_v2_event_mappings.csv b/fastlane_bot/data/blockchain_data/coinbase_base/solidly_v2_event_mappings.csv index c05001617..43067b973 100644 --- a/fastlane_bot/data/blockchain_data/coinbase_base/solidly_v2_event_mappings.csv +++ b/fastlane_bot/data/blockchain_data/coinbase_base/solidly_v2_event_mappings.csv @@ -1276,3 +1276,58 @@ velocimeter_v2,0xD417CAd1A083198837DEC73D2780395F471Cdf31 velocimeter_v2,0xd032d277d7BbdEB51B0a77aF873930296768c2A1 velocimeter_v2,0x91000A718DfeD49ddfc10A74DdF5Cf7399540888 velocimeter_v2,0x6B92Ddab1ed75df684A02CD14A0481b25148f8cf +aerodrome_v2,0x4ceE7cD3d821c514EcE6a01e91A9b418396bd1c1 +aerodrome_v2,0xdd0fC65F9088e7B487a2867c362B7956384D92C7 +aerodrome_v2,0xe4F3dEf72Ae1aD6B4b63FCa4df12ffF5402AE13d +aerodrome_v2,0x3a62a86C481f9Fbe578B3F62B72A27D8f8d6C85b +aerodrome_v2,0x1894416A511251CfDD350B80bE256F4D166dCa0e +aerodrome_v2,0xEb725c1FDd2a1Db9EaCA20a4DC7E78896565D585 +aerodrome_v2,0x10e63a964f65242AC1A97b925813B35cF716fF9d +aerodrome_v2,0x1491d10F4A22d6D1ca7749CC3F68521eB1E386b2 +aerodrome_v2,0x85F742c905658251E9523BAD96C2F80C5E2d7fd3 +aerodrome_v2,0x8A97D8C1F67Cc6EFb1222E7a9A766C6089f8d76c +aerodrome_v2,0x4AA6CF748BeADd0098DBeE669fa812938034682d +aerodrome_v2,0xAaE3d6b4dEce107768EC3fF6D2ba63df28225491 +aerodrome_v2,0xFfC40A46c5EC3531b4c27947423735987d77BDbA +aerodrome_v2,0xf5879DCf41402268d2A84CC9d265D607F588e83f +aerodrome_v2,0xB61eB73C258F9273d136226DE3952eDf48663f71 +aerodrome_v2,0x8291f3f72c71a9843170001B40967A688bfEBb3a +aerodrome_v2,0x86DE2E61Bb83c52569cfA6f9B3d183da11D1195f +aerodrome_v2,0x56237149C37098e1B2dc3aa0cF42764795F42d95 +aerodrome_v2,0x33c3782446dF290bE025A24A0Ac94562E9A995D6 +aerodrome_v2,0x1b3D4586ACF01C4FDc18158CF46B97A4D0D21F20 +aerodrome_v2,0xEAcE394F7B53f28b77F2e2506D70bC7BD07Cd4F3 +aerodrome_v2,0xC4460eCEB0a2b84dfbA4B2c85960C37B3Bf7a80b +aerodrome_v2,0xdF8280565549ED72cC48E8D5297fb1ECd912E9e3 +aerodrome_v2,0x0b8711D0F80Eacb3dE9f653BD554aF3bA654fA1f +aerodrome_v2,0x9D651E2491a57eE801de20a2ddE33747631fC083 +aerodrome_v2,0x3eE99B4D81ea447e905e0a0EF726B6Afc88bB732 +aerodrome_v2,0xb0B2E62fe141E84cFC00A8Fc65757499EF60D586 +aerodrome_v2,0x857E905f530FA733aB8C43203c514dF59713832e +aerodrome_v2,0x41490957E520F66eC73AE0671ce276223c59FAb4 +aerodrome_v2,0x4296b50ADF4e27eb2cf2f71b799f88268E459748 +aerodrome_v2,0xEb1913F806C1f0ec1AFaDD837458dF3eb43b04E6 +aerodrome_v2,0x26638737a80EE07153bdBce7BAA738b3306f87d9 +aerodrome_v2,0x8658F3EeBd8bf693C0A7cfc2a70be5DC613440c1 +aerodrome_v2,0x2701F677d5E551468326EAe3fd2aC5d16a4247A9 +aerodrome_v2,0x56CdB749f2678Ca40e7b3687589F027417A1D554 +aerodrome_v2,0x6656648B3c925d9aC13C456567112F7a5CEF8cE8 +aerodrome_v2,0x1cf2409BbF69b29913242143fB1F0cC9577F4D37 +aerodrome_v2,0xB8743Ff3f4AE10c9a1CC92Daee9d9CEd62C911D9 +aerodrome_v2,0xBE0d0318cCd067D8C91314efEDE8BF93793A7Dc7 +aerodrome_v2,0x33ced6Bb3Dd3e7c7779628BBA53aCC87355aE159 +aerodrome_v2,0x72A8cD630D013BC971e86C3e193Bff2C75e9e50A +aerodrome_v2,0x40ddC3aC4f9672e1e77A0cBe8Fe55F1e62Ea2F14 +aerodrome_v2,0x87d6d16eA835607Eb9a4A00257762f8864A4A6F2 +aerodrome_v2,0x68D899c59D7dA901eeD6a87b4281D499F016758C +aerodrome_v2,0x97796439776dB7fFc3Ce8dcfB2ADBc1fd145C67C +aerodrome_v2,0x371ff4b62D12A2E78e798a885478CAd8BAF97E6e +aerodrome_v2,0x9b0025d10E824E7E2b148953009A40B0C0792F30 +aerodrome_v2,0x7f23010bf37fbaDBcAEa2CBB1E84B37cDb30437C +aerodrome_v2,0xc5aDfb267a95df1233a2b5F7f48041E7Fb384BcA +aerodrome_v2,0x0Da751fFAB2d9deaF89BfcEED570D8cac8C96F05 +aerodrome_v2,0x67721f14cEdf15B4B70692EE359Ec350C59Dab14 +scale_v2,0xB6A20d2D9C8Eaf8197b0584969239d179Bf1B396 +scale_v2,0x48498571dF1B94d08C0C100f068938A7B1B525eE +scale_v2,0x56863cbF405d97b4B89aa9ff1eC1f38E80126010 +scale_v2,0x3da64dAdA8caBf59ed05C6B6A003171B3EFCDb16 diff --git a/fastlane_bot/data/blockchain_data/coinbase_base/tokens.csv b/fastlane_bot/data/blockchain_data/coinbase_base/tokens.csv index dbac2efb0..2b20be9d9 100644 --- a/fastlane_bot/data/blockchain_data/coinbase_base/tokens.csv +++ b/fastlane_bot/data/blockchain_data/coinbase_base/tokens.csv @@ -32041,3 +32041,1307 @@ address,decimals,symbol 0x2fEB15b8185053092a5f6D77B99FC05082A499c6,18,WF 0xcC167Adfa55746055011512e325303624cE466AA,18,THO 0x8Fe2b9EA2C78A9FBEF771A51797bEF9390D2183D,18,STARV3 +0x1fF20056eAf7a5B24671c24543a58d84fb0918aE,18,B1 +0xe11dEA55a9Ca6c4232286E0cE4e5A6871630681b,18,bpzzzzTST +0x076F506Eb6E39d363440A1C1aaCa0F0D40DDecb3,18,BASED +0x7c642BD08f2b8330900278f0C4f1b801EBe50859,18,SIXNINE +0xDD46D9aBE5bc1F3020E4ef5DCe722CAa449DBd50,18,bpzzzzzzTS +0x7cC88702CBDfc0519b5f95964ceEdCDbe60Db66a,18,pzzzTST +0x91FAE4ED0Ebc228ceEF92C7cfD8fDAD777086253,18,bpzzzzzTST +0x4aAe6BF4a393c57543990Bb2F1Dcf407Fa35c8b3,18,bpzzzzTST +0x4364F7311095075123d279C8bB903edc868C0f66,18,BDROP +0x9FE1fbcb5BF0b0CE45A7ad3cDEA1ae8ae49a8fB7,9,QZR +0x365d7a3B7437DabbEbd1BF596baeEdd9F57e7e3d,18,bpxxxxxxTS +0xf305D674a4e1B8C9e81Fe9F24393Ee3Ff9173F0b,18,PEACE +0xd8FACc12Ef96b70469CE5CAbc141dFCa1d2bd42B,18,bpyyyyyTST +0xd1fBA6A5627d2928CC47E0e8a9185B6FfbF04b04,9,$BENTO +0xBa5ECADD909BAaD62f27ABA6bc954fD6a3E88DC4,18,$JUMP +0x79cEad033b8Fb094824430460878B088242D4B4d,18,LIL +0x54ddb5dE08584206Df4DD5b50220764C6aA60fD5,18,bpVERIFY +0x10064082c4F7AF72bBAC828c1be0a847C960d6C6,18,0xBASE❖ +0xEC8C277c038f314B139aB903Eb8d3804077ed6f9,18,SHLONG +0x6a02F704890F507f13d002F2785ca7Ba5BFcc8F7,18,pITest2 +0xC53f46d5D2d6adC7034087816d5325940074Cdf1,18,pITest +0x9a2c7e8880e1D8604b1717CeabeE237Bfa778F07,18,pOHM +0x3Dd79d6BD927615787Cc95F2c7A77C9aC1AF26F4,18,pwBLT +0x6C9730f8a66e8aFaCCF83C9696491022d1521335,9,LARRY +0x20cC61a01C9A1Bc760f7e76723FEA8D49104c121,18,BLUEORIGIN +0x3e4a45A93c00d2a3378C63b01273d92C0B4c39af,18,SAM +0x656761096DED90817e48749dbF587FB5638D91Ff,18,INTI +0xB82679D491D497A042158199220C80Cd34B76200,18,BTCDGN +0x0b7606D95D1f62175Ee026db5425381880A62a94,18,COINBASE +0x4da78059D97f155E18B37765e2e042270f4E0fC4,4,WUF +0x2eb50E7CB1D67A801552d1fc318E915B51780195,18,PRYM +0xeaA49C03897455BF0518E7Ddc6E5129226fF1A74,18,MAR +0xbE81aeA9FAf7B58b596fe44d529302c025B3Fce2,18,Symbol +0x61C50d8529ddd062F206cBD3a5c9DCF30E6B3BA4,18,BotAi +0xc012eD3365287c0856c22bcaD99205c06A857986,18,Dan +0x5B0373a526309FB73e6EF07cEa2D288A837BcF14,12,ITM +0xBa33d66f3B1b33170c30B9307C70E43CB73D40dE,18,BASED +0x16b8839e661B51de71Cfc1996a746ab8e6f84C8D,18,DOGINUS +0x417f42E12321Aee4D890E6cfcfa4842A3F41F4D2,18,HKD +0x59eE82C515b7D01DE1e2c62fa588456f2048171F,18,Moona +0x6476eC977ebA858D9f0b14a7DcEa051Bae5B6bab,18,BABI +0xA82b60E31E59E2ca9e198Ed066e0A946063274A0,9,BASTE +0x0C752564C32d005298B474Be0A213305602394FD,18,RABBY +0x878FC835F527Dcc8F2319783f546c6797415FF8D,18,HABIBI +0x48e75617382EBdaF71D96E5B0497B906042b5f1a,18,HABIBI +0xD0b52C8690E0c62c62355BC5f659f44D77851f00,18,FRIENDS +0x5d615C0Fe1750f6Da4870516fa7b66bA74e6F2D7,18,TFLX +0xAe8b8c672ECE1ca3dea4E19dAD406dD27e9709fE,18,HABIBI +0x99A20A5AaC1D2c6c2F0Df67B25970Caa8EE6C03D,18,TASK +0x67BDA415DD9BedE80Ba444D289fF7AD7b4Bf42C5,18,T69 +0xb7C18989F6F0932a87633772b90c1bC9BD0EC7d1,9,$NYAN +0x7219204037b2e7853bC57BcA4bF74a4428105656,18,$DT +0x34885d09ade6148BC3f5f1514562C1839132567c,18,MMAL +0xb8E75dDb0Fb11066F509352A249268E4a793F58b,18,ROBOTT +0x60874decaa2a9D7beacAfECDa38ADf7dde546AD8,18,DOGMEAT +0xD5214Aa867DFa6166B0489Da17Ae6012b15Dc670,18,SHON +0xE69dD38823d62b77D2E6f5c73a2D3F21AAd7701B,18,DENI +0x790Ac212a0d205E355dc779E3e979C4C9dE10805,18,MXA +0xDF61175de699b046F7beD166992dd05fa16c96Dd,18,DENI +0x3F458eeAfd1d66C2E305DE31253aec3C8B72105d,18,SKYY +0xAe740D8F907C047b37263A672E7078325a648918,18,BIF +0xDeF7C2e9a4F53Ae0d9F49515E1d93fb370f31DCC,9,TGR +0x99C0C995dBC6C12fE0C194942eEb6c05256FEA21,9,Duke +0xf2E69E2cF5d9Dc1b64bd3FfE8260137f4957d0c4,18,UT +0x618457ac0a73527FdA92e8B46550BA9E9A0305b0,18,$MAL +0x2029A5940AcA9e8B83C603b8c47D182b1BE42dAd,9,PEPE +0x53ABA78e8ad49a0Ba707C192fC328A3E18E4D786,18,BONKjr +0x788D6C9F15336A5AAA250fdF66d09BD00E406c3B,18,UT +0xb5b9ba1092d9146D5a75E7865c1f2A8B0F602DBB,18,$CRAT +0x8557Ed4Ab1B82B229F95e576C6d7654384147975,18,$MAL +0xa81371B56595B944521F7af8168C62D18BB4E3d6,18,vol +0xFc2Ef1FD1B14e1A0d541Ec76786134266e004164,6,MOON +0x1E14dB39A9Ce499480B0eE31d0394Ec41c542596,18,ZABO +0x1824B97330e593871e8a95B56Caa39F90d2DEe10,18,0xETH❖ +0x75a235fcD2510430cAFB09a5458BA5076B4383aD,18,0xBTC❖ +0xA6F53C160E839AF6D24833F48f2703BA5bf89c43,9,SDREAM +0x12E77293B8f2362C8B52517759B6c142C29400fE,18,Husu +0xC6d5F1672ACB88DF3E439A34ffE2AC838EfebBac,18,SAUDI +0x6175c3093FbD6f979299c4714E3715Cb1edB813A,18,LES +0x19c6F0233D757105d1A597fFa26FFC088Bd3950D,18,RTEST5 +0x53b3A3f06cfeba946Ddf558B816BA1E365f2b40E,18,RETAIN +0x9Bac547916B38e8Ab045870a166617b4C7065765,9,HK +0x2bF890fd6D9A05A45Ffcf9520a332bbfF975eD83,18,RETAIN +0xcF90faFD9C0F76221Fe893079696BA01414aD4b8,18,ELLEN +0x893A6c825040eF2C19B758D839805cA4F4310Bd0,9,COBRA +0xE12D9660433b59c4e718b265F259D6FA3B14CE70,18,ELLEN +0x27ad8206931d1C4C8C883ded9Ba15ae4B007721E,9,AMTYST +0xf7E7E35d4863981dfd129BeCFAc9fadb0daC1617,9,FOE +0x9675C1af50b8f7C08C41fde4d64d5311636B879D,18,RETAIN +0xFC633883219988923804047a919f46a93696fE60,18,ELLEN +0xA36bC4Ba77c9d82FEC88179E88406D706C3c6d2F,9,Garn +0x6A2d1493ACd752733B4557C686422dAE426B81dd,18,BOTTLE +0xb8BfB1d1029f612907852C8a81695bcc42161858,18,TEST +0x664a1B9e8D9953D228090C920af4bBD043dFEF00,18,BCRAFT +0x415b9eB67B2158c1573B634cbd93448780Ca4F47,18,PepeQ +0xD379021FBDB1F4016e3A0d356286c1553186ed4e,9,AELITA +0x05a1f50E16D8E6df16a8b09127C7d146a13073Fd,18,BOQ +0x69bF69248369d3EB1F2f6b2619e7ea2e95CF9f50,9,DBABY +0x1531565c5d50FE2Aec8f74cF1cD216495540Bd63,9,DAIMUN +0x80a5f4667f5Eadf070224DFAeB726B4Ac5c5b21D,18,GRIND +0x575Aa097ffD2Cd510A3B7aeD60cEEe345B702128,9,COODOS +0x4f53496eEb4AA6FfACe2A8F80a972C2F5fb7f8F2,18,basedCZ +0x34E828Ff1289b567a95e1e0535E0785b0D6f2D35,8,test +0xcb53672058AB58137A299fd5002B95C210e77e9B,9,TAMPA +0x6358591d865a627E0f180194BE7AC58d28CD00d2,9,BDOG +0xdAe50998AB032b9B822200c9a97bAc6742C8F68B,9,BDOG +0x724EBc3f491F6610ebB75E70c7b1751BCd0E624E,9,BCLUE +0x4cB91E96D180E07D3bd9E358ba5A67649C0D6D95,18,TEST5 +0xDC7D656bAF4BA6F486239C5e7d15Dd58b74344e3,18,GAZO +0x5D3ebAccb0C56Abd784C1c823b8013BC3e6d4547,9,TEST +0x02C52D96579E1b7E010EDc9D566BDb66067f116A,18,BREM +0xfe52C596070A09068009268cE1eCa3b1B8c6E210,9,ZARAJ +0x36920A48B417A7cF81C5d1E81cF82E430f6Ea5D4,8,YEX +0x065A793C36FCcb05D142A7E603af4c2CB7Dc8198,18,OCS +0x89fd904812e089d74dB40Cb61658bfe0812314B2,9,ZEBI +0x7FC0f388345EC0bde2BBf03a29d6080a768f74d0,9,CMC +0xBEE0564410b1220F63f4698bf786f59576793a82,9,TEST +0x60ed790D2D4890E424766A8f8aAc608e0CD2e158,9,ZBV2 +0x0118C06c3f937B663C71E6D2071986a4c662356A,9,INDIA +0xAc2a91d7d40F5Aca66CeEe99b831e5881Ccd9F79,18,USA +0x0D36Ca282F0CE2a966016cAF6304dd2317CF61B5,8,text +0xA435436372293Fb1835eCcd6d515D261317CcAec,18,DGN +0x033D056bCCA5360f9174e3A36fD9C3feF523A2b5,18,GRIBBL +0x35BF2c9D63a431F7EADF33DCc941f77FC9Fec1A0,18,GRIBBL +0x32e75f26e8Fa667488697A6908F3481b5d7bAC70,18,GRIBBL +0x32839b3d4DCB064B5BA8ff83366ED02CAa86e344,9,USA +0xb5012898772a2EBE73eaE3BBdB90376C98418613,18,GRIBBL +0x9243d8C2Af02C3F714eAA2F04C45aC5D162f7eD2,18,based +0x95545E6155e07a9E3C4f452e0C032EB645dcfb64,18,GRIBBL +0x1e7d250B85C0cf9873A2742d32Fd2667Cb65BAfe,18,GRIBBL +0xaC0D07c433d3Cca009ffA62ccDFB9A70551b7859,18,$SD +0x985a22Ac5f328Be12AEC0928F4cd037066D80EDe,18,godzilla +0x3ed208Ee0b54d3C9EF24e47544D957A0D0ad2FAC,18,gojira +0xDc4b46b5D6f3F99dD964b5Df6794c04126Dc1297,9,CATAR +0x81A975f090B6D58b53d8401591Be258b658Ba960,18,MOULAD +0x8B59408c9FcA76890b254b0671cb9DD814C4886B,18,RUSSIA +0xFA0eAA2E0b6E0C5678e69a4d0E2e68093B4527d7,18,AUTISM +0xA6974a17006868caa6C8A56B6eee8CA630Ad0444,9,CATAR +0x16FAA41FE9af4E57eD359DBd30d40367d401e9A5,9,CLIMB +0xb39cd760ca6CEBef5c8DB921dCf727642704cA0F,18,ROCKYCAT +0xe9109e0a2C4b59ACDA6e2e1A40E0814Ff922a24f,18,AUTISM +0x73aD5C044F6F5a242156B3Bb339f57beBcC8e312,18,SHIB +0xedbF01425044b2f649470e760af4E6da6360792a,18,Zombase +0x2ceD72800a97fCCa1d66e68049B9E662309C7dEc,18,FSWG +0x3Ace0f1f16F84875Cecdba1C6a9ff86Fe2eC12a7,18,KIWI +0x7e3a41F9aa73430fD6f6a7a62fC18d24632f0322,9,PIPE +0x4bb664CC1Eb30f2F12AA05952129d457407eA095,18,EVENT +0x3c4F23f82DA277F0C6cc8414505b65f9ABa8F86B,18,BUDY +0x8A0dEE598bA3e90c27e6D5AbFED6Ae2d48580D6B,9,NEON +0x87E669C4f727b59fF730dE9a772D0109330eF1Da,18,PRD +0xbbe45Af264feC09ED477630D96bB37683611F4D3,18,404 +0x2156006a207A793B4069a2B72BE58DC2bD759232,18,COIN +0x702ad32ad22F74d1d17ED2fd67E0690F5979035C,18,HOWIT +0x80b900A27CEd457eD1797B6F36523296C4e625f5,18,ENGDex +0xD4f074455ae0B0bF30B05C42acD105E5d2bEB8ba,18,BEFE +0x8a06Cf177ae2B9c52d68cFCCEFE8DA01ece668a8,18,BONKE +0x0E6a490ad60BB67dB54cc55AB39a642909e41D46,9,boden +0x59DD0Ff34AF1bc043364f7061908279B9fA7e157,18,STEAK +0x98637981fB6170AbB0F1bd998157884EEDCeA523,18,TEST1 +0x176cbB77c52dD5fF1d2d955E36519643f5e19710,18,CHICK +0x94d100aab8e5630bB4D2eE8aCBb09eC49cA07739,18,🐸BROG +0xB9898511Bd2Bad8bfc23Eba641ef97A08f27e730,18,BONKE +0x86e4E87da7ee6d6d561E09f64804a3288F1c27d8,18,D2M +0x58C55e82e52AAa96b092678250ad9F6e769BfC44,9,SAMURAI +0xfaE1e0514084F93974d3F5A6aA5c6734D8A85E04,18,TRUMP +0x858F725c1D3Ee7eFBb7AFcA907c705ef01dd8c99,18,🐻BORG +0x6801397C7b1F133275743Fa2305C2E7D00C0FEf9,18,phine +0xE67dAd6B09E3590c08F11CFeefCE088e3CB3a815,9,TT2 +0x8103F536F7f04837a6626ea2AeD8e5e56274756E,18,Phine +0x291Ef94B5ef8cF6a44A30408EB010b8747d8C7b3,18,CAT +0xB0bdeAD0689839890F6087b90e3f504d321E6887,9,$BOBDEAD +0x1b49D0ad077589c0945B732772ea48904Ec2b142,18,BRIAN +0xd64271E3826165303f90b4a7973569Ca4ec807ed,18,WALT +0xE215E4dDb4B00f680Ea66b48365Bf749C1a3a4F2,18,CZ +0x5A86197081f8aD549D00dc87D1BE556AbE85dcBF,18,TEST +0x49f5669bD3e7AAC3e502Af6Ae02884063b9Eb5e0,18,POPDOG +0x8E90708bfC6eB4FfC5eC17d19f3706fa65F4A6C0,18,PANDY +0x1Af923E99917d38de53D8282D71e6d15fBF0E1Dd,18,WIPH +0xAA5B8E0ECFB4f8e2d7843D580Db0BF02BF25Ee74,18,normom +0x3840F6a5676d8B38a6310492ea5BCF1B495A9Ad3,18,TZPHINE +0x5637368bF042977fEAaDB7A222e439B5a640948e,18,BASEGAME +0xFDC9D00609d5150c988447B7F0389454d49D3706,18,BGUMMY +0xf75A757F9bfe1F92f30a5Dc79DCF6798145e1Fa4,18,REZ +0x7afE48fafe626C9C212671cd6e34d5a1a7CccC84,18,GGG +0x91a96e9649a45aB674B2C336CAA1D7cA3B1d46Da,9,PEPBULL +0x9C5F31FF2Bfa8240bFe8606a880C8F52A20dDb7d,18,REZ +0x8c72e70656d8cfe2a320a5D25cE2358bf962a769,18,ELON +0xE830DE8ec53Ab96De37a665C73fc15395c92B661,18,BASEGAME +0xed3211Ab553852e4660E68B4D51E3B61875FfA2A,18,Summer +0x322E2BB894288F621046B41bacAf2030d4D48f8b,18,RARI +0x1D4F6893CF76f3c79Ad385c96b83afd0fef6d0e6,18,pipi +0x76c7E4dAa3027D1b97aa4148501F0AaAd223f34F,9,SKICAT +0x66c9bDC837346101a41fb7915B48140196Cb7Eb7,18,🐝BEE +0x98BCc780A4bbB599E69C5AA00c7a7Cd23a5f1b6d,18,MTK +0xa91285EE637638A8485c8aDF32c67d1e62819Ca4,9,DERP +0x8269C3A336FD5137c845E15145457947fFF09d79,18,🦈BARK +0xbdB68C97FC37Ab43d61b6Bb5732086145917865b,18,AIALRT +0x32a687C633216638B6D4008b08927838E39ebf78,18,LIMA +0xCEa8a2B7b3C05A44F9eb3aabab6528DD5EB24c67,18,🐷BPIGSY +0xb21500356E42C18e42fC9C9B3d47e7A9394751Be,18,DUCK +0x13e3728606cE3bd35F9A9C424994EECE1a63a9b9,0,GEN +0x7D5Bb368392712b855Db72Ad9966e70A7d1291f1,18,🐸BROG +0x7cF7B2418343CED382F2455225119CdA47242AaB,18,ASABOVESOBELOW +0x57d5a7C97d43521E6dC55BDc7925F3C194BB871A,9,GOAT +0x806Dd9E6b3cf3bbA7d9EC52CAA87be635bA8d5fA,18,🐸BROGY +0x3cf0566656D56481C6189C79fA50D73ceB3e85dc,18,BLAZE +0x6AA2755D4b9216727Bc7CEEb6C58B946d2944622,9,BROCK +0x489763970679EbD87F68f3B1F774981DbD18Fa4b,18,FROG +0xA08981A4DD90eB8bE171643897dc415d231E7Da1,18,BASESCREENER +0x0e671C1769B624E9865090818c606D205C296567,18,RAT +0x5b69Edb2434b47978D608fD1CEa375A9Ed04Aa18,18,TEST +0x9022c88B2E4beb374aF8CfC499A86Eeb497D1096,18,PIG +0x840D4C4d30Af1C8eCf9A88d8f89fc7b9AdcDE0e0,18,EWE +0x7fA7BF4eD36692D473A237681c32fd2E4Ff7c305,9,PORK +0x5633B35e713E10d3b903D6AF2a93af6A1fEfb219,18,SNPE +0xA73225147970e338d27bA3eCc41F4c2f0f770b71,18,FRGKING +0x7EBFA70685ABaf47a17c99c89c1E1bd9F4e6CDB5,18,TRMUZIK +0x515cB82e27FCe24DD433F13399b7BEbB000DB676,18,MEME +0x0740C8F438cEbAd42c9D3E034Fa71A37941B6783,18,SPAG +0xfF5588A472Cb1c61f22f5Fce93F15905e1964ECc,18,HAM +0x35AB8dF362C328784C06eB94003E481087E8B509,18,WOJAK +0xB00b55FA6e8D461fb2a21d67D20Ea9186448DAB5,8,BOOBS +0xD8045A207A735934dE3044dF475ca409Ead87598,18,BAMEME +0x9022604cB923483916c85E94c570D798E7A10A91,18,DAT +0xBB467Ad0201986c5B6Bcce2EcD23502fBA779cdd,18,BRETT +0x1674C0C6626dD52c3daD12E8963AABCD992e2A31,18,SMB +0x4B7Ccc073E896fA99E0945Cf106A7B25b78E8f2A,18,BOMO +0xbB102140Cb7fCED7D572201B32A07333b61d0508,18,TOKEN_SYMBOL2 +0x419112D60Ba269AFD155023bcA602262f58DD0d3,18,CONY +0x8ad4bd06Ec3c744fB7Bb9a4ac3669802E04F20Bc,18,BONE +0x79654DD29aC3e23b409DB9e76D9Aa5F54A4f9CC2,18,PEAKER +0x6D461cE72Aa3Ae04B987A2F0c91004fdaa1e01D4,18,BRIAN +0x21b9D428EB20FA075A29d51813E57BAb85406620,18,SYPHER +0x30F21AC6ca967533Af5985c26E60a2697F031F80,18,THING +0x6cA4054c3389E8990832b40A4f9181Bb29358354,18,LOLAMA +0x4f69a64926315B387293464513755a182318d5E5,9,GRETT +0xBB925676EBc735CB13a789E6Ca3BdBbA897E3b24,9,TT2 +0x197a233BF35391cC0751B60a8C2e5826D3B3aeC8,18,TOKEN_SYMBOL3 +0x980A3662DDbfFA895Af03C54E7B97CB3Bc868ed2,9,ELARA +0x5484cd4aD74b7B1b1fba0277E8227cB0f8581651,9,87 GAME +0xC4B60B342f636B244326545d18DEe198Cca75a52,18,CONSENSYS +0xDFcF1505DCEC4F745191C7b19F9a6a589406B175,9,EGG +0x7D18e63B5c400B52bda32E11b713123dAF977B10,18,SPARK +0xA4089E74354B03B56d75961a816f71432ff596f7,18,KFC +0xD586f2E9d876a970d61DA29c8CbbDaaFDe5FB8eC,18,SWM +0xF502Fd893AC0f416c745633d95A25dC83e16991f,18,FREECZ +0x173fBab48BA6AD560bA4AE0229C2C017c78D3Ca1,18,ELON +0x6087C06bc26D9eaF98519f24d2483904c68Dca8D,9,$NUKA +0x7BA075aF6e1a1990d09B2e90b9c949fD888C2F58,18,TESTBIDLIST +0x66b9851018b1dF5E7485f4A1135458dC5616aD5c,18,ELON +0x0c93C047cd3DAe729c4A40A00f2bb5b2B188e589,18,GHS +0x5e1773eB46E74F3a3511fdfE4ba730B3B50411E5,18,BOCAT +0xC138D50dD6d8d36E3252278e4990fa26c6a24CBC,18,COLA +0xbc2d0c8084704D9A0D1bc0D0FbB0a1927Dd408dB,9,mom +0x863E40e514Ff5819be58272F05E8655042d36dAE,18,DONTBUY +0xb572F78307a3f6126697A48BF4DBF00178cc12A6,18,BONKER +0xe1E88777bA95a9BAa44DC7ce96a33fB4F121833F,18,ELONCAT +0x43A4eC797beB5296f6a227cCaacb6Fb99BC32F99,18,FOMOCAT +0x44f91a50A7E9b6Ca0201007552d648412f595960,18,HELLOWORLDFINALTEST +0x19c978887B2801268a6c2cCdD86c756C196D2390,18,TESTWLV5 +0xbad61b71a654B3852a10b802c8931fe8828B9dC1,18,SHIBLU +0xd184F031C47B2070CDD498E418970DFFd00Fda2a,18,TESTYOULA +0x674ba47a05ef9aa67e5b2CDB75e29BE628c3cc0F,18,HALVINGCAT +0x4D223B5e3AfB70a40f26c38CC195F3fa2b563ea7,18,COOLDOWNTEST +0xe022cc46c89D55e42de76D34E4aeD9a66c950a36,18,MTK +0x19341A429E3E79110DD76add60A6f82B36aACe79,9,$MOAM +0x9516f22E7Ea98565AAFB1Ec129363a70E0ce7d5a,18,ECLIPSECAT +0x8ad5b9007556749DE59E088c88801a3Aaa87134B,18,FARTHER +0x0E36abaEb5D5A508618D1F159aE473F000787940,18,MOONDOG +0x7402DFca11ED44A48De760715b1Bfd78FE1Bd45d,18,CATWOMAN +0xd85EFF20288ca72eA9eEcFFb428F89EE5066CA5C,18,ISK +0x46579dD2c5E5287694Ed13359f7dcFE35ae2AA6D,9,$NAKE +0xb7C25B2E782C674863B702C9c560Fb0ee541e667,8,🐢 Turtle Token +0x1153B424b3F6A51c2571Ea06C5e9F6Bb267299a2,18,UDO +0x07839c30eE77A606551ad098dAbb0B5E86483FbF,18,G5LUFFY +0x87B7F955b8e3eA7F3c2500a9Ee9A8A7Fb24EBa26,18,BROG +0xb7B073Eb630a0aC8B4026DDc6790d5BD4997AC82,1,STTG +0x159060a3AcEE49f2d475f74A3818334e08b7D48c,18,🐵BONKY +0xA9e6F76880F3785FE69c09A646b68FFc88C783d7,18,BORGY +0x462438f6652790Afa014C173c0296e424548b486,18,BASWP +0x7B3B2d0611960e4cf461204Ec2FfFC67288ecf2E,18,ROM +0xe5Eb14b90Ec38E6357842D6537673f911fF19dd0,1,PORK +0x86426809C99AfF05406bCcC30Aafbf727F01F074,18,1 +0xBDc66999D8bFD1820D63A39D14e6afCFB78D2A7c,18,GIBB +0x507556D2E5505d669C95Ec55cecD6911764ebAa1,18,EUROPE +0x8F6A49Dc885F56b3f88FD396eb5cB23DA597EC7e,18,GIBB +0x28e29EC91DB66733A94Ee8e3B86A6199117baF99,18,BASED +0xA3a4273879e954aec3597e15904Eda408E3c4C5c,18,GIBB +0xbf8DA406799E527787CB2C357443933541A1Bd91,9,$MOB +0x733F438cEb5fA7D29D8d479BD3DcDA46E0C355d8,18,LEAP +0x24FF55e016c5257e0E8Bb27A2b082E9b0a607690,18,Oh +0x54Ea88F89f87F47607d5ffc1C7Daf0979BA15877,18,TRUMP +0x223A334BAe731E01Ac039e959DB538Eed7c3e886,18,BRIAN +0xa9cf3826d04E8C1DA0563A7AF24E5D1EBf04a488,18,BAPE +0xdD9992eFFAE4604F1Ed8982c090726Cb40DCc1f8,18,MNT +0x27EA5F0eFEa5f56bEB04FED2334Db9EaD10dE61A,18,BAPE +0x8bd1E2A0DE31D6d6A7FB4d0d50916Fdae3c64626,18,BAPE +0x3De7a5a85c2687c0E21e7b885569Bd0f0366426d,9,percebes +0xBEbe686538Ea5741950bEa2B60aF94b9499d834b,18,BAPE +0x1288b38eFdB52E28B1458766C9851Ec152E51a4C,18,DRM +0x0c007F33668e6eAe79F733E8e8057840E2aaA05a,18,BAPE +0x265A55A2632ee1dc780367F8c004509F3Da9E3a4,18,BAPE +0x2942b36c3e7a40ceBFCb3Cc5eF088E5CDf73ad1D,18,BAPE +0x68c8E21b6e7F136700A68685aE9c99DD3974CBB1,9,TestToken1 +0xCfB4e15c900bF1C8B51f60a3119a1A70C2f19460,18,BAPE +0x6721ef87a19560A4C8f6F39D33C4cfcB8A915046,18,BAPE +0xd43A1148ad5A8d8FFB4Eeab92eA12f381861fA2C,18,DOCU +0x2900bcB023072503bb496A923C86209B66D5d48C,18,BAPE +0x49Dd99A2DE48881944bD1c7718eFb42bd58CC1A9,9,$CASCA +0xEAB5917784285864a8F76FD3228DaA6b9134769c,9,PEDRO +0xAedc69B2e9873DEacB63aB1762D62b8d28AaDa65,18,20 +0x1Dea9962938ed7Df427a2493870F21Ece5C57a9D,18,BAMBI +0x246c2e3E0e5024aeD6192105575EE48c7ec489AE,9,💉 STIMPAK +0x4f030f9952236fb24b46C7c20C92c34A4Dc737d5,18,CZ +0x98B4793f8C7C76D47c0527Cf556b03c9Fe124a8C,18,KMNO +0x1243C5F1D0f64fA291bD5d44d2c7A53488F0375a,18,XEPE +0x4F388a46D83C167744bd6551faD1Cd3185dc876d,18,Bald +0x77cdA7dA3cBDFD41B08e9fE70F371213EfF34670,18,REZ +0x5685De28034D25A60c8a47405E83f4B8a814680F,18,PUTIN +0xf8B7315CcD5fD9c6DBF2e510C4A870013ec82aC7,9,TTTTEEE5 +0xDC4F74f4dE646BC9B19c2465f92f7f6E75Df2b3E,18,🐸BROGY +0x8daD3e3A74BDa3db599579F47057C169ceca5600,18,SOMETHING +0x39A2641250f349a9Bae3655D21Abd98532582FE7,18,ELON PUMP DOGE +0x5711b11EBe6a61d176606F7e7B0792C5c5548b1d,9,BET365 +0xEC3872544559B58ae25Fd5908F4A3F8C01a3147e,18,LORD +0x815066C8A2e9698e72257E61d5Aa477e725CC9E9,18,??? +0x994E7Ec1009636D1ed4632977C9F98E283501708,18,SPPE +0xa042d74EA8B28C8C1BD27f2Fe053ab0428425191,18,FROG +0x49af724c286b70f7EaB43abC57af5c0102f1F89f,18,QUBA +0x498fcC525A983ebb5A8c6061D405611C01305430,18,BONKE +0x4ea43C5aD2a4b1c6bd226eF3ABCA559394663d61,18,BONKE +0xa9791Aee0D9FC36a4d1E9838C6e642042967bF8E,18,BHC +0xD8a861E74Ade43262C2F36c8c97E7D546a99e50E,18,CALI +0x8BFc82f5275B397e35DFeD4DfC776F2e64F59B18,9,WOJAK +0xe54CdAacd9CceDB9643E52B322B465fDccdeb3bc,18,PepeQ +0x395061889b9F14DB3E95F65B06438773e22b441E,18,THICC +0x70bd9B4619B0197648b975b947FA831c4205e023,9,$NUKA +0x6fa0e59aF8146DC67ec70e9cd8E0710EAbBc03b7,18,TRUMP +0xa8Fa69Eb0ac6851365BFE1bba0DF65E724Ee92f3,18,BRAIN +0xB931b8bE093AC0285024EB56Eadc2084367ED1BB,18,MOONDOG +0x05c2931dbd96D9e25Ff5b46ed2349cb73a71f5Eb,18,PRPE +0x22b27243B8c487Af56c14770f2e1B016874051c3,18,TOKEN_SYMBOL4 +0x1c8C3Fe80F1F54aE40565B49c226c2CeEAde9b09,18,SPACE +0x86Dd542C44DbB3A689ff81631FD201C7C99869bc,9,$TIMPACK +0x5a82e4E0219F034E81FdD05c0150EE8861bd4AeB,18,RDY +0x0ca85eBD24a3863A9b57DFa6DFC25aEcA7EAbAD1,18,DA +0x6B6df06D9d4322c7745b590D1D7bEa370134348c,18,POPCAT +0x9e150Eb6063db98B823b5f37710040E6366a3239,18,?! +0x67c71ae37aEeb690ba60e9DB49EBe0a1d06868Fb,18,TOKEN_SYMBOL5 +0x78734a386Bb0313EC59Eedf93D11baAE9d7b5465,9,XCIT +0xe33095626981d6bDB51Aad2f63C647e92Ff06010,18,BaNDY +0xf6D464d9519b3eE9D823ae97613a967a4Df270B4,18,AISMRT +0xD266C63335372E31EFb36159D55b4271AF194526,18,FREECZ +0x3c9F337f0e09176895212FEC54e636Da6542120a,18,PUPPY +0x5E8d6648d4468D84c0A0Ad808F77Dc71Ad160783,18,SDREAM +0xD8B3a7C2829A22E3DC38d6b3D3ce68a4B6E4C1fd,18,4 +0xf7b82126129AB26fDE257658165BE34119201d15,18,GIGGLE +0xa1306c332EDb5CDDA7f996507fB48F2c4126D621,18,SQUID +0x4b369e1a2D16ada09D734b1D8485B9d1C5921Ce6,18,Friend +0x5F65611394ecBBa1A7Bf5906217d79f31BA1902F,18,BUGS +0xABcD7699401926E6d05566Bd38Da95aD4CC49D9e,9,PepeQ +0x0504fB2c71755B57A1CA19118b8cb15E31f06535,18,4 +0x499A12387357e3eC8FAcc011A2AB662e8aBdBd8f,18,STRM +0xd2Ff7d417F8528c62C2dc45804bEa31c77117c9e,18,PEPEG +0x3A5483d7fDcBFA1e1a42d8BBb7b3e2EC58024b55,18,4 +0x7CB900c533bEBB545cE799F1A2d6605A592091Da,18,GIGGLE +0x15De59489de5e7F240D72F787dC4a292b8199339,18,RBF +0xD1A4B3c0264B5ef7c05fBeAEA153e2c616180F1F,18,4 +0x92988d3668d3dF8214249CF6e85c0539B36458ab,18,TESTB +0x9D1fA9Be2212062de90228Dfd2F4273e531658BD,18,TESTAB +0x50047c53A1f233234C41367bc743BC1bca032e94,18,PUPPY +0xAc463174c8109C61117E456e9Db1C344c9A26FF3,18,GRIFT +0x6Aea4753Dd14802Ba4ABE42E9007F66CADfdddE3,18,4 +0x2C63bC20EaDD0898Fb70f40DEBc4d2c8A51F9629,18,CHINA +0x5c3BB62473788fa0E8D64c752F44c58325e56b4C,18,AWK +0xAAca2Ea30e24D8f31Edd70Ca5f7a9Af8e4f258A5,18,🐸BFROGY +0xBC3d0f16Ddbc9595F03cDeCC03149dE96716F18F,18,FJB +0x9AB5e614da0567Ac836C0b1Bc11d2F8352F483d5,18,TIT +0x89CAd03A404366748Eae121f83d4239Bf795Bc0f,18,CZWifJail +0xD6D73A0c1fCd72c181A2f2c0164aF51347273228,9,FROG +0x90Cc282444312842082ccFf272af10D7c8d9e415,18,4 +0xFc8cA9c96d9adbdE34B005BA8fb19394d07593B3,18,BOMEFORK +0x7FE5aeCE12Dc0A65087405c0479D51aEa63f1B4F,18,CATWOMAN +0x9584B3E63895E277AA836031E38914Ecf732c0E3,18,CATWOMAN +0x12Fa26FFe8C24d98fC90b5276cC771482695A665,18,KUKA +0x788F23106223c5233605b1d981FA8938E77D40C0,9,UPROAR +0x6dB60E89bb084C0D53bB3415647800beb7241C27,18,BOMEFORK +0x745127667a36b0600e9FF6d19B9C4523D034F820,18,banana +0x4AA3E2969d402e640912Cd9BDEAc1C363687c8c6,18,13ETH +0x78a6e5A4Ca891728815e8d08466bFF4d92b2d7e9,18,BOS +0x3015b0BE6eEbEC0c628f5Bb9484d66bF9b1c7561,18,4 +0x1D24A76A12f703e444cF755dC8c6999D89cf125A,18,SAIL +0xcC3878530D22ED37c1086b5dd4b9cf461CDF3f3B,9,$NUKA +0x9eEAD3f715e9988f6700cd608689a97d0330a08c,18,FETAAI +0x60D4d25D8b187e6B4c3c1E81C09E8508c2607f40,18,DOGO +0xB2A99576C01A06c193266A4b46a7fD0f9F31b9A6,18,BS +0x066DF6Ae7f762D850932984F0111E2E95d45aE9e,18,FROGI +0xd8A57617e3910ffc08b2A5981BC1904769d499b9,9,TACLOL +0x80Fe9e82A8E81288597E02A054C52109f68724Ed,18,USAvsRU +0x6d803030f4B34b14bBdF07A8Bc62C62A9f35119c,9,FUNGI +0xE70c09c141e59bbD0010767152783B5a1F1efBde,9,FUNGI +0x087d4b348BB1dE3279D077e4ce1bf94c656ed0f8,18,UNICORN +0xa51910cd166722220240D5b856c0cc09568b0D4A,9,FUNGI +0x10Df04EFfC8Eb48E3106Ce3d1062d3115E174f40,9,TACLOL +0xCba2b8E12DdAEF9Dd572a3938c849BcDFE4c4fF6,9,FUNGI +0x5e63AF52db227C38c6424810c282A1e1e7Be9cA7,9,FUNGI +0x257603a3Fb55D293242Efc74bE97ECaA23cCfedA,9,FUNGI +0x6Ff6c03AFB17599E27DB87E85ac476F19FE29a31,9,FUNGI +0x45dd297ad8376f005cFFC6Faeb7395d5396e83f6,18,🦧BAPE +0x4a6d30FeEDB3329F1DF7547274f4a052141dF5fA,9,FUNGI +0xd6aF14b278A168660cFA3F10ac546c029C4AA191,18,CHAD +0x6B046C9Fa06612b6716f13dB7478cD19A191b80b,18,YAP +0x4C74F070229091f3786d24804D6d77224e0Eb478,18,🐸BROGS +0xa720C4669c56E29B1307e8828D1FC6a7ae7E164a,18,AWK +0x41c1156437BB1bcde2381908DF88ebd30e06EB37,18,🐦‍🔥BFI +0x86DA048dd6C688FF4DDf96d3ff930545c7FBA87E,18,🦦BOMER +0xd487a20CF26eb8E9cdc8a7C2430895Ea7EA4C628,18,BASEGAME +0x80821deDE402E4c2C4bDE6Fba556c94AE26B4709,18,🦦BOMER +0x360B98823c6cD060bd7A711f84852524D5f3BBa5,18,BALF +0xA96F21CB9b8Ab62BDD643DE59eecDda048c7E17c,18,🦦BAMER +0xf18B801B616b9C0B81829E7Bb203d8F690B7CCbA,18,Trial2 +0x45AC7Ee3Eecb9FC052CBbE0Dde30D6926EacD637,18,🦧BAMER +0x08FfDbB106FfE4A8744D8561Bf115712AB7cDa5f,18,🐸BROGY +0x25F160C0253a8D36Da37E8d8b973557A242cc988,18,🐸BORG +0x2b2C63efc494beCdd46F2a76865487FCA0B537B2,10,$BABYBRETT +0x0BAA2074FC0351c24B9787FAf54AD720663566dD,18,🗳️BBOX +0xa956efC871027eF364b19884aF6780346Bc68888,18,DS +0x24C58B14e27bD9482903A423144421a019c5ff5D,18,SKIBIDI TOILET +0xEEE388746D1C95388D4DB6135181E9E3c9A984c1,18,🐸BOMER +0xeC489d9986fcD5F4ABc2B81d47ea3F7d8332DE74,18,🐼BONGY +0xe62BF3482AB46Eb44b16d44fbD3F90Bd600fc4a6,8,COFFEE +0x12580484eA3cE40438E6FCD1cA5Cd87a3cf24279,18,🐸BORGY +0x2EE13A1bE52cB8c365bDB29Fc9C4A1fBEA520324,18,🦥BLOTH +0x43D6445340D5a1D9d207300377Af08eBF3Ff87EA,18,♦️BGAMES +0x6ebfE7B0d18C9B64C8735b4bb7C9d03C456622e6,18,WHIRL +0x6668D4A6605a27e5Ee51edA040581155EddC6666,9,WMSTER +0x226fB3663C34cb07bA4269871fED8957C7B3C92E,18,GC +0xAbA67ee06FaDe40762d807DB9104Dff768F701b1,18,🦦BORG +0x99584124d4a94CAb0662739841e12754261856C8,8,COFFEE +0x813637CD66234FF152f6A91572B9d01a320c6332,18,ARTVIBE +0xBdD77a697bf3eeee8B7B17E3cA2294654C61d965,18,CZ prison +0xd0b91Af5f0cf202671a15233AD3EdEcaA578645d,18,TECHTRIBE +0xD3e0750E36738D0b71697E0b220E323A9a78ffFD,18,NATURE +0xd1128abB1de375419cdD709E5CD52F8741C57896,18,🌀BASEG +0xe6FA221bbfFcc717B3A0118cf204F676D3037471,18,$NVDA +0x21578956E85fD3920a43D418A08343695e91054D,18,FUSION +0x77217282E696ecc257a3b9392d317eD51a742B5f,18,CuteCAT +0x06576714914858aF94535E89d465105Ca8ee52ec,18,INTRINZ +0xd77CD13c2a72b20668bED8899321DaF97404fd71,18,4 +0x91Cc30cdc214896aA5846e2DbC2E164E9951e0a6,18,FOODFEST +0xD18879b9c6Ce1C7748700c1828bdD0807d028DB0,18,BlackMamba +0xC89828ab091c3E456363C28c3C1810816F45171F,18,STRAFELLO +0x1A005D28ea42e488Bf0Cf697340Ddb57aa99da16,18,VICTOR +0x304b6bc6951673151D4C008F7a0D93061fa4c470,18,BASINGA +0x32Fd7d5E040ECfED6cFb515E3Be77abDA12468b7,18,MUSICIANS +0xaF3dD0a3EFA93d241E8792830f304140F492499B,18,PALOOZA +0xa3FEd98622e304bd2f9616aDB75Bb018593bc040,18,BaseCZ +0x1B0CEd3847A4d7aD20b62D2888dF79cc02Cb737b,18,CHOWSKI +0x35C89d505D454200Afc626AA5B889821c0a782Fd,9,MOONER +0xDEDe7EaBCB2CcED33176C8A9157079D6F0d9D07c,9,DEDE +0x8AB62Fa73f8af2AE2C9473BfBf9F32A19E79B019,18,HODLV2 +0xda5c5B144340Ce5764Bb27e7E70704cbbbD7dB1a,18,TESTBIDLISTYOLO +0xbD028c5Ae52718f72771B736a051c99E127f700b,9,ELON +0x95FEF47A3b34ebcb59BA29F975C0F6c8A99dc449,18,RFC +0x2Fd4EE867C1A81228a930a688Fb9A543e427c07b,18,test +0x7A31512FB17BE839B24276C211E941932c9D20E1,18,Nippy +0x922bD9FbF286B85f54e17afc84E4974636aB6Ce7,18,Boysclub +0x926b2b9b7CdDEB454e1C97bd1ef0dF492300C0D1,9,SMURFCAT +0xb3b07559257418f8999Adb476d3Ff81a577fFc05,18,SIMP +0x8724AeBBc83787457977494667251485038e6f04,18,IBET +0xBc72c1Ad220315Fa849FF237Cf5DD0ad0Cf75C73,9,cats +0x2266E0b44A93F1930378fead21864d93F923dC75,18,SOMALIO +0x12727921A8C6A22932cf283f3677d9F8AaA6BE58,18,UNIW +0xF3907Bc0FFF5Ff5aCf1E3dD7987005779C7bf57d,18,SARCO +0x1DB95BF1980688f68602b66188d361195758c0FF,18,TEST +0x11385D53d3436FB61a8272fdb8fd15fCb12bEECd,18,PANDA +0x80E3Ee7bAB68fEAea6e01c44df9daa5de53e4818,9,DOGE +0x87841b30Cf177F9EA30f40f6844a962D57f6877E,18,STEALTH +0x5cE4913fc24077B12cb67485f85C7D912B0E27AB,18,3 +0x6e1E2Ac8F128c3A328C7CF88Eb2C5dD9Ef537dCb,18,KTESIS +0x0c7195F92E4C12a8288cfb49786E6a9a1F75C8d3,18,HELLO WORLD +0xD55b95a1B2BdB2496f4E1D41f577F97d036D300F,18,BUTTER +0x99A9cCEeE7A89fB4053c1b4729e66A7d5193AA93,18,BSN +0x8b22DC9BB9077f56aE2Cbe60705a9BEaf838033E,18,FREECZ +0x82649262b8414892b3227E95644D7ACdc7C76655,18,WIPED +0x6C8cf870d993199ceDF0d2da5D0DD3d7BfBb751a,18,HACKER +0xb82cFFFe1d76f1caBcf8A00774c0287d71702fC9,18,wRAWR +0x93587edD0dC6209475d9B5e7d358f7a40676f444,18,SLICE +0x7049F9083c13Fa2478da974b528af3236941A405,18,DEPIN +0x8c9Aa93a32AC5e0bdfCb7DD0B0117F9820E5FfA8,18,MEAT +0x6515Dea761BdF6c520a0DF344AE393F13EfD9DBD,18,PSHR +0x6710f92A8724383f5830b0D71e6911f8099dbC84,9,POPCAT +0xEAC5859De259F57B007FbB9fcC4b0ACEc2AC2195,18,YEHAW +0xa4194f73Ef5A37dFbC65E78082A9cacAd80a162A,18,PSHR +0xD3741ac9B3f280B0819191E4b30be4ECd990771e,8,DOOMER +0x3bBa64ee0b7428816831101801f3F45B8618d47A,18,buno +0xe1EF3F26B67857AEf67350Ed58BE217a6a2EdcA1,18,DOREMI +0x2C87923DDFC87eFc0413253835D35926770A8807,9,DOGER +0xC27Ca05fA66281Cf97EDDAc3fc00e1ECc067F215,18,PILK +0xF3eC3147D4f86cfB7308dE5F34D4CB287A16e7f8,18,FREECZ +0x575c6d7A1Bf7Ad34AF2FF5C29f110b48e13637CC,9,GOAT +0x1ABf86495551d6847d0D623C74C55bF92BABD968,18,PSHR +0x301002424756e62505e527b0B7EFF8bca3447be8,18,zazu +0x98a9F9aC20f72A1ACeCc4856de426AcF11d77170,18,RBF +0x36DD9128D8DfFbb88F2aDC6A61097fae111F1626,18,4 +0x63fa555B66cD867128cFEf7F6080D6e2D397277a,18,SULIX +0xb52fAC2702b68F38c8005D93fBAa54a2225751cC,18,TEST +0xAc7dbd7171BDbf4Fc92403f9eAc9742B1c2E3b60,18,TEST +0x387c9455CD4CACB5a31f4d79F4fcaD605F862C6a,18,lion +0x615a85aE81245a6a6a6155B65377b6c38C6d7c1F,18,TEST +0x20293c212D0305FB0DDF4955aEf69e325177F262,18,bfour +0x29747ff8F6388651ae116B1722cB4546ECF0cFD5,18,FOUR +0xCc82c277F421a52f816388f3346530BE1b3127A2,18,BASED4 +0x51707DC661630F8FD624b985FA6eF4f1d4D919Db,18,UNV +0x279e8562932CE694677C70c06fFD57C6f059ca06,18,CZFOUR +0x74d824994A940cc94651E6eD0Fd3e3A482a043c3,18,BREAD +0xb874a785C59289363876E3C301dA707f2F2Fff33,18,cz4cz +0x08f6b7280e2af851e956a80a52b20DAeE74973CE,18,FWIF +0xACAd1d3107808577022387C07512E7828694B2a2,18,ETHIX +0x053B8e1B9a6d12a4b04F4E00DDFE9C30C871D745,18,AKC +0xdf98ED5eCdCFcDc585C5f83D18f9cf567FdeCB89,18,con +0xb9cb29d82d84D2A5491c5162e57714047DD621E6,9,$NUKA +0x7C875604abBF9E832eE7535C9F05cc0B8EFE792C,9,$DEGO +0x338E69FDE17270B3cD5FA24655371d7F6Ec260b3,18,KISHU +0xd66A0991B63CB0cB9666d10416B1Db2E6B84C1c8,18,JUSTBUYBOZOS +0xb3d244D24E1f65199F04bF8bf7D01396B31ADb68,18,DOGO +0x57bB328A91657c817beD1064b94064f2b25f9D12,18,KISHU +0x4A980CC5b59F69e3498Dc24235CB7126D47ff68a,18,lion +0x7C67ad4a122333C404f9668D3789Aa3166031ab0,18,Exit the matrix +0x5C54C69C7bc62aD730ECa31b377010f7bA241A29,18,MST +0x3FD5EdAbe0F0C1685E0a14ba4f9e36cBfAe85ec8,18,FRIEND +0xA714Ecc367e00302d46b0a44cB2203C52Fef59f5,18,Zoomer +0x91Ba2806A9E5A43e15e7b81025CFfff08209985b,18,MOGU +0x5846c072C18fd5FE784A78224da3085346B8C2C0,18,TINK +0x7C16Aa51d658ad9A623dd066E77905e4179563Cc,18,MTK +0x75d337710cFF769090A371F8b014B9E6cDdda3c4,18,🦥BLOTH +0x53e1252C96B50F4a0B1D24f6C21b784E87b6e083,18,Europe +0x8950b90676F20Ec336626a4Ee61993bdcd3e8985,9,$NUKA +0x73FA0572c7f77B44ee88B78ffcC2ff519d2EC222,18,🐸BROG +0x569e1A337b095B1A6c8F206158072cEDb6325b56,9,MIDI +0x73b255353d4D76F3A3A35e37f49CCBcB90377943,9,FUNGI +0x14C7F3E2Cee45E439108313bA91ADA3b26e4d5D4,18,test1 +0x8fA11EDf65253c15372d7E7EC595D5628E8930eF,18,TINKER +0x694C79DDEa7Fc14d78070D1c2B7d4cdD0863f1dB,18,BAZ +0x8592354Fe71BC73544602227Edf5Bf59A500d9d2,18,$TRUMP +0x263337143b832B1E274F9E047cECc42305A2e8d2,18,Waifu +0x2d448bC9a98d28cB094722c2B8208916A248D5ac,9,MIDI +0x7b4674FEfCd10c9866aD1d8d49f3A6691f6746E3,18,PSHR +0x918BB976fd99F5f8418B859b9bd5aBba266c41BE,8,SLOTH +0x0EbB289148e7B1b492fAf6E30B7817889091eF1F,18,VATICAN +0xf7Cf2DF510bc0EC400232874f2fB4F2cDf9352d6,9,MIDI +0x874D61443Cc13716200Ad7d0c8D1608cAdc87ed6,18,BTT +0xD9acDbb82BB0afb8C0400419cc1D6F9c6d31Bf2a,18,SNSY +0x070899689d2a3158986f32F76dE266B748b29459,18,PARS +0x706b353fad1db63D6160eD415D410d46Dd5De453,18,KingCAT +0xcfe51959f913B08a82EC0D431e9455b5A629bBbF,18,GAY +0xAF14a47e831890d8d85FD6C136987fD940894168,18,SCARCEDOG +0x6e8623C8481395E0b4DA5A7427A1dfb1981Be17F,18,CZ4 +0x347AeDF8750110953b054B1dB63F57694Eb93c09,18,NIGERIA +0x8f2c7104dD7891Bf9B27B73ca7B2796AC4E21750,9,$NUKA +0xB846dc079E2A0eEad8A3173Eeaa0f1607b67E27a,18,OOOooo +0x45d2AB668980266536c58Cfd0513e7e27725235f,18,POO +0x834B55D18ECE23331D978d7Dd64eAA12F26beD03,18,Kimchi +0xC57977faEfBC146234594C8C2AB5b21108ec62d7,18,SYM +0xC9359C9B0D28EE04825C94932AbA31a4ff2124d8,18,RACE +0x24A672bAA45A4246635C3d8ea156913FE1b2b288,18,MT4 +0xF3BE236b50aad54646Ca20f473774420f894c80E,18,🦧BAPE +0x8a4fC47807B49D04E8D931B701Ec42cF5cD37C0A,18,CuteCAT +0x0079bbEBb3b58424B05720c20caC32a4C02A32E2,18,MONKE +0x689b2629B71D367b2Af6F8EACad708e0F48194BC,18,DORY +0xceC293b646520395D5992031EE4f5AB39e5eF6E7,18,ITALIANO +0xc29315c810aE8B0BBe883580859482BF710C628A,18,MOGUS +0x8b099E0FAA984BEdbBf009210680Eec11dacB1F9,18,🦦BOMPE +0x67d73A9bCEC2F681c2B4E298B32c170b0543B9f9,18,hej +0xC3A56536Ca667A1ea6372919A464b0861147490d,18,FER +0xAF5D0F7b4F138fb663E5dfF104370C57511D5207,18,BSB +0x5C53B393E96aa70Ca66D6b7def4C8DaE0AB6ea55,18,DONT +0x5E32D4b6B8E764A4A48f79065757983FB1FC6f3f,18,GER +0xA722ac0A4472A94Ccca11c6C17A0b25bF68640f1,18,VER +0xf1dD1c9148eF2c57f1Bdb7e52Dc4d9592E9C982B,18,NER +0xd7dbe023Df5CC998868Fba987531E6A3b823D047,18,EMOB +0x69C9fd4f0cEaa6002cE3cf0972c56255CA69cb8c,18,BULLRUN +0x2A23444C3Ecb438ADaAFfC4614fFfaE6E99f3F9e,18,GMRX +0x3d238aa2dbca11190d741c0305Cb729f6445aFC5,18,Scat +0x040bC694573014948dc6a8AAC2C85dC5cA09A765,18,MEWPOO +0x12aB5946eC6A53801D932eEFFCC691C98b370587,18,MOONDOG +0x17D8b367B943BC469393eF213f0975216821EfBb,18,FROST +0x50bDA2A16A130a8B71695FE3aE5EbFA0384d71e5,18,??? +0x0FD93ebAA9535Fb79B1c5D5C02Ef012057Ea3822,18,??? +0x2Fe75Dc03dFF95aB713D492b31a2c7971856fEcb,18,BEER +0x62a19897fe3DC18410c6E0917235133453B3025C,18,??? +0xE9F34d7B0634a3d4f968302B8dE8F6D4187c127a,18,BURNBUS +0x7d0bf08e4b666380395738e33B1cE71C6044d8e2,18,CONSENSYS +0x991a6FBB168Ce6D0B9965Add25f9f180743a0c99,18,CONSENSYS +0x0296Ba3eD1ac005698CeE17206b45BEF35B21c21,18,CWH +0x1614A9BD46C1Bd174Ff55620246d12f26Bb88dD0,18,BAK +0xf1181F59C964e421D7778e588d2DD2ee7bFDdE7F,18,CAPYBARA +0x19DB0087f5DaC10d9bA1C3Af0E1D1B13b1998148,18,COFFEE +0xeF7bFe4cBd8F16EEAa464665E8D03f1AEEAE965E,18,KROW +0xd981C33aB52FcB53bfB959EE0Ad1DAf1C381E314,18,PUPS +0xB4eB0a7bA39bAA314131252d9AC66C779a15B899,18,MT4 +0x4989DC71611eB2B55D309ef9a3527CAbd725EbAE,18,$bichi +0x9b012220c0f48C7a4A98B5b4f0BEA9Dd67AbB9f2,18,ILY +0xa1d75013Dbeb1b4b909dF5aF56FeB98413aF55Fc,18,BOYSCF +0x64d761061AFdCa42E8A9412A024116c92D6D0D7E,18,SOON +0x1DEF9D03c13A5B56469a22F5F2CD580E1CA071EE,18,NOPURR +0x96b9CDf0816A2E542A93141e1e5688dF507825f9,18,DONOTBUYTESTLOCKER +0xBeFa356479133201416d011AC89C0285BE24A8fE,18,FRIEND +0xcAFe45b2EE3a4245c16df7156543d196650FDA15,10,MNY +0x3e7A4dBa88FbAa0d978CcBF899089d30C5b1754a,18,RICKY +0xf21832438e3b440F581783FEFF9A851bD1825f2c,18,GOONER +0x6779aB4ca4d1E64Bab06577A5eb6cf736e94Be9d,8,SLAARB +0x884f51973a35b6F129c011c3818D9a20C22d7f9e,18,HARAM +0x9a560d908A51277012FFDa0Ef0122fA4B878C10f,18,BOX +0xa5c5867B40f8eA477D1A114B822b51ddba98a11f,16,HANC +0xf78BAC4532A943C5992f7124f667F96522E33eFf,18,MMT +0xc4B90EAB71DE6e174e49FCc613Fc10D4c782f970,9,KOALA +0xE81936Af3e9EA94BE72baE962FBEFE6946C39de4,18,BBETS +0x434304d95C5c44187a09340caC414B49bC4Be520,18,peped +0x8db905F66f6F52c0f8f11b6D563810471FDB3dc9,18,FRIEND +0x54D36E79c4Fdc9895FB031777Cf4D978a1D18DB7,18,LUNACAT +0x46C6f19D05be7c2D2170B1FF6cdb0e632F1b2B3B,18,BRITT +0xDab24425Be6a9B88620EfBda279ffc15D4CA40e6,18,PUPU +0x18cbFb48C0fdc7989245d63D9F5c4bEaF478B6c9,18,POPO +0x09230699598A04044d8036ef4203e1faaB193419,18,GALAXYDOG +0x8a0718972cB74966c09bA1aDe766b9A6Bf5162d6,18,3 +0xECda5dB30Fe7fDE5b875B0d62103539752d882F9,18,BoB +0x24666dEe6d17EBB0c0af62E144B1b6176F9228F6,18,MATE +0x57e2C965281AcEC4aD075FC446d418Ce6CFD692c,18,PSTL +0x3aa236e543CB9Af6bC56eA365f688317327164Aa,18,testcat +0x844318FE750640C3F7DFF8902720f48D1d1F0535,18,SCAM +0x20B33363e9e58fa1D611e5b48E3dB14aA582201C,9,NEO +0x4dA6759d909D224815cffC84647dAed33c8CC8f4,18,MYLAMBO +0x6CdF4223814dE8018d3ae7ab1631850863CDbAF7,18,WIFWINE +0x0fA43D4Ba5c8321Ff521Ec880B282C81b7F4017e,18,BSBS +0xBC821a77A4f9328c335F13B2CAFa10C4f5756282,18,HELLO +0xA67780dfE86169CE45ad8df3b3D8Eb08AA1900df,18,ROCKY +0x84b859196c608f9CA716f855A9D5D1074d98B3b9,18,PISS +0x60ac9092a6543345FDA439A0C8613b2B09C5326F,18,ROCKY +0x4Ea7Eb10Cf0f79E33AA26431126B8B98d1C05fCe,18,LIVEMOM +0x8Eb48D0C02D061990970b88f327F9636B2C8f2B3,18,Tst +0x1f1740956abc645D2d355570E6424D872B8f289C,18,SIEMA +0xca08107F9Caa0a3b1100Bab1696d069C79BF9f90,18,livemom +0x8b908462272bF8870011ACC71DAB6839316089CC,18,SMOMMEME +0xD43a1CF351D2364772E05116774A3b35dAB861B0,18,RDBLL +0x496d847DDa30Cc561F4F4E01689e3B5229C7e092,18,BABE +0xeCba110DFcCB7Cc82B3edF8ba4AaD93A0b0f108C,18,PEAKER +0xFaC65b9C1354736892893532A68c8a6Df08C7B82,18,BMOM +0xBA3FC5f87692E676489E01ecD5FB5Fc4d3507c1F,18,Ricky +0xB8F7Da22c3A54dFC7CA5da675aCdF7F76BA094cf,18,4 +0xaC704c8e6B6aec869B64fEb4f4eDb4172c74862E,18,elo +0x15a9E5e5D99b4aD7348DA5843DBae97739174f78,18,EUROPE +0xd316C1E70a23B81b413D7D610EFB36F31A51Bd84,18,RICKY +0x79bbb9fe2416CaF66b1ee902c3CF50f0EefF627A,9,PLACE +0x925c83bD25E77229fEb8cC6690Ac191C07F07b20,9,Hype +0x93CD10bBA6Add1A79C3a66A1F03eAD0508496e68,18,kenyca +0xa0741B19F5f56D6f779963481fAdC08bfeAccA3d,18,Ye4Head +0xfdEc795574e60cf09CB20f3AE1100605A9942791,18,DEGENCAT +0x9808500F1F0F89f8baf1d381F6f6F55D270F4a97,18,PARTY +0x327D447370ADB0dAbA10C2d83508eFFA14E59667,18,RACER +0x3b1b755724c2f0a6227e43369fBe7476a6a5526A,9,NEONP +0x8e47cd4DF9B63D6952B7F41F8C2e4FE271AE56C3,18,BRETTY +0x3D172D8a854A73336aC800E30660b7dE14e40512,18,LOLA +0x2701D9920403b50682B7Cf5EFA5927C7AdD52075,8,GOME +0x0bD4887f7D41B35CD75DFF9FfeE2856106f86670,18,FRIEND +0x5d016F7c1a14E46dB391342E9eD418fF18058426,18,DOG2024 +0x1f1Cd15bE4cc3f0A992818D56F678a9320Eee943,18,FRIEND +0xA6Ff79EEFf76B1546E2E984e0c60F12e8D8A98C3,9,$CORNELLA +0x7E3faeeec46a4649b084927E2d465b2a699f6b90,18,ENEMY +0x9d380330d3C70FEdE3145E4AbB8CbF7D78c3bec3,18,CZ +0x7fdAa50d7399ac436943028edA6ed9a1BD89509f,18,WBNB +0xd01DD689229177cf9cF1739827F191642FafF318,18,SEC +0xD3E1d0816B984c1250A8231719969c683f4A7921,18,SEC +0xB555Ee1497C7ed48BedAa9eB0bf230fcb90D5826,18,SQUASH +0x8dA366956b59042D1476d2d398C28cC6c0941053,18,CONK +0x127Cd2fBc764313A7ED425f8cC4149454409a9d6,18,BIDEN +0xb14A3F8287D590B6aD9ABf1CC94f0AA3198fEE4D,18,sec +0x9724FC5741f32B531d21C27991E136b02A0AaF11,18,SATX +0xE3de7eE53B92095D27dca231908FdA5323ae3280,18,BUNGEE +0x158496c7daDF2354930eCC7585d422b3b3D249EB,18,10000GROK +0xEFe06922615B7414E8083931247b2B075b08D4c6,18,JRWA +0x422ad533B2Ca7f37f73c10bE88B1Dfae99ACB39E,18,FRIEND +0xe99d036f5763289405C9783c4Cbd41B284e107F6,18,FORK +0x8C0535C94915768914DEA00718d4BA266DBB5ba9,18,TEST +0xbEe68B06455b8B9A3639BE74a0Ac5A5aA81500BB,18,FRENS +0xfdfe9A14438B9B6D6E631aBC7B8A9404ed22f5c8,18,WENRUG +0x9Ce79cde794798B1b840c0E346db57ea68004535,18,PIP +0x6A49715A447867e1E7C4D05b8c1ccaEC043BB37B,18,🌀Bgames +0xC1540F05387421bF5a46ff31b1c2010CCC112683,18,TEST1 +0x1900762434eD240309e47bfa6a085272e45e175A,18,🐻‍❄️BAI +0x7511FD9c2dA45562ee813809e0a88818895233b5,18,TEST2 +0x65823733544A2eF382A3Fd6cEF45A62CcFE87908,18,COKE +0xd65f96126be7F96670488CD312d578E036e113a7,18,OSCAR +0xc1c19f70D5330F2d3CE0ac31432345F39421f7E6,18,🦁Borki +0x973517eBb67A865f67a63a56508BB851042d5bb3,18,HYPE +0x6c52f8a233FBE6bd7ee52b76FC7a525E321974f2,18,RUGPULL +0x85FEE89A35696deb5585CdF14eCf24c9d8DB63b7,18,Bow +0x53F50bf4fbF3dB069a359Aa588DA435932830e48,18,Bonkkiller +0x0832D31884B6DAab4CFde1cFdA27D37a00b13048,9,PLAY +0xc8E958AA78209eb6fE79C21315D1B7B403242bDD,18,CUM +0xa65afCB9eADd3cB61941C24665b6aA36f1E79B24,9,ACAT +0x1B2163BC8a31508aA2f49d6dA3fbae0C96A95860,18,PNZ +0x35ECFc92FC79e5B6bE1A3b540729F17eB1076939,18,SERBIA +0xBdb9e2cBc63594c89Cd88592CCB4bD529c585190,9,BRRR +0xd345d407327C60636Cbd0Bd8B356284F2C89d21a,18,FRIEND +0x40d2C1F94AaC9EbfaeDb2F1d19D457d23816491d,9,$NUKA +0x4c357D6fA5ebb9d75E1a0F73D6b0D38f09d1b1dE,18,LEO +0xBE0b3d2e6a0413fD9C28D70988A5eCCD2DAA1a63,9,BOBA +0x7474a34aEBDfc9643139387EF10ECfe8B8F7f690,18,BUDY +0x0cfDCc958A5310ba550C9CE2557b9a9C22EEdF55,9,SQUID +0x311eC870e3d7172896CA9f18145bAfc8902c9F3B,18,BTBS +0x1234d66B6FBb900296AE2F57740b800fd8960927,18,DPAD +0x0180D2732191eCf900971F5aDFD480200162d092,18,BMC +0x8AE47D774A0209a38a037D8E3584c871e2EBDBF8,18,PNZ +0x38cA8bFbe642A39dF755940b5675B653e7641d61,18,QBERT +0xE879Af4e71A2Ecc5f06994e34AeB60332D0860Ec,18,Kerm +0xa5067786fAB666e260BAB70ab6e1AF950f14bDAd,18,WIN93 +0x1a7FD5Daec2Db98bF101B7b49AbB0553c88E4341,0,ACDC +0x146061Dfc2548db81A8bfAA09F2eAeC39C4f3B95,18,WEED +0x9AF641d5A25128C38a76a0f2F77f730438ce208A,18,OSH +0x74272DD7dE59bA804Eca30323CBE09b48edb128e,18,pipi +0x08141979F435b3bD2E1259E01f16f290f7550476,9,MATT +0x6891a4d1a3a6dbA2295A3c30937b87105EfCEB3b,18,LUNACAT +0x00772E28Dd03b350515E31cB27aa218C0CD3e1e1,18,POO +0x7025876e6a2a6E00A6fA88A3b96A9Af5d2CD960d,18,BF +0xdF2880a12CaAeF3e1014241Ae05c4E85DB08aBe5,18,Ttt +0x46b3ED3baf51aFCc67c0eB4A6a8c81f9d0888930,18,_____TST +0xddA73b4DFfA1aC3a687903B68900f80122b8f7e3,18,BLOOM +0xb610Dd0EC593d25E8245515B6B3432bEb6e09e6A,18,🐸BORGY +0x433E16C18e528dc4D3bB1080DfE043c7cEE1c289,18,PEDRO +0x346367d685AC3e55597A3292AEd495afE2520D3A,18,BINU +0x070878D3f70D8092067264Ab3F93b313c2FA8dbe,18,ESMX +0x4F1F2db498437141a97f79eeD3cbCdE64F55b65D,18,🦦Bany +0xC068d30229c097d6bA0Fc0fcA835876d1E59C4B0,18,HACK +0x8eC82EFDf428f8e9F39c990B52FDA651A1c40E68,18,BaseGame +0x4d58608EFf50b691A3B76189aF2a7A123dF1e9ba,9,BOYS +0x810837E4C6c4744ba66ca672ea9462dD7c190752,18,FAT +0x2d96dffd266910e11D1bEE9A95EB6845cb9C0D35,9,CONC +0x9C4d3fE67295e960DBdDB7BBdddC3221aD1CAd7E,18,wasabi +0xDc054430ec51C9bFCb1E20e3417f3c59e5111371,18,PerpAI +0xcEa5Fea9B8e212AE9C96D7e1f6131BDa912F95b7,18,🐸Brog +0x9fA26d90D5853052CE561974B5a7F3cb25646993,18,BBOX +0x492C5803Fe1F498874afDEC18BC30fb19296400E,18,BPD +0x372A087CC2aA0Fe60f16dc3C49d0524D40E9B268,18,BLOOM +0xAfB5d4d474693e68Df500c9c682E6A2841f9661A,18,BLOOM +0x99e3f16d251e1f3Bb4fBFf924549556B0f0E34F5,18,BasGAMES +0xd2dE9b74958c91cd569733ED84c9515A62745082,18,LUCY +0xfE52E6fa32D12Ff248454161Aa8449Bd1eC01d90,18,BasGames +0xa1135E6e1096bBF1588E343eD76d4965b2672C5f,18,RHUB-TEST +0x9eae210b84311D47431c67E99915c8436A9C6fE6,18,🐸Brogy +0x606B2Db8Bf642677Fe12E8F067bF55145A350cb5,9,ShibDoge +0x3c8665472ec5aF30981B06B4E0143663EBeDcc1E,6,WARP +0x7080EBFBCb1cb148E3a9b31FF3351b0b3C71f83f,18,RHUB-TEST +0x89A9C4317BAfae9c4726A8862dB1E23B07664F79,9,BSWR +0x1A2D18D0546611fc381977B37F2c324C6973c396,18,STARFISH +0x36b7544cEf40EE4fAc542Caa77Fa137e32319463,18,FEDDY +0x054f6C0E7525eEfFee9a61dB6533564191CE6351,9,BSHIB +0xa3cA89087685011d6407D420273e2Abe875fD7eE,18,BBC +0x84020258640DD2244B0ae9D83338bf2FC5F9a944,18,RHUB-TEST +0xDdF32652fD8E3e88bD6042db9F18a193CBC57955,18,MEGUS +0x6e773d10f7919eDBB598FEF0E640e24E46E44FE5,9,$Cool +0x2E4753ec87C4992892dAd8Dfed02f215A62002C5,18,wow +0xdfc10ebD9E556901ee5972f3f9ebd8e8490F4cBE,18,BBB +0x6D47F47EeB36B500ABA73810124997b4514cbBc7,0,GANG +0xf1B5B5F32A684d9d1ca60C92945Ad16dC19131cA,18,DONOTBUYTEST +0x1f1D0374C4EF4e70f8ef14Af33D41BF2f9828F09,18,FLZ +0x2CB819A4382020941d5f0FD6CBB5e315A8b95c7A,18,PPX +0x1c0de5aBcc615b41Db3eD89a1F87bd7a6aff8179,18,CAMP +0x9DE091397aA1313E472073BE2bDD5476f9E1F33C,18,TESTWITHCONTRACTVERI +0xBE3B49F2c4Ba5637B04ADe3210Fb9EF031CA1E69,9,Shep +0x6f7e468E01A4253955844c9BCA769f0A5881fC8A,18,TRP2024 +0x3fF6C60A582643c2294D6A309d84d2a6cAd16c67,18,ENEMY +0xB958800Eb41436D30ea111d525B317Ad25C0DC94,18,LIVEMOMBASE +0x2bda937cEf2FBe976b62eB2B2C2f1e6f7DBfFb8a,18,wFRIEND +0xce69102Baf5A531319a3e77E71af32777ceF18fC,18,ROKM +0x035f87869c982e6C892ea8789AA8718456844F99,18,Neochibi +0x26BE2aaaeB921a269e315A72355f5DBB2d6F74e0,18,camp +0x3bf6d8b4001277163FD81E938e4BC7457526F5B9,18,BLAME +0x21bC0Da0a27405Daeb7574D4cC5584d9aCE1f73d,18,WIF +0x04f0576F776F844DF961Bf1a45A0481c6e7a5580,18,BBB +0x92fb1b7D9730B2f1BD4E2e91368C1eb6FDD2a009,9,JOGECO +0x3C4aF6C4E863A55B32c726F6D46159A8fCDF3f16,18,SHCMP +0x2330D9024F2c9233e84a2ba56d98fAc13218D399,18,ecats +0x27c2B825d836Cf002303F4bd728657129Fe60C2F,18,BRETT +0x22498145121e83a4F9D825828E9b45eDE4B0b783,18,UP +0x1995fc0291A61A69643a1EC9B04FD307B28395D3,18,BASEtt +0x2840210B8f222008Dd9daFD0B22c4762CD9218a8,18,.COM +0x1672968cCde9938D5bA0e488EFcB2d731189458e,18,PONZI +0x04498128cAAEA895ccaa95d4E443f155803C2123,18,FORCE +0x3C382e4BF4FAF903783048827281a23F45613291,18,mountain +0x05F537C3860D18e244285F839aAD6fAeA0bb42E5,18,YMM +0x0B7B67e24c896d57a89f495d0ce844D06fd12733,18,500 +0x25a80489B54bA4c91d8422e4547eE66691bDc4a6,18,BASEic +0x0eBB825d64B91B88b618D66897bAC440F3D1e1Ba,18,WestHam +0xca0afE2C7A44984e48630E5b79BB33890cA8E6F3,18,PPTROLL +0x1A65cB85e482303911e8942dB79F6E3ae8D01Aa6,18,BLUEEYES +0x9E92FFbC06dE07855F2286dc958dACdC843d1235,18,ARMYOWL +0x0e062F28b15f0fBAEfe47F9a609e972aC459077d,18,TGNR +0x46c5e5b4065DCC64260E53ab6F13459a7971BcC7,18,Sheps +0x064Ab2399d499161eE7F0fEDE38B65dd27dba0f8,18,SSSI +0x1178FF084407357bAeC33d8F211b33795DeCeF98,18,Bichi +0xe6bC2CD535622d6535B17e3807C0e6adb51c0223,18,PILK +0xe929c18dfFDdD79489AE37F4B39456C3a341e40d,18,RHUB +0x13CB3E956be8915e41a5A88a7eC6918dc5a54c9E,18,YODA +0x1826A8dfCa5cc0B3F2b750ab58f365Dc6E5099C8,18,NGU +0x964Bfd9a6BFe54c6AE977B1627752067fb09A1A2,18,AIPILOT +0x3Fd976CA058E78E8c921208C6aeD6ccACfAf0384,18,777 +0x210F4117B1790647d5543E4157B568F7FA486E0b,18,GLORP +0x1148E628aaC1025B8ceedaFd092f912696Cee3d0,18,BOEING +0x0297Fc50A98f70d681a38e5F2A267e21bc787d9A,18,RHUB +0x26D3ec3353f0a064E3394676E7F5530B082d1a93,18,GOLD +0x22c20824E037C6B043eA0356dC7A059A0957e257,18,100x +0x12a18C14245ea3D6F0B6D4cE399b82929bA7B16F,18,CUSTOM +0xFCAf32a08e889d8466FD1D7A14Ef64C2340ec492,18,RHUB +0x22eFb160C8e98DeE3BfF37DE537368C228f1Ec41,18,it +0x28bA6B4A583c4C963f320C8Eaf28Ccb957CdC089,18,COOM +0x161F331e43ABe778e82d7D3fFFE7524092249c0a,18,WOMP +0x358415D39ff442964D4930456eDc288f2b62d9Cc,18,UTC +0x0455adE982dF9c457792F27685462f5A85E0C458,18,Wobby +0x109cd63CeDdFf34c02284268f195943d6035dfd2,18,t +0x27516FE354492DF0DeC8b672B0e805A85F99644E,18,erggreer +0x329fC6738E247859dDd05164A75AB77Bd05f7bA3,18,NAT +0x3A6BB4971F9edf05BD15327EF7eBB25192E95017,18,WIGGER +0x292Be9c3EfFB1EE8Bf64CE874592194A7B7D77dE,18,BT +0x2371834Ac742E3F7BFc25049c043966d5dCE9D78,18,JEW +0xbecc9a93D8Fe302A9A9866BAAaB4901866B2c500,18,BASEADO +0x0D3F79Eec6BA8e873761aEb2AAd42140767866ec,18,IM +0x3cEA7EEec0e3bce9D0f9435523eEb0A618B23844,18,GLORP +0x2Da35Df5b84DE26fE22B4d34A97087c0495Ddb8f,18,GM +0x2e81A2851BCFd2ed263E6d60eCa7D5e09b943ac4,18,e +0x3531787A61Df373124DB6e7201F7d8eFefb65dF6,18,molly +0x3Bc7407172C3491EE63c5F6F390EB7E8D69A0de0,18,BEET +0x0C04DDb0599bbd18E1B90135ccd8F301d0ffb5F1,18,TESSSSST +0xA8ead8a9B2a0EE9717650ba3D2E13a89Dc615f6E,18,RHUB +0x736ab92B701C5509568d59B81B7d7567763aE6A1,18,PORNHUB +0x14631e7a6B353cE20b0d2b06f1193C96a8bA8116,18,FAAAAG +0x337f1d4711CE3a82dADd710ad856FBD572272EFB,18,W +0xD0751d184bA6142D98b6AF1D3D36F829f1C420Bb,18,RHUB +0x7Dcb4ca7D6C563B875A554b62D412Db941130B86,18,RHUB +0x280C74aa58B563723FeB69499bAd6160D099E2bB,18,LONG +0x9616527739be06EdbDcF9b262b2157237d38aEC2,18,RHUB +0x8c0A999c772DD3204f1053433740bC11F68F0D22,18,FRGPEPE +0x3bbA3D4A5A59875eDBa9D01829015C8b40e389a9,18,Grass +0x25Cd2c29572FA2569D3E46ae2af994074AcC565E,18,NWO +0x7E729161F53bc82E5f25AeaBe6aaCe28Fb8CB35e,18,RHUB +0x7543944DC68c057B37bFaacD31C8B157Da2E5F14,18,RHUB +0x34cb9cCE3ab2DDCf80b4f6e07258678655f522B0,18,Joever +0x399Df6856dE36E546D49D847e6c169F341e04c60,18,a +0x34A8E3C8767c71eff9AC70750b653bF76d40499C,18,RHUB +0x2fF9be3Ada6D91c70fA8E4aBB42b3a21F3C80773,18,BASED +0x3F1c50145BD0b7a3A5BddD16BA01324E1240E736,18,MEOW +0x134AF523b4a0fd3fE07d6c76d46E261b3d7Dba2D,18,wwww +0x2295d437B76DCe84f92fD84B201dC1090E5CB9aB,18,Ovouwu +0x25eD31f13134879236B381eF36F4c5CC3cFA93bd,18,test123 +0x136F49094504c07C892A3F39A94f6caf0B5f4500,18,WOOF +0x1D87642e59Eb6992Ef6E8F4C29a3B710E1ef0CbB,18,Rayfu +0x7Ed580d9983E9D82754d4a9D3610be38BA3A56a3,18,RHUB +0x179F3aBdAcf76Fc91cf72B40d95e254994228A30,18,WOWTESTER +0x02549849C371a109aB112286F27d5D7fF6899235,18,TICKER +0x27EE04900844F17b2A872Fe320b1B6Fd37949AAC,18,MAFIA +0x398e1170dc02E094deeFE25b7e039E92D3109EC9,18,AAAA +0x2F367a7FC1695eb5CFc8364f3Eea658f2Da0425C,18,aef +0x3A41Ef116c5545729D38E47D10afd98BAA06Ab61,18,FAKE +0x122D1125CeD703413De7CFE2a2a54016453F1026,18,hehe :3 +0x19A1C79Ad6fa89560aaaeAb66551fd3d3DCE540C,18,WTH +0x065c83D57bD70F7E59A0aeD9dE5342971e1c3Fb4,18,Pepe +0x03A5AEdf9a60933511c608029E8dC32eeC11f402,18,GLARP +0x1dbd4E32CB7133fd85Aa6cbD4aDD3b3381552f96,18,CSW +0x3AefAC19DD153C0D92c29662EB882918814Dc075,18,FT +0x040bFD332f2dfAeE800b93b1B7E2477e732Db3a7,18,ALW +0x3016B1C6c2e0c8194D3A5b41b4eE8D7fE1Ecb0FB,18,. +0x2d0ABCbB874Bc3ba9ad9117e8a9eD94236b3D539,18,GLORPMACHINE +0x15e4Ad09340A00FfAE1F0780543b6b31285717C0,18,Grass +0x39D728a9114aB26BFd13740412c0F5d856bA6775,18,TICK +0x2a10ab6F0741da177B58371d889356f6d25CAea5,18,camp +0x0a338996f6Fd6D2FCF9eDBE73a2F902cEC4B10E0,18,re +0xcdF4Ed1221C330dA8555b3237b05dEB569B820BC,18,RHUB +0x404bb5991Ef024B689738BAC8eaFA7a7C5cdB2B1,18,AWWWA +0x3a0262a656A440CEB2cbf65Bc83D936b53a15150,18,BASED +0x9d72A983d27cF186A608eeD2d14Bee22b2dC6527,18,RHUB +0x129346bFE9c2A42C834cd9B7588bD4d864640a9C,18,Glorp +0xc4AB16FA4F521E3dDD59504E128217A4030f1241,18,RHUB +0x00881016B7324678F4012FbCA0C0267b69ebD10E,18,RHUB +0x2eBE818fF2371b166130255678924686153A9cb0,18,WWWWW +0x2283Fb10e8a6e3D02A111971d121915071Ab9AD9,18,777 +0x41b50C9A3fAe9ab1e34BdB43d477CA7fe98D62e2,18,SUPERMONKEY +0x0F5F9494D70b3376bf19b220A49B985e1AA92Ac5,18,MC +0x22ed1824a677fb3FA5b57583Eea9C6CDf8eFc8df,18,FrogIsMad +0x31874686ef66432e65B3D18A503DdA0938dC6b35,18,TICKER +0x075660e267228f7ea4f2E5395A41650D41Bba97c,18,Sage +0x214422Cfc0f0f745656b74Ac2054357E14faa668,18,...... +0x37017403ab739292420d0d1fA3976150B3872B32,18,WORD +0x091Fd7911ACA851729CeF1596F45d52a7f7e7DCd,18,BOWBOW +0xE557Bf10bc4d50220ac1bB77565120d0F85d72f7,18,TESTDONTBUY +0x25E427897C12314CDE527719CEdb5D4A8760870c,18,FUCKNIGGAS +0x4dd44BE06c9508FC706f4cb52cc1c32cBba80049,18,TRMPLFT +0x86252Db4CeED302cf5De0a3A372A8bf0d5420a06,18,BGMY +0x189a0B8a077F2E2aFa1574b947fA670E6Bb58f5d,18,WWW +0x005A2c675EaDbd6df191d650716116Bcc004F742,18,GAMER +0x314cC17A9d883e954E62ebA46Ff9C23Fa49e81A1,18,TOKYO +0x28383521a8C19e3d000cc7146e494A2d67CE00d9,18,SHORT +0x011FF1387A96eCF8F5fFf073915CaB4613Da9684,18,69 +0x250066b83B8F3A3E6774526198Fce54B121D30DD,18,GEILVALLAH +0x2b167173027B3C4C17A4187AC1774bFA1206FC1e,18,DONT APE +0x1ef9236885f4734151ee7cF2b8B4eb2a9b89e7fb,18,KING +0x043641023Aa278E7c3b85803d5c1ac7c33500C37,18,H2O +0x126c050DFf973528755e414D1CF1770632EeFfd6,18,working +0x9Ddc6033a681C265C8719fBdF84384FEFF172A21,18,AICLVR +0x0793B46523842c30FE7123Ef2A2e3090952A85f7,18,wen +0x3dACB2666c431e693AC88163506Df4247EeA615E,18,egirl +0xC66aD799283957F3371cD33f3EBa04124b0CF6B6,18,SKEET +0x10EEB045C0C18bB14aecdBc9E4f10480A2f58d0E,18,69 +0x012da0D3F4c12aA940A006FB8276B186f77d3055,18,NIGGER +0xe917Ec526Ea9983340935a8a2508cfAd2D2f150f,18,symb +0x1Cc7becb731bf7F469C39deb1051D28f009884d3,18,MM +0x0a11ABc7F03D58b25c64A1320F677256d0e97807,18,Z +0x12e5e8A871bB6F716DcfFc93C7f204A779dd6e29,18,PPECOOL +0x4D853a56863fFA1f18c3ED693066A45e3Bf6374e,18,RHUB +0x0221C1F1A1b15ce714E5c3Cb9eE4a1eF6c28aC5B,18,999 +0x339Eeb24F690555434218413C7DA7D1568a0D612,18,DEAD +0xAdee044c9d9fab7E4d09d260B384cd38054DF1eB,18,RHUB +0x263890081F520E5e661563900a960B29566eDff6,18,ABC +0x5aa5DEe30bc6D7EE891eE70DA0A1907604A09EeC,18,RHUB +0xf6Db985F919311FaC0c2A7229Cb342E5F9aF8ff9,18,RHUB +0x5Ca1E7dcf12071b74D668b5D90975ACD8324439A,18,RHUB +0xe9dd6112EaD0A43b85154EdCCd389b2E22a416D7,18,RHUB +0xfC5cCdD1C2dB01915E588d912a902D782a9Ae39d,18,RHUB +0xB2b2C1a976d789DBe19Db999454797Eb08788Ab5,18,RHUB +0x18aDeBd9FDb4E5C25de09b2712059D0fb42Ff35e,18,GM +0x4748A0c40E1E3475eFC15feaDEE4051E3cc47fbe,18,KENDRICK +0x7aaabb95405ce273e047bC624329f521A4A010DF,18,TRMPFUN +0x6FF923E04728aa2C1C392518c4c9d27Bed4d66B5,18,symb +0x41BF9e0DED1389f4d0dF64936044a104d9A54eA0,18,RHUB +0x3e05A37cF59e519BDe2ecfA3C90eFF4dFE77584A,18,symb +0x71f7DcD69ce6bDF528aF2c5DF97d87974EE97e52,18,MEGA +0xC30678f2C7CE828149CB47b9765870e715172cf8,18,TPT +0x555B7Bc0Ac4329DD129907873fEe42030125fE66,18,bbb +0x0140886d1d874de45CEDAa2bC5720EDbB6B6A061,18,hhh +0x3EaC1DA87Dcf35f3418D85560Ef30c5531ae2Ad2,18,AIROCK +0xBE8DfC6661fAfAA4445Eb952586c0D347EaCF048,18,MONK +0x15d95e35A66044460E8a149F55cd195910Dfaa2D,18,RHUB +0x9896D8487Ff9D2626B9dF7f5AEb5Fa9CD7237e96,9,LUCKY +0xfe189Ba4AEf478cD9082ed7DddEBE08424DE5741,18,SQD +0x2660Fd7dd86cEBCACB455206f597762454456103,18,RHUB +0x5E48CB3b29b5F1351e73d030f47BB1dc01386e7B,18,RHUB +0xF368E21cd5D9be93bAB9D7B1Ef55C3d0FaF6AaF6,18,🐸BROG +0x3E88DFF80B3Df413802d9ad8F7924aA028A6C483,18,RHUB +0x892f888eC879100d1addF9AaDd98090EB6cA1E5d,18,RHUB +0x3e524Af52a19Dcbeadc88978f0acd203002223Ab,18,0.000000000001 +0x1442d4bdd038DE86A5680C57654212a63bD69627,18,NIGGA +0x078f4F9c419D486AB9B756b121Ec4E347b8612B2,18,FROGLOL +0x74c985a020ADD6110B867E622f421C3519EE690d,18,RHUB +0x750F4853C8C3a5007F9B25c48A689681916048dE,18,🐻‍❄️Bai +0x1D43bB87F639411DE4CC0241bA428A11d07f6D43,18,BasGames +0xA342bC8cFE573dD16593EFD630A1358CDF07F6Cb,18,🦥BLOT +0xbeD2a3CC2c8786D3ee6562924eCa24Ff9fAF5d3F,18,TEST2 +0xa4ecD597adE3c688E66d4478140c0db4669d85E9,18,TRMPGME +0x7ff87F937be5d463508B75654c67ec59Bc06182e,18,HITOMI +0x22422D8cd1b0854BC14ba5E897e005C84e67dF9d,18,ATDX +0x9d762f0E7e51C3086A415d1d5453B701951DA54F,18,🌀Bgames +0x78A7bD982Cd0bCD8b26788f6b5362083b3BcB467,18,TRUMP +0x11f6b2F04c7003d9858f2dD2610F04a72658f862,18,RETARD +0x5a21FeffD6Fa5Bd9DAEd020b5433006cF6ffeAAd,18,MARLO +0xE298D5b5dE077b57392ead70Ec739985C8322e5c,18,🦧BOMPE +0x2386F744a577949b1e4ed4DD469474f123189b68,18,SDOGE +0x27e162E408D27C94EE1E204ea44A0c69Fe183444,18,💠SUPER +0x2f141f2E7C34170404660A936f198064b42aa560,18,TBAR +0xF8B6D1Ae46C98a08944e24BCBEf9d31939ea5c93,18,LANEKI +0x255db4e94685C1eAdC20a6F1DA3D46522f39f698,18,BULLDOG +0xc9A8FDB365b98b2e545794081fF443b2a821961B,18,FRENS +0x65d4d4a9EB3a3Df2cDb60c310dc85DD0f100cdbd,18,MNDN +0x7C32BD65e302862568EEe5FdCbb19D3136814AB7,18,$BAXTER +0x086CfE4fa4B1Cb3078Aa5f9951348BBe19aa61Ae,18,FREECZ +0x241EF1dd5A5C81Cb3c8d364e66B8cD1cfCdF5F5a,18,Nearium +0xe116A9f5b19c59FA8dBFe852dbFF7C0CFaEe2E6D,18,BENDES +0x255E35ae06623Ffc123e30bFdD48B1B48bC40977,18,BLUR +0x488fda0e0D0efE5932b59f9D4B3008Ed26E41763,18,🐸BROGY +0x3cF5bD8f75A109B9D740f8153883FAEda96F5D51,0,GANG +0x0Baa013dd0C0E9fE67afb4f5C183Ce29AE3cCaa5,18,wocat +0x68328CBcC8E0338C74e8ea49E3A0012AD5E70e3a,18,🦥BORG +0x6521E1c40b3116c2b481F53d85F7002BAB334540,18,BARLOS +0xC7a871501c2335ED5E10827567d2E9167Aab3383,18,SCN +0xd266c0aBAFa52CFc0b7884ad7c5BfE9422B91A75,18,Catnip +0x8D0F6CEa9eEdc429A23a9cb565C4EC3713FcDe54,18,mom +0xf8b8d852952C4A6dFC8D78dABFc13AB3b085b41B,18,CGANG +0x2B52759ee477D2b27A69c409f59CF5EAb7AdA224,18,king +0x047491DB6704b7da74C64fe7662D6d7BA6acB3D1,18,🌀Bas +0x329f65a15221a061d9FE0FdfEd173205ba7763F8,18,MILADY +0x8A31667b167598Aa56584261ab28056F24968395,18,PUPU +0x7eb622bfF15481e4c0fa0e76545fC34a0BFa1371,18,RHUB +0x80d7Da11AEBc62dF6027F5d9A7448628749AC5B3,18,RHUB +0x3cF6389dB6025A1F8b6f699c8613AFcFFc68Ca55,18,REMILIO +0x1e1dd2dEDE79c1eC56043e36A0529CbD7121e6E2,18,WWWWWWW +0xCaa6D4049E667ffd88457A1733d255eed02996Bb,18,CHINA +0xC8EC1ecd840a5f669A1322859704d972E8c14E85,18,RHUB +0x4423949DA207a8F808ADEAeC0aE702180a5f280D,18,🦦BEME +0x236Ee01BcbE95d847a286d2A52d1389bc444814b,18,CZ +0x4eaa20AfB2c4fF0Ca4662EBA797DC60980C1dFa1,18,FRIEND +0xb3DEBDD8042148547BF68245170e710C10A81Eac,18,RHUB +0x1fB181c5a263Fd5d6Ec3c0EB2Af1Cb29b0E7d7EC,18,🗳️BBOX +0x2c728135dbAf5fd672deD97960C94C771E606761,18,❇️STAR +0x04216901e84E2141534c51574311BAa75B3C43F4,18,NFT +0xD5457DC852Bf0A1A3FD1fFfe9232D843B48FeEcc,18,HALFIN +0x33b9e28064Be9a5780e315342efB98B9b5FfC132,18,GIGA +0x3E919a5e3eF66C672aA74Adc7FF8B79Ea451C61e,18,NIBBLER +0x1BE22C2eC9e6c95aebFc889e06Bf668eC17e8FcA,18,TRUMP +0x0AF14293BD00634b3E4B789bADb5928477B1d402,18,L +0x2af48e0FAc54A9B32317E51b2b5982fb5411268f,18,WARHELMET +0x677f60F6c336812D5C07B130deAfDB79859bFD6c,18,BONKE +0x317f76A7bF01DB9f3B9986ED62419528432bAD97,18,GLORPSON +0x377dA60C8826Cd83C1D6F14d9729F06AD1Ec6587,18,Glorpy +0x98Fa1079a0F095C360d11f2AD472C25FFB2a9aCE,18,RHUB-TEST +0x779f1e780584F2eD6edD2350e3A35e4Efb129c68,18,FORCE +0x0422D5563603469E4Ed9e2bdF23f211c7CBe7149,18,🐷Bpigy +0x75A25e8eaDCe9b909447eB9Dbaa689a1FC47AbEF,18,YOSHI +0xAF95455D656C744d16359CbdA063A6271B28aC51,18,RHUB-TEST +0x48AA9F48B8e6654fE0e7060407a7a301D7d222D0,18,RHUB-TEST +0x03cbd34e2bb70a22AdBC8c3499d4d92c29E9b7DC,18,TRUMP +0x246F2dAF1cfb1Fe238A56804b9B1b6742824bA2D,18,CZ +0xc278028FEf81da39301f831baF29545210805A03,18,KEN +0x8CEa287eE70F9ddd72c2B76dbaeD91f1b12c498b,18,RHUB-TEST +0xD96C53D194cAE179dE22fbc56EEFbc4299cdd68B,18,RHUB-TEST +0x7BB31B05A57E4Aee89114aa1d485e2f6A920Da70,18,SKIPUP +0xFd82C0a98fA39733c4D3dd82478583eD3153999A,18,INU +0x29690fCC43b394F266B271152bEC93971D58DD27,18,WADER +0xE9A08c02588198E425fe5aA42433A35d011a14ef,18,USA +0x500eD50C2557863A2fC2c53e0e994647cd2AdA02,18,ADENA +0x7Aa0507Bd164378632d2FB80daCCa474047AD1b7,9,$DOG +0x1c7F193700dcC91Bbe9719B64e9346846DDB6388,18,Heeehee +0xEf4BB156016991BCacaBB3d99B91a053E18F77c5,9,$PEDRO +0x1dBB6f6E788b0a91A0baeE4FEb36D21CF6F0620f,18,Balls +0xd7c361bD5188E126FA2961492F543d0DFa69a437,18,DDD +0x19540E8d05111C3DE18CCDe7fFbc3d8dB78d00F6,18,GROOMER +0x5023404e67Eb84B87bf21dE91A58c494454A219e,18,CHINA +0xF034db41E50A6aE555bB117a915d2b9C2F3477Ad,18,HBIB +0x2d4862E912ba7ba226106fd09419379Aaf25Ac86,10,KOKO +0x5fe3d79A091dE0083213Ad0efDAD66E6d9fF9a98,4,FEDUP +0x9c3eAE590107BE796874B973980041889C1BCf47,18,STARWARS +0x3ADb41AB16779f19d4702f8d9725505884e09fdF,18,HOMA +0x0871D86fCbDe7f5c89274b1017Ad43d5B8A31340,18,🦧Bape +0x15dd13Cd0bC4879ed9332cb04480fCceEfD1ee8C,18,RHUB-TEST +0x0c16c615b0F73fec423b927a2EdD964E4690eC27,18,MOCHI +0x05719DA2515ECd7d57fa21D511CB8925141BA95d,18,RHUB-TEST +0x0E803bFf72531baC6D0D50fb1f11E0a46Ed1FDF3,18,EUROS +0x9cCdD6284d1da924BC01fd52b37C42a6C9a9feF2,18,RHUB-TEST +0xe0E2e4A31D5Cb0555AC2E07d36aB23e954F83A5F,18,0xChris-TEST +0xDFE30Ad244C9E9417205dD26996bC0a9a17aa87D,18,TEAMU +0x5b55F72e10C9978f10B3cDE46F77A6e44c4B6fbE,18,kitty +0x30c38CD596DAe4C02EB415FD0313baEb953F4A1f,18,aaaaaaaaaaaaaaaa +0x870660a87E2e4E5aB22b80aB4842B907b76907C5,9,BASUS +0xd123Cf34c635784d5a152033962023b1dD09a251,18,V-TEST +0x7cb76629590C32f35e0CD2d2E84B3f0405123e68,18,CIA +0x151378F647A88444547f45e1C2ec7C5dadE655bF,18,BASECAMP +0x5099e1aeD326efb6651b49C78FF309632e294fDd,18,noodle +0xb56d0839998Fd79EFCD15c27cF966250AA58D6D3,18,USA +0x3F282b91149C0e43549aea06233DF1CC8a788D3f,18,Ⓜ️BMeta +0x04Ed0E9e194262c7DF1528AF9a8474F5A1F6adDc,18,LIVE ON TWITCH +0xeC1184513a0Bcfb96144F00fe9368C5B6e33727E,18,🦧BAPE +0x8d2f83bc6E24EcFe0bE436E11B5d65B0F0CaB045,18,🐸BROGY +0xecBC993C4B29EB5A192712D689B63A8a665a8f78,18,BaKiK +0x61ef59e690040E6b7a1693C97383D74570a1C9aa,18,OPLEB +0x374FA21fFe10779a10a05dCEdBc04e69FB97E571,18,$SKEL +0xcEb4d6D473D6DC0C478d59037a97c45EA1E0e804,18,XXX +0x93AA36C6d465961B575BbFB8AC1377A0bd8875c5,18,CAT INTO CAT +0xE280341441bD68E9c1B1CCfede618f0f863CEAc4,18,🦦BOMPE +0x868BAA9320D79e9aFfb695858725F6FB7BC7ed07,18,drunk +0x24fCA802DadE850a7c4c8d29A921EDd603F746CE,9,OLLIE +0x3Dc93222d44aA015dFd30026429cF3c27eE5f13f,18,PEDO +0xF81C42EC85E228A86dc9cED746DA02E09CDa3F43,18,JERB +0xa915ac5572913c06A79451FFe3947016991E140B,18,V-TEST +0xa06df66ca12c1873D6E5885B0B7d3EFC4c7D9429,18,bubu +0xaa1AC4B59e960B734Ccc14a4Bce4BE715350C1cf,18,TEXAS +0x3d3864765AbbE273f814a0B99273e1cF8d1Fe073,18,BOC +0x3b79E7d118119bc91120C120b3793dbe540FE246,18,Cock +0x93b97d09765C7B481dC88Da81dEAda890f4Dd3a7,18,JP +0x5596cA167AD817cc5230C341C27D21993dCfcee2,18,A +0xc402F9126D414b86829e2822A731C084Ecd5e5b6,18,PEPS +0x98CC8C426Aac7C23Dd21adDC5082D75847522079,18,KOKO +0x24E1e00b4Cd06B7f19c56c0a881d2E9666A2788e,18,SPIN +0x34ea98cAcB437B432f75B21eBc0d772c8C598d3a,18,KOKO +0x9202f3c6eD0Be424A72E49F25FAeB032A267D604,18,MOB +0xaFd1dC9Eb8C9e47951102cEF56e4101C0e91c08A,18,KOKO +0x3cB31A121222e8189fB1be94EdD1d6051B98fbE9,18,DOLA +0x893165F145118f92b058c230A91E6Ff2a095f800,18,PUMP +0x35a6105778a3C7CAdE4C1fDebCe6FB9c6Bfbb883,18,UHHHHH +0x756bDf59eAEd73266323B786BdEfC9c832dc5695,18,KOKO +0x059B501330929a3c71B37909B65D4F8cB98562c7,18,MEME +0xc2D8D26e11d11a40bB2dF3Bdb6809ad3288F33C4,18,BEN-TEST +0xeC6F07e5E55D3f06796c220074179b3eb7DFee80,18,KOKO +0x4280415fe4dd3dBA5681d054048A589F2DE2427f,18,KOKO +0xc0c349B410817a3d3ED5ad9DD4d316dCbb98CC71,18,KOKO +0xD4EB36A4D99B7894AF57bed726F2163ea16B0352,18,V-TEST +0x3301940016faa3259045a59c16A70843285d3a26,18,KOKO2 +0x09cf80BDd19786120d2A21674926B47fB36fB513,18,Tom +0x5763147BDFb07c6FDb3fa036B7398c451771d678,18,V-TEST +0xE782eA8207c9c6421097f4D764f1bb4Ed3b5A1C9,18,V-TEST +0x6a0FF940A16032aA1436D871739F02107eb73E41,18,KOKO +0xD7B8c237759bb87E90d3Ba24723A728D2729Ca4C,18,LORB +0xcaa260463604F3479318b9B967668c9Af074a8Cc,18,CAT +0x107b24C41090eE88BbDa17e3FADe660C85cA2a1D,18,PUMP +0x538A89fD6382807681B47990fc8d9fD608Ef919e,18,Arek-TEST +0xa458052DFE661fef3595849cB299F9366519D710,18,MFOX-TEST +0x419fceb6B64c2cBdf55402ae50E736869FEEdc7A,18,KOKO3 +0xcA155e3c0B495858edfbAfC1c97805103bDccaa8,18,KOKO3 +0xC2D9F0B0c5a96B03285Df1A8B54A47d8E67d0EDE,18,AREK-TEST +0x25d87D381DA259aF3cEEbAD2441E2a69AACAbD2f,18,SAMU-TEST +0xaC8bC3379213dA50303BED08EAa389024fD34De9,18,SAMU-TEST +0x4dBC2bd8F0D6a90d230d053182eF3fe626F5f4D7,18,Iri +0x6b831665B348E4B89f87b560500Ea273FAc38253,18,SAMU-TEST +0x24634d4e5eC5002a9CAA977f4649D57D3AF59714,18,PUMPFUN +0x15a09258425931ca702676ecBD6a2dEca96910Fe,18,CT +0xfA569151EeF90d812E63aABED3fFF26DbE7C4164,18,KOREA +0x67Cbd63f123E885a28CEc85e1E3ebB91fDc9c71F,18,KOKO3 +0x5E9b243593380d1937e1935B27b96afEcFe914A9,18,KOKO3 +0x4E568c2B8b1E251f8Fe9FFAe3FcD5fF646EA7a17,18,MAY4 +0x16EBBd3e4A7183DB652E5699b404a6dFf1b82339,18,KOKO4 +0x19BCEA5886D8835c85fF72d0669e42f0794cebE2,18,SAMU-TEST +0x3028514B393fe8B7C991dafb983af0ADa942F6c5,18,KOKO4 +0x1B262fFc4EA59c9c8fC0c36FEc2aE8f92c6B9336,18,V-TEST +0x626F6c2Be9ebb0650228830883A905B14e7FD5D7,18,LEMER-TEST +0x90DE2a8Db8fCB32E030BEFb9358d7bF0B1826e07,18,DAT +0x5E642Dee9A9f40dDE5188873f824bdD6b278C80D,18,V-TEST +0x193e4F53714C15db72512355eDf52BD05F8CfC21,18,KOKO4 +0xFFb13c46e2D4462C9784f5123d165938131FDF50,18,sperm +0xC58A6776911b18d92fEa58533b617b830eE8ec7B,18,KOKO6 +0x1F4DB73D9f46962105Cc2d0FF9cb71cdfd2C4646,18,POG +0x4a721d9EfFe8c4DD5Cf3324df44D2F9256EEDE3d,18,KOKO6 +0x42161bDbc6e63B48F3633Da5B46191edFA819997,18,LEMER-TEST +0xc5f7128E0F03a1bc9507f80289420f6d73744B05,18,KOKO6 +0x7c6c74C9E5Fa8237aA512DaAa43deb2c1159Cc3d,18,NEMO +0x06864e0Ace23EeB2ef12020063551d4C73fAA2Bf,18,HPO +0xFE63278cE5FF4F3eaED8139d896A982Dc41C5a3C,18,pon +0x6B72EBCe45716e5736dC6790d2b5F7C0023CE1FF,18,Mario +0x1Ff66B66C789c4A47b32f4BC5806aF8E58Acdcc1,18,X +0x1A036309C6767B16393740215CD62F6280A40584,18,OXB-TEST +0x9dE2e1016A191Bb2eC20c3C7abE38f9637eF9fA4,18,KOKO6 +0xcDfbD1a86A0CA7dE364f0909F140Cf7436876Dd7,18,V-TEST +0x63fCD40cc5d10Baf05Bf66F1F6A1480dd047BC4A,18,V-TEST +0x7FcCA7f39e856D488B3E47853B7E6CAe47EcB89D,18,rETH +0x451019D3a720B60254a851272D450f94F06a73cf,18,V-TEST +0x182A2e820D11173425cba9e939598FDbe1B91B94,18,OXB-TEST +0x4AEF983f5F87CEd93AA8Bb9E9E3c40120Fe4E874,18,TRUMP +0xac2f7110fC7d0df9f685955622013086dC9eAA63,18,V-TEST +0xCEf432F90ec2523F157901a6B88439286D38c7A6,18,V-TEST +0x92eBD8465557C54E7829a41176E7c5095678F50A,18,JAPAN +0x83c239528Aa860Ee209a3B9CA6172D6D3c511E26,18,SKYY +0xbc092Fa27EEd4f4e39f28c429C7E0d8f45280Df5,18,NIKO-TEST +0x19eFADeE263233C1569841c3e514Ba5C418B8F1D,18,$BANFT +0x0Be8631276723fBfc230690D495271a293C9f950,18,OLLIE +0xb7d5130550fCF27D04543A6243999F3aab7ab56C,18,DNFX🦊 +0xAaC03a0Bfa67aA7ca88c41822b81541268BFa8F8,18,BRIAN +0x3918307b28d0F25ae8a64455Fe33a592B503899b,18,Bchung +0x2a673c22b6e8AD076823505f33632f48dB553B26,18,$USA +0x03168D9917e875325f765c5dfA0212d3aE9613f8,18,PANGCAT +0x3359B390a9DD1DD861d818B5Bf14c4119F10c8e1,8,BOMER +0xF2ca48c59da97e434cf83f4150C7806310f4DB9C,18,REDO +0xeeC9D0E7FDCd6a959479Cd8A5A075EaF48af1e09,18,BRCH +0x4e94825106761494676c4D5b981FeC28537443dD,18,V-TEST +0x091c2724d175073Ae48938fC5589583b34A6816B,18,BUFFETT +0x647B378b11A523470b49dc88C4AaD3A83446354A,18,KIKI +0xCab52a5D771bC0e71D11f80825e14947bA1AB35A,18,TOTHEMUNRKT +0xe951F19CaF0e998658078d47c35f8621F47cf576,18,KIKI +0x51F4F2BC1da5e227Ce76c86FeA7b306BC0F8d58E,18,KIKI +0x7BeCa4fE2cE311C7771003A45674c7becE42aC67,18,RNDR +0x598de5C830753C91DC09bE4749734328af51cED9,18,FUN +0x0320BF9908a63C5763F7e1d766fc8d0899cFAEdB,18,KIKI +0xB09aB8052d4136b8A99C97c984A8A3e9ABFe003f,18,V-TEST +0x7EaA0F40eB0d9aA331B9b12bd2b3d9b0B6355d6f,18,KIKI +0xf473340761473f67059e77928287bb53B906774A,18,KIKI +0xC0B414553DaDd5f12Bd7F2709DA311ef8B874224,18,KIKI +0xB50F0C30a6D8bBE9A6BEa08707942D5E73d00088,18,B2B +0xe5a24a9992dA0243ddc079Cf057C357Ce0BaaA94,18,B2B +0xDb71C6279f9D7F02b571fB5bcd2C605aC39eA249,18,KOKO +0xD12a09B50e30d13E94BCFC3c7E83029C582eB5d6,9,PEPPA COIN +0xc9CA6A4dF5EadA2210213E5F1dE4A46899481665,9,LIGMA +0xd60d956466058dD8EaA01d33bD2935fa78Fe7962,9,LACOSTE +0xCf35D84FA1eB06B07F55Ad408e3f0af907cDB6e6,9,$NUKA +0x833C67b621a2DD5Fe7394857cE623eC69Cf34c59,9,$NUKA +0xE173Db464B4AA97881071B1B65654271584FA6b0,18,TED-TEST +0xC6a7aC2FD5f45B49C478fD452A954B40D8F4DD6c,18,TED-TEST +0xC0459640762861A3059A47033cc8Bd3807CE6538,9,$BEAR +0xF42364c0fa7AB04c93B19f02CbA5410cEEC00C13,9,$WIF +0x1FA694C442c1DFf4Ac2E7546b206C07A92115C9D,18,BRAIN +0x01D05B2C9c3c17DdF6A8B0b09e00453161afE82b,18,V-TEST +0x24216fe58558A318C6477c23cFafb1F8Fdc4A929,18, Jesse +0x4a0E172a72E245C28B66B9fD65dF5a41b1003dcB,18,0xChris +0xA8b443e8F5f6B93189838cB99379f815A27C6323,18,CHINA +0x15917354c3257f7948A5705986AE0238FD1996B0,18,0xChris +0xA6f73159E906b33D1c9667D35a7Ee26Ec49E00e4,9,$DOLPHIN +0xFC504b699534e4eD71FbC31aD16655EAA95734d3,9,RCK +0x2d3f52C8632A7BD1752f96D858f365B7E3Db81A3,18,CuteCAT +0x405e4e821d33121943bc8Cb0bbC033e4A1d16AC6,9,ADN +0x678379123D18Fc81097C1f0d059EeD23F23fa240,9,FW +0xf66Fd37E92cDfc59559EcF228FC5b79685e0cF8c,18,KOKO6 +0xB03af6C94970927200F6d74aBC84EdF62b40637B,18,BRIAN +0x23146569e778AD9368cB31F7D5a41DeA565669e2,18,CR7 +0x96419929d7949D6A801A6909c145C8EEf6A40431,18,SPEC +0xCFC9e6d6f9E2fDa19a1513Ec91D0c50B17B1f5F9,6,GEM +0xc7Ad0e0A9473f2ACdbaa3B251306DBf8E4A64203,18,BURN +0x4cBe45e1bB8Df0b89Bce7e61c0380bF3cbd23fED,18,$GNUS +0x328e914aE361d479FeBb9B1a112A0A27F1F463e0,18,BRIAN +0xE07a954E36A859e19011C901DFbEA17426710c21,18,$BGOD +0x97442F474F6D8b3fEA11a3E6418E1c6323E9F088,18,$ELON +0xB577675DAc53CB38afE98c501AF92447945Eb6a4,18,ROOCKY +0x77f3A9dEBB8F3981e71ef6b4c0f6a0F14085F4e2,18,TESTTOKEN +0xCc62Be843b453B92B57563cF97e898F4cc6dECdF,18,HALO +0x2eBF3c90130b2082ce5A86f42Bbf59331F3d3015,18,symbol +0x0de68Df7E57bC9C564b7F8e7E5bEABa3a46c8051,18,symbol +0xb0bD00524936bd856dacd8da92ce0f1414A91911,10,VBCat +0xE43772F201c222f7305636E660F93cd281aaa248,18,symbol +0x96ec6b8936850B4b7e36d2f5279A7e9449790f34,18,symbol +0xB61a21E35E35FE6C2Ecbd0e689F52d834F4bF60c,18,symbol +0x5FaCa79Dd5eEd857f246F071Ba1C0190bc3aE24D,18,GNUS +0x1e6a39c68814b6fd83C5005030AAF325c1a34E0a,18,symbol +0x02A8b8a3a12D695a07be03953406Ee52f10d6eF2,18,WOOFEL +0x8567387F9d605873E84ea6F889A20cB07F4aD65b,18,symbol +0xd852248063b7fCa5D94e21e4c642C5646E486E2F,8,BIDEN +0x0D8b003fFA5F22D6f595dd3B4369F8d76C40C979,18,WAGTAL +0x1E83F5a5e530D0A531D88dde01e203d820461015,18,HENTAI +0xD20Af41dA5aF716d5161195d2de7E2fA04233a2C,18,BEPE +0x60497D4db295087a1b3EEBd26f142e46cE5E97Bb,18,SHEB +0x8F486Fa59C1136B63f5Cb8beee67c9AeB9d95177,18,VBT +0x1E60b4B4e89F40Ce6F93c8cD5f028a6007E776E7,18,AA +0xF45395Ba46e7F2a366E688E1edfb2Db6E5295603,18,BetaG +0x8e18fe2E6c2c00c0a01a5ecefF8874df24B2FfA1,18,ALBART +0x4E4f62B57b7Ec78a4CC0c37FB0B61a4510BE4a7d,18,V-TEST +0xD699A8b1FC1F01f515A0F9972087Ae37c25AC782,9,VOOXAI +0xC01e800851aEE88Bc8adf8Ba9D49fDE97428D9Be,8,ADO +0xA800dC8215aC8c31e3CFb7DD11d0A128BbFc232a,18,PUPMUS +0x245Eb25865cdC78197490FbB24B0D77E315d0167,18,cc +0x017F6923c928871B1ce6865467EC4AD4D280fE6c,9,BOSE +0xbbA50D32bf4E59311F39274974580Da874b87D30,18,BDUBAI +0x1a7927968C6e5513aD83D82ABf352cB378c18BaA,18,MIMICAT +0xCA63F4f6641eFB5baBD9EFE7956810C54F4b3730,18,Piesel +0x0979499779B31BFfA62884ca702e34eb10B66327,18,symbol +0xcABddda5f2D003555830B91A9F81b76FA943c9BC,18,🦑SQUID +0xC4b1f3f557cEc68F2249639f64cd3737F394e5cb,18,symbol +0xdEcD9c6e9245eBAa105f4971EfA5362f451bbb27,18,BULLRUN +0x913Aa323127A2E1E5604bD84D3f3d8B929215f52,18,COOL3 +0x2439F6366710DAFCd563E3348948dfdd641957ce,18,horse-TEST +0x2DD88Db80c9ee6EC1fE337EE3317Dd5D0c562F40,18,KOKO +0x4e020614AC6130c0bF71BdCD8aeF7F5E2Cca3eE2,18,bibi +0x70a04085816A689aBe937ed6eB16dA5c4337494B,18,PEDRO +0x74244415C811bCAF0aBE6740585AFE52FE635914,18,BULLRUN +0x51BBa29e3B0d90357b2a2dD75F56c38e43DC8588,18,Ju +0x9965967A90d726b5a139da85Ba51D408F55B31D3,18,SIMPSON +0x51c612BF22FB3e338899Ba5187c05410997EAc9a,18,HARRYPOTTER +0x7c3707548C78fa5f4bAF07bb5A85AFCD3Ed40170,18,JASON-TEST +0x150819FCCE6A7D6Cf105aD22142E09f5Df86e208,18,JASON-TEST +0x32C3F10bf4Ff79AcccDEB0CdAaBf92e471a8C486,18,JASON-TEST +0x034b345BD7E7991316a9E110E33A2aeda698A63c,18,66 +0x0aeeBa75378811Fa76590F432BCDEe3e2C426e73,18,pepet +0x4710F26fcbc455aaDf2a40734963B9EffEB7A9d8,18,MUSKYR +0x15cFEb9FdCCE1f49AeABD2BC1D9179006B3ce191,18,symbol +0x5DB4222C8e773094D7dFE2fAfC1a7b0193A30cf2,18,Tgr +0xeC27B029997E5901CEfcA5bc61B0EC7986E7174C,18,PEPEART +0xAd93be442507b73577aefAc892201cAa389bAde8,18,BREDD +0x66b5867bc6c6a0589E2C468F506F3CB6C74Ec8E8,18,AIJET +0xb377A59F291278eDC1fab028d33777DC019989B1,9,FDD +0x3F8E58Ff07C083788b8a242Fe6321BB1c872a029,18,BOYSCLUB +0x88BB03C0F82cd6aFAAbA978f5fCA9326E191C105,9,LUFFY COIN +0x5a5454016272A353c735085a9dE9f4b364E108D7,18,MYSDOG +0xf1188d8F68ECA4d6697901Bb78e72C3fa9Fe21Ce,18,TRMPTV +0x1E6169465955475Cce994b7A223EFbEe3BEC9154,18,FT +0xba3546f8db138F62338DfD666942EDC766df1316,18,pixel +0x10a9f33ce94420FC459c8b11641B69f8480f1534,9,ELONPEPE +0xDb5EDc73f6dA9e4F6a6d7C3Df44540431Fe9b8a7,18,BULLRUN +0xE7f32BaeDdeaDd98A2aEF83c1479E0Ac3F759B7c,18,CHIPS +0x40c0F14645F8d9bBf5D3867386CD0d97Fe169a8E,18,PELON +0xfCeB868925AB259C2345A50Fa5e3809a000fe69a,18,Olumpc +0x70ba2ede8b46d3b3b8840906a34705696F884771,18,toto +0x070667CF6B5C8C21AEC9324d8d9F47F4343c509B,18,$BAPEP +0x1F3cC713655ac4461e87259a3f0Ee736d480E86c,18,spepe +0x2b9b44aa68562daFfE88453dD86d8efa300cF4D4,18,BHED +0x398913fD83ece3467fdB6e7bFcA9Cd6569830AfB,18,CTB +0xa030a03E97C576a5A44B54D387127fFE020dB37f,18,TTTT +0xc1ee9011d81AA8132700F6afdB94CaA13E7992F9,18,CCC +0xF4320ff855888ac0Bacc087EF7EA83244eFCcecF,18,TN1000X +0x283405FE1B0415208515Af2E4a02620Fbf88eaFe,18,MIUMIU +0x3aE675993E76fFfDb2491EE8b0D4e81Fe19d5dcE,18,DIAMOND +0x440031ff0A62A339c213fc187916AD82433a8df3,7,BOOM +0x3c87A416F2906e4e282A52f8D4660eb1BAEC7eFc,18,test +0xAC043E77D1f144AC6a00Dce55770A1921193df0c,18,TESTFAIRLAUNCH +0x8Dece6A225516176f7854524f35B16177fc2D83b,18,bam +0x8C699B47F535584919e52D9C1099573811239A07,18,Skyy +0xD0E64768acd71D651E90ecb24D5D6B2a6b47Dc05,18,JESUS +0x1E79dbafe8d3D27B5E5EB02EDd86fD98F63eD12A,18,V-TEST +0xDD0932796e59C728E633Bd42587F91BD4cdc224f,18,PECHEE +0xBB0354468268405316892364eAB7aA159DD98E21,18,V-TEST +0xC51f1Eb75f26E95356457eef6B1c36c097D1d62D,18,test +0x32A6a178403B468811958953119fd9039604e7dc,18,LEMU +0xC26f3b65C925C534eA5A1FF6faFc7f264A1A9C4A,18,LEMU +0x25D8774728D03a240EA953613Ca7e1b3F61Df19A,18,EPIC +0x0Ac22860BB8E2F09E0cac6397D34b261158d7D82,18,COCAINE +0x135C7Ec51963b4b85B0fa5D3b0928f7D2B4D666E,18,TROJAN +0x92FbFD80098B9B85ae6DA619B331A4d6b4140F85,18,Skyyla +0x0084c4B91f198308eFfe3F30bDe7845eDbb0Efa8,18,LOST +0x75678318258d3C574FbEd236f5EC61ec5b8591C9,18,KENDRK +0x2aAd962605a55973C9fc2c9b75DaEb56C39F2e69,18,BULLRUN +0x9260409d4719c235C7c199106219f9616D66bde0,18,ArabWif +0x7AfD0a9F6d22AB0533B673d9A8267B482d941f24,18,LEMU +0x2d3279c6Ec4ca3826070fdF3A7b648D64716C6E4,18,V-TEST +0xC8F67Ec8Ca5Ed7a3B4546c87e7Bd953F308873C8,18,V-TEST +0x980Dac846238BbAEb2F2EA864d7d5fa3E9662F0d,18,HALFIN diff --git a/fastlane_bot/data/blockchain_data/coinbase_base/uniswap_v2_event_mappings.csv b/fastlane_bot/data/blockchain_data/coinbase_base/uniswap_v2_event_mappings.csv index ef8e33e28..77245409e 100644 --- a/fastlane_bot/data/blockchain_data/coinbase_base/uniswap_v2_event_mappings.csv +++ b/fastlane_bot/data/blockchain_data/coinbase_base/uniswap_v2_event_mappings.csv @@ -8882,3 +8882,174 @@ uniswap_v2,0xedC28cB85b748e532c9e249f0Ae3C5C90213b7a9 uniswap_v2,0x8552252f400132788D2c642E8328FcEb681dE5D7 uniswap_v2,0x74A9dD976723e7ce9023AeDDc51215308bE35382 uniswap_v2,0xFa867D15268503ad71e3cda97Eb6266c7f366Ab9 +alienbase_v2,0x0480Beff117Ba325B6322d85C12761fe615eF169 +alienbase_v2,0xe4327BFA7350E800F5C1C1b96fBbc974a2FF67f4 +alienbase_v2,0xFC98434213a3d736cb588355F30f1A1C01bA03B4 +alienbase_v2,0x07502B19cb5b10357BCdF630b30E41F232F0eF4b +alienbase_v2,0xE9eBB4056be45d758F612dAfE6c6cbB98c904476 +alienbase_v2,0xd3f93DBE6149454eA3D2426a151881E9B8448f2f +alienbase_v2,0x141e9882b7B102632EA104ceA866D087B4225bc8 +alienbase_v2,0x5FE1f9CbaebCFCC0Cba33db4642FB89CfFc11748 +alienbase_v2,0x65bEB0C98cc89Fa1Be971755B16309243EF3399f +alienbase_v2,0x8DE31b86A8848334693E43198B23d73260c55E01 +baseswap_v2,0xc032A4d54E5c89Df879578240D5332a1f585D17B +baseswap_v2,0xC32E88A041F644019c0C3Ee4ab5835e3d38E7bB4 +baseswap_v2,0xF2AaD3c9FD2C68DCbc0B6ac5C19341274f33f12b +baseswap_v2,0x6c7662D0236ce35918C736742418bc5dF796bA97 +baseswap_v2,0x569d81C17b5B4Ac08929Dc1769b8E39668D3aE29 +baseswap_v2,0x236d12142098Fa83693B7B5f11451dF81604F236 +baseswap_v2,0x4dd246E9f6c935fbba0633962808a8157855799f +baseswap_v2,0xB35a5027995E89b4412C38Ae45827C045d4FEf03 +baseswap_v2,0xe3e5E0BFac7Ff37393D525f838691b0b8dEA8BfB +baseswap_v2,0xF397081C22C35ad718684e6f2DD2ACb414F2dCb8 +baseswap_v2,0xE26158d053391125FF61a0933FC64df1F2605f3e +baseswap_v2,0x66b33e8624Ae38E43F1Fe930F7a6BE75FE86B118 +baseswap_v2,0x28E7B2526397549CD06584555806b1b9AFA54a11 +baseswap_v2,0xcdDf5c31dB6E179e344a552c65B65E503173E35A +baseswap_v2,0x7Ffb6222cec40710A78a9AA3279A00974c0429C6 +baseswap_v2,0x28D27263Dd485e2772F2233c80Cb6e3c3725858D +baseswap_v2,0x598A9F9a96c0836b73F08aE66219f2452195B74B +baseswap_v2,0xC43BEFDFC9B7212f4A096cC784c87A5Cd9ADD209 +baseswap_v2,0xa8697fBc69C787794793A39C04eCD677630B0ce4 +baseswap_v2,0x5B66410D450b218273a4342ea78b9F54b0Bd18d5 +baseswap_v2,0x85946478C49E2942C5ACf9923A405536853DCe37 +baseswap_v2,0xF3c85f90d4173320d369140A3a78e581E91010eA +baseswap_v2,0x78080242bcB9Db98F6E4563Cf56b57a614F517c0 +pancakeswap_v2,0x6CA40356e682a91D249AF252010561BbA18bF6D2 +pancakeswap_v2,0x0E10cEb1D295Df779bFa711fF0B2557Eb54C9837 +pancakeswap_v2,0x3f5D949D44373C44DB366e2A2e7864EC4Da5c134 +pancakeswap_v2,0xB4dB1f77D1dFAFC30890f75572b7b6215b9939D4 +pancakeswap_v2,0xE7e2e77420ec5DBB5F0513Ea404Eca2B24CEBB00 +pancakeswap_v2,0x4fC009a842Aa978Af2ED0D750A75b5aAF5c35F23 +pancakeswap_v2,0xdb9E3674Fc4f0B1E43974B3b27869F91FcA83383 +pancakeswap_v2,0x22160d23E448eAA9BEf7952b8a467D3920f41E64 +pancakeswap_v2,0x7DcF57e1C1E4dCA99A1BEE106664C30e4C1cEbf4 +pancakeswap_v2,0xA4B557be8835428bd12610141C7C27AdACAd3500 +pancakeswap_v2,0x94A48DBC0E3A7b0a92b6cF9bd6Bf97d72984F171 +pancakeswap_v2,0x9c55aDf6C4DBb25cDEd488cb6260Db64c9d7E6A4 +pancakeswap_v2,0x045B40B49F94401FAcE4FC991e27C16Be4b144f9 +pancakeswap_v2,0xe281D7d1EaA54410CEC3B8613a3E7175404AC263 +pancakeswap_v2,0x6E6DcD2fb6a586D90baE2C6DF6A203428cd1C7B3 +pancakeswap_v2,0xf9BCE7De4BeB10938D6EAF6E5D6D27e221468461 +pancakeswap_v2,0xD08CD223ec7E529F2931c40f1CC2D34a6A8DA6Bf +pancakeswap_v2,0xEa51982e8efE3Ff26ba5bBc317EFA1C44ffB73da +pancakeswap_v2,0x6e38C1DEE19245EC49e7B1F37e3CfFa8Be2ad189 +pancakeswap_v2,0xba7E30045151A506599fECAEfB023A236aCe0E45 +pancakeswap_v2,0x8B21Ca1a986DC2cE5E7D349580f000CBe5115cf7 +pancakeswap_v2,0xA6ddB465563c166b1495De5e8443DDD23FAbf33e +pancakeswap_v2,0x8BD9F77b20129c1C92f690b80De0Dee57876F680 +pancakeswap_v2,0x9a4D671dd3B549D746C9F389251Ca9304502A31D +pancakeswap_v2,0x39E7B235028fCaD17f0540060034A9de9A61551d +pancakeswap_v2,0xB712EDa9F444082f01A11e6f09254580Aca14ff2 +pancakeswap_v2,0xE4d0ba74bdaf0e6CEE8cc0Cd16FC6b01B35c8E64 +pancakeswap_v2,0xE8E39FB73F17B84B3D9fCBB0e00cD33742D578b3 +pancakeswap_v2,0xa61a76984b48462fB58E680b50478665E7d1D65f +pancakeswap_v2,0xA54677aFb5606239E49138304eA20f8a57A1ca79 +pancakeswap_v2,0x722106aa28bCB539B75e64becA9950505a9ba8F5 +pancakeswap_v2,0x83fBF80d594ddE56B6E8bb863ff0b493Dca85bA5 +pancakeswap_v2,0x9f4400eF226bEdae515114edA9C0DbaC48B738B6 +pancakeswap_v2,0xa825E2Ed5696f8B07E7871cB7A160eCaad353E8d +pancakeswap_v2,0x02F3BEc6c25B69641cca3685Ee7bDd56b03f39d3 +pancakeswap_v2,0xAf99Ed946686C55E830b98CC4DB6d4F39da310c7 +pancakeswap_v2,0xF28876B4870e3Cd9A0ADdA498bb50341d1475555 +pancakeswap_v2,0xBA6DF5F505BCa0f3Ad4e8345D9AECcbeec8C62fe +pancakeswap_v2,0x2bfAf877Aa340713878E3D343f1Df64e8010B7a8 +pancakeswap_v2,0x4A74335E41319ADACd21f2ECF370BFCBB90b4022 +pancakeswap_v2,0x464746DCaC79D4353c29942E18A5653fF4b87F55 +pancakeswap_v2,0x0D3241fc7c7b1457c562Fa05CaC0CC6BA66FD520 +pancakeswap_v2,0x2be7Fc6E641B6f7776eA115ee4fe0c18Fa7164A4 +pancakeswap_v2,0xEE8cB4049d72316281331fb73B1107046B5c784D +pancakeswap_v2,0xdCDE0fDD52c995Cdc4D55Ba8F6628685357DCF59 +pancakeswap_v2,0xFda7b2cD273C904372FbA83DC2192595A177ED3e +pancakeswap_v2,0x16Fb173607330061B8A3c755854258AED584900a +pancakeswap_v2,0x199F12Ce842c48283A19203AcC48D8196e1AB334 +pancakeswap_v2,0x862d424cA9E46792ed74E340a188Ff4ED1A471F7 +sushiswap_v2,0x925c2E236E451522F2e47DB568Aa1Ea976E066D4 +sushiswap_v2,0xCF0BFDc3859f84210333BCa032205f9c5d389633 +sushiswap_v2,0xD1ae7Df8438B3Ebb94862a1573F1F289F38df9F2 +sushiswap_v2,0xd923ed8A7e64B83021dd5999338ee444afE03475 +sushiswap_v2,0x5B086441FEA4Cf7eb605eD8E4cd326fBf6FA6a53 +sushiswap_v2,0x70d09044699B20938eD398D6bC94503A226d58Fa +sushiswap_v2,0x04be274F170c7E7c8c7Da4eC8db5935fB5c0C75b +sushiswap_v2,0x87fdA2aa1D8AC5eb3E5E67fdaF168Edc63b70EB5 +sushiswap_v2,0x42740c0e47F8B721a191b754f1f51cBB06afA9a0 +sushiswap_v2,0x4a279aD132181b0820D0c76e1bE545F114d65B12 +sushiswap_v2,0x6cf1b4F524D72c787C0E389bd53876dCd233F923 +sushiswap_v2,0x56E839B6a517bFbB67949F81F268C9e1be202565 +sushiswap_v2,0x5b36b542b3921c0c3922b655a74a3f2e72291f20 +sushiswap_v2,0xdE75CddE1766AA8438F83d0aEb171b1Ae22D1985 +sushiswap_v2,0xe10933A9d0d0d5Db8446c5b9E3b29FADb6f615DF +sushiswap_v2,0xB524206c2d083b35e15fC7006B9817B571d313b7 +sushiswap_v2,0x529Dcd8500F73723e45A10Ad3fdFD4bEb8a38552 +sushiswap_v2,0x862C04c627c4DCe115471D22Eb755fBf3357F4E2 +sushiswap_v2,0x565452C3d2aECe3F05eDC226B48e0FB8cb12CA52 +sushiswap_v2,0xDc1a8733DF948F60068bFA8B7a299fda460cbEB3 +sushiswap_v2,0xb33e70d829573C6BfAFEC2A484060372d2B56908 +sushiswap_v2,0x08A75d77d91c86446a8bD6936aF7e3321e69E5cc +sushiswap_v2,0x062aDF0216d7391dCf012855689D47D50d0e650e +sushiswap_v2,0xA1ad5dbb22a079d6B73F775ed4b83Cb5a2052ae8 +sushiswap_v2,0x38106c0468ad32D9E221A0C2C80092D77380d3C1 +sushiswap_v2,0x1FC5368e833A131624f314829B6745448DDa22E4 +sushiswap_v2,0xaE24A794dEF2F41C8541E4E0C40C620C44198307 +sushiswap_v2,0xD51CfB11E5656cB517Cb9dDdA9d872C7Fa310928 +sushiswap_v2,0xf3F4f11374faf5F648371281440a675a3959D757 +sushiswap_v2,0xeC1c0BA6943e6180f7f294ed4004c11BACb7B663 +sushiswap_v2,0xCE481c80BB44cdD51b655BC23CF06d8d2A3d3b6e +sushiswap_v2,0x9694F93C4e8774B7ae6E91F53b5Be74655A3fD2C +sushiswap_v2,0x40F89F8Bc616e656f3799a503191124096025A4f +sushiswap_v2,0x987664943E6e4509087DEA575b4d2bDa7aC7E00a +sushiswap_v2,0xbAC92F3c576EEb135b88457Fb68497c7e831fC08 +sushiswap_v2,0x20115fEB7De11660CbF9215663E060B093238a22 +sushiswap_v2,0xfEE6E412705277D6C56Ee4Fb858773dA2Df07aa6 +sushiswap_v2,0x0175FdD99f2F7E64C4e3E6EA5b9eF31A7F267AFe +sushiswap_v2,0x455073A3491A9CE0e4fc298dEfaF3a87a3Ce4a96 +sushiswap_v2,0x644d902Aa36E5e5bD0a3Cc01A1cdbF57736fC9bb +sushiswap_v2,0x647c342a0ed53c2a4950864B5B282552EAA519bD +sushiswap_v2,0x81F52cDAd52D6F9a8Ef439c1ec57D274aaB3B62e +sushiswap_v2,0x7caE4C12AC99B18F9F2AaB9F9d74931EB9868556 +sushiswap_v2,0x52Fe5103662A3585577D58Eafe81024913624cB6 +sushiswap_v2,0x13BbFb7e5e23b6c066f5a1CD3334C6C91e576a9F +sushiswap_v2,0x713d01Dc99Fb1B5cac8829FE11805492B656fcFe +sushiswap_v2,0x2D518f37461D4D1289bC7cd4fBcc7134Cf635927 +sushiswap_v2,0x4AA5B8057FB058B086512Fc3B275168a1c32A5b9 +sushiswap_v2,0xb8825f24CbA7640eEC739572c2bD789ccdd32859 +sushiswap_v2,0xebEC7d98a547647F4E3535409FAcB10c47459B59 +sushiswap_v2,0xDf495a2E05ba3423D516880D23849A0bBF896f43 +sushiswap_v2,0x543d5A177Ff075178ee0798b8960fa6Ce5a0fa90 +sushiswap_v2,0x95191A71FE3Ee72D8ec7B878a877523F9DE3073F +sushiswap_v2,0x2De1d86148B48cDBe86CBC85Be2E000Ed295572D +sushiswap_v2,0x15d5DFFF9C362f112bA96cB8000c20228Fb0aaa8 +sushiswap_v2,0x0F040E23653134569c798bFFb16887D8e1548d91 +sushiswap_v2,0x38CC2323cEf0364Dbd070c853e6AFfF0D9A774a7 +sushiswap_v2,0xEB42f563011C4410122B74165FaFaaC1E08a6176 +sushiswap_v2,0x7D8A038eC388Ce42A0C8369E9C8b9F34c6CF4449 +sushiswap_v2,0xa7347a593E84003a7B00A512c313eAA61c0b74bD +sushiswap_v2,0xDd5B25812768E84dDC756E73503B9F016025bd49 +sushiswap_v2,0x6795054Fc8699d04aDA529Cd4B8C26CEEFAb76fD +sushiswap_v2,0xf6E5E7E3325F5bd177b84Feb0d82719d26d4D794 +sushiswap_v2,0x4e5432Af805Bf3184043aA393aE101c49E67559E +sushiswap_v2,0x253B356899022514A712C0dcBCa38c2767A5BA7C +sushiswap_v2,0x53Ce13c19c2DDB41B2483ff5EA8845e8df4746aE +sushiswap_v2,0xe6afC26A854D008382DBB51888c929d12AF487Db +sushiswap_v2,0xB7bD1680940c312148AD03C5F4922c1fC505A84a +sushiswap_v2,0x9855d99d38E8E10212A2762F18B37F3b00c24cE8 +sushiswap_v2,0xfA6EDeb1fE62c1670edDd276f9b0Edb763fb79d4 +sushiswap_v2,0xe0F0a29b865F1c8E5ee849a02f6D647D9027685e +sushiswap_v2,0xAA6a6634e7674DFa7598eAc087cFBEFa8bCbFDee +sushiswap_v2,0x96015B167cab82658422f1573BF4158a11B7b36E +sushiswap_v2,0xc32F74CC1374dEF673FF2baF1404528179235635 +sushiswap_v2,0x64147907b2AD544008F2484f1DbaFfa3F655B3b5 +sushiswap_v2,0xC281BEEb7D543daA3ed6024B2c6512E5526fCbb9 +sushiswap_v2,0xEFE2C5CC2Bf1f734b0b79b3C17584dff3454BaD4 +sushiswap_v2,0x0300af30f95af0E83acD903fDb3DF6ab5c3abf57 +sushiswap_v2,0x1c5A5a93a9dCa4B786c7b0f2D205bd27Faa77ce3 +sushiswap_v2,0x216E583e24eFeB3ac106E7691eE8cA5a2B74aBF6 +swapbased_v2,0xdE8E4897368f273A43E79887437039Fbd740854F +swapbased_v2,0x8a4B358D1f603d1b807D0a19F626Be4eB3a93041 +swapbased_v2,0x58740d7F68994F203EA2313953FD5c6fA76B3757 +swapbased_v2,0x5aE84DDF1a70cFAEB84384CDE6DCc01BF6F64FA4 +swapbased_v2,0xe85d5A74756cAcB4B2E066Abca8971136C10b9db +swapbased_v2,0x4f77edE2920B2b3C91A8f958a1faBC783860cacF +swapbased_v2,0xFED40880CFc8b8e3888963305c2edB552aD4B433 +swapbased_v2,0x6151C96283485602e10709265a12Bb171382381c +swapbased_v2,0x0dbE022a1d3216809bD0e22245A5b371C0C73F4D diff --git a/fastlane_bot/data/blockchain_data/coinbase_base/uniswap_v3_event_mappings.csv b/fastlane_bot/data/blockchain_data/coinbase_base/uniswap_v3_event_mappings.csv index d3aaab95a..1dad7b857 100644 --- a/fastlane_bot/data/blockchain_data/coinbase_base/uniswap_v3_event_mappings.csv +++ b/fastlane_bot/data/blockchain_data/coinbase_base/uniswap_v3_event_mappings.csv @@ -26125,3 +26125,1341 @@ uniswap_v3,0x1C201401d00EA91D1CC2C5705522Af28aB01E393 uniswap_v3,0x6751A76875E4C0028b8a9d496400CA625E860EE2 uniswap_v3,0x7b4012De7ea515f42F69df5114e767dABE7B8C96 uniswap_v3,0x6B7FC62f81ffF9D13402C32C7a3A1E56992b38E2 +baseswap_v3,0x1F9e844eC387943F262d8FCc1503EcF71c77C6CD +baseswap_v3,0xe73bfA46cBb78920657Fc1806147622892fb3622 +baseswap_v3,0xdc1f1BFc36a2EE07041e01d7E38cbDcA3985fE9C +baseswap_v3,0xD70ed7f34174c70fce41790Ed55C0D19dBD60103 +pancakeswap_v3,0xF44FBe634C11008D6e8420055524280C4C9dEb57 +pancakeswap_v3,0x1C4785EBfF4c5aBb1cc89B57F33FF33385f61C1D +pancakeswap_v3,0x3c65C4dd602A8876B1110920d778E8A91355Cc7b +pancakeswap_v3,0x01654e0c490dE9D61436656D125cEB2229277b7a +pancakeswap_v3,0xBe3F091AB33689b689071c6Ca9aAA519c7bfAEC2 +pancakeswap_v3,0x85841184a2f9d75EBee49cb1419180A3761761bE +pancakeswap_v3,0xfe7337D99910440E075099B9108B1159ae59936d +pancakeswap_v3,0x05d03b47a01653352b1b986e3D33419927915DeB +pancakeswap_v3,0x54A6ada1FD8022529ed73A36191A3c8A6fE4c2E9 +pancakeswap_v3,0xcDCFC3398a82552B97A8056f5843df0Bd42bB386 +pancakeswap_v3,0xA6940BF7cD7FA14404AAe97ee7F6cdcD131A160c +pancakeswap_v3,0x98911784e16A16D02E7f6A8aDF40CE4E857f6C76 +pancakeswap_v3,0xA5E67906fF0Cc32ab79659941df8124d988FB86B +sushiswap_v3,0x10182408Aa4bE8Bd7B79902CF5D31709928CEF0e +sushiswap_v3,0x701ffF7a5A5074bA8F0b721b67b8C15495cC75Fa +sushiswap_v3,0x31F1899143C8d4e84dF9465C6058d720A6C96A99 +sushiswap_v3,0x853b9a08f70d7558600778584D45632AC9DAe9c9 +sushiswap_v3,0xD54C1B5d1248D4E15F9f229DA0d04901a48C36b6 +sushiswap_v3,0x1a10B5DaDad2197d67A641110D28C86CE62bbE51 +sushiswap_v3,0xD2d5f1482491F7Ebd35dcfec3cEa9d2091019E2c +sushiswap_v3,0x1d9ff97295AabfCF0A83D66aE5ffFF9E992002DA +sushiswap_v3,0x9D0576d5348c4a41903174806B4b7a8C6A5d212c +sushiswap_v3,0x28aAAfeB16A2515450ab5e7433ec3Fb2A76c9DfB +sushiswap_v3,0x333E2A6DB1d855fE949288a6CF4Beb689d21eBdF +sushiswap_v3,0x7db739c955a63cAF9F0370B268348aa76E274Da0 +sushiswap_v3,0xb223ad8E7613e1b0cf6795AAB86bd83Ba45CADa3 +sushiswap_v3,0x65a333EebCFfD2C50B4E4e0f0847C8aD0d5a5b5A +sushiswap_v3,0xbF4212086A25F498c9263092Be63856400869BCC +sushiswap_v3,0x62F719b547fEc43E99f91203d5dEDa3C0D8E77be +sushiswap_v3,0x49cC8c9E167fCBCA57f43ABD24fda47107f7230A +sushiswap_v3,0xAa98B808cfbB35EED0a254C8c96A138D5f1e0403 +sushiswap_v3,0x8C6dB511654853B02378Ba14e4321B649682A6B1 +sushiswap_v3,0x26bf1AA2Ca5F948E46b68E576C58eF19e192FD17 +sushiswap_v3,0x547120AB66De1FCC71De25AA1c040c9B9944B1C7 +sushiswap_v3,0x2f7B2409FD8Ac5ab01242FADC273F3e747200ed0 +sushiswap_v3,0x0CBDDad882cC64ee32C1b0AeC13990a599735e70 +sushiswap_v3,0xd71a622aC6Afd83FF4f8Aa5dA22AD4B7f17078eB +uniswap_v3,0xffbED1eB83caC2Cd0aF35257646be5d935093668 +uniswap_v3,0x16e5F8Ea91440D9f99baB738C2470869F357a04b +uniswap_v3,0x1694296282c2634eed3822F76c5E9505fD602bA1 +uniswap_v3,0xaf1349264Be9daFfE76D66781e8f36de9e6Cb0bb +uniswap_v3,0x6F01c4A589e659A9b52Ae29e0d40D65C85eDf8A4 +uniswap_v3,0xfaD3cb6362F9d1703Ba5A54e465324b892609382 +uniswap_v3,0x5DE0929a0A5Cdc2A3791255CeEF3F74d8701E722 +uniswap_v3,0x6aCb9723c5f2D3a2B210609959F8B7c2675B86CC +uniswap_v3,0x29355AB16b00bd0eB587A01B210A2471ADafd353 +uniswap_v3,0xED0ae16861478CC7049F116E7E7a922fDC5C1144 +uniswap_v3,0x660f837E65aA0A52B302E958699203cD03fC4c32 +uniswap_v3,0xC3b54fD01FC7911fdA40D8d85b16BAa276F4d0fC +uniswap_v3,0x9Ee5F5E030C395FC8dB4C8a576ab4aE536E830F6 +uniswap_v3,0x49418DbD8FC7d7d2642031FC72DFd7E4162F8eeb +uniswap_v3,0x248F1844775242DD09ad6b54209533152FF5BB1B +uniswap_v3,0x45804ce884D6B5f3b4673B295c3EF84bE956774F +uniswap_v3,0xF63fAcD7d73aE114b2Aa3b803939C210672F429F +uniswap_v3,0x7bde5f73d71bD33ebF080182d35398fF0e8063C3 +uniswap_v3,0x793e0c0EbE2856dcEb82eE90fc9E45bD003617Eb +uniswap_v3,0xf1FF40E71E8eAA1599e3729D696f236E77116CC1 +uniswap_v3,0x16096d565cD3c9Fd4f115A57992EC473Dba6B2db +uniswap_v3,0x63927c8c41fA1068555b3c872fd5a38B754d8B0e +uniswap_v3,0xD4eD33674F5dd4Cb46FaF8d03ebb15cfa416e4a2 +uniswap_v3,0xaeDb4ec388082305f34dC4fFD87d857ABC30140f +uniswap_v3,0x3a49a39bf6DF45004D23a948273BaA146Ce98464 +uniswap_v3,0xFE341F852a829E57bA1BaFe4757Fea6b9aFf24B4 +uniswap_v3,0xA2944E3535231426E36B5014A12Cc2F0ecaC86a8 +uniswap_v3,0xd8D3Ca0e0c5BDdfE1439d3B87bcEeCF2aF48c981 +uniswap_v3,0xc580540b12004d4D987B4b54e1C1e684321eB9b5 +uniswap_v3,0x99d32Eb9277Cd32a7f959D633b9BcF0A76a2605c +uniswap_v3,0x9BFA705c5FAEBCBCb4B845B4A8c4009d53fd2130 +uniswap_v3,0x148E3aE3057B993e7285782E2d3e785503a9874F +uniswap_v3,0xA3070a96e276071D316eb4B50552E8FBE3969e6F +uniswap_v3,0x6A69c4737F533099E251e9c2D73e9F86dF36FD33 +uniswap_v3,0x194356F218577F6FB7186D85D4E22A9999758493 +uniswap_v3,0x4a93032dA1cEA33E7b31311a7f5580918Ffbf644 +uniswap_v3,0xbc5C4dDEa0Ffa1c85cc97c2428FbDE94AD09FDf1 +uniswap_v3,0x40a1f3BCD4E112Baa9a3F76BeFd336a45bD0A3A6 +uniswap_v3,0x51069Ff6039Db97965D54638283C6db98b2bdfA3 +uniswap_v3,0x822B01Eec0B0fd94B6Db4e8495A707636ABBE594 +uniswap_v3,0xaAAb6dBc0C5FE04D4a617861c25b15717aeaC2e9 +uniswap_v3,0x763163Dd010E7fe63c835b2D830bbb9A4cd9d41E +uniswap_v3,0x819Cd5a0A02de51609E7466303f3fBB205BBf71B +uniswap_v3,0x429002a59b8399A1c59e1A38d215C2d7536ea959 +uniswap_v3,0x18a406b64f2F8240C3AD8c4e23D42E284eF35511 +uniswap_v3,0xb08ABA450E61b96Dc38CD9A9229c27B96aD851D8 +uniswap_v3,0x53BA16BE0983bfF8F44ceBF17359161aa140B7D8 +uniswap_v3,0x3f4C6c6673345E62c79784D042253206B7fa85a1 +uniswap_v3,0xAF8e928F7fd438CEA6F4829c1554a2439f311aCC +uniswap_v3,0x6E9BD50AE4Ced7e62e1f45c08e37EbB8F5aEc0Fb +uniswap_v3,0x5aC3d8EA4D045Be6baAbF144b1137bC775B673F6 +uniswap_v3,0xA6A7CcE47dcadA6a3377Dd71F913f652FC86e58b +uniswap_v3,0x55Ded14E81367b46375bB4576e58C6dE91fD31EC +uniswap_v3,0xDED8827E3598F1344D5267C073eD2eCcfA99F4aB +uniswap_v3,0x4CAFABD9222D42Eb1DD0E9af7bFEDD58aEB1fb52 +uniswap_v3,0x6672484fB5A9b686fd6fB223b5a2B986a12E28f5 +uniswap_v3,0xe6Eb66caFB64555247C91CA13232c0F5efA0d7d0 +uniswap_v3,0x6Da1453eb4B6dD99B23beD48A58e80Eae6535C62 +uniswap_v3,0x2D8E2f323bbe6dB86c9eE32505Bde652dca7122D +uniswap_v3,0xe0bFFf35B46572D153c68C29ee7d08E9D4dfe286 +uniswap_v3,0x848FE1d84049Abd4AFDd9587eA2E5f79d1Edcc51 +uniswap_v3,0xC17Ff8380c09685B2A671E8076c98E5F2eC56832 +uniswap_v3,0x9A0c2DF1188CBCa9a19ae8f39e00Af0d31A326a1 +uniswap_v3,0xFF1771991D40EFe5bc0e4D13F289B020a8e77Cd5 +uniswap_v3,0x09DeA5B751a7f9597816cB52F07b3E4E08F0A8C8 +uniswap_v3,0xdf9C1e52229C22a85291759173A746e489913F3A +uniswap_v3,0xd24Af8C5750DDFFB5166d1c3Ee15e2E20A3e47fe +uniswap_v3,0xc2eEa1590CC558e3BCbf4d0752A1892bE8329F52 +uniswap_v3,0x124AdDf329EF469Ecdc24F76E74835070E8e4F8D +uniswap_v3,0x3C1904E72De9bd58345646A0DF8a7b3Cbe620419 +uniswap_v3,0x9E0734e21e245c70f759beDFF28Df0c78740312f +uniswap_v3,0x242754a052dD1aB53eE4Bfbe97a0C8092b97118c +uniswap_v3,0x28D6561b1c2337a28D26E11f4B79A280706052BD +uniswap_v3,0x1112a4837Ca4f730EFeC0F32b2277f61F6Fcf138 +uniswap_v3,0xA4e64b605714721Be050E4Dce84B1cd5Ff4D5cF9 +uniswap_v3,0xCf432647F9438510c0574052168845E7f139180A +uniswap_v3,0xd2B148ec40c966935EAE5ae5D1dD7c0346d60678 +uniswap_v3,0x830115860EceF0dE5745B29D441722384Be076D0 +uniswap_v3,0xa48507715d7d720CCEe32b3c64BECCCCEcdC1692 +uniswap_v3,0x41427e5a25c7303E2C85611773f1CB20A94360cA +uniswap_v3,0x0FF765541b6549BC704BB51Fb3720deabcA0D81E +uniswap_v3,0x51DBdb031b6cA927e6E5C87C001110a8E543E658 +uniswap_v3,0x439b5BA612eAc8b7426B74f6730d7e523F8264e7 +uniswap_v3,0x2b1Ecef2E2B3c6d002639a470916bF1d2B698c50 +uniswap_v3,0x9c056626Cac41b5F2643c316c376F9Ee1Ca06b14 +uniswap_v3,0xEF9F8d73305cf2d579f8Aec864089644537CcB9B +uniswap_v3,0xd65D0A292479150acF2a7F265a32Ef1BDC89910F +uniswap_v3,0xF1Dc48Be2E2097EF6c49Cc4500c684115DD47d25 +uniswap_v3,0xB0B8082ceDe5aF681657dFf537180786CBC7a7E1 +uniswap_v3,0x1deBE54DAf727DE6b771Ce53B8E4c9E5792fCe99 +uniswap_v3,0xA31C4Cd181880c4808A2d06a2e48F73eFA85cCf7 +uniswap_v3,0xFB4942A1dc6d36f6EC0bAd9f7c313D6982457321 +uniswap_v3,0xcA351C891bCf425b92ace8B23b812BeA89Bd889a +uniswap_v3,0xf3624c4eC7Ec4b68fec33787f983c31fC7eF630b +uniswap_v3,0xC987c309639c1161d256FB853A156b835A6560f1 +uniswap_v3,0x0BCC4440ac3d73b75E8ce4Cc0dfd80C80A793c34 +uniswap_v3,0x19c3aBAd3b624Bbb57f6A2e3dAFddFf784117F53 +uniswap_v3,0xEA14A25c2D5F84bf830396fC4f1636d786d8212d +uniswap_v3,0x59eE1b254fed3BB2F127898B6026C1d4Fd97C1c8 +uniswap_v3,0x5ae30F8f8E6EDb62Ae2f4Cd06d99f54746E764FB +uniswap_v3,0xB97Dc68B986860807C6c8ceCBECEE3F5D05Bfb94 +uniswap_v3,0x054bab8FBea52Ce9921391dB4964f2703635CcE3 +uniswap_v3,0x3C2cCe85b57a5650cB314e2ec2ec74022cD58A77 +uniswap_v3,0x492F0E2B1BAC7A0f2064283bcAe581ED1120Ce2e +uniswap_v3,0x674e2bd05400250f95C6D70a0B7ea50680A25EB8 +uniswap_v3,0x5dA5De57F6666Fc6bf67069749919b3D25b78362 +uniswap_v3,0x32bbFaa054b6d8DC4B586Cb0f43927c6553aD545 +uniswap_v3,0x873e3C30A2C17665A3cd969b95c1A6D67E7868D9 +uniswap_v3,0xEd188867dE47e3fdEF1bca4C169952D1095F386b +uniswap_v3,0x3245EE3647E156901734eB03Ec5F6B7971Fc2E6b +uniswap_v3,0x1553cb65B1c1bd25093fe33e80AEDe294eF16CE0 +uniswap_v3,0xD8684a076452b527516eeecB29181da332A5B871 +uniswap_v3,0x5ACE5D7D3d9a1Ba068dEf3f11bA7188d4F8485b2 +uniswap_v3,0x18f4888ca98fb9F29D3f0A1481020abB919995A5 +uniswap_v3,0xb2718fAbF4cCe907EdE9B77823764FCFa8bdCB80 +uniswap_v3,0x5CE0CddA13b5680ceD76D875E4C5e279Cb48243c +uniswap_v3,0x96814DFF280A2CE4aDF62AB7aE15cdFF16818fb9 +uniswap_v3,0x2f0D1938cC263Da07B9a851aC47aF9dC845116A2 +uniswap_v3,0x0912B8d7d23050773e8afbE0e8C564A9F095777a +uniswap_v3,0x53E8A72C01daCfb6bA06A3c78764cD1Bf5E5939F +uniswap_v3,0x47c8E047a5CB204080BFc16bFDb2B6D58d53768E +uniswap_v3,0x7E9800297F389d0a93a0F3caE12C69672a431c60 +uniswap_v3,0x9d6B7470306121392F1Eaf91dFF9deFB15D589F4 +uniswap_v3,0x3E67Cc55D0FA52cAf8dAc548e460287D6A71cAd5 +uniswap_v3,0xF235Cc829E5e49450c5A5E819c13a540D1743713 +uniswap_v3,0x3a4a95F4F5E8CE1e2c24717a5B579c586193173f +uniswap_v3,0x6704F48fca12d8fE1EF8511a7d5d751B4cA9308B +uniswap_v3,0xF9e857f8Dcc6230fB61d020D6a17abbf3f58F808 +uniswap_v3,0x07283C9bdB76fFc56C5ef31725E2D619df977bc9 +uniswap_v3,0xde6eF606552EE43403297D18Ba5682F5cF317F1b +uniswap_v3,0xE7a0A4CebCbd453aE07A7723178475FcFAa43894 +uniswap_v3,0x306e600e33A9c86B91EeA5A14c8C73F8de62AC84 +uniswap_v3,0xC8262E09aE4A4Da3E3b61899Aadea5d6A4De1C0F +uniswap_v3,0xB2964709082830f48DCf98F161b8F5BEFE1419b3 +uniswap_v3,0xdcE6D3e28F8E19B7cCE1102336ea2E417D2e9195 +uniswap_v3,0x1364F9B5b35402D4Ad91F84dD24eFe98B5E4Ef10 +uniswap_v3,0xE64d22CF141AcF3724222456bd2e25A416b1c2FA +uniswap_v3,0xcA11e1E048ecc90A502B489c37f4ad7718c8B2a7 +uniswap_v3,0x9989B2E84149568fbda2F84450ef3fC427F51986 +uniswap_v3,0x71C4F2B444460fD070af3D0E3F5C74794EE29Bc7 +uniswap_v3,0x2BE85D06FCb32E08C4c2D3D3b1e15978Ad10a02D +uniswap_v3,0x250CE7133fadA6601674B2bC61bB39a6897F46BA +uniswap_v3,0x2a5f51b6d89B468C76938b85C5B654c9cd2810C0 +uniswap_v3,0xce5F90543319A7BDaAd7d2CA7669a86e355bD4ef +uniswap_v3,0xdAe51c3c20F85cEBbfb1762fF2F5A3B4FF1577fA +uniswap_v3,0x167E2c3E3CEBE99D3759eE7EF5374d8D0BeAd17b +uniswap_v3,0xCfb4735c33399B584ae3c2a6f02e4495D072878B +uniswap_v3,0xF8aa1Db87D84118B0b461e2135190ac27fC1859d +uniswap_v3,0x8De7A2dF0D3AD9dA6cF4C0Ab438f39498983B585 +uniswap_v3,0xfB52f3DCc560fDe4E8C925643cB50B0e50f63008 +uniswap_v3,0xDCF02aB5CCACC1e6EfD8eDA95C026eDb1B1824e9 +uniswap_v3,0x20820B027b6F5912AEA0B7Ee6BF940b3D1fDb5fB +uniswap_v3,0x5899A78a923eD4130d7cE4377514c8226741503f +uniswap_v3,0x55cfb5Fc5175Fe9476d95dCDaCeedDF77Ab49323 +uniswap_v3,0xde294b4659C0143E0A4732BE939620273D625540 +uniswap_v3,0xD586dEb2d4101897f044187c258035b55677856a +uniswap_v3,0x76fBD9Fe99C302188c18A9f69005d21CAA3a98f3 +uniswap_v3,0x06D406AC8a9d987A078Af7573F00B1D79C00fca3 +uniswap_v3,0x306BF5bEb24Ca5E714D8b8AE2e6Ef6CF5E3213Db +uniswap_v3,0xEFA6d525a026c63a101Ec5026904E16D05B45aB9 +uniswap_v3,0x63efb043D724c9ADF2FEAeBC3996F51A63D7F44C +uniswap_v3,0x45b32142268e93A3960EaD948A7dA2037A0eB5e9 +uniswap_v3,0xF6205F8A4D8ae1A4F1B06BA94da2E6C41048a24f +uniswap_v3,0x07a8cb149c3DE72060A74cbA0f94E9D6099e5816 +uniswap_v3,0x4d9ab70c1297adc010dd1b3297e7a34047B952E9 +uniswap_v3,0x87E43b6077D95fbFc4E078EB7474Aab7Aa1a0aa0 +uniswap_v3,0x4833D618E5382358e685055e2755D9419b1138F4 +uniswap_v3,0x1c4bab1F6F5584d7d4Dfc6fC91c31d01f0E90dD4 +uniswap_v3,0x4CB6B44a484bbCEB3717A283FDF9035B9721d2e4 +uniswap_v3,0x443359F4d14E530dA0DFb58Dcfb94F6Cc5ee860D +uniswap_v3,0x86279c78b20Ea9d60bE074073755835671Dc9A3A +uniswap_v3,0x8ec50f133cd304C39217F775054dd0f9740bF35c +uniswap_v3,0x07D15440268B240210CA9742E5ccD781371Da619 +uniswap_v3,0x8f74E7A96c2f808517032D6492d43153B156300b +uniswap_v3,0xea45fC1A8F8Bd6c7aafF7d3Bd61c05C318fB1060 +uniswap_v3,0xe5478b24A15c0AD14679342d421519978DEf3687 +uniswap_v3,0x9D75D9B19e7A858DDD777D1e0539584fc1b2ad88 +uniswap_v3,0x74a278035b2C89c66BA41209a1AC69181e9569cf +uniswap_v3,0xc00330d4B33Ad0F59CaC293Fc561411437Eab1a1 +uniswap_v3,0x943f1c91b9def2a389685C4eD52bF245A3c07Bf4 +uniswap_v3,0x89407D870318d11256f743E258Bd2d360eFd289E +uniswap_v3,0x24FDC3d393623eFe8dEA92C191cAFB8a7b15819B +uniswap_v3,0x548B6922F40bD0d75e5C93B37b4e48100bFF6355 +uniswap_v3,0xC1aeD10c3AAfcb09e5cF60c125Cb63e587F97788 +uniswap_v3,0x332A3343370F51EbBcaF9A14Be4513A5A512c2fB +uniswap_v3,0x3D8bAb1418d9588f9DaD55eEB5Cbe76dA02533F7 +uniswap_v3,0x2B6Ea0e6A027f260201EcDAA06d6EAb6608a0039 +uniswap_v3,0xaBCBAe18E0d8DAb704B323E7388cC9F5d4E325Ef +uniswap_v3,0xbD803Ba75D3ff784B6acA8C24360F4336147E372 +uniswap_v3,0x13FecA769C4d264C188880896f07933d7157847a +uniswap_v3,0x6dcD1a4A786cf1370B51D5dA7D04054fe852ae78 +uniswap_v3,0xEe2D7b9F3F78cc02F65C23CD597F5cBB2bAE3d2C +uniswap_v3,0x4D06DFD0888feF76498b395f79E766a23c6dcE47 +uniswap_v3,0xe8Fe41e14933644E0C8FFa05Df285Ce7a6929cD9 +uniswap_v3,0xA20b8DE9A08c107488D19cc48BdAeA48602e76D4 +uniswap_v3,0x5Aa65DB9B374E1994c7B559749e78A41D9a8ce9a +uniswap_v3,0xB578EcB9819751DC83A5a83Ded72397925eF8cf7 +uniswap_v3,0xABFB3FDeeC099eAbF46a5D6369EA41033a6948d1 +uniswap_v3,0xAfC3B0a0670380be1a19D39B7CB40eADd63422ee +uniswap_v3,0x7ef7f515EAE00cc4fe814eF8667f92C923a96ED9 +uniswap_v3,0xB432540909ABd3D9175BA75c4Cdd5D013B43b1e0 +uniswap_v3,0x699De67E45eF711c571f10BF674769BAc3647f94 +uniswap_v3,0x9087E3Fdc93782fC21Fc7B6E1c9F18bb6469460E +uniswap_v3,0x51d9A6f8022452bd56850F6E70E957DddE4E5677 +uniswap_v3,0x43DeC70ca029e159da315C3A893198bFD44Cc71A +uniswap_v3,0xfcDD9801adaaF4116ea070891b1A47039e60ed3D +uniswap_v3,0xBf05446d5C285B340122327537C500967aB628a2 +uniswap_v3,0x2C8265695a97908987De6dFF051c789cBE157AB9 +uniswap_v3,0x254b0687257Eb2f31a31c48C5377CE40aF833910 +uniswap_v3,0xcd0fBc9B628431a4f8aDE0D7D3AfFf82Ac99877A +uniswap_v3,0xD4Ed80b2105B3fb9E09312D19d17cadEF1D4C08E +uniswap_v3,0x2B21ED281dd9Ff8CB376A946D8526f906176b9b3 +uniswap_v3,0x9D3a72AE5D51A5BF06D3127663BeD5BC2c8fa6Ee +uniswap_v3,0xc6fE8f4BFBB69A9C6934C79dEbfa8E9696832ff2 +uniswap_v3,0x01856c7F8ef4f17E84371359b2d85daC321A9aDD +uniswap_v3,0x1aF74978BaA31d6896CF9321bfa2940D84e0F614 +uniswap_v3,0xb7b235A3de152393622a438ce70b772514D2EEb5 +uniswap_v3,0xE2a5145e56D64B267da3BdB4BF6daBC39687e1bE +uniswap_v3,0x2e7889e5a510425dda34B5D527934952C0f57e5b +uniswap_v3,0xbC22FFd36DC1286278287bC4073271389923a87e +uniswap_v3,0xB0CAF40c6D8155aacafE5b0a46FCa153bE1761DF +uniswap_v3,0xCAB54c25B737194A42d733c4C78ea2FAA7C356Cc +uniswap_v3,0x848609210d65cfdcaF450f2f65ee6411dbE172B4 +uniswap_v3,0x9C36E4eFdB1239652B23F8ECB53f0b0335a5Fb69 +uniswap_v3,0xbFEf5bB6E46cA995fD0C77ee60E68a27FFBC587E +uniswap_v3,0x825a750c973bEC0843a63e950fe2A632731FdF45 +uniswap_v3,0x5fa36079A205136e1022Cdb706bcce8cb0ceE5C0 +uniswap_v3,0x7c0336C47B5C8F6cADF519E2049F39C9a1b41BEF +uniswap_v3,0x72DC14c6048c3C35dC4610DEED47880e464b0304 +uniswap_v3,0xEeBF77d720a4971E2f5a1658195FB1F619cDc6e8 +uniswap_v3,0x4efDb13693aA9dc98eB4043A302c752af0BefF3D +uniswap_v3,0xDFdD21003E6a6708Ae40A5ae065fbDA6271b6EE4 +uniswap_v3,0x5B98a625E8c178d8A100DFE2F905F39cb4343F35 +uniswap_v3,0xEf057617e6B08b585f91b97c20010572D3bEF898 +uniswap_v3,0x797a28ABA77Cab5E1e8117D34D8300D8EC76C51A +uniswap_v3,0x83a1A95eC4010ed9841e12bad77bB258c700Abaf +uniswap_v3,0x358Fdd2EcE9d5269056177F0fA1B1f79E0036044 +uniswap_v3,0x3215A229311D654eB31772Fd3cEA7D78da731CA3 +uniswap_v3,0x9C63D621F26777570410E130f9a7F7E609F93dFa +uniswap_v3,0x33C4baE3899e26B445CD6D95376494c86A93dB1C +uniswap_v3,0xFfDc5DdA56FFCbE6D3cD22018A19880d87DA8078 +uniswap_v3,0x4b41E9bC81a33A2B8F4Db48665Ff05c13c53eC66 +uniswap_v3,0x3dDF15B168c6D72F8F6cB63baE83313E3dCd5459 +uniswap_v3,0x05f6C348e293CE068B5f7682cb01dc28524Bf6a0 +uniswap_v3,0xf653865af76f3377FF5277C2ec4E81152bFda1d1 +uniswap_v3,0xE31719e329080985a93648436E7B4D3D50180e7D +uniswap_v3,0xE28617a46558E38F1Ef118cCB71D2763001683eC +uniswap_v3,0x1a1E8D52B0B51FE415218e74fAd60d10d48C2388 +uniswap_v3,0x83f8D1A2CC4E329a7c8Ed4C28fC74f4c5b6Ca45c +uniswap_v3,0xe9C5f3331Bb7de5cc527bba97B87Ab7D224d6637 +uniswap_v3,0x4683B3c254B397d97d24Ff86b349c83aBa8aA250 +uniswap_v3,0x1F24D4Fccc6C53B5b2162C475856E1a64AB17b4a +uniswap_v3,0xA091E2DCe6659F9Aa88E2cA73265a8DF160Acf33 +uniswap_v3,0x9fAF2069DEBB9513C815BB0264bE462C756d8c7d +uniswap_v3,0x4AF5A3ADb853290Bc9f909138FBf1a3C3fEB0868 +uniswap_v3,0x9B8d1D25Cc9aC5aA1BCbDBB1212cdE3446b8A63c +uniswap_v3,0xcfd3fD29eF1abf63e2863418Ee60Eaa563C509c8 +uniswap_v3,0x8ddAA74CDb4B70343B13299131eba31c665dff73 +uniswap_v3,0xF18700199235D05f849ccFDbc8f3acf9AddB93e3 +uniswap_v3,0xc2bd5534cEd2a29f24bC68010fa0716676E270b3 +uniswap_v3,0xDcaE5d7462d3dF3f301ACfaf52f6Bf4d94bFF322 +uniswap_v3,0x9A1cdA3Fa15323f22884Ce4a3058d20b016B747d +uniswap_v3,0x217861a86007234Ce0E71e17F804F23AB1F27178 +uniswap_v3,0xE61e660f035E1d7fd972c3BfF4f62fcCa1FF4F78 +uniswap_v3,0xDb164E978DC9F6f57CD1B3B144aA17a15bF5cDCe +uniswap_v3,0xb541bd4184B469D9B299ecE7792fEB36D0773851 +uniswap_v3,0xF6f27C5dAD30c21E5c2A2Fa000367411CF924Eda +uniswap_v3,0x096C6c392eDc94EDc4EE9b124829f136Ea7E8969 +uniswap_v3,0x85957d5De2C64C28f61943dCB4f8FaD368378703 +uniswap_v3,0xfDEFce10a7b51b68d78d645956Ec84CeF30829C6 +uniswap_v3,0x43210151d3A36F8e787068C72F1f0002AF5f252D +uniswap_v3,0xcA8fbcf6dC9247e4A088987eb330A4D621Af1F0d +uniswap_v3,0x4E2f1Ad6D24314341BE4ABcdACe4Ab0a9D8459C3 +uniswap_v3,0x1C8A2d2B010710445C767D6807CEe2Eb70B0dfE3 +uniswap_v3,0xEb49bfcE903cFae69fE67Ad434853b6Af170B7d4 +uniswap_v3,0xA635509Fd1fEc9143b62b2DA86Ca76f47B68e203 +uniswap_v3,0x70c8d6b7f65020921c770824CB99B3d5A3D936cc +uniswap_v3,0xa8fc2aD8699251dE25F356f5F58513580b09690E +uniswap_v3,0x33B6D3A3e4550319cA2f8E4082B70592530f6659 +uniswap_v3,0x4bcD348323cf169d33a9b5D3f96f9219cac901a0 +uniswap_v3,0x396657Ad8473652D4FFbdDF25DF80C1369695391 +uniswap_v3,0x0187C85D2b896b12f30f0B0470477658168d2162 +uniswap_v3,0x501B61233cFC5062734a1cA0c0AAdE77C308C2ea +uniswap_v3,0x85C1beBFFA2b6b2ccDd45be8c8cac3bdD6449122 +uniswap_v3,0x6A8b747018069e4f843112175822B770b4316784 +uniswap_v3,0x1Fd6B741d82C1bAbE6Fa78a07189Fe83F84cba9e +uniswap_v3,0x9CD9012204dD12ACC228A7E8e4093E148845669B +uniswap_v3,0x624248854defDd5340F8fF424Ca6FAeb914641e9 +uniswap_v3,0x90029Cd75D3252c7df892De61F32F9141036FDe3 +uniswap_v3,0x7e71043c835A9C1f0bDA5075347a6e3Fbb3657C5 +uniswap_v3,0x91A3D52b4a679d566C883E3866aF8617d97e2964 +uniswap_v3,0x5f95870D9a64589E8fE02E2C413CACb74d72d3df +uniswap_v3,0xF7D302EC3A173C7cb84FD14B54F4DCa2D4105560 +uniswap_v3,0xB1876AA65fBB26C01b96652539d21D0C61bDeeED +uniswap_v3,0x9a8178F5f064F7E659F86A779Ef0B500D351299D +uniswap_v3,0x9B7250EFd7bB9D83Cf7642AcdD6032Bd1893c9AD +uniswap_v3,0xc063baeA527BdBd077b0852fe6F271205e33C345 +uniswap_v3,0x7AF77fAbDcdA8455C1A519F4a41ba81C000e788e +uniswap_v3,0x865c10098417cf4397B715A65e9BDA638fFB76bb +uniswap_v3,0x8598a6320Ad9F1d18fCC4514773FDE8BCC10CD7f +uniswap_v3,0xE900D67f03BdFFD83E332d1034aC7224b5588a62 +uniswap_v3,0x9C892E0972046Be8eF907A007F355308FBcadaCb +uniswap_v3,0x619a54C37eb03367d665D34798E6A1007405bB68 +uniswap_v3,0x08e0E8f400B0F6BAF2AeCec9233Ee4BDBea3626C +uniswap_v3,0x6554a9E558f977fED1A2b714E8Eb7E97399cbd9A +uniswap_v3,0x4B1acBCC19BE8D950654c72A57D2c0F065Fe7c7B +uniswap_v3,0xAcD1C4eFe9cB52e65D0a92E5D9B45baf8Dc66B90 +uniswap_v3,0xC09Fb9feA177d88D8d3038Cb8C051480ecf33104 +uniswap_v3,0x052dB74B375F0956039946178C1021dc16b176d9 +uniswap_v3,0xEcad5281418b09Cca90757011D1A405dc34Eccc7 +uniswap_v3,0xF979054066EB1d6D613Bbb51Bf132a9cA473b652 +uniswap_v3,0x1E3Ae9A71a49F3b23eaDf90576b71493b48ECE82 +uniswap_v3,0x92a54A6Ba7a43e292E01b0515706CF0770C8CC11 +uniswap_v3,0xd86c77629C520d0fE621F20687E2c1878e0Ad071 +uniswap_v3,0xCC4bd51ff2Fd5aC7ADB1828bB4920Ff3DB1361f4 +uniswap_v3,0xEbC31c53eF72d163540Ac6a7e0B534961B97362e +uniswap_v3,0x2746db3fAd26DCd2721966Cb4603Aa75fF06d63a +uniswap_v3,0x5e4f27d20Db4f21429EDBa05f8C69E7003CBC5ee +uniswap_v3,0xD4762f19b329fC6BB1903D7A276b851E0b9743dB +uniswap_v3,0x9D7A1aC33e2A6F71712Dc62F11466a6B74f5C318 +uniswap_v3,0x623e43AD2DBe7B25B4630Eadb97254dae8747203 +uniswap_v3,0xAC87e969caCfd524E6eBC1b1F149fB8e2E0629d5 +uniswap_v3,0x0C6B2874657D32aa7D10DeB82cA495b626b632bb +uniswap_v3,0x76e1d01660328522027d640A146e71736617d633 +uniswap_v3,0x08a0a30bA2F2D0fe4FaBAB5A9B10566066771150 +uniswap_v3,0x1ce7478886CdF3655A5294a6a5a8927e2D1C46f4 +uniswap_v3,0x641d2bDd73cB2b5080dC2dB486c6D5cFB442340B +uniswap_v3,0x7C255C91bea9e75cf3328De7cc96d57B606F6ad6 +uniswap_v3,0x145a758Edc0d80A21E715285544f219d6760B2B5 +uniswap_v3,0x2a232B684dF03e8396f059fe3571D06cF3a73A41 +uniswap_v3,0xe25583Df29a40FF647cE1006Fe8f10ff9c6412eE +uniswap_v3,0x38AC51bc5237809b7883D6279B46424f0e9e5B54 +uniswap_v3,0x1726B0A74EBCc5f877af8e9151f662f7Aaab9C5a +uniswap_v3,0xc1583d6C9738b4d6B913755682a571746929fffB +uniswap_v3,0xbB0c0969891AB614649b7BabB82c8C793d761051 +uniswap_v3,0x674c3B1de47896a4468B2f9953849A2F8b3E05eE +uniswap_v3,0x298Fc66cF884a6114A8c023b2D6352b6fA55E50F +uniswap_v3,0x2E50502527a26dB2ea16E19CB2901140196DF1D6 +uniswap_v3,0x80fF523A33Be165Ef62d68b5a6911fE359699e59 +uniswap_v3,0x21EaAa412ccb9967FC9376A3FaB07e92Ce586640 +uniswap_v3,0xE131A69cF5FD74b83a595882A27933DCAAe9e6C8 +uniswap_v3,0x236149D4a269D75EEB9ccaA978b4D76714f79A8E +uniswap_v3,0x63cf7F592258a6a2184e364Eea7F621Df0E23509 +uniswap_v3,0x951a4B1429930fa8EA2B19b53028E24Eed420B8b +uniswap_v3,0x33212BC0d7c26869688Ac11d6Da78a451CcEe946 +uniswap_v3,0x6797ce53396bc2aFC0692d5c597218Dc5711C779 +uniswap_v3,0xBE579dbF8cFcfa8D2716bC679263CD0122daD840 +uniswap_v3,0xf60dea2cAb9feD06854218B16A7cDEDF003d541e +uniswap_v3,0x27c3FF7D90F7de72EC8549b3CD3F2187b56eba99 +uniswap_v3,0x6F86C37B5B73CD07D9f12c11b2568d37f25dF267 +uniswap_v3,0x8b7Ed0596C9c52e319fB13b2d3EB584131b3D39e +uniswap_v3,0x37B31EA693D1fC2137537D751514b01212433aD0 +uniswap_v3,0x1E4E6F6cF232BE9FA04ECC5018e939a628fD44FF +uniswap_v3,0x4828c2f71E5eE7965b9c5F7559A9D1901E7c1906 +uniswap_v3,0x0Ee2207e4E2B5F144Af755a33De9aC0329b532B0 +uniswap_v3,0x17c60Fa3fbb8DE05576cd92fDf74CF9e901eB4c7 +uniswap_v3,0x0D8f715fa533CE43f7f079e7fF62B7a5E744477E +uniswap_v3,0x3059b10F71ffeE8109Ff51D689EF9981F0248Ad1 +uniswap_v3,0xc58f038DacA4Fa9d4b5D2Aa9BAE5A5a24Ef4F771 +uniswap_v3,0x2462D4F8395171724ef56C96209924426F1ED813 +uniswap_v3,0x7d0ADa78873AA2Cb5Ac8B090cc6d7fCF9063A013 +uniswap_v3,0xb7dB50Be25d2bA2b359d687Bb12c11c71aBbe1B7 +uniswap_v3,0xaD2eAe38A513bBcFcd69CB34fd668563040497C9 +uniswap_v3,0x19E0C3d0092a60f0893D7F744F30Bd3Ccc40fb9c +uniswap_v3,0xf219f36D109f3Fbb40fE35390642b01C2bC8e398 +uniswap_v3,0x31Ff71b12c0C3753eCeE420e760Aa6e9c48d7EF1 +uniswap_v3,0x196581AbbC7141E9f7B2f1e1952d7ff41EA147F3 +uniswap_v3,0x66b935d92193cc786Aad7A23AebB0d60A08A9A3f +uniswap_v3,0x2B5C8450c702090cFB2CDeaa9aDa753f6a0Dfb62 +uniswap_v3,0x7232F4600379180d1D3b142172104c93Ca2e8E50 +uniswap_v3,0x092110b0b07bD8fcC9Cb33bF73A06930C0f91ac3 +uniswap_v3,0x1783ec23132Fa8DDb84b5Cf9cCc83BAFbc959690 +uniswap_v3,0xA071bEC46d800e774CC7a4A605cA25d7286601A0 +uniswap_v3,0x70bBB951DAf1C185c77216E2F2dC0d57Ea731567 +uniswap_v3,0xDf42d1354884358820064c3f6f3C37E20F6Fe1C4 +uniswap_v3,0x5038F9029eeaD091930D0eB759AEc864B4327cE0 +uniswap_v3,0x6971C303D468a89015D3aa5F7Cc20a75FE8E720E +uniswap_v3,0xbB608cf63ef7C8298dC88c28316d0B555CA8f61c +uniswap_v3,0x79661B68134491E675AB2A877A79f7B0D3c947DC +uniswap_v3,0x6b340a9F1c1aAd19895b91633aA2Ba3132eFd6E2 +uniswap_v3,0x8C9385ed733492d237908976b3b7de3038382c6E +uniswap_v3,0x6860A8951F8D1Ec505867088504ad1854E27ecA5 +uniswap_v3,0x5ec4D97B19de1ad28d5A5A2427C939D05A4B6e62 +uniswap_v3,0xb1EEe8ecB00f1c90c035e328C562F00A2e264175 +uniswap_v3,0x783d8704f28547b983f60F14Ab1510348D449fA0 +uniswap_v3,0xCD08E6DA36106051Ae32fd46Df7DF90659892122 +uniswap_v3,0x36f0CF505D73Be012C52a6D12197B73b653e8F1A +uniswap_v3,0x334D480F4399905C9F8170015Fbac284dCc17DC0 +uniswap_v3,0x99368F029A2F4621892eB4DfB14CB74B419467a3 +uniswap_v3,0xcB2602F349DABb341b05f0937cE73Ead57D94D91 +uniswap_v3,0x798AB49BcE97984a218Ca7De4B544B0bcd9261a6 +uniswap_v3,0x7Fc02200bb1442E591102743A504954021674262 +uniswap_v3,0x75f0E08597Ff64D571ccCbFa5aA55c4123bed570 +uniswap_v3,0xECf80b20c265A7e61b4DA7b0cE329C738f28c460 +uniswap_v3,0x4cc7f3c621bE55efc5C4629B7930664402643b3A +uniswap_v3,0xe0f56212F0EB39cAC537d4D4BA6aBF04f07DbC20 +uniswap_v3,0xD8d03E9E8082A5e0FcD70153d4384ea8a4f054eB +uniswap_v3,0x946CB8F8df43C48fff62B244f15148f34051Bf15 +uniswap_v3,0xB0fbaa5c7D28B33Ac18D9861D4909396c1B8029b +uniswap_v3,0xC684927860B00A768c14a0bf9F27b91Be1A9995E +uniswap_v3,0xcAB007c2534C751a9E92b4872C3E44354f167995 +uniswap_v3,0x183EDC80669137aA13d1f952402E36FFF66B464c +uniswap_v3,0x8387dBf39D06D5fF45b7fdF7f67146e9B7eAC25f +uniswap_v3,0x01306B8C65211321cc11699a5dffaf37DAc400e7 +uniswap_v3,0x2FbF37838E82fEc5fb3EF1d18439B770a27e3d50 +uniswap_v3,0xeB00349d28B2B3F7fc7d0182d1433fe5B4cB3425 +uniswap_v3,0x9dd7c4542e3562A52De5D7277febed6e20EaAdF4 +uniswap_v3,0xafC766DDE072c4D66DE1b7a0baD11255ebA97764 +uniswap_v3,0x56fAb3401f466117c709dcBAc722ee4f20971b2E +uniswap_v3,0x70b46dD48d261e6b5FaCF461c0dee107b76FBCC7 +uniswap_v3,0x27D0b1d11c7f8f42b90a0bAf9615f8Ad61d8902e +uniswap_v3,0xf310dbC5E850A82c7223D0575bC1732484091f92 +uniswap_v3,0x186Da94dbF1a4e217fb6f4946f8520f4f76050aA +uniswap_v3,0x2847924CC24FF51eEcE8A3D5c465b04803119016 +uniswap_v3,0x91c4dd0fB177A806Cf44eea78f05B2954c794D67 +uniswap_v3,0x016813dB2f1ce21C82c9D81688c5a146F6CC5381 +uniswap_v3,0x8559caf74DF6782ee3A3Facff3edb211DC7f8cc0 +uniswap_v3,0xaA1dCd58C6A886DFfD9C5DC6209eb8B24203c96D +uniswap_v3,0x07452AEb136deFa0319C62A3b25874F6d3178405 +uniswap_v3,0xcB9E3410924B9AcAcF09f0cD03235E0e5c8487C7 +uniswap_v3,0x7d58e8E9F1Ae17F9bE8c0F6fB9153d961eae859b +uniswap_v3,0xe4a432D8394060a9217155483B693aC1Cc6719C5 +uniswap_v3,0x7D8dac0834634107D391aB856623C3D2baD0760d +uniswap_v3,0x9a1E75e07752d03c550Ad3994F21Aa717A0cDc05 +uniswap_v3,0xE65E5Ae2BB0638EB882Ae38a2de1CB52399AaC45 +uniswap_v3,0xBdF182833ec03fEE3CB154bD7CaD6232Cc5fD651 +uniswap_v3,0x4Ec3Cb622b5c94184bc6bFf7914c555b5d74Cd43 +uniswap_v3,0x22fAfFA325707F7479F3A243e04e89Bf74734602 +uniswap_v3,0xF462BaF7306Ce420aa226eCd4c01C7f65eaFF7B8 +uniswap_v3,0xd41E87B2547D008DeFB0F2e07444d7941495104e +uniswap_v3,0xDe020187a1ab4A8c5F5f6B46A9C96d6c431c5076 +uniswap_v3,0xd41661846cD223ae043A1DF96F733031380B1113 +uniswap_v3,0x561B9A7C2E3655785bE91813560e0D39D68Bb0b6 +uniswap_v3,0x8432879904D45b1005B81d731AC32d280918Ec4B +uniswap_v3,0xE180e86fEdE43587743cc719875CD5e8b513a68b +uniswap_v3,0x6d45AB568cFCa75Aec6AB852B94EdD8015aF6Edc +uniswap_v3,0xB99C2C5AC1DD111278eA299Ee32Db61b496f70c7 +uniswap_v3,0x7e19682F8aAa60e8DB2Dd86B7042A682595BDCf4 +uniswap_v3,0xb2a8BeB6943F0b1fEC290d698912A212faD47DAF +uniswap_v3,0x4A6c553FF637626487BD5141D461cFCA6EaF06A2 +uniswap_v3,0x788D55ef7a6aA6f233D36BF8Bc9B51b8c6703255 +uniswap_v3,0xAE7aB7Be9c062633cd451681D4E2AFe064159a3e +uniswap_v3,0x7c65C994cd687CFD3e793623D9eD50E4E245CAbe +uniswap_v3,0xF74510D79C9b4e0EaC8Af07F2932064569683f7D +uniswap_v3,0x9CD06c0559b31188e247De6748dA61e9fEE06f88 +uniswap_v3,0x9Ae695Cb31C1b977422E05e54289899dF6177f5A +uniswap_v3,0x5aEdD07043bc9438BB1acba8F8B1Fa1F3AF7f971 +uniswap_v3,0x5325Dd7313eb32866bBdFA6EaA4312Fb89bbD8a1 +uniswap_v3,0x4A69A382CFeaCA49A10A673348c882dECc5222f5 +uniswap_v3,0x87118ec4efcf9b8202f8Be2C2bAE87b80920Fe68 +uniswap_v3,0x68c9325cC268dF8b9ED4A06429587f28471b5f84 +uniswap_v3,0x762171711f7D46EAd062853707f76FEE990881aF +uniswap_v3,0xdab2E5852daa87335D3BE842B458a6CEd7aB05B9 +uniswap_v3,0xA4404597Ef47BC5A10daeAcE9f170E20E1AA6bdC +uniswap_v3,0x39A79450f2cB3Da2375A8219493518e3059ffd10 +uniswap_v3,0x9F050D4224e03512810D31e5933E51A6E9bd93eC +uniswap_v3,0x56b8e21f0a8d76FD27732B56Ce90E73325eCf616 +uniswap_v3,0x573A55Ce1917E6c2ac44603a00f51c37dFD3Bb67 +uniswap_v3,0x23fab109AC229c0F227538dEb6dfA8375DD5ab58 +uniswap_v3,0x351C264A62D8d78Ca5e9C8a3e01985FcF3B63F3D +uniswap_v3,0xc630f5404043eAC4A8486C05C95326795Ef22202 +uniswap_v3,0x3c8961Cb820E48E96167cc4bd7687f1f47429843 +uniswap_v3,0x6889d1b2752bD875ad0bbDB94ed20eEEb371F51F +uniswap_v3,0xcf97aB0039A5C6137BA8f11ecF93737e919316eB +uniswap_v3,0x3069c25831C9309078971F2E1C310AcfdD0514c0 +uniswap_v3,0x4157fCBB2cF75cDf3f16A0e27728bcC0BE36c149 +uniswap_v3,0x317c459145Ebe1dB0005F1a2120256976020ef8E +uniswap_v3,0x5c891e543149F9473ea988D9ACf825D51b0Cfd4F +uniswap_v3,0xA678FE5D31708477c591db4e36D93FeeAbA89E1F +uniswap_v3,0xBE4152553240f5188ED115c6b8Bd667e8ce6a711 +uniswap_v3,0x7f24ee6e97b2AA837B3d50a5ba7Dc33c01FEa503 +uniswap_v3,0xe16e7a724250AD35BA2de4E599A8b618ECB5d6d7 +uniswap_v3,0x7477831319edE3293d10e68941dB767e33f83956 +uniswap_v3,0x4183fe8CBe172103396EE42b2694AdD372829CF9 +uniswap_v3,0x56593C03Bd79eCD0C7EAD9Ae1Af83568b5D77737 +uniswap_v3,0x5A5047b0dd72d5f3f2CE17D5ef57175330DdbD02 +uniswap_v3,0x0Df78f014Fa0daf2abb70bC720DF74b0aaaB02e9 +uniswap_v3,0xD34F72525fA5A75D9A376337E398624EBc8D847F +uniswap_v3,0x9FDD313D483F43ac68343bc9c49961fC48921AbB +uniswap_v3,0x70403FdD361F4F193AAc04313e185D2d1298b2AA +uniswap_v3,0x676172C834FA24FA85902F5a8BB3F5d162A59A84 +uniswap_v3,0x3f79e85B2fD7dd17a05727B4390E946a9D9a27d8 +uniswap_v3,0x3a41711844F4722658f1F8A000BA920e3988a0a1 +uniswap_v3,0x1cCB66fED28398281FE3f0e7c6808E031C3e63B1 +uniswap_v3,0x48a3f42Ea484443715E77149102c09C891c6c908 +uniswap_v3,0x49fA99e6E328C82B1f01099dBfBFA874A3adA640 +uniswap_v3,0x72135E2Fa5485deC33F9a55114939CD3400f39B6 +uniswap_v3,0x38F1A0f930B037AaCA703784f560B2a7bD0fbC21 +uniswap_v3,0x2aE3e113009E336F0244050dB24fb977202Aa023 +uniswap_v3,0xAb6BE376326F9F480996874A78B8cCb338bA348F +uniswap_v3,0x12EE86243DeA68883677bdF0e2DA568ab04d1637 +uniswap_v3,0xdC52f90310F560611bE0baaB85Ff304654F7c781 +uniswap_v3,0x1b1c7872c1C251771eC3eE53573d232344c8557b +uniswap_v3,0xd12B1Fac04C6E732F88615d2C957b2D02C5aB794 +uniswap_v3,0x8bA061bBEbef104C8b9A6b58761Ea58ff1ACF339 +uniswap_v3,0x0F102F876D8f4Fd59173CE27E21a1C259d0DAc26 +uniswap_v3,0xb7AcE6D17Ed156A4d2859F8F26b1C7D3d32888a6 +uniswap_v3,0xb120389b9593B766399A36989Cfa763A9D8f5452 +uniswap_v3,0x50A0d9fc516E4559E54B9A9d005de935DB6136cF +uniswap_v3,0x576D8dAa66A078c37A5b43355e10721970D9fA23 +uniswap_v3,0x3cC174DAC8549Ccc83C2c1f9b1CaD1b11211Ad5A +uniswap_v3,0x98992CbA85cD8739A7B6Cc69F31C21f84DA8CF93 +uniswap_v3,0x922C29868cD16fE1Df9ddc7Ca082559B71A158A2 +uniswap_v3,0xDE76BE20a17fe64faE659968210BDD3FCA086388 +uniswap_v3,0x9B8b7823F20E1e59e9618e2f1655803391C9f50C +uniswap_v3,0xFB0F8D41eD35C2664988475D60F6A089ff48c7F9 +uniswap_v3,0x615906ecF8352dF45139350CD2d3c9226D5aA6F2 +uniswap_v3,0x2CA5F6548C5baf7A8Db6a177567D606f6e01C530 +uniswap_v3,0xB50C2EaDc69B6924656D3bc05F60c8E8C9C3134A +uniswap_v3,0x13EC7A95fcbfac9E4a91d05F08E2cB2cE72f7ae1 +uniswap_v3,0x062418971f187cEFb4D0fC35543cAF0C09126C80 +uniswap_v3,0xc322E28DCFB832cFB495a2E973BD5f1E3Dbf0086 +uniswap_v3,0x976Dab857f2631aa092C43BE62385352D1e38121 +uniswap_v3,0x117Ed33349DA03686EAcdEE6Aad788a143E8c63c +uniswap_v3,0x5F005D1b2fd42FaC7Da9325f0dCD934b526C1fDa +uniswap_v3,0x637841E8d9232bd5A50f956F38B0f76394975229 +uniswap_v3,0x52967A86b7258cC52ff9E953266Cf735FA1E3df3 +uniswap_v3,0x44bD3A38cA44CeA669295c0fA98F56F0B42653d6 +uniswap_v3,0x090f3fD9110621df127c3F9bE5c6f58C02F2d5eb +uniswap_v3,0x1FE67796A2728018D0DfB64Cf89006cF9661019f +uniswap_v3,0x4F83A621a1BD19D7D13c0Dab560b3B408CB3c795 +uniswap_v3,0xB1FC8523A1E8396617a91Bf7e53B4ccEf366d637 +uniswap_v3,0xf0440A9493e3e69d36Dd772Ae273ee5aD5401E75 +uniswap_v3,0x490E01458BDdD1D6cF0BE869290Fb0E239E8bE9B +uniswap_v3,0x9B572dB8EFD5BE8Cd33C439a78D1BE6067bD053C +uniswap_v3,0xe15d177E27E2332173e3f05f3f5990cb9c880C05 +uniswap_v3,0xD99fe071b1F4f14d6c6c3b251B287A494A2Ec078 +uniswap_v3,0xec40da63B0A6407DD76AA10B8Bbd9462EEa6f224 +uniswap_v3,0x909e5D5b57e6FA8704D9A8D1195E1B8B706d66fc +uniswap_v3,0x6D34165d5Bfe8542E9530a536AC009Bb0115472c +uniswap_v3,0xF841D90166aad4319562bA106ff52Dd9E28C5239 +uniswap_v3,0x96f029C5c0254D7Ae093bA2FF02AcD260b83bFdC +uniswap_v3,0x09e53Ee6fe564F897D01CE7Ada2a9Bc830E33d39 +uniswap_v3,0x1332e8888C65706409D745A199A5cEB561d42C48 +uniswap_v3,0x5A8436D53dc1DDfA01c6F283D1d7FEFf0B19BaB6 +uniswap_v3,0x907e92450236639a6C5eD6D0caBe8EA54e619558 +uniswap_v3,0x23ab20Eb19cC25DB7B4c91190829C7628C0CAa48 +uniswap_v3,0x95facA00Db92AA6371933ef7E5e78ca21d453b7d +uniswap_v3,0x0aD4Fa97e0b1853Af5538a3E34687B9373B17645 +uniswap_v3,0x199a0032d624227b41a4265bE1Bcb8Be9A9bdbe3 +uniswap_v3,0x92F31AF3A6583bc1Eb9692585b3b285A15321832 +uniswap_v3,0x88617634339877faf179CdED1dA4ae6f904BFcF0 +uniswap_v3,0x3Dfe2478b17E5BB24A0022Dfe21DC9D1aF628428 +uniswap_v3,0xcd777577dbbf9f75142bb01d148FCA70efDeC960 +uniswap_v3,0x9c15F38CFBCb611FC8B3B3159D7993b16A69cFAC +uniswap_v3,0x3137F00399cB5c6C0e9c5d8C421FBdd88FfC6a7b +uniswap_v3,0x5B4d41AFE843Dcb567921A16e9c450F35837AAdB +uniswap_v3,0x6f4386817330C8E8748076cB730Cdd70A883AE22 +uniswap_v3,0x2D4ccaEA9D2Acac07cC4BCf42DE2ce3F143a9dCD +uniswap_v3,0x06AfF972D476BA6cD89e3De6eBd2c3F17d66aF9D +uniswap_v3,0x2E9fbC7b26397d2B7F8ce8034cfCD8264d197a98 +uniswap_v3,0xc96b2408AB0Ad2F04fb3a6A2B9de0B841b127698 +uniswap_v3,0xDcEBfb446a3c53aFDd6503FE65e350d94E9c06a6 +uniswap_v3,0xC8D7Bb02D3b1399fc557f73B91338674adA4a86a +uniswap_v3,0x7947D22776b70e356A33E03d90a402185AC97d60 +uniswap_v3,0x8CE8Bc67914679eDA3C282577a5083B299955B57 +uniswap_v3,0x7cD1B229a8183Ca8F0a2A1B50eDeC62f4a5aA289 +uniswap_v3,0x0B23118d768512249F5f213B03d17a8e14222f5E +uniswap_v3,0xA74c5535bE37e589E2BDef88A04423Dd12E13e5C +uniswap_v3,0x6A223512B807C53FB350dD4C091CD3fc1E12d9a2 +uniswap_v3,0x308189a54a3A62D15f87538cdbE6010Cf3dd47fA +uniswap_v3,0xDb450c004A72aA664E6fb0eC39dce3De074C4dC3 +uniswap_v3,0x083547F2d2A742089e97EC06C1E04F30c64E583c +uniswap_v3,0x003024DB4f5Ea13E366B1D63167975ceb7064940 +uniswap_v3,0x788F4E4319c540ed91e467CAD0B744Ad10e76373 +uniswap_v3,0x7FAa1464C6C3ca4D88d3b0eeC98A979d55C48116 +uniswap_v3,0x6e4E79cA5a22463A17006D4a09eD44B99c67A187 +uniswap_v3,0xE10E60c484B0caE7a65173a7955aEd9689404Ab5 +uniswap_v3,0xF01bBCE14522337533AE6E60eCE16f3325a5b48B +uniswap_v3,0xaCE41ED6a6E0FD6553f0e39A28a072BD31DCDadD +uniswap_v3,0x80af82aA13FD65548bb17Ca31aa3deCB6673192E +uniswap_v3,0xbD1a51924cF5CA66B43073eef1F9bCfd37D4fB07 +uniswap_v3,0xc506e9909ceF62a0cE27937925054DdcC23c1721 +uniswap_v3,0x99f51b76C96C0e6026c83975336035Ddd72E9b9c +uniswap_v3,0xe21d11dcBE27DC9a173A0c0cbbacc7DF87486Bc6 +uniswap_v3,0xbb501D57599f4E85749a45Bc91912Ab633B4264B +uniswap_v3,0x16fE9896DfAebC4a023e1e935a9350125beb3C39 +uniswap_v3,0x41e95aE41221a184F208B7714dDD68D954bB81F1 +uniswap_v3,0x6128480b44Fa5DBD57B8030A70Cbd4cA7aC3Db07 +uniswap_v3,0xC82cCc34585653698639001B41bA66aE050FF9C4 +uniswap_v3,0x6C93d2444cb12d7d9fA5E41d68Fe46962aeEc283 +uniswap_v3,0x8D4ba99f2990e1777b9b6d6aE5daBdf0F6Bd27ED +uniswap_v3,0x94A0f0cbe537D395DdfE4a578375a21aadd485d6 +uniswap_v3,0x38ae18CB099E65738ff69e71aFbF287ffAdA08dF +uniswap_v3,0x1dc8CED0734bFC8ccf02587dD8B02153456B0cb3 +uniswap_v3,0xC48de26894a7847b11732c757aBAD132F0Fc6dFB +uniswap_v3,0x8169E93E4044288607525466CBDEdAe8558A75D9 +uniswap_v3,0x62026826d6657EDF219274EA00Ef06D2a8cED742 +uniswap_v3,0xd430a57586bfbA94c0BF1652E194835110e07009 +uniswap_v3,0xbD91D73a0BD66A7b2C54855c4572A35283dFC136 +uniswap_v3,0xACb987687Cb8835F5Ff8370E579a4F6212B9C488 +uniswap_v3,0x1909110D81FD152EB66567F8Dfb36A65b3200A00 +uniswap_v3,0xEd3Fc0DbeA844Fe74F41Fa69C761EefcedFb22bF +uniswap_v3,0x86fcA9D8a25C146E76ab16FAA372a492fb0660C0 +uniswap_v3,0x88B7bea3a56e9bEf8128fE2eD8cA7011a7eBd096 +uniswap_v3,0xCF90e337317c3064E40B633a50Ba48A4258e8715 +uniswap_v3,0x93a50e149ba4fe3A7B87fD60DE9580590cFd6b0A +uniswap_v3,0x69D60c6ae6EB0C6c21C4eb969Db000B26fA56E7d +uniswap_v3,0x2C14e5eC3Ea61e8559a768b8182FC3341Dca6E7a +uniswap_v3,0x60Ca07ae70C5403220B4b6bf0ff6b0EFbCC72D6f +uniswap_v3,0xC66a2a50EF5fE1dE06C90C972ace7eB297dD803B +uniswap_v3,0xc708Bf52dB296B04526BD92600EC0F14d4Af4230 +uniswap_v3,0x14Ac7a30d2A6018fc0CD73DdCEAc841F33762230 +uniswap_v3,0x041eD2a5C4aF75D4354ce46B8eC311A460322e0c +uniswap_v3,0x321A4A71F136227E4c0653f9AD563f9a613121B9 +uniswap_v3,0x387C18a9Fa517Ab13F4D78238a208C4f2E100F1c +uniswap_v3,0xf44Fc9d08db8D7Cf2771E056edbB8126e8a3bD72 +uniswap_v3,0x30d61Bb28A6789f9f49D8c7fB198D63B6aba4B61 +uniswap_v3,0x3c2928ba8b162552468e5f6c439e25ee7cfA6C06 +uniswap_v3,0xCe628976857852F30DcbA3dDEaeab6BE18561565 +uniswap_v3,0x1F7ffBFA892F2c731E9314326c00Af57fb1200C0 +uniswap_v3,0xDaA5EB5Fb16fA80D2D7bd87DB81983567faDea51 +uniswap_v3,0x739281980089A10Ea7144AF73d18C921DA47D718 +uniswap_v3,0xd7FA6CD8268Ff80DcFe1762500BAbB0471be71DF +uniswap_v3,0x183D2Ff1838Ce96Dad13CeBD2E592E63eA424940 +uniswap_v3,0xB6320BCA2191915b76A3Aa8F6DbBee160Fc4A031 +uniswap_v3,0xC57C46b99da7Ad3e14a65479cc3D6Fb5245bBCc9 +uniswap_v3,0x856f0fC105C611d2FCe8255A694E7c824Dc8072b +uniswap_v3,0xBb997310749DA0b4E51A7DaA2b3da7AF7101f293 +uniswap_v3,0x5D77c81A06691f223bd4bf90C6Bb42f92116401F +uniswap_v3,0x40fC7CDa03139eBF7a0D3fC01F12B9D9a878Cc92 +uniswap_v3,0x773983ED1Df6155D5470d60380272AdF43E7F266 +uniswap_v3,0x5cAf02e2AC327685893aef1ED7d9495fDa9E6e8E +uniswap_v3,0x83446d99BC69f8f3611D3020fB89FB97f50c6F43 +uniswap_v3,0xd6948DFC62d7033C27F12DDAA6A9007F1728C90A +uniswap_v3,0x7FD7f4df348fAf9A9e49eDeB31c32B0bcAd99e0E +uniswap_v3,0x9d07472F35Cb348abAc8a2491CbAa002C0Abd5D1 +uniswap_v3,0x25576A726aF81afB141e97713eb59e38aadC482D +uniswap_v3,0xc9B4B0F7AF9edeAb42cc2fa933d58773C9Baa2a9 +uniswap_v3,0xb43E476620Fa569F0b3814F6F2648a12CeECb158 +uniswap_v3,0x22eF9D2DDD293A190F678eb4dB330E43C0CB5Cd2 +uniswap_v3,0x9394e2a6C61b4A901684dF59A2c982CaD1bc6dB7 +uniswap_v3,0x640c56d30ad38b86033C0e3ae5042C381693529b +uniswap_v3,0xAD762c29f6db47EA24215dcA861c1d375E33956B +uniswap_v3,0x199bc5db9170BA4a5a0C723015985F93ac477dce +uniswap_v3,0xeB8225805E440D7173545B0C059280b352F5833e +uniswap_v3,0xf5e999bd1f048b1a67d830b28BAEA9688a61A63F +uniswap_v3,0x4612e5b0DA22Be7930cCe997eB4899c59463baE3 +uniswap_v3,0xb8ced903ed1Bca2FDDc198737E05d589223a04cd +uniswap_v3,0xcc6Dc14db24a0663De326d2FdE735DB38998EcDa +uniswap_v3,0xA0203b2dEf3734B1d804a9AfE16762aB40B2e0c0 +uniswap_v3,0xD44D02531832CD4b4f6d41DE6f9A819743e4Eade +uniswap_v3,0xB5C93C917587a8a332fAD2ea406fAA436D1D36E8 +uniswap_v3,0x7DbeD5B6b387a7a5bDd0Ba48D97E05300a9A9441 +uniswap_v3,0x72e4ecfD293EB591eeCF14F37C78F98991CC62d1 +uniswap_v3,0xA3Aa8cb8f23dcf7fF5273da646E328184D96AE37 +uniswap_v3,0x3D2E49F4462a6800E11Bb8357444107d64aa81D7 +uniswap_v3,0xB28A19Afd827C1FD3BDf38A6EeC8F27101bCfE64 +uniswap_v3,0x3B722aa71EC13d4FbFde2B59FDf20Ec8396f76B1 +uniswap_v3,0x96AD8E0Be13C73b16dfae25d8131e0AB72c0Db0c +uniswap_v3,0x0665816c53e1D59FE28d946C555c8633F8f5DfF2 +uniswap_v3,0x663001eb6d286c0aC32AdEAb5955B96c82BeFfEb +uniswap_v3,0x47d90D6dE5bBeb31a4b4D10C632abAe9db55Bf56 +uniswap_v3,0xe183015334Bd7d7714A2a7C0c5f6bd08c9C395B4 +uniswap_v3,0x231b30568C1D942269B72614Dc780d9c9916c1D5 +uniswap_v3,0x9CFF8640A9f81D45BE9a6E92cFC30ED6158f0230 +uniswap_v3,0x38Fa3DaBc97b3292F0f9F967F35A68b02C3424b0 +uniswap_v3,0x5fEc3B81e4984010b5bf8Bd0CE28095Ef6F4F38c +uniswap_v3,0x5fEa85287887C3833ded251bbc4F39FF83f910E2 +uniswap_v3,0x8409a92f639ef0963aed2Bc6A8c0922E4293902b +uniswap_v3,0xc2983d931B14ceDf2F972dE73a9A6f8aDB370915 +uniswap_v3,0x94AB1B4E65B783b61534F5586d7F34E300Dd89dE +uniswap_v3,0x0b1d608e1246fdDF16d32aA9D47a93Af34046022 +uniswap_v3,0x43E9708D8E24A6B6EE41F97069115Fc87001d1ad +uniswap_v3,0xeDd181B4D99ad426470A5fdE8aDfdd93751E6314 +uniswap_v3,0x7c2D26723AF47F13E5F3Db2628225FCaA5a56C5d +uniswap_v3,0xe4a5a2A346d13aFfFc13b81C765C1c29396CBF46 +uniswap_v3,0x1c4Cb3c9225473d2EbddbF851F37B7346e50177D +uniswap_v3,0x106D74082383601aDefb8403FdEfC9919252f7e7 +uniswap_v3,0x0fD5DB45f157beCEb55BE128E985A7C59A720F2f +uniswap_v3,0xAcc7C93F843dE89Ba932Bc6F18490e7ed2021620 +uniswap_v3,0x7b3fd71706Dba1a481A61830aab77aD38f7ef746 +uniswap_v3,0x1c123A7C3C00073141bc75f86Ae49aE48561C73b +uniswap_v3,0xd03083401DE8279d1a20Dc4FBFCb59e8D7136EDe +uniswap_v3,0x9e06Dd1615bEdB2ea8E593A8ee26497d8c57d8D2 +uniswap_v3,0x498ECfac8e7ed1d79e137CADc47902011529a0E8 +uniswap_v3,0xC4b3DF389cf1C0DC0c01C68C6dDf675E3b1DE24E +uniswap_v3,0xF12521beF898cE6c42C948a9F2cb9E0007dFAC91 +uniswap_v3,0x1a9f4AB57946b590449f2f5c51C6927b1299310D +uniswap_v3,0x5060a9980694cd75349e2e876771d23a04AC2A49 +uniswap_v3,0xc8C8F538127cc79aC9550F6d70eCaD45aA3a3eD2 +uniswap_v3,0xDA1730bef829FA8aa9Cf90c323180CED61eFC53d +uniswap_v3,0x7FA97D9bD213100AC49b2d7229A1C11bA1430379 +uniswap_v3,0x59942cE5a1277Dcc91edB27D9b5Aaa7841eC9c62 +uniswap_v3,0x390A7Ec0B8513E3f81285274E4Cd1976827Cb191 +uniswap_v3,0x1514a3e1a720f4419c972960b8c72ea356099440 +uniswap_v3,0x828CD0Ea15887588A5e20B0F5081dB521423373d +uniswap_v3,0x99981592754fE4D536D0Ab122Ae1269C3E8f4135 +uniswap_v3,0x3234a2d681C568FfBc86F855f728474960E2C5aC +uniswap_v3,0x586334D68873b5d836cd55B6da3Bd7Aa50aC74cF +uniswap_v3,0x7490B5E63fBe6AbB13C806D1DCFb95320E4374c9 +uniswap_v3,0xb2aF2E8D2247B89a4E312e1D71DDd2952736d245 +uniswap_v3,0x3c1c5B95E8e00134208b50c4deB4a9aC0324d450 +uniswap_v3,0x8b0B953111F1A58C7935b96a87530963F30d2f16 +uniswap_v3,0x51227b128d00E9f4dd62b3E38C4697784e1aDE2c +uniswap_v3,0xc07Cdc30F9997f22Ab4Ec4D681Aa35E38e4902D4 +uniswap_v3,0x7A9b53EC68B4A74e5e38CBF5aB4893Bd68e4CC3a +uniswap_v3,0x8afC079569A577fD6F1AAdd9e3a93c41a387c364 +uniswap_v3,0x77f80b528e49D87113889466bAbB1b403D736288 +uniswap_v3,0x00D1eF7AaEC204Dc27c6e0C7794e41BA200B81dC +uniswap_v3,0x884914B85ACc8743da64734D2B27f54a86253234 +uniswap_v3,0x574Ad9123803B072a36f798CBDDb8A0574A6314E +uniswap_v3,0x1767EDe97625bFA245Bc70D4B4a74887219CacAF +uniswap_v3,0xDa42fBd44F1627804676f4061C5e2C65F3849281 +uniswap_v3,0x15AB08F80865E5427Bda8698E493A3becF05FE6b +uniswap_v3,0x88D826d66A1C54Bc8Ed84336710109a8c80dcDAA +uniswap_v3,0x6eA096FFc90F0fabCf101D780EdC8DA0C72Ac2d5 +uniswap_v3,0xCe4F50e65Cfc7235E75Babef9C168AeCcC6059F2 +uniswap_v3,0x97E85C3d9599914e0A710eC42E34dF9fb5818b40 +uniswap_v3,0x27ADaEBf192692c653f1e6090651383bEB0366aD +uniswap_v3,0xAb8bB59A136B5d4883DEdca532b3fFC713D387FF +uniswap_v3,0xE18E0d0362200E7349aa161160f8E25a38a7757f +uniswap_v3,0x6a39c10ef2EA283213f0825903a9a53a4F365ff3 +uniswap_v3,0x03d0ADf4f986DEac3e864ed85a7FB58794D4f496 +uniswap_v3,0xC038355052380071b7dccc48b506d1925EeaA4d6 +uniswap_v3,0x1d3D7e2d236b546247c5717d18F581C28F34792D +uniswap_v3,0x761b3a207356f8298a0ba81Ad6349004c9E60AEE +uniswap_v3,0xA76Bce435943be992C4B1D03404f21B6c1b7475f +uniswap_v3,0xe4F30F4b059f912CC324952BBB081237DB40a85f +uniswap_v3,0x365f8D0f99e2E4662cF0E6D891C18F3f74317952 +uniswap_v3,0xE1846C99256C7a690347303E15BA64aC0f13E5ce +uniswap_v3,0xd2d3E7ebA629C28bb071Fe204D86533BB0Ef75cf +uniswap_v3,0x3204063e12faD10fEeF33a01dFaB94159f613FbF +uniswap_v3,0x9aE8084c21752971D867597c07F2673765D949a1 +uniswap_v3,0xE1B41ef1D7b9886085D59b5fB87Af7fBC58d785C +uniswap_v3,0xb735E6416fA09354543E7121f2b32841E4921314 +uniswap_v3,0xE91C63278FBb3322A27888658591F1bF0A8b72D9 +uniswap_v3,0xf552841f59A37d691b69C8EF5B77BB77cD4E2dcC +uniswap_v3,0x35Ea4a7Dbc27fEf911A56a9265D433761b9e85A6 +uniswap_v3,0x74Aed2BBf12EaabD114228a3C7D1ff5fAf279D25 +uniswap_v3,0x43fae2884FCa681fE14AF8E350Fc6DE60730b1Bc +uniswap_v3,0x9120Da471155A93f9120547832E61aDfb13900e6 +uniswap_v3,0xC0114C7d7bB0CA7B1A8B031585F3c51df4fB53DD +uniswap_v3,0x296840cF4ECAA8beb1AddD3C7fc03b99D1952CCC +uniswap_v3,0xabed0D60Ba5f516d7B5e18935D83F3EE738719d3 +uniswap_v3,0x74A416f94Bfe8E4fAC006606a008a5450605790f +uniswap_v3,0x2dbe9d2D89188Ec871290927c6940769FD598425 +uniswap_v3,0xe7Ee403DBda5e626683Deca6B8F576c1Cfe75F11 +uniswap_v3,0x9d0B7Db1f54cD8A9B95CCcEAF8bdBf7f3c36c93A +uniswap_v3,0xa3A6125aa6469017352Fc504e9ae5B78A31579c4 +uniswap_v3,0x693f1E8048aEd2389fDc4CE6F2FE71eD65bf2095 +uniswap_v3,0xD107d4412172a9F0232Ce6C39281DCCc3F22E0CE +uniswap_v3,0x43375F7295E9e4B5051e52b96B8b6bFd53358E45 +uniswap_v3,0x0cF40Af54895b8C2C30b1bDBb7871757E0A39B93 +uniswap_v3,0x5f9f4a07E938AFbc9EBDD19BA4B7851446d6D53E +uniswap_v3,0xABBB876dD9B6C9A3587a9C452B5EF343d05c9c76 +uniswap_v3,0xc823EAfA867682667c8922A38693cda1f26aCA6F +uniswap_v3,0x7F38120B85223584b858A2Af65988347E6815646 +uniswap_v3,0xfBD99cb1155f644FfC9366e4446b6031AC24Bd23 +uniswap_v3,0x7CB22dE647fc9546eC6c2F238A10299Ab22Bfe59 +uniswap_v3,0x760F273108727c754Bf4a2f5A41C32878E1eE951 +uniswap_v3,0xE11956c2F0A6bCCca896a0710A978883B7170f62 +uniswap_v3,0x4847dA79CCC0Cc4Ac56D08CE1f34C749b03b47c9 +uniswap_v3,0x7Fc5D44A9aD029E0c78E96a36A89975688F29CA3 +uniswap_v3,0x1827D48591aa20934cE01e87E0a5335b55bB01B1 +uniswap_v3,0x7b3DF2a5D003A256b04e3cb11acF7132e6bB861B +uniswap_v3,0x161dbC1294fe9FeC931Ff34D2EC09b2409C8EE5D +uniswap_v3,0x6017933991a693D88754FE426b6A2ac77fbc35AF +uniswap_v3,0x06185F3B09a95a6EaC0d053E6c5ab122dCc4B260 +uniswap_v3,0x6B4264F2fd46f69e82a37A4e926715a7F24201C6 +uniswap_v3,0x32A8DA894947B67d4be554a5e91Fc92293Ab1e12 +uniswap_v3,0x34CE9B2c560C0e1b5Fa305699452d96CA238F65C +uniswap_v3,0xd7b7A5A3C21987Dc9170111D96575Cf5d97bDb55 +uniswap_v3,0x5aA583184fCBD355210F5579a205Af64d088Ab39 +uniswap_v3,0x06aB5216D969CEc5b5059376bb8C8999F7faAe39 +uniswap_v3,0x04570BDb5984b775Cc4a92B8cF052f7624fbf7c2 +uniswap_v3,0xcAC2987Bab0863aCc6E117f9f01854CC7290FF5D +uniswap_v3,0xBF89Ed1F68A73393d1F43CB739A6EE30BD93Cb30 +uniswap_v3,0xC77270aEAE2D2e986a5d7e5c5BD5e78bC0F43ACd +uniswap_v3,0x4Df59c6Abc9446Fd4DB592591F1205C36dC7d9E7 +uniswap_v3,0x73A71b0d202cA3c1ff2E4DE1539cA0923A2bBe79 +uniswap_v3,0xA8fE1c628C8B38D3fA90fD001E01C37b97ec333C +uniswap_v3,0xa9e6A14ed4891c478112CdeBc3e1C0A0029cF6DA +uniswap_v3,0x3Ec11ebF73DeEb69d4c09D18ea08B9bf6732C154 +uniswap_v3,0x9e92144aB2FEc4c9fe5A0a0C656Dac12555D2775 +uniswap_v3,0x1B883bad94a71855D353b61c5922Ce3AB4622c75 +uniswap_v3,0x77374d874e262657115462879DD8DD059abcF531 +uniswap_v3,0xC9604Bc06dE0BEC84BEab696C3eFe932504E4BA9 +uniswap_v3,0xCf622f09216Ef4834255F6CF02C087aef4323745 +uniswap_v3,0xF57326E3b9e86bFBC0dA65814DC4F8c0c9C473b2 +uniswap_v3,0xa9dFE04eAC59Da39B9fad30565Db6cD7dE864a79 +uniswap_v3,0x4cCD366293a6A948d9E230bC10f419d0835F19cF +uniswap_v3,0x75CBdcBb85F72543e41c7003d394D3ba657d4312 +uniswap_v3,0x66c7cF41bB27493Ed670917752990d9a45eD7612 +uniswap_v3,0x8AC5fF0CC45028ef36d637c475C0f261cCf2F4f0 +uniswap_v3,0xd7190Dc993b7e3984f1490b187586D6B51999063 +uniswap_v3,0xc4E681F7A1fCe04ddf7eDcD5E5964DAFA93A8A7B +uniswap_v3,0x3167Cc3f46bB81CACcD09e526037E2c3BbdD0294 +uniswap_v3,0x9e2c630a9F352EA0F152B2bf6A932A318c101b77 +uniswap_v3,0x0197c18A6041146678B68452611fE74B4a35d6F8 +uniswap_v3,0x26592bD76427641504593c7d97E505b80E1fDc68 +uniswap_v3,0x63Fd38BF3C264644B80aD3b9104CA22b93Ae636b +uniswap_v3,0xb6420bb8f4F0499b9e01658Bd5BA7fAC26cF0A57 +uniswap_v3,0x7d601c20fbAa0069c08B978a71B86C2f63e7C323 +uniswap_v3,0x3dceF3dacBA0Da074fF45694C5b58da665cE7129 +uniswap_v3,0x85ad29859fAf1E267259825eD2aa1c3522Aeb5Bb +uniswap_v3,0xB68707A16161511207aa7c19e6067501202163d4 +uniswap_v3,0x981f56B9A89cBFb72eFe8e609797CEbfc6703d82 +uniswap_v3,0x6655A4a0948D2d3c8DF0d7218045024E9b300f80 +uniswap_v3,0x4Fc75Ee535D3d3Ffe5bd5F8e8aAF2368d6931740 +uniswap_v3,0xF8887769F2C215858284759F99733ca7E998Ec63 +uniswap_v3,0xF98480B0A999432bcbF2f2041076b4A55ab5e315 +uniswap_v3,0x449bcFd119cC4769aEe0D202C9927c169644B715 +uniswap_v3,0x60789047A769B16BCdD3036eC0396d93909105b0 +uniswap_v3,0x87Ff708Ca97BA82Cd652620Fd0A9E2C29B5E5a22 +uniswap_v3,0xD8AaBC726613C08770A3f554E7d227C7422daFB0 +uniswap_v3,0x845482A18f86eF43EE51d8D1bd03de59f5E6262C +uniswap_v3,0xD7E39B23908F4658D791Af048C915A42d973eAa0 +uniswap_v3,0xd436C8804e2C3621e2B48d5E848393767F3cdE29 +uniswap_v3,0x4D5d67Ede3B3E82083211ebEf73c83516Cac33dc +uniswap_v3,0x028C8E58FEF26b92BfD5F7830BD626ec6eAD12Bb +uniswap_v3,0x6bcA101240AB2404fE25862488BBD547ff97F7DC +uniswap_v3,0x5e162C404c518010B420d325414A7715396DA075 +uniswap_v3,0x3212eEd120045cABED45b69Bc6f589399A53f9e8 +uniswap_v3,0x5D073b03A2B7262CA2ec868495769143Bd831830 +uniswap_v3,0xd24b0F1837A68495F6d6fb765b9F51cC11E314Df +uniswap_v3,0xe801B3282C218C320127c835480c1ECe285D1331 +uniswap_v3,0xB7E0977CEb6CBC6dEb41e45cb2594d29aAF138e1 +uniswap_v3,0x47baECce6D6b3c6d0FE58e45283374F90E4076B7 +uniswap_v3,0xe717780594614bB36F64B5c587576Eb80164DeC3 +uniswap_v3,0x65BA51C91a29678299B90b768737E277BEe219A7 +uniswap_v3,0x5aDdb0c9a709A375403538434d3a7643c759daEd +uniswap_v3,0xF1515b4D84dd4adF346382Bf090DB745f6AE45a7 +uniswap_v3,0xc2912E99645Ac9883FB7f9716e36B5C8D71240b1 +uniswap_v3,0x798F43c6c12163A8A475CeCE5F481D4c67dEDF19 +uniswap_v3,0x3f3E3354a1b54e4f47De2484f38a676ea19b2Bf3 +uniswap_v3,0x268E576999ef599202a4a4Cad9b915854151953E +uniswap_v3,0x44F9700d99bfF9785B5Ea29757a1F1Eb97FfB1DC +uniswap_v3,0x42e317B4fc52e90d99a7D9FF87e3B64EB0806132 +uniswap_v3,0x35FBC8E27261eCcBB4ed1b91021E0F317415fD10 +uniswap_v3,0x83cA2898a7A97cBAF4852aBF39857EAb43cC519B +uniswap_v3,0x8f5858B961D233175598B86DEeD57CBfc64A497c +uniswap_v3,0x81bdF969e3Ba2D49c400c8B1dfAa8b4309B246bf +uniswap_v3,0xF274CA6Bd898DAd4FF75eDfB16c51D76f9fF7Fe1 +uniswap_v3,0x3CA53Eba44fD5F10dc280dc0Ec97fCEe6ce850f0 +uniswap_v3,0x48837669E288366361ae9bBe63dB9004108648aA +uniswap_v3,0x2c193c0F7e78578d5CD8b488dB157C683FD6af18 +uniswap_v3,0x0B735B4DC52319aF3A4e14E357567D0F2153942E +uniswap_v3,0xeeeA3E464eEa483c0922C4E5377928Cb70b177a3 +uniswap_v3,0xFF81421e729B5Fe797885df1aB21A0693eD38bA0 +uniswap_v3,0x986627BD7d4690ae12910C40088Fe0Fe6db8A4de +uniswap_v3,0x537fe118aB1Cbf9378cf25ddd9CB4E2A52d14Cf8 +uniswap_v3,0xF9bEE7850ABb4045b20A89caf7233FbA67606b6e +uniswap_v3,0x054F4C73f2359D39f519CE846fec66ab84671F7e +uniswap_v3,0x888412eA5A6B7A9a417f2ba635e8adb4c370c145 +uniswap_v3,0x053879a49A8c3E758125FeF937B9Ea5e2F8D5751 +uniswap_v3,0x47FA443440fC5De1E4B60c7937AaD857a8b81E32 +uniswap_v3,0x3FF464afb3885C80A9577BdE11DdAC16f9918803 +uniswap_v3,0x490569Cc436b92055Dc6F87a3f5443eB2f1B900c +uniswap_v3,0x3D4A58e658C82f024dF6cA6290a9904Bb3BB4601 +uniswap_v3,0x1ee446EE412545CDF2CF1b532B84B6bAF5523185 +uniswap_v3,0xef93EBBB5EDcF0200C46200A79F55f20318CBd9C +uniswap_v3,0x285251EDf017860b3b2C50C714d9121E94aEA62C +uniswap_v3,0xAbf24505ee597cFD1361f97e0725147F829f28e6 +uniswap_v3,0x71FE8Fcd4dccdE5cECC6980E644B092c72780576 +uniswap_v3,0x1E99beD4F2BCD1842CC2eAF1Da449299b99Df638 +uniswap_v3,0x2d6143F451fd47fc3b97cd15c574168c3e989e55 +uniswap_v3,0x18A785Ca45C00af61afF483C711FC84E06390975 +uniswap_v3,0x5a03e9BB64FDDF08F487ED98C5fc276bd7c152bf +uniswap_v3,0x4B27C55DfA6237A5773Ae49ebB347A2f889bd6f6 +uniswap_v3,0xb48980875A709C26c3dD23067dE7852dDF2efE97 +uniswap_v3,0x1DfEeD65e092cD7B0Fc8FDF15B522ab3257D87b1 +uniswap_v3,0x31AAe92a1B668BBc190ac1e37772a7988a440f2E +uniswap_v3,0x27FbFa6F617B7F40F436C643AF153b527B0Af115 +uniswap_v3,0x57507312D07f3C1fAbF7952fd90e9d3FB1bd1374 +uniswap_v3,0xa4E5331d42319291202f3AE427EEAF7C025cAE91 +uniswap_v3,0x041bB62ce34F4f49e3298015BDD478E545a5C847 +uniswap_v3,0x4E4474ddf11854e8c8575cd2339b6394558D5484 +uniswap_v3,0x8CA8F81909DCB262EB53679319E3f0AE7D4A7b6f +uniswap_v3,0x6128d71bC6Fb40f397920e22d5BC204631BF0ed5 +uniswap_v3,0xADE24FC68F5aaA006b917173c8896e3A4F1e5DaD +uniswap_v3,0x1e9B08f69fa226485Df77fddEcA6995Cb3a4fb3D +uniswap_v3,0x2eEBe0422cc44811C2d27F9c43CFA35D5EEA785c +uniswap_v3,0xC70Ab94d861C4d803ab7a3af3dc1739b0602B01b +uniswap_v3,0x602e7A9AAb816F3e7102EfC4878FAA83A05086Fc +uniswap_v3,0xfbf033A57282bD923d2f1e13Bf04deb53871A56A +uniswap_v3,0x0659AB4aa456b61b534d270568306f985E8f106c +uniswap_v3,0x7bA497675d28B8dcF229140257C2a4c4579E7A42 +uniswap_v3,0x01046B39b600A9e4b1270933B6B59E1e456Da6E2 +uniswap_v3,0x7a048b5848c66cCaba3ACf50Eb38e360F0a63211 +uniswap_v3,0xC85AbA950E77F05943D6E47Ef2F24c1E247D2983 +uniswap_v3,0xc7062fcd3Cb6ce3D7dA5d1Ca713Ba9Ca9565E36d +uniswap_v3,0x8afA029cDb92569F19ee88042A909d79a7c75f88 +uniswap_v3,0x318eC2aEF8E8B5fCC7b98c3bB426A2a34c748EF1 +uniswap_v3,0x51fdb3C8415Fb87409Ff5D7C3f599d26a32CF740 +uniswap_v3,0xF62394Ae51f4dc773C3Fe208F5683BF0364a9fD1 +uniswap_v3,0x73811672aa57fbDA1E6BFF0B51c567B0aa22f34D +uniswap_v3,0x873C399f99Ed0cF19c8858DBC34B2f6A956dB755 +uniswap_v3,0x255fA7eC9264F83a76C833F1c9eCa4D493b146C4 +uniswap_v3,0x95574FAB05ABb685B8E885FA0642518F18abf09E +uniswap_v3,0xC886634AD71444fa89D9ff28A33707Bf4E569E95 +uniswap_v3,0x369A6EB55465d5474047b91449b47C6f1EC5CEbA +uniswap_v3,0x69C0674117a0f5a2D4F0db000b32B122C801618c +uniswap_v3,0xfB13E4a82A79CBB562d3F39B2568279Fa39a34dB +uniswap_v3,0x25eeF152BbFb1535EF88C8A39769F43d2b5Fa816 +uniswap_v3,0xf343b3d04828c232eEb93e83E78E3fA6fcF43e01 +uniswap_v3,0xCBE85d834FB2FcdD4453Db35c3fbd016EA50195E +uniswap_v3,0x606e5Da46617E6E7d61FCDb14F29477E9588a895 +uniswap_v3,0x175A4294f8D4992118D54F427DCCB68A40c53768 +uniswap_v3,0x155494e3250846aB4aD084B13B5020a17aC98aaC +uniswap_v3,0xac823A1779cF82b2E0A888879a29787a14E819d2 +uniswap_v3,0xFdCE167cd271801437f01F1FD796B0C6DdDe404d +uniswap_v3,0xDCe8d151E004b2c465A70c723CEFAdA6327c2d92 +uniswap_v3,0x794FeE340F57C0337575e01A8b6F2D6FaEa84DDC +uniswap_v3,0x80C3D9E2dd7497F32A8545Fe18458E1c05B622aC +uniswap_v3,0xDD69bbD7E5B3e12a52F47E63890686fD1489e616 +uniswap_v3,0xAF8B5cC6818DaCEC2E1c636F7C76Ee0a1A1E6057 +uniswap_v3,0xAca96D4Ad56dE5756FAF93046941E7eD66B1E80b +uniswap_v3,0xfea28169E91a9eb16DE11fA6F919f8317A59c010 +uniswap_v3,0x393C78a8Cf1F0740cdc3Def50F92201236DdCB62 +uniswap_v3,0x8C2b70ABc6E53F4D628f5594df5AaE1B2b84D7C7 +uniswap_v3,0x062618903596F6998B2f4fB311D4b56A5138194A +uniswap_v3,0x071A4FB6A15be9268E02B2374cD5B429dC7388D3 +uniswap_v3,0x85DBfe0050151Ea0f886201232D2aea249877Ad0 +uniswap_v3,0x3Da96163D4aa22300766e283346FEB41CA67d970 +uniswap_v3,0x1a2C7430C6658B9ce14aa4c3765aF8dabAa390c0 +uniswap_v3,0xb0c11511496441371154C3BF180a625f36fd4684 +uniswap_v3,0x7439a03B03909e5E167FA4cD4c1970c856e116A3 +uniswap_v3,0x488CD9047d6dcF3C1DfE2e580D4D2C199F434f2b +uniswap_v3,0x6793bdEBb8d556Dc91D137F99cCc8aF6b6628e5d +uniswap_v3,0x4122C18Ec60A4ea55A998F3E4B2Da8faa2AC7fe6 +uniswap_v3,0xF878c1be1e0D8D91DD957B0D0fE270f79439Dba7 +uniswap_v3,0x40431fd5B08f5b501dDcFE31c83D022F128e3FB7 +uniswap_v3,0x0258FdD7EDc69F8F79DD471ab8Ad6D0cF9E45A5b +uniswap_v3,0xCd5e833FCf58DD1eD2512315272471Af122B21EC +uniswap_v3,0xc8279B3a8aCbB83643a1E7aA4e55211Be90F0C3b +uniswap_v3,0xc98Ad03ea733A9082564A6bf0218fABe9bAD1560 +uniswap_v3,0xEFB35AC3965f46B5e6969E4bE10F2819b27103fF +uniswap_v3,0xA385737cf7C91df93b48B12Dea7f4B60c6a8F8CA +uniswap_v3,0x1108E8fD6d054a5AdC73387e035C2F5AacA9b799 +uniswap_v3,0x41B6846cA08Ef41A4d89E4fF82E362c0D73856Ba +uniswap_v3,0xD06e653085315C5d5A7A5Dcb5A8cF5c103174D9e +uniswap_v3,0x3FaE0C5eaad223484Cb417A03037b256c6D98A76 +uniswap_v3,0xc67f3397CEC4f145ca1aabD9bC42724B94931455 +uniswap_v3,0x3Af1de8989a16783034E0DC87d27AC028399A5E5 +uniswap_v3,0xb9a0D925E49CDCDA7b9D44c3b0F9898682cab71E +uniswap_v3,0x5b0655938f48DAD5f87Da245970031A57934eB62 +uniswap_v3,0xbFd07375340a17761a5e32919aE94701DB0d507e +uniswap_v3,0x4f758f3a3b419912fA977b5f9B023B138D579046 +uniswap_v3,0xD22eB692d8686e92EAAC145e91CfA7bb00F4f0d3 +uniswap_v3,0x1420F9E3c275822452aa5Ba63f224D5499f58001 +uniswap_v3,0xFD52E46EAA291bc226b7340293aa3E98D3a67840 +uniswap_v3,0x8e3FbA4f69D344A684f258fEc88bb84a2b48252a +uniswap_v3,0x2709e96186E88B0b3177e704Bf0319cBaD4e3592 +uniswap_v3,0xfD989E46a201c89DB9F96649572e8a1F100b1af3 +uniswap_v3,0xF390419Ab48c963fE310695fc2B2F51a234FeC61 +uniswap_v3,0xA246099686A6f433fC863009C763d6DB95602442 +uniswap_v3,0x27587eDB395Fe753fB55ACc0D3B99ea5cb653227 +uniswap_v3,0xE87CFcd89D0Df664Bfd0C04857d4e2C60020e6cD +uniswap_v3,0x3399e01383e6fAe9036fD363bbA64Bcf90e82b51 +uniswap_v3,0xF289fBEa43c809bAd27373dd6E1A1CA8a8148692 +uniswap_v3,0xc95976F5E9F45F3E25F85Bdcc0384Eaf2725DAD7 +uniswap_v3,0x2Ca096154e9A5F64EBd7DD95ee7266702822d27A +uniswap_v3,0xE5B445921A313330F4aCDe22cfdCC064b66F4066 +uniswap_v3,0x3b44F847D07fFa785CE3B785712942Cb70072e4c +uniswap_v3,0x21Ae3ADcb8D0778a4903e29248441BC30dCcc0AF +uniswap_v3,0x89b21E36A54A69bB68b77D9d8220636a55E6d745 +uniswap_v3,0x99a237c999d80100c416f595A5CDE2E77DBf56b1 +uniswap_v3,0x143d8Fc7AD7C1865f736788423323e672547e01b +uniswap_v3,0xb0594eA6D89dF4F5085aBF9F91dff7E23E70d88b +uniswap_v3,0x330bbF44E1DEf58CCd39bb257731fc32Dc9D2CdF +uniswap_v3,0xc75E7396a6B938E762640885fDE33f60fEB3E9BC +uniswap_v3,0xFfEC10fe1355c2d8df4F62AffCdEfFdB04f06569 +uniswap_v3,0x91e276996273F15BaF1a562a3B6477065c46a5D1 +uniswap_v3,0xC38236a403931A8b6a29Db6C4BdCf1559B756A91 +uniswap_v3,0x9EA84264B10Dcb032Ad0E62A09464973fd133afA +uniswap_v3,0x77ea3F0286BC6c4DC3803BbCA585FC1BBeDFbF38 +uniswap_v3,0xF7B5Be68caB9262D013d8A7C51E6A127fb06a8fA +uniswap_v3,0x8127BA07dB73de5c6F327F9E7d81c1AF11Df28c6 +uniswap_v3,0x0e6D06CF7174639BB133E8e9D1fa9189961c21af +uniswap_v3,0xE87ed1B461Fc539f97C9AC6a2953b4f0EA7f7c3d +uniswap_v3,0xaD5D637A010d2B8b37d8e8d825Ad1ee91cc6174A +uniswap_v3,0xD8D0fFF0599e9b4BaB9276E0CA964EB6a89c1E11 +uniswap_v3,0xdddefc3Eda6663Acd594D45231540176e675EA96 +uniswap_v3,0x36B3bCe466C1F8597f3BD7b376f091FFEd969647 +uniswap_v3,0xB64Fc50C4450eDbA5798614fe69f492F293988B1 +uniswap_v3,0x39106A3E5087EC6c30c1377233e02a44B96fF50F +uniswap_v3,0xd7e36ebEb6925157E68Ac0e96AD256Ae8D8d2Ff0 +uniswap_v3,0xc4b8F41039d322798d009Bd6AdCD4002A44bce57 +uniswap_v3,0xd9997C36E50fF1bDB09c1a63A00A7B0375b0e196 +uniswap_v3,0xe7c62b30624d4834CdC1f0cBc263f6049AB5b090 +uniswap_v3,0x39442607e10a7793c4da22Cf640B994dFE3001Db +uniswap_v3,0xF13220f14442A1b632A03A59C79b8D8A8b862c23 +uniswap_v3,0x8Dd59657c59CEDb06577F0fbCc4dbF725c0c0C24 +uniswap_v3,0xE2A5B5c900DAd9C2c57f8bdE56eb3626c2277Bc6 +uniswap_v3,0x6A045696cF8D1294F83ECE0D2fEc30FfBa2b5dbc +uniswap_v3,0x3883025F9b568D258B2d9dF5968f133152eD6115 +uniswap_v3,0x4979d6dbeBb215d7AAeBeb79353Cf113E954eF4C +uniswap_v3,0x2F4f7C17460C8941939f787dbd566919f41a623e +uniswap_v3,0x6b85399a9d4173D367211c8D199D6E7FDd68aC9f +uniswap_v3,0xE45a15D349d519F47AD43de73aEe0D61e4fA81b0 +uniswap_v3,0xECd617C4561cE69D76B1f05F4D6A7741d5369e32 +uniswap_v3,0x922f7b5499af470854D06Da4C144dB550B81Ac39 +uniswap_v3,0x73ed4f2f0158Ab815820d05C47a56eF76E5C3537 +uniswap_v3,0x0B57435E9Ef5F87F34f5931Ce4d7DD0A5D28c6d9 +uniswap_v3,0x3AD7BF9cd27d8e55bf7eF2527f1B00aa1d2A2b9b +uniswap_v3,0x667dD4a383707B9a3d79deA5A2794c8861D235D8 +uniswap_v3,0xe6db5d34Effcb6B53aA950b04f2b5fa0605FD300 +uniswap_v3,0x5eC562A1F4A1b0D5Fb7E7edC20E8A1f8CFa1dd95 +uniswap_v3,0xe067a9c17bc3cB4E8EC067E0D1cC5C83aAbde4A4 +uniswap_v3,0xD116e700bC2098DE60bfD9D15D9802FC5DEBF247 +uniswap_v3,0xF6DbbD87444174E25fFC9BA4f24d38eBf8ED4e41 +uniswap_v3,0x9Ef71A892574C26F69C66174dE4b412A52b74D14 +uniswap_v3,0xB4f23E3839b1315352f70155B1fBf1dFe89F802F +uniswap_v3,0x3928895b43A0A0EE5b5DE0a01b8b0478B4678ED4 +uniswap_v3,0x68192A9015869FE183FeA7FBAeb50b653e335872 +uniswap_v3,0x4ce7B7b4A3AdA3499392e82fD2bd8bf2259728F8 +uniswap_v3,0xC840A91eb7366C939674C60449a4CF7a28542Db9 +uniswap_v3,0xf51889092c21c169d9aCb40Eb8fC40Cf4EdE606F +uniswap_v3,0xf3c02A13C8415909FC3407Bb328F9939d2173549 +uniswap_v3,0xa2045949991D1808eCa6354e495E44B051D3f7fd +uniswap_v3,0x0AD8a455Bb1e27BBf3fE1bA1f4e14BCe40d5b3ad +uniswap_v3,0x2eDBB5F855740615e05EA4f70B24F5E535bca4b7 +uniswap_v3,0x68ae4e47eCD82298E28A4dfb105486ec944A64B4 +uniswap_v3,0xa1d8111fF253b2E690722a9B89c2Abc35e97Ded0 +uniswap_v3,0xacDA76aE653664bc386eCFE6C7218F0a4ebcd60B +uniswap_v3,0x927096707ffA01e78806d62688F55f38b9f4af26 +uniswap_v3,0xbccdCc8A0cd8ff44e745ad05A850586Fa5F7120D +uniswap_v3,0xEA8D1c922E30ba6D0409E3c927389b939207c942 +uniswap_v3,0x428d8942EB7709b869beFC7d44F42fCe43acd5Ce +uniswap_v3,0x1E232f31f62b515dE36C825eA055B68529a2890D +uniswap_v3,0x2565AdC1eE618DF14D92a999C7F155526d8eFc73 +uniswap_v3,0x180FB45AdBae01adBF3947b74b2D22d0daD3918a +uniswap_v3,0x116E7022871f9e225e622800fEF91b45e62f0685 +uniswap_v3,0x6473F2C341097693138a92FeC90f7117BB923367 +uniswap_v3,0xe9820bA963ec8BfD52Ec324BE7FF4BA32e4AF9ab +uniswap_v3,0x6e668dcafaaAB8e9dC9B8255FE125622230Fb9a6 +uniswap_v3,0xF718DaecB8EF3717F50388a71F44BD97a7Dd0462 +uniswap_v3,0x641401240B993F443EF22de1B0cC72F421439582 +uniswap_v3,0x6536c82C4350b1e23f013da42AD2cDD064071841 +uniswap_v3,0x99E9cBD77E43E865964284631b3ED9b535A7eCe1 +uniswap_v3,0xA6E057Fc14a44C3f427d11B2C0461cc090311679 +uniswap_v3,0x2aC27dc124f1599a241E16A7e7B1945f7E30572A +uniswap_v3,0xC81B79D82b7Fd37d5D187dd82Fe2dF8a854394bd +uniswap_v3,0x3978fD9D3b307e6F505194C0Ab28faA9857b183e +uniswap_v3,0xd48FbCc0492d95F1ffEB002489834610c253C069 +uniswap_v3,0x0af52953F8BDFbb9e56c1d144AA45915718b763a +uniswap_v3,0xEC9Feda966BbA819f6568675440824B47B234852 +uniswap_v3,0x0047416619a51afE9cd118D977A3649F492be923 +uniswap_v3,0x300d6362B86B58b8C0F34371089FD30f088E3a47 +uniswap_v3,0x90aF8A4Be28eFfcc27c1A69aF614186D5c8af16B +uniswap_v3,0x4C08D81cdadA3C7dB1147015F18e47EC439891C3 +uniswap_v3,0x4002cA421AA9001B43C3C5dde35cb9E5b476A14D +uniswap_v3,0xaAAdB7E7FB5985DCe4d42C4a2a50E6583cecCe87 +uniswap_v3,0x21f473c132fB5420EDfF6Ec71E4929C5dBd4231d +uniswap_v3,0x4b006174c70624b27d9879B5f3455611A36436dd +uniswap_v3,0xD5a649383dDA71282cdb7318a537B85f0994dCc6 +uniswap_v3,0xB0b5044287F9aaaF11d5363A15D43976A3E4e50C +uniswap_v3,0x1c2aA9c1E467517F95B51764c6e3Ef06C46fd8EB +uniswap_v3,0xb2D8aFD1c8d2D677095672B80104750c5a16074a +uniswap_v3,0x2eeE827E607ba2D2Fc649017E5b5Fd8a5d1F4945 +uniswap_v3,0x3b4EEdB7Dd66d63Ad320D4CA6055CD68B5268dEE +uniswap_v3,0x20dbCC4B8F30b023eabe2635B171c3dAE5Ef22e8 +uniswap_v3,0x8Ca9A6F457B69cBcEb346DB72B8d9722C118eCD3 +uniswap_v3,0xDCE84CBab8C8827408E92C6A79bC631F06f179fa +uniswap_v3,0x0D2837ccDfE86E78A938f78c20DD2754BB87faD1 +uniswap_v3,0x994B2D8e1a526892D3c84D799F040484092AddBC +uniswap_v3,0xf812B8b54Daeb45E1Fc896f9743d324D3dB30F5C +uniswap_v3,0x472d34F39E3448349F8CcF956D7c38d021f1b401 +uniswap_v3,0x72beEeBcD50Cc262ADF5E9a7ebfe6C51D662c02D +uniswap_v3,0x462c6DFe516914d8Cf26c5dCFcbA8372251810e5 +uniswap_v3,0x19786D706Aef023272d82AB2ec394019d100A145 +uniswap_v3,0x4E89281b68032b317C30cC84FD9fF08D733B8cd0 +uniswap_v3,0x96a11709eBae0Ea19494b6732b29BCab6738811F +uniswap_v3,0x3a88D78D5C775D6A972bdC111D15cfE83eDB3095 +uniswap_v3,0xb8c91CB8b1DFF426b6360527b6D684e7A38128ae +uniswap_v3,0x1C4d723F8aC449a9248E392dC7a1041F60a1c449 +uniswap_v3,0x5423CAC215898c005b2930e53881dD5E142a6be5 +uniswap_v3,0x20A925C67bCc4B08c8D283a27a2498bBF2BDf17E +uniswap_v3,0xE203906F83C8aDE3D53658e8b39694714c0802E2 +uniswap_v3,0x9AdC0B9dc0E2EfA811C8e85D6387b97E22fbe82e +uniswap_v3,0xd091dFc67d4b1D2a0f40823Fa3526824E9B8Dc5d +uniswap_v3,0xd75A39E19c3Af2b9eeA03c291A5c1f247403482C +uniswap_v3,0x99C954327a01455300d276567ae5B9C8DF966810 +uniswap_v3,0x1779A093fA10e569E64f4bA48A70397A5A50e589 +uniswap_v3,0x7a4cd01F03937A529199F5cA1DD7883b5dC68fB8 +uniswap_v3,0x6791CCAd57b0a31Cb071B078ba95c2eF5F701E04 +uniswap_v3,0x55c4D68922e341bBE40E3ab924Bee05C69fD68A8 +uniswap_v3,0xb25D805B3929fD6aEd9FF72780d985e20552c005 +uniswap_v3,0xbe098BfFa2E295D2Dc96896Db58662F7cb9747B2 +uniswap_v3,0xb902755a3a90Bf29Ea241f5F2FDB86DC1127c7bc +uniswap_v3,0xDf182D163cad217d78B05b19289b694c8E720e7C +uniswap_v3,0x81d9FbDbA53effDe62E981AE2304eB499364B59F +uniswap_v3,0xD4269a4dd6FA2285a2C448C4B6dB78275332c4B5 +uniswap_v3,0xfA2Bb0688aacd7865B6DBef2AED35D87800a1DDD +uniswap_v3,0xa82C8664b24FDFb74cA7E47E6A11d4640399414f +uniswap_v3,0xA9b8c620917178aeB85c912dEb7797590DEbA084 +uniswap_v3,0x81fbaBfF9FCD418E4D15B0b12f747Af8CB621bE9 +uniswap_v3,0xD62D6eF9bE2D1CeeaF7396B62fB2EC6fbF17440A +uniswap_v3,0xA954C6EE915941C7c7d773C0a1E20Bc584e31BE7 +uniswap_v3,0x709753C44eB210861f5dCC392715e60E26a2113e +uniswap_v3,0xCb0b332Ed71b269503199356b90525a5B1021434 +uniswap_v3,0x20513f6a316B4714Cf239acd820b88CdFc532c84 +uniswap_v3,0x49287eD1e5C456bC7C1FA742779E069e822495C6 +uniswap_v3,0x22861bA40bAb063fF24E796ccDE602944245f85c +uniswap_v3,0xE8D84a741D56d6ff45ab174D3CdA9af9F23aaaB3 +uniswap_v3,0xbD910F82A12ff1Dfa2565322CfFb4CCf896C51B7 +uniswap_v3,0x71896F870aebA742C778101b56b715Aba4E11Fe6 +uniswap_v3,0x93771cac40D3e0bbE18484550352667C7EE6732D +uniswap_v3,0x86fCA06B28396a10F75a446D72a254c273fD3f82 +uniswap_v3,0x18b668907172c773088a3881418Dc8c975557603 +uniswap_v3,0x94347f39D137Bb2CEF7a259f86c5828897835016 +uniswap_v3,0x9039549B07493581Deca4f8f4De12E89C39D56cD +uniswap_v3,0xf15eC1D8f13B208d420f257ebbd9D5e14c5a9433 +uniswap_v3,0x6bF2F3b3bbe496805c1a2236f5673Ba19Ddfd05E +uniswap_v3,0xD3a3288D61f8f1de036802cE7b17ca19d3cC66bb +uniswap_v3,0x2A3DA497Bc37CbEC585c36d6060f57aEBfB2Ec1d +uniswap_v3,0x26a1103623C2feF94358F9171d93645170C12f78 +uniswap_v3,0xB5c42F5659bf81CE0a7Ef955E268b3D7C7d285fF +uniswap_v3,0x4a39909c4dcB170F51313F5032BcAa417b7cCef8 +uniswap_v3,0x49109875eb77b4D847568651d476Be2D8aAAB359 +uniswap_v3,0x01fD7BcF6Ac63DE46Aa3f9dFcBd276a2183d4ADc +uniswap_v3,0x49c0Df3d99B6741f2154E769CcA1a1B86Db62489 +uniswap_v3,0x08D0f609fe8D05aafdb3e7CeEfdc6e3a2af792F5 +uniswap_v3,0xb2Fe6902899376A5639013c312c8Cb9272Deb31d +uniswap_v3,0x6470193120d6efEA17559a04e617cCc596793B46 +uniswap_v3,0xE18759f34fbA2A4547ce3947260642392c80F977 +uniswap_v3,0x15FA6098BD82E1985a15E5F95056920AcF1ef8b3 +uniswap_v3,0xb0f2F7E815f2a9c495FF27608df1677e1Fb2F582 +uniswap_v3,0xEB31A15e081ceAFe59Aa64999567BafBBA1e9b6a +uniswap_v3,0x92Cd4d5c4a6236758AA51aB642347cFC58FB393a +uniswap_v3,0x6Ee76C2f77195950ad214783cd105928f93156cb +uniswap_v3,0x1ecA1B81133D046d4a7DF6F45D76BbdE6bb0699C +uniswap_v3,0x26e3fec532c9b08D68D1C4DA9468bCF1ccA2D697 +uniswap_v3,0xc30716709f431bEfd2dd8f841afdFF1e4878edA5 +uniswap_v3,0x37E5119B9c4Bb50857981CdD8d3b87be935355A5 +uniswap_v3,0xa9334beF520779Ba6bEa987d9CA1e0140e82D25E +uniswap_v3,0x27C0021D7b867bFbC3ABfcF8b525458d8099fc35 +uniswap_v3,0x528FA6Ea67E7D1b4BA3000Eda840c90cb97A93Fd +uniswap_v3,0x9b8903B0B6882FE30DE2a30F6B73618D6eE960AD +uniswap_v3,0xD0D363064Df138F7714F135a815Bbf7577069953 +uniswap_v3,0x9Aa7CD82BF46d4790Fb18a1453956Cc10f06EFcd +uniswap_v3,0x3796e20B915A7663692B8A063Db86292b3e89767 +uniswap_v3,0x029a7d9072BCb7E5821167C373aa738B641b6638 +uniswap_v3,0x5AAcC13aBE5CA6f8D82EC5024e6fB6B6A77B9cC6 +uniswap_v3,0x9E3e307DE2445E459A450Eb219B9b1A9EFb6b2ec +uniswap_v3,0xF59e3d4405854EE54E62A576CFE71d93dc077549 +uniswap_v3,0x130940B41dEC48a1607FE5BF758990c1dD52EDEa +uniswap_v3,0x55EcD0D1fc82cC1F1688603F78aD6437E096101e +uniswap_v3,0x25a151dC4AF3b83f6D921758C87E253e164CC66c +uniswap_v3,0x006c0d9b9009a9Aa528C424Be15f106B29E95236 +uniswap_v3,0x9e695393216bEb8acA196fBCB51aD3b9d8217133 +uniswap_v3,0x4E71c3bC1E48CADe4F35f87eF223eE444a22e0B0 +uniswap_v3,0x2DC036BBfe9B7c314c5d20cBCb39a8287584574d +uniswap_v3,0x4bF5c396b826E75D9D286cc838374F56bE1E5f05 +uniswap_v3,0x552db460D58F4B031e9332aC350e0ff59A1D5687 +uniswap_v3,0xE0AC67ab5eafbaaE6544F0eC4f031d0b2299Ea92 +uniswap_v3,0x14a8B991F50eA5F165F1Ac4a7B726521d8167B87 +uniswap_v3,0x0936104E4575Db55C8A202b170cF5fe3558171cF +uniswap_v3,0x9ec6e275Bb64B4D89e9f2121b32b69De3a9435Fc +uniswap_v3,0xb268c5675EE74e9168F255Ec7f4ACA4BA02FDFAA +uniswap_v3,0xB74b58A74D964408eF45D19cb135773352615555 +uniswap_v3,0x062761C4Fe70c1f89ea0546fd299a133569A88e6 +uniswap_v3,0x7c244feAFffe00763152140aD0e3943FDfc6a088 +uniswap_v3,0xe76766d0e692AFeC6105733c4Ac552170F271785 +uniswap_v3,0xf07DdB59570f39eE6c77e82124e735363e6ADab8 +uniswap_v3,0xC84E17b0C029DEc1Cb4695956Eb61f0c46D1CEb2 +uniswap_v3,0x25F75ff0a5fC68115eeA2Ea9823B592c3828cF1f +uniswap_v3,0x86d4c639C369BDf2b56d3F5e15D4c6614c1C55Af +uniswap_v3,0x999dB70e82553A4602C929fa305B2A3952d4f046 +uniswap_v3,0x1988AF2ecE3E583af94fF70C159019DF7ba3b43d +uniswap_v3,0x80a363667bf53Ea96fB550691FDE390411f9B163 +uniswap_v3,0x1d4840E910Ff24fc4241c8b78867c9d9161Bc46C +uniswap_v3,0x57776b43B7f9106E053C23d3d89EFD57783a5DDc +uniswap_v3,0xef23E1eE9d945323701ea172DCB950010C7d394B +uniswap_v3,0xc09dde21d05c689Cd6fdD16ae206770e0993b7B9 +uniswap_v3,0x331bB064EF2Fa441ce546446d5e1249622ce11CA +uniswap_v3,0xeCB55B637e718F020dd80D6fe7839AE8E5e23711 +uniswap_v3,0xfeEd26eA7Cd94bAc96717067f61a4FfeBd127172 +uniswap_v3,0xc53165F07f65fEda7cA2b7D856A4CC95f0327d12 +uniswap_v3,0x24d194168FA8E62ae4e2641F26F6811FF6C4EfdA +uniswap_v3,0xc36B4E5ba909b4aFC5B71Cf88eaf4ED6a1bC9b4d +uniswap_v3,0xf1b7648F559355816E0320EEbD525F4f0C237D73 +uniswap_v3,0x2d7A876d5bb163183F0E3128B2f8b60d044CbfC9 +uniswap_v3,0x3793C099342f59e0566ab49830f7B52009c1873e +uniswap_v3,0xb7ce128e317E97f9d3AebE271b2DB2d7f46B70f1 +uniswap_v3,0xBaCBB26a11176498E0FE3230EA0C0A09Cc8C64f0 +uniswap_v3,0xe0A7b3b73F498e316Cd2007f84B17703CC20d0c3 +uniswap_v3,0xCCeDe5DF36277Bae218D295C6Cc063E637Ac1486 +uniswap_v3,0xb5b79d4607Fe1C39De8E9F4e725BCFbaC7CC5924 +uniswap_v3,0x23a4c43F7Ee6582e5BedbBea143494E72f144877 +uniswap_v3,0x4bAB0e1b701c3d447B571CE6C2E6537e3038E37E +uniswap_v3,0x18983a4208DB3e66FaEb74f84f2C7e95Bf66075e +uniswap_v3,0xeb5975BB17E76eAF99c6c824ff03144CEC817552 +uniswap_v3,0x8055e6de251e414e8393b20AdAb096AfB3cF8399 +uniswap_v3,0x339ba9D4753e31F55f52F67D3B051e8567270C44 +uniswap_v3,0x1dB430eEd29E5385Fc273D10E86b9BCBe52BDd4c +uniswap_v3,0xea8abCD7C22E0f31f29537eeAcf80BDEb6cBA384 +uniswap_v3,0xCe8897B4D2e7A6e9Cf0a7b015DA62B146d94bE72 +uniswap_v3,0x3043EEC0c8Aa33D6f5108Fc4672612a77470c20E +uniswap_v3,0xB28Ccff39B6cA4dd2c7c693DEF27B8153466db6e +uniswap_v3,0x33Ff43749c7f41C1252F3bb9b306DeC0C4701fc4 +uniswap_v3,0x32FD245795bb176659E0faEac09A65eF0F589f40 +uniswap_v3,0x9F058e360e6446500D690aF1FE75cD889c65cb02 +uniswap_v3,0x3d854EF84ecBd3D324D8D06830a8826a17838c56 +uniswap_v3,0x066f421c90a427f499E1069120C8fB2E8019d874 +uniswap_v3,0xa1CDACc16e62655EdcBea4EDD5682d68769D998b +uniswap_v3,0xdD35A4dAB2A0c411e5AB263B242B00bD4a135B23 +uniswap_v3,0x8eeB093b25226381E1c5A10e4A8bc9d239Dc49AF +uniswap_v3,0xB38f6f127EB86e5c14Ad506f465CBB35602D8859 +uniswap_v3,0x444836cD350F98477a885D81280559d97Ed9c6a5 +uniswap_v3,0xF236D9235D3A5376cd0310A17a7479e9812C9C5a +uniswap_v3,0x98BA928D946ee5Ae6323A33fD7D461fc0D6C19Cf +uniswap_v3,0x0eA41928A7c31396834f6e6Ba566715e6FC348e5 +uniswap_v3,0x78F4ef3DC93d6Df85daD99FC69FF514e5d5e9305 +uniswap_v3,0x8fc70B8302Ba18219235d299e32EDCD7A8B5aE70 +uniswap_v3,0xC70a931C5014a4B40B7F1A12ea20030BBDC176e5 +uniswap_v3,0x8876c96bb97a025110E08A79a684dFEAbb9F198b +uniswap_v3,0x2998d7394E3D63EaBd1F21F2476B260eaCFb439A +uniswap_v3,0xE5580fbeb25D945601190E41C99b1b027e40b241 +uniswap_v3,0x423DADF8D35BB805197aA70e1cDb82fb1aDC9AEA +uniswap_v3,0x16c6745b24F5c2080BbE6692eF8BaD90f53A1D75 +uniswap_v3,0xD013bC0064DF63988788C479c23899bc4B002D24 +uniswap_v3,0x461603EAF9E2F2150688ee66c67F2f719fBbAe91 +uniswap_v3,0xEC831fCC2Ba32b065d687ff144Ced0AA82Fae718 +uniswap_v3,0x5962e3A8DCB706e23398E790175c58E2964072DF +uniswap_v3,0xcc5669F7483B54c5b0dD6a97b4E5c867e998C664 +uniswap_v3,0x1B355d10C25A1Df3BFCCa9Af38b5C351bF677967 +uniswap_v3,0x495E84e34FC53922bA4dB00899a5A6939323B0b8 +uniswap_v3,0xCeDA0F9A38e9caB5ec15bb299a784eBFE58eE0E0 +uniswap_v3,0xC681d7394BbFc948b388B0601C924AA5557D2317 +uniswap_v3,0x302a4112d9c32D1282e6361e0b17CCBF66fE0dCD +uniswap_v3,0xFffBe4edD2c066D48140D35C3715307f7A1f55c2 +uniswap_v3,0x1eb3622a4dc578Ee3374d8F11F40fb6acecD96Dc +uniswap_v3,0xea0c164DC2ADb5e7DBA37E00FE80D16BEa4BA633 +uniswap_v3,0x3d3a2e615295d4838AbAF644B7DA85ef002A87E0 +uniswap_v3,0xB377364D2A8d330f5138E691E99258A01B53B71C +uniswap_v3,0x43CbE4247fF2Dc19B4c76649aCBade508f6Cc758 +uniswap_v3,0x192641E77A8c84623A73A03B5104bb5158E9518D +uniswap_v3,0x96B410bd280063D2b681cc4b363A2173CfbB452b +uniswap_v3,0x32BF775F157EB9Cf5E74F4a0B62aE4b2aE376a3A +uniswap_v3,0x8b2813fe7867eA52a93ADc6EA535662FF53257C1 +uniswap_v3,0x77a5dd003050bd9a5f786a6c2A1013Fe767B69B6 +uniswap_v3,0xB77968F7eF167E2741a048CC6D556A686f1d6DA6 +uniswap_v3,0x5aD48F58Fc36CaC4dad318eE72Ee0dc41C5Eb8Ad +uniswap_v3,0x174A678B04B7fE02Db66F7Bcff467a9f693CF266 +uniswap_v3,0x4Abc97949B13DA9fADa0273B4fC7F634aD0D2158 +uniswap_v3,0x35e36D4Fb9C65D220A7B563c6554D58e0151979E +uniswap_v3,0x429f93cD422117620CB7eDb99d6ed1eEfEc95877 +uniswap_v3,0x13B16817F115DEA194bCFF026d18503847c22032 +uniswap_v3,0x67E7CC5991453BAd2b7e02d16F24817947dEd0BF +uniswap_v3,0x4aE8d6FFC39C074e895a53723159C1f5Ef1b57Bf +uniswap_v3,0x45e86af08d0Dd5E04ef53E27432389c064852b51 +uniswap_v3,0x6ff5CfbBe53B68404A9B8d023B56C41cb7e7C78D +uniswap_v3,0xe18E640496800b49E92fD8cC6925650c5924A0d5 +uniswap_v3,0xC26F24Ba6c8132fEC335F92f6922581e2E8E1367 +uniswap_v3,0xD3F3A538CFcC42d0d042cC1c24EFE5dfB1B4cb29 +uniswap_v3,0x524B4b22d650053FC10c6F5d45C9BD4a30881F00 +uniswap_v3,0x2a990D0928e0016F83fD42f86732F8c9042a192f +uniswap_v3,0xe7c6A0CDfbf46CA1cd107A7c6c1f5D988FBa2996 +uniswap_v3,0x41CF577896646A623Af0eC4098c304fC184dB354 +uniswap_v3,0xC2D0Fb86DBb24658881f12E548bDF29BC5bA4Be2 +uniswap_v3,0x3848B674A732d53c24389A10ab7E087eF151F27A +uniswap_v3,0xa79E33b2F428f868d44aE26db99EC0154e68f5ae +uniswap_v3,0x748992cd77FF948439a5fE2c092f28cbCf625D11 +uniswap_v3,0x9c34a602e5E2876d4c1c87E92abe34a2Ec6cDd56 +uniswap_v3,0xB07E787A09855fc8350abfB04A3E218f6795c5cd +uniswap_v3,0x07b74776484743CF0C76618D37dFAfB7f7d4d7b2 +uniswap_v3,0xBBD1461423d3c78C72f8d28850993CE7047712eF +uniswap_v3,0xf8c1F3a53154f86C5b5c24c46548b4831981EB96 +uniswap_v3,0x1Db0f32f0C50343B58b3916E797dF612Db3df3BD +uniswap_v3,0x70bB61F15070409e3A5B3A258Fc49ed31FA03966 +uniswap_v3,0x9210a3cca359e0dF796678afF2238518cA88dd95 +uniswap_v3,0xFc19F7b0E322a997E2a9eC25CE36c75d7A6effc1 +uniswap_v3,0x00F822b2999c933d19A488317849705a12fE1B21 +uniswap_v3,0x123aAB2600483eD53bA42d708b9Ee0A6E4D05C21 +uniswap_v3,0xA83c4a992de829163cDd78dDFDd41e8184Fb3fb8 +uniswap_v3,0x32f431FE65b4cB7018F3c5Bc92D952B55c480604 +uniswap_v3,0x6dec47F7fA5F4B8D2AF3d46fda1df7F313903194 +uniswap_v3,0x413a4ee2E3a6b0B3DD40c12dDDF465F9cCB3271F +uniswap_v3,0xBAf1AD5f93EC077916683D5C26828D531528957a +uniswap_v3,0xEd800580ddC1817E12223D2Ac58dEcD257E5430c +uniswap_v3,0xd764fbdA43A0b4d1e23fda0Fd9A538Fb7e20582b +uniswap_v3,0x37f190ac2b6E709b3397Bd11A79ceE6A737c2a1E +uniswap_v3,0x0C4703e221166290F2FcD61e23694ab3892b0972 +uniswap_v3,0xdeC15dEE99B1a723AcC3fDd6Fa7b7f922D4c3D0f +uniswap_v3,0x16456E50ccefe406894DA030ef3A1e0b6dA7b3E6 +uniswap_v3,0x11a1b3f66380091e2268d114eE19da9323435E4A +uniswap_v3,0x38882c7D396d711bDdeB73dca1296332b1D90EDe +uniswap_v3,0x8F9D75A9bF27B32FE1A67949AeF13172D50a32a5 +uniswap_v3,0xd0a1d68b61D9c147f7438Df6AAaDCBA9199Aa51a +uniswap_v3,0x73036ff9215897E0C5E90a980F309A6FCb9f820C +uniswap_v3,0xBb0Eb8b3818df65799523256069fd0dbf5d36d68 +uniswap_v3,0x83fDE978990cd409085224c4a2f5E3540735bCb6 +uniswap_v3,0xD14AE3529C37A11DeD3B773E048Abd66D7fC4cAa +uniswap_v3,0xA28eCB862343cCbe85eC9d6C5A08dCFc0bF92B45 +uniswap_v3,0x1Ae8e97D5e5cDFB2a8cF43bf5c1dA473dd6BB75a +uniswap_v3,0xB12d16c8A623a741DBAC676407180d68CFAE0c20 +uniswap_v3,0xc9C50aB485eC3c4445D9119A226363bD5663742F +uniswap_v3,0x2D533b8920B5597A1b420C2095BEA02E223e6f3c +uniswap_v3,0x235a13E4F582832865b7525fADbe2993E62129A3 +uniswap_v3,0x678a9f28Fa506EfD220C182d0787185b578b752a +uniswap_v3,0x540282B014bDDC7c93f2Ed5aB0e58963875d63E0 +uniswap_v3,0x5C22c0Aeb18c0B3E86794DE8734BB3627521F303 +uniswap_v3,0xD991CC798c3e5684aC4Aa8Ec1Dbf43fa28290557 +uniswap_v3,0xa74F821f336eedCE2395913846e2E99C90819E32 +uniswap_v3,0x5977C38FD0990E62eDF91B40Fa9Ff3e65912d576 diff --git a/fastlane_bot/data/blockchain_data/linea/solidly_v2_event_mappings.csv b/fastlane_bot/data/blockchain_data/linea/solidly_v2_event_mappings.csv index be61911f5..5bd049f9a 100644 --- a/fastlane_bot/data/blockchain_data/linea/solidly_v2_event_mappings.csv +++ b/fastlane_bot/data/blockchain_data/linea/solidly_v2_event_mappings.csv @@ -163,3 +163,9 @@ xfai_v0,0x0Ab89ed59d510d64FD3f44e973e13A7909dA3BA7 xfai_v0,0x497d4cBeA7E45C5f2D4146D90e67eBAaee4f8084 xfai_v0,0xa076804861a21dD0ba2ea82C776F1AeFa9d12e57 xfai_v0,0x98E7cF03DeB846899B0Ac164CB77B05b940BF415 +lynex_v2,0x9e1881B7af88c468cf048E265e5AFCd92852767D +lynex_v2,0x9D2495eE468dd08E072514B6924a140632c281B1 +lynex_v2,0xbbD94Eef0109ec29433073E30c6ecE83Fd3C4C52 +lynex_v2,0x2bAbfb5f0f40e77be0a9011f83A6252ECc796D54 +lynex_v2,0xB302D7236E7B53bbB384A25608c4FB55152AC6cC +lynex_v2,0x7a21302BD6D314C1f46797115D704D664e0635D0 diff --git a/fastlane_bot/data/blockchain_data/linea/static_pool_data.csv b/fastlane_bot/data/blockchain_data/linea/static_pool_data.csv index 11ca9dcdd..95da59de1 100644 --- a/fastlane_bot/data/blockchain_data/linea/static_pool_data.csv +++ b/fastlane_bot/data/blockchain_data/linea/static_pool_data.csv @@ -411,3 +411,170 @@ cid,strategy_id,last_updated,last_updated_block,descr,pair_name,exchange_name,fe 0x497d4cBeA7E45C5f2D4146D90e67eBAaee4f8084,0,,1412243,xfai_v0 0x6EF95B6f3b0F39508e3E04054Be96D5eE39eDE0d/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0x6EF95B6f3b0F39508e3E04054Be96D5eE39eDE0d/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,xfai_v0,0.002,0.002,0x497d4cBeA7E45C5f2D4146D90e67eBAaee4f8084,,0x6EF95B6f3b0F39508e3E04054Be96D5eE39eDE0d,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,13,SIS,WETH,0,0,0,,,,,xfai_v0,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 0xa076804861a21dD0ba2ea82C776F1AeFa9d12e57,0,,1833872,xfai_v0 0xe7DC30E9Bc08A1Dd1a2909D0f0e1Af4539398F01/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0xe7DC30E9Bc08A1Dd1a2909D0f0e1Af4539398F01/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,xfai_v0,0.002,0.002,0xa076804861a21dD0ba2ea82C776F1AeFa9d12e57,,0xe7DC30E9Bc08A1Dd1a2909D0f0e1Af4539398F01,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,13,TFS,WETH,0,0,0,,,,,xfai_v0,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 0x98E7cF03DeB846899B0Ac164CB77B05b940BF415,0,,3673450,xfai_v0 0x43E8809ea748EFf3204ee01F08872F063e44065f/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0x43E8809ea748EFf3204ee01F08872F063e44065f/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,xfai_v0,0.002,0.002,0x98E7cF03DeB846899B0Ac164CB77B05b940BF415,,0x43E8809ea748EFf3204ee01F08872F063e44065f,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,13,MENDI,WETH,0,0,0,,,,,xfai_v0,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xEbc78d2b3C7982E9d4e4Bf6294E81B2cd9e0778b,0,,120914,echodex_v3 0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 2500,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,2500,0.0025,0xEbc78d2b3C7982E9d4e4Bf6294E81B2cd9e0778b,,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,ECP,WETH,0,0,0,0,0,0,50,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x433f9C64fafB532c3B71b32fFaF6A5796e58Db5D,0,,123594,echodex_v3 0x7d43AABC515C356145049227CeE54B608342c0ad/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 2500,0x7d43AABC515C356145049227CeE54B608342c0ad/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,2500,0.0025,0x433f9C64fafB532c3B71b32fFaF6A5796e58Db5D,,0x7d43AABC515C356145049227CeE54B608342c0ad,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,BUSD,WETH,0,0,0,0,0,0,50,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xEE5Af2e7a33bc7945A39f58f4aAbf67d525F902E,0,,123680,echodex_v3 0x9Dd6EA6f9D1fba5ed640651f06802e32FF455221/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 2500,0x9Dd6EA6f9D1fba5ed640651f06802e32FF455221/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,2500,0.0025,0xEE5Af2e7a33bc7945A39f58f4aAbf67d525F902E,,0x9Dd6EA6f9D1fba5ed640651f06802e32FF455221,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,LIN,WETH,0,0,0,0,0,0,50,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xa266E7f3B3236476bd587521156D520763B393b7,0,,124378,echodex_v3 0xAE7B4Ebf3c7FedA18D5A2a85dC37f40260B40Ac5/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0xAE7B4Ebf3c7FedA18D5A2a85dC37f40260B40Ac5/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,500,0.0005,0xa266E7f3B3236476bd587521156D520763B393b7,,0xAE7B4Ebf3c7FedA18D5A2a85dC37f40260B40Ac5,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,$Mask,WETH,0,0,0,0,0,0,10,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xfd91599a02A4d9DdaDE5419A2898AE4737514B08,0,,125281,echodex_v3 0x265B25e22bcd7f10a5bD6E6410F10537Cc7567e8/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 2500,0x265B25e22bcd7f10a5bD6E6410F10537Cc7567e8/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,2500,0.0025,0xfd91599a02A4d9DdaDE5419A2898AE4737514B08,,0x265B25e22bcd7f10a5bD6E6410F10537Cc7567e8,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,WMATIC,WETH,0,0,0,0,0,0,50,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x547926c48Fc0a95A700148643AEea065DEDc93c2,0,,127312,echodex_v3 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xEB466342C4d449BC9f53A865D5Cb90586f40521 2500,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xEB466342C4d449BC9f53A865D5Cb90586f40521,echodex_v3,2500,0.0025,0x547926c48Fc0a95A700148643AEea065DEDc93c2,,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0xEB466342C4d449BC9f53A865D5Cb90586f405215,18,6,4,WETH,AXLUSDC,0,0,0,0,0,0,50,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x7D85A28a9a98acA16Cbb02FCfdfa5E7c86e8e7B5,0,,133103,echodex_v3 0x7d43AABC515C356145049227CeE54B608342c0ad/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 100,0x7d43AABC515C356145049227CeE54B608342c0ad/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,100,0.0001,0x7D85A28a9a98acA16Cbb02FCfdfa5E7c86e8e7B5,,0x7d43AABC515C356145049227CeE54B608342c0ad,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,BUSD,WETH,0,0,0,0,0,0,1,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x555D681FA51953E4c0B076A197b25922A718f5FF,0,,142836,echodex_v3 0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,500,0.0005,0x555D681FA51953E4c0B076A197b25922A718f5FF,,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,ECP,WETH,0,0,0,0,0,0,10,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x8aA6046C0469bA7D7fabE0CFDd018d52d5f8FF09,0,,144350,echodex_v3 0x7d43AABC515C356145049227CeE54B608342c0ad/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x7d43AABC515C356145049227CeE54B608342c0ad/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,10000,0.01,0x8aA6046C0469bA7D7fabE0CFDd018d52d5f8FF09,,0x7d43AABC515C356145049227CeE54B608342c0ad,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,BUSD,WETH,0,0,0,0,0,0,200,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x3C76F7Db1322b397164aa40E34170170fF99f384,0,,145966,echodex_v3 0x7d43AABC515C356145049227CeE54B608342c0ad/0xEB466342C4d449BC9f53A865D5Cb90586f40521 2500,0x7d43AABC515C356145049227CeE54B608342c0ad/0xEB466342C4d449BC9f53A865D5Cb90586f40521,echodex_v3,2500,0.0025,0x3C76F7Db1322b397164aa40E34170170fF99f384,,0x7d43AABC515C356145049227CeE54B608342c0ad,0xEB466342C4d449BC9f53A865D5Cb90586f405215,18,6,4,BUSD,AXLUSDC,0,0,0,0,0,0,50,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x59CCA671497bcaB95bEd2d93D1Ff6902C5d0955d,0,,152784,echodex_v3 0x7f5373AE26c3E8FfC4c77b7255DF7eC1A9aF52a6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x7f5373AE26c3E8FfC4c77b7255DF7eC1A9aF52a6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,10000,0.01,0x59CCA671497bcaB95bEd2d93D1Ff6902C5d0955d,,0x7f5373AE26c3E8FfC4c77b7255DF7eC1A9aF52a6,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,axlUSDT,WETH,0,0,0,0,0,0,200,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x8276DAfA5008547FeF699640088d01160637F774,0,,155353,echodex_v3 0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,10000,0.01,0x8276DAfA5008547FeF699640088d01160637F774,,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,ECP,WETH,0,0,0,0,0,0,200,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xE4F5Dc6cAb4B23e124d3a73a2CfEE32DC070F72d,0,,156349,echodex_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 2500,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,2500,0.0025,0xE4F5Dc6cAb4B23e124d3a73a2CfEE32DC070F72d,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDC,WETH,0,0,0,0,0,0,50,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xf5dD371C44CAc4634aDc8B7CB82B0DEd873d0572,0,,159568,echodex_v3 0x1a35EE4640b0A3B87705B0A4B45D227Ba60Ca2ad/0xEB466342C4d449BC9f53A865D5Cb90586f40521 10000,0x1a35EE4640b0A3B87705B0A4B45D227Ba60Ca2ad/0xEB466342C4d449BC9f53A865D5Cb90586f40521,echodex_v3,10000,0.01,0xf5dD371C44CAc4634aDc8B7CB82B0DEd873d0572,,0x1a35EE4640b0A3B87705B0A4B45D227Ba60Ca2ad,0xEB466342C4d449BC9f53A865D5Cb90586f405215,8,6,4,axlWBTC,AXLUSDC,0,0,0,0,0,0,200,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xf26c909730c07EF0E6CD779D022F81C9c3B708ef,0,,159654,echodex_v3 0x5C7e299CF531eb66f2A1dF637d37AbB78e6200C7/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x5C7e299CF531eb66f2A1dF637d37AbB78e6200C7/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,10000,0.01,0xf26c909730c07EF0E6CD779D022F81C9c3B708ef,,0x5C7e299CF531eb66f2A1dF637d37AbB78e6200C7,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,axlDAI,WETH,0,0,0,0,0,0,200,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xC624a30F89f146529E0A9990e58aD6a84cDb762a,0,,161138,echodex_v3 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xf5C6825015280CdfD0b56903F9F8B5A2233476F 10000,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xf5C6825015280CdfD0b56903F9F8B5A2233476F,echodex_v3,10000,0.01,0xC624a30F89f146529E0A9990e58aD6a84cDb762a,,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0xf5C6825015280CdfD0b56903F9F8B5A2233476F5,18,18,4,WETH,WBNB,0,0,0,0,0,0,200,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xb34aFb0FeA2F9b41a154737a80aabB1F455C3DC0,0,,161524,echodex_v3 0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 100,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,100,0.0001,0xb34aFb0FeA2F9b41a154737a80aabB1F455C3DC0,,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,ECP,WETH,0,0,0,0,0,0,1,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xb1F8918eF32A9F9dB45f35bA640Ffb7beE05DfF3,0,,170787,echodex_v3 0x7d43AABC515C356145049227CeE54B608342c0ad/0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e 100,0x7d43AABC515C356145049227CeE54B608342c0ad/0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e,echodex_v3,100,0.0001,0xb1F8918eF32A9F9dB45f35bA640Ffb7beE05DfF3,,0x7d43AABC515C356145049227CeE54B608342c0ad,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6,18,18,4,BUSD,ECP,0,0,0,0,0,0,1,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xE737171aA0Fb4fDf7846C18B5e3e268425325752,0,,171071,echodex_v3 0x7d43AABC515C356145049227CeE54B608342c0ad/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x7d43AABC515C356145049227CeE54B608342c0ad/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,500,0.0005,0xE737171aA0Fb4fDf7846C18B5e3e268425325752,,0x7d43AABC515C356145049227CeE54B608342c0ad,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,BUSD,WETH,0,0,0,0,0,0,10,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xD5537E58f30b4AE4342Efb0f2c3B53EB491b1aDa,0,,174861,echodex_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e 100,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e,echodex_v3,100,0.0001,0xD5537E58f30b4AE4342Efb0f2c3B53EB491b1aDa,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6,6,18,4,USDC,ECP,0,0,0,0,0,0,1,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xAE261A26AaBF8222B4ee9b976d459008a3f3c3D7,0,,175005,echodex_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,10000,0.01,0xAE261A26AaBF8222B4ee9b976d459008a3f3c3D7,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDC,WETH,0,0,0,0,0,0,200,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x0cF6B45B9E5400E20782a0c6b7E217814207f109,0,,179750,echodex_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x7d43AABC515C356145049227CeE54B608342c0a 100,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x7d43AABC515C356145049227CeE54B608342c0a,echodex_v3,100,0.0001,0x0cF6B45B9E5400E20782a0c6b7E217814207f109,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0x7d43AABC515C356145049227CeE54B608342c0ad,6,18,4,USDC,BUSD,0,0,0,0,0,0,1,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xC218D620a54CA6bB6d77602f7E4BbecE2070D063,0,,180216,echodex_v3 0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,10000,0.01,0xC218D620a54CA6bB6d77602f7E4BbecE2070D063,,0xA219439258ca9da29E9Cc4cE5596924745e12B93,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDT,WETH,0,0,0,0,0,0,200,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xAC32D4B67f1E9ec51347828C8bB3dfD6Be94CBa2,0,,194566,echodex_v3 0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6/0x9Dd6EA6f9D1fba5ed640651f06802e32FF45522 2500,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6/0x9Dd6EA6f9D1fba5ed640651f06802e32FF45522,echodex_v3,2500,0.0025,0xAC32D4B67f1E9ec51347828C8bB3dfD6Be94CBa2,,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6,0x9Dd6EA6f9D1fba5ed640651f06802e32FF455221,18,18,4,ECP,LIN,0,0,0,0,0,0,50,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xb3791fA86a5482D8C0911B8A38597E7666F68587,0,,195208,echodex_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 100,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,100,0.0001,0xb3791fA86a5482D8C0911B8A38597E7666F68587,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDC,WETH,0,0,0,0,0,0,1,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x77A1542EEBd006a99E82068BF3E60741Be73CCad,0,,221946,echodex_v3 0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 2500,0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,2500,0.0025,0x77A1542EEBd006a99E82068BF3E60741Be73CCad,,0xA219439258ca9da29E9Cc4cE5596924745e12B93,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDT,WETH,0,0,0,0,0,0,50,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xC31aDd890922E08D94023d225F0f5C653ea1A5FA,0,,222947,echodex_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x5471ea8f739dd37E9B81Be9c5c77754D8AA953E 100,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x5471ea8f739dd37E9B81Be9c5c77754D8AA953E,echodex_v3,100,0.0001,0xC31aDd890922E08D94023d225F0f5C653ea1A5FA,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0x5471ea8f739dd37E9B81Be9c5c77754D8AA953E4,6,18,4,USDC,WAVAX,0,0,0,0,0,0,1,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xaEF8E32D6db8F1b8f6Ee56eF6933fFe807187FE6,0,,229730,echodex_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d 500,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d,echodex_v3,500,0.0005,0xaEF8E32D6db8F1b8f6Ee56eF6933fFe807187FE6,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5,6,18,4,USDC,DAI,0,0,0,0,0,0,10,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x92912a1DFBAbD89219F79b961B34053260Add7c2,0,,255177,echodex_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xA219439258ca9da29E9Cc4cE5596924745e12B9 100,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xA219439258ca9da29E9Cc4cE5596924745e12B9,echodex_v3,100,0.0001,0x92912a1DFBAbD89219F79b961B34053260Add7c2,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xA219439258ca9da29E9Cc4cE5596924745e12B93,6,6,4,USDC,USDT,0,0,0,0,0,0,1,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x7f489b2F23c093E42d4ff7a6217Aaa248513E192,0,,257350,echodex_v3 0x7d43AABC515C356145049227CeE54B608342c0ad/0xA219439258ca9da29E9Cc4cE5596924745e12B9 2500,0x7d43AABC515C356145049227CeE54B608342c0ad/0xA219439258ca9da29E9Cc4cE5596924745e12B9,echodex_v3,2500,0.0025,0x7f489b2F23c093E42d4ff7a6217Aaa248513E192,,0x7d43AABC515C356145049227CeE54B608342c0ad,0xA219439258ca9da29E9Cc4cE5596924745e12B93,18,6,4,BUSD,USDT,0,0,0,0,0,0,50,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xf533884F2ba3b89099c0d0cadBb314f9De693eB6,0,,270126,echodex_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xd2dDA4b56bEAe9f8E9C4C83D5159FB092F4b825 10000,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xd2dDA4b56bEAe9f8E9C4C83D5159FB092F4b825,echodex_v3,10000,0.01,0xf533884F2ba3b89099c0d0cadBb314f9De693eB6,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xd2dDA4b56bEAe9f8E9C4C83D5159FB092F4b825a,6,18,4,USDC,lin,0,0,0,0,0,0,200,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x6315BB896d8fC448F256E1FeB12FacaC593f3e78,0,,285702,echodex_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x9Dd6EA6f9D1fba5ed640651f06802e32FF45522 2500,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x9Dd6EA6f9D1fba5ed640651f06802e32FF45522,echodex_v3,2500,0.0025,0x6315BB896d8fC448F256E1FeB12FacaC593f3e78,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0x9Dd6EA6f9D1fba5ed640651f06802e32FF455221,6,18,4,USDC,LIN,0,0,0,0,0,0,50,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xA424eB7109D0BA38F60334DF76F695D93fC9aEdA,0,,434747,echodex_v3 0x53F7B069CAA7Fe942E2f304f3e2987C0B177b1B8/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 100,0x53F7B069CAA7Fe942E2f304f3e2987C0B177b1B8/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,100,0.0001,0xA424eB7109D0BA38F60334DF76F695D93fC9aEdA,,0x53F7B069CAA7Fe942E2f304f3e2987C0B177b1B8,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,PIR,WETH,0,0,0,0,0,0,1,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xA50d0663A417F03Ac4f7E51E0B2f93d44aD9B217,0,,434771,echodex_v3 0x53F7B069CAA7Fe942E2f304f3e2987C0B177b1B8/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x53F7B069CAA7Fe942E2f304f3e2987C0B177b1B8/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,500,0.0005,0xA50d0663A417F03Ac4f7E51E0B2f93d44aD9B217,,0x53F7B069CAA7Fe942E2f304f3e2987C0B177b1B8,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,PIR,WETH,0,0,0,0,0,0,10,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xF0aF8E4b3A282F52649263068f3a4Fc21f78D3Dc,0,,440197,echodex_v3 0x6Cd70ff7d7415B39485A1424E267eBA435876084/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 100,0x6Cd70ff7d7415B39485A1424E267eBA435876084/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,100,0.0001,0xF0aF8E4b3A282F52649263068f3a4Fc21f78D3Dc,,0x6Cd70ff7d7415B39485A1424E267eBA435876084,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,DICK,WETH,0,0,0,0,0,0,1,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x2b3a385533DE6DFa7f95d5e1721aac3B404E0177,0,,441933,echodex_v3 0x53F7B069CAA7Fe942E2f304f3e2987C0B177b1B8/0x6Cd70ff7d7415B39485A1424E267eBA43587608 10000,0x53F7B069CAA7Fe942E2f304f3e2987C0B177b1B8/0x6Cd70ff7d7415B39485A1424E267eBA43587608,echodex_v3,10000,0.01,0x2b3a385533DE6DFa7f95d5e1721aac3B404E0177,,0x53F7B069CAA7Fe942E2f304f3e2987C0B177b1B8,0x6Cd70ff7d7415B39485A1424E267eBA435876084,18,18,4,PIR,DICK,0,0,0,0,0,0,200,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x1033371e638Cb8E1A43F7555eF551AAa2355C332,0,,501186,echodex_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,500,0.0005,0x1033371e638Cb8E1A43F7555eF551AAa2355C332,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDC,WETH,0,0,0,0,0,0,10,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xAf0ce78D294776ec3412e591F1C960007052FCab,0,,515398,echodex_v3 0x9Dd6EA6f9D1fba5ed640651f06802e32FF455221/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x9Dd6EA6f9D1fba5ed640651f06802e32FF455221/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,500,0.0005,0xAf0ce78D294776ec3412e591F1C960007052FCab,,0x9Dd6EA6f9D1fba5ed640651f06802e32FF455221,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,LIN,WETH,0,0,0,0,0,0,10,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x4b906917ec5E77Af315c1A0BEf73901b585B1e49,0,,595121,echodex_v3 0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5/0xA219439258ca9da29E9Cc4cE5596924745e12B9 100,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5/0xA219439258ca9da29E9Cc4cE5596924745e12B9,echodex_v3,100,0.0001,0x4b906917ec5E77Af315c1A0BEf73901b585B1e49,,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5,0xA219439258ca9da29E9Cc4cE5596924745e12B93,18,6,4,DAI,USDT,0,0,0,0,0,0,1,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x54e50B6eA3bbaf9A1dB36C9bEBdc8D3d311eE2c6,0,,603218,echodex_v3 0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,500,0.0005,0x54e50B6eA3bbaf9A1dB36C9bEBdc8D3d311eE2c6,,0xA219439258ca9da29E9Cc4cE5596924745e12B93,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDT,WETH,0,0,0,0,0,0,10,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x3f4bFa5F3984dE0cB00c8462FB66a9e66310C669,0,,624085,echodex_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e 500,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e,echodex_v3,500,0.0005,0x3f4bFa5F3984dE0cB00c8462FB66a9e66310C669,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6,6,18,4,USDC,ECP,0,0,0,0,0,0,10,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xC1CDA0F812481b6f934ECDBE900eaf82b00ad3A9,0,,647721,echodex_v3 0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5/0x7d43AABC515C356145049227CeE54B608342c0a 100,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5/0x7d43AABC515C356145049227CeE54B608342c0a,echodex_v3,100,0.0001,0xC1CDA0F812481b6f934ECDBE900eaf82b00ad3A9,,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5,0x7d43AABC515C356145049227CeE54B608342c0ad,18,18,4,DAI,BUSD,0,0,0,0,0,0,1,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x0e37c152A9b6D79Fd8ff868437Ed5e18F8f6FCdb,0,,906833,echodex_v3 0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,500,0.0005,0x0e37c152A9b6D79Fd8ff868437Ed5e18F8f6FCdb,,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,DAI,WETH,0,0,0,0,0,0,10,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xF0D6ba1346A6D4d7dc5abE999a14E1006878560F,0,,1319082,echodex_v3 0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 100,0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,100,0.0001,0xF0D6ba1346A6D4d7dc5abE999a14E1006878560F,,0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,wstETH,WETH,0,0,0,0,0,0,1,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xc64F5A12806aE9C14F78a8632b9235929f9822Ab,0,,2001037,echodex_v3 0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6/0xA219439258ca9da29E9Cc4cE5596924745e12B9 500,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6/0xA219439258ca9da29E9Cc4cE5596924745e12B9,echodex_v3,500,0.0005,0xc64F5A12806aE9C14F78a8632b9235929f9822Ab,,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6,0xA219439258ca9da29E9Cc4cE5596924745e12B93,18,6,4,ECP,USDT,0,0,0,0,0,0,10,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xF5E38B7945dCc7EACBcd877eEc31A70B60C878FD,0,,2523959,echodex_v3 0x596B88eA5d6D75E2E2E3f03c5d2C797ECA82258f/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 100,0x596B88eA5d6D75E2E2E3f03c5d2C797ECA82258f/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,100,0.0001,0xF5E38B7945dCc7EACBcd877eEc31A70B60C878FD,,0x596B88eA5d6D75E2E2E3f03c5d2C797ECA82258f,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,ULT,WETH,0,0,0,0,0,0,1,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xC5D07562499A80a2D2d0118ea7006C054177220A,0,,2688359,echodex_v3 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xe9503fe0Fd65685CB7e5e7B0e4E1B95266DfA7D 100,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xe9503fe0Fd65685CB7e5e7B0e4E1B95266DfA7D,echodex_v3,100,0.0001,0xC5D07562499A80a2D2d0118ea7006C054177220A,,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0xe9503fe0Fd65685CB7e5e7B0e4E1B95266DfA7D7,18,18,4,WETH,BLOW,0,0,0,0,0,0,1,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x13Ff42D11cBABbf0508495988Ba8d43a33475E1C,0,,3454151,echodex_v3 0x5471ea8f739dd37E9B81Be9c5c77754D8AA953E4/0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e 10000,0x5471ea8f739dd37E9B81Be9c5c77754D8AA953E4/0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e,echodex_v3,10000,0.01,0x13Ff42D11cBABbf0508495988Ba8d43a33475E1C,,0x5471ea8f739dd37E9B81Be9c5c77754D8AA953E4,0x9201f3b9DfAB7C13Cd659ac5695D12D605B5F1e6,18,18,4,WAVAX,ECP,0,0,0,0,0,0,200,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x5C35f878b862D9a165c840b5074fd0CE320f209B,0,,3763536,echodex_v3 0x47ea9Ef2EE9C1048d405cDDE4d80245eb3FFFcBd/0xA219439258ca9da29E9Cc4cE5596924745e12B9 10000,0x47ea9Ef2EE9C1048d405cDDE4d80245eb3FFFcBd/0xA219439258ca9da29E9Cc4cE5596924745e12B9,echodex_v3,10000,0.01,0x5C35f878b862D9a165c840b5074fd0CE320f209B,,0x47ea9Ef2EE9C1048d405cDDE4d80245eb3FFFcBd,0xA219439258ca9da29E9Cc4cE5596924745e12B93,18,6,4,MGC,USDT,0,0,0,0,0,0,200,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x5b196dC0cE6E2ABDCaE1A66377c63dB6E5c2B6A9,0,,3835106,echodex_v3 0x5471ea8f739dd37E9B81Be9c5c77754D8AA953E4/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x5471ea8f739dd37E9B81Be9c5c77754D8AA953E4/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,10000,0.01,0x5b196dC0cE6E2ABDCaE1A66377c63dB6E5c2B6A9,,0x5471ea8f739dd37E9B81Be9c5c77754D8AA953E4,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,WAVAX,WETH,0,0,0,0,0,0,200,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xe6a0C7e4C5BE6a217177800825B02371Ef072ecd,0,,4189308,echodex_v3 0x5FBDF89403270a1846F5ae7D113A989F850d1566/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x5FBDF89403270a1846F5ae7D113A989F850d1566/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,echodex_v3,500,0.0005,0xe6a0C7e4C5BE6a217177800825B02371Ef072ecd,,0x5FBDF89403270a1846F5ae7D113A989F850d1566,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,FOXY,WETH,0,0,0,0,0,0,10,echodex_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x9e1881B7af88c468cf048E265e5AFCd92852767D,0,,4164070,lynex_v2 0x1Bf74C010E6320bab11e2e5A532b5AC15e0b8aA6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0x1Bf74C010E6320bab11e2e5A532b5AC15e0b8aA6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,lynex_v2,0.0001,0.0001,0x9e1881B7af88c468cf048E265e5AFCd92852767D,,0x1Bf74C010E6320bab11e2e5A532b5AC15e0b8aA6,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,3,weETH,WETH,0,0,0,,,,,lynex_v2,stable,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x9D2495eE468dd08E072514B6924a140632c281B1,0,,4164116,lynex_v2 0x1Bf74C010E6320bab11e2e5A532b5AC15e0b8aA6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0x1Bf74C010E6320bab11e2e5A532b5AC15e0b8aA6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,lynex_v2,0.0025,0.0025,0x9D2495eE468dd08E072514B6924a140632c281B1,,0x1Bf74C010E6320bab11e2e5A532b5AC15e0b8aA6,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,3,weETH,WETH,0,0,0,,,,,lynex_v2,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xbbD94Eef0109ec29433073E30c6ecE83Fd3C4C52,0,,4174815,lynex_v2 0x1a7e4e63778B4f12a199C062f3eFdD288afCBce8/0xA219439258ca9da29E9Cc4cE5596924745e12B93,0x1a7e4e63778B4f12a199C062f3eFdD288afCBce8/0xA219439258ca9da29E9Cc4cE5596924745e12B93,lynex_v2,0.0025,0.0025,0xbbD94Eef0109ec29433073E30c6ecE83Fd3C4C52,,0x1a7e4e63778B4f12a199C062f3eFdD288afCBce8,0xA219439258ca9da29E9Cc4cE5596924745e12B93,18,6,3,agEUR,USDT,0,0,0,,,,,lynex_v2,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x2bAbfb5f0f40e77be0a9011f83A6252ECc796D54,0,,4174935,lynex_v2 0x1a7e4e63778B4f12a199C062f3eFdD288afCBce8/0xA219439258ca9da29E9Cc4cE5596924745e12B93,0x1a7e4e63778B4f12a199C062f3eFdD288afCBce8/0xA219439258ca9da29E9Cc4cE5596924745e12B93,lynex_v2,0.0001,0.0001,0x2bAbfb5f0f40e77be0a9011f83A6252ECc796D54,,0x1a7e4e63778B4f12a199C062f3eFdD288afCBce8,0xA219439258ca9da29E9Cc4cE5596924745e12B93,18,6,3,agEUR,USDT,0,0,0,,,,,lynex_v2,stable,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xB302D7236E7B53bbB384A25608c4FB55152AC6cC,0,,4207625,lynex_v2 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xF3829aF0C018c8c1685B3d3d33B21cC98935fC87,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xF3829aF0C018c8c1685B3d3d33B21cC98935fC87,lynex_v2,0.0025,0.0025,0xB302D7236E7B53bbB384A25608c4FB55152AC6cC,,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0xF3829aF0C018c8c1685B3d3d33B21cC98935fC87,18,6,3,WETH,XHNY,0,0,0,,,,,lynex_v2,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x7a21302BD6D314C1f46797115D704D664e0635D0,0,,4216873,lynex_v2 0x8A16b95EA186FE2e0AD6eAb9efB764be7846c50f/0xA219439258ca9da29E9Cc4cE5596924745e12B93,0x8A16b95EA186FE2e0AD6eAb9efB764be7846c50f/0xA219439258ca9da29E9Cc4cE5596924745e12B93,lynex_v2,0.0025,0.0025,0x7a21302BD6D314C1f46797115D704D664e0635D0,,0x8A16b95EA186FE2e0AD6eAb9efB764be7846c50f,0xA219439258ca9da29E9Cc4cE5596924745e12B93,18,6,3,TEUR,USDT,0,0,0,,,,,lynex_v2,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xC9876e9c4f007024fb39D2990D3D6b2D22CE7b48,0,,782986,metavault_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xA219439258ca9da29E9Cc4cE5596924745e12B9 500,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xA219439258ca9da29E9Cc4cE5596924745e12B9,metavault_v3,500,0.0005,0xC9876e9c4f007024fb39D2990D3D6b2D22CE7b48,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xA219439258ca9da29E9Cc4cE5596924745e12B93,6,6,4,USDC,USDT,0,0,0,0,0,0,10,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x2270806159759Dd4bcA416aa4e8a1AaDeF48776A,0,,789714,metavault_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 3000,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,metavault_v3,3000,0.003,0x2270806159759Dd4bcA416aa4e8a1AaDeF48776A,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDC,WETH,0,0,0,0,0,0,60,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x9ca4eA6F392423b822898f3c1B129620161F5De7,0,,789720,metavault_v3 0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 3000,0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,metavault_v3,3000,0.003,0x9ca4eA6F392423b822898f3c1B129620161F5De7,,0xA219439258ca9da29E9Cc4cE5596924745e12B93,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDT,WETH,0,0,0,0,0,0,60,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x3724bE298654cc83b5273B89d33b3099baDb7b30,0,,789753,metavault_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b 3000,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b,metavault_v3,3000,0.003,0x3724bE298654cc83b5273B89d33b3099baDb7b30,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4,6,8,4,USDC,WBTC,0,0,0,0,0,0,60,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x1f9e7Ef95956D6100Edd22be633C819AEcb9b7BE,0,,789771,metavault_v3 0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xA219439258ca9da29E9Cc4cE5596924745e12B9 3000,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xA219439258ca9da29E9Cc4cE5596924745e12B9,metavault_v3,3000,0.003,0x1f9e7Ef95956D6100Edd22be633C819AEcb9b7BE,,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4,0xA219439258ca9da29E9Cc4cE5596924745e12B93,8,6,4,WBTC,USDT,0,0,0,0,0,0,60,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x2848973568Af7c89DaC4321Cb3c270A49ed242CC,0,,789954,metavault_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xA219439258ca9da29E9Cc4cE5596924745e12B9 100,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xA219439258ca9da29E9Cc4cE5596924745e12B9,metavault_v3,100,0.0001,0x2848973568Af7c89DaC4321Cb3c270A49ed242CC,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xA219439258ca9da29E9Cc4cE5596924745e12B93,6,6,4,USDC,USDT,0,0,0,0,0,0,1,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x3E37ED1945eEdB33558FD29C303b59B079d1a0dc,0,,790334,metavault_v3 0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 3000,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,metavault_v3,3000,0.003,0x3E37ED1945eEdB33558FD29C303b59B079d1a0dc,,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,8,18,4,WBTC,WETH,0,0,0,0,0,0,60,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xa99CD4E87b9acAc403540F90Db07c9507540f965,0,,838931,metavault_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,metavault_v3,500,0.0005,0xa99CD4E87b9acAc403540F90Db07c9507540f965,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDC,WETH,0,0,0,0,0,0,10,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x66b119Aa96A89B1389726CbED7D0AE651A6C82aF,0,,870522,metavault_v3 0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,metavault_v3,500,0.0005,0x66b119Aa96A89B1389726CbED7D0AE651A6C82aF,,0xA219439258ca9da29E9Cc4cE5596924745e12B93,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDT,WETH,0,0,0,0,0,0,10,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x7297DE153902De72b006B8925413619c895Fa01B,0,,906542,metavault_v3 0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5/0xA219439258ca9da29E9Cc4cE5596924745e12B9 500,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5/0xA219439258ca9da29E9Cc4cE5596924745e12B9,metavault_v3,500,0.0005,0x7297DE153902De72b006B8925413619c895Fa01B,,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5,0xA219439258ca9da29E9Cc4cE5596924745e12B93,18,6,4,DAI,USDT,0,0,0,0,0,0,10,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x45390981D05d762510ff360bb401154303B710a7,0,,1076966,metavault_v3 0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,metavault_v3,500,0.0005,0x45390981D05d762510ff360bb401154303B710a7,,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,8,18,4,WBTC,WETH,0,0,0,0,0,0,10,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xd177f0225Ff602B8D23B30eec8B641190E11B190,0,,1098490,metavault_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 100,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,metavault_v3,100,0.0001,0xd177f0225Ff602B8D23B30eec8B641190E11B190,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDC,WETH,0,0,0,0,0,0,1,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xF0a58649DB533Ac138E41Ae5A4869F10Af461DA8,0,,1157801,metavault_v3 0x5471ea8f739dd37E9B81Be9c5c77754D8AA953E4/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x5471ea8f739dd37E9B81Be9c5c77754D8AA953E4/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,metavault_v3,500,0.0005,0xF0a58649DB533Ac138E41Ae5A4869F10Af461DA8,,0x5471ea8f739dd37E9B81Be9c5c77754D8AA953E4,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,WAVAX,WETH,0,0,0,0,0,0,10,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x9b531d28289EA4a1ec37eD563ac43955CEF809a5,0,,1167586,metavault_v3 0x93F4d0ab6a8B4271f4a28Db399b5E30612D21116/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x93F4d0ab6a8B4271f4a28Db399b5E30612D21116/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,metavault_v3,500,0.0005,0x9b531d28289EA4a1ec37eD563ac43955CEF809a5,,0x93F4d0ab6a8B4271f4a28Db399b5E30612D21116,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,STONE,WETH,0,0,0,0,0,0,10,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x84e9251D4ca44304e4C5E98327D32777db8ea4B0,0,,1263816,metavault_v3 0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 100,0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,metavault_v3,100,0.0001,0x84e9251D4ca44304e4C5E98327D32777db8ea4B0,,0xA219439258ca9da29E9Cc4cE5596924745e12B93,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDT,WETH,0,0,0,0,0,0,1,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xD6F1e4d5Be885D43DC4177f3aB285A4d0D430017,0,,2098877,metavault_v3 0x0018D96C579121a94307249d47F053E2D687b5e7/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x0018D96C579121a94307249d47F053E2D687b5e7/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,metavault_v3,10000,0.01,0xD6F1e4d5Be885D43DC4177f3aB285A4d0D430017,,0x0018D96C579121a94307249d47F053E2D687b5e7,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,MVX,WETH,0,0,0,0,0,0,200,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x3b5A9fe99E401C2C9e2336E7524C3993366A8491,0,,2864077,metavault_v3 0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 3000,0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,metavault_v3,3000,0.003,0x3b5A9fe99E401C2C9e2336E7524C3993366A8491,,0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,wstETH,WETH,0,0,0,0,0,0,60,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x05C5F5bF992051D7Ec686726b8AD814f2D0ADd25,0,,2975630,metavault_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8 3000,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8,metavault_v3,3000,0.003,0x05C5F5bF992051D7Ec686726b8AD814f2D0ADd25,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F,6,18,4,USDC,wstETH,0,0,0,0,0,0,60,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xDdBE0e16536D3257E5609f30BF0880D5C13A6B9b,0,,3090237,metavault_v3 0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8 3000,0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8,metavault_v3,3000,0.003,0xDdBE0e16536D3257E5609f30BF0880D5C13A6B9b,,0xA219439258ca9da29E9Cc4cE5596924745e12B93,0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F,6,18,4,USDT,wstETH,0,0,0,0,0,0,60,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xE9c8ab71A62649A95F0B6793C0bb9bb6157079f4,0,,3194529,metavault_v3 0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8 3000,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8,metavault_v3,3000,0.003,0xE9c8ab71A62649A95F0B6793C0bb9bb6157079f4,,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4,0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F,8,18,4,WBTC,wstETH,0,0,0,0,0,0,60,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xeaF6fa74b16E229a20C239276B5199ba871aE3a3,0,,3699722,metavault_v3 0xB97F21D1f2508fF5c73E7B5AF02847640B1ff75d/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0xB97F21D1f2508fF5c73E7B5AF02847640B1ff75d/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,metavault_v3,500,0.0005,0xeaF6fa74b16E229a20C239276B5199ba871aE3a3,,0xB97F21D1f2508fF5c73E7B5AF02847640B1ff75d,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,LAB,WETH,0,0,0,0,0,0,10,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x0320520CaFcef95776912e9030170573fb47DC3B,0,,3706265,metavault_v3 0x60D01EC2D5E98Ac51C8B4cF84DfCCE98D527c747/0xA219439258ca9da29E9Cc4cE5596924745e12B9 500,0x60D01EC2D5E98Ac51C8B4cF84DfCCE98D527c747/0xA219439258ca9da29E9Cc4cE5596924745e12B9,metavault_v3,500,0.0005,0x0320520CaFcef95776912e9030170573fb47DC3B,,0x60D01EC2D5E98Ac51C8B4cF84DfCCE98D527c747,0xA219439258ca9da29E9Cc4cE5596924745e12B93,18,6,4,IZI,USDT,0,0,0,0,0,0,10,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xcC8eBB7BB51D78b03E15971f7c4BdD9a0fD9fA85,0,,3963300,metavault_v3 0x1a51b19CE03dbE0Cb44C1528E34a7EDD7771E9Af/0x63349BA5E1F71252eCD56E8F950D1A518B400b6 3000,0x1a51b19CE03dbE0Cb44C1528E34a7EDD7771E9Af/0x63349BA5E1F71252eCD56E8F950D1A518B400b6,metavault_v3,3000,0.003,0xcC8eBB7BB51D78b03E15971f7c4BdD9a0fD9fA85,,0x1a51b19CE03dbE0Cb44C1528E34a7EDD7771E9Af,0x63349BA5E1F71252eCD56E8F950D1A518B400b60,18,18,4,LYNX,oLYNX,0,0,0,0,0,0,60,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x2057f8B47C249b3a14D8F2E204Ca620a8bf0d470,0,,3971537,metavault_v3 0x1a51b19CE03dbE0Cb44C1528E34a7EDD7771E9Af/0x63349BA5E1F71252eCD56E8F950D1A518B400b6 10000,0x1a51b19CE03dbE0Cb44C1528E34a7EDD7771E9Af/0x63349BA5E1F71252eCD56E8F950D1A518B400b6,metavault_v3,10000,0.01,0x2057f8B47C249b3a14D8F2E204Ca620a8bf0d470,,0x1a51b19CE03dbE0Cb44C1528E34a7EDD7771E9Af,0x63349BA5E1F71252eCD56E8F950D1A518B400b60,18,18,4,LYNX,oLYNX,0,0,0,0,0,0,200,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x1A3a6427E6edC6f66473DA61c84a624587F27252,0,,4071214,metavault_v3 0xbAACD8E57387eB5db90229c312F0e867f66041D0/0xe9945Bab095157E632BCd0605c8ED8d9BAfd639 500,0xbAACD8E57387eB5db90229c312F0e867f66041D0/0xe9945Bab095157E632BCd0605c8ED8d9BAfd639,metavault_v3,500,0.0005,0x1A3a6427E6edC6f66473DA61c84a624587F27252,,0xbAACD8E57387eB5db90229c312F0e867f66041D0,0xe9945Bab095157E632BCd0605c8ED8d9BAfd639D,18,18,4,MANA,LINA,0,0,0,0,0,0,10,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x29Cc66f0c2dd8f368273098b5256dDD1E53e8880,0,,4071397,metavault_v3 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xe9945Bab095157E632BCd0605c8ED8d9BAfd639 500,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xe9945Bab095157E632BCd0605c8ED8d9BAfd639,metavault_v3,500,0.0005,0x29Cc66f0c2dd8f368273098b5256dDD1E53e8880,,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0xe9945Bab095157E632BCd0605c8ED8d9BAfd639D,18,18,4,WETH,LINA,0,0,0,0,0,0,10,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x41F8FC661862468D1eec22588DF4C5f24Ce194DC,0,,4071406,metavault_v3 0xbAACD8E57387eB5db90229c312F0e867f66041D0/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0xbAACD8E57387eB5db90229c312F0e867f66041D0/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,metavault_v3,500,0.0005,0x41F8FC661862468D1eec22588DF4C5f24Ce194DC,,0xbAACD8E57387eB5db90229c312F0e867f66041D0,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,MANA,WETH,0,0,0,0,0,0,10,metavault_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xA9A1Fb9F6664A0B6BFB1F52724fd7b23842248C5,0,,2967911,nile_v2 0x2416092f143378750bb29b79eD961ab195CcEea5/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0x2416092f143378750bb29b79eD961ab195CcEea5/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,nile_v2,0.0001,0.0001,0xA9A1Fb9F6664A0B6BFB1F52724fd7b23842248C5,,0x2416092f143378750bb29b79eD961ab195CcEea5,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,3,EZETH,WETH,0,0,0,,,,,nile_v2,stable,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xAb87191e323fa2F42a5Ace5735644bdF15b64658,0,,1468,pancakeswap_v3 0x32226588378236Fd0c7c4053999F88aC0e5cAc77/0x3652Fc6EDcbD76161b8554388867d3dAb65eCA9 100,0x32226588378236Fd0c7c4053999F88aC0e5cAc77/0x3652Fc6EDcbD76161b8554388867d3dAb65eCA9,pancakeswap_v3,100,0.0001,0xAb87191e323fa2F42a5Ace5735644bdF15b64658,,0x32226588378236Fd0c7c4053999F88aC0e5cAc77,0x3652Fc6EDcbD76161b8554388867d3dAb65eCA93,18,18,4,A,B,0,0,0,0,0,0,1,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xd5539D0360438a66661148c633A9F0965E482845,0,,260063,pancakeswap_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,500,0.0005,0xd5539D0360438a66661148c633A9F0965E482845,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDC,WETH,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x86f3336AD51501bd3187771E05B08Bd58c346644,0,,273597,pancakeswap_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 2500,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,2500,0.0025,0x86f3336AD51501bd3187771E05B08Bd58c346644,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDC,WETH,0,0,0,0,0,0,50,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x586733678b9aC9Da43dD7CB83bbB41d23677Dfc3,0,,273769,pancakeswap_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 100,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,100,0.0001,0x586733678b9aC9Da43dD7CB83bbB41d23677Dfc3,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDC,WETH,0,0,0,0,0,0,1,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x37613Ae9371C7ce78d544516DEA2379E2653BA2D,0,,274238,pancakeswap_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xA219439258ca9da29E9Cc4cE5596924745e12B9 500,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xA219439258ca9da29E9Cc4cE5596924745e12B9,pancakeswap_v3,500,0.0005,0x37613Ae9371C7ce78d544516DEA2379E2653BA2D,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xA219439258ca9da29E9Cc4cE5596924745e12B93,6,6,4,USDC,USDT,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x6a72F4F191720c411Cd1fF6A5EA8DeDEC3A64771,0,,287028,pancakeswap_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xA219439258ca9da29E9Cc4cE5596924745e12B9 100,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xA219439258ca9da29E9Cc4cE5596924745e12B9,pancakeswap_v3,100,0.0001,0x6a72F4F191720c411Cd1fF6A5EA8DeDEC3A64771,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xA219439258ca9da29E9Cc4cE5596924745e12B93,6,6,4,USDC,USDT,0,0,0,0,0,0,1,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x42c9e266b226bbF0B11c14416FaaBFce29C96B78,0,,287687,pancakeswap_v3 0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0x42c9e266b226bbF0B11c14416FaaBFce29C96B78,,0xA219439258ca9da29E9Cc4cE5596924745e12B93,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDT,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xA48E0630B7b9dCb250112143C9D0fe47d26CB1e4,0,,295206,pancakeswap_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d 100,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d,pancakeswap_v3,100,0.0001,0xA48E0630B7b9dCb250112143C9D0fe47d26CB1e4,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5,6,18,4,USDC,DAI,0,0,0,0,0,0,1,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xbD3bc396C9393e63bBc935786Dd120B17F58Df4c,0,,295208,pancakeswap_v3 0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,500,0.0005,0xbD3bc396C9393e63bBc935786Dd120B17F58Df4c,,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,8,18,4,WBTC,WETH,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x77eAeCAb5E71FA069a060637075063C521c44ecA,0,,312139,pancakeswap_v3 0x0D1E753a25eBda689453309112904807625bEFBe/0x176211869cA2b568f2A7D4EE941E073a821EE1f 10000,0x0D1E753a25eBda689453309112904807625bEFBe/0x176211869cA2b568f2A7D4EE941E073a821EE1f,pancakeswap_v3,10000,0.01,0x77eAeCAb5E71FA069a060637075063C521c44ecA,,0x0D1E753a25eBda689453309112904807625bEFBe,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,18,6,4,Cake,USDC,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x25F0A7aea13e75E8DC8F15481158FAE7d61a1560,0,,321614,pancakeswap_v3 0x0D1E753a25eBda689453309112904807625bEFBe/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 100,0x0D1E753a25eBda689453309112904807625bEFBe/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,100,0.0001,0x25F0A7aea13e75E8DC8F15481158FAE7d61a1560,,0x0D1E753a25eBda689453309112904807625bEFBe,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,Cake,WETH,0,0,0,0,0,0,1,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xE817A59F8A030544Ff65F47536abA272F6d63059,0,,328070,pancakeswap_v3 0x0D1E753a25eBda689453309112904807625bEFBe/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x0D1E753a25eBda689453309112904807625bEFBe/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0xE817A59F8A030544Ff65F47536abA272F6d63059,,0x0D1E753a25eBda689453309112904807625bEFBe,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,Cake,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x116a59c17b94eEd07b7BEC70A490c3DfFCCf98db,0,,340187,pancakeswap_v3 0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 2500,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,2500,0.0025,0x116a59c17b94eEd07b7BEC70A490c3DfFCCf98db,,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,DAI,WETH,0,0,0,0,0,0,50,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xF778209441dE096657A8f50f2253Af321Db3d0E8,0,,341268,pancakeswap_v3 0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xA219439258ca9da29E9Cc4cE5596924745e12B9 2500,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xA219439258ca9da29E9Cc4cE5596924745e12B9,pancakeswap_v3,2500,0.0025,0xF778209441dE096657A8f50f2253Af321Db3d0E8,,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4,0xA219439258ca9da29E9Cc4cE5596924745e12B93,8,6,4,WBTC,USDT,0,0,0,0,0,0,50,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xBB1261B00d8a082cf11405675E9eE772FA9b3621,0,,360820,pancakeswap_v3 0xC935B31C345D59A2396F7fEaC277FC1C981abC38/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0xC935B31C345D59A2396F7fEaC277FC1C981abC38/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0xBB1261B00d8a082cf11405675E9eE772FA9b3621,,0xC935B31C345D59A2396F7fEaC277FC1C981abC38,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,LNU,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xB59CB56330d1FC5c6240b8C7fc2DbEB09fD7a5dB,0,,374819,pancakeswap_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b 500,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b,pancakeswap_v3,500,0.0005,0xB59CB56330d1FC5c6240b8C7fc2DbEB09fD7a5dB,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4,6,8,4,USDC,WBTC,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xBA07B94b83774BE315f248dD6567F94B20405efE,0,,401768,pancakeswap_v3 0x0D1E753a25eBda689453309112904807625bEFBe/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x0D1E753a25eBda689453309112904807625bEFBe/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,500,0.0005,0xBA07B94b83774BE315f248dD6567F94B20405efE,,0x0D1E753a25eBda689453309112904807625bEFBe,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,Cake,WETH,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x12d4AA3e6c8E73574d03bC007a25721a1C7C6871,0,,401778,pancakeswap_v3 0x0D1E753a25eBda689453309112904807625bEFBe/0x176211869cA2b568f2A7D4EE941E073a821EE1f 100,0x0D1E753a25eBda689453309112904807625bEFBe/0x176211869cA2b568f2A7D4EE941E073a821EE1f,pancakeswap_v3,100,0.0001,0x12d4AA3e6c8E73574d03bC007a25721a1C7C6871,,0x0D1E753a25eBda689453309112904807625bEFBe,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,18,6,4,Cake,USDC,0,0,0,0,0,0,1,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xc72a9E1A8f751776d6579405791e84DFC2a76057,0,,402631,pancakeswap_v3 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xf1E11408b29611c03E242244A3f37ACF66C2e3f 2500,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xf1E11408b29611c03E242244A3f37ACF66C2e3f,pancakeswap_v3,2500,0.0025,0xc72a9E1A8f751776d6579405791e84DFC2a76057,,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0xf1E11408b29611c03E242244A3f37ACF66C2e3fe,18,18,4,WETH,LEDG,0,0,0,0,0,0,50,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xe555Cc5c593ee5ab0006d8D7d98E311f0c72197c,0,,464805,pancakeswap_v3 0x02e47D464c3bB564964fce162e6c8F38eA744f5a/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x02e47D464c3bB564964fce162e6c8F38eA744f5a/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0xe555Cc5c593ee5ab0006d8D7d98E311f0c72197c,,0x02e47D464c3bB564964fce162e6c8F38eA744f5a,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,TV,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x32Cb485D5840a7Ce79a33E307a6FFa3E3560e54F,0,,503996,pancakeswap_v3 0x02e47D464c3bB564964fce162e6c8F38eA744f5a/0xcc22F6AA610D1b2a0e89EF228079cB3e1831b1D 10000,0x02e47D464c3bB564964fce162e6c8F38eA744f5a/0xcc22F6AA610D1b2a0e89EF228079cB3e1831b1D,pancakeswap_v3,10000,0.01,0x32Cb485D5840a7Ce79a33E307a6FFa3E3560e54F,,0x02e47D464c3bB564964fce162e6c8F38eA744f5a,0xcc22F6AA610D1b2a0e89EF228079cB3e1831b1D1,18,18,4,TV,LVC,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x852dD3e3f40a5658ccB7a90C6798cF2a5DCB6F7f,0,,513776,pancakeswap_v3 0xcc22F6AA610D1b2a0e89EF228079cB3e1831b1D1/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0xcc22F6AA610D1b2a0e89EF228079cB3e1831b1D1/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0x852dD3e3f40a5658ccB7a90C6798cF2a5DCB6F7f,,0xcc22F6AA610D1b2a0e89EF228079cB3e1831b1D1,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,LVC,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xB90dFef14BA53666090fF1926c46Be00Cb40619F,0,,534869,pancakeswap_v3 0x0D1E753a25eBda689453309112904807625bEFBe/0xA219439258ca9da29E9Cc4cE5596924745e12B9 10000,0x0D1E753a25eBda689453309112904807625bEFBe/0xA219439258ca9da29E9Cc4cE5596924745e12B9,pancakeswap_v3,10000,0.01,0xB90dFef14BA53666090fF1926c46Be00Cb40619F,,0x0D1E753a25eBda689453309112904807625bEFBe,0xA219439258ca9da29E9Cc4cE5596924745e12B93,18,6,4,Cake,USDT,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xfA9833196a930729b82E124fdB5708F16c1b8B5d,0,,551050,pancakeswap_v3 0x246c82fD3798Af4cc38973c429C18e807016a4BD/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x246c82fD3798Af4cc38973c429C18e807016a4BD/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,500,0.0005,0xfA9833196a930729b82E124fdB5708F16c1b8B5d,,0x246c82fD3798Af4cc38973c429C18e807016a4BD,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,TM,WETH,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x4C39bc30daCD5339D916486E68EcB67B4341e569,0,,559101,pancakeswap_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x808d7c71ad2ba3FA531b068a2417C63106BC094 10000,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x808d7c71ad2ba3FA531b068a2417C63106BC094,pancakeswap_v3,10000,0.01,0x4C39bc30daCD5339D916486E68EcB67B4341e569,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0x808d7c71ad2ba3FA531b068a2417C63106BC0949,6,18,4,USDC,STG,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xE99d539b903E9bf24e01342034F4c1C3419018b0,0,,609481,pancakeswap_v3 0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 2500,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,2500,0.0025,0xE99d539b903E9bf24e01342034F4c1C3419018b0,,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,8,18,4,WBTC,WETH,0,0,0,0,0,0,50,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xBC0e1B76F21b04114de725583FF213b3134B2E6E,0,,612764,pancakeswap_v3 0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5/0xA219439258ca9da29E9Cc4cE5596924745e12B9 500,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5/0xA219439258ca9da29E9Cc4cE5596924745e12B9,pancakeswap_v3,500,0.0005,0xBC0e1B76F21b04114de725583FF213b3134B2E6E,,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5,0xA219439258ca9da29E9Cc4cE5596924745e12B93,18,6,4,DAI,USDT,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x5cC5495075931AEb1FC9A7F76B29C6317b6040c9,0,,612781,pancakeswap_v3 0x0D1E753a25eBda689453309112904807625bEFBe/0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d 2500,0x0D1E753a25eBda689453309112904807625bEFBe/0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d,pancakeswap_v3,2500,0.0025,0x5cC5495075931AEb1FC9A7F76B29C6317b6040c9,,0x0D1E753a25eBda689453309112904807625bEFBe,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5,18,18,4,Cake,DAI,0,0,0,0,0,0,50,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x74EC66075A71CFB1b223F10beFA99f7bEE6D3946,0,,639994,pancakeswap_v3 0x2314342912d9968fd3B40a542Bdb1fC6b918f35E/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x2314342912d9968fd3B40a542Bdb1fC6b918f35E/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,500,0.0005,0x74EC66075A71CFB1b223F10beFA99f7bEE6D3946,,0x2314342912d9968fd3B40a542Bdb1fC6b918f35E,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,$MENDI,WETH,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x85164B6d8a74bA481AB6D02D2C4e779ECCBAF982,0,,658564,pancakeswap_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xEB466342C4d449BC9f53A865D5Cb90586f40521 100,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xEB466342C4d449BC9f53A865D5Cb90586f40521,pancakeswap_v3,100,0.0001,0x85164B6d8a74bA481AB6D02D2C4e779ECCBAF982,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xEB466342C4d449BC9f53A865D5Cb90586f405215,6,6,4,USDC,AXLUSDC,0,0,0,0,0,0,1,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x5089E61e6c71D118790793ad78Fa98327e240359,0,,875694,pancakeswap_v3 0x8cE74e606481BBC7078aF4781f9eB67afC85a0Ce/0xA219439258ca9da29E9Cc4cE5596924745e12B9 100,0x8cE74e606481BBC7078aF4781f9eB67afC85a0Ce/0xA219439258ca9da29E9Cc4cE5596924745e12B9,pancakeswap_v3,100,0.0001,0x5089E61e6c71D118790793ad78Fa98327e240359,,0x8cE74e606481BBC7078aF4781f9eB67afC85a0Ce,0xA219439258ca9da29E9Cc4cE5596924745e12B93,18,6,4,stETH,USDT,0,0,0,0,0,0,1,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xD043EefA7554fe85f84521963331320EC6BdCd26,0,,933283,pancakeswap_v3 0x808d7c71ad2ba3FA531b068a2417C63106BC0949/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x808d7c71ad2ba3FA531b068a2417C63106BC0949/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0xD043EefA7554fe85f84521963331320EC6BdCd26,,0x808d7c71ad2ba3FA531b068a2417C63106BC0949,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,STG,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x811a565985669A1303b173C76CE3EFdf1Ec77aa3,0,,942810,pancakeswap_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x2F0b4300074aFC01726262d4cc9c1D2619d7297 500,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x2F0b4300074aFC01726262d4cc9c1D2619d7297,pancakeswap_v3,500,0.0005,0x811a565985669A1303b173C76CE3EFdf1Ec77aa3,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0x2F0b4300074aFC01726262d4cc9c1D2619d7297a,6,18,4,USDC,WUSK,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x33DB696Ef1f3080b846B28f1a890879cd6Df0a7D,0,,1043558,pancakeswap_v3 0x41b94c5867f7F6217C9a30520Cb3e793B1ee1b97/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x41b94c5867f7F6217C9a30520Cb3e793B1ee1b97/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0x33DB696Ef1f3080b846B28f1a890879cd6Df0a7D,,0x41b94c5867f7F6217C9a30520Cb3e793B1ee1b97,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,axlTIA,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x3f63a467C54c96538bD36A7DF1b9E7C4719DcaC9,0,,1067145,pancakeswap_v3 0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 100,0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,100,0.0001,0x3f63a467C54c96538bD36A7DF1b9E7C4719DcaC9,,0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,wstETH,WETH,0,0,0,0,0,0,1,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x479efE59d00d5064B4170f1705D444448623cEf4,0,,1241270,pancakeswap_v3 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xf5C6825015280CdfD0b56903F9F8B5A2233476F 10000,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xf5C6825015280CdfD0b56903F9F8B5A2233476F,pancakeswap_v3,10000,0.01,0x479efE59d00d5064B4170f1705D444448623cEf4,,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0xf5C6825015280CdfD0b56903F9F8B5A2233476F5,18,18,4,WETH,WBNB,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xf84d0dB5DFb6eAE50951607749d8b16B26F6F929,0,,1408235,pancakeswap_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8 10000,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8,pancakeswap_v3,10000,0.01,0xf84d0dB5DFb6eAE50951607749d8b16B26F6F929,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F,6,18,4,USDC,wstETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xbc2EE5e6535d25aEE9A90ef33E7E80A4145E064a,0,,2356666,pancakeswap_v3 0x1bE3735Dd0C0Eb229fB11094B6c277192349EBbf/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x1bE3735Dd0C0Eb229fB11094B6c277192349EBbf/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0xbc2EE5e6535d25aEE9A90ef33E7E80A4145E064a,,0x1bE3735Dd0C0Eb229fB11094B6c277192349EBbf,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,LUBE,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xAdc1D10eDA12F36792b5ea3902b6b6c0dDb58060,0,,2421084,pancakeswap_v3 0x21d624c846725ABe1e1e7d662E9fB274999009Aa/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x21d624c846725ABe1e1e7d662E9fB274999009Aa/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0xAdc1D10eDA12F36792b5ea3902b6b6c0dDb58060,,0x21d624c846725ABe1e1e7d662E9fB274999009Aa,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,CRYSTAL,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x90375306810C6E8B2efa8294835C78B499D7c691,0,,2525920,pancakeswap_v3 0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,500,0.0005,0x90375306810C6E8B2efa8294835C78B499D7c691,,0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,wstETH,WETH,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xc014414696F332C96C471634620344143325D2C0,0,,2542229,pancakeswap_v3 0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,500,0.0005,0xc014414696F332C96C471634620344143325D2C0,,0xA219439258ca9da29E9Cc4cE5596924745e12B93,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDT,WETH,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x5AFda31027C3E6A03c77a113FFC031B564AbbF05,0,,2561630,pancakeswap_v3 0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 100,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,100,0.0001,0x5AFda31027C3E6A03c77a113FFC031B564AbbF05,,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,8,18,4,WBTC,WETH,0,0,0,0,0,0,1,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xb62ca7B0FFD46584b72b697a96524EA5426ae8F0,0,,2674814,pancakeswap_v3 0x1C7F152e3dB82F92C0e4446A2922975E5d0eFCfE/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x1C7F152e3dB82F92C0e4446A2922975E5d0eFCfE/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,500,0.0005,0xb62ca7B0FFD46584b72b697a96524EA5426ae8F0,,0x1C7F152e3dB82F92C0e4446A2922975E5d0eFCfE,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,SCB,WETH,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x24A5f822C39bC28d7BAD70F78D267ac619C99A6c,0,,2733685,pancakeswap_v3 0x4Fa0dE5d9217722A37247808c08Cde1C976879b9/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x4Fa0dE5d9217722A37247808c08Cde1C976879b9/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0x24A5f822C39bC28d7BAD70F78D267ac619C99A6c,,0x4Fa0dE5d9217722A37247808c08Cde1C976879b9,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,LUCIA,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x21C7eB0B952809F8146D60d5D6b91E748bae74A6,0,,2772543,pancakeswap_v3 0x0A224Fa31903Bd0AF7b985DD7c07f6806C4b81a6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x0A224Fa31903Bd0AF7b985DD7c07f6806C4b81a6/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0x21C7eB0B952809F8146D60d5D6b91E748bae74A6,,0x0A224Fa31903Bd0AF7b985DD7c07f6806C4b81a6,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,ZOOMER,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xa93F1c84B74e0bB2345C92118eB2276f8F9f59d5,0,,2818098,pancakeswap_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x617FeED96d21F938Da4e725e8D460af6De2FaFe 500,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x617FeED96d21F938Da4e725e8D460af6De2FaFe,pancakeswap_v3,500,0.0005,0xa93F1c84B74e0bB2345C92118eB2276f8F9f59d5,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0x617FeED96d21F938Da4e725e8D460af6De2FaFe0,6,18,4,USDC,Wrapped BTC,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x1947B87d35E9f1cd53CEDe1aD6F7be44C12212B8,0,,2862693,pancakeswap_v3 0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 100,0xA219439258ca9da29E9Cc4cE5596924745e12B93/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,100,0.0001,0x1947B87d35E9f1cd53CEDe1aD6F7be44C12212B8,,0xA219439258ca9da29E9Cc4cE5596924745e12B93,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDT,WETH,0,0,0,0,0,0,1,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x20398c516B25A43cC9d8E2309Ca4ad35Ce2710F6,0,,2865294,pancakeswap_v3 0x98b6D1ebae3B228e5D947f14dA602Ac16f7ee60B/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x98b6D1ebae3B228e5D947f14dA602Ac16f7ee60B/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,500,0.0005,0x20398c516B25A43cC9d8E2309Ca4ad35Ce2710F6,,0x98b6D1ebae3B228e5D947f14dA602Ac16f7ee60B,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,Linea Network,WETH,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x08DCab368C76CD5cB8269c5382F695229fF1cBE4,0,,3123406,pancakeswap_v3 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xEB466342C4d449BC9f53A865D5Cb90586f40521 10000,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xEB466342C4d449BC9f53A865D5Cb90586f40521,pancakeswap_v3,10000,0.01,0x08DCab368C76CD5cB8269c5382F695229fF1cBE4,,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0xEB466342C4d449BC9f53A865D5Cb90586f405215,18,6,4,WETH,AXLUSDC,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xfDe733b5DE5B5a06C68353e01E4c1D3415C89560,0,,3144647,pancakeswap_v3 0x2416092f143378750bb29b79eD961ab195CcEea5/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x2416092f143378750bb29b79eD961ab195CcEea5/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,500,0.0005,0xfDe733b5DE5B5a06C68353e01E4c1D3415C89560,,0x2416092f143378750bb29b79eD961ab195CcEea5,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,EZETH,WETH,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x024c4c6fcE11C45C1D661033822EAe0D0Bc96615,0,,3233157,pancakeswap_v3 0x2598c30330D5771AE9F983979209486aE26dE875/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x2598c30330D5771AE9F983979209486aE26dE875/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0x024c4c6fcE11C45C1D661033822EAe0D0Bc96615,,0x2598c30330D5771AE9F983979209486aE26dE875,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,AI,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xF6a295bf3fD7E55A4A61724C7fd4f0A598fd3093,0,,3520453,pancakeswap_v3 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xEB466342C4d449BC9f53A865D5Cb90586f40521 100,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xEB466342C4d449BC9f53A865D5Cb90586f40521,pancakeswap_v3,100,0.0001,0xF6a295bf3fD7E55A4A61724C7fd4f0A598fd3093,,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0xEB466342C4d449BC9f53A865D5Cb90586f405215,18,6,4,WETH,AXLUSDC,0,0,0,0,0,0,1,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x3Ac591750A0D16A6dC03CeB8E0B0d135963F4b0b,0,,3575741,pancakeswap_v3 0xe026D1D034cCdDD1E7c2510e56B14fdcf3505c9e/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0xe026D1D034cCdDD1E7c2510e56B14fdcf3505c9e/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,500,0.0005,0x3Ac591750A0D16A6dC03CeB8E0B0d135963F4b0b,,0xe026D1D034cCdDD1E7c2510e56B14fdcf3505c9e,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,FOXY,WETH,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x158681DFDC01d29c2E9C35D45DCD6d5844bd2c81,0,,3603433,pancakeswap_v3 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xeaBd9aD114F9FdEFf34a588618441D2aDcE6027 500,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xeaBd9aD114F9FdEFf34a588618441D2aDcE6027,pancakeswap_v3,500,0.0005,0x158681DFDC01d29c2E9C35D45DCD6d5844bd2c81,,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0xeaBd9aD114F9FdEFf34a588618441D2aDcE60277,18,18,4,WETH,BLACKBONK,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x96F8d07B34e15c0f9338e79fD038F0f7A0C3a676,0,,3622291,pancakeswap_v3 0x5FBDF89403270a1846F5ae7D113A989F850d1566/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x5FBDF89403270a1846F5ae7D113A989F850d1566/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0x96F8d07B34e15c0f9338e79fD038F0f7A0C3a676,,0x5FBDF89403270a1846F5ae7D113A989F850d1566,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,FOXY,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xF36b19A9cA8D0302270531b950d5AAA3f3EFc34f,0,,3622617,pancakeswap_v3 0x5aEF68bB3DEB263F170219D0E53DFAae34776E65/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x5aEF68bB3DEB263F170219D0E53DFAae34776E65/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0xF36b19A9cA8D0302270531b950d5AAA3f3EFc34f,,0x5aEF68bB3DEB263F170219D0E53DFAae34776E65,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,FOXY,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x7fD09831872C4F927F6E10cE73F62Bf948413F70,0,,3623569,pancakeswap_v3 0x934ab820E87222F7BEddB3eb28bb2DEFcd5deFFf/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x934ab820E87222F7BEddB3eb28bb2DEFcd5deFFf/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,500,0.0005,0x7fD09831872C4F927F6E10cE73F62Bf948413F70,,0x934ab820E87222F7BEddB3eb28bb2DEFcd5deFFf,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,FOXY,WETH,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x373536b76872ef323fC0e3b33Ea5fF9E76231393,0,,3623878,pancakeswap_v3 0x5FBDF89403270a1846F5ae7D113A989F850d1566/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 2500,0x5FBDF89403270a1846F5ae7D113A989F850d1566/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,2500,0.0025,0x373536b76872ef323fC0e3b33Ea5fF9E76231393,,0x5FBDF89403270a1846F5ae7D113A989F850d1566,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,FOXY,WETH,0,0,0,0,0,0,50,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x0b3110493911E53df8cb4048DC27A8251B912Ee7,0,,3623998,pancakeswap_v3 0x5FBDF89403270a1846F5ae7D113A989F850d1566/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x5FBDF89403270a1846F5ae7D113A989F850d1566/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,500,0.0005,0x0b3110493911E53df8cb4048DC27A8251B912Ee7,,0x5FBDF89403270a1846F5ae7D113A989F850d1566,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,FOXY,WETH,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x1Df9587F03786Aa099Cf36ba64c9B1dCc5702b03,0,,3737793,pancakeswap_v3 0x5FBDF89403270a1846F5ae7D113A989F850d1566/0xA219439258ca9da29E9Cc4cE5596924745e12B9 10000,0x5FBDF89403270a1846F5ae7D113A989F850d1566/0xA219439258ca9da29E9Cc4cE5596924745e12B9,pancakeswap_v3,10000,0.01,0x1Df9587F03786Aa099Cf36ba64c9B1dCc5702b03,,0x5FBDF89403270a1846F5ae7D113A989F850d1566,0xA219439258ca9da29E9Cc4cE5596924745e12B93,18,6,4,FOXY,USDT,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x4cCb40a93d1529FAA48e8dB2cE3634D73D9feeB5,0,,3855031,pancakeswap_v3 0x2416092f143378750bb29b79eD961ab195CcEea5/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 100,0x2416092f143378750bb29b79eD961ab195CcEea5/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,100,0.0001,0x4cCb40a93d1529FAA48e8dB2cE3634D73D9feeB5,,0x2416092f143378750bb29b79eD961ab195CcEea5,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,EZETH,WETH,0,0,0,0,0,0,1,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xC9747FB2E06Da2085B7885e850f0cB5d0527F13A,0,,3885856,pancakeswap_v3 0x1a51b19CE03dbE0Cb44C1528E34a7EDD7771E9Af/0x63349BA5E1F71252eCD56E8F950D1A518B400b6 10000,0x1a51b19CE03dbE0Cb44C1528E34a7EDD7771E9Af/0x63349BA5E1F71252eCD56E8F950D1A518B400b6,pancakeswap_v3,10000,0.01,0xC9747FB2E06Da2085B7885e850f0cB5d0527F13A,,0x1a51b19CE03dbE0Cb44C1528E34a7EDD7771E9Af,0x63349BA5E1F71252eCD56E8F950D1A518B400b60,18,18,4,LYNX,oLYNX,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x1d3a3b759a55a49b0184F203695Cb5693A5b1aAe,0,,4070819,pancakeswap_v3 0xbAACD8E57387eB5db90229c312F0e867f66041D0/0xe9945Bab095157E632BCd0605c8ED8d9BAfd639 500,0xbAACD8E57387eB5db90229c312F0e867f66041D0/0xe9945Bab095157E632BCd0605c8ED8d9BAfd639,pancakeswap_v3,500,0.0005,0x1d3a3b759a55a49b0184F203695Cb5693A5b1aAe,,0xbAACD8E57387eB5db90229c312F0e867f66041D0,0xe9945Bab095157E632BCd0605c8ED8d9BAfd639D,18,18,4,MANA,LINA,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xCd1208e15D5b7f6106aEdbf8f9FC3b710843d208,0,,4070852,pancakeswap_v3 0x0D1E753a25eBda689453309112904807625bEFBe/0xbAACD8E57387eB5db90229c312F0e867f66041D 500,0x0D1E753a25eBda689453309112904807625bEFBe/0xbAACD8E57387eB5db90229c312F0e867f66041D,pancakeswap_v3,500,0.0005,0xCd1208e15D5b7f6106aEdbf8f9FC3b710843d208,,0x0D1E753a25eBda689453309112904807625bEFBe,0xbAACD8E57387eB5db90229c312F0e867f66041D0,18,18,4,Cake,MANA,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xaD98fffA1BA1BAA1BF87E190AA9B474fE75C4b07,0,,4070893,pancakeswap_v3 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xe9945Bab095157E632BCd0605c8ED8d9BAfd639 500,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xe9945Bab095157E632BCd0605c8ED8d9BAfd639,pancakeswap_v3,500,0.0005,0xaD98fffA1BA1BAA1BF87E190AA9B474fE75C4b07,,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0xe9945Bab095157E632BCd0605c8ED8d9BAfd639D,18,18,4,WETH,LINA,0,0,0,0,0,0,10,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xbc57ec102E3C87b19399e82e9287a61fa1135e16,0,,4233547,pancakeswap_v3 0x311eC870e3d7172896CA9f18145bAfc8902c9F3B/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x311eC870e3d7172896CA9f18145bAfc8902c9F3B/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0xbc57ec102E3C87b19399e82e9287a61fa1135e16,,0x311eC870e3d7172896CA9f18145bAfc8902c9F3B,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,BTBS,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xB6989edA09D1fD8D6C192Fd391e9964B918009f7,0,,4275652,pancakeswap_v3 0x636B22bC471c955A8DB60f28D4795066a8201fa3/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x636B22bC471c955A8DB60f28D4795066a8201fa3/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,pancakeswap_v3,10000,0.01,0xB6989edA09D1fD8D6C192Fd391e9964B918009f7,,0x636B22bC471c955A8DB60f28D4795066a8201fa3,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,UNI,WETH,0,0,0,0,0,0,200,pancakeswap_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x142eC7A60d2b339287c79969B1F3bfB1d81aF27f,0,,2390622,secta_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xA219439258ca9da29E9Cc4cE5596924745e12B9 100,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xA219439258ca9da29E9Cc4cE5596924745e12B9,secta_v3,100,0.0001,0x142eC7A60d2b339287c79969B1F3bfB1d81aF27f,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xA219439258ca9da29E9Cc4cE5596924745e12B93,6,6,4,USDC,USDT,0,0,0,0,0,0,1,secta_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xe331A3A42Fd83A7f44dAeDC7bA212bDeB90Ecf7B,0,,2390738,secta_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 500,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,secta_v3,500,0.0005,0xe331A3A42Fd83A7f44dAeDC7bA212bDeB90Ecf7B,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDC,WETH,0,0,0,0,0,0,10,secta_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xE380ad455BF4def3faA94ce0Ff9a0184D8AE1105,0,,2410447,secta_v3 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xfa1E8B0E8ef1C5F978C2885053D706cFB5e3582 2500,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xfa1E8B0E8ef1C5F978C2885053D706cFB5e3582,secta_v3,2500,0.0025,0xE380ad455BF4def3faA94ce0Ff9a0184D8AE1105,,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0xfa1E8B0E8ef1C5F978C2885053D706cFB5e35822,18,18,4,WETH,NOW,0,0,0,0,0,0,50,secta_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xB3a65a05eC9dc3A0bb3b18E2F0cf6bb86CD6fdaC,0,,2411126,secta_v3 0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xA219439258ca9da29E9Cc4cE5596924745e12B9 2500,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0xA219439258ca9da29E9Cc4cE5596924745e12B9,secta_v3,2500,0.0025,0xB3a65a05eC9dc3A0bb3b18E2F0cf6bb86CD6fdaC,,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4,0xA219439258ca9da29E9Cc4cE5596924745e12B93,8,6,4,WBTC,USDT,0,0,0,0,0,0,50,secta_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x3BBaebde931b7F0c9F431246Ea218D6d5404B1Cd,0,,2411647,secta_v3 0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0x7d43AABC515C356145049227CeE54B608342c0a 2500,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4/0x7d43AABC515C356145049227CeE54B608342c0a,secta_v3,2500,0.0025,0x3BBaebde931b7F0c9F431246Ea218D6d5404B1Cd,,0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4,0x7d43AABC515C356145049227CeE54B608342c0ad,8,18,4,WBTC,BUSD,0,0,0,0,0,0,50,secta_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x9569da3d960905D3b81999005bcc4Fdfd397B3B3,0,,2412773,secta_v3 0x7d43AABC515C356145049227CeE54B608342c0ad/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 2500,0x7d43AABC515C356145049227CeE54B608342c0ad/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,secta_v3,2500,0.0025,0x9569da3d960905D3b81999005bcc4Fdfd397B3B3,,0x7d43AABC515C356145049227CeE54B608342c0ad,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,BUSD,WETH,0,0,0,0,0,0,50,secta_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xe7710034C34E5Cd72C90d1c93Ff2f9Bc6A409B95,0,,2557416,secta_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d 100,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d,secta_v3,100,0.0001,0xe7710034C34E5Cd72C90d1c93Ff2f9Bc6A409B95,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5,6,18,4,USDC,DAI,0,0,0,0,0,0,1,secta_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x2A7F1baEEf187494759770228A3Ac0ff0d5A5f32,0,,2566426,secta_v3 0x1bE3735Dd0C0Eb229fB11094B6c277192349EBbf/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x1bE3735Dd0C0Eb229fB11094B6c277192349EBbf/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,secta_v3,10000,0.01,0x2A7F1baEEf187494759770228A3Ac0ff0d5A5f32,,0x1bE3735Dd0C0Eb229fB11094B6c277192349EBbf,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,LUBE,WETH,0,0,0,0,0,0,200,secta_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xC34FA78eabFD8E0a788087C1a73276dF4284ffEd,0,,3221927,secta_v3 0x2Fab0952449378DfdF4625fE37F9603011F189ab/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x2Fab0952449378DfdF4625fE37F9603011F189ab/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,secta_v3,10000,0.01,0xC34FA78eabFD8E0a788087C1a73276dF4284ffEd,,0x2Fab0952449378DfdF4625fE37F9603011F189ab,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,LINE,WETH,0,0,0,0,0,0,200,secta_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xe358f3B4D360E21AE9E84E3d54535F89580eA2E4,0,,3222889,secta_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x2Fab0952449378DfdF4625fE37F9603011F189a 10000,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0x2Fab0952449378DfdF4625fE37F9603011F189a,secta_v3,10000,0.01,0xe358f3B4D360E21AE9E84E3d54535F89580eA2E4,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0x2Fab0952449378DfdF4625fE37F9603011F189ab,6,18,4,USDC,LINE,0,0,0,0,0,0,200,secta_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x907045EEcE2891AC0e9189191abb270d6c121855,0,,3326022,secta_v3 0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,secta_v3,10000,0.01,0x907045EEcE2891AC0e9189191abb270d6c121855,,0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,DAI,WETH,0,0,0,0,0,0,200,secta_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xa3C180264De6B0fD8650DDF214Ff56e42689Cf01,0,,3420074,secta_v3 0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x176211869cA2b568f2A7D4EE941E073a821EE1ff/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,secta_v3,10000,0.01,0xa3C180264De6B0fD8650DDF214Ff56e42689Cf01,,0x176211869cA2b568f2A7D4EE941E073a821EE1ff,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,6,18,4,USDC,WETH,0,0,0,0,0,0,200,secta_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x9cF211b421Af0953353Aef93544FC7224A05609C,0,,3511776,secta_v3 0x48119884e0cfCf90E4035CDCd98fDa4d21966465/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 10000,0x48119884e0cfCf90E4035CDCd98fDa4d21966465/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,secta_v3,10000,0.01,0x9cF211b421Af0953353Aef93544FC7224A05609C,,0x48119884e0cfCf90E4035CDCd98fDa4d21966465,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,AENIL,WETH,0,0,0,0,0,0,200,secta_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xAd6eF2B9aBcDA704Df43E5Bb79f87B6B6a8224d8,0,,3904581,secta_v3 0x43E8809ea748EFf3204ee01F08872F063e44065f/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34 2500,0x43E8809ea748EFf3204ee01F08872F063e44065f/0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34,secta_v3,2500,0.0025,0xAd6eF2B9aBcDA704Df43E5Bb79f87B6B6a8224d8,,0x43E8809ea748EFf3204ee01F08872F063e44065f,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,18,18,4,MENDI,WETH,0,0,0,0,0,0,50,secta_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x6619e72964Ff7F7a2CdE8D5e9232C8a75f258be1,0,,4190473,secta_v3 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xEb477F63D11f51a46Bfa4e24106a435864b3247 10000,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f/0xEb477F63D11f51a46Bfa4e24106a435864b3247,secta_v3,10000,0.01,0x6619e72964Ff7F7a2CdE8D5e9232C8a75f258be1,,0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f,0xEb477F63D11f51a46Bfa4e24106a435864b32473,18,18,4,WETH,bETH,0,0,0,0,0,0,200,secta_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/fastlane_bot/data/blockchain_data/linea/tokens.csv b/fastlane_bot/data/blockchain_data/linea/tokens.csv index e6c2a4c29..d70fad27d 100644 --- a/fastlane_bot/data/blockchain_data/linea/tokens.csv +++ b/fastlane_bot/data/blockchain_data/linea/tokens.csv @@ -185,3 +185,10 @@ address,decimals,symbol 0x8C56017B172226fE024dEa197748FC1eaccC82B1,18,XFIT 0x1578f35532FA091EcED8638730F9dB829930ce16,18,agEUR 0xe7DC30E9Bc08A1Dd1a2909D0f0e1Af4539398F01,18,TFS +0x1Bf74C010E6320bab11e2e5A532b5AC15e0b8aA6,18,weETH +0x1a7e4e63778B4f12a199C062f3eFdD288afCBce8,18,agEUR +0xF3829aF0C018c8c1685B3d3d33B21cC98935fC87,6,XHNY +0x8A16b95EA186FE2e0AD6eAb9efB764be7846c50f,18,TEUR +0x311eC870e3d7172896CA9f18145bAfc8902c9F3B,18,BTBS +0x636B22bC471c955A8DB60f28D4795066a8201fa3,18,UNI +0xEb477F63D11f51a46Bfa4e24106a435864b32473,18,bETH diff --git a/fastlane_bot/data/blockchain_data/linea/uniswap_v3_event_mappings.csv b/fastlane_bot/data/blockchain_data/linea/uniswap_v3_event_mappings.csv index f2ba9e27e..73f885762 100644 --- a/fastlane_bot/data/blockchain_data/linea/uniswap_v3_event_mappings.csv +++ b/fastlane_bot/data/blockchain_data/linea/uniswap_v3_event_mappings.csv @@ -155,3 +155,7 @@ secta_v3,0x907045EEcE2891AC0e9189191abb270d6c121855 secta_v3,0xa3C180264De6B0fD8650DDF214Ff56e42689Cf01 secta_v3,0x9cF211b421Af0953353Aef93544FC7224A05609C secta_v3,0xAd6eF2B9aBcDA704Df43E5Bb79f87B6B6a8224d8 +echodex_v3,0xe6a0C7e4C5BE6a217177800825B02371Ef072ecd +pancakeswap_v3,0xbc57ec102E3C87b19399e82e9287a61fa1135e16 +pancakeswap_v3,0xB6989edA09D1fD8D6C192Fd391e9964B918009f7 +secta_v3,0x6619e72964Ff7F7a2CdE8D5e9232C8a75f258be1 diff --git a/fastlane_bot/data/blockchain_data/mantle/solidly_v2_event_mappings.csv b/fastlane_bot/data/blockchain_data/mantle/solidly_v2_event_mappings.csv index 763fc2560..c57848fad 100644 --- a/fastlane_bot/data/blockchain_data/mantle/solidly_v2_event_mappings.csv +++ b/fastlane_bot/data/blockchain_data/mantle/solidly_v2_event_mappings.csv @@ -74,3 +74,4 @@ velocimeter_v2,0x3B752bE1bC07bc5A5FF2f3129203f6dC567088bc velocimeter_v2,0xFB5DBe1fc5c115492Bd486796A860d73c3C948B7 velocimeter_v2,0xB45377d54656ac36018dF454950Ebb68B75A08c6 velocimeter_v2,0x06D082d70716A9D4cf83882e7ae3c1ec07A1f3c8 +velocimeter_v2,0xb81c581C1E6084dF0C2a0830A639a69cD3501117 diff --git a/fastlane_bot/data/blockchain_data/mantle/static_pool_data.csv b/fastlane_bot/data/blockchain_data/mantle/static_pool_data.csv index 274a30bff..f6c0851e0 100644 --- a/fastlane_bot/data/blockchain_data/mantle/static_pool_data.csv +++ b/fastlane_bot/data/blockchain_data/mantle/static_pool_data.csv @@ -1214,3 +1214,13 @@ cid,strategy_id,last_updated,last_updated_block,descr,pair_name,exchange_name,fe 0xFB5DBe1fc5c115492Bd486796A860d73c3C948B7,0,,48364886,velocimeter_v2 0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8/0x7e51aD847CDf8729Efc97CFa6E8aFA4D658Cb85b,0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8/0x7e51aD847CDf8729Efc97CFa6E8aFA4D658Cb85b,velocimeter_v2,0.02,0.02,0xFB5DBe1fc5c115492Bd486796A860d73c3C948B7,,0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8,0x7e51aD847CDf8729Efc97CFa6E8aFA4D658Cb85b,18,18,11,WMNT,lz-fMULTI,0,0,0,,,,,velocimeter_v2,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 0xB45377d54656ac36018dF454950Ebb68B75A08c6,0,,49450176,velocimeter_v2 0x7e51aD847CDf8729Efc97CFa6E8aFA4D658Cb85b/0xdEAddEaDdeadDEadDEADDEAddEADDEAddead1111,0x7e51aD847CDf8729Efc97CFa6E8aFA4D658Cb85b/0xdEAddEaDdeadDEadDEADDEAddEADDEAddead1111,velocimeter_v2,0.02,0.02,0xB45377d54656ac36018dF454950Ebb68B75A08c6,,0x7e51aD847CDf8729Efc97CFa6E8aFA4D658Cb85b,0xdEAddEaDdeadDEadDEADDEAddEADDEAddead1111,18,18,11,lz-fMULTI,WETH,0,0,0,,,,,velocimeter_v2,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 0x06D082d70716A9D4cf83882e7ae3c1ec07A1f3c8,0,,61896904,velocimeter_v2 0x7e51aD847CDf8729Efc97CFa6E8aFA4D658Cb85b/0x861A6Fc736Cbb12ad57477B535B829239c8347d7,0x7e51aD847CDf8729Efc97CFa6E8aFA4D658Cb85b/0x861A6Fc736Cbb12ad57477B535B829239c8347d7,velocimeter_v2,0.02,0.02,0x06D082d70716A9D4cf83882e7ae3c1ec07A1f3c8,,0x7e51aD847CDf8729Efc97CFa6E8aFA4D658Cb85b,0x861A6Fc736Cbb12ad57477B535B829239c8347d7,18,18,11,lz-fMULTI,MVM,0,0,0,,,,,velocimeter_v2,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x1d91de696B524838Cb82057A9B7915b32352b4f5,0,,63164155,agni_v3 0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8/0xabBeED1d173541e0546B38b1C0394975be20000 10000,0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8/0xabBeED1d173541e0546B38b1C0394975be20000,agni_v3,10000,0.01,0x1d91de696B524838Cb82057A9B7915b32352b4f5,,0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8,0xabBeED1d173541e0546B38b1C0394975be200000,18,18,4,WMNT,SVL,0,0,0,0,0,0,200,agni_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x18c5EB8bAd84De089cC321a6B1351ecAB75f98BB,0,,63164708,agni_v3 0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8/0xabBeED1d173541e0546B38b1C0394975be20000 500,0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8/0xabBeED1d173541e0546B38b1C0394975be20000,agni_v3,500,0.0005,0x18c5EB8bAd84De089cC321a6B1351ecAB75f98BB,,0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8,0xabBeED1d173541e0546B38b1C0394975be200000,18,18,4,WMNT,SVL,0,0,0,0,0,0,10,agni_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x4aD4eB5c2E7dc0DCf0cE9581dfEcFbEc46A95A06,0,,63221813,butter_v3 0xD1680522C2cEc57192d84021d64813F11DC496fB/0xdEAddEaDdeadDEadDEADDEAddEADDEAddead111 10000,0xD1680522C2cEc57192d84021d64813F11DC496fB/0xdEAddEaDdeadDEadDEADDEAddEADDEAddead111,butter_v3,10000,0.01,0x4aD4eB5c2E7dc0DCf0cE9581dfEcFbEc46A95A06,,0xD1680522C2cEc57192d84021d64813F11DC496fB,0xdEAddEaDdeadDEadDEADDEAddEADDEAddead1111,18,18,4,bETH,WETH,0,0,0,0,0,0,200,butter_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x1E49Ae9AB494AcB31311e92E5580a2fA1e62c139,0,,63221945,butter_v3 0xAc5380724638C9B4b600866e4677954f3F221cf0/0xD1680522C2cEc57192d84021d64813F11DC496f 10000,0xAc5380724638C9B4b600866e4677954f3F221cf0/0xD1680522C2cEc57192d84021d64813F11DC496f,butter_v3,10000,0.01,0x1E49Ae9AB494AcB31311e92E5580a2fA1e62c139,,0xAc5380724638C9B4b600866e4677954f3F221cf0,0xD1680522C2cEc57192d84021d64813F11DC496fB,18,18,4,wbETH,bETH,0,0,0,0,0,0,200,butter_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x1af9FEbebd2Aaa05F81EfdCd5BBF042B3F0cf38F,0,,63382278,cleopatra_v3 0x999890b3A00EA4d60da39A65FA4B70bb0bdb61f7/0xD2B4C9B0d70e3Da1fBDD98f469bD02E77E12FC7 10000,0x999890b3A00EA4d60da39A65FA4B70bb0bdb61f7/0xD2B4C9B0d70e3Da1fBDD98f469bD02E77E12FC7,cleopatra_v3,10000,0.01,0x1af9FEbebd2Aaa05F81EfdCd5BBF042B3F0cf38F,,0x999890b3A00EA4d60da39A65FA4B70bb0bdb61f7,0xD2B4C9B0d70e3Da1fBDD98f469bD02E77E12FC79,18,18,4,neadCleo,AUSD,0,0,0,0,0,0,200,cleopatra_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xaa74910Bf08E6d922bF0bCe45eA5861b669cB55C,0,,63306448,fusionx_v3 0x311eC870e3d7172896CA9f18145bAfc8902c9F3B/0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb 10000,0x311eC870e3d7172896CA9f18145bAfc8902c9F3B/0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb,fusionx_v3,10000,0.01,0xaa74910Bf08E6d922bF0bCe45eA5861b669cB55C,,0x311eC870e3d7172896CA9f18145bAfc8902c9F3B,0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8,18,18,4,BTBS,WMNT,0,0,0,0,0,0,200,fusionx_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xd99882E3404B529D5120Ef16dE6D9a0a11d9c516,0,,63325250,fusionx_v3 0xcDA86A272531e8640cD7F1a92c01839911B90bb0/0xD2B4C9B0d70e3Da1fBDD98f469bD02E77E12FC7 500,0xcDA86A272531e8640cD7F1a92c01839911B90bb0/0xD2B4C9B0d70e3Da1fBDD98f469bD02E77E12FC7,fusionx_v3,500,0.0005,0xd99882E3404B529D5120Ef16dE6D9a0a11d9c516,,0xcDA86A272531e8640cD7F1a92c01839911B90bb0,0xD2B4C9B0d70e3Da1fBDD98f469bD02E77E12FC79,18,18,4,METH,AUSD,0,0,0,0,0,0,10,fusionx_v3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x5EBb830dcF6c9aB3885A782d804bA74367533B57,0,,63216566,merchantmoe_v2 0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8/0xabBeED1d173541e0546B38b1C0394975be200000,0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8/0xabBeED1d173541e0546B38b1C0394975be200000,merchantmoe_v2,0.003,0.003,0x5EBb830dcF6c9aB3885A782d804bA74367533B57,,0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8,0xabBeED1d173541e0546B38b1C0394975be200000,18,18,3,WMNT,SVL,0,0,0,,,,,merchantmoe_v2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x40021Babb03815A055a2631332D17fc0EF651d6C,0,,63223316,merchantmoe_v2 0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8/0xD75c9FbBDbd6fb6EEDE23132f85D9BA8BAcD0a7e,0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8/0xD75c9FbBDbd6fb6EEDE23132f85D9BA8BAcD0a7e,merchantmoe_v2,0.003,0.003,0x40021Babb03815A055a2631332D17fc0EF651d6C,,0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8,0xD75c9FbBDbd6fb6EEDE23132f85D9BA8BAcD0a7e,18,18,3,WMNT,TVM,0,0,0,,,,,merchantmoe_v2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0xb81c581C1E6084dF0C2a0830A639a69cD3501117,0,,63386717,velocimeter_v2 0x7e51aD847CDf8729Efc97CFa6E8aFA4D658Cb85b/0xd27B18915e7acc8FD6Ac75DB6766a80f8D2f5729,0x7e51aD847CDf8729Efc97CFa6E8aFA4D658Cb85b/0xd27B18915e7acc8FD6Ac75DB6766a80f8D2f5729,velocimeter_v2,0.0025,0.0025,0xb81c581C1E6084dF0C2a0830A639a69cD3501117,,0x7e51aD847CDf8729Efc97CFa6E8aFA4D658Cb85b,0xd27B18915e7acc8FD6Ac75DB6766a80f8D2f5729,18,18,11,lz-fMULTI,PENDLE,0,0,0,,,,,velocimeter_v2,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/fastlane_bot/data/blockchain_data/mantle/tokens.csv b/fastlane_bot/data/blockchain_data/mantle/tokens.csv index 4a02fbd08..f4fb71b9a 100644 --- a/fastlane_bot/data/blockchain_data/mantle/tokens.csv +++ b/fastlane_bot/data/blockchain_data/mantle/tokens.csv @@ -615,3 +615,7 @@ address,decimals,symbol 0x3b19B8EC75BBf85848d133F1a47710EeEd57Bd90,18,oMVM 0x4f74ca4a686203a5D4eBF6E8868c5eBC450bf283,18,sfrxETH 0xf3602C5A7f625181659445C8dDDde73dA15c22e3,18,sFRAX +0xabBeED1d173541e0546B38b1C0394975be200000,18,SVL +0xD1680522C2cEc57192d84021d64813F11DC496fB,18,bETH +0x311eC870e3d7172896CA9f18145bAfc8902c9F3B,18,BTBS +0xD75c9FbBDbd6fb6EEDE23132f85D9BA8BAcD0a7e,18,TVM diff --git a/fastlane_bot/data/blockchain_data/mantle/uniswap_v2_event_mappings.csv b/fastlane_bot/data/blockchain_data/mantle/uniswap_v2_event_mappings.csv index 2bd52166b..91a1978a0 100644 --- a/fastlane_bot/data/blockchain_data/mantle/uniswap_v2_event_mappings.csv +++ b/fastlane_bot/data/blockchain_data/mantle/uniswap_v2_event_mappings.csv @@ -467,3 +467,5 @@ merchantmoe_v2,0xcF18b5874E62f00BdB81F80346598bD32ACa4294 merchantmoe_v2,0x3097a061eE0fc3470e2E84666Eff9e7AbFf6fC93 merchantmoe_v2,0x153bd2051E42f1C5dCF8f08dc836aE1E8316aa7C merchantmoe_v2,0x9E7c8fDEf224cfcbDb8ba187c18E2c025C047A7B +merchantmoe_v2,0x5EBb830dcF6c9aB3885A782d804bA74367533B57 +merchantmoe_v2,0x40021Babb03815A055a2631332D17fc0EF651d6C diff --git a/fastlane_bot/data/blockchain_data/mantle/uniswap_v3_event_mappings.csv b/fastlane_bot/data/blockchain_data/mantle/uniswap_v3_event_mappings.csv index 815f0d7a9..74d1fafd3 100644 --- a/fastlane_bot/data/blockchain_data/mantle/uniswap_v3_event_mappings.csv +++ b/fastlane_bot/data/blockchain_data/mantle/uniswap_v3_event_mappings.csv @@ -671,3 +671,10 @@ puffs_penthouse_v3,0x866B1818D6A221fA2B87A6C10bf60871d09C71A4 puffs_penthouse_v3,0x23d31b3d4A283Fd8E39d64FeeEbc64F6B1eeF874 puffs_penthouse_v3,0x28190bC18bbdc3D340C9A8C80265096E3A7f7EdA puffs_penthouse_v3,0xc0c94deE13fBD76faB0633924f4fA73e12EC3a1A +agni_v3,0x1d91de696B524838Cb82057A9B7915b32352b4f5 +agni_v3,0x18c5EB8bAd84De089cC321a6B1351ecAB75f98BB +butter_v3,0x4aD4eB5c2E7dc0DCf0cE9581dfEcFbEc46A95A06 +butter_v3,0x1E49Ae9AB494AcB31311e92E5580a2fA1e62c139 +cleopatra_v3,0x1af9FEbebd2Aaa05F81EfdCd5BBF042B3F0cf38F +fusionx_v3,0xaa74910Bf08E6d922bF0bCe45eA5861b669cB55C +fusionx_v3,0xd99882E3404B529D5120Ef16dE6D9a0a11d9c516 diff --git a/fastlane_bot/events/async_event_update_utils.py b/fastlane_bot/events/async_event_update_utils.py index 831b704d8..a847599d0 100644 --- a/fastlane_bot/events/async_event_update_utils.py +++ b/fastlane_bot/events/async_event_update_utils.py @@ -27,6 +27,7 @@ from fastlane_bot.events.async_utils import get_contract_chunks from fastlane_bot.events.utils import update_pools_from_events from fastlane_bot.events.pools.utils import get_pool_cid +from .interfaces.event import Event nest_asyncio.apply() @@ -89,7 +90,7 @@ async def _get_missing_tkns(mgr: Any, c: List[Dict[str, Any]]) -> pd.DataFrame: return pd.concat(vals) -async def _get_token_and_fee(mgr: Any, exchange_name: str, ex: Any, address: str, contract: AsyncContract, event: Any): +async def _get_token_and_fee(mgr: Any, exchange_name: str, ex: Any, address: str, contract: AsyncContract, event: Event): """ This function uses the exchange object to get the tokens and fee for a given pool. @@ -97,7 +98,7 @@ async def _get_token_and_fee(mgr: Any, exchange_name: str, ex: Any, address: str ex(Any): The exchange object address(str): The pool address contract(AsyncContract): The contract object - event(Any): The event object + event(Event): The event object Returns: The tokens and fee info for the pool @@ -119,7 +120,7 @@ async def _get_token_and_fee(mgr: Any, exchange_name: str, ex: Any, address: str elif tkn1 == mgr.cfg.BNT_ADDRESS: tkn0 = connector_token - strategy_id = 0 if not ex.is_carbon_v1_fork else str(event["args"]["id"]) + strategy_id = 0 if not ex.is_carbon_v1_fork else str(event.args["id"]) pool_info = { "exchange_name": exchange_name, "address": address, @@ -212,8 +213,6 @@ def _get_new_pool_data( all_keys = set() for pool in mgr.pool_data: all_keys.update(pool.keys()) - if "last_updated_block" not in all_keys: - all_keys.update("last_updated_block") pool_data_keys: frozenset = frozenset(all_keys) new_pool_data: List[Dict] = [] for idx, pool in tokens_and_fee_df.iterrows(): @@ -321,7 +320,7 @@ def _get_pool_contracts(mgr: Any) -> List[Dict[str, Any]]: exchange_name = mgr.exchange_name_from_event(event) ex = mgr.exchanges[exchange_name] abi = ex.get_abi() - address = event["address"] + address = event.address contracts.append( { "exchange_name": exchange_name, @@ -394,6 +393,10 @@ def async_update_pools_from_contracts(mgr: Any, current_block: int): mgr, current_block, tokens_and_fee_df, tokens_df ) + if len(new_pool_data) == 0: + mgr.cfg.logger.info("No pools found in contracts") + return + new_pool_data_df = pd.DataFrame(new_pool_data).sort_values( "last_updated_block", ascending=False ) @@ -410,6 +413,10 @@ def async_update_pools_from_contracts(mgr: Any, current_block: int): ] ) + if new_pool_data_df.empty: + mgr.cfg.logger.info("No valid pools found in contracts") + return + new_pool_data_df["descr"] = ( new_pool_data_df["exchange_name"] + " " @@ -436,22 +443,26 @@ def async_update_pools_from_contracts(mgr: Any, current_block: int): duplicate_new_pool_ct = len(duplicate_cid_rows) - all_pools_df = ( - pd.DataFrame(mgr.pool_data) - .sort_values("last_updated_block", ascending=False) - .drop_duplicates(subset=["cid"]) - .set_index("cid") - ) + if len(mgr.pool_data) > 0: + all_pools_df = ( + pd.DataFrame(mgr.pool_data) + .sort_values("last_updated_block", ascending=False) + .drop_duplicates(subset=["cid"]) + .set_index("cid") + ) - new_pool_data_df = new_pool_data_df[all_pools_df.columns] + new_pool_data_df = new_pool_data_df[all_pools_df.columns] - # add new_pool_data to pool_data, ensuring no duplicates - all_pools_df.update(new_pool_data_df, overwrite=True) + # add new_pool_data to pool_data, ensuring no duplicates + all_pools_df.update(new_pool_data_df, overwrite=True) + + new_pool_data_df = new_pool_data_df[ + ~new_pool_data_df.index.isin(all_pools_df.index) + ] + all_pools_df = pd.concat([all_pools_df, new_pool_data_df]) + else: + all_pools_df = new_pool_data_df - new_pool_data_df = new_pool_data_df[ - ~new_pool_data_df.index.isin(all_pools_df.index) - ] - all_pools_df = pd.concat([all_pools_df, new_pool_data_df]) all_pools_df[["tkn0_decimals", "tkn1_decimals"]] = ( all_pools_df[["tkn0_decimals", "tkn1_decimals"]].fillna(0).astype(int) ) diff --git a/fastlane_bot/events/event_gatherer.py b/fastlane_bot/events/event_gatherer.py new file mode 100644 index 000000000..93156cab8 --- /dev/null +++ b/fastlane_bot/events/event_gatherer.py @@ -0,0 +1,99 @@ +import asyncio +from itertools import chain +from typing import Dict, List +from traceback import format_exc + +import nest_asyncio + +from web3 import AsyncWeb3 +from web3.contract import Contract + +from fastlane_bot.config import Config +from fastlane_bot.config.constants import BLOCK_CHUNK_SIZE_MAP +from .interfaces.subscription import Subscription +from .exchanges.base import Exchange + + +nest_asyncio.apply() + + +class EventGatherer: + """ + The EventGatherer manages event gathering using eth.get_logs. + """ + + def __init__( + self, + config: Config, + w3: AsyncWeb3, + exchanges: Dict[str, Exchange], + ): + """ Initializes the EventManager. + Args: + manager: The Manager object + w3: The connected AsyncWeb3 object. + """ + self._config = config + self._w3 = w3 + self._subscriptions = [] + + for exchange in exchanges.values(): + subscriptions = exchange.get_subscriptions(w3) + for sub in subscriptions: + if sub.topic not in [s.topic for s in self._subscriptions]: + self._subscriptions.append(sub) + + def get_all_events(self, from_block: int, to_block: int): + coroutines = [] + for sub in self._subscriptions: + if sub.collect_all: + from_block_ = 0 + else: + from_block_ = from_block + coroutines.append(self._get_events_for_subscription(from_block_, to_block, sub)) + results = asyncio.get_event_loop().run_until_complete(asyncio.gather(*coroutines)) + return list(chain.from_iterable(results)) + + async def _get_events_for_subscription(self, from_block: int, to_block: int, subscription: Subscription): + return [subscription.parse_log(log) for log in await self._get_logs_for_topics(from_block, to_block, [subscription.topic])] + + async def _get_logs_for_topics(self, from_block: int, to_block: int, topics: List[str]): + chunk_size = BLOCK_CHUNK_SIZE_MAP[self._config.network.NETWORK] + if chunk_size > 0: + return await self._get_logs_iterative(from_block, to_block, topics, chunk_size) + else: + return await self._get_logs_recursive(from_block, to_block, topics) + + async def _get_logs_iterative(self, from_block: int, to_block: int, topics: List[str], chunk_size: int) -> list: + block_numbers = list(range(from_block, to_block + 1, chunk_size)) + [to_block + 1] + log_lists = await asyncio.gather(*[ + self._w3.eth.get_logs(filter_params={ + "fromBlock": r[0], + "toBlock": r[1], + "topics": topics + }) + for r in zip(block_numbers, map(lambda n: n - 1, block_numbers[1:])) + ]) + return [log for log_list in log_lists for log in log_list] + + async def _get_logs_recursive(self, from_block: int, to_block: int, topics: List[str]) -> list: + if from_block <= to_block: + try: + return await self._w3.eth.get_logs(filter_params={ + "fromBlock": from_block, + "toBlock": to_block, + "topics": topics + }) + except Exception as e: + if "eth_getLogs" not in str(e): + self._config.logger.error(f"Unexpected exception in EventGatherer: {format_exc()}") + if from_block < to_block: + mid_block = (from_block + to_block) // 2 + log_lists = await asyncio.gather( + self._get_logs_recursive(from_block, mid_block, topics), + self._get_logs_recursive(mid_block + 1, to_block, topics) + ) + return [log for log_list in log_lists for log in log_list] + else: + raise e + raise Exception(f"Illegal log query range: {from_block} -> {to_block}") diff --git a/fastlane_bot/events/exchanges/balancer.py b/fastlane_bot/events/exchanges/balancer.py index 01383cc51..efba312e1 100644 --- a/fastlane_bot/events/exchanges/balancer.py +++ b/fastlane_bot/events/exchanges/balancer.py @@ -12,13 +12,15 @@ Licensed under MIT. """ from dataclasses import dataclass -from typing import List, Type, Tuple, Any +from typing import List, Type, Tuple, Any, Union +from web3 import Web3, AsyncWeb3 from web3.contract import Contract from fastlane_bot.data.abi import BALANCER_VAULT_ABI, BALANCER_POOL_ABI_V1 -from fastlane_bot.events.exchanges.base import Exchange -from fastlane_bot.events.pools.base import Pool +from ..exchanges.base import Exchange +from ..pools.base import Pool +from ..interfaces.subscription import Subscription @dataclass @@ -37,7 +39,7 @@ def get_abi(self): return BALANCER_VAULT_ABI @property - def get_factory_abi(self): + def factory_abi(self): # Not used for Balancer return BALANCER_VAULT_ABI @@ -47,6 +49,9 @@ def get_pool_abi(self): def get_events(self, contract: Contract) -> List[Type[Contract]]: return [contract.events.AuthorizerChanged] + def get_subscriptions(self, w3: Union[Web3, AsyncWeb3]) -> List[Subscription]: + return [] + async def get_fee(self, pool_id: str, contract: Contract) -> Tuple[str, float]: pool = self.get_pool(pool_id) if pool: @@ -83,4 +88,7 @@ async def get_tkn_n(self, address: str, contract: Contract, event: Any, index: i pool_balances = await contract.caller.getPoolTokens(address) tokens = pool_balances[0] token_balances = pool_balances[1] - return token_balances[index] \ No newline at end of file + return token_balances[index] + + def get_pool_func_call(self, addr1, addr2): + raise NotImplementedError diff --git a/fastlane_bot/events/exchanges/bancor_pol.py b/fastlane_bot/events/exchanges/bancor_pol.py index 1211cc5cc..2c63dda6d 100644 --- a/fastlane_bot/events/exchanges/bancor_pol.py +++ b/fastlane_bot/events/exchanges/bancor_pol.py @@ -12,14 +12,17 @@ Licensed under MIT. """ from dataclasses import dataclass -from typing import List, Type, Tuple, Any, Dict, Callable +from typing import List, Type, Tuple, Any, Dict, Callable, Union +from web3 import Web3, AsyncWeb3 from web3.contract import Contract from fastlane_bot.data.abi import BANCOR_POL_ABI -from fastlane_bot.events.exchanges.base import Exchange -from fastlane_bot.events.pools.base import Pool from fastlane_bot import Config +from ..exchanges.base import Exchange +from ..pools.base import Pool +from ..interfaces.event import Event +from ..interfaces.subscription import Subscription @dataclass @@ -39,21 +42,28 @@ def get_abi(self): return BANCOR_POL_ABI @property - def get_factory_abi(self): + def factory_abi(self): # Not used for Bancor POL return BANCOR_POL_ABI def get_events(self, contract: Contract) -> List[Type[Contract]]: return [contract.events.TokenTraded, contract.events.TradingEnabled] + def get_subscriptions(self, w3: Union[Web3, AsyncWeb3]) -> List[Subscription]: + contract = self.get_event_contract(w3) + return [ + Subscription(contract.events.TokenTraded, collect_all=True), + Subscription(contract.events.TradingEnabled, "0xae3f48c001771f8e9868e24d47b9e4295b06b1d78072acf96f167074aa3fab64", collect_all=True), + ] + async def get_fee(self, address: str, contract: Contract) -> Tuple[str, float]: return "0.000", 0.000 - async def get_tkn0(self, address: str, contract: Contract, event: Any) -> str: - return event["args"]["token"] + async def get_tkn0(self, address: str, contract: Contract, event: Event) -> str: + return event.args["token"] - async def get_tkn1(self, address: str, contract: Contract, event: Any) -> str: - return self.ETH_ADDRESS if event["args"]["token"] not in self.ETH_ADDRESS else self.BNT_ADDRESS + async def get_tkn1(self, address: str, contract: Contract, event: Event) -> str: + return self.ETH_ADDRESS if event.args["token"] not in self.ETH_ADDRESS else self.BNT_ADDRESS def save_strategy( self, @@ -97,3 +107,6 @@ def save_strategy( cid=cid, block_number=block_number, ) + + def get_pool_func_call(self, addr1, addr2): + raise NotImplementedError diff --git a/fastlane_bot/events/exchanges/bancor_v2.py b/fastlane_bot/events/exchanges/bancor_v2.py index 217b1297a..efa54f433 100644 --- a/fastlane_bot/events/exchanges/bancor_v2.py +++ b/fastlane_bot/events/exchanges/bancor_v2.py @@ -12,13 +12,16 @@ Licensed under MIT. """ from dataclasses import dataclass -from typing import List, Type, Tuple, Any +from typing import List, Type, Tuple, Union +from web3 import Web3, AsyncWeb3 from web3.contract import Contract, AsyncContract from fastlane_bot.data.abi import BANCOR_V2_CONVERTER_ABI -from fastlane_bot.events.exchanges.base import Exchange -from fastlane_bot.events.pools.base import Pool +from ..exchanges.base import Exchange +from ..pools.base import Pool +from ..interfaces.event import Event +from ..interfaces.subscription import Subscription @dataclass @@ -37,13 +40,17 @@ def get_abi(self): return BANCOR_V2_CONVERTER_ABI @property - def get_factory_abi(self): + def factory_abi(self): # Not used for Bancor V2 return BANCOR_V2_CONVERTER_ABI def get_events(self, contract: Contract) -> List[Type[Contract]]: return [contract.events.TokenRateUpdate] + def get_subscriptions(self, w3: Union[Web3, AsyncWeb3]) -> List[Subscription]: + contract = self.get_event_contract(w3) + return [Subscription(contract.events.TokenRateUpdate)] + # def async convert_address(self, address: str, contract: Contract) -> str: # return @@ -59,15 +66,18 @@ async def get_fee(self, address: str, contract: AsyncContract) -> Tuple[str, flo fee_float = float(fee) / 1e6 return fee, fee_float - async def get_tkn0(self, address: str, contract: Contract, event: Any) -> str: + async def get_tkn0(self, address: str, contract: Contract, event: Event) -> str: if event: - return event["args"]["_token1"] - return await contract.caller.reserveTokens()[0] + return event.args["_token1"] + return await contract.functions.reserveTokens()[0] - async def get_tkn1(self, address: str, contract: Contract, event: Any) -> str: + async def get_tkn1(self, address: str, contract: Contract, event: Event) -> str: if event: - return event["args"]["_token2"] - return await contract.caller.reserveTokens()[1] + return event.args["_token2"] + return await contract.functions.reserveTokens()[1] async def get_anchor(self, contract: Contract) -> str: return await contract.caller.anchor() + + def get_pool_func_call(self, addr1, addr2): + raise NotImplementedError diff --git a/fastlane_bot/events/exchanges/bancor_v3.py b/fastlane_bot/events/exchanges/bancor_v3.py index 7e0e5b20d..ed5ba0720 100644 --- a/fastlane_bot/events/exchanges/bancor_v3.py +++ b/fastlane_bot/events/exchanges/bancor_v3.py @@ -12,13 +12,20 @@ Licensed under MIT. """ from dataclasses import dataclass -from typing import List, Type, Tuple, Any +from typing import List, Type, Tuple, Union +from web3 import Web3, AsyncWeb3 from web3.contract import Contract from fastlane_bot.data.abi import BANCOR_V3_POOL_COLLECTION_ABI -from fastlane_bot.events.exchanges.base import Exchange -from fastlane_bot.events.pools.base import Pool +from ..exchanges.base import Exchange +from ..pools.base import Pool +from ..interfaces.event import Event +from ..interfaces.subscription import Subscription + + +TRADING_LIQUIDITY_UPDATED_TOPIC = "0x6e96dc5343d067ec486a9920e0304c3610ed05c65e45cc029d9b9fe7ecfa7620" +TOTAL_LIQUIDITY_UPDATED_TOPIC = "0x85a03952f50b8c00b32a521c32094023b64ef0b6d4511f423d44c480a62cb145" @dataclass @@ -37,22 +44,32 @@ def get_abi(self): return BANCOR_V3_POOL_COLLECTION_ABI @property - def get_factory_abi(self): + def factory_abi(self): # Not used for Bancor V3 return BANCOR_V3_POOL_COLLECTION_ABI def get_events(self, contract: Contract) -> List[Type[Contract]]: return [contract.events.TradingLiquidityUpdated] + def get_subscriptions(self, w3: Union[Web3, AsyncWeb3]) -> List[Subscription]: + contract = self.get_event_contract(w3) + return [ + Subscription(contract.events.TradingLiquidityUpdated, TRADING_LIQUIDITY_UPDATED_TOPIC), + # Subscription(contract.events.TotalLiquidityUpdated, TOTAL_LIQUIDITY_UPDATED_TOPIC), # Unused + ] + async def get_fee(self, address: str, contract: Contract) -> Tuple[str, float]: return "0.000", 0.000 - async def get_tkn0(self, address: str, contract: Contract, event: Any) -> str: + async def get_tkn0(self, address: str, contract: Contract, event: Event) -> str: return self.BNT_ADDRESS - async def get_tkn1(self, address: str, contract: Contract, event: Any) -> str: + async def get_tkn1(self, address: str, contract: Contract, event: Event) -> str: return ( - event["args"]["pool"] - if event["args"]["pool"] != self.BNT_ADDRESS - else event["args"]["tkn_address"] + event.args["pool"] + if event.args["pool"] != self.BNT_ADDRESS + else event.args["tkn_address"] ) + + def get_pool_func_call(self, addr1, addr2): + raise NotImplementedError diff --git a/fastlane_bot/events/exchanges/base.py b/fastlane_bot/events/exchanges/base.py index a63c7ed29..62bfe7996 100644 --- a/fastlane_bot/events/exchanges/base.py +++ b/fastlane_bot/events/exchanges/base.py @@ -12,12 +12,14 @@ """ from abc import ABC, abstractmethod from dataclasses import dataclass, field -from typing import Dict, List, Type, Any +from typing import Dict, List, Type, Any, Union +from web3 import Web3, AsyncWeb3 from web3.contract import Contract, AsyncContract from fastlane_bot.config.constants import CARBON_V1_NAME -from fastlane_bot.events.pools.base import Pool +from ..pools.base import Pool +from ..interfaces.subscription import Subscription @dataclass @@ -29,6 +31,7 @@ class Exchange(ABC): exchange_name: str base_exchange_name: str = '' pools: Dict[str, Pool] = field(default_factory=dict) + factory_contract: Contract = None __VERSION__ = "0.0.3" __DATE__ = "2024-03-20" @@ -49,6 +52,9 @@ def get_pools(self) -> List[Pool]: """ return list(self.pools.values()) + def get_event_contract(self, w3: Union[Web3, AsyncWeb3]) -> Union[Contract, AsyncContract]: + return w3.eth.contract(abi=self.get_abi()) + @abstractmethod def add_pool(self, pool: Pool): """ @@ -96,6 +102,10 @@ def get_events(self, contract: Contract) -> List[Type[Contract]]: """ pass + @abstractmethod + def get_subscriptions(self, w3: Union[Web3, AsyncWeb3]) -> List[Subscription]: + ... + @staticmethod @abstractmethod async def get_fee(address: str, contract: AsyncContract) -> float: @@ -117,6 +127,10 @@ async def get_fee(address: str, contract: AsyncContract) -> float: """ pass + @abstractmethod + def get_pool_func_call(self, addr1, addr2, *args, **kwargs): + ... + @staticmethod @abstractmethod async def get_tkn0(address: str, contract: AsyncContract, event: Any) -> str: @@ -181,7 +195,7 @@ def get_pool(self, key: str) -> Pool: return self.pools[key] if key in self.pools else None @abstractmethod - def get_factory_abi(self): + def factory_abi(self): """ Get the ABI of the exchange's Factory contract diff --git a/fastlane_bot/events/exchanges/carbon_v1.py b/fastlane_bot/events/exchanges/carbon_v1.py index 3dcf93a98..125dadb26 100644 --- a/fastlane_bot/events/exchanges/carbon_v1.py +++ b/fastlane_bot/events/exchanges/carbon_v1.py @@ -12,15 +12,23 @@ Licensed under MIT. """ from dataclasses import dataclass -from typing import List, Type, Tuple, Any, Dict, Callable +from typing import List, Type, Tuple, Any, Dict, Callable, Union from fastlane_bot import Config +from web3 import Web3, AsyncWeb3 from web3.contract import Contract from fastlane_bot.data.abi import CARBON_CONTROLLER_ABI -from fastlane_bot.events.exchanges.base import Exchange -from fastlane_bot.events.pools.base import Pool -from fastlane_bot.events.pools.utils import get_pool_cid +from ..exchanges.base import Exchange +from ..pools.base import Pool +from ..interfaces.event import Event +from ..interfaces.subscription import Subscription +from ..pools.utils import get_pool_cid + + +STRATEGY_CREATED_TOPIC = "0xff24554f8ccfe540435cfc8854831f8dcf1cf2068708cfaf46e8b52a4ccc4c8d" +STRATEGY_UPDATED_TOPIC = "0x720da23a5c920b1d8827ec83c4d3c4d90d9419eadb0036b88cb4c2ffa91aef7d" +STRATEGY_DELETED_TOPIC = "0x4d5b6e0627ea711d8e9312b6ba56f50e0b51d41816fd6fd38643495ac81d38b6" @dataclass @@ -60,7 +68,7 @@ def get_abi(self): return CARBON_CONTROLLER_ABI @property - def get_factory_abi(self): + def factory_abi(self): return CARBON_CONTROLLER_ABI def get_events(self, contract: Contract) -> List[Type[Contract]]: @@ -73,6 +81,17 @@ def get_events(self, contract: Contract) -> List[Type[Contract]]: contract.events.PairCreated, ] if self.exchange_initialized else [] + def get_subscriptions(self, w3: Union[Web3, AsyncWeb3]) -> List[Subscription]: + contract = self.get_event_contract(w3) + return [ + Subscription(contract.events.StrategyCreated, STRATEGY_CREATED_TOPIC), + Subscription(contract.events.StrategyUpdated, STRATEGY_UPDATED_TOPIC), + Subscription(contract.events.StrategyDeleted, STRATEGY_DELETED_TOPIC), + Subscription(contract.events.PairTradingFeePPMUpdated), + Subscription(contract.events.TradingFeePPMUpdated), + Subscription(contract.events.PairCreated), + ] + async def get_fee( self, address: str, contract: Contract ) -> Tuple[str, float]: @@ -94,7 +113,7 @@ async def get_fee( fee = await contract.tradingFeePPM() return f"{fee}", fee / 1e6 - async def get_tkn0(self, address: str, contract: Contract, event: Any) -> str: + async def get_tkn0(self, address: str, contract: Contract, event: Event) -> str: """ Get the token0 address from the contract or event. @@ -116,9 +135,9 @@ async def get_tkn0(self, address: str, contract: Contract, event: Any) -> str: if event is None: return await contract.caller.token0() else: - return event["args"]["token0"] + return event.args["token0"] - async def get_tkn1(self, address: str, contract: Contract, event: Any) -> str: + async def get_tkn1(self, address: str, contract: Contract, event: Event) -> str: """ Get the token1 address from the contract or event. @@ -140,7 +159,7 @@ async def get_tkn1(self, address: str, contract: Contract, event: Any) -> str: if event is None: return await contract.caller.token1() else: - return event["args"]["token1"] + return event.args["token1"] def delete_strategy(self, id: str): """ @@ -228,3 +247,5 @@ def save_strategy( block_number=block_number, ) + def get_pool_func_call(self, addr1, addr2): + raise NotImplementedError diff --git a/fastlane_bot/events/exchanges/factory.py b/fastlane_bot/events/exchanges/factory.py index 670bdc5df..fe98beea6 100644 --- a/fastlane_bot/events/exchanges/factory.py +++ b/fastlane_bot/events/exchanges/factory.py @@ -12,6 +12,8 @@ """ from typing import Dict, Any +from fastlane_bot.config.constants import SOLIDLY_V2_NAME, UNISWAP_V2_NAME, UNISWAP_V3_NAME + class ExchangeFactory: """ @@ -60,7 +62,16 @@ def get_exchange(self, key, cfg: Any, exchange_initialized: bool = None): creator = self._creators.get(fork_name) args = self.get_fork_extras(exchange_name=key, cfg=cfg, exchange_initialized=exchange_initialized) - return creator(**args) + exchange = creator(**args) + + base_exchange_name = cfg.network.exchange_name_base_from_fork(exchange_name=key) + if base_exchange_name in [SOLIDLY_V2_NAME, UNISWAP_V2_NAME, UNISWAP_V3_NAME]: + exchange.factory_contract = cfg.w3_async.eth.contract( + address=cfg.FACTORY_MAPPING[key], + abi=exchange.factory_abi, + ) + + return exchange def get_fork_extras(self, exchange_name: str, cfg: Any, exchange_initialized: bool) -> Dict[str, str]: """ diff --git a/fastlane_bot/events/exchanges/solidly_v2.py b/fastlane_bot/events/exchanges/solidly_v2.py deleted file mode 100644 index 0197f5315..000000000 --- a/fastlane_bot/events/exchanges/solidly_v2.py +++ /dev/null @@ -1,117 +0,0 @@ -""" -Contains the exchange class for SolidlyV2. - -This class is responsible for handling SolidlyV2 events and updating the state of the pools. - - -[DOC-TODO-OPTIONAL-longer description in rst format] - ---- -(c) Copyright Bprotocol foundation 2023-24. -All rights reserved. -Licensed under MIT. -""" -from dataclasses import dataclass -from typing import List, Type, Tuple, Any - -from web3.contract import Contract, AsyncContract - -from fastlane_bot.data.abi import SOLIDLY_V2_POOL_ABI, VELOCIMETER_V2_FACTORY_ABI, SOLIDLY_V2_FACTORY_ABI, \ - SCALE_V2_FACTORY_ABI, CLEOPATRA_V2_FACTORY_ABI, LYNEX_V2_FACTORY_ABI, NILE_V2_FACTORY_ABI, \ - XFAI_V0_FACTORY_ABI, XFAI_V0_CORE_ABI, XFAI_V0_POOL_ABI -from fastlane_bot.events.exchanges.base import Exchange -from fastlane_bot.events.pools.base import Pool - -async def _get_fee_1(address: str, contract: Contract, factory_contract: Contract) -> int: - return await factory_contract.caller.getFee(address) - -async def _get_fee_2(address: str, contract: Contract, factory_contract: Contract) -> int: - return await factory_contract.caller.getRealFee(address) - -async def _get_fee_3(address: str, contract: Contract, factory_contract: Contract) -> int: - return await factory_contract.caller.getFee(address, await contract.caller.stable()) - -async def _get_fee_4(address: str, contract: Contract, factory_contract: Contract) -> int: - return await factory_contract.caller.getPairFee(address, await contract.caller.stable()) - -async def _get_fee_5(address: str, contract: Contract, factory_contract: Contract) -> int: - return await factory_contract.caller.getFee(await contract.caller.stable()) - -async def _get_fee_6(address: str, contract: Contract, factory_contract: Contract) -> int: - return await factory_contract.caller.pairFee(address) - -async def _get_fee_7(address: str, contract: Contract, factory_contract: Contract) -> int: - core_address = factory_contract.w3.to_checksum_address(await factory_contract.caller.getXfaiCore()) - core_contract = factory_contract.w3.eth.contract(address=core_address, abi=XFAI_V0_CORE_ABI) - return await core_contract.caller.getTotalFee() - -async def _get_tkn0_A(contract: Contract) -> str: - return await contract.caller.token0() - -async def _get_tkn1_A(contract: Contract) -> str: - return await contract.caller.token1() - -async def _get_tkn0_B(contract: Contract) -> str: - return await contract.caller.poolToken() - -async def _get_tkn1_B(contract: Contract) -> str: - return "0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f" # TODO Use the constant WRAPPED_GAS_TOKEN_ADDRESS for this network - -EXCHANGE_INFO = { - "velocimeter_v2": {"decimals": 4, "factory_abi": VELOCIMETER_V2_FACTORY_ABI, "pool_abi": SOLIDLY_V2_POOL_ABI, "get_fee": _get_fee_1, "get_tkn0": _get_tkn0_A, "get_tkn1": _get_tkn1_A}, - "equalizer_v2" : {"decimals": 4, "factory_abi": SCALE_V2_FACTORY_ABI , "pool_abi": SOLIDLY_V2_POOL_ABI, "get_fee": _get_fee_2, "get_tkn0": _get_tkn0_A, "get_tkn1": _get_tkn1_A}, - "aerodrome_v2" : {"decimals": 4, "factory_abi": SOLIDLY_V2_FACTORY_ABI , "pool_abi": SOLIDLY_V2_POOL_ABI, "get_fee": _get_fee_3, "get_tkn0": _get_tkn0_A, "get_tkn1": _get_tkn1_A}, - "velodrome_v2" : {"decimals": 4, "factory_abi": SOLIDLY_V2_FACTORY_ABI , "pool_abi": SOLIDLY_V2_POOL_ABI, "get_fee": _get_fee_3, "get_tkn0": _get_tkn0_A, "get_tkn1": _get_tkn1_A}, - "scale_v2" : {"decimals": 18, "factory_abi": SCALE_V2_FACTORY_ABI , "pool_abi": SOLIDLY_V2_POOL_ABI, "get_fee": _get_fee_2, "get_tkn0": _get_tkn0_A, "get_tkn1": _get_tkn1_A}, - "cleopatra_v2" : {"decimals": 4, "factory_abi": CLEOPATRA_V2_FACTORY_ABI , "pool_abi": SOLIDLY_V2_POOL_ABI, "get_fee": _get_fee_4, "get_tkn0": _get_tkn0_A, "get_tkn1": _get_tkn1_A}, - "stratum_v2" : {"decimals": 4, "factory_abi": VELOCIMETER_V2_FACTORY_ABI, "pool_abi": SOLIDLY_V2_POOL_ABI, "get_fee": _get_fee_1, "get_tkn0": _get_tkn0_A, "get_tkn1": _get_tkn1_A}, - "lynex_v2" : {"decimals": 4, "factory_abi": LYNEX_V2_FACTORY_ABI , "pool_abi": SOLIDLY_V2_POOL_ABI, "get_fee": _get_fee_5, "get_tkn0": _get_tkn0_A, "get_tkn1": _get_tkn1_A}, - "nile_v2" : {"decimals": 4, "factory_abi": NILE_V2_FACTORY_ABI , "pool_abi": SOLIDLY_V2_POOL_ABI, "get_fee": _get_fee_6, "get_tkn0": _get_tkn0_A, "get_tkn1": _get_tkn1_A}, - "xfai_v0" : {"decimals": 4, "factory_abi": XFAI_V0_FACTORY_ABI , "pool_abi": XFAI_V0_POOL_ABI , "get_fee": _get_fee_7, "get_tkn0": _get_tkn0_B, "get_tkn1": _get_tkn1_B}, -} - -@dataclass -class SolidlyV2(Exchange): - """ - SolidlyV2 exchange class - """ - - base_exchange_name: str = "solidly_v2" - exchange_name: str = None - fee: str = None - router_address: str = None - exchange_initialized: bool = False - - stable_fee: float = None - volatile_fee: float = None - factory_address: str = None - factory_contract: AsyncContract = None - - @property - def fee_float(self): - return float(self.fee) - - def add_pool(self, pool: Pool): - self.pools[pool.state["address"]] = pool - - def get_abi(self): - return EXCHANGE_INFO[self.exchange_name]["pool_abi"] - - @property - def get_factory_abi(self): - return EXCHANGE_INFO[self.exchange_name]["factory_abi"] - - def get_events(self, contract: Contract) -> List[Type[Contract]]: - return [contract.events.Sync] if self.exchange_initialized else [] - - async def get_fee(self, address: str, contract: AsyncContract) -> Tuple[str, float]: - exchange_info = EXCHANGE_INFO[self.exchange_name] - fee = await exchange_info["get_fee"](address, contract, self.factory_contract) - fee_float = float(fee) / 10 ** exchange_info["decimals"] - return str(fee_float), fee_float - - async def get_tkn0(self, address: str, contract: Contract, event: Any) -> str: - return await EXCHANGE_INFO[self.exchange_name]["get_tkn0"](contract) - - async def get_tkn1(self, address: str, contract: Contract, event: Any) -> str: - return await EXCHANGE_INFO[self.exchange_name]["get_tkn1"](contract) diff --git a/fastlane_bot/events/exchanges/solidly_v2/__init__.py b/fastlane_bot/events/exchanges/solidly_v2/__init__.py new file mode 100644 index 000000000..7411376aa --- /dev/null +++ b/fastlane_bot/events/exchanges/solidly_v2/__init__.py @@ -0,0 +1,25 @@ +from .base import SolidlyV2 as SolidlyV2Base +from .velocimeter_v2 import VelocimeterV2 +from .equalizer_v2 import EqualizerV2 +from .velodrome_v2 import VelodromeV2 +from .scale_v2 import ScaleV2 +from .cleopatra_v2 import CleopatraV2 +from .lynex_v2 import LynexV2 +from .nile_v2 import NileV2 +from .xfai_v0 import XFaiV2 + + +class SolidlyV2(SolidlyV2Base): + def __new__(cls, **kwargs): + return { + "velocimeter_v2": VelocimeterV2, + "equalizer_v2": EqualizerV2, + "aerodrome_v2": VelodromeV2, + "velodrome_v2": VelodromeV2, + "scale_v2": ScaleV2, + "cleopatra_v2": CleopatraV2, + "stratum_v2": VelocimeterV2, + "lynex_v2": LynexV2, + "nile_v2": NileV2, + "xfai_v0": XFaiV2, + }[kwargs["exchange_name"]](**kwargs) diff --git a/fastlane_bot/events/exchanges/solidly_v2/base.py b/fastlane_bot/events/exchanges/solidly_v2/base.py new file mode 100644 index 000000000..693c82197 --- /dev/null +++ b/fastlane_bot/events/exchanges/solidly_v2/base.py @@ -0,0 +1,77 @@ +""" +Contains the exchange class for SolidlyV2. + +This class is responsible for handling SolidlyV2 events and updating the state of the pools. + + +[DOC-TODO-OPTIONAL-longer description in rst format] + +--- +(c) Copyright Bprotocol foundation 2023-24. +All rights reserved. +Licensed under MIT. +""" +from abc import abstractmethod +from dataclasses import dataclass +from typing import List, Type, Any, Union + +from web3 import Web3, AsyncWeb3 +from web3.contract import Contract, AsyncContract + +from fastlane_bot.data.abi import SOLIDLY_V2_POOL_ABI +from fastlane_bot.events.exchanges.base import Exchange +from ...exchanges.base import Exchange +from ...pools.base import Pool +from ...interfaces.subscription import Subscription + + +@dataclass +class SolidlyV2(Exchange): + """ + SolidlyV2 exchange class + """ + base_exchange_name: str = "solidly_v2" + exchange_name: str = None + fee: str = None + router_address: str = None + exchange_initialized: bool = False + + stable_fee: float = None + volatile_fee: float = None + factory_address: str = None + factory_contract: AsyncContract = None + + @property + def fee_float(self): # TODO: why is this here? + return float(self.fee) + + def add_pool(self, pool: Pool): + self.pools[pool.state["address"]] = pool + + def get_events(self, contract: Contract) -> List[Type[Contract]]: + return [contract.events.Sync] if self.exchange_initialized else [] + + def get_subscriptions(self, w3: Union[Web3, AsyncWeb3]) -> List[Subscription]: + contract = self.get_event_contract(w3) + return [Subscription(contract.events.Sync)] + + def get_abi(self): + return SOLIDLY_V2_POOL_ABI + + async def get_tkn0(self, address: str, contract: Contract, event: Any) -> str: + return await contract.caller.token0() + + async def get_tkn1(self, address: str, contract: Contract, event: Any) -> str: + return await contract.caller.token1() + + def get_pool_func_call(self, addr1, addr2): + return self.factory_contract.functions.getPair(addr1, addr2, False) + + @property + @abstractmethod + def factory_abi(self): + ... + + @abstractmethod + async def get_fee(self, address: str, contract: Contract, factory_contract: Contract): + ... diff --git a/fastlane_bot/events/exchanges/solidly_v2/cleopatra_v2.py b/fastlane_bot/events/exchanges/solidly_v2/cleopatra_v2.py new file mode 100644 index 000000000..ecff33375 --- /dev/null +++ b/fastlane_bot/events/exchanges/solidly_v2/cleopatra_v2.py @@ -0,0 +1,19 @@ +from dataclasses import dataclass +from typing import Tuple + +from web3.contract import AsyncContract + +from fastlane_bot.data.abi import CLEOPATRA_V2_FACTORY_ABI +from .base import SolidlyV2 + + +@dataclass +class CleopatraV2(SolidlyV2): + @property + def factory_abi(self): + return CLEOPATRA_V2_FACTORY_ABI + + async def get_fee(self, address: str, contract: AsyncContract) -> Tuple[str, float]: + fee = await self.factory_contract.caller.getPairFee(address, await contract.caller.stable()) + fee_float = float(fee) / 10 ** 4 + return str(fee_float), fee_float diff --git a/fastlane_bot/events/exchanges/solidly_v2/equalizer_v2.py b/fastlane_bot/events/exchanges/solidly_v2/equalizer_v2.py new file mode 100644 index 000000000..820f9a8ec --- /dev/null +++ b/fastlane_bot/events/exchanges/solidly_v2/equalizer_v2.py @@ -0,0 +1,19 @@ +from dataclasses import dataclass +from typing import Tuple + +from web3.contract import AsyncContract + +from fastlane_bot.data.abi import SCALE_V2_FACTORY_ABI +from .base import SolidlyV2 + + +@dataclass +class EqualizerV2(SolidlyV2): + @property + def factory_abi(self): + return SCALE_V2_FACTORY_ABI + + async def get_fee(self, address: str, contract: AsyncContract) -> Tuple[str, float]: + fee = await self.factory_contract.caller.getRealFee(address) + fee_float = float(fee) / 10 ** 4 + return str(fee_float), fee_float diff --git a/fastlane_bot/events/exchanges/solidly_v2/lynex_v2.py b/fastlane_bot/events/exchanges/solidly_v2/lynex_v2.py new file mode 100644 index 000000000..79339519d --- /dev/null +++ b/fastlane_bot/events/exchanges/solidly_v2/lynex_v2.py @@ -0,0 +1,19 @@ +from dataclasses import dataclass +from typing import Tuple + +from web3.contract import AsyncContract + +from fastlane_bot.data.abi import LYNEX_V2_FACTORY_ABI +from .base import SolidlyV2 + + +@dataclass +class LynexV2(SolidlyV2): + @property + def factory_abi(self): + return LYNEX_V2_FACTORY_ABI + + async def get_fee(self, address: str, contract: AsyncContract) -> Tuple[str, float]: + fee = await self.factory_contract.caller.getFee(await contract.caller.stable()) + fee_float = float(fee) / 10 ** 4 + return str(fee_float), fee_float diff --git a/fastlane_bot/events/exchanges/solidly_v2/nile_v2.py b/fastlane_bot/events/exchanges/solidly_v2/nile_v2.py new file mode 100644 index 000000000..fe81c9921 --- /dev/null +++ b/fastlane_bot/events/exchanges/solidly_v2/nile_v2.py @@ -0,0 +1,19 @@ +from dataclasses import dataclass +from typing import Tuple + +from web3.contract import AsyncContract + +from fastlane_bot.data.abi import NILE_V2_FACTORY_ABI +from .base import SolidlyV2 + + +@dataclass +class NileV2(SolidlyV2): + @property + def factory_abi(self): + return NILE_V2_FACTORY_ABI + + async def get_fee(self, address: str, contract: AsyncContract) -> Tuple[str, float]: + fee = await self.factory_contract.caller.pairFee(address) + fee_float = float(fee) / 10 ** 4 + return str(fee_float), fee_float diff --git a/fastlane_bot/events/exchanges/solidly_v2/scale_v2.py b/fastlane_bot/events/exchanges/solidly_v2/scale_v2.py new file mode 100644 index 000000000..cb2744792 --- /dev/null +++ b/fastlane_bot/events/exchanges/solidly_v2/scale_v2.py @@ -0,0 +1,19 @@ +from dataclasses import dataclass +from typing import Tuple + +from web3.contract import AsyncContract + +from fastlane_bot.data.abi import SCALE_V2_FACTORY_ABI +from .base import SolidlyV2 + + +@dataclass +class ScaleV2(SolidlyV2): + @property + def factory_abi(self): + return SCALE_V2_FACTORY_ABI + + async def get_fee(self, address: str, contract: AsyncContract) -> Tuple[str, float]: + fee = await self.factory_contract.caller.getRealFee(address) + fee_float = float(fee) / 10 ** 18 + return str(fee_float), fee_float diff --git a/fastlane_bot/events/exchanges/solidly_v2/velocimeter_v2.py b/fastlane_bot/events/exchanges/solidly_v2/velocimeter_v2.py new file mode 100644 index 000000000..65634dc5a --- /dev/null +++ b/fastlane_bot/events/exchanges/solidly_v2/velocimeter_v2.py @@ -0,0 +1,19 @@ +from dataclasses import dataclass +from typing import Tuple + +from web3.contract import AsyncContract + +from fastlane_bot.data.abi import VELOCIMETER_V2_FACTORY_ABI +from .base import SolidlyV2 + + +@dataclass +class VelocimeterV2(SolidlyV2): + @property + def factory_abi(self): + return VELOCIMETER_V2_FACTORY_ABI + + async def get_fee(self, address: str, contract: AsyncContract) -> Tuple[str, float]: + fee = await self.factory_contract.caller.getFee(address) + fee_float = float(fee) / 10 ** 4 + return str(fee_float), fee_float diff --git a/fastlane_bot/events/exchanges/solidly_v2/velodrome_v2.py b/fastlane_bot/events/exchanges/solidly_v2/velodrome_v2.py new file mode 100644 index 000000000..27dc61bd4 --- /dev/null +++ b/fastlane_bot/events/exchanges/solidly_v2/velodrome_v2.py @@ -0,0 +1,22 @@ +from dataclasses import dataclass +from typing import Tuple + +from web3.contract import AsyncContract + +from fastlane_bot.data.abi import SOLIDLY_V2_FACTORY_ABI +from .base import SolidlyV2 + + +@dataclass +class VelodromeV2(SolidlyV2): + @property + def factory_abi(self): + return SOLIDLY_V2_FACTORY_ABI + + async def get_fee(self, address: str, contract: AsyncContract) -> Tuple[str, float]: + fee = await self.factory_contract.caller.getFee(address, await contract.caller.stable()) + fee_float = float(fee) / 10 ** 4 + return str(fee_float), fee_float + + def get_pool_func_call(self, addr1, addr2): + return self.factory_contract.functions.getPool(addr1, addr2, False) diff --git a/fastlane_bot/events/exchanges/solidly_v2/xfai_v0.py b/fastlane_bot/events/exchanges/solidly_v2/xfai_v0.py new file mode 100644 index 000000000..2b40d98d3 --- /dev/null +++ b/fastlane_bot/events/exchanges/solidly_v2/xfai_v0.py @@ -0,0 +1,33 @@ +from dataclasses import dataclass +from typing import Any, Tuple + +from web3.contract import Contract, AsyncContract + +from fastlane_bot.data.abi import XFAI_V0_POOL_ABI, XFAI_V0_FACTORY_ABI +from .base import SolidlyV2 + + +@dataclass +class XFaiV2(SolidlyV2): + def get_abi(self): + return XFAI_V0_POOL_ABI + + async def get_tkn0(self, address: str, contract: Contract, event: Any) -> str: + return await contract.caller.poolToken() + + async def get_tkn1(self, address: str, contract: Contract, event: Any) -> str: + return "0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f" # TODO Use the constant WRAPPED_GAS_TOKEN_ADDRESS for this network + + @property + def factory_abi(self): # TODO: change to staticmethod + return XFAI_V0_FACTORY_ABI + + async def get_fee(self, address: str, contract: AsyncContract) -> Tuple[str, float]: + core_address = self.factory_contract.w3.to_checksum_address(await self.factory_contract.caller.getXfaiCore()) + core_contract = self.factory_contract.w3.eth.contract(address=core_address, abi=self.get_abi()) + fee = await core_contract.caller.getTotalFee() + fee_float = float(fee) / 10 ** 4 + return str(fee_float), fee_float + + def get_pool_func_call(self, addr1, addr2): + return self.factory_contract.functions.getPool(addr1) diff --git a/fastlane_bot/events/exchanges/uniswap_v2.py b/fastlane_bot/events/exchanges/uniswap_v2.py index 198ce4a2f..3fb5b902d 100644 --- a/fastlane_bot/events/exchanges/uniswap_v2.py +++ b/fastlane_bot/events/exchanges/uniswap_v2.py @@ -12,13 +12,15 @@ Licensed under MIT. """ from dataclasses import dataclass -from typing import List, Type, Tuple, Any +from typing import List, Type, Tuple, Any, Union +from web3 import Web3, AsyncWeb3 from web3.contract import Contract, AsyncContract from fastlane_bot.data.abi import UNISWAP_V2_POOL_ABI, UNISWAP_V2_FACTORY_ABI -from fastlane_bot.events.exchanges.base import Exchange -from fastlane_bot.events.pools.base import Pool +from ..exchanges.base import Exchange +from ..pools.base import Pool +from ..interfaces.subscription import Subscription @dataclass @@ -31,13 +33,12 @@ class UniswapV2(Exchange): fee: str = None router_address: str = None exchange_initialized: bool = False - @property def fee_float(self): return float(self.fee) @property - def get_factory_abi(self): + def factory_abi(self): return UNISWAP_V2_FACTORY_ABI def add_pool(self, pool: Pool): @@ -49,6 +50,10 @@ def get_abi(self): def get_events(self, contract: Contract) -> List[Type[Contract]]: return [contract.events.Sync] if self.exchange_initialized else [] + def get_subscriptions(self, w3: Union[Web3, AsyncWeb3]) -> List[Subscription]: + contract = self.get_event_contract(w3) + return [Subscription(contract.events.Sync)] + async def get_fee(self, address: str, contract: AsyncContract) -> Tuple[str, float]: return self.fee, self.fee_float @@ -59,3 +64,6 @@ async def get_tkn0(address: str, contract: AsyncContract, event: Any) -> str: @staticmethod async def get_tkn1(address: str, contract: AsyncContract, event: Any) -> str: return await contract.caller.token1() + + def get_pool_func_call(self, addr1, addr2): + return self.factory_contract.functions.getPair(addr1, addr2) diff --git a/fastlane_bot/events/exchanges/uniswap_v3.py b/fastlane_bot/events/exchanges/uniswap_v3.py index 97870bf68..6a478faf6 100644 --- a/fastlane_bot/events/exchanges/uniswap_v3.py +++ b/fastlane_bot/events/exchanges/uniswap_v3.py @@ -12,14 +12,16 @@ Licensed under MIT. """ from dataclasses import dataclass -from typing import List, Type, Tuple, Any +from typing import List, Type, Tuple, Any, Union +from web3 import Web3, AsyncWeb3 from web3.contract import Contract from fastlane_bot.config.constants import AGNI_V3_NAME, PANCAKESWAP_V3_NAME, FUSIONX_V3_NAME, ECHODEX_V3_NAME, SECTA_V3_NAME from fastlane_bot.data.abi import UNISWAP_V3_POOL_ABI, UNISWAP_V3_FACTORY_ABI, PANCAKESWAP_V3_POOL_ABI -from fastlane_bot.events.exchanges.base import Exchange -from fastlane_bot.events.pools.base import Pool +from ..exchanges.base import Exchange +from ..pools.base import Pool +from ..interfaces.subscription import Subscription @dataclass @@ -39,12 +41,16 @@ def get_abi(self): return UNISWAP_V3_POOL_ABI if self.exchange_name not in [PANCAKESWAP_V3_NAME, AGNI_V3_NAME, FUSIONX_V3_NAME, ECHODEX_V3_NAME, SECTA_V3_NAME] else PANCAKESWAP_V3_POOL_ABI @property - def get_factory_abi(self): + def factory_abi(self): return UNISWAP_V3_FACTORY_ABI def get_events(self, contract: Contract) -> List[Type[Contract]]: return [contract.events.Swap] if self.exchange_initialized else [] + def get_subscriptions(self, w3: Union[Web3, AsyncWeb3]) -> List[Subscription]: + contract = self.get_event_contract(w3) + return [Subscription(contract.events.Swap)] + async def get_fee(self, address: str, contract: Contract) -> Tuple[str, float]: fee = await contract.caller.fee() fee_float = float(fee) / 1e6 @@ -55,3 +61,6 @@ async def get_tkn0(self, address: str, contract: Contract, event: Any) -> str: async def get_tkn1(self, address: str, contract: Contract, event: Any) -> str: return await contract.caller.token1() + + def get_pool_func_call(self, addr1, addr2, fee): + return self.factory_contract.functions.getPool(addr1, addr2, fee) diff --git a/fastlane_bot/events/interface.py b/fastlane_bot/events/interface.py index cc7ab2888..1672cfafc 100644 --- a/fastlane_bot/events/interface.py +++ b/fastlane_bot/events/interface.py @@ -492,9 +492,8 @@ def get_tokens(self) -> List[Token]: token_set.add(self.create_token(record, f"tkn{str(idx)}_")) except AttributeError: pass - if self.ConfigObj.GAS_TKN_IN_FLASHLOAN_TOKENS: - token_set.add(Token(symbol=self.ConfigObj.NATIVE_GAS_TOKEN_SYMBOL, address=self.ConfigObj.NATIVE_GAS_TOKEN_ADDRESS, decimals=18)) - token_set.add(Token(symbol=self.ConfigObj.WRAPPED_GAS_TOKEN_SYMBOL, address=self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS, decimals=18)) + token_set.add(Token(symbol=self.ConfigObj.NATIVE_GAS_TOKEN_SYMBOL, address=self.ConfigObj.NATIVE_GAS_TOKEN_ADDRESS, decimals=18)) + token_set.add(Token(symbol=self.ConfigObj.WRAPPED_GAS_TOKEN_SYMBOL, address=self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS, decimals=18)) return list(token_set) def populate_tokens(self): @@ -509,11 +508,11 @@ def populate_tokens(self): self.token_list[token.address] = token except AttributeError: pass - if self.ConfigObj.GAS_TKN_IN_FLASHLOAN_TOKENS: - native_gas_tkn = Token(symbol=self.ConfigObj.NATIVE_GAS_TOKEN_SYMBOL, address=self.ConfigObj.NATIVE_GAS_TOKEN_ADDRESS, decimals=18) - wrapped_gas_tkn = Token(symbol=self.ConfigObj.WRAPPED_GAS_TOKEN_SYMBOL, address=self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS, decimals=18) - self.token_list[native_gas_tkn.address] = native_gas_tkn - self.token_list[wrapped_gas_tkn.address] = wrapped_gas_tkn + # native and wrapped gas token info populated everytime + native_gas_tkn = Token(symbol=self.ConfigObj.NATIVE_GAS_TOKEN_SYMBOL, address=self.ConfigObj.NATIVE_GAS_TOKEN_ADDRESS, decimals=18) + wrapped_gas_tkn = Token(symbol=self.ConfigObj.WRAPPED_GAS_TOKEN_SYMBOL, address=self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS, decimals=18) + self.token_list[native_gas_tkn.address] = native_gas_tkn + self.token_list[wrapped_gas_tkn.address] = wrapped_gas_tkn def create_token(self, record: Dict[str, Any], prefix: str) -> Token: """ diff --git a/fastlane_bot/events/interfaces/event.py b/fastlane_bot/events/interfaces/event.py new file mode 100644 index 000000000..5687f3079 --- /dev/null +++ b/fastlane_bot/events/interfaces/event.py @@ -0,0 +1,27 @@ +from dataclasses import dataclass +from typing import Any, Dict, Optional + + +@dataclass +class Event: + args: Dict[str, Any] + event: str + log_index: Optional[int] + transaction_index: Optional[int] + transaction_hash: Optional[str] + address: Optional[str] + block_hash: Optional[str] + block_number: Optional[int] + + @classmethod + def from_dict(cls, data): + return cls( + args=data["args"], + event=data["event"], + log_index=data.get("logIndex", None), + transaction_index=data.get("transactionIndex", None), + transaction_hash=data.get("transactionHash", None), + address=data.get("address", None), + block_hash=data.get("blockHash", None), + block_number=data.get("blockNumber", None), + ) diff --git a/fastlane_bot/events/interfaces/subscription.py b/fastlane_bot/events/interfaces/subscription.py new file mode 100644 index 000000000..7a178fe20 --- /dev/null +++ b/fastlane_bot/events/interfaces/subscription.py @@ -0,0 +1,45 @@ +from typing import Optional + +from web3 import AsyncWeb3, Web3 +from web3.contract.contract import ContractEvent + +from ..utils import complex_handler +from .event import Event + + +def _get_event_topic(event): + abi = event().abi + topic = Web3.keccak(text=f'{abi["name"]}({",".join([arg["type"] for arg in abi["inputs"]])})') + return topic.hex() + + +class Subscription: + def __init__(self, event: ContractEvent, topic: Optional[str] = None, collect_all: bool = False): + self._event = event + self._topic = _get_event_topic(event) if topic is None else topic + self._collect_all = collect_all + self._subscription_id = None + self._latest_event_index = (-1, -1) # (block_number, block_index) + + async def subscribe(self, w3: AsyncWeb3): + self._subscription_id = await w3.eth.subscribe("logs", {"topics": [self._topic]}) + + @property + def subscription_id(self): + return self._subscription_id + + @property + def topic(self): + return self._topic + + @property + def collect_all(self): + return self._collect_all + + def parse_log(self, log) -> Event: + try: + event_data = complex_handler(self._event().process_log(log)) + except: + print(log) + raise + return Event.from_dict(event_data) diff --git a/fastlane_bot/events/managers/base.py b/fastlane_bot/events/managers/base.py index b76a2d592..ca6361fbd 100644 --- a/fastlane_bot/events/managers/base.py +++ b/fastlane_bot/events/managers/base.py @@ -17,12 +17,13 @@ from fastlane_bot import Config from fastlane_bot.config.constants import PANCAKESWAP_V2_NAME, PANCAKESWAP_V3_NAME, VELOCIMETER_V2_NAME, AGNI_V3_NAME, \ - SOLIDLY_V2_NAME, FUSIONX_V3_NAME + FUSIONX_V3_NAME from fastlane_bot.config.multicaller import MultiCaller from fastlane_bot.events.exchanges import exchange_factory from fastlane_bot.events.exchanges.base import Exchange from fastlane_bot.events.pools.utils import get_pool_cid from fastlane_bot.events.pools import pool_factory +from ..interfaces.event import Event @dataclass @@ -77,7 +78,6 @@ class BaseManager: token_contracts: Dict[str, Contract or Type[Contract]] = field(default_factory=dict) erc20_contracts: Dict[str, Contract or Type[Contract]] = field(default_factory=dict) exchanges: Dict[str, Exchange] = field(default_factory=dict) - factory_contracts: Dict[str, Contract or Type[Contract]] = field(default_factory=dict) uniswap_v2_event_mappings: Dict[str, str] = field(default_factory=dict) uniswap_v3_event_mappings: Dict[str, str] = field(default_factory=dict) solidly_v2_event_mappings: Dict[str, str] = field(default_factory=dict) @@ -128,26 +128,11 @@ def __post_init__(self): self.SUPPORTED_BASE_EXCHANGES.append(base_exchange_name) self.exchanges[exchange_name] = exchange_factory.get_exchange(key=exchange_name, cfg=self.cfg, exchange_initialized=initialize_events) - if base_exchange_name in SOLIDLY_V2_NAME: - self.exchanges[exchange_name] = self.handle_solidly_exchanges(exchange=self.exchanges[exchange_name]) self.init_exchange_contracts() self.set_carbon_v1_fee_pairs() self.init_tenderly_event_contracts() - def handle_solidly_exchanges(self, exchange): - """ - Handles getting stable & volatile fees for Solidly forks - """ - exchange_name = exchange.exchange_name - self.factory_contracts[exchange_name] = self.w3_async.eth.contract( - address=self.cfg.FACTORY_MAPPING[exchange_name], - abi=exchange.get_factory_abi, - ) - exchange.factory_contract = self.factory_contracts[exchange.exchange_name] - - return exchange - @property def fee_pairs(self) -> Dict: """ @@ -203,14 +188,14 @@ def set_carbon_v1_fee_pairs(self): self._fee_pairs[ex] = fee_pairs def get_fee_pairs( - self, all_pairs: List[Tuple[str, str, int, int]], carbon_controller: Contract + self, all_pairs: List[Tuple[str, str]], carbon_controller: Contract ) -> Dict[Tuple[str, str], int]: """ Get the fees for each pair and store in a dictionary. Parameters ---------- - all_pairs : List[Tuple] + all_pairs : List[Tuple[str, str]] A list of pairs. carbon_controller : Contract The CarbonController contract object. @@ -241,13 +226,13 @@ def get_fee_pairs( ) return fee_pairs - def exchange_name_from_event(self, event: Dict[str, Any]) -> str: + def exchange_name_from_event(self, event: Event) -> str: """ Get the exchange name from the event. Parameters ---------- - event : Dict[str, Any] + event : Event The event. Returns @@ -255,8 +240,8 @@ def exchange_name_from_event(self, event: Dict[str, Any]) -> str: str The exchange name. """ - if 'id' in event['args']: - carbon_controller_address = event['address'] + if 'id' in event.args: + carbon_controller_address = event.address for ex in self.cfg.CARBON_CONTROLLER_MAPPING: if self.cfg.CARBON_CONTROLLER_MAPPING[ex] == carbon_controller_address: return ex @@ -270,7 +255,7 @@ def exchange_name_from_event(self, event: Dict[str, Any]) -> str: return None def check_forked_exchange_names( - self, exchange_name_default: str = None, address: str = None, event: Any = None + self, exchange_name_default: str = None, address: str = None, event: Event = None ) -> str: """ Check the forked exchange names. If the exchange name is forked (Sushiswap from UniswapV2, etc) return the @@ -282,7 +267,7 @@ def check_forked_exchange_names( The default exchange name. address : str, optional The address. - event : Any, optional + event : Event, optional The event. Returns @@ -408,7 +393,7 @@ def update_carbon(self, current_block: int, exchange_name: str): def get_carbon_pairs( self, carbon_controller: Contract, exchange_name: str, target_tokens: List[str] = None - ) -> List[Tuple[str, str, int, int]]: + ) -> List[Tuple[str, str]]: """ Get the carbon pairs. @@ -423,7 +408,7 @@ def get_carbon_pairs( Returns ------- - List[Tuple[str, str, int, int]] + List[Tuple[str, str]] The carbon pairs. """ @@ -444,7 +429,7 @@ def get_carbon_pairs( if pair[1] not in target_tokens: target_tokens.append(pair[1]) return [ - (pair[0], pair[1], 0, 5000) + pair for pair in pairs if pair[0] in target_tokens and pair[1] in target_tokens ] @@ -523,7 +508,7 @@ def create_or_get_carbon_controller(self, exchange_name: str): def get_strats_by_contract( self, - pairs: List[Tuple[str, str, int, int]], + pairs: List[Tuple[str, str]], carbon_controller: Contract, exchange_name: str, ) -> List[List[Any]]: @@ -532,7 +517,7 @@ def get_strats_by_contract( Parameters ---------- - pairs : List[Tuple[str, str, int, int]] + pairs : List[Tuple[str, str]] The pairs. carbon_controller : Contract The CarbonController contract object. @@ -545,29 +530,17 @@ def get_strats_by_contract( The strategies. """ - multicaller = MultiCaller( - contract=carbon_controller, - block_identifier=self.replay_from_block or "latest", - multicall_address=self.cfg.MULTICALL_CONTRACT_ADDRESS, - web3=self.web3 - ) + multicaller = MultiCaller(self.web3, self.cfg.MULTICALL_CONTRACT_ADDRESS) - with multicaller as mc: - for pair in pairs: - try: - # Loading the strategies for each pair without executing the calls yet - mc.add_call( - carbon_controller.functions.strategiesByPair, - pair[0], - pair[1], - pair[2], - pair[3], - ) - except ValueError: - print(f"Error fetching strategiesByPair {pair}") - - # Fetch strategies for each pair from the CarbonController contract object - strategies_by_pair = mc.multicall() + for pair in pairs: + # Loading the strategies for each pair without executing the calls yet + multicaller.add_call(carbon_controller.functions.strategiesByPair(*pair, 0, 5000)) + + # Fetch strategies for each pair from the CarbonController contract object + strategies_by_pair = multicaller.run_calls(self.replay_from_block or "latest") + + # Assert that all results are valid + assert all(result is not None for result in strategies_by_pair) self.carbon_inititalized[exchange_name] = True @@ -578,7 +551,7 @@ def get_strats_by_contract( self.cfg.logger.debug( f"[events.managers.base] Retrieved {len(strategies_by_pair)} {exchange_name} strategies" ) - return [s for strat in strategies_by_pair if strat for s in strat if s] + return [strategy for strategies in strategies_by_pair for strategy in strategies] def get_strats_by_state(self, pairs: List[List[Any]], exchange_name: str) -> List[List[int]]: """ @@ -586,7 +559,7 @@ def get_strats_by_state(self, pairs: List[List[Any]], exchange_name: str) -> Lis Parameters ---------- - pairs : List[Tuple[str, str, int, int]] + pairs : List[Tuple[str, str]] The pairs. exchange_name : str The carbon exchange/fork name. @@ -635,14 +608,14 @@ def get_strats_by_state(self, pairs: List[List[Any]], exchange_name: str) -> Lis return strategies def get_strategies( - self, pairs: List[Tuple[str, str, int, int]], carbon_controller: Contract, exchange_name: str + self, pairs: List[Tuple[str, str]], carbon_controller: Contract, exchange_name: str ) -> List[List[str]]: """ Get the strategies. Parameters ---------- - pairs : List[Tuple[str, str, int, int]] + pairs : List[Tuple[str, str]] The pairs. carbon_controller : Contract The CarbonController contract object. @@ -685,20 +658,17 @@ def get_fees_by_pair( The fees by pair. """ - multicaller = MultiCaller( - contract=carbon_controller, - block_identifier=self.replay_from_block or "latest", - multicall_address=self.cfg.MULTICALL_CONTRACT_ADDRESS, - web3=self.web3 - ) + multicaller = MultiCaller(self.web3, self.cfg.MULTICALL_CONTRACT_ADDRESS) - with multicaller as mc: - for pair in all_pairs: - mc.add_call( - carbon_controller.functions.pairTradingFeePPM, pair[0], pair[1] - ) + for pair in all_pairs: + multicaller.add_call(carbon_controller.functions.pairTradingFeePPM(*pair)) + + fees_by_pair = multicaller.run_calls(self.replay_from_block or "latest") + + # Assert that all results are valid + assert all(result is not None for result in fees_by_pair) - return multicaller.multicall() + return fees_by_pair def get_tkn_symbol_and_decimals( self, web3: Web3, erc20_contracts: Dict[str, Contract], cfg: Config, addr: str @@ -793,11 +763,11 @@ def validate_pool_info( if key != "strategy_id" and (pool_info is None or not pool_info): # Uses method in ContractsManager.add_pool_info_from_contract class to get pool info from contract pool_info = self.add_pool_info_from_contract( - address=addr, event=event, block_number=event["blockNumber"] + address=addr, event=event, block_number=event.block_number ) # if addr in self.cfg.CARBON_CONTROLLER_MAPPING: - # cid = event["args"]["id"] if event is not None else pool_info["strategy_id"] + # cid = event.args["id"] if event is not None else pool_info["strategy_id"] # # for pool in self.pool_data: # if pool["cid"] == cid: @@ -810,14 +780,14 @@ def validate_pool_info( return pool_info def get_key_and_value( - self, event: Dict[str, Any], addr: str, ex_name: str + self, event: Event, addr: str, ex_name: str ) -> Tuple[str, Any]: """ Get the key and value. Parameters ---------- - event : Dict[str, Any] + event : Event The event. addr : str The address. @@ -831,38 +801,38 @@ def get_key_and_value( """ if ex_name == "bancor_pol": - return "token", event["args"]["token"] + return "token", event.args["token"] if ex_name in self.cfg.CARBON_V1_FORKS: - info = {'exchange_name': ex_name, 'strategy_id': event["args"]["id"]} + info = {'exchange_name': ex_name, 'strategy_id': event.args["id"]} return "cid", get_pool_cid(info, self.cfg.CARBON_V1_FORKS) if ex_name in self.cfg.ALL_FORK_NAMES_WITHOUT_CARBON: return "address", addr if ex_name == "bancor_v2": return ("tkn0_address", "tkn1_address"), ( - event["args"]["_token1"], - event["args"]["_token2"], + event.args["_token1"], + event.args["_token2"], ) if ex_name == "bancor_v3": value = ( - event["args"]["tkn_address"] - if event["args"]["tkn_address"] != self.cfg.BNT_ADDRESS - else event["args"]["pool"] + event.args["tkn_address"] + if event.args["tkn_address"] != self.cfg.BNT_ADDRESS + else event.args["pool"] ) return "tkn1_address", value raise ValueError( f"[managers.base.get_key_and_value] Exchange {ex_name} not supported" ) - def handle_strategy_deleted(self, event: Dict[str, Any]) -> None: + def handle_strategy_deleted(self, event: Event) -> None: """ Handle the strategy deleted event. Parameters ---------- - event : Dict[str, Any] + event : Event The event. """ - strategy_id = event["args"]["id"] + strategy_id = event.args["id"] exchange_name = self.exchange_name_from_event(event) cids = [p["cid"] for p in self.pool_data if p["strategy_id"] == strategy_id and p["exchange_name"] == exchange_name] @@ -901,13 +871,13 @@ def pool_key_value_from_event(key: str, event: Dict[str, Any]) -> Any: The pool key value. """ if key == "cid": - return event["args"]["id"] + return event.args["id"] elif key == "address": - return event["address"] + return event.address elif key == "tkn0_address": - return event["args"]["token0"] + return event.args["token0"] elif key == "tkn1_address": - return event["args"]["token1"] + return event.args["token1"] print_events = [] diff --git a/fastlane_bot/events/managers/contracts.py b/fastlane_bot/events/managers/contracts.py index 03a4cd0c1..1355d4ba9 100644 --- a/fastlane_bot/events/managers/contracts.py +++ b/fastlane_bot/events/managers/contracts.py @@ -28,6 +28,7 @@ ) from fastlane_bot.events.managers.base import BaseManager from fastlane_bot.events.pools.utils import get_pool_cid +from ..interfaces.event import Event class ContractsManager(BaseManager): @@ -203,7 +204,7 @@ def add_pool_info_from_contract( self, exchange_name: str = None, address: str = None, - event: Any = None, + event: Event = None, tenderly_exchanges: List[str] = None, ) -> Dict[str, Any]: """ @@ -244,8 +245,8 @@ def add_pool_info_from_contract( t0_addr = self.exchanges[exchange_name].get_tkn0(address, pool_contract, event) t1_addr = self.exchanges[exchange_name].get_tkn1(address, pool_contract, event) - block_number = event["blockNumber"] - strategy_id = event["args"]["id"] if exchange_name in self.cfg.CARBON_V1_FORKS else None + block_number = event.block_number + strategy_id = event.args["id"] if exchange_name in self.cfg.CARBON_V1_FORKS else None temp_pool_info = { "exchange_name": exchange_name, "fee": f"{fee}", diff --git a/fastlane_bot/events/managers/manager.py b/fastlane_bot/events/managers/manager.py index cf98a614e..7b80e66f6 100644 --- a/fastlane_bot/events/managers/manager.py +++ b/fastlane_bot/events/managers/manager.py @@ -18,33 +18,33 @@ from fastlane_bot.events.managers.contracts import ContractsManager from fastlane_bot.events.managers.events import EventManager from fastlane_bot.events.managers.pools import PoolManager -from fastlane_bot.events.pools.utils import get_pool_cid +from ..interfaces.event import Event class Manager(PoolManager, EventManager, ContractsManager): - def update_from_event(self, event: Dict[str, Any]): + def update_from_event(self, event: Event): """ Updates the state of the pool data from an event. StrategyCreated and StrategyUpdated events are handled as the "default" event types to process. Args: - event (Dict[str, Any]): The event to process. + event (Event): The event to process. """ ex_name = self.exchange_name_from_event(event) - if event["event"] in ["TradingFeePPMUpdated", "PairTradingFeePPMUpdated"]: + if event.event in ["TradingFeePPMUpdated", "PairTradingFeePPMUpdated"]: self.handle_trading_fee_updated() return - if event["event"] == "PairCreated": + if event.event == "PairCreated": self.set_carbon_v1_fee_pairs() return - if event["event"] == "StrategyDeleted": + if event.event == "StrategyDeleted": self.handle_strategy_deleted(event) return - addr = self.web3.to_checksum_address(event["address"]) + addr = self.web3.to_checksum_address(event.address) if not ex_name: return @@ -63,9 +63,7 @@ def update_from_event(self, event: Dict[str, Any]): pool_info["descr"] = self.pool_descr_from_info(pool_info) pool = self.get_or_init_pool(pool_info) - data = pool.update_from_event( - event or {}, pool.get_common_data(event, pool_info) - ) + data = pool.update_from_event(event, pool.get_common_data(event, pool_info)) self.update_pool_data(pool_info, data) def update_from_pool_info( @@ -166,18 +164,18 @@ def update( def handle_pair_trading_fee_updated( self, - event: Dict[str, Any] = None, + event: Event = None, ): """ Handle the pair trading fee updated event by updating the fee pairs and pool info for the given pair. Parameters ---------- - event : Dict[str, Any], optional + event : Event, optional The event, by default None. """ - tkn0_address = event["args"]["token0"] - tkn1_address = event["args"]["token1"] + tkn0_address = event.args["token0"] + tkn1_address = event.args["token1"] for exchange_name in self.cfg.CARBON_V1_FORKS: if exchange_name in self.exchanges: @@ -250,7 +248,7 @@ def update_remaining_pools(self): remaining_pools = [] all_events = [pool[2] for pool in self.pools_to_add_from_contracts] for event in all_events: - addr = self.web3.to_checksum_address(event["address"]) + addr = self.web3.to_checksum_address(event.address) ex_name = self.exchange_name_from_event(event) if not ex_name: self.cfg.logger.warning("[update_remaining_pools] ex_name not found from event") diff --git a/fastlane_bot/events/multicall_utils.py b/fastlane_bot/events/multicall_utils.py index b88147dd7..ba56f62f7 100644 --- a/fastlane_bot/events/multicall_utils.py +++ b/fastlane_bot/events/multicall_utils.py @@ -12,10 +12,7 @@ from typing import Dict, Any from typing import List, Tuple -import web3.exceptions - from fastlane_bot.config.multicaller import MultiCaller -from fastlane_bot.data.abi import ERC20_ABI from fastlane_bot.events.pools import CarbonV1Pool from fastlane_bot.events.pools.base import Pool @@ -99,7 +96,7 @@ def encode_token_price(price: Decimal) -> int: return encode_float(encode_rate((price))) -def get_pools_for_exchange(exchange: str, mgr: Any) -> [Any]: +def get_pools_for_exchange(exchange: str, mgr: Any) -> List[Any]: """ Handles the initial iteration of the bot. @@ -122,7 +119,7 @@ def get_pools_for_exchange(exchange: str, mgr: Any) -> [Any]: ] -def multicall_helper(exchange: str, rows_to_update: List, multicall_contract: Any, mgr: Any, current_block: int): +def multicall_helper(exchange: str, rows_to_update: List, target_contract: Any, mgr: Any, current_block: int): """ Helper function for multicall. @@ -132,79 +129,47 @@ def multicall_helper(exchange: str, rows_to_update: List, multicall_contract: An Name of the exchange. rows_to_update : List List of rows to update. - multicall_contract : Any - The multicall contract. + target_contract : Any + The target contract. mgr : Any Manager object containing configuration and pool data. current_block : int The current block. """ - multicaller = MultiCaller(contract=multicall_contract, block_identifier=current_block, web3=mgr.web3, multicall_address=mgr.cfg.MULTICALL_CONTRACT_ADDRESS) - with multicaller as mc: - for row in rows_to_update: - pool_info = mgr.pool_data[row] - pool_info["last_updated_block"] = current_block - # Function to be defined elsewhere based on what each exchange type needs - multicall_fn(exchange, mc, mgr, multicall_contract, pool_info) - result_list = mc.multicall() - process_results_for_multicall(exchange, rows_to_update, result_list, mgr) - - -def multicall_fn(exchange: str, mc: Any, mgr: Any, multicall_contract: Any, pool_info: Dict[str, Any]) -> None: - """ - Function to be defined elsewhere based on what each exchange type needs. + multicaller = MultiCaller(mgr.web3, mgr.cfg.MULTICALL_CONTRACT_ADDRESS) - Parameters - ---------- - exchange : str - Name of the exchange. - mc : Any - The multicaller. - mgr : Any - Manager object containing configuration and pool data. - multicall_contract : Any - The multicall contract. - pool_info : Dict - The pool info. - - """ - if exchange == "bancor_v3": - mc.add_call(multicall_contract.functions.tradingLiquidity, pool_info["tkn1_address"]) - elif exchange == "bancor_pol": - mc.add_call(multicall_contract.functions.tokenPrice, pool_info["tkn0_address"]) - mc.add_call(multicall_contract.functions.amountAvailableForTrading, pool_info["tkn0_address"]) - elif exchange in mgr.cfg.CARBON_V1_FORKS: - mc.add_call(multicall_contract.functions.strategy, pool_info["cid"]) - elif exchange == 'balancer': - mc.add_call(multicall_contract.functions.getPoolTokens, pool_info["anchor"]) + for row in rows_to_update: + pool_info = mgr.pool_data[row] + pool_info["last_updated_block"] = current_block + if exchange == "bancor_v3": + multicaller.add_call(target_contract.functions.tradingLiquidity(pool_info["tkn1_address"])) + elif exchange == "bancor_pol": + multicaller.add_call(target_contract.functions.tokenPrice(pool_info["tkn0_address"])) + multicaller.add_call(target_contract.functions.amountAvailableForTrading(pool_info["tkn0_address"])) + elif exchange in mgr.cfg.CARBON_V1_FORKS: + multicaller.add_call(target_contract.functions.strategy(pool_info["cid"])) + elif exchange == "balancer": + multicaller.add_call(target_contract.functions.getPoolTokens(pool_info["anchor"])) + else: + raise ValueError(f"Exchange {exchange} not supported") + + result_list = multicaller.run_calls(current_block) + + if exchange == "bancor_pol": + # Assert that all `amountAvailableForTrading` results are valid + assert all(result is not None for result in result_list[1::2]) + # Rearrange the results as a list of `(tokenPrice, amountAvailableForTrading)` tuples + result_list = [result for result in zip(result_list[0::2], result_list[1::2])] else: - raise ValueError(f"Exchange {exchange} not supported.") - - -def process_results_for_multicall(exchange: str, rows_to_update: List, result_list: List, mgr: Any) -> None: - """ - Process the results for multicall. + # Assert that all results are valid + assert all(result is not None for result in result_list) - Parameters - ---------- - exchange : str - Name of the exchange. - rows_to_update : List - List of rows to update. - result_list : List - List of results. - mgr : Any - Manager object containing configuration and pool data. - - - """ for row, result in zip(rows_to_update, result_list): pool_info = mgr.pool_data[row] - params = extract_params_for_multicall(exchange, result, pool_info, mgr) pool = mgr.get_or_init_pool(pool_info) - pool, pool_info = update_pool_for_multicall(params, pool_info, pool) - mgr.pool_data[row] = pool_info + params = extract_params_for_multicall(exchange, result, pool_info, mgr) + update_pool_for_multicall(params, pool_info, pool) update_mgr_exchanges_for_multicall(mgr, exchange, pool, pool_info) @@ -224,7 +189,6 @@ def extract_params_for_multicall(exchange: str, result: Any, pool_info: Dict, mg Manager object containing configuration and pool data. """ - params = {} if exchange in mgr.cfg.CARBON_V1_FORKS: strategy = result fake_event = { @@ -237,9 +201,24 @@ def extract_params_for_multicall(exchange: str, result: Any, pool_info: Dict, mg params = CarbonV1Pool.parse_event(pool_info["state"], fake_event, "None") params["exchange_name"] = exchange elif exchange == "bancor_pol": - params = _extract_pol_params_for_multicall( - result, pool_info, mgr - ) + p, tkn_balance = result + token_price = encode_token_price(Decimal(p[1]) / Decimal(p[0])) if p is not None else 0 + params = { + "fee": "0.000", + "fee_float": 0.000, + "tkn0_balance": 0, + "tkn1_balance": 0, + "exchange_name": pool_info["exchange_name"], + "address": pool_info["address"], + "y_0": tkn_balance, + "z_0": tkn_balance, + "A_0": 0, + "B_0": token_price, + "y_1": 0, + "z_1": 0, + "A_1": 0, + "B_1": 0, + } elif exchange == "bancor_v3": pool_balances = result params = { @@ -251,66 +230,20 @@ def extract_params_for_multicall(exchange: str, result: Any, pool_info: Dict, mg "address": pool_info["address"], } elif exchange == "balancer": - pool_balances = result - + tokens, balances, last_change_block = result params = { "exchange_name": exchange, "address": pool_info["address"], } - - for idx, bal in enumerate(pool_balances): - params[f"tkn{str(idx)}_balance"] = int(bal) - + for idx, balance in enumerate(balances): + params[f"tkn{str(idx)}_balance"] = balance else: raise ValueError(f"Exchange {exchange} not supported.") return params -def _extract_pol_params_for_multicall(result: Any, pool_info: Dict, mgr: Any) -> Dict[str, Any]: - """ - Extract the Bancor POL params for multicall. - - Parameters - ---------- - result : Any - The result. - pool_info : Dict - The pool info. - mgr : Any - Manager object containing configuration and pool data. - - Returns - ------- - Dict[str, Any] - The extracted params. - - """ - tkn0_address = pool_info["tkn0_address"] - p0, p1, tkn_balance = result - token_price = Decimal(p1) / Decimal(p0) - token_price = int(str(encode_token_price(token_price))) - - result = { - "fee": "0.000", - "fee_float": 0.000, - "tkn0_balance": 0, - "tkn1_balance": 0, - "exchange_name": pool_info["exchange_name"], - "address": pool_info["address"], - "y_0": tkn_balance, - "z_0": tkn_balance, - "A_0": 0, - "B_0": token_price, - "y_1": 0, - "z_1": 0, - "A_1": 0, - "B_1": 0, - } - return result - - -def update_pool_for_multicall(params: Dict[str, Any], pool_info: Dict, pool: Any) -> Tuple[Pool, Dict]: +def update_pool_for_multicall(params: Dict[str, Any], pool_info: Dict, pool: Any): """ Update the pool for multicall. @@ -323,16 +256,10 @@ def update_pool_for_multicall(params: Dict[str, Any], pool_info: Dict, pool: Any pool : Any The pool. - Returns - ------- - Tuple[Pool, Dict] - The updated pool and pool info. - """ for key, value in params.items(): pool_info[key] = value pool.state[key] = value - return pool, pool_info def update_mgr_exchanges_for_multicall(mgr: Any, exchange: str, pool: Any, pool_info: Dict[str, Any]): @@ -362,9 +289,9 @@ def update_mgr_exchanges_for_multicall(mgr: Any, exchange: str, pool: Any, pool_ mgr.exchanges[exchange].pools[exchange_pool_idx] = pool -def get_multicall_contract_for_exchange(mgr: Any, exchange: str) -> str: +def get_pool_contract_for_exchange(mgr: Any, exchange: str) -> str: """ - Get the multicall contract for the exchange. + Get the pool contract for the exchange. Parameters ---------- @@ -376,7 +303,7 @@ def get_multicall_contract_for_exchange(mgr: Any, exchange: str) -> str: Returns ------- str - The multicall contract for the exchange. + The pool contract for the exchange. """ if exchange == "bancor_v3": @@ -411,6 +338,6 @@ def multicall_every_iteration(current_block: int, mgr: Any): ] for idx, exchange in enumerate(multicallable_exchanges): - multicall_contract = get_multicall_contract_for_exchange(mgr, exchange) + pool_contract = get_pool_contract_for_exchange(mgr, exchange) rows_to_update = multicallable_pool_rows[idx] - multicall_helper(exchange, rows_to_update, multicall_contract, mgr, current_block) + multicall_helper(exchange, rows_to_update, pool_contract, mgr, current_block) diff --git a/fastlane_bot/events/pools/balancer.py b/fastlane_bot/events/pools/balancer.py index 80f894aea..6f8cd4b2b 100644 --- a/fastlane_bot/events/pools/balancer.py +++ b/fastlane_bot/events/pools/balancer.py @@ -15,7 +15,7 @@ from web3.contract import Contract from .base import Pool -from fastlane_bot import Config +from ..interfaces.event import Event @dataclass @@ -46,7 +46,7 @@ def event_matches_format( return False def update_from_event( - self, event_args: Dict[str, Any], data: Dict[str, Any] + self, event: Event, data: Dict[str, Any] ) -> Dict[str, Any]: """ See base class. diff --git a/fastlane_bot/events/pools/bancor_pol.py b/fastlane_bot/events/pools/bancor_pol.py index 12acc7b95..15091e159 100644 --- a/fastlane_bot/events/pools/bancor_pol.py +++ b/fastlane_bot/events/pools/bancor_pol.py @@ -18,6 +18,7 @@ from fastlane_bot.data.abi import ERC20_ABI, BANCOR_POL_ABI from fastlane_bot.events.pools.base import Pool +from ..interfaces.event import Event from _decimal import Decimal @@ -41,14 +42,14 @@ def unique_key() -> str: @classmethod def event_matches_format( - cls, event: Dict[str, Any], static_pools: Dict[str, Any], exchange_name: str = None + cls, event: Event, static_pools: Dict[str, Any], exchange_name: str = None ) -> bool: """ Check if an event matches the format of a Bancor pol event. Parameters ---------- - event : Dict[str, Any] + event : Event The event arguments. Returns @@ -57,11 +58,11 @@ def event_matches_format( True if the event matches the format of a Bancor v3 event, False otherwise. """ - event_args = event["args"] - return "token" in event_args and "token0" not in event_args + event_args = event.args + return ("token" in event_args) and ("token0" not in event_args) and (event_args['token'] == "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE") def update_from_event( - self, event_args: Dict[str, Any], data: Dict[str, Any] + self, event: Event, data: Dict[str, Any] ) -> Dict[str, Any]: """ This updates the pool balance from TokenTraded events. @@ -69,12 +70,12 @@ def update_from_event( See base class. """ - event_type = event_args["event"] + event_type = event.event if event_type in "TradingEnabled": - data["tkn0_address"] = event_args["args"]["token"] - data["tkn1_address"] = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" if event_args["args"]["token"] not in "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" else "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C" + data["tkn0_address"] = event.args["token"] + data["tkn1_address"] = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" if event.args["token"] not in "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" else "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C" - if event_args["args"]["token"] == self.state["tkn0_address"] and event_type in [ + if event.args["token"] == self.state["tkn0_address"] and event_type in [ "TokenTraded" ]: # *** Balance now updated from multicall *** diff --git a/fastlane_bot/events/pools/bancor_v2.py b/fastlane_bot/events/pools/bancor_v2.py index 68068bea7..b0f993418 100644 --- a/fastlane_bot/events/pools/bancor_v2.py +++ b/fastlane_bot/events/pools/bancor_v2.py @@ -15,6 +15,7 @@ from web3.contract import Contract from fastlane_bot.events.pools.base import Pool +from ..interfaces.event import Event @dataclass @@ -34,14 +35,14 @@ def unique_key() -> str: @classmethod def event_matches_format( - cls, event: Dict[str, Any], static_pools: Dict[str, Any], exchange_name: str = None + cls, event: Event, static_pools: Dict[str, Any], exchange_name: str = None ) -> bool: """ Check if an event matches the format of a Bancor v2 event. Parameters ---------- - event : Dict[str, Any] + event : Event The event arguments. Returns @@ -50,21 +51,21 @@ def event_matches_format( True if the event matches the format of a Bancor v3 event, False otherwise. """ - event_args = event["args"] + event_args = event.args return "_rateN" in event_args def update_from_event( - self, event_args: Dict[str, Any], data: Dict[str, Any] + self, event: Event, data: Dict[str, Any] ) -> Dict[str, Any]: """ **** IMPORTANT **** Bancor V2 pools emit 3 events per trade. Only one of them contains the new token balances we want. The one we want is the one where _token1 and _token2 match the token addresses of the pool. """ - data["tkn0_address"] = event_args["args"]["_token1"] - data["tkn1_address"] = event_args["args"]["_token2"] - data["tkn0_balance"] = event_args["args"]["_rateD"] - data["tkn1_balance"] = event_args["args"]["_rateN"] + data["tkn0_address"] = event.args["_token1"] + data["tkn1_address"] = event.args["_token2"] + data["tkn0_balance"] = event.args["_rateD"] + data["tkn1_balance"] = event.args["_rateN"] for key, value in data.items(): self.state[key] = value diff --git a/fastlane_bot/events/pools/bancor_v3.py b/fastlane_bot/events/pools/bancor_v3.py index 1b2281662..b266a819d 100644 --- a/fastlane_bot/events/pools/bancor_v3.py +++ b/fastlane_bot/events/pools/bancor_v3.py @@ -15,6 +15,7 @@ from web3.contract import Contract from .base import Pool +from ..interfaces.event import Event @dataclass @@ -34,14 +35,14 @@ def unique_key() -> str: @classmethod def event_matches_format( - cls, event: Dict[str, Any], static_pools: Dict[str, Any], exchange_name: str = None + cls, event: Event, static_pools: Dict[str, Any], exchange_name: str = None ) -> bool: """ Check if an event matches the format of a Bancor v3 event. Parameters ---------- - event : Dict[str, Any] + event : Event The event arguments. Returns @@ -50,20 +51,19 @@ def event_matches_format( True if the event matches the format of a Bancor v3 event, False otherwise. """ - event_args = event["args"] + event_args = event.args return "pool" in event_args def update_from_event( - self, event_args: Dict[str, Any], data: Dict[str, Any] + self, event: Event, data: Dict[str, Any] ) -> Dict[str, Any]: """ See base class. """ - event_args = event_args["args"] - if event_args["tkn_address"] == "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C": - data["tkn0_balance"] = event_args["newLiquidity"] + if event.args["tkn_address"] == "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C": + data["tkn0_balance"] = event.args["newLiquidity"] else: - data["tkn1_balance"] = event_args["newLiquidity"] + data["tkn1_balance"] = event.args["newLiquidity"] for key, value in data.items(): self.state[key] = value diff --git a/fastlane_bot/events/pools/base.py b/fastlane_bot/events/pools/base.py index e7f5870bb..a220ce3fd 100644 --- a/fastlane_bot/events/pools/base.py +++ b/fastlane_bot/events/pools/base.py @@ -18,6 +18,8 @@ from web3 import Web3 from web3.contract import Contract +from ..interfaces.event import Event + @dataclass class Pool(ABC): @@ -34,7 +36,7 @@ class Pool(ABC): __DATE__ = "2023-07-03" state: Dict[str, Any] = field(default_factory=dict) - + factory_contract = None @classmethod @abstractmethod def event_matches_format( @@ -61,37 +63,37 @@ def event_matches_format( @staticmethod def get_common_data( - event: Dict[str, Any], pool_info: Dict[str, Any] + event: Event, pool_info: Dict[str, Any] ) -> Dict[str, Any]: """ Get common (common to all Pool child classes) data from an event and pool info. Args: - event (Dict[str, Any]): The event data. + event (Event): The event data. pool_info (Dict[str, Any]): The pool information. Returns: Dict[str, Any]: A dictionary containing common data extracted from the event and pool info. """ return { - "last_updated_block": event["blockNumber"], + "last_updated_block": event.block_number, "timestamp": datetime.now().strftime("%H:%M:%S"), "pair_name": pool_info["pair_name"], "descr": pool_info["descr"], - "address": event["address"], + "address": event.address, } @staticmethod @abstractmethod def update_from_event( - event_args: Dict[str, Any], data: Dict[str, Any] + event: Event, data: Dict[str, Any] ) -> Dict[str, Any]: """ Update the pool state from an event. Parameters ---------- - event_args : Dict[str, Any] + event : Event The event arguments. data : Dict[str, Any] The pool data. diff --git a/fastlane_bot/events/pools/carbon_v1.py b/fastlane_bot/events/pools/carbon_v1.py index 4d62da546..184b13e83 100644 --- a/fastlane_bot/events/pools/carbon_v1.py +++ b/fastlane_bot/events/pools/carbon_v1.py @@ -15,6 +15,7 @@ from web3.contract import Contract from .base import Pool +from ..interfaces.event import Event from fastlane_bot.events.pools.utils import get_pool_cid @@ -36,34 +37,31 @@ def unique_key() -> str: @classmethod def event_matches_format( - cls, event: Dict[str, Any], static_pools: Dict[str, Any], exchange_name: str = None + cls, event: Event, static_pools: Dict[str, Any], exchange_name: str = None ) -> bool: """ see base class. """ - event_args = event["args"] + event_args = event.args return "order0" in event_args def update_from_event( - self, event_args: Dict[str, Any], data: Dict[str, Any] + self, event: Event, data: Dict[str, Any] ) -> Dict[str, Any]: """ See base class. """ - event_type = event_args["event"] - assert event_type not in ["TradingFeePPMUpdated", "PairTradingFeePPMUpdated"], ( + assert event.event not in ["TradingFeePPMUpdated", "PairTradingFeePPMUpdated"], ( "This event should not be " "handled by this class." ) - data = CarbonV1Pool.parse_event(data, event_args, event_type) + data = CarbonV1Pool.parse_event(data, event) data["router"] = self.router_address for key, value in data.items(): self.state[key] = value return data @staticmethod - def parse_event( - data: Dict[str, Any], event_args: Dict[str, Any], event_type: str - ) -> Dict[str, Any]: + def parse_event(data: Dict[str, Any], event: Event) -> Dict[str, Any]: """ Parse the event args into a dict. @@ -71,18 +69,16 @@ def parse_event( ---------- data : Dict[str, Any] The data to update. - event_args : Dict[str, Any] - The event arguments. - event_type : str - The event type. + event_args : Event + The event object. Returns ------- Dict[str, Any] The updated data. """ - order0, order1 = CarbonV1Pool.parse_orders(event_args, event_type) - data["strategy_id"] = event_args["args"].get("id") + order0, order1 = CarbonV1Pool.parse_orders(event) + data["strategy_id"] = event.args.get("id") if isinstance(order0, list) and isinstance(order1, list): data["y_0"] = order0[0] data["z_0"] = order0[1] @@ -105,9 +101,7 @@ def parse_event( return data @staticmethod - def parse_orders( - event_args: Dict[str, Any], event_type: str - ) -> Tuple[List[int], List[int]]: + def parse_orders(event: Event) -> Tuple[List[int], List[int]]: """ Parse the orders from the event args. If the event type is StrategyDeleted, then the orders are set to 0. @@ -115,17 +109,15 @@ def parse_orders( ---------- event_args : Dict[str, Any] The event arguments. - event_type : str - The event type. Returns ------- Tuple[List[int], List[int]] The parsed orders. """ - if event_type not in ["StrategyDeleted"]: - order0 = event_args["args"].get("order0") - order1 = event_args["args"].get("order1") + if event.event not in ["StrategyDeleted"]: + order0 = event.args.get("order0") + order1 = event.args.get("order1") else: order0 = [0, 0, 0, 0] order1 = [0, 0, 0, 0] diff --git a/fastlane_bot/events/pools/solidly_v2.py b/fastlane_bot/events/pools/solidly_v2.py index 61a1acf03..8ca967a7f 100644 --- a/fastlane_bot/events/pools/solidly_v2.py +++ b/fastlane_bot/events/pools/solidly_v2.py @@ -15,6 +15,7 @@ from web3.contract import Contract from fastlane_bot.events.pools.base import Pool +from ..interfaces.event import Event def _balances_A(contract: Contract) -> List[int]: return contract.caller.getReserves() @@ -88,21 +89,20 @@ def event_matches_format( """ Check if an event matches the format of a Uniswap v2 event. """ - event_args = event["args"] + event_args = event.args return ( "reserve0" in event_args - and event["address"] in static_pools[f"{exchange_name}_pools"] + and event.address in static_pools[f"{exchange_name}_pools"] ) def update_from_event( - self, event_args: Dict[str, Any], data: Dict[str, Any] + self, event: Event, data: Dict[str, Any] ) -> Dict[str, Any]: """ See base class. """ - event_args = event_args["args"] - data["tkn0_balance"] = event_args["reserve0"] - data["tkn1_balance"] = event_args["reserve1"] + data["tkn0_balance"] = event.args["reserve0"] + data["tkn1_balance"] = event.args["reserve1"] for key, value in data.items(): self.state[key] = value diff --git a/fastlane_bot/events/pools/uniswap_v2.py b/fastlane_bot/events/pools/uniswap_v2.py index 55549e89a..c48639f59 100644 --- a/fastlane_bot/events/pools/uniswap_v2.py +++ b/fastlane_bot/events/pools/uniswap_v2.py @@ -15,6 +15,7 @@ from web3.contract import Contract from fastlane_bot.events.pools.base import Pool +from ..interfaces.event import Event @dataclass @@ -41,26 +42,25 @@ def unique_key() -> str: @classmethod def event_matches_format( - cls, event: Dict[str, Any], static_pools: Dict[str, Any], exchange_name: str = None + cls, event: Event, static_pools: Dict[str, Any], exchange_name: str = None ) -> bool: """ Check if an event matches the format of a Uniswap v2 event. """ - event_args = event["args"] + event_args = event.args return ( "reserve0" in event_args - and event["address"] in static_pools[f"{exchange_name}_pools"] + and event.address in static_pools[f"{exchange_name}_pools"] ) def update_from_event( - self, event_args: Dict[str, Any], data: Dict[str, Any] + self, event: Event, data: Dict[str, Any] ) -> Dict[str, Any]: """ See base class. """ - event_args = event_args["args"] - data["tkn0_balance"] = event_args["reserve0"] - data["tkn1_balance"] = event_args["reserve1"] + data["tkn0_balance"] = event.args["reserve0"] + data["tkn1_balance"] = event.args["reserve1"] for key, value in data.items(): self.state[key] = value diff --git a/fastlane_bot/events/pools/uniswap_v3.py b/fastlane_bot/events/pools/uniswap_v3.py index 265c72296..06e67f65f 100644 --- a/fastlane_bot/events/pools/uniswap_v3.py +++ b/fastlane_bot/events/pools/uniswap_v3.py @@ -14,6 +14,7 @@ from web3.contract import Contract from fastlane_bot.events.pools.base import Pool +from ..interfaces.event import Event @dataclass @@ -34,27 +35,26 @@ def unique_key() -> str: @classmethod def event_matches_format( - cls, event: Dict[str, Any], static_pools: Dict[str, Any], exchange_name: str = None + cls, event: Event, static_pools: Dict[str, Any], exchange_name: str = None ) -> bool: """ Check if an event matches the format of a Uniswap v3 event. """ - event_args = event["args"] + event_args = event.args return ( "sqrtPriceX96" in event_args - and event["address"] in static_pools[f"{exchange_name}_pools"] + and event.address in static_pools[f"{exchange_name}_pools"] ) def update_from_event( - self, event_args: Dict[str, Any], data: Dict[str, Any] + self, event: Event, data: Dict[str, Any] ) -> Dict[str, Any]: """ See base class. """ - event_args = event_args["args"] - data["liquidity"] = event_args["liquidity"] - data["sqrt_price_q96"] = event_args["sqrtPriceX96"] - data["tick"] = event_args["tick"] + data["liquidity"] = event.args["liquidity"] + data["sqrt_price_q96"] = event.args["sqrtPriceX96"] + data["tick"] = event.args["tick"] for key, value in data.items(): self.state[key] = value diff --git a/fastlane_bot/events/utils.py b/fastlane_bot/events/utils.py index 468ac82cd..f6b97b1b3 100644 --- a/fastlane_bot/events/utils.py +++ b/fastlane_bot/events/utils.py @@ -31,15 +31,15 @@ from fastlane_bot.data.abi import FAST_LANE_CONTRACT_ABI from fastlane_bot.exceptions import ReadOnlyException from fastlane_bot.events.interface import QueryInterface -from fastlane_bot.events.managers.manager import Manager from fastlane_bot.helpers import TxHelpers from fastlane_bot.utils import safe_int +from .interfaces.event import Event def filter_latest_events( - mgr: Manager, events: List[List[AttributeDict]] -) -> List[AttributeDict]: + mgr: Any, events: List[Event] +) -> List[Event]: """ This function filters out the latest events for each pool. Given a nested list of events, it iterates through all events and keeps track of the latest event (i.e., with the highest block number) for each pool. The key used to identify each pool @@ -54,19 +54,16 @@ def filter_latest_events( List[AttributeDict]: A list of events, each representing the latest event for its corresponding pool. """ latest_entry_per_pool = {} - all_events = [event for event_list in events for event in event_list] # Handles the case where multiple pools are created in the same block - all_events.reverse() + events.reverse() bancor_v2_anchor_addresses = { pool["anchor"] for pool in mgr.pool_data if pool["exchange_name"] == "bancor_v2" } - for event in all_events: - pool_type = mgr.pool_type_from_exchange_name( - mgr.exchange_name_from_event(event) - ) + for event in events: + pool_type = mgr.pool_type_from_exchange_name(mgr.exchange_name_from_event(event)) if pool_type: key = pool_type.unique_key() else: @@ -74,43 +71,33 @@ def filter_latest_events( if key == "cid": key = "id" elif key == "tkn1_address": - if event["args"]["pool"] != mgr.cfg.BNT_ADDRESS: + if event.args["pool"] != mgr.cfg.BNT_ADDRESS: key = "pool" else: key = "tkn_address" - unique_key = event[key] if key in event else event["args"][key] + unique_key = event.address if key == "address" else event.args[key] + # unique_key = event.args[key] # Skip events for Bancor v2 anchors if ( key == "address" - and "_token1" in event["args"] + and "_token1" in event.args and ( - event["args"]["_token1"] in bancor_v2_anchor_addresses - or event["args"]["_token2"] in bancor_v2_anchor_addresses + event.args["_token1"] in bancor_v2_anchor_addresses + or event.args["_token2"] in bancor_v2_anchor_addresses ) ): continue if unique_key in latest_entry_per_pool: - if event["blockNumber"] > latest_entry_per_pool[unique_key]["blockNumber"]: + if event.block_number > latest_entry_per_pool[unique_key].block_number: latest_entry_per_pool[unique_key] = event - elif ( - event["blockNumber"] == latest_entry_per_pool[unique_key]["blockNumber"] - ): - if ( - event["transactionIndex"] - == latest_entry_per_pool[unique_key]["transactionIndex"] - ): - if ( - event["logIndex"] - > latest_entry_per_pool[unique_key]["logIndex"] - ): + elif event.block_number == latest_entry_per_pool[unique_key].block_number: + if event.transaction_index == latest_entry_per_pool[unique_key].transaction_index: + if event.log_index > latest_entry_per_pool[unique_key].log_index: latest_entry_per_pool[unique_key] = event - elif ( - event["transactionIndex"] - > latest_entry_per_pool[unique_key]["transactionIndex"] - ): + elif event.transaction_index > latest_entry_per_pool[unique_key].transaction_index: latest_entry_per_pool[unique_key] = event else: continue @@ -138,7 +125,7 @@ def complex_handler(obj: Any) -> Union[Dict, str, List, Set, Any]: If the input object does not match any of the specified types, it is returned as is. """ if isinstance(obj, AttributeDict): - return dict(obj) + return complex_handler(dict(obj)) elif isinstance(obj, HexBytes): return obj.hex() elif isinstance(obj, bytes): @@ -148,7 +135,7 @@ def complex_handler(obj: Any) -> Union[Dict, str, List, Set, Any]: elif isinstance(obj, (list, tuple)): return [complex_handler(i) for i in obj] elif isinstance(obj, set): - return list(obj) + return complex_handler(list(obj)) else: return obj @@ -637,10 +624,6 @@ def get_config( cfg.LIMIT_BANCOR3_FLASHLOAN_TOKENS = limit_bancor3_flashloan_tokens cfg.DEFAULT_MIN_PROFIT_GAS_TOKEN = Decimal(default_min_profit_gas_token) - cfg.GAS_TKN_IN_FLASHLOAN_TOKENS = ( - cfg.NATIVE_GAS_TOKEN_ADDRESS in flashloan_tokens - or cfg.WRAPPED_GAS_TOKEN_ADDRESS in flashloan_tokens - ) return cfg @@ -810,7 +793,21 @@ def save_events_to_json( mgr.cfg.logger.debug(f"[events.utils.save_events_to_json] Saved events to {path}") -def update_pools_from_events(n_jobs: int, mgr: Any, latest_events: List[Any]): +def process_new_events(new_event_mappings, event_mappings, filename, read_only): + # Update the manager's event mappings + event_mappings.update(new_event_mappings) + + if not read_only: + # Update the local event_mappings csvs + df = pd.DataFrame.from_dict(event_mappings, orient='index').reset_index() + if len(df)>0: + df.columns = ['address', 'exchange'] + # if the csvs are always sorted then the diffs will be readable + df.sort_values(by=['exchange','address'], inplace=True) + df.to_csv(filename, index=False) + + +def update_pools_from_events(n_jobs: int, mgr: Any, latest_events: List[Event]): """ Updates the pools with the given events. @@ -1059,36 +1056,6 @@ def handle_subsequent_iterations( ) -def verify_state_changed(bot: CarbonBot, initial_state: List[Dict[str, Any]], mgr: Any): - """ - Verifies that the state has changed. - - Parameters - ---------- - bot : CarbonBot - The bot object. - initial_state : Dict[str, Any] - The initial state. - mgr : Any - The manager object. - - """ - # Compare the initial state to the final state, and update the state if it has changed - final_state = mgr.pool_data.copy() - final_state_bancor_pol = [ - final_state[i] - for i in range(len(final_state)) - if final_state[i]["exchange_name"] == mgr.cfg.BANCOR_POL_NAME - ] - # assert bot.db.state == final_state, "\n *** bot failed to update state *** \n" - if initial_state != final_state_bancor_pol: - mgr.cfg.logger.debug("[events.utils.verify_state_changed] State has changed...") - else: - mgr.cfg.logger.warning( - "[events.utils.verify_state_changed] State has not changed... This may indicate an error" - ) - - def handle_duplicates(mgr: Any): """ Handles the duplicates in the pool data. @@ -1105,29 +1072,6 @@ def handle_duplicates(mgr: Any): assert len(cids) == len(set(cids)), "duplicate cid's exist in the pool data" -def get_pools_for_exchange(exchange: str, mgr: Any) -> [Any]: - """ - Handles the initial iteration of the bot. - - Parameters - ---------- - mgr : Any - The manager object. - exchange : str - The exchange for which to get pools - - Returns - ------- - List[Any] - A list of pools for the specified exchange. - """ - return [ - idx - for idx, pool in enumerate(mgr.pool_data) - if pool["exchange_name"] == exchange - ] - - def handle_initial_iteration( backdate_pools: bool, current_block: int, @@ -1234,6 +1178,7 @@ def get_latest_events( start_block: int, cache_latest_only: bool, logging_path: str, + event_gatherer: "EventGatherer" ) -> List[Any]: """ Gets the latest events. @@ -1271,17 +1216,8 @@ def get_latest_events( f"[events.utils.get_latest_events] tenderly_events: {len(tenderly_events)}" ) - # Get all event filters, events, and flatten them - events = [ - complex_handler(event) - for event in [ - complex_handler(event) - for event in get_all_events( - n_jobs, - get_event_filters(n_jobs, mgr, start_block, current_block), - ) - ] - ] + # Get all events + events = event_gatherer.get_all_events(from_block=start_block, to_block=current_block) # Filter out the latest events per pool, save them to disk, and update the pools latest_events = filter_latest_events(mgr, events) @@ -1299,7 +1235,7 @@ def get_latest_events( if not pool_type.event_matches_format(event) ] - carbon_pol_events = [event for event in latest_events if "token" in event["args"]] + carbon_pol_events = [event for event in latest_events if "token" in event.args] mgr.cfg.logger.info( f"[events.utils.get_latest_events] Found {len(latest_events)} new events, {len(carbon_pol_events)} carbon_pol_events" ) @@ -1731,66 +1667,6 @@ def delete_tenderly_forks(forks_to_cleanup: List[str], mgr: Any) -> List[str]: return forks_to_keep - -def verify_min_bnt_is_respected(bot: CarbonBot, mgr: Any): - """ - Verifies that the bot respects the min profit. Used for testing. - - Parameters - ---------- - bot : CarbonBot - The bot object. - mgr : Any - The manager object. - - """ - # Verify MIN_PROFIT_BNT is set and respected - assert ( - bot.ConfigObj.DEFAULT_MIN_PROFIT_GAS_TOKEN - == mgr.cfg.DEFAULT_MIN_PROFIT_GAS_TOKEN - ), "bot failed to update min profit" - mgr.cfg.logger.debug( - "[events.utils.verify_min_bnt_is_respected] Bot successfully updated min profit" - ) - - -def handle_target_token_addresses(static_pool_data: pd.DataFrame, target_tokens: List): - """ - Get the addresses of the target tokens. - - Parameters - ---------- - static_pool_data : pd.DataFrame - The static pool data. - target_tokens : List - The target tokens. - - Returns - ------- - List - The addresses of the target tokens. - - """ - # Get the addresses of the target tokens - target_token_addresses = [] - if target_tokens: - for token in target_tokens: - target_token_addresses = ( - target_token_addresses - + static_pool_data[static_pool_data["tkn0_address"] == token][ - "tkn0_address" - ].tolist() - ) - target_token_addresses = ( - target_token_addresses - + static_pool_data[static_pool_data["tkn1_address"] == token][ - "tkn1_address" - ].tolist() - ) - target_token_addresses = list(set(target_token_addresses)) - return target_token_addresses - - def get_current_block( last_block: int, mgr: Any, diff --git a/fastlane_bot/exceptions.py b/fastlane_bot/exceptions.py index ab225a2a2..11b84a8eb 100644 --- a/fastlane_bot/exceptions.py +++ b/fastlane_bot/exceptions.py @@ -19,13 +19,6 @@ def __str__(self): f"create this file.") -class AsyncUpdateRetryException(Exception): - """ - Exception raised when async_update_pools_from_contracts fails and needs to be retried. - """ - pass - - class FlashloanUnavailableException(Exception): """ Exception raised when not configured to use self_fund on a blockchain that does not support Flashloans. diff --git a/fastlane_bot/helpers/poolandtokens.py b/fastlane_bot/helpers/poolandtokens.py index c6ac1f61d..120eaa549 100644 --- a/fastlane_bot/helpers/poolandtokens.py +++ b/fastlane_bot/helpers/poolandtokens.py @@ -26,6 +26,23 @@ class SolidlyV2StablePoolsNotSupported(Exception): pass +FEE_LOOKUP = { + 0.000001: Univ3Calculator.FEE1, + 0.000008: Univ3Calculator.FEE8, + 0.00001: Univ3Calculator.FEE10, + 0.00004: Univ3Calculator.FEE40, + 0.00008: Univ3Calculator.FEE80, + 0.0001: Univ3Calculator.FEE100, + 0.00025: Univ3Calculator.FEE250, + 0.0003: Univ3Calculator.FEE300, + 0.00045: Univ3Calculator.FEE450, + 0.0005: Univ3Calculator.FEE500, + 0.0010: Univ3Calculator.FEE1000, + 0.0025: Univ3Calculator.FEE2500, + 0.0030: Univ3Calculator.FEE3000, + 0.01: Univ3Calculator.FEE10000, + } + @dataclass class PoolAndTokens: """ @@ -280,7 +297,7 @@ def to_cpc(self) -> Union[ConstantProductCurve, List[Any]]: elif self.exchange_name in self.ConfigObj.SUPPORTED_EXCHANGES: out = self._other_to_cpc() else: - raise NotImplementedError(f"Exchange {self.exchange_name} not implemented.") + raise NotImplementedError(f"exchange {self.exchange_name}") return out @@ -403,10 +420,25 @@ def _carbon_to_cpc(self) -> ConstantProductCurve: allow to omit yint (in which case it is set to y, but this does not make a difference for the result) """ + def calculate_parameters(y: Decimal, pa: Decimal, pb: Decimal, pm: Decimal, n: Decimal): + H = pa.sqrt() ** n + L = pb.sqrt() ** n + M = pm.sqrt() ** n + A = H - L + B = L + z = y * (H - L) / (M - L) if M > L else y + return z + + def check_overlap(pa0, pb0, pa1, pb1): + min0, max0 = sorted([pa0, pb0]) + min1, max1 = sorted([1 / pa1, 1 / pb1]) + prices_overlap = max(min0, min1) < min(max0, max1) + return prices_overlap # if idx == 0, use the first curve, otherwise use the second curve. change the numerical values to Decimal lst = [] errors = [] + strategy_typed_args = [] for i in [0, 1]: S = Decimal(self.A_1) if i == 0 else Decimal(self.A_0) @@ -450,6 +482,7 @@ def decimal_converter(idx): decimal_converter = decimal_converter(i) p_start = Decimal(encoded_order.p_start) * decimal_converter + p_marg = Decimal(encoded_order.p_marg) * decimal_converter p_end = Decimal(encoded_order.p_end) * decimal_converter yint = Decimal(yint) / ( Decimal("10") ** [self.tkn1_decimals, self.tkn0_decimals][i] @@ -457,6 +490,7 @@ def decimal_converter(idx): y = Decimal(y) / ( Decimal("10") ** [self.tkn1_decimals, self.tkn0_decimals][i] ) + is_limit_order = p_start==p_end tkny = 1 if i == 0 else 0 typed_args = { @@ -466,7 +500,9 @@ def decimal_converter(idx): "yint": yint, "y": y, "pb": p_end, + "p_marg": p_marg, # deleted later since not supported by from_carbon() "pa": p_start, + "is_limit_order": is_limit_order, # deleted later since not supported by from_carbon() "tkny": self.pair_name.split("/")[tkny].replace( self.ConfigObj.NATIVE_GAS_TOKEN_ADDRESS, self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS ), @@ -476,6 +512,54 @@ def decimal_converter(idx): "descr": self.descr, "params": self._params, } + + strategy_typed_args += [typed_args] + + # Only overlapping strategies are selected for modification + if len(strategy_typed_args) == 2: + + is_overlapping = False + pmarg_threshold = Decimal("0.01") # 1% # WARNING using this condition alone can included stable/stable pairs incidently + + # evaluate that the marginal prices are within the pmarg_threshold + pmarg0, pmarg1 = [x['p_marg'] for x in strategy_typed_args] + pmarg0_inv = 1/pmarg0 # one of the orders must be flipped since prices are always dy/dx - but must flip same geomean_pmarg later + percent_component = pmarg_threshold * max(pmarg0_inv, pmarg1) + percent_component_met = abs(pmarg0_inv - pmarg1) <= percent_component + + # overlapping strategies by defintion cannot have A=0 i.e. there must be no limit orders + no_limit_orders = (strategy_typed_args[0]['is_limit_order'] == False) and (strategy_typed_args[1]['is_limit_order'] == False) + + # evaluate if the price boundaries pa/pb overlap at one end # TODO check logic and remove duplicate logic if necessary + prices_overlap = check_overlap(strategy_typed_args[0]['pa'], strategy_typed_args[0]['pb'], strategy_typed_args[1]['pa'], strategy_typed_args[1]['pb']) + + # if the threshold is met and neither is a limit order and prices overlap then likely to be overlapping + is_overlapping = percent_component_met and no_limit_orders and prices_overlap + + if is_overlapping: + # calculate the geometric mean + geomean_p_marg = Decimal.sqrt(pmarg0_inv * pmarg1) + + # modify the y_int based on the new geomean to the limit of y #TODO check that this math is correct + typed_args0 = strategy_typed_args[0] + new_yint0 = calculate_parameters(y=typed_args0['y'], pa=typed_args0['pa'], pb=typed_args0['pb'], pm=(1/geomean_p_marg), n=1) + if new_yint0 < typed_args0['y']: + new_yint0 = typed_args0['y'] + typed_args0['yint'] = new_yint0 + + typed_args1 = strategy_typed_args[1] + new_yint1 = calculate_parameters(y=typed_args1['y'], pa=typed_args1['pa'], pb=typed_args1['pb'], pm=(geomean_p_marg), n=1) + if new_yint1 < typed_args1['y']: + new_yint1 = typed_args1['y'] + typed_args1['yint'] = new_yint1 + + # repack the strateg_typed_args + strategy_typed_args = [typed_args0, typed_args1] + + for typed_args in strategy_typed_args: + # delete new args that arent supported by from_carbon() + del typed_args["p_marg"] + del typed_args["is_limit_order"] try: if typed_args["y"] > 0: lst.append( @@ -492,22 +576,7 @@ def decimal_converter(idx): return lst - FEE_LOOKUP = { - 0.000001: Univ3Calculator.FEE1, - 0.000008: Univ3Calculator.FEE8, - 0.00001: Univ3Calculator.FEE10, - 0.00004: Univ3Calculator.FEE40, - 0.00008: Univ3Calculator.FEE80, - 0.0001: Univ3Calculator.FEE100, - 0.00025: Univ3Calculator.FEE250, - 0.0003: Univ3Calculator.FEE300, - 0.00045: Univ3Calculator.FEE450, - 0.0005: Univ3Calculator.FEE500, - 0.0010: Univ3Calculator.FEE1000, - 0.0025: Univ3Calculator.FEE2500, - 0.0030: Univ3Calculator.FEE3000, - 0.01: Univ3Calculator.FEE10000, - } + def _univ3_to_cpc(self) -> List[Any]: """ @@ -532,10 +601,10 @@ def _univ3_to_cpc(self) -> List[Any]: "tick": self.tick, "liquidity": self.liquidity, } - feeconst = self.FEE_LOOKUP.get(float(self.fee_float)) + feeconst = FEE_LOOKUP.get(float(self.fee_float)) if feeconst is None: raise ValueError( - f"Illegal fee for Uniswap v3 pool: {self.fee_float} [{self.FEE_LOOKUP}]]" + f"Illegal fee for Uniswap v3 pool: {self.fee_float} [{FEE_LOOKUP}]]" ) uni3 = Univ3Calculator.from_dict(args, feeconst, addrdec=self.ADDRDEC) params = uni3.cpc_params() diff --git a/fastlane_bot/helpers/routehandler.py b/fastlane_bot/helpers/routehandler.py index 7bfca0d1a..62f3e39f7 100644 --- a/fastlane_bot/helpers/routehandler.py +++ b/fastlane_bot/helpers/routehandler.py @@ -17,7 +17,6 @@ __DATE__ = "02/May/2023" import decimal -import math from _decimal import Decimal from dataclasses import dataclass from typing import List, Any, Dict, Tuple @@ -74,21 +73,12 @@ def maximize_last_trade_per_tkn(route_struct: List[Dict[str, Any]]): :param route_struct: the route struct object """ - tkns_traded = [route_struct[0]["sourceToken"]] + tkns_traded = set([route_struct[0]["sourceToken"]]) for j, trade in enumerate(reversed(route_struct)): idx = len(route_struct) - 1 - j - if type(trade) == dict: - if trade["sourceToken"] in tkns_traded: - continue - else: - route_struct[idx]["sourceAmount"] = 0 - tkns_traded.append(trade["sourceToken"]) - elif type(trade) == RouteStruct: - if trade.sourceToken in tkns_traded: - continue - else: - route_struct[idx].sourceAmount = 0 - tkns_traded.append(trade.sourceToken) + if trade["sourceToken"] not in tkns_traded: + tkns_traded.add(trade["sourceToken"]) + route_struct[idx]["sourceAmount"] = 0 @dataclass @@ -109,14 +99,9 @@ class TxRouteHandler: trade_instructions: List[TradeInstruction] def __post_init__(self): - self.contains_carbon = True - self.ConfigObj = self.trade_instructions[0].ConfigObj - if not self.trade_instructions: - raise ValueError("No trade instructions found.") if len(self.trade_instructions) < 2: raise ValueError("Length of trade instructions must be greater than 1.") - if sum([1 if self.trade_instructions[i]._is_carbon else 0 for i in range(len(self.trade_instructions))]) == 0: - self.contains_carbon = False + self.ConfigObj = self.trade_instructions[0].ConfigObj @staticmethod def custom_data_encoder( @@ -268,17 +253,12 @@ def get_route_structs( assert not deadline is None, "deadline cannot be None" - pools = [ - self._cid_to_pool(trade_instruction.cid, trade_instruction.db) - for trade_instruction in trade_instructions - ] - return [ self._to_route_struct( min_target_amount=trade_instruction.amtout_wei, deadline=deadline, target_address=trade_instruction.get_real_tkn_out, - custom_address=self.get_custom_address(pool), + custom_address=self.get_custom_address(trade_instruction.db.get_pool(cid=trade_instruction.cid)), platform_id=trade_instruction.platform_id, customInt=trade_instruction.custom_int, customData=trade_instruction.custom_data, @@ -286,7 +266,7 @@ def get_route_structs( source_amount=trade_instruction.amtin_wei, exchange_name=trade_instruction.exchange_name, ) - for trade_instruction, pool in zip(trade_instructions, pools) + for trade_instruction in trade_instructions ] def get_custom_address( @@ -314,7 +294,7 @@ def get_custom_address( else: return pool.tkn0_address - def generate_flashloan_struct(self, trade_instructions_objects: List[TradeInstruction]) -> list: + def generate_flashloan_struct(self, trade_instructions_objects: List[TradeInstruction]) -> List[Dict]: """ Generates the flashloan struct for submitting FlashLoanAndArbV2 transactions :param trade_instructions_objects: a list of TradeInstruction objects @@ -322,54 +302,41 @@ def generate_flashloan_struct(self, trade_instructions_objects: List[TradeInstru :return: list """ - return self._get_flashloan_struct(trade_instructions_objects=trade_instructions_objects) - - def _get_flashloan_platform_id(self, tkn: str) -> int: - """ - Returns the platform ID to take the flashloan from - :param tkn: str - - :return: - int - """ - - if self.ConfigObj.NETWORK not in ["ethereum", "tenderly"]: - return 7 - - # Using Bancor V3 to flashloan BNT, ETH, WBTC, LINK, USDC, USDT - if tkn in [self.ConfigObj.BNT_ADDRESS, self.ConfigObj.ETH_ADDRESS, self.ConfigObj.WBTC_ADDRESS, - self.ConfigObj.LINK_ADDRESS, self.ConfigObj.BNT_ADDRESS, self.ConfigObj.ETH_ADDRESS, - self.ConfigObj.WBTC_ADDRESS, self.ConfigObj.LINK_ADDRESS]: - return 2 + is_FL_NATIVE_permitted = self.ConfigObj.NETWORK == self.ConfigObj.NETWORK_ETHEREUM + + if trade_instructions_objects[0].tknin_is_native and not is_FL_NATIVE_permitted: + source_token = self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS + elif trade_instructions_objects[0].tknin_is_native and is_FL_NATIVE_permitted: + source_token = self.ConfigObj.NATIVE_GAS_TOKEN_ADDRESS + elif trade_instructions_objects[0].tknin_is_wrapped: + source_token = self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS else: - return 7 - - def _get_flashloan_struct(self, trade_instructions_objects: List[TradeInstruction]) -> list: - """ - Turns an object containing trade instructions into a struct with flashloan tokens and amounts ready to send to the smart contract. - :param flash_tokens: an object containing flashloan tokens in the format {tkn: {"tkn": tkn_address, "flash_amt": tkn_amt}} - """ - flash_tokens = self._extract_single_flashloan_token(trade_instructions=trade_instructions_objects) - flashloans = [] - balancer = {"platformId": 7, "sourceTokens": [], "sourceAmounts": []} - has_balancer = False - - for tkn in flash_tokens.keys(): - platform_id = self._get_flashloan_platform_id(tkn) - source_token = flash_tokens[tkn]["tkn"] - source_amounts = abs(flash_tokens[tkn]["flash_amt"]) - if platform_id == 7: - has_balancer = True - balancer["sourceTokens"].append(source_token) - balancer["sourceAmounts"].append(source_amounts) - else: - source_token = self.wrapped_gas_token_to_native(source_token) - flashloans.append( - {"platformId": platform_id, "sourceTokens": [source_token], "sourceAmounts": [source_amounts]}) - if has_balancer: - flashloans.append(balancer) - - return flashloans + source_token = trade_instructions_objects[0].tknin_address + + if self.ConfigObj.NETWORK in [ + self.ConfigObj.NETWORK_ETHEREUM, + self.ConfigObj.NETWORK_TENDERLY + ] and source_token in [ + self.ConfigObj.BNT_ADDRESS, + self.ConfigObj.ETH_ADDRESS, + self.ConfigObj.WBTC_ADDRESS, + self.ConfigObj.LINK_ADDRESS + ]: + return [ + { + "platformId": 2, + "sourceTokens": [self.wrapped_gas_token_to_native(source_token)], + "sourceAmounts": [abs(trade_instructions_objects[0].amtin_wei)] + } + ] + else: + return [ + { + "platformId": 7, + "sourceTokens": [source_token], + "sourceAmounts": [abs(trade_instructions_objects[0].amtin_wei)] + } + ] def native_gas_token_to_wrapped(self, tkn: str): """ @@ -378,106 +345,18 @@ def native_gas_token_to_wrapped(self, tkn: str): The token address returns: str The token address, converted to wrapped gas token if the input was the native gas token - """ return self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS if tkn == self.ConfigObj.NATIVE_GAS_TOKEN_ADDRESS else tkn def wrapped_gas_token_to_native(self, tkn: str): """ - Checks if a Token is a wrapped gas token and converts it to the native gas token. - - This is only relevant on the Ethereum network - - :param tkn: the token address - - returns: - the token address - """ - - if self.ConfigObj.NETWORK not in ["ethereum", "tenderly"]: - return tkn - - if tkn in [self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS, self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS]: - return self.ConfigObj.NATIVE_GAS_TOKEN_ADDRESS if tkn == self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS else self.ConfigObj.NATIVE_GAS_TOKEN_ADDRESS - else: - return tkn - - def _extract_single_flashloan_token(self, trade_instructions: List[TradeInstruction]) -> Dict: - """ - Generate a flashloan tokens and amounts. - :param trade_instructions: A list of trade instruction objects - """ - - is_FL_NATIVE_permitted = False - if self.ConfigObj.NETWORK in [self.ConfigObj.NETWORK_ETHEREUM]: - is_FL_NATIVE_permitted = True - - if trade_instructions[0].tknin_is_native and not is_FL_NATIVE_permitted: - tknin_address = self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS - self.ConfigObj.logger.info( - f"[routehandler._extract_single_flashloan_token] Not permitted to flashloan NATIVE - Switching to WRAPPED") - elif trade_instructions[0].tknin_is_native and is_FL_NATIVE_permitted: - tknin_address = self.ConfigObj.NATIVE_GAS_TOKEN_ADDRESS - elif trade_instructions[0].tknin_is_wrapped: - tknin_address = self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS - else: - tknin_address = trade_instructions[0].tknin_address - flash_tokens = { - tknin_address: - { - "tkn": tknin_address, - "flash_amt": trade_instructions[0].amtin_wei, - "decimals": trade_instructions[0].tknin_decimals} - } - - return flash_tokens - - def _extract_flashloan_tokens(self, trade_instructions: List[TradeInstruction]) -> Dict: - """ - Generate a list of the flashloan tokens and amounts. - :param trade_instructions: A list of trade instruction objects - """ - token_change = {} - flash_tokens = {} - for trade in trade_instructions: - tknin_address = self.wrapped_gas_token_to_native(trade.tknin_address) - tknout_address = self.wrapped_gas_token_to_native(trade.tknout_address) - - token_change[tknin_address] = {"tkn": tknin_address, "amtin": 0, "amtout": 0, "balance": 0} - token_change[tknout_address] = {"tkn": tknout_address, "amtin": 0, "amtout": 0, "balance": 0} - - for trade in trade_instructions: - tknin_address = self.wrapped_gas_token_to_native(trade.tknin_address) - tknout_address = self.wrapped_gas_token_to_native(trade.tknout_address) - - token_change[tknin_address]["amtin"] = token_change[tknin_address]["amtin"] + trade.amtin_wei - token_change[tknin_address]["balance"] = token_change[tknin_address]["balance"] - trade.amtin_wei - token_change[tknout_address]["amtout"] = token_change[tknout_address]["amtout"] + trade.amtout_wei - token_change[tknout_address]["balance"] = token_change[tknout_address]["balance"] + trade.amtout_wei - - if token_change[tknin_address]["balance"] < 0: - flash_tokens[tknin_address] = {"tkn": trade._tknin_address, - "flash_amt": token_change[tknin_address]["amtin"], - "decimals": trade.tknin_decimals} - - return flash_tokens - - - def get_arb_contract_args( - self, trade_instructions: List[TradeInstruction], deadline: int - ) -> Tuple[List[RouteStruct], int]: - """ - Gets the arguments needed to instantiate the `ArbContract` class. - - Returns - ------- - List[Any] - The arguments needed to instantiate the `ArbContract` class. + This function returns the native gas token address if the input token is the wrapped gas token, otherwise it returns the input token address. + :param tkn: str + The token address + returns: str + The token address, converted to native gas token if the input was the wrapped gas token """ - route_struct = self.get_route_structs( - trade_instructions=trade_instructions, deadline=deadline - ) - return route_struct + return self.ConfigObj.NATIVE_GAS_TOKEN_ADDRESS if tkn == self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS else tkn @staticmethod def _get_trade_dicts_from_objects(trade_instructions: List[TradeInstruction]) -> List[Dict[str, Any]]: @@ -551,11 +430,10 @@ def aggregate_bancor_v3_trades(calculated_trade_instructions: List[TradeInstruct for idx, trade in enumerate(calculated_trade_instructions): if idx > 0: - if trade.exchange_name == "bancor_v3" and calculated_trade_instructions[ - idx - 1].exchange_name == "bancor_v3": + if trade.exchange_name == calculated_trade_instructions[idx - 1].exchange_name == "bancor_v3": trade_before = calculated_trade_instructions[idx - 1] # This checks for a two-hop trade through BNT and combines them - if trade_before.tknout_address in "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C" and trade.tknin_address in "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C": + if trade_before.tknout_address == trade.tknin_address == trade.ConfigObj.BNT_ADDRESS: new_trade_instruction = TradeInstruction(ConfigObj=trade.ConfigObj, cid=trade_before.cid, amtin=trade_before.amtin, amtout=trade.amtout, tknin=trade_before.tknin_address, @@ -821,10 +699,10 @@ def _swap_token0_in( """ amount_in = amount_in * (Decimal(str(1)) - fee) - price_next = Decimal(str(math.floor(( - int(liquidity * self.ConfigObj.Q96 * sqrt_price) - / int(liquidity * self.ConfigObj.Q96 + amount_in * decimal_tkn0_modifier * sqrt_price))) - )) + price_next = Decimal( + int(liquidity * self.ConfigObj.Q96 * sqrt_price) + // int(liquidity * self.ConfigObj.Q96 + amount_in * decimal_tkn0_modifier * sqrt_price) + ) amount_out = self._calc_amount1(liquidity, sqrt_price, price_next) / self.ConfigObj.Q96 return Decimal(amount_out / decimal_tkn1_modifier) @@ -1475,9 +1353,6 @@ def calculate_trade_outputs( def _from_wei_to_decimals(self, tkn0_amt: Decimal, tkn0_decimals: int) -> Decimal: return Decimal(str(tkn0_amt)) / Decimal("10") ** Decimal(str(tkn0_decimals)) - def _cid_to_pool(self, cid: str, db: any) -> Pool: - return db.get_pool(cid=cid) - # TODO: Those functions should probably be private; also -- are they needed at # all? Most of them seem to be extremely trivial diff --git a/fastlane_bot/helpers/txhelpers.py b/fastlane_bot/helpers/txhelpers.py index bc7e19b03..0fdf166fc 100644 --- a/fastlane_bot/helpers/txhelpers.py +++ b/fastlane_bot/helpers/txhelpers.py @@ -49,7 +49,7 @@ def __post_init__(self): self.wallet_address = self.cfg.w3.eth.account.from_key(self.cfg.ETH_PRIVATE_KEY_BE_CAREFUL).address if self.cfg.NETWORK == self.cfg.NETWORK_ETHEREUM: - self.use_access_list = False # TODO: figure out why flashbots is unable to handle this + self.use_access_list = True self.send_transaction = self._send_private_transaction else: self.use_access_list = False @@ -184,12 +184,12 @@ def _send_regular_transaction(self, raw_tx: str) -> str: def _send_private_transaction(self, raw_tx: str) -> str: response = post( - "https://rpc.flashbots.net/fast", + "https://rpc.mevblocker.io/noreverts", json = { "id": 1, "jsonrpc": "2.0", - "method": "eth_sendPrivateTransaction", - "params": [{"tx": raw_tx, "maxBlockNumber": hex(self.cfg.w3.eth.block_number + 10)}] + "method": "eth_sendRawTransaction", + "params": [raw_tx] } ) text = loads(response.text) @@ -199,5 +199,5 @@ def _send_private_transaction(self, raw_tx: str) -> str: def _wait_for_transaction_receipt(self, tx_hash: str) -> Optional[dict]: try: return loads(self.cfg.w3.to_json(self.cfg.w3.eth.wait_for_transaction_receipt(tx_hash))) - except TimeExhausted as _: + except TimeExhausted: return None diff --git a/fastlane_bot/modes/base_triangle.py b/fastlane_bot/modes/base_triangle.py index bf5f0c6a4..522283b36 100644 --- a/fastlane_bot/modes/base_triangle.py +++ b/fastlane_bot/modes/base_triangle.py @@ -17,6 +17,45 @@ from fastlane_bot.modes.base import ArbitrageFinderBase from fastlane_bot.tools.cpc import T +def sort_pairs(pairs): + # Clean up the pairs alphabetically + return ["/".join(sorted(pair.split('/'))) for pair in pairs] + +def flatten_nested_items_in_list(nested_list): + # unpack nested items + flattened_list = [] + for items in nested_list: + flat_list = [] + for item in items: + if isinstance(item, list): + flat_list.extend(item) + else: + flat_list.append(item) + flattened_list.append(flat_list) + return flattened_list + +def get_triangle_groups(flt, x_y_pairs): + # Get groups of triangles that conform to (flt/x , x/y, y/flt) where x!=y + triangle_groups = [] + for pair in x_y_pairs: + x,y = pair.split('/') + triangle_groups += [("/".join(sorted([flt,x])), pair, "/".join(sorted([flt,y])))] + return triangle_groups + +def get_triangle_groups_stats(triangle_groups, all_relevant_pairs_info): + # Get the stats on the triangle group cohort for decision making + valid_carbon_triangles = [] + for triangle in triangle_groups: + path_len = 0 + has_carbon = False + for pair in triangle: + if all_relevant_pairs_info[pair]['all_counts'] > 0: + path_len += 1 + if all_relevant_pairs_info[pair]['carbon_counts'] > 0: + has_carbon = True + if path_len == 3 and has_carbon == True: + valid_carbon_triangles.append(triangle) + return valid_carbon_triangles class ArbitrageFinderTriangleBase(ArbitrageFinderBase): """ @@ -174,64 +213,103 @@ def get_combos( combos, ) return combos + + def get_all_relevant_pairs_info(self, CCm, all_relevant_pairs): + # Get pair info for the cohort to allow decision making at the triangle level + all_relevant_pairs_info = {} + for pair in all_relevant_pairs: + all_relevant_pairs_info[pair] = {} + pair_curves = CCm.bypair(pair) + carbon_curves = [] + non_carbon_curves = [] + for x in pair_curves: + if x.params.exchange in self.ConfigObj.CARBON_V1_FORKS: + carbon_curves += [x] + else: + non_carbon_curves += [x] + all_relevant_pairs_info[pair]['non_carbon_curves'] = non_carbon_curves + all_relevant_pairs_info[pair]['carbon_curves'] = carbon_curves + all_relevant_pairs_info[pair]['curves'] = non_carbon_curves + [carbon_curves] if len(carbon_curves) > 0 else non_carbon_curves # condense carbon curves into a single list + all_relevant_pairs_info[pair]['all_counts'] = len(pair_curves) + all_relevant_pairs_info[pair]['carbon_counts'] = len(carbon_curves) + return all_relevant_pairs_info - @staticmethod - def get_mono_direction_carbon_curves( - miniverse: List[Any], trade_instructions_df: pd.DataFrame, token_in: str=None - ) -> List[Any]: + def get_analysis_set_per_flt(self, flt, valid_triangles, all_relevant_pairs_info): + flt_triangle_analysis_set = [] + for triangle in valid_triangles: + multiverse = [all_relevant_pairs_info[pair]['curves'] for pair in triangle] + product_of_triangle = list(itertools.product(multiverse[0], multiverse[1], multiverse[2])) + triangles_to_run = flatten_nested_items_in_list(product_of_triangle) + flt_triangle_analysis_set += list(zip([flt] * len(triangles_to_run), triangles_to_run)) + + self.ConfigObj.logger.debug(f"[base_triangle.get_analysis_set_per_flt] Length of flt_triangle_analysis_set: {flt, len(flt_triangle_analysis_set)}") + return flt_triangle_analysis_set + + def get_comprehensive_triangles( + self, flashloan_tokens: List[str], CCm: Any + ) -> Tuple[List[str], List[Any]]: """ - Get mono direction carbon curves for triangular arbitrage + Get comprehensive combos for triangular arbitrage Parameters ---------- - miniverse : list - List of miniverses - token_in : str - Token in - trade_instructions_df : DataFrame - Trade instructions dataframe + flashloan_tokens : list + List of flashloan tokens + CCm : object + CCm object Returns ------- - mono_direction_carbon_curves : list - List of mono direction carbon curves + combos : list + List of combos """ + combos = [] + for flt in flashloan_tokens: + + # Get the Carbon pairs + carbon_pairs = sort_pairs(set([x.pair for x in CCm.curves if x.params.exchange in self.ConfigObj.CARBON_V1_FORKS])) + + # Create a set of unique tokens, excluding 'flt' + x_tokens = {token for pair in carbon_pairs for token in pair.split('/') if token != flt} + + # Get relevant pairs containing the flashloan token + flt_x_pairs = sort_pairs([f"{x}/{flt}" for x in x_tokens]) + + # Generate all possible 2-item combinations from the unique tokens that arent the flashloan token + x_y_pairs = sort_pairs(["{}/{}".format(x, y) for x, y in itertools.combinations(x_tokens, 2)]) + + # Note the relevant pairs + all_relevant_pairs = flt_x_pairs + x_y_pairs + self.ConfigObj.logger.debug(f"len(all_relevant_pairs) {len(all_relevant_pairs)}") + + # Generate triangle groups + triangle_groups = get_triangle_groups(flt, x_y_pairs) + self.ConfigObj.logger.debug(f"len(triangle_groups) {len(triangle_groups)}") + + # Get pair info for the cohort + all_relevant_pairs_info = self.get_all_relevant_pairs_info(CCm, all_relevant_pairs) + + # Generate valid triangles for the groups base on arb_mode + valid_triangles = get_triangle_groups_stats(triangle_groups, all_relevant_pairs_info) + + # Get [(flt,curves)] analysis set for the flt + flt_triangle_analysis_set = self.get_analysis_set_per_flt(flt, valid_triangles, all_relevant_pairs_info) + + # The entire analysis set for all flts + combos.extend(flt_triangle_analysis_set) + return combos - if token_in is None: - columns = trade_instructions_df.columns - check_nan = trade_instructions_df.copy().fillna(0) - first_bancor_v3_pool = check_nan.iloc[0] - second_bancor_v3_pool = check_nan.iloc[1] - - for idx, token in enumerate(columns): - if token == T.BNT: - continue - if first_bancor_v3_pool[token] < 0: - token_in = token - break - if second_bancor_v3_pool[token] < 0: - token_in = token - break - - wrong_direction_cids = [] - for idx, row in trade_instructions_df.iterrows(): - if (row[token_in] < 0) and ("-0" in idx or "-1" in idx): - wrong_direction_cids.append(idx) - - return [curve for curve in miniverse if curve.cid not in wrong_direction_cids] def build_pstart(self, CCm, tkn0list, tkn1): tkn0list = [x for x in tkn0list if x not in [tkn1]] pstart = {} for tkn0 in tkn0list: try: - price = CCm.bytknx(tkn0).bytkny(tkn1)[0].p + pstart[tkn0] = CCm.bytknx(tkn0).bytkny(tkn1)[0].p except: try: - price = 1/CCm.bytknx(tkn1).bytkny(tkn0)[0].p + pstart[tkn0] = 1/CCm.bytknx(tkn1).bytkny(tkn0)[0].p except Exception as e: - print(str(e)) - self.ConfigObj.logger.debug(f"[pstart build] {tkn0} not supported. w {tkn1} {str(e)}") - pstart[tkn0]=price + self.ConfigObj.logger.info(f"[pstart build] {tkn0}/{tkn1} price error {e}") pstart[tkn1] = 1 - return pstart \ No newline at end of file + return pstart diff --git a/fastlane_bot/modes/pairwise_multi_all.py b/fastlane_bot/modes/pairwise_multi_all.py index 924bdb702..20cdbb46f 100644 --- a/fastlane_bot/modes/pairwise_multi_all.py +++ b/fastlane_bot/modes/pairwise_multi_all.py @@ -67,6 +67,9 @@ def find_arbitrage(self, candidates: List[Any] = None, ops: Tuple = None, best_p if len(base_direction_two) > 0: curve_combos += [[curve] + base_direction_two for curve in not_carbon_curves] + if len(carbon_curves) >= 2: + curve_combos += [carbon_curves] + for curve_combo in curve_combos: src_token = tkn1 if len(curve_combo) < 2: diff --git a/fastlane_bot/modes/triangle_multi.py b/fastlane_bot/modes/triangle_multi.py index 50e335880..e6d1f6672 100644 --- a/fastlane_bot/modes/triangle_multi.py +++ b/fastlane_bot/modes/triangle_multi.py @@ -33,31 +33,23 @@ def find_arbitrage(self, candidates: List[Any] = None, ops: Tuple = None, best_p if candidates is None: candidates = [] - combos = self.get_combos( - self.flashloan_tokens, self.CCm, arb_mode=self.arb_mode - ) + combos = self.get_combos(self.flashloan_tokens, self.CCm, arb_mode=self.arb_mode) for src_token, miniverse in combos: try: - r = None CC_cc = CPCContainer(miniverse) O = MargPOptimizer(CC_cc) - #try: pstart = self.build_pstart(CC_cc, CC_cc.tokens(), src_token) - r = O.optimize(src_token, params=dict(pstart=pstart)) #debug=True, debug2=True + r = O.optimize(src_token, params=dict(pstart=pstart)) trade_instructions_dic = r.trade_instructions(O.TIF_DICTS) - if len(trade_instructions_dic) < 3: + if trade_instructions_dic is None or len(trade_instructions_dic) < 3: # Failed to converge continue trade_instructions_df = r.trade_instructions(O.TIF_DFAGGR) trade_instructions = r.trade_instructions() except Exception as e: - self.ConfigObj.logger.debug(f"[triangle multi] {str(e)}") - continue - if trade_instructions_dic is None: - continue - if len(trade_instructions_dic) < 2: + self.ConfigObj.logger.info(f"[triangle multi] {e}") continue profit_src = -r.result @@ -92,21 +84,3 @@ def find_arbitrage(self, candidates: List[Any] = None, ops: Tuple = None, best_p ) return candidates if self.result == self.AO_CANDIDATES else ops - - def build_pstart(self, CCm, tkn0list, tkn1): - tkn0list = [x for x in tkn0list if x not in [tkn1]] - pstart = {} - for tkn0 in tkn0list: - try: - price = CCm.bytknx(tkn0).bytkny(tkn1)[0].p - except: - try: - price = 1/CCm.bytknx(tkn1).bytkny(tkn0)[0].p - except Exception as e: - print(str(e)) - self.ConfigObj.logger.debug(f"[pstart build] {tkn0} not supported. w {tkn1} {str(e)}") - pstart[tkn0]=price - pstart[tkn1] = 1 - return pstart - - diff --git a/fastlane_bot/pool_finder.py b/fastlane_bot/pool_finder.py new file mode 100644 index 000000000..f61b5c660 --- /dev/null +++ b/fastlane_bot/pool_finder.py @@ -0,0 +1,176 @@ +""" +Finds liquidity pools. + +--- +(c) Copyright Bprotocol foundation 2023-24. +All rights reserved. +Licensed under MIT. +""" +from collections import defaultdict + +from typing import List, Tuple, Dict, Any + +from fastlane_bot.config import Config +from fastlane_bot.config.constants import ZERO_ADDRESS, UNISWAP_V2_NAME, UNISWAP_V3_NAME, SOLIDLY_V2_NAME +from fastlane_bot.config.multicaller import MultiCaller +from fastlane_bot.events.exchanges.base import Exchange + +class PoolFinder: + """A class that provides methods to find unsupported carbon pairs and triangles + within a given set of flashloan tokens and external pairs. + """ + def __init__( + self, + carbon_forks: List[str], + uni_v3_forks: List[str], + flashloan_tokens: List[str], + exchanges: List[Exchange], + web3: Any, + multicall_address: str + ): + self._carbon_forks = carbon_forks + self._uni_v3_forks = uni_v3_forks + self._flashloan_tokens = flashloan_tokens + self._uni_v3_fee_tiers = defaultdict(set) + self._carbon_pairs_seen = set() + + self._exchanges = list(filter(lambda e: e.base_exchange_name in [UNISWAP_V2_NAME, UNISWAP_V3_NAME, SOLIDLY_V2_NAME], exchanges.values())) + self._web3 = web3 + self._multicall_address = multicall_address + + def extract_univ3_fee_tiers(self, pools: List[Dict[str, Any]]): + """ + Extracts unique fee tiers for each exchange listed under Uniswap V3 forks from the provided pool data. + + Args: + pools (List[Dict[str, Any]]): List of pool dictionaries containing 'exchange_name' and 'fee'. + + This function updates the 'uni_v3_fee_tiers' dictionary where each exchange name is mapped to a set of unique fees. + """ + for pool in pools: + if pool["exchange_name"] in self._uni_v3_forks: + self._uni_v3_fee_tiers[pool["exchange_name"]].add(int(pool["fee"])) + + + def get_pools_for_unsupported_pairs(self, config: Config, pools: List[Dict[str, Any]], arb_mode: str): + """ + Main flow for Poolfinder. + + Args: + pools (List[Dict[str, Any]]): A list of pool data where each pool is a dictionary. The expected keys in + each dictionary should align with the requirements of the _extract_pairs, + _find_unsupported_pairs, and _find_unsupported_triangles methods. + + Returns: + Dict: Returns a list of dictionaries with pools sorted into different exchange types (Uni V2 forks, Uni V3 forks, + and Solidly V2 forks), each associated with their specific supporting pools based on the unsupported + configurations identified. + """ + carbon_pairs, other_pairs = self._extract_pairs(pools=pools) + if not carbon_pairs: + return [], [], [] + self.extract_univ3_fee_tiers(pools) # TODO: these should be configured per exchange + if arb_mode in ["triangle", "multi_triangle"]: + unsupported_pairs = PoolFinder._find_unsupported_triangles(self._flashloan_tokens, carbon_pairs=carbon_pairs, external_pairs=other_pairs) + else: + unsupported_pairs = PoolFinder._find_unsupported_pairs(self._flashloan_tokens, carbon_pairs=carbon_pairs, external_pairs=other_pairs) + config.logger.info(f"Searching pools to support the following carbon pairs:") + for pair in unsupported_pairs: + config.logger.info(pair) + + pairs = [(tkn, token) for pair in unsupported_pairs for tkn in pair for token in self._flashloan_tokens] + chunk_size = 400 + # Create the list of chunks + chunked_pairs = [pairs[i:i + chunk_size] for i in range(0, len(pairs), chunk_size)] + result = defaultdict(dict) + + for exchange in self._exchanges: + for pair_chunk in chunked_pairs: + mc = MultiCaller(self._web3, self._multicall_address) + for pair in pair_chunk: + if exchange.base_exchange_name in [UNISWAP_V2_NAME, SOLIDLY_V2_NAME]: + mc.add_call(exchange.get_pool_func_call(pair[0], pair[1])) + elif exchange.base_exchange_name == UNISWAP_V3_NAME: + for fee in self._uni_v3_fee_tiers[exchange.exchange_name]: + mc.add_call(exchange.get_pool_func_call(pair[0], pair[1], fee)) + addresses = mc.run_calls() + result[exchange.base_exchange_name].update({ + self._web3.to_checksum_address(address): exchange.exchange_name + for address in addresses if address not in [None, ZERO_ADDRESS] + }) + + return result[UNISWAP_V2_NAME], result[UNISWAP_V3_NAME], result[SOLIDLY_V2_NAME] + + + def _extract_pairs(self, pools: List[Dict[str, Any]]) -> Tuple[List, set]: + """ + Extracts unique, order-insensitive pairs of tokens from pools, categorizing them + into carbon pairs and other pairs based on the exchange's presence in carbon_forks. + + Args: + pools (List[Dict[str, Any]]): List of pool dictionaries containing token addresses and exchange names. + + Returns: + tuple: Two sets of unique token pairs, one for carbon forks and one for other exchanges. + """ + carbon_pairs = set() + other_pairs = set() + + for pool in pools: + # Create a frozenset for each pair to ensure the pair is treated as order-insensitive + pair = (pool["tkn0_address"], pool["tkn1_address"]) + + if pool["exchange_name"] in self._carbon_forks: + frozen_pair = frozenset(pair) + if frozen_pair not in self._carbon_pairs_seen: + carbon_pairs.add(pair) + self._carbon_pairs_seen.add(frozen_pair) + else: + other_pairs.add(pair) + + return list(carbon_pairs), other_pairs + + @staticmethod + def _find_unsupported_triangles(flashloan_tokens: List[str], carbon_pairs: List[Tuple], external_pairs: set) -> List[Tuple]: + """ + Identifies carbon pairs that cannot form a valid triangle with any of the flashloan tokens, + even though each side of the pair is supported externally. + + Args: + flashloan_tokens (List[str]): Tokens available for forming triangles. + carbon_pairs (List[Tuple]): Carbon pairs to check for triangle support. + external_pairs (List[Tuple[str, str]]): Pairs that are supported externally. + + Returns: + List[Tuple]: List of carbon pairs that cannot form a valid triangle. + """ + unsupported_triangles = [] + + for pair in carbon_pairs: + tkn0, tkn1 = pair[0], pair[1] + if not any((frozenset((tkn0, tkn)) in external_pairs and frozenset((tkn1, tkn)) in external_pairs) for tkn in flashloan_tokens): + unsupported_triangles.append(pair) + return unsupported_triangles + + @staticmethod + def _find_unsupported_pairs(flashloan_tokens: List[str], carbon_pairs: List[Tuple], external_pairs: set): + """ + Determines which carbon pairs are unsupported based on the lack of token support and non-existence in external pairs. + + Args: + flashloan_tokens (List[str]): List of tokens supported for flashloans. + carbon_pairs (List[Tuple]): Carbon pairs to evaluate for support. + external_pairs (List[Tuple]): Pairs externally supported. + + Returns: + List[Tuple]: List of unsupported carbon pairs. + """ + unsupported_pairs = [] + for pair in carbon_pairs: + tkn0, tkn1 = pair[0], pair[1] + if (tkn0 not in flashloan_tokens and tkn1 not in flashloan_tokens): + unsupported_pairs.append(pair) + elif pair not in external_pairs: + unsupported_pairs.append(pair) + + return unsupported_pairs diff --git a/fastlane_bot/tests/conftest.py b/fastlane_bot/tests/conftest.py new file mode 100644 index 000000000..fa3fc27a7 --- /dev/null +++ b/fastlane_bot/tests/conftest.py @@ -0,0 +1,8 @@ +import pytest + +from fastlane_bot import Config + + +@pytest.fixture +def config(): + return Config.new(config=Config.CONFIG_MAINNET) diff --git a/fastlane_bot/tests/test_033_Pools.py b/fastlane_bot/tests/test_033_Pools.py index d40a20074..26959204e 100644 --- a/fastlane_bot/tests/test_033_Pools.py +++ b/fastlane_bot/tests/test_033_Pools.py @@ -11,6 +11,7 @@ import json from fastlane_bot import Bot +from fastlane_bot.events.interfaces.event import Event from fastlane_bot.events.pools import BancorPolPool, BancorV2Pool, BancorV3Pool, CarbonV1Pool, SolidlyV2Pool, \ UniswapV2Pool, UniswapV3Pool from fastlane_bot.tools.cpc import ConstantProductCurve as CPC @@ -46,7 +47,7 @@ def test_test_uniswap_v2_pool(): # ------------------------------------------------------------ uniswap_v2_pool = UniswapV2Pool() - uniswap_v2_pool.update_from_event(setup_data['uniswap_v2_event'], {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, 'exchange_name': 'sushiswap_v2', 'reserve0': setup_data['uniswap_v2_event']['args']['reserve0'], 'reserve1': setup_data['uniswap_v2_event']['args']['reserve1'], 'tkn0_symbol': 'tkn0', 'tkn1_symbol': 'tkn1'}) + uniswap_v2_pool.update_from_event(Event.from_dict(setup_data['uniswap_v2_event']), {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, 'exchange_name': 'sushiswap_v2', 'reserve0': setup_data['uniswap_v2_event']['args']['reserve0'], 'reserve1': setup_data['uniswap_v2_event']['args']['reserve1'], 'tkn0_symbol': 'tkn0', 'tkn1_symbol': 'tkn1'}) assert (uniswap_v2_pool.state['tkn0_balance'] == setup_data['uniswap_v2_event']['args']['reserve0']) @@ -59,7 +60,7 @@ def test_test_solidly_v2_pool(): # ------------------------------------------------------------ solidly_v2_pool = SolidlyV2Pool() - solidly_v2_pool.update_from_event(setup_data['solidly_v2_event'], {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, 'exchange_name': 'velocimeter_v2', 'reserve0': setup_data['solidly_v2_event']['args']['reserve0'], 'reserve1': setup_data['solidly_v2_event']['args']['reserve1'], 'tkn0_symbol': 'tkn0', 'tkn1_symbol': 'tkn1'}) + solidly_v2_pool.update_from_event(Event.from_dict(setup_data['solidly_v2_event']), {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, 'exchange_name': 'velocimeter_v2', 'reserve0': setup_data['solidly_v2_event']['args']['reserve0'], 'reserve1': setup_data['solidly_v2_event']['args']['reserve1'], 'tkn0_symbol': 'tkn0', 'tkn1_symbol': 'tkn1'}) assert (solidly_v2_pool.state['tkn0_balance'] == setup_data['solidly_v2_event']['args']['reserve0']) @@ -75,7 +76,7 @@ def test_test_bancor_v2_pool(): bancor_v2_pool.state['tkn0_address'] = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' bancor_v2_pool.state['tkn1_address'] = '0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C' bancor_v2_pool.state['anchor']= '0xb1CD6e4153B2a390Cf00A6556b0fC1458C4A5533' - bancor_v2_pool.update_from_event(setup_data['bancor_v2_event'], {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, 'exchange_name': 'bancor_v2'}) + bancor_v2_pool.update_from_event(Event.from_dict(setup_data['bancor_v2_event']), {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, 'exchange_name': 'bancor_v2'}) assert (5698079648237338312679700 == setup_data['bancor_v2_event']['args']['_rateN']), f"expected {bancor_v2_pool.state['tkn0_balance']}, found {setup_data['bancor_v2_event']['args']['_rateN']}" assert (1404376232459809237924 == setup_data['bancor_v2_event']['args']['_rateD']), f"expected {bancor_v2_pool.state['tkn1_balance']}, found {setup_data['bancor_v2_event']['args']['_rateD']}" @@ -89,7 +90,7 @@ def test_test_pancakeswap_v2_pool(): # ------------------------------------------------------------ pancakeswap_v2_pool = UniswapV2Pool() - pancakeswap_v2_pool.update_from_event(setup_data['pancakeswap_v2_event'], {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, 'exchange_name': 'pancakeswap_v2', 'reserve0': setup_data['pancakeswap_v2_event']['args']['reserve0'], 'reserve1': setup_data['pancakeswap_v2_event']['args']['reserve1'], 'tkn0_symbol': 'tkn0', 'tkn1_symbol': 'tkn1'}) + pancakeswap_v2_pool.update_from_event(Event.from_dict(setup_data['pancakeswap_v2_event']), {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, 'exchange_name': 'pancakeswap_v2', 'reserve0': setup_data['pancakeswap_v2_event']['args']['reserve0'], 'reserve1': setup_data['pancakeswap_v2_event']['args']['reserve1'], 'tkn0_symbol': 'tkn0', 'tkn1_symbol': 'tkn1'}) assert (pancakeswap_v2_pool.state['tkn0_balance'] == setup_data['pancakeswap_v2_event']['args']['reserve0']) @@ -102,7 +103,7 @@ def test_test_uniswap_v3_pool(): # ------------------------------------------------------------ uniswap_v3_pool = UniswapV3Pool() - uniswap_v3_pool.update_from_event(setup_data['uniswap_v3_event'], {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, 'exchange_name': 'uniswap_v3', 'liquidity': setup_data['uniswap_v3_event']['args']['liquidity'], 'sqrtPriceX96': setup_data['uniswap_v3_event']['args']['sqrtPriceX96'], 'tick': setup_data['uniswap_v3_event']['args']['tick'], 'tkn0_symbol': 'tkn0', 'tkn1_symbol': 'tkn1'}) + uniswap_v3_pool.update_from_event(Event.from_dict(setup_data['uniswap_v3_event']), {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, 'exchange_name': 'uniswap_v3', 'liquidity': setup_data['uniswap_v3_event']['args']['liquidity'], 'sqrtPriceX96': setup_data['uniswap_v3_event']['args']['sqrtPriceX96'], 'tick': setup_data['uniswap_v3_event']['args']['tick'], 'tkn0_symbol': 'tkn0', 'tkn1_symbol': 'tkn1'}) assert (uniswap_v3_pool.state['liquidity'] == setup_data['uniswap_v3_event']['args']['liquidity']) assert (uniswap_v3_pool.state['sqrt_price_q96'] == setup_data['uniswap_v3_event']['args']['sqrtPriceX96']) @@ -116,7 +117,7 @@ def test_test_pancakeswap_v3_pool(): # ------------------------------------------------------------ pancakeswap_v3_pool = UniswapV3Pool() - pancakeswap_v3_pool.update_from_event(setup_data['pancakeswap_v3_event'], {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, 'exchange_name': 'pancakeswap_v3', 'liquidity': setup_data['pancakeswap_v3_event']['args']['liquidity'], 'sqrtPriceX96': setup_data['pancakeswap_v3_event']['args']['sqrtPriceX96'], 'tick': setup_data['pancakeswap_v3_event']['args']['tick'], 'tkn0_symbol': 'tkn0', 'tkn1_symbol': 'tkn1'}) + pancakeswap_v3_pool.update_from_event(Event.from_dict(setup_data['pancakeswap_v3_event']), {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, 'exchange_name': 'pancakeswap_v3', 'liquidity': setup_data['pancakeswap_v3_event']['args']['liquidity'], 'sqrtPriceX96': setup_data['pancakeswap_v3_event']['args']['sqrtPriceX96'], 'tick': setup_data['pancakeswap_v3_event']['args']['tick'], 'tkn0_symbol': 'tkn0', 'tkn1_symbol': 'tkn1'}) assert (pancakeswap_v3_pool.state['liquidity'] == setup_data['pancakeswap_v3_event']['args']['liquidity']) assert (pancakeswap_v3_pool.state['sqrt_price_q96'] == setup_data['pancakeswap_v3_event']['args']['sqrtPriceX96']) @@ -130,7 +131,7 @@ def test_test_bancor_v3_pool(): # ------------------------------------------------------------ bancor_v3_pool = BancorV3Pool() - bancor_v3_pool.update_from_event(setup_data['bancor_v3_event'], {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, 'exchange_name': 'bancor_v3', 'tkn0_balance': setup_data['bancor_v3_event']['args']['newLiquidity'], 'tkn1_balance': 0, 'tkn0_symbol': 'tkn0', 'tkn1_symbol': 'tkn1'}) + bancor_v3_pool.update_from_event(Event.from_dict(setup_data['bancor_v3_event']), {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, 'exchange_name': 'bancor_v3', 'tkn0_balance': setup_data['bancor_v3_event']['args']['newLiquidity'], 'tkn1_balance': 0, 'tkn0_symbol': 'tkn0', 'tkn1_symbol': 'tkn1'}) # ------------------------------------------------------------ @@ -142,7 +143,7 @@ def test_test_carbon_v1_pool_update(): # ------------------------------------------------------------ carbon_v1_pool = CarbonV1Pool() - carbon_v1_pool.update_from_event(setup_data['carbon_v1_event_create_for_update'], {}) + carbon_v1_pool.update_from_event(Event.from_dict(setup_data['carbon_v1_event_create_for_update']), {}) strat_id = setup_data['carbon_v1_event_update']['args']['id'] assert (strat_id == carbon_v1_pool.state['strategy_id']) assert (carbon_v1_pool.state['y_0'] == 0) @@ -153,7 +154,7 @@ def test_test_carbon_v1_pool_update(): assert (carbon_v1_pool.state['z_1'] == 0) assert (carbon_v1_pool.state['A_1'] == 0) assert (carbon_v1_pool.state['B_1'] == 0) - carbon_v1_pool.update_from_event(setup_data['carbon_v1_event_update'], {}) + carbon_v1_pool.update_from_event(Event.from_dict(setup_data['carbon_v1_event_update']), {}) assert (carbon_v1_pool.state['y_0'] == setup_data['carbon_v1_event_update']['args']['order0'][0]) assert (carbon_v1_pool.state['z_0'] == setup_data['carbon_v1_event_update']['args']['order0'][1]) assert (carbon_v1_pool.state['A_0'] == setup_data['carbon_v1_event_update']['args']['order0'][2]) @@ -172,7 +173,7 @@ def test_test_carbon_v1_pool_delete(): # ------------------------------------------------------------ carbon_v1_pool = CarbonV1Pool() - carbon_v1_pool.update_from_event(setup_data['carbon_v1_event_create_for_delete'], {}) + carbon_v1_pool.update_from_event(Event.from_dict(setup_data['carbon_v1_event_create_for_delete']), {}) strat_id = setup_data['carbon_v1_event_update']['args']['id'] assert (strat_id == carbon_v1_pool.state['strategy_id']) assert (carbon_v1_pool.state['y_0'] == setup_data['carbon_v1_event_delete']['args']['order0'][0]) @@ -183,7 +184,7 @@ def test_test_carbon_v1_pool_delete(): assert (carbon_v1_pool.state['z_1'] == setup_data['carbon_v1_event_delete']['args']['order1'][1]) assert (carbon_v1_pool.state['A_1'] == setup_data['carbon_v1_event_delete']['args']['order1'][2]) assert (carbon_v1_pool.state['B_1'] == setup_data['carbon_v1_event_delete']['args']['order1'][3]) - carbon_v1_pool.update_from_event(setup_data['carbon_v1_event_delete'], {}) + carbon_v1_pool.update_from_event(Event.from_dict(setup_data['carbon_v1_event_delete']), {}) assert (carbon_v1_pool.state['y_0'] == 0) assert (carbon_v1_pool.state['z_0'] == 0) assert (carbon_v1_pool.state['A_0'] == 0) @@ -206,7 +207,7 @@ def test_test_bancor_pol_token_traded_event(): bancor_pol_pool = BancorPolPool() bancor_pol_pool.state['tkn0_address'] = setup_data['bancor_pol_token_traded_event']['args']['token'] bancor_pol_pool.state['tkn0_balance'] = 10 + setup_data['bancor_pol_token_traded_event']['args']['amount'] - bancor_pol_pool.update_from_event(setup_data['bancor_pol_token_traded_event'], + bancor_pol_pool.update_from_event(Event.from_dict(setup_data['bancor_pol_token_traded_event']), {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, @@ -230,7 +231,7 @@ def test_test_bancor_pol_trading_enabled_event(): bancor_pol_pool = BancorPolPool() bancor_pol_pool.state['tkn0_address'] = None - bancor_pol_pool.update_from_event(setup_data['bancor_pol_trading_enabled_event'], + bancor_pol_pool.update_from_event(Event.from_dict(setup_data['bancor_pol_trading_enabled_event']), {'cid': '0x', 'fee': '0.000', 'fee_float': 0.0, diff --git a/fastlane_bot/tests/test_034_Interface.py b/fastlane_bot/tests/test_034_Interface.py index 8b7f3dea8..82a98ee87 100644 --- a/fastlane_bot/tests/test_034_Interface.py +++ b/fastlane_bot/tests/test_034_Interface.py @@ -35,7 +35,6 @@ cfg_mock = Mock() cfg_mock.logger = MagicMock() -cfg_mock.GAS_TKN_IN_FLASHLOAN_TOKENS = False qi = QueryInterface(mgr=None, ConfigObj=cfg_mock) qi.state = [{'exchange_name': 'uniswap_v2', 'address': '0x123', 'tkn0_key': 'TKN-0x123', 'tkn1_key': 'TKN-0x456', 'pair_name': 'Pair-0x789', 'liquidity': 10}, {'exchange_name': 'sushiswap_v2', 'address': '0xabc', 'tkn0_key': 'TKN-0xabc', 'tkn1_key': 'TKN-0xdef', 'pair_name': 'Pair-0xghi', 'liquidity': 0}] diff --git a/fastlane_bot/tests/test_035_Utils.py b/fastlane_bot/tests/test_035_Utils.py index 712c0e53b..6f7ab23a1 100644 --- a/fastlane_bot/tests/test_035_Utils.py +++ b/fastlane_bot/tests/test_035_Utils.py @@ -12,6 +12,7 @@ from web3.types import HexBytes from fastlane_bot import Bot +from fastlane_bot.events.interfaces.event import Event from fastlane_bot.events.pools import UniswapV2Pool, UniswapV3Pool, BancorV3Pool, CarbonV1Pool from fastlane_bot.events.utils import filter_latest_events, complex_handler from fastlane_bot.tools.cpc import ConstantProductCurve as CPC @@ -47,10 +48,10 @@ def exchange_name_from_event(self, event): return 'uniswap_v2' mocked_mgr = MockManager() -event1 = AttributeDict({'args': {'reserve0': 100, 'reserve1': 100}, 'event': 'Sync', 'address': '0xabc', 'blockNumber': 5, 'transactionIndex': 0, 'logIndex': 0}) -event2 = AttributeDict({'args': {'reserve0': 200, 'reserve1': 200}, 'event': 'Sync', 'address': '0xabc', 'blockNumber': 10, 'transactionIndex': 1, 'logIndex': 1}) -event3 = AttributeDict({'args': {'reserve0': 300, 'reserve1': 300}, 'event': 'Sync', 'address': '0xdef', 'blockNumber': 7, 'transactionIndex': 1, 'logIndex': 1}) -mock_events = [[event1, event2, event3]] +event1 = Event.from_dict({'args': {'reserve0': 100, 'reserve1': 100}, 'event': 'Sync', 'address': '0xabc', 'blockNumber': 5, 'transactionIndex': 0, 'logIndex': 0, 'transactionHash': '', 'blockHash': ''}) +event2 = Event.from_dict({'args': {'reserve0': 200, 'reserve1': 200}, 'event': 'Sync', 'address': '0xabc', 'blockNumber': 10, 'transactionIndex': 1, 'logIndex': 1, 'transactionHash': '', 'blockHash': ''}) +event3 = Event.from_dict({'args': {'reserve0': 300, 'reserve1': 300}, 'event': 'Sync', 'address': '0xdef', 'blockNumber': 7, 'transactionIndex': 1, 'logIndex': 1, 'transactionHash': '', 'blockHash': ''}) +mock_events = [event1, event2, event3] # ------------------------------------------------------------ @@ -62,9 +63,9 @@ def test_test_filter_latest_events(): # ------------------------------------------------------------ result = filter_latest_events(mocked_mgr, mock_events) - assert (len(result) == len({event['address'] for event in result})) - pool_address = result[0]['address'] - pool_events = [event for event in mock_events[0] if (event['address'] == pool_address)] + assert (len(result) == len({event.address for event in result})) + pool_address = result[0].address + pool_events = [event for event in mock_events if (event.address == pool_address)] # ------------------------------------------------------------ diff --git a/fastlane_bot/tests/test_036_Manager.py b/fastlane_bot/tests/test_036_Manager.py index 8d5ae2772..511c76ff9 100644 --- a/fastlane_bot/tests/test_036_Manager.py +++ b/fastlane_bot/tests/test_036_Manager.py @@ -14,6 +14,7 @@ from unittest.mock import MagicMock from fastlane_bot import Bot, Config +from fastlane_bot.events.interfaces.event import Event from fastlane_bot.events.exchanges import UniswapV2, UniswapV3, CarbonV1, BancorV3 from fastlane_bot.events.managers.manager import Manager from fastlane_bot.events.pools.utils import get_pool_cid @@ -85,7 +86,7 @@ def test_test_update_from_event_uniswap_v2(): assert event['args']['reserve0'] != [pool['tkn0_balance'] for pool in manager.pool_data if pool['address'] == event['address']][0] - manager.update_from_event(event) + manager.update_from_event(Event.from_dict(event)) assert event['address'] in [pool['address'] for pool in manager.pool_data] assert event['args']['reserve0'] == [pool['tkn0_balance'] for pool in manager.pool_data if pool['address'] == event['address']][0] @@ -105,7 +106,7 @@ def test_test_update_from_event_uniswap_v3(): assert event['args']['liquidity'] != [pool['liquidity'] for pool in manager.pool_data if pool['address'] == event['address']][0] - manager.update_from_event(event) + manager.update_from_event(Event.from_dict(event)) assert event['address'] in [pool['address'] for pool in manager.pool_data] assert event['args']['liquidity'] == [pool['liquidity'] for pool in manager.pool_data if pool['address'] == event['address']][0] @@ -126,8 +127,8 @@ def test_test_update_from_event_carbon_v1_update(): event_create_for_update = event_data['carbon_v1_event_create_for_update'] event = event_data['carbon_v1_event_update'] - manager.update_from_event(event_create_for_update) - pools_to_add_from_contracts = [event[2]['args']['id'] for event in manager.pools_to_add_from_contracts] + manager.update_from_event(Event.from_dict(event_create_for_update)) + pools_to_add_from_contracts = [event[2].args['id'] for event in manager.pools_to_add_from_contracts] assert event['args']['id'] in pools_to_add_from_contracts @@ -148,7 +149,7 @@ def test_test_update_from_event_carbon_v1_create(): manager.pool_data = [pool for pool in manager.pool_data if pool['cid'] != event['args']['id']] assert event['args']['id'] not in [pool['cid'] for pool in manager.pool_data] - manager.update_from_event(event) + manager.update_from_event(Event.from_dict(event)) assert event['args']['id'] not in [pool['cid'] for pool in manager.pool_data] # - @@ -171,7 +172,7 @@ def test_test_update_from_event_carbon_v1_delete(): manager.pool_data = [pool for pool in manager.pool_data if pool['cid'] != cid] assert cid not in [pool['cid'] for pool in manager.pool_data] - manager.update_from_event(event) + manager.update_from_event(Event.from_dict(event)) assert cid in [p[-1] for p in manager.pools_to_add_from_contracts] fake_pool_data = { "address": event['address'], @@ -183,5 +184,5 @@ def test_test_update_from_event_carbon_v1_delete(): manager.pool_data.append(fake_pool_data) event['event'] = 'StrategyDeleted' - manager.update_from_event(event) + manager.update_from_event(Event.from_dict(event)) assert cid not in [pool['cid'] for pool in manager.pool_data] \ No newline at end of file diff --git a/fastlane_bot/tests/test_037_Exchanges.py b/fastlane_bot/tests/test_037_Exchanges.py index 81a51b5ea..27f1ad82e 100644 --- a/fastlane_bot/tests/test_037_Exchanges.py +++ b/fastlane_bot/tests/test_037_Exchanges.py @@ -11,6 +11,7 @@ import json from fastlane_bot import Bot +from fastlane_bot.events.interfaces.event import Event from fastlane_bot.events.exchanges.balancer import Balancer from fastlane_bot.tools.cpc import ConstantProductCurve as CPC from fastlane_bot.events.exchanges import UniswapV2, UniswapV3, CarbonV1, BancorV3, BancorV2, BancorPol, SolidlyV2 @@ -261,7 +262,7 @@ def test_test_bancor_v2_exchange(): async def test_bancor_v2_exchange(): assert (bancor_v2_exchange.get_abi() == BANCOR_V2_CONVERTER_ABI) assert (await bancor_v2_exchange.get_fee('', mocked_contract) == (3000, 0.003)) - assert (await bancor_v2_exchange.get_tkn0('', mocked_contract, setup_data['bancor_v2_event']) == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') + assert (await bancor_v2_exchange.get_tkn0('', mocked_contract, Event.from_dict(setup_data['bancor_v2_event'])) == '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') # Run the test in an event loop asyncio.run(test_bancor_v2_exchange()) @@ -283,7 +284,7 @@ def test_test_carbon_v1_exchange_update(): async def test_carbon_v1_exchange_update(): assert (carbon_v1_exchange.get_abi() == CARBON_CONTROLLER_ABI) assert (await carbon_v1_exchange.get_fee('', mocked_contract) == ('2000', 0.002)) - assert (await carbon_v1_exchange.get_tkn0('', mocked_contract, setup_data['carbon_v1_event_update']) == setup_data['carbon_v1_event_update']['args']['token0']) + assert (await carbon_v1_exchange.get_tkn0('', mocked_contract, Event.from_dict(setup_data['carbon_v1_event_update'])) == setup_data['carbon_v1_event_update']['args']['token0']) # Run the test in an event loop asyncio.run(test_carbon_v1_exchange_update()) @@ -305,7 +306,7 @@ def test_test_carbon_v1_exchange_create(): async def test_carbon_v1_exchange_create(): assert (carbon_v1_exchange.get_abi() == CARBON_CONTROLLER_ABI) assert (await carbon_v1_exchange.get_fee('', mocked_contract) == ('2000', 0.002)) - assert (await carbon_v1_exchange.get_tkn0('', mocked_contract, setup_data['carbon_v1_event_create']) == setup_data['carbon_v1_event_create']['args']['token0']) + assert (await carbon_v1_exchange.get_tkn0('', mocked_contract, Event.from_dict(setup_data['carbon_v1_event_create'])) == setup_data['carbon_v1_event_create']['args']['token0']) # Run the test in an event loop asyncio.run(test_carbon_v1_exchange_create()) @@ -333,7 +334,7 @@ def test_test_carbon_v1_exchange_delete(): async def test_bancor_pol_exchange(): assert (bancor_pol_exchange.get_abi() == BANCOR_POL_ABI) assert (await bancor_pol_exchange.get_fee('', mocked_contract) == ('0.000', 0.0)) - assert (await bancor_pol_exchange.get_tkn0('', mocked_contract, setup_data['bancor_pol_trading_enabled_event']) == "0x86772b1409b61c639EaAc9Ba0AcfBb6E238e5F83") + assert (await bancor_pol_exchange.get_tkn0('', mocked_contract, Event.from_dict(setup_data['bancor_pol_trading_enabled_event'])) == "0x86772b1409b61c639EaAc9Ba0AcfBb6E238e5F83") # Run the test in an event loop asyncio.run(test_bancor_pol_exchange()) \ No newline at end of file diff --git a/fastlane_bot/tests/test_039_TestMultiMode.py b/fastlane_bot/tests/test_039_TestMultiMode.py index dc47761d1..b3c875d70 100644 --- a/fastlane_bot/tests/test_039_TestMultiMode.py +++ b/fastlane_bot/tests/test_039_TestMultiMode.py @@ -140,6 +140,7 @@ def test_test_tax_tokens(): # ------------------------------------------------------------ assert any(token.address in cfg.TAX_TOKENS for token in tokens), f"[TestMultiMode], DB does not include any tax tokens" + assert len(CCm) == 516, f"[NBTest 039 TestMultiMode] Expected 516 curves, found {len(CCm)}" for curve in CCm: for token in cfg.TAX_TOKENS: @@ -178,6 +179,7 @@ def test_test_combos_and_tokens(): # ------------------------------------------------------------ # + + assert len(CCm) == 516, f"[NBTest 039 TestMultiMode] Expected 516 curves, found {len(CCm)}" arb_finder = bot._get_arb_finder("multi") finder = arb_finder( flashloan_tokens=flashloan_tokens, @@ -205,6 +207,7 @@ def test_test_expected_output(): # ------------------------------------------------------------ # + + assert len(CCm) == 516, f"[NBTest 039 TestMultiMode] Expected 516 curves, found {len(CCm)}" arb_finder = bot._get_arb_finder("multi") finder = arb_finder( flashloan_tokens=flashloan_tokens, diff --git a/fastlane_bot/tests/test_042_TestBancorV3ModeTwoHop.py b/fastlane_bot/tests/test_042_TestBancorV3ModeTwoHop.py index 012c8b757..b94c8b0dc 100644 --- a/fastlane_bot/tests/test_042_TestBancorV3ModeTwoHop.py +++ b/fastlane_bot/tests/test_042_TestBancorV3ModeTwoHop.py @@ -206,7 +206,7 @@ def test_test_trade_merge(): ) assert len(calculated_trade_instructions) == 3 # Aggregate multiple Bancor V3 trades into a single trade - calculated_trade_instructions = TxRouteHandler.aggregate_bancor_v3_trades( + calculated_trade_instructions = tx_route_handler.aggregate_bancor_v3_trades( calculated_trade_instructions ) assert len(calculated_trade_instructions) == 2 diff --git a/fastlane_bot/tests/test_049_CustomTradingFees.py b/fastlane_bot/tests/test_049_CustomTradingFees.py index e6b2be248..c759db5df 100644 --- a/fastlane_bot/tests/test_049_CustomTradingFees.py +++ b/fastlane_bot/tests/test_049_CustomTradingFees.py @@ -14,6 +14,7 @@ from unittest.mock import MagicMock from fastlane_bot import Bot, Config +from fastlane_bot.events.interfaces.event import Event from fastlane_bot.events.exchanges import UniswapV2, UniswapV3, CarbonV1, BancorV3 from fastlane_bot.events.managers.manager import Manager Base = None @@ -77,7 +78,7 @@ def test_test_update_from_event_carbon_v1_pair_create(): assert (event['args']['token0'], event['args']['token1']) not in manager.fee_pairs[exchange_name] - manager.update_from_event(event) + manager.update_from_event(Event.from_dict(event)) assert (event['args']['token0'], event['args']['token1']) in manager.fee_pairs[exchange_name] @@ -112,7 +113,7 @@ async def test_update_from_event_carbon_v1_trading_fee_updated(): # find all pools with fee==prevFeePPM prev_default_pools = [idx for idx, pool in enumerate(manager.pool_data) if pool['fee'] == prevFeePPM] - manager.update_from_event(event) + manager.update_from_event(Event.from_dict(event)) for idx in prev_default_pools: assert manager.pool_data[idx]['fee'] == newFeePPM diff --git a/fastlane_bot/tests/test_051_BalancerFlashloans.py b/fastlane_bot/tests/test_051_BalancerFlashloans.py deleted file mode 100644 index 9449bc1d1..000000000 --- a/fastlane_bot/tests/test_051_BalancerFlashloans.py +++ /dev/null @@ -1,358 +0,0 @@ -# ------------------------------------------------------------ -# Auto generated test file `test_051_BalancerFlashloans.py` -# ------------------------------------------------------------ -# source file = NBTest_051_BalancerFlashloans.py -# test id = 051 -# test comment = BalancerFlashloans -# ------------------------------------------------------------ - - - -""" -This module contains the tests for the exchanges classes -""" -from fastlane_bot import Bot, Config -from fastlane_bot.bot import CarbonBot -from fastlane_bot.tools.cpc import ConstantProductCurve as CPC -from fastlane_bot.events.exchanges import UniswapV2, UniswapV3, CarbonV1, BancorV3 -from fastlane_bot.events.interface import QueryInterface -from fastlane_bot.helpers import TradeInstruction, TxRouteHandler -from fastlane_bot.events.managers.manager import Manager -from fastlane_bot.events.interface import QueryInterface -from joblib import Parallel, delayed -import math -import json -print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(CPC)) -print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(Bot)) -print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(UniswapV2)) -print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(UniswapV3)) -print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(CarbonV1)) -print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(BancorV3)) -from fastlane_bot.testing import * - -#plt.style.use('seaborn-dark') -plt.rcParams['figure.figsize'] = [12,6] -from fastlane_bot import __VERSION__ -require("3.0", __VERSION__) - - - -C = cfg = Config.new(config=Config.CONFIG_MAINNET) -cfg.DEFAULT_MIN_PROFIT_GAS_TOKEN = 0.00001 -assert (C.NETWORK == C.NETWORK_MAINNET) -assert (C.PROVIDER == C.PROVIDER_ALCHEMY) -setup_bot = CarbonBot(ConfigObj=C) -pools = None - -with open('fastlane_bot/tests/_data/latest_pool_data_testing.json') as f: - pools = json.load(f) - - -pools = [pool for pool in pools] -pools[0] -static_pools = pools -state = pools -exchanges = list({ex['exchange_name'] for ex in state}) -db = QueryInterface(state=state, ConfigObj=C, exchanges=exchanges) -setup_bot.db = db - -static_pool_data_filename = "static_pool_data" - -static_pool_data = pd.read_csv(f"fastlane_bot/data/{static_pool_data_filename}.csv", low_memory=False) - -uniswap_v2_event_mappings = pd.read_csv("fastlane_bot/data/uniswap_v2_event_mappings.csv", low_memory=False) - -tokens = pd.read_csv("fastlane_bot/data/tokens.csv", low_memory=False) - -exchanges = "carbon_v1,bancor_v3,uniswap_v3,uniswap_v2,sushiswap_v2" - -exchanges = exchanges.split(",") - - -alchemy_max_block_fetch = 20 -static_pool_data["cid"] = [ - cfg.w3.keccak(text=f"{row['descr']}").hex() - for index, row in static_pool_data.iterrows() - ] -static_pool_data = [ - row for index, row in static_pool_data.iterrows() - if row["exchange_name"] in exchanges -] - -static_pool_data = pd.DataFrame(static_pool_data) -static_pool_data['exchange_name'].unique() -mgr = Manager( - web3=cfg.w3, - w3_async=cfg.w3_async, - cfg=cfg, - pool_data=static_pool_data.to_dict(orient="records"), - SUPPORTED_EXCHANGES=exchanges, - alchemy_max_block_fetch=alchemy_max_block_fetch, - uniswap_v2_event_mappings=uniswap_v2_event_mappings, - tokens=tokens.to_dict(orient="records"), -) - -start_time = time.time() -Parallel(n_jobs=-1, backend="threading")( - delayed(mgr.add_pool_to_exchange)(row) for row in mgr.pool_data -) -cfg.logger.info(f"Time taken to add initial pools: {time.time() - start_time}") - -mgr.deduplicate_pool_data() -cids = [pool["cid"] for pool in mgr.pool_data] -assert len(cids) == len(set(cids)), "duplicate cid's exist in the pool data" -def init_bot(mgr: Manager) -> CarbonBot: - """ - Initializes the bot. - - Parameters - ---------- - mgr : Manager - The manager object. - - Returns - ------- - CarbonBot - The bot object. - """ - mgr.cfg.logger.info("Initializing the bot...") - bot = CarbonBot(ConfigObj=mgr.cfg) - bot.db = db - bot.db.mgr = mgr - assert isinstance( - bot.db, QueryInterface - ), "QueryInterface not initialized correctly" - return bot -bot = init_bot(mgr) -bot.db.remove_unmapped_uniswap_v2_pools() -bot.db.remove_zero_liquidity_pools() -bot.db.remove_unsupported_exchanges() -tokens = bot.db.get_tokens() -ADDRDEC = {t.address: (t.address, int(t.decimals)) for t in tokens if not math.isnan(t.decimals)} -flashloan_tokens = bot.RUN_FLASHLOAN_TOKENS -CCm = bot.get_curves() -pools = db.get_pool_data_with_tokens() - -arb_mode = "multi_pairwise" - - -# ------------------------------------------------------------ -# Test 051 -# File test_051_BalancerFlashloans.py -# Segment Test_extract_flashloan_tokens -# ------------------------------------------------------------ -def test_test_extract_flashloan_tokens(): -# ------------------------------------------------------------ - - # + - ti1 = TradeInstruction( - cid='4083388403051261561560495289181218537544', - tknin='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - amtin=5000, - tknout='0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', - amtout=1, - ConfigObj=cfg, - db = db, - tknin_dec_override = 6, - tknout_dec_override = 8, - tknin_addr_override = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - tknout_addr_override = '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', - exchange_override = 'bancor_v3' - ) - - ti2 = TradeInstruction( - cid='4083388403051261561560495289181218537544', - tknin='0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', - amtin=1, - tknout='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - amtout=5005, - ConfigObj=cfg, - db = db, - tknout_dec_override = 8, - tknin_dec_override = 6, - tknout_addr_override = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - tknin_addr_override = '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', - exchange_override = 'carbon_v1' - ) - - ti3 = TradeInstruction( - cid='4083388403051261561560495289181218537544', - tknin='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - amtin=5000, - tknout='0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', - amtout=1, - ConfigObj=cfg, - db = db, - tknin_dec_override = 6, - tknout_dec_override = 8, - tknin_addr_override = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - tknout_addr_override = '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', - exchange_override = 'bancor_v3' - ) - - ti4 = TradeInstruction( - cid='4083388403051261561560495289181218537544', - tknin='0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', - amtin=0.2, - tknout='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - amtout=1000, - ConfigObj=cfg, - db = db, - tknout_dec_override = 8, - tknin_dec_override = 6, - tknout_addr_override = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - tknin_addr_override = '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', - exchange_override = 'carbon_v1' - ) - ti5 = TradeInstruction( - cid='4083388403051261561560495289181218537544', - tknin='0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', - amtin=0.3, - tknout='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - amtout=2000, - ConfigObj=cfg, - db = db, - tknout_dec_override = 8, - tknin_dec_override = 6, - tknout_addr_override = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - tknin_addr_override = '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', - exchange_override = 'carbon_v1' - ) - - ti6 = TradeInstruction( - cid='4083388403051261561560495289181218537544', - tknin='0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', - amtin=0.5, - tknout='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - amtout=3005, - ConfigObj=cfg, - db = db, - tknout_dec_override = 8, - tknin_dec_override = 6, - tknout_addr_override = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - tknin_addr_override = '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', - exchange_override = 'carbon_v1' - ) - - ti7 = TradeInstruction( - cid='4083388403051261561560495289181218537544', - tknin='0xdAC17F958D2ee523a2206206994597C13D831ec7', - amtin=2000, - tknout='0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - amtout=1.5, - ConfigObj=cfg, - db = db, - tknin_dec_override = 6, - tknout_dec_override = 18, - tknin_addr_override = '0xdAC17F958D2ee523a2206206994597C13D831ec7', - tknout_addr_override = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - exchange_override = 'bancor_v3' - ) - - ti8 = TradeInstruction( - cid='4083388403051261561560495289181218537544', - tknin='0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - amtin=1.5, - tknout='0xdAC17F958D2ee523a2206206994597C13D831ec7', - amtout=3005, - ConfigObj=cfg, - db = db, - tknout_dec_override = 18, - tknin_dec_override = 6, - tknout_addr_override = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - tknin_addr_override = '0xdAC17F958D2ee523a2206206994597C13D831ec7', - exchange_override = 'carbon_v1' - ) - - ti9 = TradeInstruction( - cid='4083388403051261561560495289181218537544', - tknin='0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - amtin=5, - tknout='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - amtout=10000, - ConfigObj=cfg, - db = db, - tknin_dec_override = 18, - tknout_dec_override = 6, - tknin_addr_override = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - tknout_addr_override = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - exchange_override = 'bancor_v3' - ) - - ti10 = TradeInstruction( - cid='4083388403051261561560495289181218537544', - tknin='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - amtin=10000, - tknout='0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - amtout=5.7, - ConfigObj=cfg, - db = db, - tknout_dec_override = 6, - tknin_dec_override = 18, - tknout_addr_override = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - tknin_addr_override = '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', - exchange_override = 'carbon_v1' - ) - - ti11 = TradeInstruction( - cid='4083388403051261561560495289181218537544', - tknin='0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C', - amtin=50000, - tknout='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - amtout=20000, - ConfigObj=cfg, - db = db, - tknin_dec_override = 18, - tknout_dec_override = 6, - tknin_addr_override = '0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C', - tknout_addr_override = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - exchange_override = 'bancor_v3' - ) - - ti12 = TradeInstruction( - cid='4083388403051261561560495289181218537544', - tknin='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - amtin=20000, - tknout='0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C', - amtout=50115, - ConfigObj=cfg, - db = db, - tknout_dec_override = 6, - tknin_dec_override = 18, - tknout_addr_override = '0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C', - tknin_addr_override = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', - exchange_override = 'carbon_v1' - ) - instructions = [ti1, ti2] - instructions2 = [ti3, ti4, ti5, ti6, ti7, ti8] - instructions3 = [ti3, ti4, ti5, ti6, ti7, ti8, ti9, ti10, ti11, ti12] - - route_handler = TxRouteHandler(instructions) - route_handler2 = TxRouteHandler(instructions2) - route_handler3 = TxRouteHandler(instructions3) - - - flashloan_tokens = route_handler._extract_flashloan_tokens(instructions) - flashloan_tokens2 = route_handler._extract_flashloan_tokens(instructions2) - flashloan_tokens3 = route_handler._extract_flashloan_tokens(instructions3) - - - flashloan_struct = route_handler._get_flashloan_struct(instructions2) - flashloan_struct2 = route_handler._get_flashloan_struct(instructions3) - - - flash_struct3 = route_handler.generate_flashloan_struct(instructions3) - assert len(flashloan_tokens2.keys()) == 2 - assert flashloan_tokens2['0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48']["flash_amt"] == 5000000000, f"expected flashloan amount of 5000000000, found {flashloan_tokens2['0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48']['flash_amt']}" - #assert flashloan_tokens2['0xdAC17F958D2ee523a2206206994597C13D831ec7']["flash_amt"] == 2000000000, f"expected flashloan amount of 2000000000, found {flashloan_tokens2['0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48']['flash_amt']}" - # assert len(flash_struct3) == 3, f"[Advanced Routing NBTest044] wrong number of flash tokens length, expected 3, got {len(flash_struct3)}" - # assert flash_struct3[0]['platformId'] == 2, f"[Balancer Flashloan Support [NBTest049]] wrong platformId, expected 2, got {flash_struct3[0]['platformId']}" - # assert flash_struct3[1]['platformId'] == 2, f"[Balancer Flashloan Support [NBTest049]] wrong platformId, expected 2, got {flash_struct3[1]['platformId']}" - # assert flash_struct3[2]['platformId'] == 7, f"[Balancer Flashloan Support [NBTest049]] wrong platformId, expected 7, got {flash_struct3[2]['platformId']}" - - # for flashloan in flash_struct3: - # assert len(flashloan['sourceTokens']) == len(flashloan['sourceAmounts']), f"[Balancer Flashloan Support [NBTest049]] number of source tokens does not match source amounts, tkns: {len(flashloan['sourceTokens'])} amts: {len(flashloan['sourceAmounts'])}" - # - - - - \ No newline at end of file diff --git a/fastlane_bot/tests/test_064_TestMultiAllMode.py b/fastlane_bot/tests/test_064_TestMultiAllMode.py index 8af2f4b8c..6d7ff45be 100644 --- a/fastlane_bot/tests/test_064_TestMultiAllMode.py +++ b/fastlane_bot/tests/test_064_TestMultiAllMode.py @@ -224,7 +224,7 @@ def test_test_expected_output(): assert len(r) >= 25, f"[NBTest64 TestMultiPairwiseAll Mode] Expected at least 25 arbs, found {len(r)}" assert multi_carbon_count > 0, f"[NBTest64 TestMultiPairwiseAll Mode] Not finding arbs with multiple Carbon curves." - assert carbon_wrong_direction_count == 0, f"[NBTest64 TestMultiPairwiseAll Mode] Expected all Carbon curves to have the same tkn in and tkn out. Mixing is currently not supported." + assert carbon_wrong_direction_count == 6, f"[NBTest64 TestMultiPairwiseAll Mode] Expected 6 Carbon curves to be in the opposite direction." # - \ No newline at end of file diff --git a/fastlane_bot/tests/test_068_exceptions.py b/fastlane_bot/tests/test_068_exceptions.py deleted file mode 100644 index 8316197f7..000000000 --- a/fastlane_bot/tests/test_068_exceptions.py +++ /dev/null @@ -1,54 +0,0 @@ -# ------------------------------------------------------------ -# Auto generated test file `test_068_exceptions.py` -# ------------------------------------------------------------ -# source file = NBTest_068_exceptions.py -# test id = 068 -# test comment = exceptions -# ------------------------------------------------------------ - - -import pytest - -from fastlane_bot.exceptions import AsyncUpdateRetryException - - -@pytest.mark.parametrize( - "message, id", - [ - ("Failed to update, retrying...", 'happy-1'), - ("Update failed at step 3, retrying...", 'happy-2'), - ("Temporary network issue, attempt retry...", 'happy-3'), - ], -) -def test_aync_update_retry_exception_with_message(message, id): - # Act - exception = AsyncUpdateRetryException(message) - - # Assert - assert str(exception) == message, f"Test case {id} failed: The exception message does not match the expected message." - -@pytest.mark.parametrize( - "message, id", - [ - ("", 'edge-1'), - ], -) -def test_aync_update_retry_exception_with_empty_message(message, id): - # Act - exception = AsyncUpdateRetryException(message) - - # Assert - assert str(exception) == message, f"Test case {id} failed: The exception message should be empty." - -@pytest.mark.parametrize( - "message, id", - [ - ('happy-1', 'happy-1'), - (None, 'happy-2'), - ('3', 'happy-3'), - ], -) -def test_aync_update_retry_exception_raises(message, id): - # Act & Assert - with pytest.raises(AsyncUpdateRetryException, match=message): - raise AsyncUpdateRetryException(message) \ No newline at end of file diff --git a/fastlane_bot/tests/test_072_TestTerraformer.py b/fastlane_bot/tests/test_072_TestTerraformer.py index 8c151b811..fbc8eb016 100644 --- a/fastlane_bot/tests/test_072_TestTerraformer.py +++ b/fastlane_bot/tests/test_072_TestTerraformer.py @@ -4,31 +4,33 @@ ''' from unittest.mock import MagicMock, AsyncMock -from run_blockchain_terraformer import organize_pool_details_balancer, organize_pool_details_uni_v2, organize_pool_details_solidly_v2, organize_pool_details_uni_v3 +import run_blockchain_terraformer as terraformer +ADDRESS_1 = "0x".ljust(42, "1") +ADDRESS_2 = "0x".ljust(42, "2") +ADDRESS_3 = "0x".ljust(42, "3") def test_organize_pool_details_uni_v2_strategy_id(): # Mock the input parameters pool_data = { "args": { - "pair": "0x123", - "token0": "0x456", - "token1": "0x789" + "pair": ADDRESS_1, + "token0": ADDRESS_2, + "token1": ADDRESS_3 }, "blockNumber": 123456 } token_manager = MagicMock() - exchange = "test_exchange" + exchange = terraformer.UNISWAP_V2_NAME default_fee = "0.3" web3 = MagicMock() - web3.to_checksum_address.return_value = "0x123" - # Process the function - result = organize_pool_details_uni_v2( + # Call the tested function + result = terraformer.organize_pool_details_uni_v2( pool_data, token_manager, exchange, default_fee, web3 ) - # Check if the result contains 'strategy_id' with value 0 + # Assert that the output 'strategy_id' is 0 assert "strategy_id" in result assert result["strategy_id"] == 0 @@ -36,25 +38,24 @@ def test_organize_pool_details_uni_v3_strategy_id(): # Mock the input parameters pool_data = { "args": { - "pool": "0x123", - "token0": "0x456", - "token1": "0x789", + "pool": ADDRESS_1, + "token0": ADDRESS_2, + "token1": ADDRESS_3, "tickSpacing": 10, "fee": "3000" }, "blockNumber": 123456 } token_manager = MagicMock() - exchange = "test_exchange" + exchange = terraformer.UNISWAP_V3_NAME web3 = MagicMock() - web3.to_checksum_address.return_value = "0x123" - # Call the function with the mock objects - pool_info = organize_pool_details_uni_v3( + # Call the tested function + pool_info = terraformer.organize_pool_details_uni_v3( pool_data, token_manager, exchange, web3 ) - # Assert the 'strategy_id' in the output is 0 + # Assert that the output 'strategy_id' is 0 assert "strategy_id" in pool_info assert pool_info["strategy_id"] == 0 @@ -62,30 +63,28 @@ def test_organize_pool_details_solidly_v2_strategy_id(): # Mock the input parameters pool_data = { "args": { - "pair": "0x123", - "token0": "0x456", - "token1": "0x789", + "pair": ADDRESS_1, + "token0": ADDRESS_2, + "token1": ADDRESS_3, "stable": True }, "blockNumber": 123456 } token_manager = MagicMock() - exchange = "test_exchange" + exchange = terraformer.SOLIDLY_V2_NAME exchange_object = MagicMock() exchange_object.get_abi.return_value = "test_abi" exchange_object.get_fee = AsyncMock(return_value=("0.3", 0.3)) web3 = MagicMock() - web3.to_checksum_address.return_value = "0x123" async_web3 = MagicMock() async_web3.eth.contract.return_value = AsyncMock() - # Run the coroutine with asyncio.run (Python 3.7+) - pool_info = organize_pool_details_solidly_v2( - pool_data, token_manager, exchange, exchange_object, web3, async_web3 - ) - + # Call the tested function + pool_info = terraformer.organize_pool_details_solidly_v2( + pool_data, token_manager, exchange, exchange_object, web3, async_web3 + ) - # Check if the result contains 'strategy_id' with value 0 + # Assert that the output 'strategy_id' is 0 assert "strategy_id" in pool_info assert pool_info["strategy_id"] == 0 @@ -95,23 +94,17 @@ def test_organize_pool_details_balancer_strategy_id(): "swapEnabled": True, "id": "pool123", "poolType": "type1", - "address": "0x123", + "address": ADDRESS_1, "tokens": [ - {"address": "0x456", "symbol": "TKN1", "decimals": 18, "weight": 0.5}, - {"address": "0x789", "symbol": "TKN2", "decimals": 18, "weight": 0.5} + {"address": ADDRESS_2, "symbol": "TKN1", "decimals": 18, "weight": 0.5}, + {"address": ADDRESS_3, "symbol": "TKN2", "decimals": 18, "weight": 0.5} ], "swapFee": "0.003" } - token_prices = { - "0x456": {"usd": "1"}, - "0x789": {"usd": "2"} - } - web3 = MagicMock() - web3.to_checksum_address.side_effect = lambda x: x # Mock checksum address to return the same value - # Call the function - pool_info = organize_pool_details_balancer(pool_data, token_prices, web3) + # Call the tested function + pool_info = terraformer.organize_pool_details_balancer(pool_data) - # Check the 'strategy_id' in the output + # Assert that the output 'strategy_id' is 0 assert "strategy_id" in pool_info assert pool_info["strategy_id"] == 0 \ No newline at end of file diff --git a/fastlane_bot/tests/test_073_TestPoolFinder.py b/fastlane_bot/tests/test_073_TestPoolFinder.py new file mode 100644 index 000000000..bfd1611c9 --- /dev/null +++ b/fastlane_bot/tests/test_073_TestPoolFinder.py @@ -0,0 +1,74 @@ +from fastlane_bot.pool_finder import PoolFinder + + +def test_find_unsupported_pairs(): + flashloan_tokens = ['TokenA', 'TokenB'] + carbon_pairs = [('TokenA', 'TokenC'), ('TokenC', 'TokenD'), ('TokenB', 'TokenE')] + external_pairs = {frozenset(('TokenA', 'TokenB')), frozenset(('TokenC', 'TokenE'))} + # Expected result + # ('TokenA', 'TokenC') is supported by flashloan_tokens but not in external_pairs + # ('TokenC', 'TokenD') is unsupported by flashloan_tokens and not in external_pairs + # ('TokenB', 'TokenE') is supported by flashloan_tokens but not in external_pairs + expected_result = [('TokenA', 'TokenC'), ('TokenC', 'TokenD'), ('TokenB', 'TokenE')] + + # Function under test + result = PoolFinder._find_unsupported_pairs(flashloan_tokens, carbon_pairs, external_pairs) + + # Check that the function returns the correct list of unsupported pairs + assert sorted(result) == sorted(expected_result) + +def test_find_unsupported_triangles(): + flashloan_tokens = ['TokenA', 'TokenB'] + carbon_pairs = [('TokenA', 'TokenC'), ('TokenC', 'TokenD'), ('TokenB', 'TokenE')] + external_pairs = {frozenset(('TokenA', 'TokenC')), frozenset(('TokenA', 'TokenD'))} + # Expected result + # ('TokenA', 'TokenC') is unsupported by triangles + # ('TokenC', 'TokenD') is supported by triangles + # ('TokenB', 'TokenE') is unsupported by triangles + expected_result = [('TokenA', 'TokenC'), ('TokenB', 'TokenE')] + + # Function under test + result = PoolFinder._find_unsupported_triangles(flashloan_tokens, carbon_pairs, external_pairs) + + # Check that the function returns the correct list of unsupported pairs + assert len(expected_result) == len(result) + assert sorted(expected_result) == sorted(result) + + +def test_extract_pairs(): + # Sample data for testing + uni_v3_exchanges = ["fred_ex"] + flashloan_tokens = ["BNT"] + pools = [ + {"exchange_name": "CarbonX", "tkn0_address": "WBTC", "tkn1_address": "BNT"}, + {"exchange_name": "CarbonX", "tkn0_address": "BNT", "tkn1_address": "WBTC"}, # Reverse order, should be treated as same + {"exchange_name": "NonCarbon", "tkn0_address": "WETH", "tkn1_address": "USDT"}, + {"exchange_name": "NonCarbon", "tkn0_address": "USDC", "tkn1_address": "WBTC"}, + {"exchange_name": "CarbonX", "tkn0_address": "WETH", "tkn1_address": "USDC"} + ] + carbon_forks = ["CarbonX"] + + # Expected results + expected_carbon_pairs = {frozenset(('WBTC', 'BNT')), frozenset(('WETH', 'USDC'))} + expected_other_pairs = {frozenset(('WETH', 'USDT')), frozenset(('USDC', 'WBTC'))} + #expected_carbon_pairs = [('WBTC', 'BNT'), ('WETH', 'USDC')] + pool_finder = PoolFinder( + uni_v3_forks=uni_v3_exchanges, + carbon_forks=carbon_forks, + flashloan_tokens=flashloan_tokens, + exchanges={}, + web3=None, + multicall_address="" + ) + + # Call the function with test data + carbon_pairs, other_pairs = pool_finder._extract_pairs(pools) + + # Assert the results are as expected + assert frozenset(carbon_pairs[0]) in expected_carbon_pairs + assert frozenset(carbon_pairs[1]) in expected_carbon_pairs + for _pair in other_pairs: + assert frozenset(_pair) in expected_other_pairs + #assert other_pairs == expected_other_pairs + assert len(carbon_pairs) == 2 + assert len(other_pairs) == 2 diff --git a/fastlane_bot/tests/test_899_CustomMulticall.py b/fastlane_bot/tests/test_899_CustomMulticall.py index da5628765..01ce9b732 100644 --- a/fastlane_bot/tests/test_899_CustomMulticall.py +++ b/fastlane_bot/tests/test_899_CustomMulticall.py @@ -9,18 +9,15 @@ from fastlane_bot.data.abi import CARBON_CONTROLLER_ABI import os -from unittest.mock import Mock, patch from dotenv import load_dotenv load_dotenv() -import time from fastlane_bot.config.multicaller import MultiCaller -from fastlane_bot.config.multicaller import ContractMethodWrapper from web3 import Web3 +from json import dumps print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(MultiCaller)) -print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(ContractMethodWrapper)) from fastlane_bot.testing import * @@ -32,176 +29,37 @@ WEB3_ALCHEMY_PROJECT_ID = os.environ.get("WEB3_ALCHEMY_PROJECT_ID") RPC_URL = f"https://eth-mainnet.alchemyapi.io/v2/{WEB3_ALCHEMY_PROJECT_ID}" +MULTICALL_CONTRACT_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11" CARBON_CONTROLLER_ADDRESS = "0xC537e898CD774e2dCBa3B14Ea6f34C93d5eA45e1" -class MockWeb3: - class HTTPProvider: - pass - - class eth: - @staticmethod - def contract(address, abi): - return Mock() - - @staticmethod - def to_checksum_address(address): - return address - - @staticmethod - def to_checksum_address(address): - return address - -class MockContract: - - def __init__(self, address, abi): - self.address = address - self.abi = abi - - def functions(self): - return Mock() - - def encodeABI(self): - return Mock() - - def address(self): - return self.address - - def abi(self): - return self.abi - - def to_checksum_address(self, address): - return address - - # handle encoded data - def encode_abi(self): - return Mock() - - def decode_abi(self): - return Mock() - -start_time = time.time() - -w3 = Web3(Web3.HTTPProvider(RPC_URL, request_kwargs={'timeout': 60})) -contract = w3.eth.contract(address=CARBON_CONTROLLER_ADDRESS, abi=CARBON_CONTROLLER_ABI) - -mainnet_pairs = contract.caller.pairs() - -if len(mainnet_pairs) > 10: - mainnet_pairs = mainnet_pairs[:10] - -pair_fees_without_multicall = [contract.caller.pairTradingFeePPM(pair[0], pair[1]) for pair in mainnet_pairs] - -pair_fees_time_without_multicall = time.time() - start_time - -start_time = time.time() - -strats_by_pair_without_multicall = [contract.caller.strategiesByPair(pair[0], pair[1], 0, 5000) for pair in mainnet_pairs] - -strats_by_pair_time_without_multicall = time.time() - start_time - - +web3 = Web3(Web3.HTTPProvider(RPC_URL)) +multicaller = MultiCaller(web3, MULTICALL_CONTRACT_ADDRESS) +carbon_contract = web3.eth.contract(address=CARBON_CONTROLLER_ADDRESS, abi=CARBON_CONTROLLER_ABI) # ------------------------------------------------------------ # Test 899 # File test_899_CustomMulticall.py -# Segment test_multicaller_init +# Segment test_multi_caller # ------------------------------------------------------------ -def test_test_multicaller_init(): +def test_test_multi_caller(): # ------------------------------------------------------------ # + - - original_method = Mock() - multicaller = Mock() - - wrapper = ContractMethodWrapper(original_method, multicaller) - - assert wrapper.original_method == original_method - assert wrapper.multicaller == multicaller - # - - + pairs = carbon_contract.caller.pairs()[:10] + fee_funcs = [carbon_contract.functions.pairTradingFeePPM(*pair) for pair in pairs] + strat_funcs = [carbon_contract.functions.strategiesByPair(*pair, 0, 5000) for pair in pairs] + funcs = fee_funcs + strat_funcs -# ------------------------------------------------------------ -# Test 899 -# File test_899_CustomMulticall.py -# Segment test_contract_method_wrapper_call -# ------------------------------------------------------------ -def test_test_contract_method_wrapper_call(): -# ------------------------------------------------------------ - - # + - original_method = Mock() - multicaller = Mock() - - wrapper = ContractMethodWrapper(original_method, multicaller) - - result = wrapper('arg1', kwarg1='kwarg1') - - original_method.assert_called_with('arg1', kwarg1='kwarg1') - multicaller.add_call.assert_called_with(result) - # - - + for func in funcs: + multicaller.add_call(func) -# ------------------------------------------------------------ -# Test 899 -# File test_899_CustomMulticall.py -# Segment test_multi_caller_init -# ------------------------------------------------------------ -def test_test_multi_caller_init(): -# ------------------------------------------------------------ - - # + - contract = Mock() - web3 = MockWeb3() - - multicaller = MultiCaller(contract, web3=web3) - - assert multicaller.contract == contract - assert multicaller.block_identifier == 'latest' - assert multicaller._contract_calls == [] - # - - + block_number = web3.eth.get_block('latest').number -# ------------------------------------------------------------ -# Test 899 -# File test_899_CustomMulticall.py -# Segment test_multi_caller_add_call -# ------------------------------------------------------------ -def test_test_multi_caller_add_call(): -# ------------------------------------------------------------ - - # + - contract = Mock() - web3 = MockWeb3() - - multicaller = MultiCaller(contract, web3=web3) - fn = Mock() - - multicaller.add_call(fn, 'arg1', kwarg1='kwarg1') - - assert len(multicaller._contract_calls) == 1 - # - - + sc_calls = [func.call(block_identifier=block_number) for func in funcs] + mc_calls = multicaller.run_calls(block_identifier=block_number) -# ------------------------------------------------------------ -# Test 899 -# File test_899_CustomMulticall.py -# Segment test_multi_caller_context_manager -# ------------------------------------------------------------ -def test_test_multi_caller_context_manager(): -# ------------------------------------------------------------ - - # + - contract = Mock() - web3 = MockWeb3() - multicaller = MultiCaller(contract, web3=web3) - - with patch.object(multicaller, 'multicall') as mock_multicall: - with multicaller: - multicaller.multicall() - pass - - mock_multicall.assert_called_once() + for sc_output, mc_output in zip(sc_calls, mc_calls): + sc_output_str = dumps(sc_output, indent=4).lower() + mc_output_str = dumps(mc_output, indent=4).lower() + assert sc_output_str == mc_output_str, f"sc_output = {sc_output_str}, mc_output = {mc_output_str}" # - - - \ No newline at end of file diff --git a/fastlane_bot/tests/test_event_topics.py b/fastlane_bot/tests/test_event_topics.py new file mode 100644 index 000000000..506f9b280 --- /dev/null +++ b/fastlane_bot/tests/test_event_topics.py @@ -0,0 +1,51 @@ +import pytest + +from fastlane_bot.events.exchanges.carbon_v1 import CarbonV1 +from fastlane_bot.events.exchanges.bancor_pol import BancorPol +from fastlane_bot.events.exchanges.bancor_v2 import BancorV2 +from fastlane_bot.events.exchanges.bancor_v3 import BancorV3 +from fastlane_bot.events.exchanges.uniswap_v2 import UniswapV2 +from fastlane_bot.events.exchanges.uniswap_v3 import UniswapV3 +from fastlane_bot.events.exchanges.balancer import Balancer +from fastlane_bot.events.exchanges.solidly_v2 import SolidlyV2 + + +@pytest.mark.parametrize("cls,exchange_name,event_topics", [ + (CarbonV1, "carbon_v1", { + "StrategyCreated": "0xff24554f8ccfe540435cfc8854831f8dcf1cf2068708cfaf46e8b52a4ccc4c8d", + "StrategyUpdated": "0x720da23a5c920b1d8827ec83c4d3c4d90d9419eadb0036b88cb4c2ffa91aef7d", + "StrategyDeleted": "0x4d5b6e0627ea711d8e9312b6ba56f50e0b51d41816fd6fd38643495ac81d38b6", + "PairTradingFeePPMUpdated": "0x831434d05f3ad5f63be733ea463b2933c70d2162697fd200a22b5d56f5c454b6", + "TradingFeePPMUpdated": "0x66db0986e1156e2e747795714bf0301c7e1c695c149a738cb01bcf5cfead8465", + "PairCreated": "0x6365c594f5448f79c1cc1e6f661bdbf1d16f2e8f85747e13f8e80f1fd168b7c3", + }), + (BancorPol, "bancor_pol", { + "TokenTraded": "0x16ddee9b3f1b2e6f797172fe2cd10a214e749294074e075e451f95aecd0b958c", + "TradingEnabled": "0xae3f48c001771f8e9868e24d47b9e4295b06b1d78072acf96f167074aa3fab64", + }), + (BancorV2, "bancor_v2", { + "TokenRateUpdate": "0x77f29993cf2c084e726f7e802da0719d6a0ade3e204badc7a3ffd57ecb768c24", + }), + (BancorV3, "bancor_v3", { + "TradingLiquidityUpdated": "0x6e96dc5343d067ec486a9920e0304c3610ed05c65e45cc029d9b9fe7ecfa7620", + # "TotalLiquidityUpdated": "0x85a03952f50b8c00b32a521c32094023b64ef0b6d4511f423d44c480a62cb145", + }), + (UniswapV2, "uniswap_v2", { + "Sync": "0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1", + }), + (UniswapV3, "uniswap_v3", { + "Swap": "0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67", + }), + (UniswapV3, "pancakeswap_v3", { + "Swap": "0x19b47279256b2a23a1665c810c8d55a1758940ee09377d4f8d26497a3577dc83", + }), + (Balancer, "balancer", {}), + (SolidlyV2, "velocimeter_v2", { + "Sync": "0xcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a", + }), +]) +def test_event_topic(config, cls, exchange_name, event_topics): + exchange = cls(exchange_name=exchange_name) + for subscription in exchange.get_subscriptions(config.w3): + assert event_topics.pop(subscription._event.event_name) == subscription.topic + assert event_topics == {} diff --git a/fastlane_bot/utils.py b/fastlane_bot/utils.py index e1692d086..bfae0fe7b 100644 --- a/fastlane_bot/utils.py +++ b/fastlane_bot/utils.py @@ -23,7 +23,7 @@ def safe_int(value: int or float) -> int: def num_format(value: int or float) -> str: try: return "{0:.4f}".format(value) - except Exception as _: + except Exception: return str(value) @@ -68,6 +68,10 @@ def __getitem__(self, item): def decodeFloat(cls, value): """undoes the mantisse/exponent encoding in A,B""" return (value % cls.ONE) << (value // cls.ONE) + + @classmethod + def decodeRate(cls, value): + return (value / cls.ONE) ** 2 @classmethod def decode(cls, value): @@ -178,17 +182,12 @@ def p_start(self): @property def p_marg(self): + A = self.decodeFloat(int(self.A)) + B = self.decodeFloat(int(self.B)) if self.y == self.z: - return self.p_start - elif self.y == 0: - return self.p_end - raise NotImplementedError("p_marg not implemented for non-full / empty orders") - A = self.decodeFloat(self.A) - B = self.decodeFloat(self.B) - return self.decode(B + A * self.y / self.z) ** 2 - # https://github.com/bancorprotocol/carbon-simulator/blob/beta/benchmark/core/trade/impl.py - # 'marginalRate' : decodeRate(B + A if y == z else B + A * y / z), - + return self.decodeRate(B + A) + else: + return self.decodeRate(B + A * self.y/self.z) def find_latest_timestamped_folder(logging_path=None): """ diff --git a/main.py b/main.py index 42410df32..36633d9d9 100644 --- a/main.py +++ b/main.py @@ -5,9 +5,10 @@ (c) Copyright Bprotocol foundation 2023. Licensed under MIT """ - -from fastlane_bot.exceptions import AsyncUpdateRetryException, ReadOnlyException, FlashloanUnavailableException +from fastlane_bot.events.event_gatherer import EventGatherer +from fastlane_bot.exceptions import ReadOnlyException, FlashloanUnavailableException from fastlane_bot.events.version_utils import check_version_requirements +from fastlane_bot.pool_finder import PoolFinder from fastlane_bot.tools.cpc import T check_version_requirements(required_version="6.11.0", package_name="web3") @@ -38,18 +39,16 @@ get_config, get_loglevel, update_pools_from_events, + process_new_events, write_pool_data_to_disk, init_bot, get_cached_events, handle_subsequent_iterations, - verify_state_changed, handle_duplicates, get_latest_events, get_start_block, set_network_to_mainnet_if_replay, set_network_to_tenderly_if_replay, - verify_min_bnt_is_respected, - handle_target_token_addresses, get_current_block, handle_tenderly_event_exchanges, handle_static_pools_update, @@ -96,6 +95,7 @@ def int_or_none(x): "self_fund": is_true, "read_only": is_true, "is_args_test": is_true, + "pool_finder_period": int, } # Apply the transformations @@ -227,6 +227,7 @@ def main(args: argparse.Namespace) -> None: prefix_path: {args.prefix_path} self_fund: {args.self_fund} read_only: {args.read_only} + pool_finder_period: {args.pool_finder_period} +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -257,10 +258,6 @@ def main(args: argparse.Namespace) -> None: cfg, exchanges, args.blockchain, args.static_pool_data_filename, args.read_only ) - target_token_addresses = handle_target_token_addresses( - static_pool_data, args.target_tokens - ) - # Break if timeout is hit to test the bot flags if args.timeout == 1: cfg.logger.info("Timeout to test the bot flags") @@ -286,7 +283,7 @@ def main(args: argparse.Namespace) -> None: solidly_v2_event_mappings=solidly_v2_event_mappings, tokens=tokens.to_dict(orient="records"), replay_from_block=args.replay_from_block, - target_tokens=target_token_addresses, + target_tokens=args.target_tokens, tenderly_fork_id=args.tenderly_fork_id, tenderly_event_exchanges=tenderly_event_exchanges, w3_tenderly=w3_tenderly, @@ -308,19 +305,28 @@ def run(mgr, args, tenderly_uri=None) -> None: start_timeout = time.time() mainnet_uri = mgr.cfg.w3.provider.endpoint_uri handle_static_pools_update(mgr) + + event_gatherer = EventGatherer( + config=mgr.cfg, + w3=mgr.w3_async, + exchanges=mgr.exchanges, + ) + + pool_finder = PoolFinder( + carbon_forks=mgr.cfg.network.CARBON_V1_FORKS, + uni_v3_forks=mgr.cfg.network.UNI_V3_FORKS, + flashloan_tokens=args.flashloan_tokens, + exchanges=mgr.exchanges, + web3=mgr.web3, + multicall_address=mgr.cfg.network.MULTICALL_CONTRACT_ADDRESS + ) + while True: try: - # Save initial state of pool data to assert whether it has changed - initial_state = mgr.pool_data.copy() - # ensure 'last_updated_block' is in pool_data for all pools - for idx, pool in enumerate(mgr.pool_data): + for pool in mgr.pool_data: if "last_updated_block" not in pool: pool["last_updated_block"] = last_block_queried - mgr.pool_data[idx] = pool - if not pool["last_updated_block"]: - pool["last_updated_block"] = last_block_queried - mgr.pool_data[idx] = pool # Get current block number, then adjust to the block number reorg_delay blocks ago to avoid reorgs start_block, replay_from_block = get_start_block( @@ -366,6 +372,7 @@ def run(mgr, args, tenderly_uri=None) -> None: start_block, args.cache_latest_only, args.logging_path, + event_gatherer ) ) iteration_start_time = time.time() @@ -379,7 +386,7 @@ def run(mgr, args, tenderly_uri=None) -> None: f"Adding {len(mgr.pools_to_add_from_contracts)} new pools from contracts, " f"{len(mgr.pool_data)} total pools currently exist. Current block: {current_block}." ) - _run_async_update_with_retries(mgr, current_block=current_block) + async_update_pools_from_contracts(mgr, current_block=current_block) mgr.pools_to_add_from_contracts = [] # Increment the loop index @@ -426,12 +433,6 @@ def run(mgr, args, tenderly_uri=None) -> None: # Re-initialize the bot bot = init_bot(mgr) - # Verify that the state has changed - verify_state_changed(bot=bot, initial_state=initial_state, mgr=mgr) - - # Verify that the minimum profit in BNT is respected - verify_min_bnt_is_respected(bot=bot, mgr=mgr) - if args.use_specific_exchange_for_target_tokens is not None: target_tokens = bot.get_tokens_in_exchange( exchange_name=args.use_specific_exchange_for_target_tokens @@ -529,6 +530,16 @@ def run(mgr, args, tenderly_uri=None) -> None: mgr.solidly_v2_event_mappings = dict( solidly_v2_event_mappings[["address", "exchange"]].values ) + + if args.pool_finder_period > 0 and (loop_idx - 1) % args.pool_finder_period == 0: + mgr.cfg.logger.info(f"Searching for unsupported Carbon pairs.") + uni_v2, uni_v3, solidly_v2 = pool_finder.get_pools_for_unsupported_pairs(mgr.cfg, mgr.pool_data, arb_mode=args.arb_mode) + process_new_events(uni_v2, mgr.uniswap_v2_event_mappings, f"fastlane_bot/data/blockchain_data/{args.blockchain}/uniswap_v2_event_mappings.csv", args.read_only) + process_new_events(uni_v3, mgr.uniswap_v3_event_mappings, f"fastlane_bot/data/blockchain_data/{args.blockchain}/uniswap_v3_event_mappings.csv", args.read_only) + process_new_events(solidly_v2, mgr.solidly_v2_event_mappings, f"fastlane_bot/data/blockchain_data/{args.blockchain}/solidly_v2_event_mappings.csv", args.read_only) + handle_static_pools_update(mgr) + mgr.cfg.logger.info(f"Number of pools added: {len(uni_v2) + len(uni_v3) + len(solidly_v2)}") + last_block_queried = current_block total_iteration_time += time.time() - iteration_start_time @@ -539,10 +550,9 @@ def run(mgr, args, tenderly_uri=None) -> None: f"\n********************************************\n\n" ) - except Exception as e: + except Exception: mgr.cfg.logger.error(f"Error in main loop: {format_exc()}") mgr.cfg.logger.error( - f"[main] Error in main loop: {e}. Continuing... " f"Please report this error to the Fastlane Telegram channel if it persists." f"{mgr.cfg.logging_header}" ) @@ -553,27 +563,6 @@ def run(mgr, args, tenderly_uri=None) -> None: break -def _run_async_update_with_retries(mgr, current_block, max_retries=5): - failed_async_calls = 0 - - while failed_async_calls < max_retries: - try: - async_update_pools_from_contracts(mgr, current_block) - return # Successful execution - except AsyncUpdateRetryException as e: - failed_async_calls += 1 - mgr.cfg.logger.error(f"Attempt {failed_async_calls} failed: {e}") - mgr.update_remaining_pools() - - # Handling failure after retries - mgr.cfg.logger.error( - f"[main run.py] async_update_pools_from_contracts failed after " - f"{len(mgr.pools_to_add_from_contracts)} attempts. List of failed pools: {mgr.pools_to_add_from_contracts}" - ) - - raise AsyncUpdateRetryException("[main.py] async_update_pools_from_contracts failed after maximum retries.") - - if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument( @@ -602,7 +591,7 @@ def _run_async_update_with_retries(mgr, current_block, max_retries=5): "multi_triangle", "b3_two_hop", "multi_pairwise_pol", - "multi_pairwise_all", + "multi_pairwise_all" ], ) parser.add_argument( @@ -747,6 +736,11 @@ def _run_async_update_with_retries(mgr, current_block, max_retries=5): default=None, help="Custom RPC URL. If not set, the bot will use the default Alchemy RPC URL for the blockchain (if available).", ) + parser.add_argument( + "--pool_finder_period", + default=100, + help="Searches for pools that can service Carbon strategies that do not have viable routes.", + ) # Process the arguments args = parser.parse_args() diff --git a/run_blockchain_terraformer.py b/run_blockchain_terraformer.py index b9f661e7d..8435d393b 100644 --- a/run_blockchain_terraformer.py +++ b/run_blockchain_terraformer.py @@ -1,5 +1,4 @@ import math -from dataclasses import dataclass from typing import Tuple, List, Dict import pandas as pd @@ -16,7 +15,6 @@ from fastlane_bot.utils import safe_int from fastlane_bot.events.exchanges.solidly_v2 import SolidlyV2 -from fastlane_bot.events.exchanges.solidly_v2 import EXCHANGE_INFO as SOLIDLY_EXCHANGE_INFO from fastlane_bot.data.abi import ERC20_ABI, UNISWAP_V2_FACTORY_ABI, UNISWAP_V3_FACTORY_ABI import asyncio @@ -79,7 +77,7 @@ async def gather(): "coinbase_base": 0, "fantom": 5000, "mantle": 0, - "linea": 0 + "linea": 0, } ALCHEMY_KEY_DICT = { @@ -114,8 +112,7 @@ async def gather(): "optimism": "https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-optimism-v2", "coinbase_base": "https://api.studio.thegraph.com/query/24660/balancer-base-v2/version/latest", "avalanche": "https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-avalanche-v2", - "fantom": "https://api.thegraph.com/subgraphs/name/beethovenxfi/beethovenx", - + "fantom": "https://api.thegraph.com/subgraphs/name/beethovenxfi/beethovenx" } BANCOR_V2_NAME = "bancor_v2" @@ -252,21 +249,16 @@ async def gather(): "tkn7_balance", "tkn7_weight", ] -skip_token_list = ["0xaD67F7a72BA2ca971390B2a1dD907303bD577a4F".lower()] - -@dataclass -class TokenManager: - token_dict: Dict +skip_token_list = set(["0xaD67F7a72BA2ca971390B2a1dD907303bD577a4F"]) -def get_all_token_details(web3: Web3, network: str, write_path: str) -> TokenManager: +def get_all_token_details(network: str, write_path: str) -> dict: """ This function collects the number of decimals and symbol of a token, and formats it for use in a dataframe. - :param web3: the Web3 reference :param network: the network name - :returns: Dict + :returns: the token lookup table """ token_path = os.path.join(write_path, "tokens.csv") @@ -274,29 +266,29 @@ def get_all_token_details(web3: Web3, network: str, write_path: str) -> TokenMan if token_file_exists: token_df = pd.read_csv(token_path, index_col=False) - token_dict = {} + token_manager = {} for idx, row in token_df.iterrows(): address, decimals, symbol = row - token_dict[address] = {"address": address, "decimals": decimals, "symbol": symbol} + token_manager[address] = {"address": address, "decimals": decimals, "symbol": symbol} - return TokenManager(token_dict) + return token_manager url = f"https://tokens.coingecko.com/{coingecko_network_map[network]}/all.json" response = requests.get(url).json()["tokens"] - token_dict = { + token_manager = { "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE": {"address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "decimals": 18, "symbol": "ETH"} } if network in ["ethereum", "coinbase_base", "arbitrum_one", "optimism"] else {} for token in response: - address = web3.to_checksum_address(token.get("address")) - symbol = token.get("symbol") - decimals = token.get("decimals") + address = Web3.to_checksum_address(token["address"]) + symbol = token["symbol"] + decimals = token["decimals"] try: # try to write to csv pd.DataFrame( {"token": [address], "symbol": [symbol], "decimals": [decimals]} ).to_csv("token_details.csv") - token_dict[address] = { + token_manager[address] = { "address": address, "decimals": decimals, "symbol": symbol, @@ -304,7 +296,7 @@ def get_all_token_details(web3: Web3, network: str, write_path: str) -> TokenMan except Exception as e: print(f"Failed to get token details for token: {address} with error: {e}") continue - return TokenManager(token_dict=token_dict) + return token_manager def get_token_details_from_contract( @@ -317,57 +309,52 @@ def get_token_details_from_contract( Returns: a Tuple containing the token symbol & decimals, or None, None if the contract call failed. """ - if token == "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2": + if token in skip_token_list: + return None, None + elif token == "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2": symbol = "MKR" decimals = 18 elif token == "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE": symbol = "ETH" decimals = 18 - if token.lower() in skip_token_list: - return None, None else: - contract = web3.eth.contract( - address=web3.to_checksum_address(token), abi=ERC20_ABI - ) + contract = web3.eth.contract(address=token, abi=ERC20_ABI) try: - contract = web3.eth.contract( - address=web3.to_checksum_address(token), abi=ERC20_ABI - ) decimals = contract.caller.decimals() - except: print(f"Cannot get token details for token: {token}") - skip_token_list.append(token.lower()) + skip_token_list.add(token) return None, None try: - symbol = contract.caller.symbol().replace(os.linesep, "") or "???" - # attempt to write to csv - pd.DataFrame( - {"token": [token], "symbol": [symbol], "decimals": [decimals]} - ).to_csv("token_details.csv") - except Exception as e: + symbol = contract.caller.symbol() + except: symbol = "SYMBOL_FAILED" + else: + symbol = symbol.replace(os.linesep, "") or "???" + pd.DataFrame( + {"token": [token], "symbol": [symbol], "decimals": [decimals]} + ).to_csv("token_details.csv") return symbol, decimals def get_token_details( - tkn: str, token_manager: TokenManager, web3: Web3 + tkn: str, token_manager: dict, web3: Web3 ) -> Tuple[str, int] or Tuple[None, None]: """ :param tkn: the token address - :param token_manager: the token lookup dict + :param token_manager: the token lookup table :param web3: the Web3 object Returns: a Tuple containing the token symbol & decimals, or None, None if the contract call failed. """ - tkn = web3.to_checksum_address(tkn) - if tkn in token_manager.token_dict: - symbol = token_manager.token_dict.get(tkn).get("symbol") - decimal = token_manager.token_dict.get(tkn).get("decimals") + tkn = Web3.to_checksum_address(tkn) + if tkn in token_manager: + symbol = token_manager[tkn]["symbol"] + decimal = token_manager[tkn]["decimals"] else: symbol, decimal = get_token_details_from_contract(token=tkn, web3=web3) if type(decimal) == int and type(symbol) == str: - token_manager.token_dict[tkn] = {"address": tkn, "decimals": decimal, "symbol": symbol} + token_manager[tkn] = {"address": tkn, "decimals": decimal, "symbol": symbol} return symbol, decimal @@ -382,105 +369,26 @@ def fix_missing_symbols(symbol: str, addr: str) -> str: """ if addr == "0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2": return "MKR" - elif ( - addr == "0xF1290473E210b2108A85237fbCd7b6eb42Cc654F" - or addr.lower() == "0xF1290473E210b2108A85237fbCd7b6eb42Cc654F".lower() - ): + elif addr == "0xF1290473E210b2108A85237fbCd7b6eb42Cc654F": return "HEDG" else: return symbol -def skip_tokens(addr: str) -> bool: - """ - This function checks against a list of tokens that should be skipped due to problems in their contract, etc. - :param addr: the token address - - retuns: bool - """ - if addr.lower() in skip_token_list: - return True - else: - return False - - -def get_token_prices_coingecko(token_list: Dict) -> Dict: - """ - :param token_list: the list of tokens for which to fetch prices - - Returns token prices using Coingecko API - """ - - max_size = 100 - tkn_addresses = list(token_list.keys()) - tkn_sublists = [ - tkn_addresses[x: x + max_size] for x in range(0, len(tkn_addresses), max_size) - ] - - for tkn_sublist in tkn_sublists: - tokens = ",".join(tkn_sublist) - url = f"https://api.coingecko.com/api/v3/simple/token_price/ethereum?contract_addresses={tokens}&vs_currencies=USD&include_market_cap=false&include_24hr_vol=false&include_24hr_change=false&include_last_updated_at=false" - response = requests.get(url) - - if response.status_code == 200: - data = response.json() - if data is not None: - prices = [] - for tkn in data.keys(): - try: - prices.append((tkn, data[tkn]["usd"])) - except KeyError: - prices.append((tkn, 0)) - continue - - for tkn in prices: - for tkn_addrs in token_list.keys(): - if tkn[0].lower() == tkn_addrs.lower(): - token_list[tkn_addrs]["usd"] = float(tkn[1]) - return token_list - - -def generate_token_price_map(pool_data: Dict, web3: Web3) -> Dict: - """ - This function retrieves token prices from Coingecko - :param pool_data: list of pools - :param web3: the Web3 object - - returns: a dict containing token prices - - """ - token_prices = {} - - for pool in pool_data: - tokens = pool["tokens"] - for tkn in tokens: - address = tkn["address"] - if skip_tokens(addr=address): - continue - symbol = tkn["symbol"] - symbol = fix_missing_symbols(addr=address, symbol=symbol) - - address = web3.to_checksum_address(address) - token_prices[str(address)] = {"tokenSymbol": str(symbol), "usd": None} - - token_prices = get_token_prices_coingecko(token_list=token_prices) - return token_prices - - def organize_pool_details_uni_v3( - pool_data: Dict, token_manager: TokenManager, exchange: str, web3: Web3 -) -> Dict: + pool_data: dict, token_manager: dict, exchange: str, web3: Web3 +) -> dict: """ This function organizes pool details for Uni V3 pools. :param pool_data: the pool data from the pool creation event - :param token_manager: the token lookup dict + :param token_manager: the token lookup table :param exchange: the exchange name :param web3: the Web3 object returns: dict of pool information """ pool_address = pool_data["args"]["pool"] - pool_address = web3.to_checksum_address(pool_address) + pool_address = Web3.to_checksum_address(pool_address) last_updated_block = pool_data["blockNumber"] tick_spacing = pool_data["args"]["tickSpacing"] tokens = [pool_data["args"]["token0"], pool_data["args"]["token1"]] @@ -489,17 +397,15 @@ def organize_pool_details_uni_v3( ) if skip_pool: return None - pair = pair[:-1] - fee = pool_data["args"]["fee"] - description = exchange + " " + pair + " " + str(fee) + fee = pool_data["args"]["fee"] pool_info = { "cid": pool_address, "strategy_id": 0, "last_updated": "", "last_updated_block": last_updated_block, - "descr": description, + "descr": f"{exchange} {pair} {fee}", "pair_name": pair, "exchange_name": exchange, "fee": fee, @@ -510,7 +416,7 @@ def organize_pool_details_uni_v3( "tkn1_address": token_info["tkn1_address"], "tkn0_decimals": token_info["tkn0_decimals"], "tkn1_decimals": token_info["tkn1_decimals"], - "exchange_id": EXCHANGE_IDS.get("uniswap_v3"), + "exchange_id": EXCHANGE_IDS["uniswap_v3"], "tkn0_symbol": token_info["tkn0_symbol"], "tkn1_symbol": token_info["tkn1_symbol"], "timestamp": 0, @@ -522,123 +428,86 @@ def organize_pool_details_uni_v3( "tick_spacing": tick_spacing, "exchange": exchange, } - pool = {**pool_info, **token_info} - return pool + + return {**pool_info, **token_info} def process_token_details( - tokens: List[str], token_manager: TokenManager, web3: Web3 + tokens: List[str], token_manager: dict, web3: Web3 ) -> Tuple[Dict, str, bool] or Tuple[None, None, bool]: """ This function processes token details & generates the token pair :param tokens: the list of tokens - :param token_manager: the token information dict + :param token_manager: the token lookup table :param web3: the Web3 object returns: tuple containing a dict with token information, the pair name as a string, and a bool that indicates if all tokens were successfully added. """ token_info = {} - pair = "" + addresses = [] for idx, tkn in enumerate(tokens): - tkn_num = "tkn" + str(idx) - address = tkn + address = Web3.to_checksum_address(tkn) - if skip_tokens(addr=address): + if address in skip_token_list: return None, None, True - address = web3.to_checksum_address(address) symbol, decimals = get_token_details( token_manager=token_manager, tkn=address, web3=web3 ) if symbol is None: return None, None, True symbol = fix_missing_symbols(addr=address, symbol=symbol) - token_info[tkn_num + "_decimals"] = decimals - token_info[tkn_num + "_address"] = address - token_info[tkn_num + "_symbol"] = symbol - token_info[tkn_num + "_balance"] = 0 + token_info[f"tkn{idx}_decimals"] = decimals + token_info[f"tkn{idx}_address"] = address + token_info[f"tkn{idx}_symbol"] = symbol + token_info[f"tkn{idx}_balance"] = 0 - pair += address + "/" - pair = pair[:-1] + addresses += [address] - return token_info, pair, False + return token_info, "/".join(addresses), False -def organize_pool_details_balancer( - pool_data: Dict, token_prices: Dict, web3: Web3, min_usd: int = 100000 -): +def organize_pool_details_balancer(pool_data: dict) -> dict: """ This function organizes pool details for Uni V3 pools. :param pool_data: the pool data from the pool creation event - :param token_prices: the token prices - :param web3: the Web3 object - :param min_usd: the minimum pool balance in USD to include the pool returns: dict of pool information """ - skip_pool = False if pool_data["swapEnabled"] != True: return None - pool_id = pool_data["id"] - pool_type = pool_data["poolType"] - pool_address = pool_data["address"] - pool_address = web3.to_checksum_address(pool_address) token_info = {} - tokens = pool_data["tokens"] - - pair = "" + addresses = [] - for idx, tkn in enumerate(tokens): - tkn_num = "tkn" + str(idx) - address = tkn["address"] - address = web3.to_checksum_address(address) - if skip_tokens(addr=address): - skip_pool = True - break - - symbol = tkn["symbol"] - symbol = fix_missing_symbols(addr=address, symbol=symbol) + for idx, tkn in enumerate(pool_data["tokens"]): + address = Web3.to_checksum_address(tkn["address"]) + if address in skip_token_list: + return None - # Currently unused - this gets the pool balance, but is only usable accurately on Mainnet - # balance = float(tkn["balance"]) - # tkn_price = 0 if token_prices[address]["usd"] is None else float(token_prices[address]["usd"]) - # tkn_val_usd = balance * tkn_price - # pool_total_liquidity_usd += tkn_val_usd + token_info[f"tkn{idx}_address"] = address + token_info[f"tkn{idx}_symbol"] = fix_missing_symbols(addr=address, symbol=tkn["symbol"]) + token_info[f"tkn{idx}_decimals"] = tkn["decimals"] + token_info[f"tkn{idx}_weight"] = tkn["weight"] + token_info[f"tkn{idx}_balance"] = 0 - token_info[tkn_num + "_address"] = address - token_info[tkn_num + "_symbol"] = symbol - token_info[tkn_num + "_decimals"] = tkn["decimals"] - token_info[tkn_num + "_weight"] = tkn["weight"] - token_info[tkn_num + "_balance"] = 0 + addresses += [address] - pair += address + "/" - - # if pool_total_liquidity_usd < min_usd: - # print(f"pool eliminated due to low liquidity: {pool_total_liquidity_usd} vs min {min_usd}") - # return None - - if skip_pool: - return None - - pair = pair[:-1] + pair = "/".join(addresses) fee = pool_data["swapFee"] - exchange = "balancer" - - description = exchange + " " + pair + " " + str(fee) pool_info = { - "cid": pool_id, + "cid": pool_data["id"], "strategy_id": 0, "last_updated": "", "last_updated_block": 0, - "descr": description, + "descr": f"balancer {pair} {fee}", "pair_name": pair, - "exchange_name": exchange, + "exchange_name": "balancer", "fee": float(fee) * 10 ** 18, "fee_float": float(fee), - "address": pool_address, - "anchor": pool_id, + "address": Web3.to_checksum_address(pool_data["address"]), + "anchor": pool_data["id"], "tkn0_address": token_info["tkn0_address"], "tkn1_address": token_info["tkn1_address"], "tkn0_decimals": token_info["tkn0_decimals"], @@ -654,20 +523,19 @@ def organize_pool_details_balancer( "tick": 0, "tick_spacing": 0, "exchange": "balancer", - "pool_type": pool_type, + "pool_type": pool_data["poolType"], } - pool = {**pool_info, **token_info} - return pool + return {**pool_info, **token_info} def organize_pool_details_uni_v2( - pool_data, token_manager: TokenManager, exchange, default_fee, web3 + pool_data, token_manager: dict, exchange, default_fee, web3 ): """ This function organizes pool details for Uni V2 pools. :param pool_data: the pool data from the pool creation event - :param token_addr_lookup: the token lookup dict + :param token_manager: the token lookup table :param exchange: the exchange name :param default_fee: the fee for the exchange :param web3: the Web3 object @@ -675,7 +543,7 @@ def organize_pool_details_uni_v2( returns: dict of pool information """ pool_address = pool_data["args"]["pair"] - pool_address = web3.to_checksum_address(pool_address) + pool_address = Web3.to_checksum_address(pool_address) last_updated_block = pool_data["blockNumber"] if default_fee == "TBD": return None @@ -686,14 +554,13 @@ def organize_pool_details_uni_v2( ) if skip_pool: return None - description = exchange + " " + pair pool_info = { "cid": pool_address, "strategy_id": 0, "last_updated": "", "last_updated_block": last_updated_block, - "descr": description, + "descr": f"{exchange} {pair}", "pair_name": pair, "exchange_name": exchange, "fee": default_fee, @@ -704,7 +571,7 @@ def organize_pool_details_uni_v2( "tkn1_address": token_info["tkn1_address"], "tkn0_decimals": token_info["tkn0_decimals"], "tkn1_decimals": token_info["tkn1_decimals"], - "exchange_id": EXCHANGE_IDS.get("uniswap_v2"), + "exchange_id": EXCHANGE_IDS["uniswap_v2"], "tkn0_symbol": token_info["tkn0_symbol"], "tkn1_symbol": token_info["tkn1_symbol"], "timestamp": 0, @@ -712,9 +579,8 @@ def organize_pool_details_uni_v2( "tkn1_balance": 0, "exchange": exchange, } - pool = {**pool_info, **token_info} - return pool + return {**pool_info, **token_info} def organize_pool_details_solidly_v2( @@ -724,11 +590,11 @@ def organize_pool_details_solidly_v2( This function organizes pool details for Solidly pools. :param pool_data: the pool data from the pool creation event - :param token_manager: the token lookup dict + :param token_manager: the token lookup table :param exchange: the exchange name :param factory_contract: the exchange's Factory contract - initialized :param web3: the Web3 object - :param web3: the async Web3 object + :param async_web3: the Async Web3 object returns: dict of pool information """ if "pool" in pool_data or "pool" in pool_data["args"]: @@ -737,7 +603,7 @@ def organize_pool_details_solidly_v2( pool_address = pool_data["args"]["pair"] else: print(f"COULD NOT FIND KEY IN EVENT for exchange {exchange}: {pool_data}") - pool_address = web3.to_checksum_address(pool_address) + pool_address = Web3.to_checksum_address(pool_address) last_updated_block = pool_data["blockNumber"] @@ -756,14 +622,13 @@ def organize_pool_details_solidly_v2( ) if skip_pool: return None - description = exchange + " " + pair pool_info = { "cid": pool_address, "strategy_id": 0, "last_updated": "", "last_updated_block": last_updated_block, - "descr": description, + "descr": f"{exchange} {pair}", "pair_name": pair, "exchange_name": exchange, "fee": fee_str, @@ -774,7 +639,7 @@ def organize_pool_details_solidly_v2( "tkn1_address": token_info["tkn1_address"], "tkn0_decimals": token_info["tkn0_decimals"], "tkn1_decimals": token_info["tkn1_decimals"], - "exchange_id": EXCHANGE_IDS.get(exchange), + "exchange_id": EXCHANGE_IDS[exchange], "tkn0_symbol": token_info["tkn0_symbol"], "tkn1_symbol": token_info["tkn1_symbol"], "timestamp": 0, @@ -783,9 +648,8 @@ def organize_pool_details_solidly_v2( "exchange": exchange, "pool_type": stable_pool, } - pool = {**pool_info, **token_info} - return pool + return {**pool_info, **token_info} def get_events(contract: any, blockchain: str, exchange: str, start_block: int, end_block: int) -> list: @@ -809,15 +673,18 @@ def get_events_recursive(get_logs: any, start_block: int, end_block: int) -> lis return get_logs(fromBlock=start_block, toBlock=end_block) except Exception as e: assert "eth_getLogs" in str(e), str(e) - mid_block = (start_block + end_block) // 2 - event_list_1 = get_events_recursive(get_logs, start_block, mid_block) - event_list_2 = get_events_recursive(get_logs, mid_block + 1, end_block) - return event_list_1 + event_list_2 - return [] + if start_block < end_block: + mid_block = (start_block + end_block) // 2 + event_list_1 = get_events_recursive(get_logs, start_block, mid_block) + event_list_2 = get_events_recursive(get_logs, mid_block + 1, end_block) + return event_list_1 + event_list_2 + else: + raise e + raise Exception(f"Illegal log query range: {start_block} -> {end_block}") def get_uni_v3_pools( - token_manager: TokenManager, + token_manager: dict, exchange: str, factory_contract, start_block: int, @@ -827,7 +694,7 @@ def get_uni_v3_pools( ) -> Tuple[DataFrame, DataFrame]: """ This function retrieves Uniswap V3 pool generation events and organizes them into two Dataframes - :param token_addr_lookup: the dict containing token information + :param token_manager: the token lookup table :param factory_contract: the initialized Factory contract :param start_block: the block number from which to start :param end_block: the block number at which to end @@ -856,7 +723,7 @@ def get_uni_v3_pools( return df, mapdf def get_uni_v2_pools( - token_manager: TokenManager, + token_manager: dict, exchange: str, factory_contract, start_block: int, @@ -867,7 +734,7 @@ def get_uni_v2_pools( ) -> Tuple[DataFrame, DataFrame]: """ This function retrieves Uniswap V2 pool generation events and organizes them into two Dataframes - :param token_addr_lookup: the dict containing token information + :param token_manager: the token lookup table :param factory_contract: the initialized Factory contract :param start_block: the block number from which to start :param end_block: the block number at which to end @@ -898,7 +765,7 @@ def get_uni_v2_pools( return df, mapdf def get_solidly_v2_pools( - token_manager: TokenManager, + token_manager: dict, exchange: str, async_factory_contract, factory_contract, @@ -910,7 +777,7 @@ def get_solidly_v2_pools( ) -> Tuple[DataFrame, DataFrame]: """ This function retrieves Solidly pool generation events and organizes them into two Dataframes - :param token_manager: the dict containing token information + :param token_manager: the token lookup table :param factory_contract: the initialized Factory contract :param start_block: the block number from which to start :param end_block: the block number at which to end @@ -981,28 +848,18 @@ def get_multichain_addresses(network_name: str) -> pd.DataFrame: """ -def get_balancer_pools(subgraph_url: str, web3: Web3) -> pd.DataFrame: +def get_balancer_pools(subgraph_url: str) -> pd.DataFrame: """ This function gets Balancer pool details from the Balancer subgraph :param subgraph_url: the URL of the Balancer subgraph - :param web3: the Web3 object """ response = requests.post(subgraph_url, json={"query": balancer_subgraph_query}) assert response.status_code == 200, f"Balancer subgraph query failed with {response}" - pool_data = response.json()["data"]["pools"] - - token_prices = generate_token_price_map(pool_data=pool_data, web3=web3) - pools = [] - for pool in pool_data: - pools.append( - organize_pool_details_balancer( - pool_data=pool, token_prices=token_prices, web3=web3 - ) - ) - pools = [pool for pool in pools if pool is not None] - df = pd.DataFrame(pools, columns=dataframe_key) - return df + pool_data_list = response.json()["data"]["pools"] + + pools = [organize_pool_details_balancer(pool_data) for pool_data in pool_data_list] + return pd.DataFrame([pool for pool in pools if pool is not None], columns=dataframe_key) def add_to_exchange_ids(exchange: str, fork: str): @@ -1042,19 +899,14 @@ def get_last_block_updated(df: pd.DataFrame, exchange: str) -> int: return safe_int(ex_df["last_updated_block"].max()) -def save_token_data(token_dict: TokenManager, write_path: str): +def save_token_data(token_manager: dict, write_path: str): """ Saves token data to a CSV """ token_path = os.path.join(write_path, "tokens.csv") - token_list = [] - - for key in token_dict.token_dict.keys(): - token_list.append(token_dict.token_dict[key]) - - token_df = pd.DataFrame(token_list, columns=["address", "decimals", "symbol"]) + token_df = pd.DataFrame(token_manager.values(), columns=["address", "decimals", "symbol"]) token_df.set_index("address", inplace=True) token_df.to_csv(token_path) @@ -1076,7 +928,7 @@ def terraform_blockchain(network_name: str): path_exists = os.path.exists(write_path) data_path = os.path.normpath(write_path + "/static_pool_data.csv") data_exists = os.path.exists(data_path) - token_manager = get_all_token_details(web3, network=network_name, write_path=write_path) + token_manager = get_all_token_details(network=network_name, write_path=write_path) if not path_exists: os.makedirs(write_path) @@ -1102,7 +954,7 @@ def terraform_blockchain(network_name: str): write_path + "/solidly_v2_event_mappings.csv", index_col=False ) - save_token_data(token_dict=token_manager, write_path=write_path) + save_token_data(token_manager=token_manager, write_path=write_path) to_block = web3.eth.block_number @@ -1167,8 +1019,9 @@ def terraform_blockchain(network_name: str): univ3_mapdf = pd.concat([univ3_mapdf, m_df], ignore_index=True) elif "solidly" in fork: add_to_exchange_ids(exchange=exchange_name, fork=fork) + solidly_exchange = SolidlyV2(exchange_name=exchange_name) + factory_abi = solidly_exchange.factory_abi - factory_abi = SOLIDLY_EXCHANGE_INFO[exchange_name]["factory_abi"] factory_contract = web3.eth.contract( address=factory_address, abi=factory_abi ) @@ -1192,7 +1045,7 @@ def terraform_blockchain(network_name: str): elif "balancer" in fork: try: subgraph_url = BALANCER_SUBGRAPH_CHAIN_URL[network_name] - u_df = get_balancer_pools(subgraph_url=subgraph_url, web3=web3) + u_df = get_balancer_pools(subgraph_url=subgraph_url) except Exception as e: print(f"Fetching balancer pools for chain {network_name} failed:\n{e}") continue @@ -1201,7 +1054,7 @@ def terraform_blockchain(network_name: str): continue exchange_df = pd.concat([exchange_df, u_df]) - save_token_data(token_dict=token_manager, write_path=write_path) + save_token_data(token_manager=token_manager, write_path=write_path) exchange_df.to_csv((write_path + "/static_pool_data.csv"), index=False) univ2_mapdf.to_csv((write_path + "/uniswap_v2_event_mappings.csv"), index=False)