ipor-fusion 4.0.0.dev260__tar.gz → 4.0.0.dev266__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.
Files changed (344) hide show
  1. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/AGENTS.md +1 -1
  2. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/PKG-INFO +4 -3
  3. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/README.md +3 -2
  4. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/pyproject.toml +1 -1
  5. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/skills/ipor-deploy-vault/SKILL.md +26 -16
  6. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/__init__.py +2 -0
  7. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/__init__.py +2 -0
  8. ipor_fusion-4.0.0.dev266/src/ipor_fusion/core/context_manager.py +55 -0
  9. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/fee_manager.py +60 -1
  10. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/fusion_factory.py +6 -6
  11. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/plasma_vault.py +159 -0
  12. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/rewards_manager.py +14 -1
  13. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/withdraw_manager.py +9 -0
  14. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/guide/quickstart.md +26 -16
  15. ipor_fusion-4.0.0.dev266/tests/test_governance_wrappers.py +271 -0
  16. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_guide.py +48 -1
  17. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_public_api.py +2 -0
  18. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/typed_client/consumer.py +6 -0
  19. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.claude-plugin/marketplace.json +0 -0
  20. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.claude-plugin/plugin.json +0 -0
  21. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.env.example +0 -0
  22. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.gemini/settings.json +0 -0
  23. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.git-blame-ignore-revs +0 -0
  24. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.github/workflows/cd.yml +0 -0
  25. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.github/workflows/ci.yml +0 -0
  26. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.github/workflows/commit-lint.yml +0 -0
  27. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.github/workflows/notify-slack.yml +0 -0
  28. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.github/workflows/python-build.yml +0 -0
  29. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.github/workflows/python-publish.yml +0 -0
  30. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.github/workflows/release.yml +0 -0
  31. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.github/workflows/report-slack.yml +0 -0
  32. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.gitignore +0 -0
  33. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.mcp.json +0 -0
  34. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.pre-commit-config.yaml +0 -0
  35. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/.python-version +0 -0
  36. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/CHANGELOG.md +0 -0
  37. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/CLAUDE.md +0 -0
  38. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/CODEOWNERS +0 -0
  39. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/LICENSE +0 -0
  40. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/MIGRATION_4.md +0 -0
  41. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/build.sh +0 -0
  42. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/examples/CONTRIBUTING.md +0 -0
  43. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/examples/README.md +0 -0
  44. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/examples/advanced_euler_v2_credit_market_base.py +0 -0
  45. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/examples/advanced_euler_v2_looping_arbitrum.py +0 -0
  46. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/examples/composed_hypercore_flow_arbitrum_hyperevm.py +0 -0
  47. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +0 -0
  48. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/examples/external_state_margin_leg_base.py +0 -0
  49. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/examples/simple_aave_v3_supply_base.py +0 -0
  50. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/pytest.ini +0 -0
  51. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/scripts/commit-check.sh +0 -0
  52. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/scripts/crosschain_readiness.py +0 -0
  53. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/about.py +0 -0
  54. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/cache.py +0 -0
  55. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/chains.py +0 -0
  56. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/cli/__init__.py +0 -0
  57. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
  58. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/cli/config_cmd.py +0 -0
  59. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/cli/config_store.py +0 -0
  60. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/cli/main.py +0 -0
  61. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/cli/market_cmd.py +0 -0
  62. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/cli/options.py +0 -0
  63. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/cli/oracle_mapping_view.py +0 -0
  64. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/cli/vault_cmd.py +0 -0
  65. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/cli/vault_health.py +0 -0
  66. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/cli/vault_info_view.py +0 -0
  67. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
  68. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/cli/vault_rendering.py +0 -0
  69. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/config/__init__.py +0 -0
  70. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/config/roles.py +0 -0
  71. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/access.py +0 -0
  72. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/address.py +0 -0
  73. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/context.py +0 -0
  74. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/contract.py +0 -0
  75. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/erc20.py +0 -0
  76. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/external_state_executor.py +0 -0
  77. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/fuse.py +0 -0
  78. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/fuse_action.py +0 -0
  79. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/logs.py +0 -0
  80. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/multicall.py +0 -0
  81. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/oracle.py +0 -0
  82. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/simulation.py +0 -0
  83. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/core/simulation_result.py +0 -0
  84. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/__init__.py +0 -0
  85. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
  86. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/ccip/chainlink.py +0 -0
  87. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/ccip/codec.py +0 -0
  88. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/ccip/contracts.py +0 -0
  89. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
  90. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/ccip/indexer.py +0 -0
  91. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/ccip/lane.py +0 -0
  92. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/ccip/quote.py +0 -0
  93. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/ccip/transport.py +0 -0
  94. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/contracts.py +0 -0
  95. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/discovery.py +0 -0
  96. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/errors.py +0 -0
  97. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/fuses/__init__.py +0 -0
  98. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/fuses/base.py +0 -0
  99. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/fuses/ccip.py +0 -0
  100. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/fuses/stargate.py +0 -0
  101. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/lane.py +0 -0
  102. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/logs.py +0 -0
  103. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/messages.py +0 -0
  104. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/simulation.py +0 -0
  105. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
  106. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/stargate/contracts.py +0 -0
  107. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/stargate/lane.py +0 -0
  108. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/stargate/layerzero.py +0 -0
  109. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/stargate/transport.py +0 -0
  110. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/crosschain/transport.py +0 -0
  111. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/dependency_graph.py +0 -0
  112. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/entry_cli.py +0 -0
  113. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/entry_mcp.py +0 -0
  114. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/errors.py +0 -0
  115. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/explorer.py +0 -0
  116. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/field_docs.py +0 -0
  117. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/__init__.py +0 -0
  118. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/aave_v3.py +0 -0
  119. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/async_action.py +0 -0
  120. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/base.py +0 -0
  121. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/compound_v3.py +0 -0
  122. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/erc4626.py +0 -0
  123. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/euler_v2.py +0 -0
  124. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/events.py +0 -0
  125. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/external_state.py +0 -0
  126. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/external_state_event_decoding.py +0 -0
  127. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
  128. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
  129. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/hypercore.py +0 -0
  130. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/hypercore_event_decoding.py +0 -0
  131. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/merkl.py +0 -0
  132. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/morpho.py +0 -0
  133. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
  134. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
  135. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/fuses/universal.py +0 -0
  136. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/guide/__init__.py +0 -0
  137. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/guide/architecture.md +0 -0
  138. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/guide/glossary.md +0 -0
  139. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/guide/invariants.md +0 -0
  140. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/hypercore/__init__.py +0 -0
  141. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/market_ids.py +0 -0
  142. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/market_info.py +0 -0
  143. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/mcp/__init__.py +0 -0
  144. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/mcp/guide.py +0 -0
  145. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/mcp/models.py +0 -0
  146. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/mcp/server.py +0 -0
  147. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/morpho_api.py +0 -0
  148. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/py.typed +0 -0
  149. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/readers/__init__.py +0 -0
  150. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/readers/aave_v3.py +0 -0
  151. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/readers/aave_v4.py +0 -0
  152. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/readers/compound_v3.py +0 -0
  153. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/readers/hypercore.py +0 -0
  154. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/readers/hypercore_outcome.py +0 -0
  155. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/readers/lending_health.py +0 -0
  156. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/readers/morpho.py +0 -0
  157. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/readers/oracle_mapping.py +0 -0
  158. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/readers/oracle_mapping_nodes.py +0 -0
  159. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/readers/oracle_mapping_reader.py +0 -0
  160. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/readers/position_manager.py +0 -0
  161. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/readers/ramses_v2.py +0 -0
  162. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
  163. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/readers/unpriceable.py +0 -0
  164. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/substrates.py +0 -0
  165. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/types.py +0 -0
  166. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/validation.py +0 -0
  167. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/vault_data.py +0 -0
  168. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/vault_erc20.py +0 -0
  169. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/vault_info.py +0 -0
  170. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/vault_managers.py +0 -0
  171. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/vault_positions.py +0 -0
  172. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/src/ipor_fusion/vault_reads.py +0 -0
  173. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/UniswapV3UniversalRouter.py +0 -0
  174. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_crosschain.py +0 -0
  175. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_crosschain_lifecycle.py +0 -0
  176. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_crosschain_recovery.py +0 -0
  177. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_euler_v2.py +0 -0
  178. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_event_args.py +0 -0
  179. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_fake_rpc.py +0 -0
  180. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_foundry.py +0 -0
  181. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_golden.py +0 -0
  182. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_guide.py +0 -0
  183. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_hypercore_model.py +0 -0
  184. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_hypercore_shadow.py +0 -0
  185. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_live.py +0 -0
  186. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_multicall.py +0 -0
  187. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_oracle_mapping_fake.py +0 -0
  188. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_simulate.py +0 -0
  189. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/_validation.py +0 -0
  190. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/addresses.py +0 -0
  191. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/conftest.py +0 -0
  192. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/constants.py +0 -0
  193. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/hypercore_hip3_flow.json +0 -0
  194. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/hypercore_market55.json +0 -0
  195. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/market_golden/meta_morpho_v1.json +0 -0
  196. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/market_golden/meta_morpho_v1.mcp.json +0 -0
  197. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/market_golden/meta_morpho_v2.json +0 -0
  198. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/market_golden/meta_morpho_v2.mcp.json +0 -0
  199. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/market_golden/morpho_api/market.json +0 -0
  200. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/market_golden/morpho_api/vault_v1.json +0 -0
  201. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/market_golden/morpho_api/vault_v2.json +0 -0
  202. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/market_golden/morpho_api/vault_v2_not_found.json +0 -0
  203. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/market_golden/morpho_blue.json +0 -0
  204. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/market_golden/morpho_blue.mcp.json +0 -0
  205. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/market_golden/morpho_blue_api_error.json +0 -0
  206. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/market_golden/morpho_blue_api_error.mcp.json +0 -0
  207. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/market_golden/morpho_blue_no_api.json +0 -0
  208. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/market_golden/morpho_blue_no_api.mcp.json +0 -0
  209. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/oracle_mapping_golden/mapping.json +0 -0
  210. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/oracle_mapping_golden/mapping.mcp.json +0 -0
  211. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/simulate_v1_request.json +0 -0
  212. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/vault_info_golden/clean.json +0 -0
  213. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/vault_info_golden/clean.mcp.json +0 -0
  214. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/vault_info_golden/clean.txt +0 -0
  215. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/vault_info_golden/deployment_error.json +0 -0
  216. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/vault_info_golden/deployment_error.mcp.json +0 -0
  217. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/vault_info_golden/deployment_error.txt +0 -0
  218. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/vault_info_golden/fetched.cli.json +0 -0
  219. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/vault_info_golden/fetched.json +0 -0
  220. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/vault_info_golden/fetched.mcp.json +0 -0
  221. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/vault_info_golden/full.json +0 -0
  222. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/vault_info_golden/full.mcp.json +0 -0
  223. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/vault_info_golden/full.txt +0 -0
  224. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/vault_info_golden/rich.json +0 -0
  225. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/vault_info_golden/rich.mcp.json +0 -0
  226. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/fixtures/vault_info_golden/rich.txt +0 -0
  227. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_about.py +0 -0
  228. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_access_manager.py +0 -0
  229. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cache.py +0 -0
  230. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_chains.py +0 -0
  231. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_changelog.py +0 -0
  232. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_commands.py +0 -0
  233. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_config_store.py +0 -0
  234. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_helpers.py +0 -0
  235. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_hypercore.py +0 -0
  236. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_lending_health.py +0 -0
  237. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_market_golden.py +0 -0
  238. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_market_morpho_blue.py +0 -0
  239. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_mcp_parity.py +0 -0
  240. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_oracle_mapping.py +0 -0
  241. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_oracle_mapping_golden.py +0 -0
  242. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_pending_requests_scan.py +0 -0
  243. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_role_accounts.py +0 -0
  244. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_vault_info_golden.py +0 -0
  245. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_vault_predates_getters.py +0 -0
  246. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_cli_vault_validate.py +0 -0
  247. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_contract_call.py +0 -0
  248. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_contract_encoder.py +0 -0
  249. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_crosschain_ccip_events.py +0 -0
  250. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_crosschain_ccip_indexer.py +0 -0
  251. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_crosschain_ccip_quote.py +0 -0
  252. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_crosschain_chainlink.py +0 -0
  253. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_crosschain_contracts.py +0 -0
  254. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_crosschain_encoding.py +0 -0
  255. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_crosschain_errors.py +0 -0
  256. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_crosschain_lane.py +0 -0
  257. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_crosschain_layering.py +0 -0
  258. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_crosschain_readiness.py +0 -0
  259. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_crosschain_readiness_report.py +0 -0
  260. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_crosschain_transport.py +0 -0
  261. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_docs_typing.py +0 -0
  262. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_erc20.py +0 -0
  263. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_error_hierarchy.py +0 -0
  264. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_examples_composed_hypercore.py +0 -0
  265. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_examples_crosschain.py +0 -0
  266. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_examples_euler_looping_arbitrum.py +0 -0
  267. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_examples_vaults.py +0 -0
  268. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_explorer.py +0 -0
  269. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_external_state_events.py +0 -0
  270. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_external_state_executor.py +0 -0
  271. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_fee_manager.py +0 -0
  272. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_fuse_encoding.py +0 -0
  273. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_fusion_instance.py +0 -0
  274. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_hypercore_deployment.py +0 -0
  275. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_hypercore_events.py +0 -0
  276. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_hypercore_flow.py +0 -0
  277. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_hypercore_live.py +0 -0
  278. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_hypercore_outcome.py +0 -0
  279. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_hypercore_readers.py +0 -0
  280. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_hypercore_simulation.py +0 -0
  281. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_logs.py +0 -0
  282. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_mcp_hypercore.py +0 -0
  283. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_mcp_models.py +0 -0
  284. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_mcp_server.py +0 -0
  285. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_mcp_vault_validate.py +0 -0
  286. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_multicall.py +0 -0
  287. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_oracle.py +0 -0
  288. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_oracle_mapping.py +0 -0
  289. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_plasma_vault.py +0 -0
  290. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_public_type_reachability.py +0 -0
  291. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_reader_encoding.py +0 -0
  292. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_readiness_selection.py +0 -0
  293. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_revert_decoding.py +0 -0
  294. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_rewards_manager.py +0 -0
  295. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_roles.py +0 -0
  296. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_sdk_layering.py +0 -0
  297. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
  298. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
  299. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_claim_morpho_rewards.py +0 -0
  300. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_crosschain_canary.py +0 -0
  301. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_crosschain_hypercore.py +0 -0
  302. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_crosschain_hyperevm.py +0 -0
  303. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_crosschain_lifecycle.py +0 -0
  304. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_euler_v2_batch_base.py +0 -0
  305. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
  306. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
  307. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
  308. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
  309. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_examples_arbitrum.py +0 -0
  310. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_examples_base.py +0 -0
  311. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_examples_crosschain.py +0 -0
  312. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_external_state_executor_base.py +0 -0
  313. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
  314. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_looping_aave_v3_base.py +0 -0
  315. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
  316. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_morpho_blue.py +0 -0
  317. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_pilot_v3.py +0 -0
  318. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
  319. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_pilot_v5_ramses.py +0 -0
  320. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
  321. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
  322. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_readers_integration.py +0 -0
  323. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_release_funds.py +0 -0
  324. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_swap_on_base.py +0 -0
  325. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulate_vault_from_scratch_base.py +0 -0
  326. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulation_errors.py +0 -0
  327. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_simulation_observation.py +0 -0
  328. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_solidity_compiler.py +0 -0
  329. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_solidity_mirrors.py +0 -0
  330. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_substrates.py +0 -0
  331. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_types_and_events.py +0 -0
  332. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_unpriceable_tokens.py +0 -0
  333. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_validation.py +0 -0
  334. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_vault_data_block.py +0 -0
  335. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_vault_dep_graph.py +0 -0
  336. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_vault_info_fetched_golden.py +0 -0
  337. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_vault_info_onchain_base.py +0 -0
  338. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
  339. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_vault_reconciliation_onchain_base.py +0 -0
  340. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_vault_simulator_blocks.py +0 -0
  341. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_web3_context.py +0 -0
  342. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/test_withdraw_manager.py +0 -0
  343. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/tests/typed_client/rejected.py +0 -0
  344. {ipor_fusion-4.0.0.dev260 → ipor_fusion-4.0.0.dev266}/uv.lock +0 -0
@@ -269,7 +269,7 @@ the lifecycle matrix follows that.
269
269
  TypedDict's `__optional_keys__` is right at run time.
270
270
  None of them imports `cli/` (`tests/test_sdk_layering.py`)
271
271
  - `config/roles.py` — `Roles` IntEnum
272
- - `core/` — `context` (`Web3Context`), `contract` (`Call`, `ContractWrapper`),
272
+ - `core/` — `context` (`Web3Context`), `context_manager` (`ContextManager`), `contract` (`Call`, `ContractWrapper`),
273
273
  `multicall` (`Multicall3`), `logs` (`get_logs_adaptive`: every event scan pages
274
274
  `eth_getLogs` within the provider's caps from the contract's creation block, within a
275
275
  time and request budget, and raises `LogScanError` rather than return partial logs;
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ipor-fusion
3
- Version: 4.0.0.dev260
3
+ Version: 4.0.0.dev266
4
4
  Summary: The IPOR Fusion SDK for Python
5
5
  Project-URL: homepage, https://ipor.io
6
6
  Project-URL: repository, https://github.com/IPOR-Labs/ipor-fusion.py
@@ -442,13 +442,14 @@ Fuse.method() --> FuseAction --> PlasmaVault.execute([actions]) --> Call
442
442
  |--------|---------|
443
443
  | `Web3Context` | Provider connection, signing, tx dispatch, gas estimation |
444
444
  | `Call` | Pre-encoded contract call; `.call(ctx)`, `.send(ctx)`, `.calldata`, `.build_transaction(ctx)` |
445
- | `PlasmaVault` | ERC-4626 vault — execute, deposit, withdraw, fuse and market configuration |
445
+ | `PlasmaVault` | ERC-4626 vault — execute, deposit, withdraw, previews, fuse, market, fee and limit configuration |
446
446
  | `VaultSimulator` | Batch `execute` + reads through `eth_simulateV1`, multi-block, no local node |
447
447
  | `FusionFactory` | Deploy a new vault (`clone`, `clone_supervised`) |
448
448
  | `AccessManager` | Role-based access control |
449
449
  | `RewardsManager` | Claim and vest rewards |
450
450
  | `WithdrawManager` | Time-windowed withdrawal requests |
451
- | `FeeManager` | Deposit, performance, and management fee configuration |
451
+ | `FeeManager` | Deposit, performance, and management fee configuration and harvesting |
452
+ | `ContextManager` | Run calls on approved context-aware targets on the caller's behalf |
452
453
  | `FeeAccount` | Fee escrow account, resolves its `FeeManager` |
453
454
  | `PriceOracleMiddleware` | Asset price feeds |
454
455
  | `PriceOracleMiddlewareManager` | Per-vault price-source overrides |
@@ -394,13 +394,14 @@ Fuse.method() --> FuseAction --> PlasmaVault.execute([actions]) --> Call
394
394
  |--------|---------|
395
395
  | `Web3Context` | Provider connection, signing, tx dispatch, gas estimation |
396
396
  | `Call` | Pre-encoded contract call; `.call(ctx)`, `.send(ctx)`, `.calldata`, `.build_transaction(ctx)` |
397
- | `PlasmaVault` | ERC-4626 vault — execute, deposit, withdraw, fuse and market configuration |
397
+ | `PlasmaVault` | ERC-4626 vault — execute, deposit, withdraw, previews, fuse, market, fee and limit configuration |
398
398
  | `VaultSimulator` | Batch `execute` + reads through `eth_simulateV1`, multi-block, no local node |
399
399
  | `FusionFactory` | Deploy a new vault (`clone`, `clone_supervised`) |
400
400
  | `AccessManager` | Role-based access control |
401
401
  | `RewardsManager` | Claim and vest rewards |
402
402
  | `WithdrawManager` | Time-windowed withdrawal requests |
403
- | `FeeManager` | Deposit, performance, and management fee configuration |
403
+ | `FeeManager` | Deposit, performance, and management fee configuration and harvesting |
404
+ | `ContextManager` | Run calls on approved context-aware targets on the caller's behalf |
404
405
  | `FeeAccount` | Fee escrow account, resolves its `FeeManager` |
405
406
  | `PriceOracleMiddleware` | Asset price feeds |
406
407
  | `PriceOracleMiddlewareManager` | Per-vault price-source overrides |
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ipor-fusion"
3
- version = "4.0.0.dev260"
3
+ version = "4.0.0.dev266"
4
4
  description = "The IPOR Fusion SDK for Python"
5
5
  authors = [
6
6
  { name = "Adam Mydlarz", email = "amydlarz@gmail.com" },
@@ -204,22 +204,32 @@ Notes on the walk:
204
204
  so you recognise and avoid it. Verify against `ipor-abi` before use; the
205
205
  registry is the source of truth and is regenerated on release.
206
206
 
207
- | Chain | Chain id | `IporFusionFactoryProxy` (use) | `IporFusionFactoryImpl` (reverts) | Verified |
208
- |---|---|---|---|---|
209
- | Ethereum | 1 | `0xcd05909C4A1F8E501e4ED554cEF4Ed5E48D9b852` | `0xf19C1E9f6616F6056AF1e322A86fDaAaAf0263f5` | implementation slot |
210
- | Unichain | 130 | `0xC9b4E839e86284C558791C13Bda97999fc49aF63` | `0xf5Bc40C192D51ED93ADD6557884766772FA72589` | implementation slot |
211
- | TAC | 239 | `0x26b5561E2E0e7d7977431E92740903Ef3cB7194b` | `0x7DDd0bBB59eFB4b7791cE5E1Cf1587F083aE4Ef5` | implementation slot |
212
- | Botanix | 3637 | `0x7c9857f22D0cc6523C8e88BFDCbf411AB8300fF5` | `0xddb0EFB2a7a5C02e01b5A1f85C0a1110d68EeC26` | registry only |
213
- | Base | 8453 | `0x1455717668fA96534f675856347A973fA907e922` | `0x610152A79BE7F2Aa3aA70520c9331c18fe8D33b7` | clone executed on a fork |
214
- | Plasma | 9745 | `0x70d41759FBF90fB63c88197217cB08F93a1c65CB` | `0x3A42bD6fEa94421025Ae2ed01CE6f137ac785abD` | implementation slot |
215
- | Arbitrum | 42161 | `0x134fCAce7a2C7Ef3dF2479B62f03ddabAEa922d5` | `0x87f94ac9aF79261F0BC73582114f805F55Cd0b25` | clone executed on a fork |
216
- | Avalanche | 43114 | `0xa00b6379833D77fA9C9497b32dae00dF39Ac751e` | `0x399596cFccFEbBb60f8652bece8586a6Bb4199ab` | implementation slot |
217
- | Ink | 57073 | `0xEC53f69Bd1D991a2F99e96DE66E81D0E42A61D8D` | `0xe7372BC46b79e0c87AfE5286c41c20687018E425` | implementation slot |
218
- | Katana | 747474 | `0xc29b8D591d6a3f109Ca7ba384F2e00162866D37B` | `0x4a4De6e86AD0d0546F55B595cA75f55803D940bA` | registry only |
219
-
220
- "Implementation slot" means the proxy's EIP-1967 implementation slot was read
221
- and matches the registry's `IporFusionFactoryImpl`; "registry only" means the
222
- pair was taken from `ipor-abi` without an on-chain read.
207
+ | Chain | Chain id | `IporFusionFactoryProxy` (use) | `IporFusionFactoryImpl` (reverts) | Vault tooling | Verified |
208
+ |---|---|---|---|---|---|
209
+ | Ethereum | 1 | `0xcd05909C4A1F8E501e4ED554cEF4Ed5E48D9b852` | `0x14d120C365Debd920eaDf0a7AC31e659Bc58217b` | validated | implementation slot |
210
+ | Flare | 14 | `0xE75F3565D67645775351A9886F2b598f07d1860B` | `0x6C1ff6eBf5e92Dbc5591E7cCF455829De9C46579` | factory only | implementation slot |
211
+ | Unichain | 130 | `0xC9b4E839e86284C558791C13Bda97999fc49aF63` | `0x73c7CA802403BB21e9608C937c556C04d5eeBAD6` | validated | implementation slot |
212
+ | Monad | 143 | `0x62DFfe8bCaaf7960f858a4f7dDC83cc98F04cEDC` | `0x1017f0032460B3c8FBB92Bfd350F708Ff6229137` | validated | implementation slot |
213
+ | TAC | 239 | `0x26b5561E2E0e7d7977431E92740903Ef3cB7194b` | `0x7DDd0bBB59eFB4b7791cE5E1Cf1587F083aE4Ef5` | factory only | implementation slot |
214
+ | HyperEVM | 999 | `0x6bBc827F34b4e862d15215ABd4AC0E3886181665` | `0x010430cbdE2Bb8ACC48D7aDfbEb99812E83f1156` | validated | implementation slot |
215
+ | Botanix | 3637 | `0x7c9857f22D0cc6523C8e88BFDCbf411AB8300fF5` | `0xddb0EFB2a7a5C02e01b5A1f85C0a1110d68EeC26` | factory only | registry only |
216
+ | Robinhood | 4663 | `0xDF7A590b60072476E355A8EfF33e4872440bDc7C` | `0x9d897beA78F8747d8f9C45d5734089ca7225AE90` | validated | implementation slot |
217
+ | Base | 8453 | `0x1455717668fA96534f675856347A973fA907e922` | `0x378fEb2E96082FB965E2BB922AEE484d07c14014` | validated | implementation slot |
218
+ | Plasma | 9745 | `0x70d41759FBF90fB63c88197217cB08F93a1c65CB` | `0x346DA190c60d6101B77DA613a252c7aE25A7a120` | validated | implementation slot |
219
+ | Arbitrum | 42161 | `0x134fCAce7a2C7Ef3dF2479B62f03ddabAEa922d5` | `0x86C8Ea8800EB6bc8C846c3e0230178520a0ED721` | validated | implementation slot |
220
+ | Avalanche | 43114 | `0xa00b6379833D77fA9C9497b32dae00dF39Ac751e` | `0x0f358Bb3d14AB911dBfAF4d9061097e7F5Cf123F` | validated | implementation slot |
221
+ | Ink | 57073 | `0xEC53f69Bd1D991a2F99e96DE66E81D0E42A61D8D` | `0xEF774B9767cC9FC813A2b595BE870A13D5B367C0` | validated | implementation slot |
222
+ | Katana | 747474 | `0xc29b8D591d6a3f109Ca7ba384F2e00162866D37B` | `0x4a4De6e86AD0d0546F55B595cA75f55803D940bA` | validated | implementation slot |
223
+
224
+ A deployed factory is not the same as supported tooling. "Validated" chains are
225
+ `SUPPORTED_CHAIN_IDS` (`ipor_fusion.chains`): `fusion vault info`/`validate`
226
+ and `fetch_vault_data` run there. On a "factory only" chain `clone()` works,
227
+ but the vault tooling raises `UnsupportedChainError` until the chain is
228
+ validated. "Implementation slot" means the proxy's EIP-1967 implementation
229
+ slot was read on chain and matches the registry's `IporFusionFactoryImpl`;
230
+ "registry only" means the pair comes from `ipor-abi` without an on-chain read.
231
+ The factory implementations are upgraded in place, so the implementation
232
+ column changes with releases while the proxy stays.
223
233
 
224
234
  Fuse addresses are not in the SDK. Resolve them by registry name and chain
225
235
  in `ipor-abi` (`SupplyFuseAaveV3`, `BalanceFuseAaveV3`, ...), or with the
@@ -36,6 +36,7 @@ from ipor_fusion.core.access import (
36
36
  role_account_sort_key,
37
37
  )
38
38
  from ipor_fusion.core.context import InFlightLimit, Web3Context
39
+ from ipor_fusion.core.context_manager import ContextManager
39
40
  from ipor_fusion.core.contract import Call
40
41
  from ipor_fusion.core.erc20 import ERC20
41
42
  from ipor_fusion.core.external_state_executor import (
@@ -448,6 +449,7 @@ __all__ = [
448
449
  "repository_url",
449
450
  "Web3Context",
450
451
  "InFlightLimit",
452
+ "ContextManager",
451
453
  "Call",
452
454
  "get_logs_adaptive",
453
455
  "find_creation_block",
@@ -10,6 +10,7 @@ from ipor_fusion.core.access import (
10
10
  role_account_sort_key,
11
11
  )
12
12
  from ipor_fusion.core.context import InFlightLimit, Web3Context
13
+ from ipor_fusion.core.context_manager import ContextManager
13
14
  from ipor_fusion.core.contract import (
14
15
  Call,
15
16
  )
@@ -85,6 +86,7 @@ from ipor_fusion.core.withdraw_manager import (
85
86
  __all__ = [
86
87
  "Web3Context",
87
88
  "InFlightLimit",
89
+ "ContextManager",
88
90
  "Multicall3",
89
91
  "Multicall3Batch",
90
92
  "BatchValue",
@@ -0,0 +1,55 @@
1
+ """IPOR Fusion ContextManager: runs calls on context-aware targets (the vault's
2
+ managers and fuses) on behalf of the caller."""
3
+
4
+ from __future__ import annotations
5
+
6
+ from collections.abc import Sequence
7
+
8
+ from eth_typing import ChecksumAddress
9
+ from web3 import Web3
10
+
11
+ from ipor_fusion.core.contract import Call, ContractWrapper
12
+
13
+
14
+ def _address_list_decoder(value: tuple[str, ...]) -> list[ChecksumAddress]:
15
+ return [Web3.to_checksum_address(item) for item in value]
16
+
17
+
18
+ class ContextManager(ContractWrapper):
19
+ """Runs each ``(target, data)`` call with the caller set as the target's
20
+ context sender, so a contract that reads the context acts for the caller.
21
+ Only approved targets can be called."""
22
+
23
+ def get_approved_targets(self) -> Call[list[ChecksumAddress]]:
24
+ return self._view(
25
+ "getApprovedTargets()",
26
+ output_types=["address[]"],
27
+ decoder=_address_list_decoder,
28
+ )
29
+
30
+ def is_target_approved(self, target: ChecksumAddress) -> Call[bool]:
31
+ return self._view(
32
+ "isTargetApproved(address)", target, output_types=["bool"], decoder=bool
33
+ )
34
+
35
+ def get_nonce(self, sender: ChecksumAddress) -> Call[int]:
36
+ """The last nonce ``sender`` used in a signed context call; the next
37
+ signed call must carry a higher one."""
38
+ return self._view(
39
+ "getNonce(address)", sender, output_types=["uint256"], decoder=int
40
+ )
41
+
42
+ def add_approved_targets(self, targets: Sequence[ChecksumAddress]) -> Call[None]:
43
+ return self._write("addApprovedTargets(address[])", list(targets))
44
+
45
+ def remove_approved_targets(self, targets: Sequence[ChecksumAddress]) -> Call[None]:
46
+ return self._write("removeApprovedTargets(address[])", list(targets))
47
+
48
+ def run_with_context(
49
+ self, calls: Sequence[tuple[ChecksumAddress, bytes]]
50
+ ) -> Call[None]:
51
+ """Run ``calls`` in order, atomically; every target must be approved."""
52
+ return self._write(
53
+ "runWithContext((address[],bytes[]))",
54
+ ([target for target, _ in calls], [data for _, data in calls]),
55
+ )
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from collections.abc import Sequence
3
4
  from dataclasses import dataclass
4
5
 
5
6
  from eth_typing import ChecksumAddress
@@ -7,7 +8,7 @@ from web3 import Web3
7
8
  from web3.types import Timestamp
8
9
 
9
10
  from ipor_fusion.core.contract import Call, ContractWrapper
10
- from ipor_fusion.types import Fee, Period
11
+ from ipor_fusion.types import Fee, Period, Shares
11
12
 
12
13
 
13
14
  @dataclass(slots=True)
@@ -79,6 +80,64 @@ class FeeManager(ContractWrapper):
79
80
  (10000 = 100%).
80
81
  """
81
82
 
83
+ def harvest_all_fees(self) -> Call[None]:
84
+ """Distribute the collected management and performance fees to their
85
+ recipients (public)."""
86
+ return self._write("harvestAllFees()")
87
+
88
+ def harvest_management_fee(self) -> Call[None]:
89
+ return self._write("harvestManagementFee()")
90
+
91
+ def harvest_performance_fee(self) -> Call[None]:
92
+ return self._write("harvestPerformanceFee()")
93
+
94
+ def update_management_fee(self, recipients: Sequence[RecipientFee]) -> Call[None]:
95
+ """Replace the management fee recipients; each ``fee_value`` in percent
96
+ with 2 decimals (10000 = 100%)."""
97
+ return self._write(
98
+ "updateManagementFee((address,uint256)[])",
99
+ [(r.recipient, r.fee_value) for r in recipients],
100
+ )
101
+
102
+ def update_performance_fee(self, recipients: Sequence[RecipientFee]) -> Call[None]:
103
+ """Replace the performance fee recipients; each ``fee_value`` in percent
104
+ with 2 decimals (10000 = 100%)."""
105
+ return self._write(
106
+ "updatePerformanceFee((address,uint256)[])",
107
+ [(r.recipient, r.fee_value) for r in recipients],
108
+ )
109
+
110
+ def set_ipor_dao_fee_recipient_address(
111
+ self, recipient: ChecksumAddress
112
+ ) -> Call[None]:
113
+ return self._write("setIporDaoFeeRecipientAddress(address)", recipient)
114
+
115
+ def set_deposit_fee(self, fee: Fee) -> Call[None]:
116
+ """WAD (``10**18`` is 100%), as `get_deposit_fee` reports it."""
117
+ return self._write("setDepositFee(uint256)", fee)
118
+
119
+ def update_high_water_mark_performance_fee(self) -> Call[None]:
120
+ """Reset the high-water mark to the current exchange rate."""
121
+ return self._write("updateHighWaterMarkPerformanceFee()")
122
+
123
+ def update_interval_high_water_mark_performance_fee(
124
+ self, interval: Period
125
+ ) -> Call[None]:
126
+ """The least time between automatic high-water-mark resets; zero
127
+ disables them."""
128
+ return self._write(
129
+ "updateIntervalHighWaterMarkPerformanceFee(uint32)", interval
130
+ )
131
+
132
+ def calculate_deposit_fee(self, shares: Shares) -> Call[Shares]:
133
+ """The fee part, in shares, of a deposit minting ``shares``."""
134
+ return self._view(
135
+ "calculateDepositFee(uint256)",
136
+ shares,
137
+ output_types=["uint256"],
138
+ decoder=Shares,
139
+ )
140
+
82
141
  def get_deposit_fee(self) -> Call[Fee]:
83
142
  """WAD (1e18 = 100%). Reverts on FeeManager deployments predating
84
143
  the deposit fee - callers should treat a revert as no-deposit-fee."""
@@ -1,16 +1,16 @@
1
1
  """IporFusionFactoryProxy wrapper — deploys a full Fusion vault stack
2
2
  (plasmaVault + accessManager + 6 managers) in a single tx.
3
3
 
4
- Deployed signature on BASE (verified 2026-05-12 against impl bytecode):
4
+ Deployed signature on BASE (verified against the impl bytecode on 2026-05-12,
5
+ and on 2026-10-23 for the upgraded impl 0x378fEb2E96082FB965E2BB922AEE484d07c14014):
5
6
  clone(string assetName_, string assetSymbol_, address underlyingToken_,
6
7
  uint256 redemptionDelayInSeconds_, address owner_,
7
8
  uint256 daoFeePackageIndex_) → FusionInstance
8
9
 
9
- Note: the ipor-abi registry publishes a 5-arg shape (no daoFeePackageIndex);
10
- that's stale — the deployed factory impl at
11
- 0x610152a79be7f2aa3aa70520c9331c18fe8d33b7 only exposes the 6-arg variant
12
- (selector 0x8697b10a). Always trust the impl bytecode over the registry
13
- when they disagree.
10
+ Note: the ipor-abi registry has published a 5-arg shape (no
11
+ daoFeePackageIndex); both the earlier impl 0x610152a79be7f2aa3aa70520c9331c18fe8d33b7
12
+ and the current one expose only the 6-arg variant (selector 0x8697b10a). Always
13
+ trust the impl bytecode over the registry when they disagree.
14
14
 
15
15
  `clone()` is a write — call `.send(ctx)` for a real tx, then decode the
16
16
  created addresses from its receipt with `factory.decode_clone_receipt(receipt)`.
@@ -13,6 +13,7 @@ from web3 import Web3
13
13
  from web3.exceptions import ContractLogicError
14
14
  from web3.types import LogReceipt, Timestamp
15
15
 
16
+ from ipor_fusion.config.roles import Roles
16
17
  from ipor_fusion.core.context import Web3Context
17
18
  from ipor_fusion.core.contract import Call, ContractWrapper
18
19
  from ipor_fusion.core.fuse_action import FuseAction
@@ -25,7 +26,9 @@ from ipor_fusion.types import (
25
26
  Fee,
26
27
  FuseAddress,
27
28
  MarketId,
29
+ Period,
28
30
  PlasmaVaultAddress,
31
+ RoleId,
29
32
  Shares,
30
33
  )
31
34
 
@@ -403,6 +406,162 @@ class PlasmaVault(ContractWrapper):
403
406
  "maxWithdraw(address)", account, output_types=["uint256"], decoder=Amount
404
407
  )
405
408
 
409
+ def max_redeem(self, account: ChecksumAddress) -> Call[Shares]:
410
+ return self._view(
411
+ "maxRedeem(address)", account, output_types=["uint256"], decoder=Shares
412
+ )
413
+
414
+ def max_deposit(self, receiver: ChecksumAddress) -> Call[Amount]:
415
+ """Assets ``receiver`` can still deposit under the total supply cap."""
416
+ return self._view(
417
+ "maxDeposit(address)", receiver, output_types=["uint256"], decoder=Amount
418
+ )
419
+
420
+ def max_mint(self, receiver: ChecksumAddress) -> Call[Shares]:
421
+ """Shares ``receiver`` can still mint under the total supply cap."""
422
+ return self._view(
423
+ "maxMint(address)", receiver, output_types=["uint256"], decoder=Shares
424
+ )
425
+
426
+ def preview_deposit(self, assets: Amount) -> Call[Shares]:
427
+ """Shares a deposit of ``assets`` mints, after the deposit fee."""
428
+ return self._view(
429
+ "previewDeposit(uint256)", assets, output_types=["uint256"], decoder=Shares
430
+ )
431
+
432
+ def preview_mint(self, shares: Shares) -> Call[Amount]:
433
+ """Assets a mint of ``shares`` takes, the deposit fee included."""
434
+ return self._view(
435
+ "previewMint(uint256)", shares, output_types=["uint256"], decoder=Amount
436
+ )
437
+
438
+ def preview_withdraw(self, assets: Amount) -> Call[Shares]:
439
+ """Shares an instant withdrawal of ``assets`` burns, the withdraw fee
440
+ included."""
441
+ return self._view(
442
+ "previewWithdraw(uint256)", assets, output_types=["uint256"], decoder=Shares
443
+ )
444
+
445
+ def preview_redeem(self, shares: Shares) -> Call[Amount]:
446
+ """Assets an instant redemption of ``shares`` pays, after the withdraw fee."""
447
+ return self._view(
448
+ "previewRedeem(uint256)", shares, output_types=["uint256"], decoder=Amount
449
+ )
450
+
451
+ def deposit_with_permit(
452
+ self,
453
+ assets: Amount,
454
+ receiver: ChecksumAddress,
455
+ deadline: Timestamp,
456
+ v: int,
457
+ r: bytes,
458
+ s: bytes,
459
+ ) -> Call[None]:
460
+ """`deposit` with an EIP-2612 permit of the asset signed by the caller.
461
+ The vault deposits even when the permit call fails (an allowance already
462
+ in place, or a front-run permit)."""
463
+ return self._write(
464
+ "depositWithPermit(uint256,address,uint256,uint8,bytes32,bytes32)",
465
+ assets,
466
+ receiver,
467
+ deadline,
468
+ v,
469
+ r,
470
+ s,
471
+ )
472
+
473
+ def is_fuse_supported(self, fuse: FuseAddress) -> Call[bool]:
474
+ """Whether ``fuse`` is registered (`add_fuses`), so `execute` may call it."""
475
+ return self._view(
476
+ "isFuseSupported(address)", fuse, output_types=["bool"], decoder=bool
477
+ )
478
+
479
+ def is_balance_fuse_supported(
480
+ self, market: MarketId, fuse: FuseAddress
481
+ ) -> Call[bool]:
482
+ """Whether ``fuse`` is the balance fuse of ``market``."""
483
+ return self._view(
484
+ "isBalanceFuseSupported(uint256,address)",
485
+ market,
486
+ fuse,
487
+ output_types=["bool"],
488
+ decoder=bool,
489
+ )
490
+
491
+ def is_market_substrate_granted(
492
+ self, market: MarketId, substrate: bytes
493
+ ) -> Call[bool]:
494
+ """Whether the 32-byte ``substrate`` is granted on ``market``."""
495
+ if len(substrate) != 32:
496
+ raise ValueError(f"substrate must be 32 bytes, got {len(substrate)}")
497
+ return self._view(
498
+ "isMarketSubstrateGranted(uint256,bytes32)",
499
+ market,
500
+ substrate,
501
+ output_types=["bool"],
502
+ decoder=bool,
503
+ )
504
+
505
+ def is_markets_limits_activated(self) -> Call[bool]:
506
+ return self._view(
507
+ "isMarketsLimitsActivated()", output_types=["bool"], decoder=bool
508
+ )
509
+
510
+ def get_market_limit(self, market: MarketId) -> Call[int]:
511
+ """The most of the vault's total assets ``market`` may hold, as a WAD
512
+ share (``10**18`` is 100%), enforced only while limits are activated."""
513
+ return self._view(
514
+ "getMarketLimit(uint256)", market, output_types=["uint256"], decoder=int
515
+ )
516
+
517
+ def activate_markets_limits(self) -> Call[None]:
518
+ return self._write("activateMarketsLimits()")
519
+
520
+ def deactivate_markets_limits(self) -> Call[None]:
521
+ return self._write("deactivateMarketsLimits()")
522
+
523
+ def set_price_oracle_middleware(self, middleware: ChecksumAddress) -> Call[None]:
524
+ """The vault rejects a middleware whose quote currency differs from the
525
+ current one."""
526
+ return self._write("setPriceOracleMiddleware(address)", middleware)
527
+
528
+ def configure_performance_fee(
529
+ self, fee_account: ChecksumAddress, fee: Fee
530
+ ) -> Call[None]:
531
+ """``fee`` in percent with 2 decimals (10000 = 100%), as
532
+ `get_performance_fee_data` reports it."""
533
+ return self._write("configurePerformanceFee(address,uint256)", fee_account, fee)
534
+
535
+ def configure_management_fee(
536
+ self, fee_account: ChecksumAddress, fee: Fee
537
+ ) -> Call[None]:
538
+ """``fee`` in percent with 2 decimals (10000 = 100%), as
539
+ `get_management_fee_data` reports it."""
540
+ return self._write("configureManagementFee(address,uint256)", fee_account, fee)
541
+
542
+ def set_rewards_claim_manager_address(
543
+ self, rewards_claim_manager: ChecksumAddress
544
+ ) -> Call[None]:
545
+ return self._write(
546
+ "setRewardsClaimManagerAddress(address)", rewards_claim_manager
547
+ )
548
+
549
+ def enable_transfer_shares(self) -> Call[None]:
550
+ """Make share `transfer` and `transferFrom` public (PUBLIC_ROLE on both
551
+ selectors); only an access manager admin can map them back."""
552
+ return self._write("enableTransferShares()")
553
+
554
+ def set_minimal_execution_delays_for_roles(
555
+ self, delays: Sequence[tuple[RoleId | Roles, Period]]
556
+ ) -> Call[None]:
557
+ """The floor of each role's execution delay; the access manager refuses
558
+ to grant the role with a shorter one."""
559
+ return self._write(
560
+ "setMinimalExecutionDelaysForRoles(uint64[],uint256[])",
561
+ [role for role, _ in delays],
562
+ [delay for _, delay in delays],
563
+ )
564
+
406
565
  def convert_to_shares(self, amount: Amount) -> Call[Shares]:
407
566
  return self._view(
408
567
  "convertToShares(uint256)",
@@ -7,7 +7,7 @@ from web3.types import Timestamp
7
7
 
8
8
  from ipor_fusion.core.contract import Call, ContractWrapper
9
9
  from ipor_fusion.core.fuse_action import FuseAction
10
- from ipor_fusion.types import Amount, FuseAddress
10
+ from ipor_fusion.types import Amount, FuseAddress, Period
11
11
 
12
12
 
13
13
  @dataclass(slots=True)
@@ -76,3 +76,16 @@ class RewardsManager(ContractWrapper):
76
76
 
77
77
  def update_balance(self) -> Call[None]:
78
78
  return self._write("updateBalance()")
79
+
80
+ def transfer_vested_tokens_to_vault(self) -> Call[None]:
81
+ """Move the vested part (`balance_of`) to the vault; a no-op at zero."""
82
+ return self._write("transferVestedTokensToVault()")
83
+
84
+ def remove_reward_fuses(self, fuses: Sequence[FuseAddress]) -> Call[None]:
85
+ return self._write("removeRewardFuses(address[])", fuses)
86
+
87
+ def setup_vesting_time(self, vesting_time: Period) -> Call[None]:
88
+ """The vesting duration of claimed rewards. Mid-vesting it reverts
89
+ ``UnsafeVestingTime`` when the new duration would vest less than was
90
+ already transferred; `update_balance` first resets the curve."""
91
+ return self._write("setupVestingTime(uint256)", vesting_time)
@@ -72,6 +72,15 @@ class WithdrawManager(ContractWrapper):
72
72
  def update_withdraw_window(self, window: Period) -> Call[None]:
73
73
  return self._write("updateWithdrawWindow(uint256)", window)
74
74
 
75
+ def update_withdraw_fee(self, fee: Fee) -> Call[None]:
76
+ """The instant-exit fee, WAD (``10**18`` is 100%, above it reverts)."""
77
+ return self._write("updateWithdrawFee(uint256)", fee)
78
+
79
+ def update_request_fee(self, fee: Fee) -> Call[None]:
80
+ """The scheduled-exit fee charged on `request_shares`, WAD (``10**18``
81
+ is 100%, above it reverts)."""
82
+ return self._write("updateRequestFee(uint256)", fee)
83
+
75
84
  def update_plasma_vault_address(self, vault: PlasmaVaultAddress) -> Call[None]:
76
85
  return self._write("updatePlasmaVaultAddress(address)", vault)
77
86
 
@@ -119,22 +119,32 @@ Notes on the walk:
119
119
  so you recognise and avoid it. Verify against `ipor-abi` before use; the
120
120
  registry is the source of truth and is regenerated on release.
121
121
 
122
- | Chain | Chain id | `IporFusionFactoryProxy` (use) | `IporFusionFactoryImpl` (reverts) | Verified |
123
- |---|---|---|---|---|
124
- | Ethereum | 1 | `0xcd05909C4A1F8E501e4ED554cEF4Ed5E48D9b852` | `0xf19C1E9f6616F6056AF1e322A86fDaAaAf0263f5` | implementation slot |
125
- | Unichain | 130 | `0xC9b4E839e86284C558791C13Bda97999fc49aF63` | `0xf5Bc40C192D51ED93ADD6557884766772FA72589` | implementation slot |
126
- | TAC | 239 | `0x26b5561E2E0e7d7977431E92740903Ef3cB7194b` | `0x7DDd0bBB59eFB4b7791cE5E1Cf1587F083aE4Ef5` | implementation slot |
127
- | Botanix | 3637 | `0x7c9857f22D0cc6523C8e88BFDCbf411AB8300fF5` | `0xddb0EFB2a7a5C02e01b5A1f85C0a1110d68EeC26` | registry only |
128
- | Base | 8453 | `0x1455717668fA96534f675856347A973fA907e922` | `0x610152A79BE7F2Aa3aA70520c9331c18fe8D33b7` | clone executed on a fork |
129
- | Plasma | 9745 | `0x70d41759FBF90fB63c88197217cB08F93a1c65CB` | `0x3A42bD6fEa94421025Ae2ed01CE6f137ac785abD` | implementation slot |
130
- | Arbitrum | 42161 | `0x134fCAce7a2C7Ef3dF2479B62f03ddabAEa922d5` | `0x87f94ac9aF79261F0BC73582114f805F55Cd0b25` | clone executed on a fork |
131
- | Avalanche | 43114 | `0xa00b6379833D77fA9C9497b32dae00dF39Ac751e` | `0x399596cFccFEbBb60f8652bece8586a6Bb4199ab` | implementation slot |
132
- | Ink | 57073 | `0xEC53f69Bd1D991a2F99e96DE66E81D0E42A61D8D` | `0xe7372BC46b79e0c87AfE5286c41c20687018E425` | implementation slot |
133
- | Katana | 747474 | `0xc29b8D591d6a3f109Ca7ba384F2e00162866D37B` | `0x4a4De6e86AD0d0546F55B595cA75f55803D940bA` | registry only |
134
-
135
- "Implementation slot" means the proxy's EIP-1967 implementation slot was read
136
- and matches the registry's `IporFusionFactoryImpl`; "registry only" means the
137
- pair was taken from `ipor-abi` without an on-chain read.
122
+ | Chain | Chain id | `IporFusionFactoryProxy` (use) | `IporFusionFactoryImpl` (reverts) | Vault tooling | Verified |
123
+ |---|---|---|---|---|---|
124
+ | Ethereum | 1 | `0xcd05909C4A1F8E501e4ED554cEF4Ed5E48D9b852` | `0x14d120C365Debd920eaDf0a7AC31e659Bc58217b` | validated | implementation slot |
125
+ | Flare | 14 | `0xE75F3565D67645775351A9886F2b598f07d1860B` | `0x6C1ff6eBf5e92Dbc5591E7cCF455829De9C46579` | factory only | implementation slot |
126
+ | Unichain | 130 | `0xC9b4E839e86284C558791C13Bda97999fc49aF63` | `0x73c7CA802403BB21e9608C937c556C04d5eeBAD6` | validated | implementation slot |
127
+ | Monad | 143 | `0x62DFfe8bCaaf7960f858a4f7dDC83cc98F04cEDC` | `0x1017f0032460B3c8FBB92Bfd350F708Ff6229137` | validated | implementation slot |
128
+ | TAC | 239 | `0x26b5561E2E0e7d7977431E92740903Ef3cB7194b` | `0x7DDd0bBB59eFB4b7791cE5E1Cf1587F083aE4Ef5` | factory only | implementation slot |
129
+ | HyperEVM | 999 | `0x6bBc827F34b4e862d15215ABd4AC0E3886181665` | `0x010430cbdE2Bb8ACC48D7aDfbEb99812E83f1156` | validated | implementation slot |
130
+ | Botanix | 3637 | `0x7c9857f22D0cc6523C8e88BFDCbf411AB8300fF5` | `0xddb0EFB2a7a5C02e01b5A1f85C0a1110d68EeC26` | factory only | registry only |
131
+ | Robinhood | 4663 | `0xDF7A590b60072476E355A8EfF33e4872440bDc7C` | `0x9d897beA78F8747d8f9C45d5734089ca7225AE90` | validated | implementation slot |
132
+ | Base | 8453 | `0x1455717668fA96534f675856347A973fA907e922` | `0x378fEb2E96082FB965E2BB922AEE484d07c14014` | validated | implementation slot |
133
+ | Plasma | 9745 | `0x70d41759FBF90fB63c88197217cB08F93a1c65CB` | `0x346DA190c60d6101B77DA613a252c7aE25A7a120` | validated | implementation slot |
134
+ | Arbitrum | 42161 | `0x134fCAce7a2C7Ef3dF2479B62f03ddabAEa922d5` | `0x86C8Ea8800EB6bc8C846c3e0230178520a0ED721` | validated | implementation slot |
135
+ | Avalanche | 43114 | `0xa00b6379833D77fA9C9497b32dae00dF39Ac751e` | `0x0f358Bb3d14AB911dBfAF4d9061097e7F5Cf123F` | validated | implementation slot |
136
+ | Ink | 57073 | `0xEC53f69Bd1D991a2F99e96DE66E81D0E42A61D8D` | `0xEF774B9767cC9FC813A2b595BE870A13D5B367C0` | validated | implementation slot |
137
+ | Katana | 747474 | `0xc29b8D591d6a3f109Ca7ba384F2e00162866D37B` | `0x4a4De6e86AD0d0546F55B595cA75f55803D940bA` | validated | implementation slot |
138
+
139
+ A deployed factory is not the same as supported tooling. "Validated" chains are
140
+ `SUPPORTED_CHAIN_IDS` (`ipor_fusion.chains`): `fusion vault info`/`validate`
141
+ and `fetch_vault_data` run there. On a "factory only" chain `clone()` works,
142
+ but the vault tooling raises `UnsupportedChainError` until the chain is
143
+ validated. "Implementation slot" means the proxy's EIP-1967 implementation
144
+ slot was read on chain and matches the registry's `IporFusionFactoryImpl`;
145
+ "registry only" means the pair comes from `ipor-abi` without an on-chain read.
146
+ The factory implementations are upgraded in place, so the implementation
147
+ column changes with releases while the proxy stays.
138
148
 
139
149
  Fuse addresses are not in the SDK. Resolve them by registry name and chain
140
150
  in `ipor-abi` (`SupplyFuseAaveV3`, `BalanceFuseAaveV3`, ...), or with the