ipor-fusion 4.1.0.dev26__tar.gz → 4.1.0.dev35__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/PKG-INFO +1 -1
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/pyproject.toml +1 -1
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/options.py +16 -20
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/fusion_factory.py +4 -3
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/mcp/server.py +16 -6
- ipor_fusion-4.1.0.dev35/tests/_addresses.py +17 -0
- ipor_fusion-4.1.0.dev35/tests/test_addresses_helper.py +20 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_helpers.py +15 -12
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_fusion_instance.py +3 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_mcp_preflight.py +9 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_mcp_server.py +15 -5
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_types_and_events.py +2 -3
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.claude-plugin/marketplace.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.claude-plugin/plugin.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.env.example +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.gemini/settings.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.git-blame-ignore-revs +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.github/workflows/cd.yml +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.github/workflows/ci.yml +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.github/workflows/commit-lint.yml +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.github/workflows/notify-slack.yml +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.github/workflows/python-build.yml +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.github/workflows/python-publish.yml +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.github/workflows/release.yml +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.github/workflows/report-slack.yml +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.gitignore +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.pre-commit-config.yaml +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/.python-version +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/AGENTS.md +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/CHANGELOG.md +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/CLAUDE.md +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/CODEOWNERS +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/LICENSE +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/MIGRATION_4.md +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/README.md +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/build.sh +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/examples/CONTRIBUTING.md +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/examples/README.md +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/examples/advanced_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/examples/advanced_euler_v2_looping_arbitrum.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/examples/external_state_margin_leg_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/examples/hypercore_vault_official_deployment_hyperevm.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/examples/simple_aave_v3_supply_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/pytest.ini +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/scripts/commit-check.sh +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/scripts/fusion_error_signatures.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/skills/ipor-deploy-vault/SKILL.md +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/about.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cache.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/chains.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/address_cmd.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/config_cmd.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/config_store.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/main.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/market_cmd.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/oracle_mapping_view.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/preflight_cmd.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/vault_cmd.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/vault_health.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/vault_info_view.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/vault_rendering.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/config/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/config/roles.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/access.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/address.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/context.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/context_manager.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/contract.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/erc20.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/external_state_executor.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/fee_manager.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/fuse.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/fuse_action.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/fuse_decoding.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/logs.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/multicall.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/oracle.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/plasma_vault.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/rewards_manager.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/simulation.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/simulation_result.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/withdraw_manager.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/chainlink.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/codec.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/contracts.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/indexer.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/lane.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/quote.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/transport.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/contracts.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/discovery.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/errors.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/fuses/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/fuses/base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/fuses/ccip.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/fuses/stargate.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/lane.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/logs.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/messages.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/simulation.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/stargate/contracts.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/stargate/lane.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/stargate/layerzero.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/stargate/transport.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/transport.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/dependency_graph.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/entry_cli.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/entry_mcp.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/errors.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/explorer.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/field_docs.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/aave_v3.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/async_action.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/compound_v3.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/erc4626.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/euler_v2.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/events.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/external_state.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/external_state_event_decoding.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/hypercore.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/hypercore_event_decoding.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/hypercore_pre_hooks.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/merkl.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/morpho.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fuses/universal.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/fusion_errors.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/guide/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/guide/architecture.md +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/guide/glossary.md +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/guide/invariants.md +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/guide/quickstart.md +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/hypercore/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/market_ids.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/market_info.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/mcp/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/mcp/guide.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/mcp/models.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/morpho_api.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/preflight.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/py.typed +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/aave_v3.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/aave_v4.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/compound_v3.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/euler_v2.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/hypercore.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/hypercore_outcome.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/lending_health.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/morpho.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/oracle_mapping.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/oracle_mapping_nodes.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/oracle_mapping_reader.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/position_manager.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/ramses_v2.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/readers/unpriceable.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/registry.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/substrates.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/types.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/validation.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/vault_data.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/vault_erc20.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/vault_info.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/vault_managers.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/vault_positions.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/vault_reads.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/UniswapV3UniversalRouter.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_crosschain.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_crosschain_recovery.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_euler_v2.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_event_args.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_fake_rpc.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_foundry.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_golden.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_guide.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_hypercore_model.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_hypercore_shadow.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_live.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_multicall.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_oracle_mapping_fake.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_simulate.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/_validation.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/addresses.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/conftest.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/constants.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/hypercore_hip3_flow.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/hypercore_market55.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/hypercore_official.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/market_golden/meta_morpho_v1.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/market_golden/meta_morpho_v1.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/market_golden/meta_morpho_v2.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/market_golden/meta_morpho_v2.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/market_golden/morpho_api/market.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/market_golden/morpho_api/vault_v1.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/market_golden/morpho_api/vault_v2.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/market_golden/morpho_api/vault_v2_not_found.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/market_golden/morpho_blue.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/market_golden/morpho_blue.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/market_golden/morpho_blue_api_error.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/market_golden/morpho_blue_api_error.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/market_golden/morpho_blue_no_api.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/market_golden/morpho_blue_no_api.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/oracle_mapping_golden/mapping.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/oracle_mapping_golden/mapping.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/simulate_v1_request.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/vault_info_golden/clean.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/vault_info_golden/clean.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/vault_info_golden/clean.txt +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/vault_info_golden/deployment_error.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/vault_info_golden/deployment_error.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/vault_info_golden/deployment_error.txt +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/vault_info_golden/fetched.cli.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/vault_info_golden/fetched.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/vault_info_golden/fetched.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/vault_info_golden/full.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/vault_info_golden/full.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/vault_info_golden/full.txt +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/vault_info_golden/rich.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/vault_info_golden/rich.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/fixtures/vault_info_golden/rich.txt +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_about.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_access_manager.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cache.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_chains.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_address.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_changelog.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_commands.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_config_store.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_hypercore.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_lending_health.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_market_golden.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_market_morpho_blue.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_mcp_parity.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_oracle_mapping.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_oracle_mapping_golden.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_pending_requests_scan.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_preflight.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_role_accounts.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_vault_info_golden.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_vault_predates_getters.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_cli_vault_validate.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_contract_call.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_contract_encoder.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_crosschain_ccip_events.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_crosschain_ccip_indexer.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_crosschain_ccip_quote.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_crosschain_chainlink.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_crosschain_contracts.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_crosschain_encoding.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_crosschain_errors.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_crosschain_lane.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_crosschain_layering.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_crosschain_transport.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_docs_typing.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_erc20.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_error_hierarchy.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_examples_crosschain.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_examples_euler_looping_arbitrum.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_examples_hypercore_hyperevm.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_examples_vaults.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_explorer.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_external_state_events.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_external_state_executor.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_fee_manager.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_fuse_decoding.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_fuse_encoding.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_fusion_errors.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_governance_wrappers.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_guide.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_hypercore_deployment.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_hypercore_events.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_hypercore_flow.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_hypercore_live.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_hypercore_outcome.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_hypercore_pre_hooks.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_hypercore_readers.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_hypercore_simulation.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_logs.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_mcp_address.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_mcp_hypercore.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_mcp_models.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_mcp_vault_validate.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_multicall.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_oracle.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_oracle_mapping.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_plasma_vault.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_preflight.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_public_api.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_public_type_reachability.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_reader_encoding.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_registry.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_revert_decoding.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_rewards_manager.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_roles.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_sdk_layering.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_claim_morpho_rewards.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_crosschain_hyperevm.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_euler_v2_batch_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_examples_arbitrum.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_examples_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_examples_crosschain.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_examples_hyperevm.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_external_state_executor_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_looping_aave_v3_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_morpho_blue.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_pilot_v3.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_pilot_v5_ramses.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_preflight_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_readers_integration.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_release_funds.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_swap_on_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_timelock_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulate_vault_from_scratch_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulation_errors.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_simulation_observation.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_solidity_compiler.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_solidity_mirrors.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_substrates.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_unpriceable_tokens.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_validation.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_vault_data_block.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_vault_dep_graph.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_vault_info_fetched_golden.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_vault_info_onchain_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_vault_reconciliation_onchain_base.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_vault_simulator_blocks.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_web3_context.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/test_withdraw_manager.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/typed_client/consumer.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/tests/typed_client/rejected.py +0 -0
- {ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/uv.lock +0 -0
|
@@ -2,7 +2,6 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import click
|
|
4
4
|
from eth_typing import ChecksumAddress
|
|
5
|
-
from web3 import Web3
|
|
6
5
|
|
|
7
6
|
from ipor_fusion.chains import CHAIN_NAME_TO_ID, ensure_supported_chain
|
|
8
7
|
from ipor_fusion.cli.config_store import (
|
|
@@ -13,7 +12,12 @@ from ipor_fusion.core.context import Web3Context
|
|
|
13
12
|
from ipor_fusion.errors import (
|
|
14
13
|
UnsupportedChainError,
|
|
15
14
|
)
|
|
16
|
-
from ipor_fusion.types import
|
|
15
|
+
from ipor_fusion.types import (
|
|
16
|
+
ChainId,
|
|
17
|
+
PlasmaVaultAddress,
|
|
18
|
+
parse_checksum_address,
|
|
19
|
+
parse_hex_address,
|
|
20
|
+
)
|
|
17
21
|
|
|
18
22
|
|
|
19
23
|
# click < 8.4 does not make ParamType generic, so it cannot be subscripted.
|
|
@@ -27,26 +31,18 @@ class AddressType(click.ParamType): # pyright: ignore[reportMissingTypeArgument
|
|
|
27
31
|
self.fail(f"expected string, got {type(value).__name__}", param, ctx)
|
|
28
32
|
|
|
29
33
|
value = value.strip()
|
|
30
|
-
if
|
|
31
|
-
value =
|
|
34
|
+
if value[:2] in ("0x", "0X"):
|
|
35
|
+
value = value[2:]
|
|
36
|
+
value = "0x" + value
|
|
32
37
|
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
try:
|
|
39
|
+
parse_hex_address(value)
|
|
40
|
+
except ValueError:
|
|
35
41
|
self.fail(f"invalid Ethereum address: {value}", param, ctx)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
except Exception:
|
|
41
|
-
self.fail(f"invalid address checksum: {value}", param, ctx)
|
|
42
|
-
if checksum != value:
|
|
43
|
-
self.fail(
|
|
44
|
-
f"bad checksum — expected {checksum}, got {value}",
|
|
45
|
-
param,
|
|
46
|
-
ctx,
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
return Web3.to_checksum_address(value)
|
|
42
|
+
try:
|
|
43
|
+
return parse_checksum_address(value)
|
|
44
|
+
except ValueError as exc:
|
|
45
|
+
self.fail(str(exc), param, ctx)
|
|
50
46
|
|
|
51
47
|
|
|
52
48
|
ADDRESS = AddressType()
|
|
@@ -38,6 +38,7 @@ from ipor_fusion.types import (
|
|
|
38
38
|
Period,
|
|
39
39
|
PlasmaVaultAddress,
|
|
40
40
|
parse_access_manager_address,
|
|
41
|
+
parse_checksum_address,
|
|
41
42
|
parse_plasma_vault_address,
|
|
42
43
|
)
|
|
43
44
|
|
|
@@ -82,8 +83,8 @@ class FusionInstance:
|
|
|
82
83
|
def from_dict(cls, data: Mapping[str, object]) -> FusionInstance:
|
|
83
84
|
"""Rebuild an instance from its JSON form (``dataclasses.asdict``),
|
|
84
85
|
parsing every field: role addresses through their parsers, the rest
|
|
85
|
-
|
|
86
|
-
on a missing, extra or malformed field."""
|
|
86
|
+
through `parse_checksum_address`, integers and strings type-checked.
|
|
87
|
+
Raises ``ValueError`` on a missing, extra or malformed field."""
|
|
87
88
|
names = {f.name for f in fields(cls)}
|
|
88
89
|
missing = names - data.keys()
|
|
89
90
|
extra = data.keys() - names
|
|
@@ -128,7 +129,7 @@ def _text(value: object) -> str:
|
|
|
128
129
|
|
|
129
130
|
|
|
130
131
|
def _address(value: object) -> ChecksumAddress:
|
|
131
|
-
return
|
|
132
|
+
return parse_checksum_address(_text(value))
|
|
132
133
|
|
|
133
134
|
|
|
134
135
|
_FUSION_INSTANCE_OUTPUT_TYPES: list[str] = [
|
|
@@ -8,6 +8,7 @@ from collections.abc import Callable
|
|
|
8
8
|
from functools import partial
|
|
9
9
|
from typing import Annotated, Literal
|
|
10
10
|
|
|
11
|
+
from eth_typing import ChecksumAddress
|
|
11
12
|
from mcp.server.fastmcp import FastMCP
|
|
12
13
|
from pydantic import AfterValidator, BeforeValidator, Field
|
|
13
14
|
from web3 import Web3
|
|
@@ -76,8 +77,8 @@ from ipor_fusion.registry import (
|
|
|
76
77
|
from ipor_fusion.types import (
|
|
77
78
|
ChainId,
|
|
78
79
|
PlasmaVaultAddress,
|
|
80
|
+
parse_checksum_address,
|
|
79
81
|
parse_morpho_market_id,
|
|
80
|
-
parse_plasma_vault_address,
|
|
81
82
|
)
|
|
82
83
|
from ipor_fusion.validation import validate_vault
|
|
83
84
|
from ipor_fusion.vault_data import (
|
|
@@ -117,14 +118,19 @@ def _resolve_provider(cfg: FusionConfig, chain_id: ChainId) -> str:
|
|
|
117
118
|
)
|
|
118
119
|
|
|
119
120
|
|
|
120
|
-
def
|
|
121
|
-
"""
|
|
121
|
+
def _address_arg(raw: str) -> ChecksumAddress:
|
|
122
|
+
"""An address as a tool caller sends it: surrounding whitespace and a
|
|
122
123
|
missing ``0x`` are accepted, as in 3.x; letter case follows
|
|
123
124
|
`parse_checksum_address`, so a wrong EIP-55 checksum is refused."""
|
|
124
125
|
value = raw.strip()
|
|
125
126
|
if value[:2] not in ("0x", "0X"):
|
|
126
127
|
value = "0x" + value
|
|
127
|
-
return
|
|
128
|
+
return parse_checksum_address(value)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def _vault_arg(raw: str) -> PlasmaVaultAddress:
|
|
132
|
+
"""`_address_arg`, labeled as a Plasma Vault's address."""
|
|
133
|
+
return PlasmaVaultAddress(_address_arg(raw))
|
|
128
134
|
|
|
129
135
|
|
|
130
136
|
def _resolve_chain_id(
|
|
@@ -341,6 +347,10 @@ def vault_preflight(
|
|
|
341
347
|
raise ValueError(f"calldata: {exc}") from exc
|
|
342
348
|
if not actions:
|
|
343
349
|
raise ValueError("calldata: the batch has no actions")
|
|
350
|
+
try:
|
|
351
|
+
sender_address = _address_arg(sender)
|
|
352
|
+
except ValueError as exc:
|
|
353
|
+
raise ValueError(f"sender: {exc}") from exc
|
|
344
354
|
cfg = load_config()
|
|
345
355
|
checksum = _vault_arg(vault_address)
|
|
346
356
|
chain_id = _resolve_chain_id(cfg, checksum, chain_id)
|
|
@@ -350,7 +360,7 @@ def vault_preflight(
|
|
|
350
360
|
ctx,
|
|
351
361
|
checksum,
|
|
352
362
|
actions,
|
|
353
|
-
sender=
|
|
363
|
+
sender=sender_address,
|
|
354
364
|
simulate=simulate,
|
|
355
365
|
)
|
|
356
366
|
return ExecutePreflightResponse.model_validate(build_execute_preflight_json(result))
|
|
@@ -752,7 +762,7 @@ def market_meta_morpho(
|
|
|
752
762
|
vault_address: MetaMorpho V1 or Vault V2 address.
|
|
753
763
|
chain_id: EVM chain ID.
|
|
754
764
|
"""
|
|
755
|
-
info = fetch_vault(
|
|
765
|
+
info = fetch_vault(_address_arg(vault_address), chain_id)
|
|
756
766
|
payload = build_meta_morpho_json(info, chain_id)
|
|
757
767
|
return MetaMorphoVaultResponse.model_validate(payload)
|
|
758
768
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Address spellings that EIP-55 must reject."""
|
|
2
|
+
|
|
3
|
+
from web3 import Web3
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def miscased(address: str) -> str:
|
|
7
|
+
"""``address`` checksummed with one letter's case flipped: the same 20 bytes,
|
|
8
|
+
a wrong checksum. Only a mixed-case result carries a checksum, so the first
|
|
9
|
+
flip that leaves the digits mixed case is taken."""
|
|
10
|
+
checksummed = Web3.to_checksum_address(address)
|
|
11
|
+
for i, c in enumerate(checksummed[2:], start=2):
|
|
12
|
+
if c.isalpha():
|
|
13
|
+
flipped = checksummed[:i] + c.swapcase() + checksummed[i + 1 :]
|
|
14
|
+
digits = flipped[2:]
|
|
15
|
+
if digits not in (digits.lower(), digits.upper()):
|
|
16
|
+
return flipped
|
|
17
|
+
raise AssertionError(f"no wrong checksum is possible for {address}")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""The ``miscased`` test helper returns a spelling EIP-55 rejects, or fails."""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from _addresses import miscased
|
|
5
|
+
|
|
6
|
+
from ipor_fusion.types import parse_checksum_address
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_skips_a_flip_that_leaves_one_case():
|
|
10
|
+
# Flipping B gives all lowercase, which carries no checksum.
|
|
11
|
+
address = "0xBca0000000000000000000000000000000000000"
|
|
12
|
+
bad = miscased(address)
|
|
13
|
+
assert bad.lower() == address.lower()
|
|
14
|
+
with pytest.raises(ValueError, match="invalid address checksum"):
|
|
15
|
+
parse_checksum_address(bad)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_fails_when_no_flip_leaves_mixed_case():
|
|
19
|
+
with pytest.raises(AssertionError, match="no wrong checksum"):
|
|
20
|
+
miscased("0xCc00000000000000000000000000000000000000")
|
|
@@ -6,6 +6,7 @@ from unittest.mock import MagicMock, patch
|
|
|
6
6
|
|
|
7
7
|
import click
|
|
8
8
|
import pytest
|
|
9
|
+
from _addresses import miscased
|
|
9
10
|
from _multicall import decode_aggregate3, multicall_aware
|
|
10
11
|
from _validation import holding, validate
|
|
11
12
|
from click.testing import CliRunner
|
|
@@ -131,9 +132,20 @@ class TestAddressType:
|
|
|
131
132
|
checksum = Web3.to_checksum_address("0x" + "1a2b3c4d5e" * 4)
|
|
132
133
|
assert ADDRESS.convert(checksum, None, None) == checksum
|
|
133
134
|
|
|
135
|
+
@pytest.mark.parametrize(
|
|
136
|
+
"raw",
|
|
137
|
+
[
|
|
138
|
+
"0X" + "ab" * 20,
|
|
139
|
+
"0X" + "AB" * 20,
|
|
140
|
+
"0X" + VALID_CHECKSUM[2:],
|
|
141
|
+
],
|
|
142
|
+
)
|
|
143
|
+
def test_valid_with_uppercase_0x_prefix(self, raw: str):
|
|
144
|
+
assert _convert_via_cli(raw) == VALID_CHECKSUM
|
|
145
|
+
|
|
134
146
|
def test_bad_checksum_mixed_case(self):
|
|
135
147
|
good = str(Web3.to_checksum_address("0x" + "1a2b3c4d5e" * 4))
|
|
136
|
-
bad = good
|
|
148
|
+
bad = miscased(good)
|
|
137
149
|
runner = CliRunner()
|
|
138
150
|
|
|
139
151
|
@click.command()
|
|
@@ -143,6 +155,8 @@ class TestAddressType:
|
|
|
143
155
|
|
|
144
156
|
result = runner.invoke(cmd, [bad])
|
|
145
157
|
assert result.exit_code != 0
|
|
158
|
+
assert "invalid address checksum" in result.output
|
|
159
|
+
assert good not in result.output
|
|
146
160
|
|
|
147
161
|
def test_too_short(self):
|
|
148
162
|
runner = CliRunner()
|
|
@@ -1158,17 +1172,6 @@ class TestPrintBalanceFusesTable:
|
|
|
1158
1172
|
assert "Zero-Balance Fuses" not in out
|
|
1159
1173
|
|
|
1160
1174
|
|
|
1161
|
-
class TestAddressTypeChecksumException:
|
|
1162
|
-
@patch("ipor_fusion.cli.options.Web3.to_checksum_address")
|
|
1163
|
-
def test_checksum_exception_caught(self, mock_checksum):
|
|
1164
|
-
mock_checksum.side_effect = Exception("unexpected error")
|
|
1165
|
-
mixed = "0xAbCdEf1234567890aBcDeF1234567890AbCdEf12"
|
|
1166
|
-
with pytest.raises(
|
|
1167
|
-
click.exceptions.BadParameter, match="invalid address checksum"
|
|
1168
|
-
):
|
|
1169
|
-
ADDRESS.convert(mixed, None, None)
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
1175
|
class TestPrintReconciliation:
|
|
1173
1176
|
def test_within_threshold(self, capsys):
|
|
1174
1177
|
data = VaultData(
|
|
@@ -6,6 +6,7 @@ from __future__ import annotations
|
|
|
6
6
|
from dataclasses import asdict
|
|
7
7
|
|
|
8
8
|
import pytest
|
|
9
|
+
from _addresses import miscased
|
|
9
10
|
from web3 import Web3
|
|
10
11
|
|
|
11
12
|
from ipor_fusion.core.fusion_factory import FusionInstance
|
|
@@ -58,6 +59,8 @@ def test_from_dict_checksums_every_address_and_round_trips():
|
|
|
58
59
|
(lambda d: d.update(extra=1), "extra"),
|
|
59
60
|
(lambda d: d.update(plasma_vault="0x1234"), "address"),
|
|
60
61
|
(lambda d: d.update(plasma_vault=" " + d["plasma_vault"]), "address"),
|
|
62
|
+
(lambda d: d.update(plasma_vault=miscased(d["plasma_vault"])), "checksum"),
|
|
63
|
+
(lambda d: d.update(price_manager=miscased(d["price_manager"])), "checksum"),
|
|
61
64
|
(lambda d: d.update(asset_decimals="8"), "integer"),
|
|
62
65
|
(lambda d: d.update(index=True), "integer"),
|
|
63
66
|
(lambda d: d.update(asset_symbol=None), "string"),
|
|
@@ -4,6 +4,7 @@ import asyncio
|
|
|
4
4
|
from unittest.mock import MagicMock, patch
|
|
5
5
|
|
|
6
6
|
import pytest
|
|
7
|
+
from _addresses import miscased
|
|
7
8
|
from mcp.server.fastmcp.exceptions import ToolError
|
|
8
9
|
from web3 import Web3
|
|
9
10
|
|
|
@@ -26,6 +27,8 @@ from ipor_fusion.types import (
|
|
|
26
27
|
|
|
27
28
|
VAULT = PlasmaVaultAddress(Web3.to_checksum_address("0x" + "11" * 20))
|
|
28
29
|
SENDER = Web3.to_checksum_address("0x" + "33" * 20)
|
|
30
|
+
# Hex letters, so it can carry a wrong checksum; SENDER has none.
|
|
31
|
+
SENDER_HEX = "0x" + "ab" * 20
|
|
29
32
|
FUSE = FuseAddress(Web3.to_checksum_address("0x" + "55" * 20))
|
|
30
33
|
ACTION = AaveV3SupplyFuse(FUSE).supply(
|
|
31
34
|
asset=Web3.to_checksum_address("0x" + "44" * 20), amount=Amount(10)
|
|
@@ -84,3 +87,9 @@ def test_bad_calldata_is_a_tool_error(preflight):
|
|
|
84
87
|
with pytest.raises(ToolError, match="no actions"):
|
|
85
88
|
_call(vault_address=VAULT, calldata=empty, sender=SENDER)
|
|
86
89
|
preflight.assert_not_called()
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def test_wrong_sender_checksum_is_a_tool_error(preflight):
|
|
93
|
+
with pytest.raises(ToolError, match="sender: invalid address checksum"):
|
|
94
|
+
_call(vault_address=VAULT, calldata=CALLDATA, sender=miscased(SENDER_HEX))
|
|
95
|
+
preflight.assert_not_called()
|
|
@@ -5,6 +5,7 @@ import importlib.metadata
|
|
|
5
5
|
from unittest.mock import ANY, MagicMock, patch
|
|
6
6
|
|
|
7
7
|
import pytest
|
|
8
|
+
from _addresses import miscased
|
|
8
9
|
from mcp.server.fastmcp.exceptions import ToolError
|
|
9
10
|
from web3 import Web3
|
|
10
11
|
|
|
@@ -770,7 +771,7 @@ _LOAN = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
|
|
|
770
771
|
_COLLAT = "0xD2af830E8CBdFed6CC11Bab697bB25496ed6FA62"
|
|
771
772
|
_ORACLE = "0x7C65985C35181D51eF7571FA40211B57659B7d80"
|
|
772
773
|
_IRM = "0x870Ac11D48B15db9a138Cf899d20F13F79Ba00BC"
|
|
773
|
-
_VAULT = "
|
|
774
|
+
_VAULT = Web3.to_checksum_address("0xf9bddd4a9b3a45f980e11fdde96e16364ddbec49")
|
|
774
775
|
|
|
775
776
|
|
|
776
777
|
def _stub_reader_instance():
|
|
@@ -1085,6 +1086,17 @@ class TestMarketMetaMorpho:
|
|
|
1085
1086
|
with pytest.raises(MorphoApiError, match="not found"):
|
|
1086
1087
|
market_meta_morpho(vault_address=_VAULT, chain_id=1)
|
|
1087
1088
|
|
|
1089
|
+
@patch("ipor_fusion.mcp.server.fetch_vault", return_value=_v1_info())
|
|
1090
|
+
def test_accepts_padded_bare_lowercase_address(self, fetch):
|
|
1091
|
+
market_meta_morpho(vault_address=f" {_VAULT[2:].lower()} ", chain_id=1)
|
|
1092
|
+
fetch.assert_called_once_with(_VAULT, 1)
|
|
1093
|
+
|
|
1094
|
+
@patch("ipor_fusion.mcp.server.fetch_vault", return_value=_v1_info())
|
|
1095
|
+
def test_rejects_a_wrong_checksum(self, fetch):
|
|
1096
|
+
with pytest.raises(ValueError, match="invalid address checksum"):
|
|
1097
|
+
market_meta_morpho(vault_address=miscased(_VAULT), chain_id=1)
|
|
1098
|
+
fetch.assert_not_called()
|
|
1099
|
+
|
|
1088
1100
|
|
|
1089
1101
|
class TestVaultAddressArgument:
|
|
1090
1102
|
"""Tool callers may pad an address with whitespace or omit its ``0x``; the
|
|
@@ -1114,10 +1126,8 @@ class TestVaultAddressArgument:
|
|
|
1114
1126
|
_vault_arg(raw)
|
|
1115
1127
|
|
|
1116
1128
|
def test_rejects_a_wrong_checksum(self):
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
miscased = checksum[:i] + checksum[i].swapcase() + checksum[i + 1 :]
|
|
1120
|
-
for raw in (miscased, "0X" + miscased[2:], miscased[2:]):
|
|
1129
|
+
bad = miscased(self.VAULT)
|
|
1130
|
+
for raw in (bad, "0X" + bad[2:], bad[2:]):
|
|
1121
1131
|
with pytest.raises(ValueError, match="invalid address checksum"):
|
|
1122
1132
|
_vault_arg(raw)
|
|
1123
1133
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
|
|
3
3
|
import pytest
|
|
4
|
+
from _addresses import miscased
|
|
4
5
|
from eth_abi import encode
|
|
5
6
|
from hexbytes import HexBytes
|
|
6
7
|
from web3 import Web3
|
|
@@ -161,10 +162,8 @@ class TestChecksumParsers:
|
|
|
161
162
|
for bad in ("0x1234", " " + self.LOWER):
|
|
162
163
|
with pytest.raises(ValueError):
|
|
163
164
|
parser(bad)
|
|
164
|
-
i = next(i for i, c in enumerate(checksum) if c in "abcdefABCDEF")
|
|
165
|
-
miscased = checksum[:i] + checksum[i].swapcase() + checksum[i + 1 :]
|
|
166
165
|
with pytest.raises(ValueError, match="invalid address checksum"):
|
|
167
|
-
parser(miscased)
|
|
166
|
+
parser(miscased(checksum))
|
|
168
167
|
# Two characters swapped: a different address that looks right.
|
|
169
168
|
swapped = checksum[:2] + checksum[3] + checksum[2] + checksum[4:]
|
|
170
169
|
assert swapped[2:4] != checksum[2:4]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/examples/advanced_euler_v2_credit_market_base.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/examples/advanced_euler_v2_looping_arbitrum.py
RENAMED
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/examples/external_state_margin_leg_base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/oracle_mapping_view.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/cli/vault_markets_view.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/external_state_executor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/simulation_result.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/core/withdraw_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/__init__.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/chainlink.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/codec.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/contracts.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/events.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/indexer.py
RENAMED
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/quote.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/ccip/transport.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/fuses/__init__.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/fuses/base.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/fuses/ccip.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev26 → ipor_fusion-4.1.0.dev35}/src/ipor_fusion/crosschain/fuses/stargate.py
RENAMED
|
File without changes
|