ipor-fusion 4.0.0.dev144__tar.gz → 4.0.0.dev149__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.dev144 → ipor_fusion-4.0.0.dev149}/AGENTS.md +2 -1
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/MIGRATION_4.md +66 -18
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/PKG-INFO +1 -1
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/examples/composed_hypercore_flow_arbitrum_hyperevm.py +5 -4
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +5 -4
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/pyproject.toml +1 -1
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/vault_cmd.py +3 -1
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/external_state_executor.py +9 -5
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/fusion_factory.py +11 -10
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/simulation.py +3 -3
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/codec.py +4 -4
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/contracts.py +26 -15
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/lane.py +2 -2
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/transport.py +3 -3
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/contracts.py +32 -18
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/lane.py +17 -8
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/stargate/contracts.py +27 -15
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/stargate/lane.py +2 -2
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/stargate/layerzero.py +9 -3
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/stargate/transport.py +5 -5
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/transport.py +3 -3
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/external_state.py +3 -3
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/mcp/server.py +1 -1
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/morpho_api.py +66 -59
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/aave_v4.py +3 -2
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/hypercore.py +9 -7
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/lending_health.py +1 -1
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/oracle_mapping.py +3 -1
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/oracle_mapping_nodes.py +7 -6
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/oracle_mapping_reader.py +12 -10
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/validation.py +16 -16
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/vault_data.py +14 -4
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_cli_commands.py +9 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_cli_oracle_mapping.py +4 -4
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_mcp_server.py +2 -2
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_oracle_mapping.py +3 -3
- ipor_fusion-4.0.0.dev149/tests/test_vault_data_block.py +34 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.claude-plugin/marketplace.json +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.claude-plugin/plugin.json +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.env.example +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.gemini/settings.json +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.git-blame-ignore-revs +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.github/workflows/cd.yml +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.github/workflows/ci.yml +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.github/workflows/commit-lint.yml +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.github/workflows/notify-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.github/workflows/python-build.yml +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.github/workflows/python-publish.yml +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.github/workflows/release.yml +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.github/workflows/report-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.gitignore +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.mcp.json +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.pre-commit-config.yaml +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/.python-version +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/CHANGELOG.md +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/CLAUDE.md +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/CODEOWNERS +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/LICENSE +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/README.md +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/build.sh +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/examples/CONTRIBUTING.md +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/examples/README.md +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/examples/advanced_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/examples/advanced_euler_v2_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/examples/external_state_margin_leg_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/examples/simple_aave_v3_supply_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/pytest.ini +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/scripts/commit-check.sh +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/scripts/crosschain_readiness.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/skills/ipor-deploy-vault/SKILL.md +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/about.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cache.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/chains.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/config_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/config_store.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/main.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/market_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/options.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/oracle_mapping_view.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/vault_health.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/vault_info_view.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/vault_rendering.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/config/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/config/roles.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/access.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/address.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/context.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/contract.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/erc20.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/fuse.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/fuse_action.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/logs.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/multicall.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/oracle.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/chainlink.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/indexer.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/quote.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/discovery.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/errors.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/fuses/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/fuses/base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/fuses/ccip.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/fuses/stargate.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/logs.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/messages.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/simulation.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/dependency_graph.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/entry_cli.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/entry_mcp.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/errors.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/explorer.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/field_docs.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/async_action.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/erc4626.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/events.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/external_state_events.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/hypercore_events.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/merkl.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/universal.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/guide/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/guide/architecture.md +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/guide/glossary.md +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/guide/invariants.md +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/guide/quickstart.md +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/market_ids.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/market_info.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/mcp/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/mcp/guide.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/mcp/models.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/py.typed +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/hypercore_outcome.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/position_manager.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/unpriceable.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/substrates.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/types.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/vault_erc20.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/vault_info.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/vault_managers.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/vault_positions.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/vault_reads.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/UniswapV3UniversalRouter.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/_crosschain_recovery.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/_euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/_foundry.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/_guide.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/_hypercore_model.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/_hypercore_shadow.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/_simulate.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/_validation.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/addresses.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/conftest.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/constants.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/fixtures/hypercore_hip3_flow.json +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/fixtures/hypercore_market55.json +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/fixtures/vault_info_golden/clean.json +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/fixtures/vault_info_golden/clean.txt +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/fixtures/vault_info_golden/rich.json +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/fixtures/vault_info_golden/rich.txt +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_about.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_access_manager.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_cache.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_chains.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_cli_changelog.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_cli_config_store.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_cli_helpers.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_cli_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_cli_lending_health.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_cli_market_morpho_blue.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_cli_pending_requests_scan.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_cli_role_accounts.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_cli_vault_info_golden.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_cli_vault_predates_getters.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_cli_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_contract_call.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_contract_encoder.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_ccip_events.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_ccip_indexer.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_ccip_quote.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_chainlink.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_contracts.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_errors.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_lane.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_layering.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_readiness.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_readiness_report.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_transport.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_docs_typing.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_erc20.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_error_hierarchy.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_examples_composed_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_examples_euler_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_examples_vaults.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_explorer.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_external_state_events.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_external_state_executor.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_fuse_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_fusion_instance.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_guide.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_hypercore_deployment.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_hypercore_events.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_hypercore_flow.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_hypercore_live.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_hypercore_outcome.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_hypercore_readers.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_hypercore_simulation.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_logs.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_mcp_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_mcp_models.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_mcp_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_oracle.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_public_api.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_public_type_reachability.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_reader_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_readiness_selection.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_revert_decoding.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_roles.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_sdk_layering.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_claim_morpho_rewards.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_crosschain_canary.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_crosschain_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_crosschain_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_euler_v2_batch_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_examples_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_examples_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_external_state_executor_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_looping_aave_v3_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_morpho_blue.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_pilot_v3.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_pilot_v5_ramses.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_readers_integration.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_release_funds.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_swap_on_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_vault_from_scratch_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_solidity_compiler.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_solidity_mirrors.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_substrates.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_types_and_events.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_unpriceable_tokens.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_validation.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_vault_dep_graph.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_vault_info_onchain_base.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_vault_simulator_blocks.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_web3_context.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/test_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/typed_client/consumer.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/tests/typed_client/rejected.py +0 -0
- {ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/uv.lock +0 -0
|
@@ -441,7 +441,8 @@ are not validated.
|
|
|
441
441
|
## Domain rules (verified against the contracts)
|
|
442
442
|
|
|
443
443
|
- `fetch_vault_data(ctx, vault, *, block=, lending=, metadata=)` is the snapshot:
|
|
444
|
-
it resolves one block (``block``, else
|
|
444
|
+
it resolves one block (``block``, else `ctx.default_block` with a tag or hash resolved to its
|
|
445
|
+
number, else latest),
|
|
445
446
|
runs every read on `ctx.at_block(block)` (log scans end there too) and returns
|
|
446
447
|
everything validation and the ``vault info`` document need, so neither reads the
|
|
447
448
|
chain. The chain is `ctx.chain_id`; ``lending=False`` skips lending health, the
|
|
@@ -94,7 +94,7 @@ placeholder wrapper.
|
|
|
94
94
|
`aggregate3(calls)` still returns the raw `Call`), `VaultSimulator`,
|
|
95
95
|
`CrosschainSimulator` and `OracleMappingReader(ctx, oracle)`.
|
|
96
96
|
- Resolvers that probe the chain stay eager and return context-free wrappers:
|
|
97
|
-
`price_oracle_middleware(ctx,
|
|
97
|
+
`price_oracle_middleware(ctx, address)`, `resolve_access_manager(ctx, vault)`,
|
|
98
98
|
`ExternalStateExecutor.for_vault(ctx, vault)`. A resolved oracle carries the ABI
|
|
99
99
|
found on that chain and block; resolve again for another one.
|
|
100
100
|
- Crosschain lanes own both contexts: `CcipLane` / `StargateLane` take `hub_ctx=` and
|
|
@@ -113,9 +113,9 @@ placeholder wrapper.
|
|
|
113
113
|
do not see a CCIP recall or tell a parked command from a pending one. `CrosschainTransport.executor(address)`
|
|
114
114
|
and `.dispatcher(address)` no longer take a context.
|
|
115
115
|
- Chain-bound decoding takes the chain explicitly:
|
|
116
|
-
`ExternalStateExecutor.pending_proposals(
|
|
116
|
+
`ExternalStateExecutor.pending_proposals(balance_account, *, chain_id)`,
|
|
117
117
|
`parse_balance_proposed(log, *, chain_id)` and
|
|
118
|
-
`find_balance_proposed(logs,
|
|
118
|
+
`find_balance_proposed(logs, balance_account=None, *, chain_id)` require it (3.x fell back
|
|
119
119
|
to the wrapper's context). The decoder captures it, so `.call(ctx)`, `Multicall3`
|
|
120
120
|
and `VaultSimulator.observe` stamp the same hash for the same bytes, whatever
|
|
121
121
|
context executes them. Pass `ctx.chain_id` for the chain you read from.
|
|
@@ -134,7 +134,7 @@ placeholder wrapper.
|
|
|
134
134
|
| `call.build_transaction(block=b)`, `call.estimate_gas(block=b)` | `call.build_transaction(ctx, block=b)`, `call.estimate_gas(ctx, block=b)` |
|
|
135
135
|
| `call.ctx` | gone: keep the context yourself |
|
|
136
136
|
| `Multicall3(ctx, address)` | `Multicall3(ctx, address=address)` |
|
|
137
|
-
| `executor.pending_proposals(
|
|
137
|
+
| `executor.pending_proposals(balance_account)` | `executor.pending_proposals(balance_account, chain_id=ctx.chain_id)` |
|
|
138
138
|
| `executor.parse_balance_proposed(log)` / `find_balance_proposed(logs)` | `...(log, chain_id=...)` / `...(logs, chain_id=...)` |
|
|
139
139
|
| `CcipLane(executor=, dispatcher=, spoke_chain_id=, ...)` | `CcipLane(hub_ctx=, spoke_ctx=, executor=, dispatcher=, ...)` (same for `StargateLane`) |
|
|
140
140
|
| `transport.executor(ctx, address)` / `transport.dispatcher(ctx, address)` | `transport.executor(address)` / `transport.dispatcher(address)` |
|
|
@@ -174,7 +174,8 @@ The vault read is one pinned snapshot, and the chain is always the context's:
|
|
|
174
174
|
|
|
175
175
|
- `fetch_vault_data(ctx, vault, *, block=None, lending=True, metadata=True)` takes
|
|
176
176
|
the vault address (not a `PlasmaVault`) and no `chain_id`. It resolves one block
|
|
177
|
-
(`block`, else
|
|
177
|
+
(`block`, else `ctx.default_block`, with a `safe` / `finalized` tag or a block hash
|
|
178
|
+
resolved to its number, else the latest) and runs every
|
|
178
179
|
read, log scans included, on `ctx.at_block(block)`; `ctx` is not modified. In 3.x
|
|
179
180
|
`block_number` only selected the block reported in `VaultData`, and the reads ran
|
|
180
181
|
wherever `ctx` pointed. The old `chain_id=0` switch is `lending=False`;
|
|
@@ -289,6 +290,8 @@ fails at run time:
|
|
|
289
290
|
keyword.
|
|
290
291
|
- `encode_oft_compose_msg(*, nonce=, src_eid=, amount_ld=, compose_msg=)` takes
|
|
291
292
|
keyword arguments only.
|
|
293
|
+
- `build_oracle_mapping(ctx, vault, *, effective_block, max_depth=6)` takes
|
|
294
|
+
`effective_block` and `max_depth` by keyword.
|
|
292
295
|
- The vault parameter is named `vault` throughout: `validate_vault`,
|
|
293
296
|
`fetch_deployment_info`, `fetch_vault_lending_health`, `build_oracle_mapping`,
|
|
294
297
|
`read_external_state`, `ExternalStateExecutor.for_vault`, `read_hypercore_nav`,
|
|
@@ -434,8 +437,8 @@ are cached in a `ContractCache`, injected instead of always written to `~/.cache
|
|
|
434
437
|
explicitly (default: the file cache); pass `cache=ctx.cache` to share the
|
|
435
438
|
context's policy. The CLI's text and JSON output name contracts through the
|
|
436
439
|
context's cache.
|
|
437
|
-
- `build_vault_info_json(data)` without `resolve_name` names no contract (
|
|
438
|
-
`contract`
|
|
440
|
+
- `build_vault_info_json(data)` without `resolve_name` names no contract (fuse and
|
|
441
|
+
balance-fuse entries show `contract` as `"?"`, substrate entries omit it) instead of reading names from the on-disk cache; pass
|
|
439
442
|
`resolve_name=partial(get_contract_name, chain_id, api_key=..., cache=ctx.cache)`
|
|
440
443
|
for the CLI's document.
|
|
441
444
|
- `ipor_fusion.cache` is a public module now and exports `ContractCache`,
|
|
@@ -536,13 +539,19 @@ converted amounts `Amount`. A custom `VaultState` annotates the same.
|
|
|
536
539
|
`PlasmaVault.total_supply()`, `balance_of()` and `get_total_supply_cap()` return
|
|
537
540
|
`Shares` (vault shares), and `transfer` / `approve` / `transfer_from` /
|
|
538
541
|
`set_total_supply_cap` take `Shares`; `ERC20` keeps `Amount`.
|
|
542
|
+
`Reconciliation` amounts (`balance_fuses_total`, `underlying_on_vault`,
|
|
543
|
+
`erc20_direct_total`, `sum`, `on_chain_total_assets`, `delta`,
|
|
544
|
+
`pending_withdrawals`, `implied_market_total`, `market_storage_divergence`) are
|
|
545
|
+
`Amount`. `FusionInstance.asset_decimals` / `underlying_token_decimals` are
|
|
546
|
+
`Decimals`, and `CloneArgs.redemption_delay_seconds` is a `Period`.
|
|
547
|
+
`VaultSimulator.current_time` is a `Timestamp`.
|
|
539
548
|
|
|
540
549
|
**Vault data and helpers.** `ensure_supported_chain` takes `ChainId`.
|
|
541
550
|
`fetch_unpriceable_priced_tokens` takes the oracle and underlying as
|
|
542
551
|
`ChecksumAddress`. `resolve_token_symbol`, `resolve_token_decimals`,
|
|
543
552
|
`get_contract_name` and `get_deployment_tx` take `HexAddress` (a checksum address
|
|
544
|
-
fits), and the `resolve_name`
|
|
545
|
-
|
|
553
|
+
fits), and the `resolve_name` callback receives one (a callback typed for `str`
|
|
554
|
+
still fits). Market-keyed data is keyed by `MarketId`:
|
|
546
555
|
`VaultData.market_substrates`, `dependency_graph`, `morpho_positions`,
|
|
547
556
|
`aave_positions`, `market_balances`; the `VaultState` protocol,
|
|
548
557
|
`fetch_vault_lending_health`, `fetch_unpriceable_priced_tokens` and the
|
|
@@ -566,9 +575,13 @@ The Uniswap V3 / Ramses V2 position events' `version`, `sender` and `recipient`
|
|
|
566
575
|
`MarketId`; `Erc20Holding.address` is `HexAddress`, and `SubstrateInfo.address` is
|
|
567
576
|
`HexAddress | None`. `LegacyPriceOracleMiddleware` takes `base_currency_decimals:
|
|
568
577
|
Decimals`, and `PriceOracleMiddleware.base_currency_decimals()` returns
|
|
569
|
-
`Call[Decimals]`. `get_logs_adaptive(chain_id=)`
|
|
570
|
-
`ChainId`; `quote_ccip_native_fee(block=)` and
|
|
578
|
+
`Call[Decimals]`. `get_logs_adaptive(chain_id=)` takes `ChainId | None` and
|
|
579
|
+
`LogSource.get_logs` a `ChainId`; `quote_ccip_native_fee(block=)` and
|
|
571
580
|
`OracleMappingReader.asset_source_events` take a `BlockIdentifier`.
|
|
581
|
+
`OracleMappingReader.token_decimals`, `feed_decimals` and `vault_decimals` return
|
|
582
|
+
`Decimals | None` and `vault_convert_to_assets` an `Amount | None`;
|
|
583
|
+
`AaveV4OracleReader.decimals()` returns `Call[Decimals]`; and `OraclePrice.decimals`, `OracleNode.decimals` and
|
|
584
|
+
`OracleAsset.decimals` are `Decimals` (`| None` on the nodes).
|
|
572
585
|
|
|
573
586
|
**Address roles.** `PlasmaVault(address)`,
|
|
574
587
|
`validate_vault`, `fetch_deployment_info`, the HyperCore, lending-health and
|
|
@@ -602,7 +615,8 @@ by `ChainId` (`HYPEREVM_CHAIN_ID` is one) and `explorer.SUPPORTED_CHAINS` is a
|
|
|
602
615
|
type-checks; `PUBLIC_ALLOCATOR_ADDRESSES` values are `ChecksumAddress`.
|
|
603
616
|
|
|
604
617
|
**Markets, substrates and access.** Every `IporFusionMarkets` member is a `MarketId`.
|
|
605
|
-
`
|
|
618
|
+
`market_name` and `format_market_label` take `MarketId`, `decode_substrate` a
|
|
619
|
+
`MarketId | None`.
|
|
606
620
|
`AccessManager.has_role`, `grant_role`, `revoke_role` and `read_accounts_with_role`
|
|
607
621
|
take `RoleId | Roles`; `RoleAccount.role_id` is `RoleId`.
|
|
608
622
|
|
|
@@ -619,6 +633,12 @@ takes a `ChecksumAddress`, and `build_morpho_blue_market_json` takes
|
|
|
619
633
|
records is `ChecksumAddress`; optional ones (`curator`, `guardian`, `fee_recipient`,
|
|
620
634
|
`performance_fee_recipient`, `management_fee_recipient`, `inner_vault`,
|
|
621
635
|
`VaultFlowCap.admin`, the `VaultV2Cap` market params) are `ChecksumAddress | None`.
|
|
636
|
+
Token amounts on those records are `Amount` (`VaultFlowCap.max_in` / `max_out`, the
|
|
637
|
+
`VaultAllocation`, `VaultV1Info`, `VaultV1MarketAllocation`, `VaultV2Info` and
|
|
638
|
+
`MorphoApiMarket` asset amounts and caps, `VaultV2Cap.absolute_cap` / `allocation`
|
|
639
|
+
/ `room`, `VaultV2Adapter.assets`, `cap_room`), token decimals are `Decimals` and
|
|
640
|
+
`MorphoApiMarket.timestamp` is a `Timestamp`. `lltv`, `fee_wad`,
|
|
641
|
+
`relative_cap_wad` and `fee_wei` stay `int`.
|
|
622
642
|
|
|
623
643
|
**Crosschain.** The executor, dispatcher and factory wrappers, the lanes and
|
|
624
644
|
`StargateCrosschainCommandFuse.enter(request_id=)` take the crosschain ids above, and
|
|
@@ -630,7 +650,25 @@ on CCIP, `active_return` → `OperationId`, `asset_id`, `tracked_position_set_ha
|
|
|
630
650
|
`CcipObservation`, `OutboundMessage`, `CcipMessageSent`, `Any2EVMMessage`,
|
|
631
651
|
`VerifierResult`, `Packet.guid`, `TaxiMessage`, `StargateChain`; and the helpers
|
|
632
652
|
`fetch_verifier_result(message_id=)`, `lz_receive_calldata(guid=)` and
|
|
633
|
-
`lz_compose_calldata(guid=)` take a `MessageId`.
|
|
653
|
+
`lz_compose_calldata(guid=)` take a `MessageId`. Lane times are typed:
|
|
654
|
+
`last_approved_observed_at()` returns a `Timestamp` and `staleness_max()` (with
|
|
655
|
+
`STALENESS_MAX` / `BALANCE_STALENESS_MAX` on the executors) a `Period`, and so do
|
|
656
|
+
the `LaneHubState` fields; `attestation(remote_timestamp=, expiry=)` and
|
|
657
|
+
`BalanceObservation` take `Timestamp`, `needs_attestation(now=, margin=)` a
|
|
658
|
+
`Timestamp` and a `Period`. The other durations are `Period` too: the executors'
|
|
659
|
+
`min_update_interval()`, `transfer_staleness_max()` and `deployment_ttl()`, both
|
|
660
|
+
factories' `config_delay()`, and the time fields of `ExecutorInitParams` and
|
|
661
|
+
`SafetyConfig` (`rescue_delay`, the staleness fields, `min_update_interval`,
|
|
662
|
+
`deployment_ttl`); `in_flight_since()`, `last_approval_at()`, `oldest_pending_at()`
|
|
663
|
+
and `pending_deployment_created_at()` return a `Timestamp`. Decimals are
|
|
664
|
+
`Decimals`: `local_decimals()` / `shared_decimals()` on the executor and dispatcher,
|
|
665
|
+
`CcipChain.local_decimals`, `StargateChain.local_decimals` / `shared_decimals`, the
|
|
666
|
+
`shared_decimals` of `CcipCrosschainFactory.asset_config()`, `schedule_asset` and
|
|
667
|
+
`execute_asset`. Token amounts are `Amount` (`EVMTokenAmount.amount`,
|
|
668
|
+
`TokenTransferV1.amount`, `TaxiMessage.amount_sd`, `OutboundMessage.token_amount`,
|
|
669
|
+
`StargateChain.to_local_decimals`), and `pending_request_shares()` returns
|
|
670
|
+
`Shares`. Counters, sequences, epochs, versions, bps and gas limits stay `int`.
|
|
671
|
+
Decoded event values
|
|
634
672
|
(`ccip_events` → `CcipEvent.values`) stay a generic mapping: convert a value
|
|
635
673
|
before passing it on.
|
|
636
674
|
|
|
@@ -653,25 +691,35 @@ fuse's `eid=` take it (`LayerZeroEid(30101)`). CCIP chain selectors are
|
|
|
653
691
|
`read_hypercore_transfer_snapshot` and the helpers `system_address`,
|
|
654
692
|
`precompile_index_of`, `perp_dex_of`, `is_native_perp_asset`, `is_hip3_asset` take the
|
|
655
693
|
HyperCore ids; `HyperCorePerpAssetInfo`, `HyperCorePerpMarket`, `HyperCoreSpotLeg`,
|
|
656
|
-
`HyperCorePendingState` and `HyperCoreTransferSnapshot` carry them.
|
|
694
|
+
`HyperCorePendingState` and `HyperCoreTransferSnapshot` carry them. Token decimals
|
|
695
|
+
(`HyperCoreTokenInfo.sz_decimals` / `wei_decimals` / `evm_extra_wei_decimals`,
|
|
696
|
+
`HyperCorePerpAssetInfo.sz_decimals`, `HyperCoreSpotLeg.wei_decimals`) are
|
|
697
|
+
`Decimals`, and `HyperCorePendingState.pending_until` / `current_timestamp` are
|
|
698
|
+
`Timestamp`; Core amounts, positions, WAD values and L1 block numbers stay `int`.
|
|
657
699
|
|
|
658
700
|
**External state.** `ExternalStateExecutor.proposal_hash` returns and `confirm_balance`
|
|
659
701
|
takes a `ProposalHash`; `BalanceProposal.proposal_hash` is a `ProposalHash`;
|
|
660
|
-
`ExternalStateEvent.transaction_hash` is a `TxHash`.
|
|
702
|
+
`ExternalStateEvent.transaction_hash` is a `TxHash | None`.
|
|
661
703
|
`ExternalStateVaultState.last_checked_custodian_timestamp`,
|
|
662
704
|
`BalanceFuseSnapshot.last_custodian_update_timestamp`, `BalanceProposal.proposed_at`,
|
|
663
705
|
`last_updated()` and `get_oldest_update_timestamp()` are web3's `Timestamp`, and
|
|
664
706
|
`ExternalStateExecutor.proposal_hash(proposed_at=)` takes one.
|
|
707
|
+
`ExternalStateExecutor.staleness_max()` / `min_update_interval()` return a `Period`,
|
|
708
|
+
and `ExternalStateSubstrates.staleness_max` / `min_update_interval` take one
|
|
709
|
+
(`Period.DAY`).
|
|
665
710
|
|
|
666
|
-
**Errors and explorer.** `TransactionError(tx_hash=)` takes a `TxHash`,
|
|
711
|
+
**Errors and explorer.** `TransactionError(tx_hash=)` takes a `TxHash | None`,
|
|
667
712
|
`LogScanError(address=)` a `ChecksumAddress`; `get_revert_reason` takes a `TxHash`;
|
|
668
713
|
`get_deployment_tx` returns a `TxHash` (a malformed hash from Etherscan is reported
|
|
669
714
|
as the error `malformed-tx-hash`).
|
|
670
715
|
|
|
671
716
|
**MCP response models** (Python constructors only; the JSON schemas are unchanged
|
|
672
717
|
except as listed under [Behavior changes](#behavior-changes)): `chain_id` fields are
|
|
673
|
-
`ChainId`, `role_id` `RoleId`, `market_id` `MarketId
|
|
674
|
-
|
|
718
|
+
`ChainId`, `role_id` `RoleId`, `market_id` `MarketId` (except
|
|
719
|
+
`LendingMarketHealth.market_id`, which stays `str | int`: a Morpho market id is a
|
|
720
|
+
string). Calling an MCP tool function
|
|
721
|
+
directly from Python takes `ChainId`. Their amount, decimals and time fields stay
|
|
722
|
+
`int`: they are JSON output models, and the SDK values above fit them unchanged.
|
|
675
723
|
|
|
676
724
|
## Behavior changes
|
|
677
725
|
|
|
@@ -68,7 +68,7 @@ from typing import Any, NamedTuple
|
|
|
68
68
|
from eth_abi.abi import encode as abi_encode
|
|
69
69
|
from eth_utils import keccak
|
|
70
70
|
from web3 import Web3
|
|
71
|
-
from web3.types import BlockIdentifier, RPCEndpoint
|
|
71
|
+
from web3.types import BlockIdentifier, RPCEndpoint, Timestamp
|
|
72
72
|
|
|
73
73
|
from ipor_fusion import (
|
|
74
74
|
ERC20,
|
|
@@ -110,6 +110,7 @@ from ipor_fusion.market_ids import IporFusionMarkets
|
|
|
110
110
|
from ipor_fusion.types import (
|
|
111
111
|
Amount,
|
|
112
112
|
ChainId,
|
|
113
|
+
Decimals,
|
|
113
114
|
HyperCoreAsset,
|
|
114
115
|
HyperCoreClientOrderId,
|
|
115
116
|
MarketId,
|
|
@@ -649,14 +650,14 @@ def _transport() -> CcipTransport:
|
|
|
649
650
|
ARBITRUM_CCIP_SELECTOR,
|
|
650
651
|
ARBITRUM_CCIP_ROUTER,
|
|
651
652
|
ARBITRUM_USDC,
|
|
652
|
-
6,
|
|
653
|
+
Decimals(6),
|
|
653
654
|
),
|
|
654
655
|
CcipChain(
|
|
655
656
|
HYPEREVM_CHAIN_ID,
|
|
656
657
|
HYPEREVM_CCIP_SELECTOR,
|
|
657
658
|
HYPEREVM_CCIP_ROUTER,
|
|
658
659
|
HYPEREVM_USDC,
|
|
659
|
-
6,
|
|
660
|
+
Decimals(6),
|
|
660
661
|
),
|
|
661
662
|
)
|
|
662
663
|
)
|
|
@@ -791,7 +792,7 @@ def _attest(flow: _Tail, tag: str, observation_label: str, *, hub_idle: int = 0)
|
|
|
791
792
|
observation,
|
|
792
793
|
remote_block=flow.spoke.current_block_number,
|
|
793
794
|
remote_timestamp=flow.spoke.current_time,
|
|
794
|
-
expiry=flow.hub.current_time + PROPOSAL_TTL,
|
|
795
|
+
expiry=Timestamp(flow.hub.current_time + PROPOSAL_TTL),
|
|
795
796
|
)
|
|
796
797
|
# SIMULATION ONLY: two keyless addresses driven from one process; live
|
|
797
798
|
# they are two signers, which is the point of the two-key design.
|
|
@@ -66,6 +66,7 @@ import sys
|
|
|
66
66
|
from typing import NamedTuple
|
|
67
67
|
|
|
68
68
|
from web3 import Web3
|
|
69
|
+
from web3.types import Timestamp
|
|
69
70
|
|
|
70
71
|
from ipor_fusion import (
|
|
71
72
|
ERC20,
|
|
@@ -85,7 +86,7 @@ from ipor_fusion import (
|
|
|
85
86
|
parse_plasma_vault_address,
|
|
86
87
|
)
|
|
87
88
|
from ipor_fusion.market_ids import IporFusionMarkets
|
|
88
|
-
from ipor_fusion.types import Amount, ChainId, MarketId, Period, Shares
|
|
89
|
+
from ipor_fusion.types import Amount, ChainId, Decimals, MarketId, Period, Shares
|
|
89
90
|
|
|
90
91
|
log = logging.getLogger("crosschain_ccip_usdc_arbitrum_hyperevm")
|
|
91
92
|
|
|
@@ -222,14 +223,14 @@ def transport() -> CcipTransport:
|
|
|
222
223
|
ARBITRUM_CCIP_SELECTOR,
|
|
223
224
|
ARBITRUM_CCIP_ROUTER,
|
|
224
225
|
ARBITRUM_USDC,
|
|
225
|
-
6,
|
|
226
|
+
Decimals(6),
|
|
226
227
|
),
|
|
227
228
|
CcipChain(
|
|
228
229
|
HYPEREVM_CHAIN_ID,
|
|
229
230
|
HYPEREVM_CCIP_SELECTOR,
|
|
230
231
|
HYPEREVM_CCIP_ROUTER,
|
|
231
232
|
HYPEREVM_USDC,
|
|
232
|
-
6,
|
|
233
|
+
Decimals(6),
|
|
233
234
|
),
|
|
234
235
|
)
|
|
235
236
|
)
|
|
@@ -431,7 +432,7 @@ def _attest(flow: _Flow, tag: str, observation_label: str, *, hub_idle: int = 0)
|
|
|
431
432
|
observation,
|
|
432
433
|
remote_block=flow.spoke.current_block_number,
|
|
433
434
|
remote_timestamp=flow.spoke.current_time,
|
|
434
|
-
expiry=flow.hub.current_time + PROPOSAL_TTL,
|
|
435
|
+
expiry=Timestamp(flow.hub.current_time + PROPOSAL_TTL),
|
|
435
436
|
)
|
|
436
437
|
# SIMULATION ONLY: the proposer and the approver are two addresses with no
|
|
437
438
|
# keys here, driven from one process. Live they are two separate signers,
|
|
@@ -449,7 +449,9 @@ def oracle_mapping(
|
|
|
449
449
|
raise click.UsageError(str(exc)) from exc
|
|
450
450
|
|
|
451
451
|
try:
|
|
452
|
-
mapping = build_oracle_mapping(
|
|
452
|
+
mapping = build_oracle_mapping(
|
|
453
|
+
ctx, vault_address, effective_block=effective_block, max_depth=max_depth
|
|
454
|
+
)
|
|
453
455
|
except UnsupportedVaultVersionError as exc:
|
|
454
456
|
raise click.ClickException(str(exc)) from exc
|
|
455
457
|
|
|
@@ -35,6 +35,7 @@ from ipor_fusion.types import (
|
|
|
35
35
|
ZERO_ADDRESS,
|
|
36
36
|
Amount,
|
|
37
37
|
ChainId,
|
|
38
|
+
Period,
|
|
38
39
|
PlasmaVaultAddress,
|
|
39
40
|
ProposalHash,
|
|
40
41
|
)
|
|
@@ -371,10 +372,10 @@ class ExternalStateExecutor(ContractWrapper):
|
|
|
371
372
|
"getOldestUpdateTimestamp()", output_types=["uint256"], decoder=Timestamp
|
|
372
373
|
)
|
|
373
374
|
|
|
374
|
-
def staleness_max(self) -> Call[
|
|
375
|
+
def staleness_max(self) -> Call[Period]:
|
|
375
376
|
"""Seconds after which a custodian report counts as stale: the pre-hook
|
|
376
377
|
blocks the vault's gated user operations past it."""
|
|
377
|
-
return self._view("stalenessMax()", output_types=["uint256"])
|
|
378
|
+
return self._view("stalenessMax()", output_types=["uint256"], decoder=Period)
|
|
378
379
|
|
|
379
380
|
def big_change_bps(self) -> Call[int]:
|
|
380
381
|
"""Basis points of total-balance change between two custodian updates
|
|
@@ -382,13 +383,16 @@ class ExternalStateExecutor(ContractWrapper):
|
|
|
382
383
|
return self._view("bigChangeBps()", output_types=["uint256"])
|
|
383
384
|
|
|
384
385
|
def dust_threshold(self) -> Call[int]:
|
|
385
|
-
"""
|
|
386
|
+
"""Dust threshold as a percent of one underlying token (100 = one whole
|
|
387
|
+
token); a leftover below it is dust, not a balance."""
|
|
386
388
|
return self._view("dustThreshold()", output_types=["uint256"])
|
|
387
389
|
|
|
388
|
-
def min_update_interval(self) -> Call[
|
|
390
|
+
def min_update_interval(self) -> Call[Period]:
|
|
389
391
|
"""Seconds a balance account must wait between two custodian
|
|
390
392
|
updates."""
|
|
391
|
-
return self._view(
|
|
393
|
+
return self._view(
|
|
394
|
+
"minUpdateInterval()", output_types=["uint256"], decoder=Period
|
|
395
|
+
)
|
|
392
396
|
|
|
393
397
|
def nonce(self) -> Call[int]:
|
|
394
398
|
"""Monotonic proposal nonce, incremented on every `proposeBalance`.
|
{ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/fusion_factory.py
RENAMED
|
@@ -35,6 +35,7 @@ from web3.types import TxReceipt
|
|
|
35
35
|
from ipor_fusion.core.contract import Call, ContractWrapper
|
|
36
36
|
from ipor_fusion.types import (
|
|
37
37
|
AccessManagerAddress,
|
|
38
|
+
Decimals,
|
|
38
39
|
Period,
|
|
39
40
|
PlasmaVaultAddress,
|
|
40
41
|
parse_access_manager_address,
|
|
@@ -51,7 +52,7 @@ class CloneArgs:
|
|
|
51
52
|
asset_name: str
|
|
52
53
|
asset_symbol: str
|
|
53
54
|
underlying_token: ChecksumAddress
|
|
54
|
-
redemption_delay_seconds:
|
|
55
|
+
redemption_delay_seconds: Period
|
|
55
56
|
owner: ChecksumAddress
|
|
56
57
|
dao_fee_package_index: int
|
|
57
58
|
|
|
@@ -64,10 +65,10 @@ class FusionInstance:
|
|
|
64
65
|
version: int
|
|
65
66
|
asset_name: str
|
|
66
67
|
asset_symbol: str
|
|
67
|
-
asset_decimals:
|
|
68
|
+
asset_decimals: Decimals
|
|
68
69
|
underlying_token: ChecksumAddress
|
|
69
70
|
underlying_token_symbol: str
|
|
70
|
-
underlying_token_decimals:
|
|
71
|
+
underlying_token_decimals: Decimals
|
|
71
72
|
initial_owner: ChecksumAddress
|
|
72
73
|
plasma_vault: PlasmaVaultAddress
|
|
73
74
|
plasma_vault_base: ChecksumAddress
|
|
@@ -118,10 +119,10 @@ _INSTANCE_FIELDS: dict[str, Callable[[Any], Any]] = {
|
|
|
118
119
|
"version": _integer,
|
|
119
120
|
"asset_name": _text,
|
|
120
121
|
"asset_symbol": _text,
|
|
121
|
-
"asset_decimals": _integer,
|
|
122
|
+
"asset_decimals": lambda value: Decimals(_integer(value)),
|
|
122
123
|
"underlying_token": _address,
|
|
123
124
|
"underlying_token_symbol": _text,
|
|
124
|
-
"underlying_token_decimals": _integer,
|
|
125
|
+
"underlying_token_decimals": lambda value: Decimals(_integer(value)),
|
|
125
126
|
"initial_owner": _address,
|
|
126
127
|
"plasma_vault": lambda value: parse_plasma_vault_address(_text(value)),
|
|
127
128
|
"plasma_vault_base": _address,
|
|
@@ -185,10 +186,10 @@ def _fusion_instance_decoder(values: tuple) -> FusionInstance:
|
|
|
185
186
|
version=version,
|
|
186
187
|
asset_name=asset_name,
|
|
187
188
|
asset_symbol=asset_symbol,
|
|
188
|
-
asset_decimals=asset_decimals,
|
|
189
|
+
asset_decimals=Decimals(asset_decimals),
|
|
189
190
|
underlying_token=addr(underlying_token),
|
|
190
191
|
underlying_token_symbol=underlying_token_symbol,
|
|
191
|
-
underlying_token_decimals=underlying_token_decimals,
|
|
192
|
+
underlying_token_decimals=Decimals(underlying_token_decimals),
|
|
192
193
|
initial_owner=addr(initial_owner),
|
|
193
194
|
plasma_vault=PlasmaVaultAddress(addr(plasma_vault)),
|
|
194
195
|
plasma_vault_base=addr(plasma_vault_base),
|
|
@@ -347,10 +348,10 @@ class FusionFactory(ContractWrapper):
|
|
|
347
348
|
version=int(values[1]),
|
|
348
349
|
asset_name=values[2],
|
|
349
350
|
asset_symbol=values[3],
|
|
350
|
-
asset_decimals=int(values[4]),
|
|
351
|
+
asset_decimals=Decimals(int(values[4])),
|
|
351
352
|
underlying_token=Web3.to_checksum_address(values[5]),
|
|
352
353
|
underlying_token_symbol=values[6],
|
|
353
|
-
underlying_token_decimals=int(values[7]),
|
|
354
|
+
underlying_token_decimals=Decimals(int(values[7])),
|
|
354
355
|
initial_owner=Web3.to_checksum_address(values[8]),
|
|
355
356
|
plasma_vault=PlasmaVaultAddress(Web3.to_checksum_address(values[9])),
|
|
356
357
|
plasma_vault_base=Web3.to_checksum_address(values[10]),
|
|
@@ -390,7 +391,7 @@ class FusionFactory(ContractWrapper):
|
|
|
390
391
|
asset_name=asset_name,
|
|
391
392
|
asset_symbol=asset_symbol,
|
|
392
393
|
underlying_token=Web3.to_checksum_address(underlying_token),
|
|
393
|
-
redemption_delay_seconds=
|
|
394
|
+
redemption_delay_seconds=Period(redemption_delay_seconds),
|
|
394
395
|
owner=Web3.to_checksum_address(owner),
|
|
395
396
|
dao_fee_package_index=int(dao_fee_package_index),
|
|
396
397
|
)
|
|
@@ -10,7 +10,7 @@ from eth_typing import ChecksumAddress
|
|
|
10
10
|
from eth_utils import keccak
|
|
11
11
|
from hexbytes import HexBytes
|
|
12
12
|
from web3 import Web3
|
|
13
|
-
from web3.types import BlockIdentifier, Nonce, RPCEndpoint
|
|
13
|
+
from web3.types import BlockIdentifier, Nonce, RPCEndpoint, Timestamp
|
|
14
14
|
from web3.utils.address import get_create_address
|
|
15
15
|
|
|
16
16
|
from ipor_fusion.core.contract import Call, _encode_calldata
|
|
@@ -221,13 +221,13 @@ class VaultSimulator:
|
|
|
221
221
|
return any(block.calls for block in self._blocks)
|
|
222
222
|
|
|
223
223
|
@property
|
|
224
|
-
def current_time(self) ->
|
|
224
|
+
def current_time(self) -> Timestamp:
|
|
225
225
|
"""Timestamp of the latest sent block or an explicit pending time.
|
|
226
226
|
|
|
227
227
|
A pending block without an explicit time will run 12 seconds later
|
|
228
228
|
once it contains a call.
|
|
229
229
|
"""
|
|
230
|
-
return self._current_time()
|
|
230
|
+
return Timestamp(self._current_time())
|
|
231
231
|
|
|
232
232
|
@property
|
|
233
233
|
def current_block_number(self) -> int:
|
{ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/codec.py
RENAMED
|
@@ -21,7 +21,7 @@ from web3 import Web3
|
|
|
21
21
|
|
|
22
22
|
from ipor_fusion.core.contract import _encode_calldata
|
|
23
23
|
from ipor_fusion.crosschain.logs import log_bytes
|
|
24
|
-
from ipor_fusion.types import CcipChainSelector, MessageId
|
|
24
|
+
from ipor_fusion.types import Amount, CcipChainSelector, MessageId
|
|
25
25
|
|
|
26
26
|
#: topic0 of ``OnRamp 2.0.0``'s ``CCIPMessageSent``; ``destChainSelector``,
|
|
27
27
|
#: ``sender`` and ``messageId`` are indexed.
|
|
@@ -72,7 +72,7 @@ class TokenTransferV1:
|
|
|
72
72
|
"""``MessageV1Codec.TokenTransferV1``. Address fields are raw bytes as
|
|
73
73
|
encoded for the destination chain (20 bytes on EVM)."""
|
|
74
74
|
|
|
75
|
-
amount:
|
|
75
|
+
amount: Amount
|
|
76
76
|
source_pool_address: bytes
|
|
77
77
|
source_token_address: bytes
|
|
78
78
|
dest_token_address: bytes
|
|
@@ -84,7 +84,7 @@ class TokenTransferV1:
|
|
|
84
84
|
if reader.uint(1) != _MESSAGE_VERSION:
|
|
85
85
|
raise ValueError("unsupported CCIP token transfer version")
|
|
86
86
|
return cls(
|
|
87
|
-
amount=reader.uint(32),
|
|
87
|
+
amount=Amount(reader.uint(32)),
|
|
88
88
|
source_pool_address=reader.prefixed(1),
|
|
89
89
|
source_token_address=reader.prefixed(1),
|
|
90
90
|
dest_token_address=reader.prefixed(1),
|
|
@@ -207,7 +207,7 @@ class EVMTokenAmount:
|
|
|
207
207
|
"""``CcipClient.EVMTokenAmount``."""
|
|
208
208
|
|
|
209
209
|
token: ChecksumAddress
|
|
210
|
-
amount:
|
|
210
|
+
amount: Amount
|
|
211
211
|
|
|
212
212
|
|
|
213
213
|
@dataclass(frozen=True, slots=True)
|
{ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/contracts.py
RENAMED
|
@@ -8,6 +8,7 @@ from dataclasses import dataclass
|
|
|
8
8
|
from eth_abi import encode
|
|
9
9
|
from eth_typing import ChecksumAddress
|
|
10
10
|
from eth_utils import keccak
|
|
11
|
+
from web3.types import Timestamp
|
|
11
12
|
|
|
12
13
|
from ipor_fusion.core.contract import Call
|
|
13
14
|
from ipor_fusion.crosschain.contracts import (
|
|
@@ -24,8 +25,10 @@ from ipor_fusion.types import (
|
|
|
24
25
|
CcipChainSelector,
|
|
25
26
|
ChainId,
|
|
26
27
|
CommandId,
|
|
28
|
+
Decimals,
|
|
27
29
|
MessageId,
|
|
28
30
|
OperationId,
|
|
31
|
+
Period,
|
|
29
32
|
PlasmaVaultAddress,
|
|
30
33
|
PositionSetHash,
|
|
31
34
|
ProposalId,
|
|
@@ -92,11 +95,11 @@ class SafetyConfig:
|
|
|
92
95
|
rescue_guardian: ChecksumAddress
|
|
93
96
|
balance_proposer: ChecksumAddress
|
|
94
97
|
balance_approver: ChecksumAddress
|
|
95
|
-
rescue_delay:
|
|
96
|
-
balance_staleness_max:
|
|
98
|
+
rescue_delay: Period
|
|
99
|
+
balance_staleness_max: Period
|
|
97
100
|
big_change_bps: int
|
|
98
|
-
min_update_interval:
|
|
99
|
-
transfer_staleness_max:
|
|
101
|
+
min_update_interval: Period
|
|
102
|
+
transfer_staleness_max: Period
|
|
100
103
|
|
|
101
104
|
def as_tuple(self) -> tuple:
|
|
102
105
|
return (
|
|
@@ -143,8 +146,10 @@ class CcipCrosschainExecutor(CrosschainExecutor):
|
|
|
143
146
|
def decimal_conversion_rate(self) -> Call[int]:
|
|
144
147
|
return self._view("DECIMAL_CONVERSION_RATE()", output_types=["uint256"])
|
|
145
148
|
|
|
146
|
-
def balance_staleness_max(self) -> Call[
|
|
147
|
-
return self._view(
|
|
149
|
+
def balance_staleness_max(self) -> Call[Period]:
|
|
150
|
+
return self._view(
|
|
151
|
+
"BALANCE_STALENESS_MAX()", output_types=["uint256"], decoder=Period
|
|
152
|
+
)
|
|
148
153
|
|
|
149
154
|
def ccip_route(self, chain_id: ChainId) -> Call[CcipRouteConfig]:
|
|
150
155
|
return self._view(
|
|
@@ -228,8 +233,13 @@ class CcipCrosschainExecutor(CrosschainExecutor):
|
|
|
228
233
|
decoder=CommandStatus,
|
|
229
234
|
)
|
|
230
235
|
|
|
231
|
-
def oldest_pending_at(self, chain_id: ChainId) -> Call[
|
|
232
|
-
return self._view(
|
|
236
|
+
def oldest_pending_at(self, chain_id: ChainId) -> Call[Timestamp]:
|
|
237
|
+
return self._view(
|
|
238
|
+
"oldestPendingAt(uint256)",
|
|
239
|
+
chain_id,
|
|
240
|
+
output_types=["uint64"],
|
|
241
|
+
decoder=Timestamp,
|
|
242
|
+
)
|
|
233
243
|
|
|
234
244
|
def pending_transfer_count(self, chain_id: ChainId) -> Call[int]:
|
|
235
245
|
return self._view(
|
|
@@ -387,13 +397,13 @@ class CcipCrosschainFactory(CrosschainFactory):
|
|
|
387
397
|
|
|
388
398
|
def asset_config(
|
|
389
399
|
self, asset_id: AssetId
|
|
390
|
-
) -> Call[tuple[ChecksumAddress,
|
|
400
|
+
) -> Call[tuple[ChecksumAddress, Decimals, bool]]:
|
|
391
401
|
"""``(token, sharedDecimals, enabled)`` for an asset id."""
|
|
392
402
|
return self._view(
|
|
393
403
|
"assetConfig(bytes32)",
|
|
394
404
|
asset_id,
|
|
395
405
|
output_types=["address", "uint8", "bool"],
|
|
396
|
-
decoder=lambda v: (_address(v[0]),
|
|
406
|
+
decoder=lambda v: (_address(v[0]), Decimals(v[1]), bool(v[2])),
|
|
397
407
|
)
|
|
398
408
|
|
|
399
409
|
def is_dispatcher(self, dispatcher: ChecksumAddress) -> Call[bool]:
|
|
@@ -412,22 +422,23 @@ class CcipCrosschainFactory(CrosschainFactory):
|
|
|
412
422
|
|
|
413
423
|
def pending_deployment_created_at(
|
|
414
424
|
self, executor: ChecksumAddress, dst_chain_id: ChainId
|
|
415
|
-
) -> Call[
|
|
425
|
+
) -> Call[Timestamp]:
|
|
416
426
|
return self._view(
|
|
417
427
|
"pendingDeploymentCreatedAt(address,uint256)",
|
|
418
428
|
executor,
|
|
419
429
|
dst_chain_id,
|
|
420
430
|
output_types=["uint64"],
|
|
431
|
+
decoder=Timestamp,
|
|
421
432
|
)
|
|
422
433
|
|
|
423
434
|
def owner(self) -> Call[ChecksumAddress]:
|
|
424
435
|
return self._view("OWNER()", output_types=["address"], decoder=_address)
|
|
425
436
|
|
|
426
|
-
def config_delay(self) -> Call[
|
|
437
|
+
def config_delay(self) -> Call[Period]:
|
|
427
438
|
"""Timelock of every scheduled asset, factory route and dispatcher
|
|
428
439
|
deployment gas limit: 24 hours in source, 300 seconds on the test
|
|
429
440
|
builds."""
|
|
430
|
-
return self._view("CONFIG_DELAY()", output_types=["uint256"])
|
|
441
|
+
return self._view("CONFIG_DELAY()", output_types=["uint256"], decoder=Period)
|
|
431
442
|
|
|
432
443
|
def executor_creation_code_hash(self) -> Call[bytes]:
|
|
433
444
|
"""keccak of the executor creation code the factory stores. It tells
|
|
@@ -466,7 +477,7 @@ class CcipCrosschainFactory(CrosschainFactory):
|
|
|
466
477
|
)
|
|
467
478
|
|
|
468
479
|
def schedule_asset(
|
|
469
|
-
self, asset_id: AssetId, token: ChecksumAddress, shared_decimals:
|
|
480
|
+
self, asset_id: AssetId, token: ChecksumAddress, shared_decimals: Decimals
|
|
470
481
|
) -> Call[None]:
|
|
471
482
|
"""Owner-only; executable after ``config_delay`` with the same arguments."""
|
|
472
483
|
return self._write(
|
|
@@ -474,7 +485,7 @@ class CcipCrosschainFactory(CrosschainFactory):
|
|
|
474
485
|
)
|
|
475
486
|
|
|
476
487
|
def execute_asset(
|
|
477
|
-
self, asset_id: AssetId, token: ChecksumAddress, shared_decimals:
|
|
488
|
+
self, asset_id: AssetId, token: ChecksumAddress, shared_decimals: Decimals
|
|
478
489
|
) -> Call[None]:
|
|
479
490
|
return self._write(
|
|
480
491
|
"executeAsset(bytes32,address,uint8)", asset_id, token, shared_decimals
|
{ipor_fusion-4.0.0.dev144 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/lane.py
RENAMED
|
@@ -22,7 +22,7 @@ from ipor_fusion.crosschain.fuses.ccip import (
|
|
|
22
22
|
)
|
|
23
23
|
from ipor_fusion.crosschain.lane import CrosschainLane, LaneFuses, LaneObservation
|
|
24
24
|
from ipor_fusion.crosschain.messages import CommandStatus, CrosschainTransportKind
|
|
25
|
-
from ipor_fusion.types import Amount, ProposalId
|
|
25
|
+
from ipor_fusion.types import Amount, Period, ProposalId
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
class CcipLane(CrosschainLane):
|
|
@@ -89,7 +89,7 @@ class CcipLane(CrosschainLane):
|
|
|
89
89
|
),
|
|
90
90
|
)
|
|
91
91
|
|
|
92
|
-
def staleness_max(self) -> Call[
|
|
92
|
+
def staleness_max(self) -> Call[Period]:
|
|
93
93
|
return self.executor.balance_staleness_max()
|
|
94
94
|
|
|
95
95
|
def default_send(self, *, token: bool) -> CcipSendParams:
|