ipor-fusion 4.1.0.dev56__tar.gz → 4.1.1.dev2__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.dev56 → ipor_fusion-4.1.1.dev2}/.claude-plugin/plugin.json +1 -1
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/CHANGELOG.md +126 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/PKG-INFO +1 -1
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/pyproject.toml +1 -1
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/erc20.py +7 -2
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/plasma_vault.py +4 -1
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/simulation_result.py +2 -1
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/errors.py +2 -1
- ipor_fusion-4.1.1.dev2/src/ipor_fusion/onchain_text.py +30 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/oracle_mapping_reader.py +4 -1
- ipor_fusion-4.1.1.dev2/tests/test_onchain_text.py +62 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/uv.lock +1 -1
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.claude-plugin/marketplace.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.env.example +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.gemini/settings.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.git-blame-ignore-revs +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.github/workflows/cd.yml +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.github/workflows/ci.yml +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.github/workflows/commit-lint.yml +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.github/workflows/notify-slack.yml +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.github/workflows/python-build.yml +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.github/workflows/python-publish.yml +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.github/workflows/release.yml +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.github/workflows/report-slack.yml +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.gitignore +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.pre-commit-config.yaml +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/.python-version +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/AGENTS.md +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/CLAUDE.md +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/CODEOWNERS +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/LICENSE +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/MIGRATION_4.md +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/README.md +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/build.sh +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/examples/CONTRIBUTING.md +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/examples/README.md +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/examples/advanced_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/examples/advanced_euler_v2_looping_arbitrum.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/examples/external_state_margin_leg_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/examples/hypercore_vault_official_deployment_hyperevm.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/examples/simple_aave_v3_supply_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/pytest.ini +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/scripts/commit-check.sh +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/scripts/fusion_error_signatures.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/skills/ipor-deploy-vault/SKILL.md +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/about.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cache.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/chains.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cli/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cli/address_cmd.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cli/config_cmd.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cli/config_store.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cli/main.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cli/market_cmd.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cli/options.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cli/oracle_mapping_view.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cli/preflight_cmd.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cli/vault_cmd.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cli/vault_health.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cli/vault_info_view.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/cli/vault_rendering.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/config/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/config/roles.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/access.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/address.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/context.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/context_manager.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/contract.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/external_state_executor.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/fee_manager.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/fuse.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/fuse_action.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/fuse_decoding.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/fusion_factory.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/logs.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/multicall.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/oracle.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/rewards_manager.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/simulation.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/withdraw_manager.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/ccip/chainlink.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/ccip/codec.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/ccip/contracts.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/ccip/indexer.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/ccip/lane.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/ccip/quote.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/ccip/transport.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/contracts.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/discovery.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/errors.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/fuses/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/fuses/base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/fuses/ccip.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/fuses/stargate.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/lane.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/logs.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/messages.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/simulation.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/stargate/contracts.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/stargate/lane.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/stargate/layerzero.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/stargate/transport.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/transport.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/dependency_graph.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/entry_cli.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/entry_mcp.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/explorer.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/field_docs.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/aave_v3.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/async_action.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/compound_v3.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/erc4626.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/euler_v2.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/events.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/external_state.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/external_state_event_decoding.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/hypercore.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/hypercore_event_decoding.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/hypercore_pre_hooks.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/merkl.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/morpho.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fuses/universal.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/fusion_errors.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/guide/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/guide/architecture.md +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/guide/glossary.md +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/guide/invariants.md +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/guide/quickstart.md +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/hypercore/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/market_ids.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/market_info.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/mcp/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/mcp/guide.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/mcp/models.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/mcp/server.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/morpho_api.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/preflight.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/py.typed +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/__init__.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/aave_v3.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/aave_v4.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/compound_v3.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/euler_v2.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/hypercore.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/hypercore_outcome.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/lending_health.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/morpho.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/oracle_mapping.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/oracle_mapping_nodes.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/position_manager.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/ramses_v2.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/unpriceable.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/registry.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/substrates.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/types.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/validation.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/vault_data.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/vault_erc20.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/vault_info.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/vault_managers.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/vault_positions.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/vault_reads.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/UniswapV3UniversalRouter.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_addresses.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_crosschain.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_crosschain_recovery.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_euler_v2.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_event_args.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_fake_rpc.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_foundry.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_golden.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_guide.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_hypercore_model.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_hypercore_shadow.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_live.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_multicall.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_oracle_mapping_fake.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_simulate.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/_validation.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/addresses.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/conftest.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/constants.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/hypercore_hip3_flow.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/hypercore_market55.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/hypercore_official.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/market_golden/meta_morpho_v1.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/market_golden/meta_morpho_v1.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/market_golden/meta_morpho_v2.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/market_golden/meta_morpho_v2.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/market_golden/morpho_api/market.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/market_golden/morpho_api/vault_v1.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/market_golden/morpho_api/vault_v2.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/market_golden/morpho_api/vault_v2_not_found.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/market_golden/morpho_blue.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/market_golden/morpho_blue.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/market_golden/morpho_blue_api_error.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/market_golden/morpho_blue_api_error.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/market_golden/morpho_blue_no_api.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/market_golden/morpho_blue_no_api.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/oracle_mapping_golden/mapping.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/oracle_mapping_golden/mapping.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/simulate_v1_request.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/vault_info_golden/clean.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/vault_info_golden/clean.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/vault_info_golden/clean.txt +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/vault_info_golden/deployment_error.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/vault_info_golden/deployment_error.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/vault_info_golden/deployment_error.txt +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/vault_info_golden/fetched.cli.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/vault_info_golden/fetched.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/vault_info_golden/fetched.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/vault_info_golden/full.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/vault_info_golden/full.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/vault_info_golden/full.txt +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/vault_info_golden/rich.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/vault_info_golden/rich.mcp.json +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/fixtures/vault_info_golden/rich.txt +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_about.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_access_manager.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_addresses_helper.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cache.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_ccip_read_disabled.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_chains.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_address.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_changelog.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_commands.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_config_store.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_helpers.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_hypercore.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_lending_health.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_market_golden.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_market_morpho_blue.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_mcp_parity.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_oracle_mapping.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_oracle_mapping_golden.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_pending_requests_scan.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_preflight.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_role_accounts.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_vault_info_golden.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_vault_predates_getters.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_cli_vault_validate.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_contract_call.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_contract_encoder.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_crosschain_ccip_events.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_crosschain_ccip_indexer.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_crosschain_ccip_quote.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_crosschain_chainlink.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_crosschain_contracts.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_crosschain_encoding.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_crosschain_errors.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_crosschain_lane.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_crosschain_layering.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_crosschain_transport.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_docs_typing.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_erc20.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_error_hierarchy.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_examples_crosschain.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_examples_euler_looping_arbitrum.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_examples_hypercore_hyperevm.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_examples_vaults.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_explorer.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_external_state_events.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_external_state_executor.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_fee_manager.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_fuse_decoding.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_fuse_encoding.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_fusion_errors.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_fusion_instance.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_governance_wrappers.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_guide.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_hypercore_deployment.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_hypercore_events.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_hypercore_flow.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_hypercore_live.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_hypercore_outcome.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_hypercore_pre_hooks.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_hypercore_readers.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_hypercore_simulation.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_logs.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_mcp_address.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_mcp_hypercore.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_mcp_models.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_mcp_preflight.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_mcp_server.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_mcp_vault_validate.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_multicall.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_oracle.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_oracle_mapping.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_plasma_vault.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_preflight.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_public_api.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_public_type_reachability.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_reader_encoding.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_registry.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_revert_decoding.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_rewards_manager.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_roles.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_sdk_layering.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_claim_morpho_rewards.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_crosschain_hyperevm.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_euler_v2_batch_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_examples_arbitrum.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_examples_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_examples_crosschain.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_examples_hyperevm.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_external_state_executor_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_looping_aave_v3_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_morpho_blue.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_pilot_v3.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_pilot_v5_ramses.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_preflight_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_readers_integration.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_release_funds.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_swap_on_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_timelock_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulate_vault_from_scratch_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulation_errors.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_simulation_observation.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_solidity_compiler.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_solidity_mirrors.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_substrates.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_types_and_events.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_unpriceable_tokens.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_validation.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_vault_data_block.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_vault_dep_graph.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_vault_info_fetched_golden.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_vault_info_onchain_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_vault_reconciliation_onchain_base.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_vault_simulator_blocks.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_web3_context.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/test_withdraw_manager.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/typed_client/consumer.py +0 -0
- {ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/tests/typed_client/rejected.py +0 -0
|
@@ -2,6 +2,132 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- version list -->
|
|
4
4
|
|
|
5
|
+
## v4.1.0 (2026-11-03)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- **cli**: Accept a 0X prefix in address arguments
|
|
10
|
+
([`cc23ff7`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/cc23ff7be50ca760eb6adc1a245746bc93a62553))
|
|
11
|
+
|
|
12
|
+
- **cli**: Check address arguments with parse_checksum_address
|
|
13
|
+
([`4023d07`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/4023d0789ed78d1ab76ce8f44d76a98b65c366f6))
|
|
14
|
+
|
|
15
|
+
- **cli**: Print a set-provider hint that runs as shown
|
|
16
|
+
([`6dd2894`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/6dd2894693038bae57b256293a4128160f35fc02))
|
|
17
|
+
|
|
18
|
+
- **cli**: Read --block-number 0 as the latest block
|
|
19
|
+
([`8dd339f`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/8dd339f0d8412389c6a473a57f119e79473e9ef6))
|
|
20
|
+
|
|
21
|
+
- **mcp**: Name the preflight sender in its parse errors
|
|
22
|
+
([`b1a6115`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/b1a61158a1f25eb9516f0e96d1a5c794ff943c65))
|
|
23
|
+
|
|
24
|
+
- **mcp**: Read block_number=0 as the latest block
|
|
25
|
+
([`320bb93`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/320bb935726d83fd7787cab9bb82430681ee6a11))
|
|
26
|
+
|
|
27
|
+
- **mcp**: Reject a wrong EIP-55 checksum in the MetaMorpho vault
|
|
28
|
+
([`02a5159`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/02a5159d727f768a40e97aad6869ff3b0356c418))
|
|
29
|
+
|
|
30
|
+
- **mcp**: Reject a wrong EIP-55 checksum in the preflight sender
|
|
31
|
+
([`4d5af23`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/4d5af236721c2cd3e9e8a0f52ed045b06039b4fa))
|
|
32
|
+
|
|
33
|
+
- **mcp**: Reject a wrong EIP-55 checksum in vault arguments
|
|
34
|
+
([`37625ec`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/37625ecb172a3478fc7fb5e522027c71c0a98dcf))
|
|
35
|
+
|
|
36
|
+
- **sdk**: Check EIP-55 in every FusionInstance address field
|
|
37
|
+
([`951f49a`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/951f49a4ccceecef4a06b8c600c12564da0c6ce5))
|
|
38
|
+
|
|
39
|
+
- **sdk**: Do not follow CCIP-Read lookups from contracts
|
|
40
|
+
([`51c8ef2`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/51c8ef25e19b9e33c8ea4317a9e1df26ad87dccd))
|
|
41
|
+
|
|
42
|
+
- **sdk**: Read the latest block's number and timestamp in one call
|
|
43
|
+
([`60a4a8f`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/60a4a8f545714f1013a2f30145837b2d8ad421cb))
|
|
44
|
+
|
|
45
|
+
- **sdk**: Reject a 0X-prefixed zero address
|
|
46
|
+
([`556ee32`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/556ee329d7954ac39f2b0dff607fa2aba7ba3bdd))
|
|
47
|
+
|
|
48
|
+
- **sdk**: Reject a wrong EIP-55 checksum in the address parsers
|
|
49
|
+
([`deac726`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/deac7262bb5ccfdc0932eab8d22ed02bd66d4c3b))
|
|
50
|
+
|
|
51
|
+
- **sdk**: Report Euler V2 lending health and never drop a borrow market
|
|
52
|
+
([`1de4598`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/1de4598248b2a73d322d68359baaa74421244b2e))
|
|
53
|
+
|
|
54
|
+
- **sdk**: Stop reporting a rounding gap as a stale ERC20 cache
|
|
55
|
+
([`29ffb53`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/29ffb53377cd91308815a0d3ede18acfe640ee4a))
|
|
56
|
+
|
|
57
|
+
- **sdk**: Stop the oracle mapping at a price oracle manager delegation cycle
|
|
58
|
+
([`1470d93`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/1470d93f85f477e24a85e6a28013f4456149d128))
|
|
59
|
+
|
|
60
|
+
### Build System
|
|
61
|
+
|
|
62
|
+
- Bump aiohttp, multidict and mcp in the lock
|
|
63
|
+
([`3c266b1`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/3c266b195f3b6ae4b72bdf8e7ae5a2c165838cc1))
|
|
64
|
+
|
|
65
|
+
### Documentation
|
|
66
|
+
|
|
67
|
+
- Block 0 reads the latest block in the tools and the CLI
|
|
68
|
+
([`308ccd2`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/308ccd22cff554c3f31f1414a8e825fac8b00625))
|
|
69
|
+
|
|
70
|
+
- Keep the CCIP example's command gas inside HyperEVM's small block
|
|
71
|
+
([`5e3a093`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/5e3a093b66c79c9565f89b7c91615cb95c2e1ff7))
|
|
72
|
+
|
|
73
|
+
- **examples**: Build address literals with parse_checksum_address
|
|
74
|
+
([`c449d13`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/c449d13ab481ec9b13497bb435569d9651f5b38c))
|
|
75
|
+
|
|
76
|
+
- **sdk**: Say the HyperCore pre-hooks take no pre-hook substrates
|
|
77
|
+
([`b609593`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/b609593ebb4b05bfd2b866e6139f02321323f6a3))
|
|
78
|
+
|
|
79
|
+
- **sdk**: Wire the HyperCore example's pre-hooks with the helper
|
|
80
|
+
([`edd2776`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/edd277677da59872f5074d8dcba2b6b5cad2daa2))
|
|
81
|
+
|
|
82
|
+
### Features
|
|
83
|
+
|
|
84
|
+
- **sdk**: Add parse_checksum_address
|
|
85
|
+
([`a9a6b84`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/a9a6b848e606318fc76fa82dc2c54c7d5b4a94d9))
|
|
86
|
+
|
|
87
|
+
- **sdk**: Expose the HyperCore order and price scales
|
|
88
|
+
([`b75c645`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/b75c645f95c525114e181519fe75c2348b7962b7))
|
|
89
|
+
|
|
90
|
+
- **sdk**: HyperCore pre-hook wiring
|
|
91
|
+
([`6f16ae6`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/6f16ae6cbe2d0f3298308f4592538cb06e52eab6))
|
|
92
|
+
|
|
93
|
+
- **sdk**: Read the HyperCore best bid and ask
|
|
94
|
+
([`5fda9ee`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/5fda9ee754eb8085df3f8c432ce65565c045bddf))
|
|
95
|
+
|
|
96
|
+
- **sdk**: Report the feeds behind a Morpho oracle in the oracle mapping
|
|
97
|
+
([`c692d72`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/c692d72449805ee98ae786f14d41d28e6de2c24e))
|
|
98
|
+
|
|
99
|
+
- **sdk**: Support TAC (239) in the vault tooling again
|
|
100
|
+
([`0cc00c3`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/0cc00c3e8d30f5937296ec6dc40896a4e1c766f7))
|
|
101
|
+
|
|
102
|
+
### Refactoring
|
|
103
|
+
|
|
104
|
+
- **mcp**: Share _vault_arg's input normalization
|
|
105
|
+
([`80744af`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/80744afd6d52d33ba7e8a075478083aef4048384))
|
|
106
|
+
|
|
107
|
+
- **sdk**: Decode Euler V2 and Dolomite substrates into typed values
|
|
108
|
+
([`8f4f1ad`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/8f4f1ad5045772da897a3e31d8514b32c6386610))
|
|
109
|
+
|
|
110
|
+
- **sdk**: Make HyperCorePreHookWiring.selectors a class constant
|
|
111
|
+
([`ae9bf3e`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/ae9bf3e72f31fe795ef5683cd7287b40a1c83d14))
|
|
112
|
+
|
|
113
|
+
- **sdk**: Move the HyperCore pre-hook wiring to its own module
|
|
114
|
+
([`b150389`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/b1503891468fe4f54379d8ba49ce68d6b3c7e041))
|
|
115
|
+
|
|
116
|
+
- **sdk**: Name the 0x813 precompile POSITION2_PRECOMPILE
|
|
117
|
+
([`9529f22`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/9529f22e8a1517ef096fe1b4bff56dcaa8139e5a))
|
|
118
|
+
|
|
119
|
+
- **sdk**: Stop coercing HyperCorePreHookWiring's hooks
|
|
120
|
+
([`759448d`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/759448d02b3d690a5de636ee91363263e7dd0e40))
|
|
121
|
+
|
|
122
|
+
### Testing
|
|
123
|
+
|
|
124
|
+
- Share a miscased-address helper
|
|
125
|
+
([`5f769ac`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/5f769ac98160baa0fe2099b3255b0f91d2b4b223))
|
|
126
|
+
|
|
127
|
+
- **sdk**: Probe the core modules' CLI isolation in one subprocess
|
|
128
|
+
([`3fc160a`](https://github.com/IPOR-Labs/ipor-fusion.py/commit/3fc160a5766171dc7bb471968d2740521b59d69e))
|
|
129
|
+
|
|
130
|
+
|
|
5
131
|
## v4.0.0 (2026-10-23)
|
|
6
132
|
|
|
7
133
|
### Bug Fixes
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from eth_typing import ChecksumAddress
|
|
2
2
|
|
|
3
3
|
from ipor_fusion.core.contract import Call, ContractWrapper
|
|
4
|
+
from ipor_fusion.onchain_text import sanitize_onchain_text
|
|
4
5
|
from ipor_fusion.types import Amount, Decimals
|
|
5
6
|
|
|
6
7
|
|
|
@@ -26,10 +27,14 @@ class ERC20(ContractWrapper):
|
|
|
26
27
|
return self._view("decimals()", output_types=["uint256"], decoder=Decimals)
|
|
27
28
|
|
|
28
29
|
def symbol(self) -> Call[str]:
|
|
29
|
-
return self._view(
|
|
30
|
+
return self._view(
|
|
31
|
+
"symbol()", output_types=["string"], decoder=sanitize_onchain_text
|
|
32
|
+
)
|
|
30
33
|
|
|
31
34
|
def name(self) -> Call[str]:
|
|
32
|
-
return self._view(
|
|
35
|
+
return self._view(
|
|
36
|
+
"name()", output_types=["string"], decoder=sanitize_onchain_text
|
|
37
|
+
)
|
|
33
38
|
|
|
34
39
|
def total_supply(self) -> Call[Amount]:
|
|
35
40
|
return self._view("totalSupply()", output_types=["uint256"], decoder=Amount)
|
|
@@ -18,6 +18,7 @@ from ipor_fusion.core.context import Web3Context
|
|
|
18
18
|
from ipor_fusion.core.contract import Call, ContractWrapper
|
|
19
19
|
from ipor_fusion.core.fuse_action import FuseAction
|
|
20
20
|
from ipor_fusion.errors import EmptyCallResultError, UnsupportedVaultVersionError
|
|
21
|
+
from ipor_fusion.onchain_text import sanitize_onchain_text
|
|
21
22
|
from ipor_fusion.types import (
|
|
22
23
|
ZERO_ADDRESS,
|
|
23
24
|
AccessManagerAddress,
|
|
@@ -614,7 +615,9 @@ class PlasmaVault(ContractWrapper):
|
|
|
614
615
|
return self._view("totalSupply()", output_types=["uint256"], decoder=Shares)
|
|
615
616
|
|
|
616
617
|
def name(self) -> Call[str]:
|
|
617
|
-
return self._view(
|
|
618
|
+
return self._view(
|
|
619
|
+
"name()", output_types=["string"], decoder=sanitize_onchain_text
|
|
620
|
+
)
|
|
618
621
|
|
|
619
622
|
def underlying_asset_address(self) -> Call[ChecksumAddress]:
|
|
620
623
|
return self._view(
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/core/simulation_result.py
RENAMED
|
@@ -13,6 +13,7 @@ from eth_typing import ChecksumAddress
|
|
|
13
13
|
from hexbytes import HexBytes
|
|
14
14
|
|
|
15
15
|
from ipor_fusion.errors import SimulationError, SimulationRunError, decode_custom_error
|
|
16
|
+
from ipor_fusion.onchain_text import sanitize_onchain_text
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
class QueuedCall(Protocol):
|
|
@@ -295,7 +296,7 @@ def _decode_revert(return_data: HexBytes, error: str | None) -> str | None:
|
|
|
295
296
|
if selector == b"\x08\xc3\x79\xa0": # Error(string)
|
|
296
297
|
try:
|
|
297
298
|
(msg,) = decode(["string"], bytes(return_data[4:]))
|
|
298
|
-
return msg
|
|
299
|
+
return sanitize_onchain_text(msg)
|
|
299
300
|
except (DecodingError, OverflowError, ValueError):
|
|
300
301
|
pass
|
|
301
302
|
if selector == b"\x4e\x48\x7b\x71": # Panic(uint256)
|
|
@@ -11,6 +11,7 @@ from web3 import Web3
|
|
|
11
11
|
from web3.types import TxParams, TxReceipt
|
|
12
12
|
|
|
13
13
|
from ipor_fusion.fusion_errors import FUSION_ERROR_SIGNATURES
|
|
14
|
+
from ipor_fusion.onchain_text import sanitize_onchain_text
|
|
14
15
|
from ipor_fusion.types import TxHash
|
|
15
16
|
|
|
16
17
|
log = logging.getLogger(__name__)
|
|
@@ -95,7 +96,7 @@ def _decode_revert_reason(data: bytes) -> str:
|
|
|
95
96
|
if selector == ERROR_SELECTOR:
|
|
96
97
|
try:
|
|
97
98
|
(reason,) = abi_decode(["string"], payload)
|
|
98
|
-
return f'Error("{reason}")'
|
|
99
|
+
return f'Error("{sanitize_onchain_text(reason)}")'
|
|
99
100
|
except Exception:
|
|
100
101
|
return f"Error(<decode failed>: 0x{payload.hex()[:64]})"
|
|
101
102
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Text read from a contract is chosen by whoever deployed it.
|
|
2
|
+
|
|
3
|
+
Callers print it, log it and hand it to other programs, so it must not carry
|
|
4
|
+
control sequences, invisible characters or unbounded length. This does not make
|
|
5
|
+
the wording trustworthy: a clean string can still say anything.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import unicodedata
|
|
9
|
+
|
|
10
|
+
MAX_ONCHAIN_TEXT_CHARS = 256
|
|
11
|
+
|
|
12
|
+
# Control, format (bidi overrides, zero-width and tag characters), surrogate,
|
|
13
|
+
# private use, and line and paragraph separators.
|
|
14
|
+
_REMOVED_CATEGORIES = frozenset({"Cc", "Cf", "Cs", "Co", "Zl", "Zp"})
|
|
15
|
+
_LINE_BREAKS = frozenset("\t\n\r\f\v\u2028\u2029")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def sanitize_onchain_text(value: str) -> str:
|
|
19
|
+
"""``value`` as one line of visible text, at most `MAX_ONCHAIN_TEXT_CHARS`
|
|
20
|
+
long plus an ellipsis when cut. Line breaks and tabs become spaces, so words
|
|
21
|
+
stay apart; other removed characters disappear."""
|
|
22
|
+
cleaned = "".join(
|
|
23
|
+
" " if character in _LINE_BREAKS else character
|
|
24
|
+
for character in value
|
|
25
|
+
if character in _LINE_BREAKS
|
|
26
|
+
or unicodedata.category(character) not in _REMOVED_CATEGORIES
|
|
27
|
+
)
|
|
28
|
+
if len(cleaned) > MAX_ONCHAIN_TEXT_CHARS:
|
|
29
|
+
return cleaned[:MAX_ONCHAIN_TEXT_CHARS] + "…"
|
|
30
|
+
return cleaned
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/readers/oracle_mapping_reader.py
RENAMED
|
@@ -20,6 +20,7 @@ from ipor_fusion.core.oracle import (
|
|
|
20
20
|
PriceOracleMiddlewareManager,
|
|
21
21
|
price_oracle_middleware,
|
|
22
22
|
)
|
|
23
|
+
from ipor_fusion.onchain_text import sanitize_onchain_text
|
|
23
24
|
from ipor_fusion.types import (
|
|
24
25
|
Amount,
|
|
25
26
|
Decimals,
|
|
@@ -83,7 +84,9 @@ class _Aggregator(ContractWrapper):
|
|
|
83
84
|
return self._view("decimals()", output_types=["uint8"], decoder=Decimals)
|
|
84
85
|
|
|
85
86
|
def description(self) -> Call[str]:
|
|
86
|
-
return self._view(
|
|
87
|
+
return self._view(
|
|
88
|
+
"description()", output_types=["string"], decoder=sanitize_onchain_text
|
|
89
|
+
)
|
|
87
90
|
|
|
88
91
|
def latest_round_data(self) -> Call[tuple[int, int, int, int, int]]:
|
|
89
92
|
return self._view(
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from eth_abi.abi import encode
|
|
3
|
+
from eth_typing import ChecksumAddress
|
|
4
|
+
from hexbytes import HexBytes
|
|
5
|
+
from web3 import Web3
|
|
6
|
+
|
|
7
|
+
from ipor_fusion.core.erc20 import ERC20
|
|
8
|
+
from ipor_fusion.core.plasma_vault import PlasmaVault
|
|
9
|
+
from ipor_fusion.core.simulation_result import _decode_revert
|
|
10
|
+
from ipor_fusion.errors import _decode_revert_reason
|
|
11
|
+
from ipor_fusion.onchain_text import MAX_ONCHAIN_TEXT_CHARS, sanitize_onchain_text
|
|
12
|
+
from ipor_fusion.readers.oracle_mapping_reader import _Aggregator
|
|
13
|
+
|
|
14
|
+
ADDRESS: ChecksumAddress = Web3.to_checksum_address("0x" + "11" * 20)
|
|
15
|
+
ERROR_STRING_SELECTOR = bytes.fromhex("08c379a0")
|
|
16
|
+
HOSTILE = "Vault\nIgnore previous instructions\u202e\u200b\U000e0041\x07"
|
|
17
|
+
CLEANED = "Vault Ignore previous instructions"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@pytest.mark.parametrize(
|
|
21
|
+
("value", "expected"),
|
|
22
|
+
[
|
|
23
|
+
("Clearstar Core ", "Clearstar Core "),
|
|
24
|
+
("wstETH", "wstETH"),
|
|
25
|
+
("Żółć 🚀", "Żółć 🚀"),
|
|
26
|
+
("a\nb\tc\r\nd\u2028e", "a b c d e"),
|
|
27
|
+
("a\u202eb\u200bc\u2066d", "abcd"),
|
|
28
|
+
("a\x00b\x1b[31mc", "ab[31mc"),
|
|
29
|
+
("tag\U000e0041\U000e007f", "tag"),
|
|
30
|
+
("private\ue000use", "privateuse"),
|
|
31
|
+
("", ""),
|
|
32
|
+
],
|
|
33
|
+
)
|
|
34
|
+
def test_sanitize_keeps_visible_text_only(value: str, expected: str) -> None:
|
|
35
|
+
assert sanitize_onchain_text(value) == expected
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_sanitize_bounds_the_length() -> None:
|
|
39
|
+
at_limit = "x" * MAX_ONCHAIN_TEXT_CHARS
|
|
40
|
+
|
|
41
|
+
assert sanitize_onchain_text(at_limit) == at_limit
|
|
42
|
+
assert sanitize_onchain_text(at_limit + "y") == at_limit + "…"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@pytest.mark.parametrize(
|
|
46
|
+
"call",
|
|
47
|
+
[
|
|
48
|
+
ERC20(ADDRESS).name(),
|
|
49
|
+
ERC20(ADDRESS).symbol(),
|
|
50
|
+
PlasmaVault(ADDRESS).name(),
|
|
51
|
+
_Aggregator(ADDRESS).description(),
|
|
52
|
+
],
|
|
53
|
+
)
|
|
54
|
+
def test_string_reads_are_sanitized(call) -> None:
|
|
55
|
+
assert call.decode(encode(["string"], [HOSTILE])) == CLEANED
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_decoded_revert_reasons_are_sanitized() -> None:
|
|
59
|
+
data = ERROR_STRING_SELECTOR + encode(["string"], [HOSTILE])
|
|
60
|
+
|
|
61
|
+
assert _decode_revert_reason(data) == f'Error("{CLEANED}")'
|
|
62
|
+
assert _decode_revert(HexBytes(data), None) == CLEANED
|
|
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.dev56 → ipor_fusion-4.1.1.dev2}/examples/advanced_euler_v2_credit_market_base.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/examples/advanced_euler_v2_looping_arbitrum.py
RENAMED
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/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
|
|
File without changes
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/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.dev56 → ipor_fusion-4.1.1.dev2}/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
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/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
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/ccip/__init__.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/ccip/chainlink.py
RENAMED
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/ccip/contracts.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/ccip/events.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/ccip/indexer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/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.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/fuses/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/fuses/stargate.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/stargate/__init__.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/stargate/contracts.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/stargate/lane.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/stargate/layerzero.py
RENAMED
|
File without changes
|
{ipor_fusion-4.1.0.dev56 → ipor_fusion-4.1.1.dev2}/src/ipor_fusion/crosschain/stargate/transport.py
RENAMED
|
File without changes
|