ipor-fusion 4.0.0.dev66__tar.gz → 4.0.0.dev68__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.0.0.dev66 → ipor_fusion-4.0.0.dev68}/MIGRATION_4.md +9 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/PKG-INFO +1 -1
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/pyproject.toml +1 -1
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/fusion_factory.py +64 -1
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/simulation.py +15 -12
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/quote.py +1 -3
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/simulation.py +2 -6
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_external_state_executor.py +1 -1
- ipor_fusion-4.0.0.dev68/tests/test_fusion_instance.py +70 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_crosschain_hyperevm.py +1 -3
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_vault_simulator_blocks.py +11 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.claude-plugin/marketplace.json +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.claude-plugin/plugin.json +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.env.example +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.gemini/settings.json +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.git-blame-ignore-revs +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.github/workflows/cd.yml +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.github/workflows/ci.yml +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.github/workflows/commit-lint.yml +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.github/workflows/notify-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.github/workflows/python-build.yml +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.github/workflows/python-publish.yml +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.github/workflows/release.yml +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.github/workflows/report-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.gitignore +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.mcp.json +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.pre-commit-config.yaml +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/.python-version +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/AGENTS.md +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/CHANGELOG.md +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/CLAUDE.md +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/CODEOWNERS +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/LICENSE +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/README.md +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/build.sh +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/examples/CONTRIBUTING.md +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/examples/README.md +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/examples/advanced_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/examples/advanced_euler_v2_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/examples/composed_hypercore_flow_arbitrum_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/examples/external_state_margin_leg_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/examples/simple_aave_v3_supply_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/pytest.ini +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/scripts/commit-check.sh +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/scripts/crosschain_readiness.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/skills/ipor-deploy-vault/SKILL.md +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/about.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/cache.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/chains.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/cli/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/cli/config_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/cli/config_store.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/cli/main.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/cli/market_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/cli/options.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/cli/oracle_mapping_view.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/cli/vault_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/cli/vault_health.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/cli/vault_info_view.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/cli/vault_rendering.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/config/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/config/roles.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/access.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/address.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/context.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/contract.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/erc20.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/external_state_executor.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/fuse_action.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/logs.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/multicall.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/oracle.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/chainlink.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/codec.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/indexer.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/lane.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/transport.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/discovery.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/errors.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/lane.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/logs.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/messages.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/stargate/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/stargate/lane.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/stargate/layerzero.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/stargate/transport.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/transport.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/dependency_graph.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/entry_cli.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/entry_mcp.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/errors.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/explorer.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/field_docs.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/async_action.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/crosschain/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/crosschain/base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/crosschain/ccip.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/crosschain/stargate.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/erc4626.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/events.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/external_state.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/external_state_events.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/hypercore_events.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/merkl.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/fuses/universal.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/guide/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/guide/architecture.md +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/guide/glossary.md +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/guide/invariants.md +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/guide/quickstart.md +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/market_ids.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/market_info.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/mcp/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/mcp/guide.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/mcp/models.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/mcp/server.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/morpho_api.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/py.typed +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/readers/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/readers/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/readers/aave_v4.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/readers/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/readers/hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/readers/hypercore_outcome.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/readers/lending_health.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/readers/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/readers/oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/readers/oracle_mapping_nodes.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/readers/oracle_mapping_reader.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/readers/position_manager.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/readers/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/readers/unpriceable.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/substrates.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/types.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/validation.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/vault_data.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/vault_info.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/vault_managers.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/vault_positions.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/vault_reads.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/UniswapV3UniversalRouter.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/_crosschain_recovery.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/_euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/_foundry.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/_guide.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/_hypercore_model.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/_hypercore_shadow.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/_simulate.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/_validation.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/addresses.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/conftest.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/constants.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/fixtures/hypercore_hip3_flow.json +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/fixtures/hypercore_market55.json +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/fixtures/vault_info_golden/clean.json +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/fixtures/vault_info_golden/clean.txt +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/fixtures/vault_info_golden/rich.json +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/fixtures/vault_info_golden/rich.txt +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_about.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_access_manager.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_cache.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_chains.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_cli_changelog.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_cli_commands.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_cli_config_store.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_cli_helpers.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_cli_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_cli_lending_health.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_cli_market_morpho_blue.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_cli_oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_cli_pending_requests_scan.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_cli_role_accounts.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_cli_vault_info_golden.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_cli_vault_predates_getters.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_cli_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_contract_call.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_contract_encoder.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_crosschain_ccip_events.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_crosschain_ccip_indexer.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_crosschain_ccip_quote.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_crosschain_chainlink.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_crosschain_contracts.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_crosschain_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_crosschain_errors.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_crosschain_lane.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_crosschain_layering.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_crosschain_readiness.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_crosschain_readiness_report.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_crosschain_transport.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_erc20.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_examples_composed_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_examples_euler_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_examples_vaults.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_explorer.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_external_state_events.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_fuse_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_guide.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_hypercore_deployment.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_hypercore_events.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_hypercore_flow.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_hypercore_live.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_hypercore_outcome.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_hypercore_readers.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_hypercore_simulation.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_logs.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_mcp_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_mcp_models.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_mcp_server.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_mcp_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_oracle.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_reader_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_readiness_selection.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_revert_decoding.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_roles.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_sdk_layering.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_claim_morpho_rewards.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_crosschain_canary.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_crosschain_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_euler_v2_batch_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_examples_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_examples_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_external_state_executor_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_looping_aave_v3_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_morpho_blue.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_pilot_v3.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_pilot_v5_ramses.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_readers_integration.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_release_funds.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_swap_on_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_vault_from_scratch_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_solidity_compiler.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_solidity_mirrors.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_substrates.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_types_and_events.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_unpriceable_tokens.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_validation.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_vault_dep_graph.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_vault_info_onchain_base.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_web3_context.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/typed_client/consumer.py +0 -0
- {ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/uv.lock +0 -0
|
@@ -110,6 +110,15 @@ Every fuse constructor, `FuseAction.fuse`, `BalanceFuse.fuse`,
|
|
|
110
110
|
`FusionInstance.access_manager` return one. `resolve_access_manager` still takes any
|
|
111
111
|
`ChecksumAddress`: it is what checks that the address is a vault.
|
|
112
112
|
|
|
113
|
+
**Simulation and factory records.** `VaultSimulator(web3, *, vault=None, alpha=None,
|
|
114
|
+
block=...)` takes every argument after `web3` by keyword, and `vault` and `alpha` are
|
|
115
|
+
optional: a simulator that only observes, deploys or sends `execute_call(call,
|
|
116
|
+
from_=...)` needs neither, so drop a zero-address placeholder. `execute()` without
|
|
117
|
+
`vault` and `alpha` raises `ValueError`, as does `execute_call` without `from_` or
|
|
118
|
+
`alpha`. `FusionInstance.from_dict(data)` rebuilds a stored instance (the
|
|
119
|
+
`dataclasses.asdict` form) with every field parsed; use it instead of
|
|
120
|
+
`FusionInstance(**data)`, which passes raw strings into the role-typed fields.
|
|
121
|
+
|
|
113
122
|
**Markets and substrates.** Every `IporFusionMarkets` member is a `MarketId`.
|
|
114
123
|
`decode_substrate`, `market_name`, `format_market_label` take `MarketId`.
|
|
115
124
|
|
|
@@ -22,7 +22,9 @@ For external-signer flows, grab the bytes directly:
|
|
|
22
22
|
|
|
23
23
|
from __future__ import annotations
|
|
24
24
|
|
|
25
|
+
from collections.abc import Callable, Mapping
|
|
25
26
|
from dataclasses import dataclass
|
|
27
|
+
from typing import Any
|
|
26
28
|
|
|
27
29
|
from eth_abi import decode as abi_decode
|
|
28
30
|
from eth_typing import ChecksumAddress
|
|
@@ -31,7 +33,13 @@ from web3 import Web3
|
|
|
31
33
|
from web3.types import TxReceipt
|
|
32
34
|
|
|
33
35
|
from ipor_fusion.core.contract import Call, ContractWrapper
|
|
34
|
-
from ipor_fusion.types import
|
|
36
|
+
from ipor_fusion.types import (
|
|
37
|
+
AccessManagerAddress,
|
|
38
|
+
Period,
|
|
39
|
+
PlasmaVaultAddress,
|
|
40
|
+
parse_access_manager_address,
|
|
41
|
+
parse_plasma_vault_address,
|
|
42
|
+
)
|
|
35
43
|
|
|
36
44
|
|
|
37
45
|
@dataclass(slots=True, frozen=True)
|
|
@@ -70,6 +78,61 @@ class FusionInstance:
|
|
|
70
78
|
context_manager: ChecksumAddress
|
|
71
79
|
price_manager: ChecksumAddress
|
|
72
80
|
|
|
81
|
+
@classmethod
|
|
82
|
+
def from_dict(
|
|
83
|
+
cls, data: Mapping[str, Any]
|
|
84
|
+
) -> FusionInstance: # proctor: ignore[primitives-untyped-dict]
|
|
85
|
+
"""Rebuild an instance from its JSON form (``dataclasses.asdict``),
|
|
86
|
+
parsing every field: role addresses through their parsers, the rest
|
|
87
|
+
checksummed, integers and strings type-checked. Raises ``ValueError``
|
|
88
|
+
on a missing, extra or malformed field."""
|
|
89
|
+
missing = _INSTANCE_FIELDS.keys() - data.keys()
|
|
90
|
+
extra = data.keys() - _INSTANCE_FIELDS.keys()
|
|
91
|
+
if missing or extra:
|
|
92
|
+
raise ValueError(
|
|
93
|
+
f"FusionInstance fields: missing {sorted(missing)}, extra {sorted(extra)}"
|
|
94
|
+
)
|
|
95
|
+
return cls(
|
|
96
|
+
**{name: parse(data[name]) for name, parse in _INSTANCE_FIELDS.items()}
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _integer(value: Any) -> int:
|
|
101
|
+
if type(value) is not int:
|
|
102
|
+
raise ValueError(f"expected an integer: {value!r}")
|
|
103
|
+
return value
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _text(value: Any) -> str:
|
|
107
|
+
if not isinstance(value, str):
|
|
108
|
+
raise ValueError(f"expected a string: {value!r}")
|
|
109
|
+
return value
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _address(value: Any) -> ChecksumAddress:
|
|
113
|
+
return Web3.to_checksum_address(_text(value))
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
_INSTANCE_FIELDS: dict[str, Callable[[Any], Any]] = {
|
|
117
|
+
"index": _integer,
|
|
118
|
+
"version": _integer,
|
|
119
|
+
"asset_name": _text,
|
|
120
|
+
"asset_symbol": _text,
|
|
121
|
+
"asset_decimals": _integer,
|
|
122
|
+
"underlying_token": _address,
|
|
123
|
+
"underlying_token_symbol": _text,
|
|
124
|
+
"underlying_token_decimals": _integer,
|
|
125
|
+
"initial_owner": _address,
|
|
126
|
+
"plasma_vault": lambda value: parse_plasma_vault_address(_text(value)),
|
|
127
|
+
"plasma_vault_base": _address,
|
|
128
|
+
"access_manager": lambda value: parse_access_manager_address(_text(value)),
|
|
129
|
+
"fee_manager": _address,
|
|
130
|
+
"rewards_manager": _address,
|
|
131
|
+
"withdraw_manager": _address,
|
|
132
|
+
"context_manager": _address,
|
|
133
|
+
"price_manager": _address,
|
|
134
|
+
}
|
|
135
|
+
|
|
73
136
|
|
|
74
137
|
_FUSION_INSTANCE_OUTPUT_TYPES: list[str] = [
|
|
75
138
|
"uint256", # index
|
|
@@ -16,7 +16,7 @@ from web3.utils.address import get_create_address
|
|
|
16
16
|
from ipor_fusion.core.contract import Call, _encode_calldata
|
|
17
17
|
from ipor_fusion.core.fuse_action import FuseAction
|
|
18
18
|
from ipor_fusion.errors import SimulationError, decode_custom_error
|
|
19
|
-
from ipor_fusion.types import
|
|
19
|
+
from ipor_fusion.types import PlasmaVaultAddress
|
|
20
20
|
|
|
21
21
|
#: ``n`` (the sent block's index in the run) -> account overrides for it.
|
|
22
22
|
StateOverrideProvider = Callable[[int], Mapping[str, Mapping[str, Any]]]
|
|
@@ -190,15 +190,16 @@ class VaultSimulator:
|
|
|
190
190
|
def __init__(
|
|
191
191
|
self,
|
|
192
192
|
web3: Web3,
|
|
193
|
-
|
|
194
|
-
|
|
193
|
+
*,
|
|
194
|
+
vault: PlasmaVaultAddress | None = None,
|
|
195
|
+
alpha: ChecksumAddress | None = None,
|
|
195
196
|
block: BlockIdentifier = "latest",
|
|
196
197
|
validation: bool = False,
|
|
197
198
|
trace_transfers: bool = False,
|
|
198
199
|
):
|
|
199
200
|
self._web3 = web3
|
|
200
|
-
self._vault =
|
|
201
|
-
self._alpha =
|
|
201
|
+
self._vault = vault
|
|
202
|
+
self._alpha = alpha
|
|
202
203
|
self._block: BlockIdentifier = block
|
|
203
204
|
self._validation = validation
|
|
204
205
|
self._trace_transfers = trace_transfers
|
|
@@ -341,6 +342,8 @@ class VaultSimulator:
|
|
|
341
342
|
|
|
342
343
|
def execute(self, actions: list[FuseAction]) -> VaultSimulator:
|
|
343
344
|
"""Queue a default `execute((address,bytes)[])` batch on the vault, from alpha."""
|
|
345
|
+
if self._vault is None or self._alpha is None:
|
|
346
|
+
raise ValueError("execute needs a simulator built with vault= and alpha=")
|
|
344
347
|
data = FuseAction.encode_execute_payload(actions, "execute((address,bytes)[])")
|
|
345
348
|
return self._queue_execute(self._vault, data, self._alpha)
|
|
346
349
|
|
|
@@ -351,11 +354,12 @@ class VaultSimulator:
|
|
|
351
354
|
e.g. `RewardsManager.claim_rewards(...)` where the wrapper differs from
|
|
352
355
|
`PlasmaVault.execute`. `from_` defaults to alpha.
|
|
353
356
|
"""
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
357
|
+
sender = from_ or self._alpha
|
|
358
|
+
if sender is None:
|
|
359
|
+
raise ValueError(
|
|
360
|
+
"execute_call needs from_ or a simulator built with alpha="
|
|
361
|
+
)
|
|
362
|
+
return self._queue_execute(call.to, call.data, sender)
|
|
359
363
|
|
|
360
364
|
def _queue_execute(
|
|
361
365
|
self, to: ChecksumAddress, data: bytes, from_: ChecksumAddress
|
|
@@ -751,8 +755,7 @@ def erc20_balance_slot(
|
|
|
751
755
|
if max_slot < 0:
|
|
752
756
|
raise ValueError(no_slot)
|
|
753
757
|
|
|
754
|
-
|
|
755
|
-
sim = VaultSimulator(web3, vault=zero, alpha=zero, block=block)
|
|
758
|
+
sim = VaultSimulator(web3, block=block)
|
|
756
759
|
for slot in range(max_slot + 1):
|
|
757
760
|
holder = Web3.to_checksum_address(
|
|
758
761
|
"0x" + keccak(encode(["uint256"], [slot]))[-20:].hex()
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/quote.py
RENAMED
|
@@ -18,13 +18,11 @@ from web3.types import BlockIdentifier
|
|
|
18
18
|
|
|
19
19
|
from ipor_fusion.core.contract import Call
|
|
20
20
|
from ipor_fusion.core.simulation import VaultSimulator
|
|
21
|
-
from ipor_fusion.types import parse_plasma_vault_address
|
|
22
21
|
|
|
23
22
|
#: Selector of ``CcipInsufficientNativeFeeBalance(uint256 balance, uint256 required)``.
|
|
24
23
|
INSUFFICIENT_NATIVE_FEE_SELECTOR: bytes = keccak(
|
|
25
24
|
text="CcipInsufficientNativeFeeBalance(uint256,uint256)"
|
|
26
25
|
)[:4]
|
|
27
|
-
_NO_VAULT = parse_plasma_vault_address(bytes(20))
|
|
28
26
|
|
|
29
27
|
|
|
30
28
|
def quote_ccip_native_fee(
|
|
@@ -45,7 +43,7 @@ def quote_ccip_native_fee(
|
|
|
45
43
|
valid at ``block`` up to the fee check; a revert before it, or a call that
|
|
46
44
|
sends no message, raises ``ValueError``.
|
|
47
45
|
"""
|
|
48
|
-
simulator = VaultSimulator(web3,
|
|
46
|
+
simulator = VaultSimulator(web3, alpha=from_, block=block)
|
|
49
47
|
simulator.with_state_override(payer, balance=hex(0))
|
|
50
48
|
simulator.add_call(call, from_=from_, label="quote", gas=gas)
|
|
51
49
|
(result,) = simulator.run().calls
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/simulation.py
RENAMED
|
@@ -25,7 +25,6 @@ Example -- bridge from a source vault and let the dispatcher settle::
|
|
|
25
25
|
from __future__ import annotations
|
|
26
26
|
|
|
27
27
|
from collections.abc import Mapping
|
|
28
|
-
from typing import Any
|
|
29
28
|
|
|
30
29
|
from eth_typing import ChecksumAddress
|
|
31
30
|
from web3 import Web3
|
|
@@ -41,7 +40,7 @@ from ipor_fusion.crosschain.transport import (
|
|
|
41
40
|
CrosschainTransport,
|
|
42
41
|
OutboundMessage,
|
|
43
42
|
)
|
|
44
|
-
from ipor_fusion.types import
|
|
43
|
+
from ipor_fusion.types import ChainId, PlasmaVaultAddress
|
|
45
44
|
|
|
46
45
|
#: What the synthetic token source holds: enough for any test amount.
|
|
47
46
|
SYNTHETIC_BALANCE = 2**96
|
|
@@ -89,10 +88,7 @@ class CrosschainSimulator:
|
|
|
89
88
|
raise ValueError(f"chain {chain_id} is not configured on the transport")
|
|
90
89
|
if chain_id in self._chains:
|
|
91
90
|
raise ValueError(f"chain {chain_id} already added")
|
|
92
|
-
|
|
93
|
-
sim = VaultSimulator(
|
|
94
|
-
web3, vault=vault or zero, alpha=alpha or zero, block=block
|
|
95
|
-
)
|
|
91
|
+
sim = VaultSimulator(web3, vault=vault, alpha=alpha, block=block)
|
|
96
92
|
# A chain without a real token holder to impersonate gets a synthetic
|
|
97
93
|
# one, funded once by a storage override; deliveries transfer from it.
|
|
98
94
|
for token in self._transport.synthetic_credit_tokens(chain_id):
|
|
@@ -64,7 +64,7 @@ def _observed(call, return_data: bytes):
|
|
|
64
64
|
Feeds a synthetic `eth_simulateV1` response to `_parse_response`, so the
|
|
65
65
|
result is whatever `observe` would actually report -- including its handling
|
|
66
66
|
of a decoder that raises."""
|
|
67
|
-
sim = VaultSimulator(MagicMock()
|
|
67
|
+
sim = VaultSimulator(MagicMock())
|
|
68
68
|
sim.observe("slot", call)
|
|
69
69
|
result = sim._parse_response(
|
|
70
70
|
simulate_response(
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""`FusionInstance.from_dict` parses a stored instance back into its typed
|
|
2
|
+
fields instead of passing raw JSON strings into role-typed addresses."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from dataclasses import asdict
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
from web3 import Web3
|
|
10
|
+
|
|
11
|
+
from ipor_fusion.core.fusion_factory import FusionInstance
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _stored() -> dict:
|
|
15
|
+
address = {
|
|
16
|
+
name: "0x" + f"{i:02x}" * 20
|
|
17
|
+
for i, name in enumerate(
|
|
18
|
+
[
|
|
19
|
+
"underlying_token",
|
|
20
|
+
"initial_owner",
|
|
21
|
+
"plasma_vault",
|
|
22
|
+
"plasma_vault_base",
|
|
23
|
+
"access_manager",
|
|
24
|
+
"fee_manager",
|
|
25
|
+
"rewards_manager",
|
|
26
|
+
"withdraw_manager",
|
|
27
|
+
"context_manager",
|
|
28
|
+
"price_manager",
|
|
29
|
+
],
|
|
30
|
+
start=0xA1,
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
"index": 3,
|
|
35
|
+
"version": 2,
|
|
36
|
+
"asset_name": "IPOR USDC",
|
|
37
|
+
"asset_symbol": "ipUSDC",
|
|
38
|
+
"asset_decimals": 8,
|
|
39
|
+
"underlying_token_symbol": "USDC",
|
|
40
|
+
"underlying_token_decimals": 6,
|
|
41
|
+
**address,
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_from_dict_checksums_every_address_and_round_trips():
|
|
46
|
+
stored = _stored()
|
|
47
|
+
instance = FusionInstance.from_dict(stored)
|
|
48
|
+
assert instance.plasma_vault == Web3.to_checksum_address(stored["plasma_vault"])
|
|
49
|
+
assert instance.access_manager == Web3.to_checksum_address(stored["access_manager"])
|
|
50
|
+
assert instance.price_manager == Web3.to_checksum_address(stored["price_manager"])
|
|
51
|
+
assert FusionInstance.from_dict(asdict(instance)) == instance
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@pytest.mark.parametrize(
|
|
55
|
+
("change", "match"),
|
|
56
|
+
[
|
|
57
|
+
(lambda d: d.pop("plasma_vault"), "missing"),
|
|
58
|
+
(lambda d: d.update(extra=1), "extra"),
|
|
59
|
+
(lambda d: d.update(plasma_vault="0x1234"), "address"),
|
|
60
|
+
(lambda d: d.update(plasma_vault=" " + d["plasma_vault"]), "address"),
|
|
61
|
+
(lambda d: d.update(asset_decimals="8"), "integer"),
|
|
62
|
+
(lambda d: d.update(index=True), "integer"),
|
|
63
|
+
(lambda d: d.update(asset_symbol=None), "string"),
|
|
64
|
+
],
|
|
65
|
+
)
|
|
66
|
+
def test_from_dict_rejects_a_malformed_field(change, match):
|
|
67
|
+
stored = _stored()
|
|
68
|
+
change(stored)
|
|
69
|
+
with pytest.raises(ValueError, match=match):
|
|
70
|
+
FusionInstance.from_dict(stored)
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/tests/test_simulate_crosschain_hyperevm.py
RENAMED
|
@@ -343,7 +343,6 @@ def test_simulate_contract_creation(web3_arb):
|
|
|
343
343
|
init_code = bytes.fromhex("600a600c600039600a6000f3") + runtime
|
|
344
344
|
simulator = VaultSimulator(
|
|
345
345
|
web3_arb,
|
|
346
|
-
vault=ZERO_ADDRESS,
|
|
347
346
|
alpha=SIMULATED_DEPLOYER,
|
|
348
347
|
block=ARBITRUM_BLOCK,
|
|
349
348
|
)
|
|
@@ -374,7 +373,6 @@ def test_compile_and_deploy_crosschain_fuses(web3_arb):
|
|
|
374
373
|
)
|
|
375
374
|
simulator = VaultSimulator(
|
|
376
375
|
web3_arb,
|
|
377
|
-
vault=ZERO_ADDRESS,
|
|
378
376
|
alpha=SIMULATED_DEPLOYER,
|
|
379
377
|
block=ARBITRUM_BLOCK,
|
|
380
378
|
)
|
|
@@ -804,7 +802,7 @@ def test_simulate_clone_htest_vault(
|
|
|
804
802
|
OWNER,
|
|
805
803
|
)
|
|
806
804
|
preview = clone.call()
|
|
807
|
-
simulator = VaultSimulator(web3,
|
|
805
|
+
simulator = VaultSimulator(web3, alpha=OWNER, block=block)
|
|
808
806
|
simulator.with_block_override(gasLimit=30_000_000)
|
|
809
807
|
simulator.add_call(clone, from_=OWNER, label="clone_vault")
|
|
810
808
|
vault = PlasmaVault(ctx, preview.plasma_vault)
|
|
@@ -573,3 +573,14 @@ def test_add_transaction_rejects_what_it_cannot_send_faithfully(transaction, mes
|
|
|
573
573
|
sim, _ = _simulator()
|
|
574
574
|
with pytest.raises(ValueError, match=message):
|
|
575
575
|
sim.add_transaction(transaction)
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
def test_a_simulator_without_vault_or_alpha_observes_but_cannot_execute():
|
|
579
|
+
sim = VaultSimulator(MagicMock(), block=100)
|
|
580
|
+
call = Call(to=PAYER, data=b"\x01", ctx=MagicMock())
|
|
581
|
+
with pytest.raises(ValueError, match="vault= and alpha="):
|
|
582
|
+
sim.execute([])
|
|
583
|
+
with pytest.raises(ValueError, match="from_ or"):
|
|
584
|
+
sim.execute_call(call)
|
|
585
|
+
sim.execute_call(call, from_=PAYER)
|
|
586
|
+
assert sim.has_calls
|
|
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.0.0.dev66 → ipor_fusion-4.0.0.dev68}/examples/advanced_euler_v2_credit_market_base.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/examples/advanced_euler_v2_looping_arbitrum.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/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
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/cli/oracle_mapping_view.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/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.0.0.dev66 → ipor_fusion-4.0.0.dev68}/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
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/core/withdraw_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/__init__.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/chainlink.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/codec.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/contracts.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/events.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/indexer.py
RENAMED
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/ccip/transport.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/stargate/__init__.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/stargate/contracts.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/stargate/lane.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/stargate/layerzero.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev66 → ipor_fusion-4.0.0.dev68}/src/ipor_fusion/crosschain/stargate/transport.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
|