diff --git a/tests/test_3jane.py b/tests/test_3jane.py index b42cace9..ee0da989 100644 --- a/tests/test_3jane.py +++ b/tests/test_3jane.py @@ -796,8 +796,6 @@ def test_accountable_recovery_rearms_alert(monkeypatch: pytest.MonkeyPatch) -> N def test_accountable_alerts_use_the_protocol_dispatch_key(monkeypatch: pytest.MonkeyPatch) -> None: """Accountable HIGH/CRITICAL share the 3jane key so they can zero caps.""" - from utils.dispatch import DISPATCHABLE_PROTOCOLS - module = load_3jane_module() alerts: list = [] stub_cache(monkeypatch, module) @@ -807,8 +805,6 @@ def test_accountable_alerts_use_the_protocol_dispatch_key(monkeypatch: pytest.Mo assert alerts[-1].severity == module.AlertSeverity.CRITICAL assert alerts[-1].protocol == module.PROTOCOL - assert module.ACCOUNTABLE_FEED.protocol == module.PROTOCOL - assert alerts[-1].protocol in DISPATCHABLE_PROTOCOLS def test_accountable_unavailable_run_does_not_rearm_critical(monkeypatch: pytest.MonkeyPatch) -> None: diff --git a/tests/test_known_addresses.py b/tests/test_known_addresses.py index ddf3c320..b51187b7 100644 --- a/tests/test_known_addresses.py +++ b/tests/test_known_addresses.py @@ -31,28 +31,18 @@ def test_chain_specific_takes_precedence(self) -> None: # Different chain → no chain-specific entry, falls through to "". self.assertEqual(known_addresses.lookup(8453, addr), "") - def test_watched_yearn_safe_label_from_safe_config(self) -> None: - self.assertEqual( - known_addresses.lookup(1, "0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52"), - "yChad (Yearn multisig/daddy)", - ) - - def test_yearn_proposer_bot_label_is_chain_agnostic(self) -> None: - self.assertEqual( - known_addresses.lookup(8453, "0x5e69fb460c9950f5ae90daffc4c4f32ecafacaa5"), - "Yearn yChad proposer bot", - ) - - def test_safe_utility_label_is_chain_agnostic(self) -> None: - self.assertEqual( - known_addresses.lookup(42161, "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D"), - "Safe MultiSendCallOnly", - ) + def test_watched_safe_labels_from_safe_config(self) -> None: + safes = [ + ["YEARN_MS", "mainnet", "0x" + "AA" * 20, "yChad"], + ["LIDO", "base-main", "0x" + "BB" * 20], + ["OTHER", "unknown-network", "0x" + "CC" * 20], + ] + with patch("protocols.safe.addresses.ALL_SAFE_ADDRESSES", safes): + labels = known_addresses._watched_safe_labels() - def test_operator_supplied_timelock_label(self) -> None: self.assertEqual( - known_addresses.lookup(1, "0x88Ba032be87d5EF1fbE87336B7090767F367BF73"), - "Yearn TimelockController", + labels, + {(1, "0x" + "aa" * 20): "yChad", (8453, "0x" + "bb" * 20): "LIDO Safe"}, ) diff --git a/tests/test_lender_borrower.py b/tests/test_lender_borrower.py index 2a3fb1be..8487dc47 100644 --- a/tests/test_lender_borrower.py +++ b/tests/test_lender_borrower.py @@ -13,7 +13,6 @@ RAY_TO_WAD, STRATEGIES, WAD, - AaveMarketConfig, Evaluation, RateSample, StrategySnapshot, @@ -75,13 +74,6 @@ def test_aave_borrow_apr_rejects_zero_rate() -> None: aave_borrow_apr_wad((0, 0, 0, 0, 0)) -def test_accumulator_config_targets_underlying_borrower() -> None: - config = STRATEGIES[1] - assert config.address == "0x13f6Cb609959a43c3bE29407766A683b42e26D28" - assert config.monitored_address == "0x41cfE42D221a591C6308Dcea419015Ba8570B380" - assert isinstance(config.market, AaveMarketConfig) - - def test_accrue_market_adds_expected_interest() -> None: market = (2_000_000, 2_000_000, 1_000_000, 1_000_000, 100, 0) accrued = accrue_market(market, 10**14, 200) diff --git a/tests/test_morpho_governance.py b/tests/test_morpho_governance.py index 212deafe..2671128b 100644 --- a/tests/test_morpho_governance.py +++ b/tests/test_morpho_governance.py @@ -125,7 +125,6 @@ def fake_get_data_for_chain(chain: Chain) -> None: governance.main() self.assertEqual(checked, list(governance.VAULTS_V1_BY_CHAIN)) - self.assertIn(Chain.HYPEREVM, checked) if __name__ == "__main__": diff --git a/tests/test_morpho_markets.py b/tests/test_morpho_markets.py index 6a7a6187..a1764018 100644 --- a/tests/test_morpho_markets.py +++ b/tests/test_morpho_markets.py @@ -15,7 +15,7 @@ MorphoV2MonitoringError, get_vault_url, ) -from protocols.morpho.config import VAULTS_V2_BY_CHAIN, VaultConfig, get_collateral_vaults_by_asset +from protocols.morpho.config import VaultConfig from protocols.morpho.markets import ( YV_COLLATERAL_AT_RISK_POINTS, YV_COLLATERAL_STABLE_PRICE_SHOCK, @@ -60,27 +60,6 @@ def _sample_metrics(market_id: str, asset_address: str = "0x" + "22" * 20) -> Ma class TestMorphoV2Configuration(unittest.TestCase): - def test_katana_collateral_strategy_vaults_are_monitored(self) -> None: - configured = {vault.address.lower() for vault in VAULTS_V2_BY_CHAIN[Chain.KATANA]} - expected = { - "0x4284d4f9f4d61ea57b8f0943547c7c19c5b9b249", - "0xca44cbe1fb03691d43d2d93aa460e2fcb03878fe", - "0xa2d38c8a3d810ebcf4c2075821c5ec8f976bb692", - "0xac596ad9771a8d0d4df108ae0406e6f913aedceb", - "0x5920a6fc553af799542eda628adfcc9ea52e141c", - "0xbeeff2d5d126d4809195eea02b605423917bb6c6", - "0xbeef042bad4472c3f7eb9a73070703788b5362d7", - } - - self.assertTrue(expected <= configured) - - collateral_vaults = { - vault.address.lower() - for vaults in get_collateral_vaults_by_asset(Chain.KATANA, version=2).values() - for vault in vaults - } - self.assertEqual(collateral_vaults, expected) - def test_discovery_fails_if_api_omits_configured_vaults(self) -> None: response = MagicMock() response.json.return_value = {"data": {"vaultV2s": {"items": []}}} @@ -488,11 +467,8 @@ def test_v2_low_liquidity_alert_flags_missing_liquidity_adapter(self) -> None: self.assertIn("No liquidity adapter set", send.call_args.args[0].message) - def test_collateral_v2_vaults_get_low_liquidity_check(self) -> None: - collateral_vault = next(v for v in VAULTS_V2_BY_CHAIN[Chain.KATANA] if v.collateral_asset) + def test_analyze_v2_vault_runs_low_liquidity_check(self) -> None: vault = self._v2_vault(0, self._market(90_000, 1_000)) - vault.address = collateral_vault.address - vault.chain = Chain.KATANA with ( patch("protocols.morpho.markets_v2.score_market_allocations"), @@ -556,23 +532,24 @@ def test_parse_liquidity_market_fails_on_unresolvable_adapter(self) -> None: _parse_liquidity_market(broken, "Example", Chain.MAINNET) def test_zero_asset_group_is_retained_for_collateral_risk_check(self) -> None: + vault_address = "0x" + "77" * 20 + asset_address = "0x" + "88" * 20 v1_vaults = [ { "__typename": "Vault", - "address": "0xe107cCdeb8e20E499545C813f98Cc90619b29859", + "address": vault_address, "name": "Yearn OG WBTC", "chain": {"id": Chain.KATANA.chain_id}, - "asset": { - "address": "0x0913DA6Da4b42f538B445599b46Bb4622342Cf52", - "symbol": "vbWBTC", - }, + "asset": {"address": asset_address, "symbol": "vbWBTC"}, "state": {"totalAssetsUsd": 0}, "liquidity": {"usd": 0}, } ] + vault_config = VaultConfig("Yearn OG WBTC", vault_address, 1, asset_address) - groups = get_yv_collateral_liquidity_by_asset(Chain.KATANA, v1_vaults, []) - wbtc_group = groups["0x0913da6da4b42f538b445599b46bb4622342cf52"] + with patch.dict("protocols.morpho.config.VAULTS_V1_BY_CHAIN", {Chain.KATANA: (vault_config,)}): + groups = get_yv_collateral_liquidity_by_asset(Chain.KATANA, v1_vaults, []) + wbtc_group = groups[asset_address] self.assertEqual(wbtc_group.combined_total_assets, 0) self.assertEqual(wbtc_group.combined_liquidity, 0) @@ -586,28 +563,12 @@ def test_market_risk_level_is_case_insensitive_and_defaults_to_5(self) -> None: self.assertEqual(get_market_risk_level(market_id, Chain.MAINNET), 5) self.assertEqual(get_market_risk_level("0x" + "00" * 32, Chain.HYPEREVM), 5) - def test_robinhood_stonk_vault_markets_are_tiered(self) -> None: - spy = "0x50bc39b5722fb5634c436d74c6787f3c125b879e7b73cf9e9ecc01bbb57b8e55" - spy_77 = "0xeb1739b2a69dd22a4285d366a06698a01018b37c24d2994fefe19cc72f313613" - nvda = "0x66306c087add8907752320b309934abcc354d21626de8115c79df49d9c214edc" - nvda_no_quote = "0x95312f02c1dae8407b2c80468a5657a9bd19c45ac277f1a61aa52c11444c5314" - usde = "0xc845da65a020ddca5f132efa8fea79676d8edfdea504226a4c01e7a9e34cddd6" - googl = "0x7408b08b03e05ffd2d21c797489a0e77a28e4bb36acb4e827c69e805d06272b4" - - self.assertEqual(get_market_risk_level(spy, Chain.ROBINHOOD), 2) - self.assertEqual(get_market_risk_level(spy_77, Chain.ROBINHOOD), 3) - self.assertEqual(get_market_risk_level(nvda, Chain.ROBINHOOD), 3) - self.assertEqual(get_market_risk_level(nvda_no_quote, Chain.ROBINHOOD), 3) - self.assertEqual(get_market_risk_level(usde, Chain.ROBINHOOD), 2) - self.assertEqual(get_market_risk_level(googl, Chain.ROBINHOOD), 4) - class TestMorphoUrls(unittest.TestCase): def test_robinhood_uses_morpho_chain_slug(self) -> None: vault = "0x8c258F25fc6fBe3f01ccC828E2C3840A46a4a9A2" self.assertEqual(get_vault_url(vault, Chain.ROBINHOOD), f"https://app.morpho.org/robinhood-chain/vault/{vault}") - self.assertEqual(Chain.ROBINHOOD.explorer_url, "https://robinhoodchain.blockscout.com") if __name__ == "__main__": diff --git a/tests/test_pegged_assets.py b/tests/test_pegged_assets.py index c4bd135a..1433f979 100644 --- a/tests/test_pegged_assets.py +++ b/tests/test_pegged_assets.py @@ -5,15 +5,23 @@ from utils.pegged_assets import ( BTC_USD_DEFILLAMA_KEY, PEGGED_ASSETS, - PEGGED_ASSETS_BY_NAME, + PeggedAsset, PegTarget, get_asset, price_deviation, resolve_peg_prices, ) -# Asset set the registry must cover per the issue acceptance criteria. -REQUIRED_ASSETS = {"WBTC", "cbBTC", "LBTC", "iUSD", "cUSD", "USDe", "USDC", "USDT", "USDS"} + +def _asset(peg: PegTarget = PegTarget.USD, depeg_pct: str = "0.02", downside_only: bool = False) -> PeggedAsset: + return PeggedAsset( + name="TEST", + defillama_key="ethereum:0x" + "11" * 20, + protocol="test", + peg=peg, + depeg_pct=Decimal(depeg_pct), + downside_only=downside_only, + ) class TestPriceDeviation(unittest.TestCase): @@ -37,34 +45,30 @@ def test_zero_peg_raises(self): class TestIsDepegged(unittest.TestCase): def test_within_tolerance_is_not_depegged(self): - usdc = get_asset("USDC") # depeg_pct = 0.02 - self.assertFalse(usdc.is_depegged(Decimal("0.99"), Decimal("1"))) + self.assertFalse(_asset().is_depegged(Decimal("0.99"), Decimal("1"))) def test_beyond_tolerance_is_depegged(self): - usdc = get_asset("USDC") - self.assertTrue(usdc.is_depegged(Decimal("0.97"), Decimal("1"))) + self.assertTrue(_asset().is_depegged(Decimal("0.97"), Decimal("1"))) def test_at_threshold_is_depegged(self): - usdc = get_asset("USDC") - self.assertTrue(usdc.is_depegged(Decimal("1.02"), Decimal("1"))) + self.assertTrue(_asset().is_depegged(Decimal("1.02"), Decimal("1"))) def test_btc_asset_uses_peg_price(self): - cbbtc = get_asset("cbBTC") # depeg_pct = 0.02, peg = BTC - self.assertFalse(cbbtc.is_depegged(Decimal("60500"), Decimal("60000"))) - self.assertTrue(cbbtc.is_depegged(Decimal("58000"), Decimal("60000"))) + btc_asset = _asset(peg=PegTarget.BTC) + self.assertFalse(btc_asset.is_depegged(Decimal("60500"), Decimal("60000"))) + self.assertTrue(btc_asset.is_depegged(Decimal("58000"), Decimal("60000"))) def test_downside_only_ignores_upside(self): - lbtc = get_asset("LBTC") # depeg_pct = 0.03, downside_only - # +5% above peg (LBTC legitimately trades above 1 BTC) -> not a depeg. - self.assertFalse(lbtc.is_depegged(Decimal("63000"), Decimal("60000"))) + asset = _asset(peg=PegTarget.BTC, depeg_pct="0.03", downside_only=True) + # +5% above peg -> not a depeg. + self.assertFalse(asset.is_depegged(Decimal("63000"), Decimal("60000"))) # -5% below peg -> depeg. - self.assertTrue(lbtc.is_depegged(Decimal("57000"), Decimal("60000"))) + self.assertTrue(asset.is_depegged(Decimal("57000"), Decimal("60000"))) # exactly at the downside threshold -> depeg. - self.assertTrue(lbtc.is_depegged(Decimal("58200"), Decimal("60000"))) + self.assertTrue(asset.is_depegged(Decimal("58200"), Decimal("60000"))) def test_symmetric_asset_flags_upside(self): - usdc = get_asset("USDC") # depeg_pct = 0.02, symmetric - self.assertTrue(usdc.is_depegged(Decimal("1.05"), Decimal("1"))) + self.assertTrue(_asset().is_depegged(Decimal("1.05"), Decimal("1"))) class TestResolvePegPrices(unittest.TestCase): @@ -87,9 +91,6 @@ def test_missing_btc_price_raises(self): class TestRegistry(unittest.TestCase): - def test_covers_required_assets(self): - self.assertTrue(REQUIRED_ASSETS.issubset(set(PEGGED_ASSETS_BY_NAME))) - def test_names_are_unique(self): names = [a.name for a in PEGGED_ASSETS] self.assertEqual(len(names), len(set(names))) @@ -102,10 +103,6 @@ def test_every_asset_has_positive_depeg_tolerance(self): for asset in PEGGED_ASSETS: self.assertGreater(asset.depeg_pct, Decimal("0"), asset.name) - def test_btc_wrappers_are_downside_only(self): - for name in ("WBTC", "cbBTC", "LBTC"): - self.assertTrue(get_asset(name).downside_only, name) - if __name__ == "__main__": unittest.main() diff --git a/tests/test_risk_anchors.py b/tests/test_risk_anchors.py index f9bae60b..23a9cbc1 100644 --- a/tests/test_risk_anchors.py +++ b/tests/test_risk_anchors.py @@ -109,30 +109,6 @@ def test_selectors_are_derived_from_signature_table(self) -> None: } self.assertEqual(_ANCHORS, expected) - def test_selectors_match_signatures(self) -> None: - # Recompute the selector for each anchored signature to catch typos. - expected = { - "acceptOwnership()": "0x79ba5097", - "mint(address,uint256)": "0x40c10f19", - "addOwnerWithThreshold(address,uint256)": "0x0d582f13", - "removeOwner(address,address,uint256)": "0xf8dc5dd9", - "swapOwner(address,address,address)": "0xe318b52b", - "changeThreshold(uint256)": "0x694e80c3", - "enableModule(address)": "0x610b5925", - "disableModule(address,address)": "0xe009cfde", - "setGuard(address)": "0xe19a9dd9", - "setFallbackHandler(address)": "0xf08a0323", - } - for sig, selector in expected.items(): - self.assertEqual("0x" + function_signature_to_4byte_selector(sig).hex(), selector, sig) - self.assertIn(selector, _ANCHORS, f"{sig} ({selector}) not registered") - - def test_safe_module_is_critical(self) -> None: - # enableModule can move funds with no owner signatures — highest band. - anchor = lookup("0x610b5925") - assert anchor is not None - self.assertEqual(anchor.level, "CRITICAL") - if __name__ == "__main__": unittest.main() diff --git a/tests/test_small_parent_flows.py b/tests/test_small_parent_flows.py index a832a860..3587bd96 100644 --- a/tests/test_small_parent_flows.py +++ b/tests/test_small_parent_flows.py @@ -20,6 +20,16 @@ "asset_decimals": 6, } +EXCLUDED_INITIATOR = "0x" + "e9" * 20 + + +@pytest.fixture(autouse=True) +def _excluded_initiators(monkeypatch: pytest.MonkeyPatch) -> None: + """Exclude a fake Katana initiator so tests don't depend on the real config.""" + monkeypatch.setattr( + monitor, "IGNORED_TRANSACTION_SENDERS", {Chain.KATANA.chain_id: frozenset({EXCLUDED_INITIATOR})} + ) + def make_event( *, @@ -127,7 +137,7 @@ def test_process_event_raises_without_alert_sender() -> None: @pytest.mark.parametrize("flow_type", ["deposit", "withdrawal"]) @pytest.mark.parametrize( "initiator", - ["0xe9312419edc29e7784ac2f5aa2fd2ac0f38ff2af", "0xe9312419edc29E7784AC2F5AA2Fd2ac0f38fF2Af"], + [EXCLUDED_INITIATOR, "0x" + "E9" * 20], ) def test_process_event_excludes_katana_initiator(flow_type: str, initiator: str) -> None: """Excluded initiators do not consume aggregate capacity or emit summaries.""" @@ -147,7 +157,7 @@ def test_process_event_excludes_katana_initiator(flow_type: str, initiator: str) def test_process_event_exclusion_is_chain_scoped() -> None: """The same address remains monitored outside Katana.""" event = make_event(chain_id=Chain.MAINNET.chain_id) - event["transactionFrom"] = "0xe9312419edc29E7784AC2F5AA2Fd2ac0f38fF2Af" + event["transactionFrom"] = EXCLUDED_INITIATOR records: list[monitor.SmallFlowRecord] = [] assert monitor.process_event(event, {"0xparent": VAULT}, 10_000, records.append) @@ -160,7 +170,7 @@ def test_process_event_does_not_exclude_other_participants(initiator: str | None event = make_event(flow_type="withdrawal", chain_id=Chain.KATANA.chain_id) event["transactionFrom"] = initiator for field in ("sender", "owner", "receiver"): - event[field] = "0xe9312419edc29E7784AC2F5AA2Fd2ac0f38fF2Af" + event[field] = EXCLUDED_INITIATOR records: list[monitor.SmallFlowRecord] = [] assert monitor.process_event(event, {"0xparent": VAULT}, 10_000, records.append) @@ -172,7 +182,7 @@ def test_monitor_flow_type_advances_past_excluded_events(monkeypatch: pytest.Mon """Excluded events advance the cursor without preventing later flows from alerting.""" chain_id = Chain.KATANA.chain_id first = make_event(flow_type=flow_type, chain_id=chain_id) - first["transactionFrom"] = "0xe9312419edc29E7784AC2F5AA2Fd2ac0f38fF2Af" + first["transactionFrom"] = EXCLUDED_INITIATOR second = make_event(flow_type=flow_type, chain_id=chain_id, block_number=101) third = {**first, "blockNumber": 102} pages = iter([[first], [second], [third], []]) diff --git a/tests/test_stables_oracles.py b/tests/test_stables_oracles.py index c2989ccc..c3e1dd6d 100644 --- a/tests/test_stables_oracles.py +++ b/tests/test_stables_oracles.py @@ -14,7 +14,6 @@ ) from utils.alert import AlertSeverity from utils.chainlink import FeedReading, RoundData -from utils.dispatch import DISPATCHABLE_PROTOCOLS from utils.pegged_assets import ChainlinkFeed, PeggedAsset, PegTarget, RateOracle, get_asset NOW = 2_000_000 @@ -230,13 +229,20 @@ def test_small_change_no_alert(self): class TestDispatchRouting(unittest.TestCase): """Alerts must carry the asset's logical protocol so emergency dispatch can fire.""" - def test_owned_asset_uses_dispatchable_protocol(self): - usde = get_asset("USDe") # owner "ethena", peg USD, 3% tolerance - feed = usde.chainlink_feed - assert feed is not None + def test_alert_protocol_is_asset_owner_not_channel(self): + feed_address = "0x" + "22" * 20 + asset = PeggedAsset( + name="fakeUSD", + defillama_key="ethereum:0x" + "11" * 20, + protocol="owner", + peg=PegTarget.USD, + depeg_pct=Decimal("0.03"), + chainlink_feed=ChainlinkFeed(address=feed_address, heartbeat=HEARTBEAT), + channel="pegs", + ) obs = OracleObservation( - asset=usde, - reading=_reading(feed.address, 90 * 10**6), # $0.90 -> off peg + asset=asset, + reading=_reading(feed_address, 90 * 10**6), # $0.90 -> off peg peg_price_usd=Decimal("1"), quote_price_usd=Decimal("1"), now=NOW, @@ -245,8 +251,7 @@ def test_owned_asset_uses_dispatchable_protocol(self): alert = check_peg_deviation(obs) assert alert is not None # protocol (not channel) carries the owner; dispatch keys off alert.protocol. - self.assertEqual(alert.protocol, "ethena") - self.assertIn(alert.protocol, DISPATCHABLE_PROTOCOLS) + self.assertEqual(alert.protocol, "owner") class TestRoundMetadataGate(unittest.TestCase): diff --git a/tests/test_threejane_context.py b/tests/test_threejane_context.py index 8bf5d14a..64d53d79 100644 --- a/tests/test_threejane_context.py +++ b/tests/test_threejane_context.py @@ -274,30 +274,6 @@ def test_every_known_label_hashes_to_its_own_entry(self) -> None: self.assertEqual(as_hex, "0x" + keccak(text=name).hex()) self.assertTrue(note, f"{name} has no explanatory note") - def test_notes_follow_the_consuming_contracts(self) -> None: - """Notes are read from the contract that consumes each key; several used to misstate units or zero.""" - notes = threejane_context._HASHED_LABELS - self.assertIn("waUSDC", notes["DEBT_CAP"]) - self.assertIn("0 blocks all new borrowing", notes["DEBT_CAP"]) - self.assertIn("not a lending limit", notes["MAX_ON_CREDIT"]) - self.assertIn("0 freezes the market", notes["CYCLE_DURATION"]) - self.assertIn("0 falls back to 1500", notes["TRANCHE_RATIO"]) - self.assertIn("syncTrancheShare", notes["TRANCHE_SHARE_VARIANT"]) - self.assertIn("USD3 deploys to credit", notes["MIN_SUSD3_BACKING_RATIO"]) - for unused in ("MIN_LOAN_DURATION", "LATE_REPAYMENT_THRESHOLD", "DEFAULT_THRESHOLD", "USD3_COMMITMENT_TIME"): - self.assertIn("no on-chain effect", notes[unused]) - - def test_every_protocol_config_lib_key_is_known(self) -> None: - """ProtocolConfigLib keys an alert can set; the redemption floors and tend threshold were missing.""" - for name in ( - "USD3_REDEMPTION_FLOOR", - "USD3_REDEMPTION_FLOOR_BPS", - "TEND_DRIFT_THRESHOLD", - "SUSD3_NOMINAL_BACKING_FLOOR", - "FULL_MARKDOWN_DURATION", - ): - self.assertIn("0x" + keccak(text=name).hex(), threejane_context._LABELS_BY_HASH) - def test_wausdc_keys_render_with_a_usdc_equivalent(self) -> None: """Two HIGH alerts left DEBT_CAP and an 81.5M credit line in "raw units"; they are waUSDC.""" wausdc = TokenUnit(threejane_context.WAUSDC_ADDRESS, "waEthUSDC", 6) diff --git a/tests/test_web3_wrapper.py b/tests/test_web3_wrapper.py index bcb40601..8454d03c 100644 --- a/tests/test_web3_wrapper.py +++ b/tests/test_web3_wrapper.py @@ -6,7 +6,7 @@ from web3 import Web3 -from utils.chains import PUBLIC_RPC_URLS, Chain +from utils.chains import Chain from utils.web3_wrapper import ( MAX_BACKOFF_SECONDS, REQUEST_TIMEOUT_SECONDS, @@ -134,29 +134,27 @@ def _client(self, chain: Chain) -> Web3Client: def _env_without_providers(self) -> dict[str, str]: return {key: value for key, value in os.environ.items() if not key.startswith("PROVIDER_URL_")} - def test_production_mapping_has_hyperevm_public_rpc(self): - self.assertEqual(PUBLIC_RPC_URLS[Chain.HYPEREVM.chain_id], "https://rpc.hyperliquid.xyz/evm") + PUBLIC_URLS = {Chain.HYPEREVM.chain_id: "https://public.example/evm"} - def test_hyperevm_falls_back_to_public_rpc(self): + def test_falls_back_to_public_rpc(self): with ( patch.dict(os.environ, self._env_without_providers(), clear=True), - # conftest blanks the mapping for isolation; restore the production values here. - patch("utils.web3_wrapper.DEFAULT_PROVIDER_URLS", PUBLIC_RPC_URLS), + patch("utils.web3_wrapper.DEFAULT_PROVIDER_URLS", self.PUBLIC_URLS), ): - self.assertEqual(self._client(Chain.HYPEREVM)._get_provider_urls(), ["https://rpc.hyperliquid.xyz/evm"]) + self.assertEqual(self._client(Chain.HYPEREVM)._get_provider_urls(), ["https://public.example/evm"]) def test_env_provider_disables_public_fallback(self): env = {**self._env_without_providers(), "PROVIDER_URL_HYPEREVM": "https://custom.example/evm"} with ( patch.dict(os.environ, env, clear=True), - patch("utils.web3_wrapper.DEFAULT_PROVIDER_URLS", PUBLIC_RPC_URLS), + patch("utils.web3_wrapper.DEFAULT_PROVIDER_URLS", self.PUBLIC_URLS), ): self.assertEqual(self._client(Chain.HYPEREVM)._get_provider_urls(), ["https://custom.example/evm"]) def test_chain_without_default_still_requires_env(self): with ( patch.dict(os.environ, self._env_without_providers(), clear=True), - patch("utils.web3_wrapper.DEFAULT_PROVIDER_URLS", PUBLIC_RPC_URLS), + patch("utils.web3_wrapper.DEFAULT_PROVIDER_URLS", self.PUBLIC_URLS), ): with self.assertRaisesRegex(ValueError, "No providers found for chain MAINNET"): self._client(Chain.MAINNET)._get_provider_urls()