From c75a767338fada91cedf4ce5c3a98bab9e128025 Mon Sep 17 00:00:00 2001 From: Sheng Lundquist Date: Tue, 22 Oct 2024 12:05:13 -0700 Subject: [PATCH 1/6] Only attempt to remove liquidity if the wallet balance is above minimum txn amount --- src/agent0/core/hyperdrive/policies/random.py | 3 ++- src/agent0/core/hyperdrive/policies/random_hold.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/agent0/core/hyperdrive/policies/random.py b/src/agent0/core/hyperdrive/policies/random.py index 173d1227fe..9623bf108e 100644 --- a/src/agent0/core/hyperdrive/policies/random.py +++ b/src/agent0/core/hyperdrive/policies/random.py @@ -127,7 +127,8 @@ def get_available_actions( all_available_actions.append(HyperdriveActionType.CLOSE_LONG) if wallet.shorts: # if the agent has open shorts all_available_actions.append(HyperdriveActionType.CLOSE_SHORT) - if wallet.lp_tokens: + # If the agent has more than minimum transaction amount of liquidity to remove + if wallet.lp_tokens >= pool_state.pool_config.minimum_transaction_amount: all_available_actions.append(HyperdriveActionType.REMOVE_LIQUIDITY) if wallet.withdraw_shares and pool_state.pool_info.withdrawal_shares_ready_to_withdraw > 0: all_available_actions.append(HyperdriveActionType.REDEEM_WITHDRAW_SHARE) diff --git a/src/agent0/core/hyperdrive/policies/random_hold.py b/src/agent0/core/hyperdrive/policies/random_hold.py index 2f3fa0124f..5258db951a 100644 --- a/src/agent0/core/hyperdrive/policies/random_hold.py +++ b/src/agent0/core/hyperdrive/policies/random_hold.py @@ -161,7 +161,8 @@ def get_available_actions( all_available_actions.append(HyperdriveActionType.CLOSE_LONG) if short_ready_to_close: # if the agent has shorts ready to close all_available_actions.append(HyperdriveActionType.CLOSE_SHORT) - if wallet.lp_tokens: + # If the agent has more than minimum transaction amount of liquidity to remove + if wallet.lp_tokens >= pool_state.pool_config.minimum_transaction_amount: all_available_actions.append(HyperdriveActionType.REMOVE_LIQUIDITY) if wallet.withdraw_shares and pool_state.pool_info.withdrawal_shares_ready_to_withdraw > 0: all_available_actions.append(HyperdriveActionType.REDEEM_WITHDRAW_SHARE) From 40fcf5c780902342c04c5743c20f947929edc440 Mon Sep 17 00:00:00 2001 From: Sheng Lundquist Date: Tue, 22 Oct 2024 12:13:06 -0700 Subject: [PATCH 2/6] Refork periodically in fork fuzz bots --- scripts/fork_fuzz_bots.py | 51 ++++++++++++++++++++++---------------- scripts/local_fuzz_bots.py | 9 ++++++- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/scripts/fork_fuzz_bots.py b/scripts/fork_fuzz_bots.py index b4f7b209cf..10eb429051 100644 --- a/scripts/fork_fuzz_bots.py +++ b/scripts/fork_fuzz_bots.py @@ -223,36 +223,35 @@ def main(argv: Sequence[str] | None = None) -> None: crash_report_additional_info={"rng_seed": rng_seed}, gas_limit=int(1e6), # Plenty of gas limit for transactions ) - # Build interactive local hyperdrive - chain = LocalChain(fork_uri=rpc_uri, config=chain_config) - - chain_id = chain.chain_id - # Select whale account based on chain id - if chain_id in WHALE_ADDRESSES: - # Ensure all whale account addresses are checksum addresses - whale_accounts = { - Web3.to_checksum_address(key): Web3.to_checksum_address(value) - for key, value in WHALE_ADDRESSES[chain_id].items() - } - else: - whale_accounts = {} - - # Get list of deployed pools on initial iteration - deployed_pools = LocalHyperdrive.get_hyperdrive_pools_from_registry(chain, registry_address) - log_message = f"Running fuzzing on pools {[p.name for p in deployed_pools]}..." - logging.info(log_message) - log_rollbar_message(message=log_message, log_level=logging.INFO) while True: + # Build interactive local hyperdrive + chain = LocalChain(fork_uri=rpc_uri, config=chain_config) + + chain_id = chain.chain_id + # Select whale account based on chain id + if chain_id in WHALE_ADDRESSES: + # Ensure all whale account addresses are checksum addresses + whale_accounts = { + Web3.to_checksum_address(key): Web3.to_checksum_address(value) + for key, value in WHALE_ADDRESSES[chain_id].items() + } + else: + whale_accounts = {} + + # Get list of deployed pools on initial iteration + deployed_pools = LocalHyperdrive.get_hyperdrive_pools_from_registry(chain, registry_address) + log_message = f"Running fuzzing on pools {[p.name for p in deployed_pools]}..." + logging.info(log_message) + log_rollbar_message(message=log_message, log_level=logging.INFO) # Check for new pools latest_block = chain.block_data() latest_block_number = latest_block.get("number", None) if latest_block_number is None: raise AssertionError("Block has no number.") - # TODO we may want to refork every once in awhile in case new pools are deployed. - # For now, we assume this script gets restarted. - + # We run fuzzbots for every num_iterations_per_episode, + # after which we will refork and restart. try: run_fuzz_bots( chain, @@ -269,6 +268,7 @@ def main(argv: Sequence[str] | None = None) -> None: lp_share_price_test=False, base_budget_per_bot=FixedPoint(1_000), whale_accounts=whale_accounts, + num_iterations=parsed_args.num_iterations_per_episode, ) except Exception as e: # pylint: disable=broad-except log_rollbar_exception(exception=e, log_level=logging.ERROR) @@ -294,6 +294,7 @@ class Args(NamedTuple): db_port: int rpc_uri: str rng_seed: int + num_iterations_per_episode: int def namespace_to_args(namespace: argparse.Namespace) -> Args: @@ -317,6 +318,7 @@ def namespace_to_args(namespace: argparse.Namespace) -> Args: db_port=namespace.db_port, rpc_uri=namespace.rpc_uri, rng_seed=namespace.rng_seed, + num_iterations_per_episode=namespace.num_iterations_per_episode, ) @@ -381,6 +383,11 @@ def parse_arguments(argv: Sequence[str] | None = None) -> Args: default=-1, help="The random seed to use for the fuzz run.", ) + parser.add_argument( + "--num-iterations-per-episode", + default=3000, + help="The number of iterations to run for each random pool config.", + ) # Use system arguments if none were passed if argv is None: diff --git a/scripts/local_fuzz_bots.py b/scripts/local_fuzz_bots.py index 3209ac4417..4ac1a861f2 100644 --- a/scripts/local_fuzz_bots.py +++ b/scripts/local_fuzz_bots.py @@ -234,7 +234,7 @@ def main(argv: Sequence[str] | None = None) -> None: run_async=False, random_advance_time=True, random_variable_rate=True, - num_iterations=3000, + num_iterations=parsed_args.num_iterations_per_episode, lp_share_price_test=parsed_args.lp_share_price_test, ) @@ -262,6 +262,7 @@ class Args(NamedTuple): genesis_timestamp: int rng_seed: int steth: bool + num_iterations_per_episode: int def namespace_to_args(namespace: argparse.Namespace) -> Args: @@ -285,6 +286,7 @@ def namespace_to_args(namespace: argparse.Namespace) -> Args: genesis_timestamp=namespace.genesis_timestamp, rng_seed=namespace.rng_seed, steth=namespace.steth, + num_iterations_per_episode=namespace.num_iterations_per_episode, ) @@ -344,6 +346,11 @@ def parse_arguments(argv: Sequence[str] | None = None) -> Args: action="store_true", help="Runs fuzz testing on the steth hyperdrive", ) + parser.add_argument( + "--num-iterations-per-episode", + default=3000, + help="The number of iterations to run for each random pool config.", + ) # Use system arguments if none were passed if argv is None: From 2b55bf125d9f238f026814616baf066aac914ebc Mon Sep 17 00:00:00 2001 From: Sheng Lundquist Date: Tue, 22 Oct 2024 12:28:53 -0700 Subject: [PATCH 3/6] Adding ignore logging to rollbar errors for fork fuzz bots --- scripts/fork_fuzz_bots.py | 24 +++++++++++++++++++ .../core/hyperdrive/policies/random_hold.py | 1 - 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/scripts/fork_fuzz_bots.py b/scripts/fork_fuzz_bots.py index 10eb429051..ba5693925c 100644 --- a/scripts/fork_fuzz_bots.py +++ b/scripts/fork_fuzz_bots.py @@ -83,6 +83,29 @@ } +def _fuzz_ignore_logging_to_rollbar(exc: Exception) -> bool: + """Function defining errors to not log to rollbar during fuzzing. + + These are the two most common errors we see in local fuzz testing. These are + known issues due to random bots not accounting for these cases, so we don't log them to + rollbar. + """ + if isinstance(exc, PypechainCallException): + orig_exception = exc.orig_exception + if orig_exception is None: + return False + + # Insufficient liquidity error + if isinstance(orig_exception, ContractCustomError) and exc.decoded_error == "InsufficientLiquidity()": + return True + + # Circuit breaker triggered error + if isinstance(orig_exception, ContractCustomError) and exc.decoded_error == "CircuitBreakerTriggered()": + return True + + return False + + def _fuzz_ignore_errors(exc: Exception) -> bool: """Function defining errors to ignore for pausing chain during fuzzing.""" # pylint: disable=too-many-return-statements @@ -218,6 +241,7 @@ def main(argv: Sequence[str] | None = None) -> None: preview_before_trade=True, log_to_rollbar=log_to_rollbar, rollbar_log_prefix="forkfuzzbots", + rollbar_log_filter_func=_fuzz_ignore_logging_to_rollbar, rng=rng, crash_log_level=logging.ERROR, crash_report_additional_info={"rng_seed": rng_seed}, diff --git a/src/agent0/core/hyperdrive/policies/random_hold.py b/src/agent0/core/hyperdrive/policies/random_hold.py index 5258db951a..221cde9800 100644 --- a/src/agent0/core/hyperdrive/policies/random_hold.py +++ b/src/agent0/core/hyperdrive/policies/random_hold.py @@ -16,7 +16,6 @@ if TYPE_CHECKING: from agent0.core.hyperdrive import HyperdriveMarketAction, HyperdriveWallet, TradeResult from agent0.ethpy.hyperdrive import HyperdriveReadInterface - from agent0.ethpy.hyperdrive.state import PoolState class RandomHold(Random): From a4342bd8557c34b2fc4921b976775ce5c7a9c754 Mon Sep 17 00:00:00 2001 From: Sheng Lundquist Date: Tue, 22 Oct 2024 13:32:16 -0700 Subject: [PATCH 4/6] Define minimum share reserves based on if agent0 is dealing with units of base or shares --- src/agent0/core/hyperdrive/policies/random.py | 51 +++++++++++++------ .../core/hyperdrive/policies/random_hold.py | 9 +++- .../hyperdrive/interface/_contract_calls.py | 17 +++++++ .../hyperdrive/interface/read_interface.py | 25 +++++++-- 4 files changed, 83 insertions(+), 19 deletions(-) diff --git a/src/agent0/core/hyperdrive/policies/random.py b/src/agent0/core/hyperdrive/policies/random.py index 9623bf108e..fcc7069088 100644 --- a/src/agent0/core/hyperdrive/policies/random.py +++ b/src/agent0/core/hyperdrive/policies/random.py @@ -113,9 +113,16 @@ def get_available_actions( A list containing all of the available actions. """ pool_state = interface.current_pool_state + # The amount of minimum transaction amount is dependent on if we're trading with + # base or vault shares + if interface.base_is_yield: + minimum_transaction_amount = interface.get_minimum_transaction_amount_shares() + else: + minimum_transaction_amount = pool_state.pool_config.minimum_transaction_amount + # prevent accidental override # compile a list of all actions - if wallet.balance.amount <= pool_state.pool_config.minimum_transaction_amount: + if wallet.balance.amount <= minimum_transaction_amount: all_available_actions = [] else: all_available_actions = [ @@ -128,6 +135,7 @@ def get_available_actions( if wallet.shorts: # if the agent has open shorts all_available_actions.append(HyperdriveActionType.CLOSE_SHORT) # If the agent has more than minimum transaction amount of liquidity to remove + # Note the lp tokens are always bounded by the actual minimum share reserves in pool config if wallet.lp_tokens >= pool_state.pool_config.minimum_transaction_amount: all_available_actions.append(HyperdriveActionType.REMOVE_LIQUIDITY) if wallet.withdraw_shares and pool_state.pool_info.withdrawal_shares_ready_to_withdraw > 0: @@ -152,6 +160,10 @@ def open_short_with_random_amount( list[Trade[HyperdriveMarketAction]] A list with a single Trade element for opening a Hyperdrive short. """ + # Shorts take units of bonds, which is always checked against the minimum transaction amount + # as defined in pool config. + minimum_transaction_amount = interface.pool_config.minimum_transaction_amount + # Calc max short is crashing, we surround in try catch to log # TODO fix all crashes in calc_max_short and calc_max_long and instead return 0 for max short try: @@ -184,16 +196,14 @@ def open_short_with_random_amount( # We don't return a trade here if this fails return [] - if maximum_trade_amount <= interface.pool_config.minimum_transaction_amount: + if maximum_trade_amount <= minimum_transaction_amount: return [] initial_trade_amount = FixedPoint( self.rng.normal(loc=float(wallet.balance.amount) * 0.1, scale=float(wallet.balance.amount) * 0.01) ) # minimum_transaction_amount <= trade_amount <= max_short - trade_amount = max( - interface.pool_config.minimum_transaction_amount, min(initial_trade_amount, maximum_trade_amount) - ) + trade_amount = max(minimum_transaction_amount, min(initial_trade_amount, maximum_trade_amount)) # optionally ignore slippage tolerance ignore_slippage = self.rng.choice([True, False], size=1) if self.randomly_ignore_slippage_tolerance else False if ignore_slippage: @@ -262,6 +272,15 @@ def open_long_with_random_amount( list[Trade[HyperdriveMarketAction]] A list with a single Trade element for opening a Hyperdrive long. """ + + pool_state = interface.current_pool_state + # open long's minimum transaction amount is dependent on if we're trading with + # base or vault shares + if interface.base_is_yield: + minimum_transaction_amount = interface.get_minimum_transaction_amount_shares() + else: + minimum_transaction_amount = pool_state.pool_config.minimum_transaction_amount + # TODO fix all crashes in calc_max_short and calc_max_long and instead return 0 for max short try: maximum_trade_amount = interface.calc_max_long(wallet.balance.amount, interface.current_pool_state) @@ -291,16 +310,14 @@ def open_long_with_random_amount( ) # We don't return a trade here if this fails return [] - if maximum_trade_amount <= interface.pool_config.minimum_transaction_amount: + if maximum_trade_amount <= minimum_transaction_amount: return [] # take a guess at the trade amount, which should be about 10% of the agent’s budget initial_trade_amount = FixedPoint( self.rng.normal(loc=float(wallet.balance.amount) * 0.1, scale=float(wallet.balance.amount) * 0.01) ) # minimum_transaction_amount <= trade_amount <= max long - trade_amount = max( - interface.pool_config.minimum_transaction_amount, min(initial_trade_amount, maximum_trade_amount) - ) + trade_amount = max(minimum_transaction_amount, min(initial_trade_amount, maximum_trade_amount)) # optionally ignore slippage tolerance ignore_slippage = self.rng.choice([True, False], size=1) if self.randomly_ignore_slippage_tolerance else False if ignore_slippage: @@ -369,14 +386,16 @@ def add_liquidity_with_random_amount( list[Trade[HyperdriveMarketAction]] A list with a single Trade element for adding liquidity to a Hyperdrive pool. """ + # LP is in units of LP, which is always checked against the minimum transaction amount + # as defined in pool config. + minimum_transaction_amount = interface.pool_config.minimum_transaction_amount + # take a guess at the trade amount, which should be about 10% of the agent’s budget initial_trade_amount = FixedPoint( self.rng.normal(loc=float(wallet.balance.amount) * 0.1, scale=float(wallet.balance.amount) * 0.01) ) # minimum_transaction_amount <= trade_amount - trade_amount: FixedPoint = max( - interface.pool_config.minimum_transaction_amount, min(wallet.balance.amount, initial_trade_amount) - ) + trade_amount: FixedPoint = max(minimum_transaction_amount, min(wallet.balance.amount, initial_trade_amount)) # return a trade using a specification that is parsable by the rest of the sim framework return [ add_liquidity_trade( @@ -401,14 +420,16 @@ def remove_liquidity_with_random_amount( list[Trade[HyperdriveMarketAction]] A list with a single Trade element for removing liquidity from a Hyperdrive pool. """ + # LP is in units of LP, which is always checked against the minimum transaction amount + # as defined in pool config. + minimum_transaction_amount = interface.pool_config.minimum_transaction_amount + # take a guess at the trade amount, which should be about 10% of the agent’s budget initial_trade_amount = FixedPoint( self.rng.normal(loc=float(wallet.balance.amount) * 0.1, scale=float(wallet.balance.amount) * 0.01) ) # minimum_transaction_amount <= trade_amount <= lp_tokens - trade_amount = max( - interface.pool_config.minimum_transaction_amount, min(wallet.lp_tokens, initial_trade_amount) - ) + trade_amount = max(minimum_transaction_amount, min(wallet.lp_tokens, initial_trade_amount)) # optionally ignore slippage tolerance ignore_slippage = self.rng.choice([True, False], size=1) if self.randomly_ignore_slippage_tolerance else False if ignore_slippage: diff --git a/src/agent0/core/hyperdrive/policies/random_hold.py b/src/agent0/core/hyperdrive/policies/random_hold.py index 221cde9800..5c2971643e 100644 --- a/src/agent0/core/hyperdrive/policies/random_hold.py +++ b/src/agent0/core/hyperdrive/policies/random_hold.py @@ -120,6 +120,12 @@ def get_available_actions( """ # pylint: disable=too-many-branches pool_state = interface.current_pool_state + # The amount of minimum transaction amount is dependent on if we're trading with + # base or vault shares + if interface.base_is_yield: + minimum_transaction_amount = interface.get_minimum_transaction_amount_shares() + else: + minimum_transaction_amount = pool_state.pool_config.minimum_transaction_amount # Initialize list of open positions if interface.hyperdrive_address not in self.open_positions: @@ -142,7 +148,7 @@ def get_available_actions( # Sanity check raise ValueError(f"Action type {position.action_type} not in allowable actions") - if wallet.balance.amount <= pool_state.pool_config.minimum_transaction_amount: + if wallet.balance.amount <= minimum_transaction_amount: all_available_actions = [] else: all_available_actions = [ @@ -161,6 +167,7 @@ def get_available_actions( if short_ready_to_close: # if the agent has shorts ready to close all_available_actions.append(HyperdriveActionType.CLOSE_SHORT) # If the agent has more than minimum transaction amount of liquidity to remove + # Note the lp tokens are always bounded by the actual minimum share reserves in pool config if wallet.lp_tokens >= pool_state.pool_config.minimum_transaction_amount: all_available_actions.append(HyperdriveActionType.REMOVE_LIQUIDITY) if wallet.withdraw_shares and pool_state.pool_info.withdrawal_shares_ready_to_withdraw > 0: diff --git a/src/agent0/ethpy/hyperdrive/interface/_contract_calls.py b/src/agent0/ethpy/hyperdrive/interface/_contract_calls.py index c3dbacf122..654205f984 100644 --- a/src/agent0/ethpy/hyperdrive/interface/_contract_calls.py +++ b/src/agent0/ethpy/hyperdrive/interface/_contract_calls.py @@ -43,6 +43,21 @@ # pylint: disable=too-many-positional-arguments +def _get_minimum_transaction_amount_shares( + interface: HyperdriveReadInterface, + hyperdrive_contract: IHyperdriveContract, + block_identifier: BlockIdentifier | None = None, +) -> FixedPoint: + # Get the minimum transaction amount in units of base + minimum_transaction_amount_base = interface.pool_config.minimum_transaction_amount + # Convert to shares via rpc call, and cast as fixed point + return FixedPoint( + scaled_value=hyperdrive_contract.functions.convertToShares(minimum_transaction_amount_base.scaled_value).call( + block_identifier=block_identifier or "latest" + ) + ) + + def _get_total_supply_withdrawal_shares( hyperdrive_contract: IHyperdriveContract, block_identifier: BlockIdentifier | None = None ) -> FixedPoint: @@ -79,6 +94,8 @@ def _get_vault_shares( block_identifier: BlockIdentifier | None = None, ) -> FixedPoint: """See API for documentation.""" + + # TODO call `hyperdrive_contract.functions.totalShares` instead of custom logic between pools if interface.hyperdrive_kind == interface.HyperdriveKind.STETH: # Type narrowing assert interface.vault_shares_token_contract is not None diff --git a/src/agent0/ethpy/hyperdrive/interface/read_interface.py b/src/agent0/ethpy/hyperdrive/interface/read_interface.py index 3ef5ec4a73..9510ef0279 100644 --- a/src/agent0/ethpy/hyperdrive/interface/read_interface.py +++ b/src/agent0/ethpy/hyperdrive/interface/read_interface.py @@ -41,6 +41,7 @@ _get_hyperdrive_base_balance, _get_hyperdrive_eth_balance, _get_long_total_supply, + _get_minimum_transaction_amount_shares, _get_short_total_supply, _get_total_supply_withdrawal_shares, _get_variable_rate, @@ -477,7 +478,25 @@ def get_checkpoint( block_identifier = "latest" return get_hyperdrive_checkpoint(self.hyperdrive_contract, checkpoint_time, block_identifier) - def get_total_supply_withdrawal_shares(self, block_identifier: BlockIdentifier | None) -> FixedPoint: + def get_minimum_transaction_amount_shares(self, block_identifier: BlockIdentifier | None = None) -> FixedPoint: + """Use an RPC to get the minimum transaction amount in units of shares at the given block. + + Arguments + --------- + block_identifier: BlockIdentifier, optional + The identifier for a block. + If not given, the latest block number is used. + + Returns + ------- + FixedPoint + The quantity of withdrawal shares available in the Hyperdrive pool. + """ + if block_identifier is None: + block_identifier = "latest" + return _get_minimum_transaction_amount_shares(self, self.hyperdrive_contract, block_identifier) + + def get_total_supply_withdrawal_shares(self, block_identifier: BlockIdentifier | None = None) -> FixedPoint: """Use an RPC to get the total supply of withdrawal shares in the pool at the given block. Arguments @@ -495,7 +514,7 @@ def get_total_supply_withdrawal_shares(self, block_identifier: BlockIdentifier | block_identifier = "latest" return _get_total_supply_withdrawal_shares(self.hyperdrive_contract, block_identifier) - def get_vault_shares(self, block_identifier: BlockIdentifier | None) -> FixedPoint: + def get_vault_shares(self, block_identifier: BlockIdentifier | None = None) -> FixedPoint: """Use an RPC to get the balance of shares that the Hyperdrive pool has in the underlying yield source. Arguments @@ -513,7 +532,7 @@ def get_vault_shares(self, block_identifier: BlockIdentifier | None) -> FixedPoi block_identifier = "latest" return _get_vault_shares(self, self.hyperdrive_contract, block_identifier) - def get_idle_shares(self, pool_state: PoolState | None) -> FixedPoint: + def get_idle_shares(self, pool_state: PoolState | None = None) -> FixedPoint: """Get the balance of idle shares that the Hyperdrive pool has. Arguments From c1708b14e5ba8436d98bad4dbb54e69d0131cded Mon Sep 17 00:00:00 2001 From: Sheng Lundquist Date: Tue, 22 Oct 2024 13:45:30 -0700 Subject: [PATCH 5/6] Adding large trade cause rate cirtuit breaker to trip to list of ignored errors to log to rollbar --- scripts/fork_fuzz_bots.py | 10 +++++++++- scripts/local_fuzz_bots.py | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/scripts/fork_fuzz_bots.py b/scripts/fork_fuzz_bots.py index ba5693925c..4140630d6a 100644 --- a/scripts/fork_fuzz_bots.py +++ b/scripts/fork_fuzz_bots.py @@ -90,7 +90,15 @@ def _fuzz_ignore_logging_to_rollbar(exc: Exception) -> bool: known issues due to random bots not accounting for these cases, so we don't log them to rollbar. """ - if isinstance(exc, PypechainCallException): + if isinstance(exc, FuzzAssertionException): + # Large circuit breaker check + if ( + len(exc.args) >= 2 + and exc.args[0] == "Continuous Fuzz Bots Invariant Checks" + and "Large trade has caused the rate circuit breaker to trip." in exc.args[1] + ): + return True + elif isinstance(exc, PypechainCallException): orig_exception = exc.orig_exception if orig_exception is None: return False diff --git a/scripts/local_fuzz_bots.py b/scripts/local_fuzz_bots.py index 4ac1a861f2..c9552860bb 100644 --- a/scripts/local_fuzz_bots.py +++ b/scripts/local_fuzz_bots.py @@ -26,7 +26,15 @@ def _fuzz_ignore_logging_to_rollbar(exc: Exception) -> bool: known issues due to random bots not accounting for these cases, so we don't log them to rollbar. """ - if isinstance(exc, PypechainCallException): + if isinstance(exc, FuzzAssertionException): + # Large circuit breaker check + if ( + len(exc.args) >= 2 + and exc.args[0] == "Continuous Fuzz Bots Invariant Checks" + and "Large trade has caused the rate circuit breaker to trip." in exc.args[1] + ): + return True + elif isinstance(exc, PypechainCallException): orig_exception = exc.orig_exception if orig_exception is None: return False From a9153d9f78633639360fb944a4ab34a4ddc3db83 Mon Sep 17 00:00:00 2001 From: Sheng Lundquist Date: Tue, 22 Oct 2024 13:50:59 -0700 Subject: [PATCH 6/6] Fixing comments --- src/agent0/core/hyperdrive/policies/random.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/agent0/core/hyperdrive/policies/random.py b/src/agent0/core/hyperdrive/policies/random.py index fcc7069088..2b2f4120c3 100644 --- a/src/agent0/core/hyperdrive/policies/random.py +++ b/src/agent0/core/hyperdrive/policies/random.py @@ -113,7 +113,7 @@ def get_available_actions( A list containing all of the available actions. """ pool_state = interface.current_pool_state - # The amount of minimum transaction amount is dependent on if we're trading with + # The minimum transaction amount is dependent on if we're trading with # base or vault shares if interface.base_is_yield: minimum_transaction_amount = interface.get_minimum_transaction_amount_shares()