ipor-fusion 4.0.0.dev191__tar.gz → 4.0.0.dev194__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 (338) hide show
  1. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/MIGRATION_4.md +10 -0
  2. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/PKG-INFO +1 -1
  3. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/pyproject.toml +1 -1
  4. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/readers/lending_health.py +2 -9
  5. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/readers/morpho.py +26 -16
  6. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cli_lending_health.py +47 -21
  7. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_reader_encoding.py +11 -8
  8. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.claude-plugin/marketplace.json +0 -0
  9. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.claude-plugin/plugin.json +0 -0
  10. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.env.example +0 -0
  11. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.gemini/settings.json +0 -0
  12. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.git-blame-ignore-revs +0 -0
  13. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.github/workflows/cd.yml +0 -0
  14. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.github/workflows/ci.yml +0 -0
  15. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.github/workflows/commit-lint.yml +0 -0
  16. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.github/workflows/notify-slack.yml +0 -0
  17. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.github/workflows/python-build.yml +0 -0
  18. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.github/workflows/python-publish.yml +0 -0
  19. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.github/workflows/release.yml +0 -0
  20. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.github/workflows/report-slack.yml +0 -0
  21. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.gitignore +0 -0
  22. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.mcp.json +0 -0
  23. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.pre-commit-config.yaml +0 -0
  24. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/.python-version +0 -0
  25. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/AGENTS.md +0 -0
  26. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/CHANGELOG.md +0 -0
  27. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/CLAUDE.md +0 -0
  28. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/CODEOWNERS +0 -0
  29. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/LICENSE +0 -0
  30. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/README.md +0 -0
  31. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/build.sh +0 -0
  32. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/examples/CONTRIBUTING.md +0 -0
  33. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/examples/README.md +0 -0
  34. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/examples/advanced_euler_v2_credit_market_base.py +0 -0
  35. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/examples/advanced_euler_v2_looping_arbitrum.py +0 -0
  36. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/examples/composed_hypercore_flow_arbitrum_hyperevm.py +0 -0
  37. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +0 -0
  38. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/examples/external_state_margin_leg_base.py +0 -0
  39. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/examples/simple_aave_v3_supply_base.py +0 -0
  40. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/pytest.ini +0 -0
  41. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/scripts/commit-check.sh +0 -0
  42. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/scripts/crosschain_readiness.py +0 -0
  43. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/skills/ipor-deploy-vault/SKILL.md +0 -0
  44. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/__init__.py +0 -0
  45. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/about.py +0 -0
  46. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/cache.py +0 -0
  47. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/chains.py +0 -0
  48. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/cli/__init__.py +0 -0
  49. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
  50. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/cli/config_cmd.py +0 -0
  51. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/cli/config_store.py +0 -0
  52. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/cli/main.py +0 -0
  53. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/cli/market_cmd.py +0 -0
  54. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/cli/options.py +0 -0
  55. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/cli/oracle_mapping_view.py +0 -0
  56. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/cli/vault_cmd.py +0 -0
  57. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/cli/vault_health.py +0 -0
  58. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/cli/vault_info_view.py +0 -0
  59. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
  60. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/cli/vault_rendering.py +0 -0
  61. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/config/__init__.py +0 -0
  62. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/config/roles.py +0 -0
  63. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/__init__.py +0 -0
  64. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/access.py +0 -0
  65. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/address.py +0 -0
  66. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/context.py +0 -0
  67. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/contract.py +0 -0
  68. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/erc20.py +0 -0
  69. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/external_state_executor.py +0 -0
  70. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/fee_manager.py +0 -0
  71. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/fuse.py +0 -0
  72. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/fuse_action.py +0 -0
  73. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/fusion_factory.py +0 -0
  74. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/logs.py +0 -0
  75. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/multicall.py +0 -0
  76. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/oracle.py +0 -0
  77. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/plasma_vault.py +0 -0
  78. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/rewards_manager.py +0 -0
  79. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/simulation.py +0 -0
  80. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/simulation_result.py +0 -0
  81. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/core/withdraw_manager.py +0 -0
  82. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/__init__.py +0 -0
  83. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
  84. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/ccip/chainlink.py +0 -0
  85. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/ccip/codec.py +0 -0
  86. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/ccip/contracts.py +0 -0
  87. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
  88. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/ccip/indexer.py +0 -0
  89. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/ccip/lane.py +0 -0
  90. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/ccip/quote.py +0 -0
  91. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/ccip/transport.py +0 -0
  92. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/contracts.py +0 -0
  93. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/discovery.py +0 -0
  94. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/errors.py +0 -0
  95. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/fuses/__init__.py +0 -0
  96. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/fuses/base.py +0 -0
  97. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/fuses/ccip.py +0 -0
  98. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/fuses/stargate.py +0 -0
  99. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/lane.py +0 -0
  100. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/logs.py +0 -0
  101. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/messages.py +0 -0
  102. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/simulation.py +0 -0
  103. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
  104. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/stargate/contracts.py +0 -0
  105. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/stargate/lane.py +0 -0
  106. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/stargate/layerzero.py +0 -0
  107. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/stargate/transport.py +0 -0
  108. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/crosschain/transport.py +0 -0
  109. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/dependency_graph.py +0 -0
  110. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/entry_cli.py +0 -0
  111. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/entry_mcp.py +0 -0
  112. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/errors.py +0 -0
  113. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/explorer.py +0 -0
  114. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/field_docs.py +0 -0
  115. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/__init__.py +0 -0
  116. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/aave_v3.py +0 -0
  117. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/async_action.py +0 -0
  118. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/base.py +0 -0
  119. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/compound_v3.py +0 -0
  120. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/erc4626.py +0 -0
  121. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/euler_v2.py +0 -0
  122. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/events.py +0 -0
  123. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/external_state.py +0 -0
  124. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/external_state_event_decoding.py +0 -0
  125. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
  126. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
  127. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/hypercore.py +0 -0
  128. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/hypercore_event_decoding.py +0 -0
  129. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/merkl.py +0 -0
  130. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/morpho.py +0 -0
  131. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
  132. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
  133. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/fuses/universal.py +0 -0
  134. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/guide/__init__.py +0 -0
  135. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/guide/architecture.md +0 -0
  136. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/guide/glossary.md +0 -0
  137. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/guide/invariants.md +0 -0
  138. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/guide/quickstart.md +0 -0
  139. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/market_ids.py +0 -0
  140. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/market_info.py +0 -0
  141. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/mcp/__init__.py +0 -0
  142. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/mcp/guide.py +0 -0
  143. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/mcp/models.py +0 -0
  144. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/mcp/server.py +0 -0
  145. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/morpho_api.py +0 -0
  146. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/py.typed +0 -0
  147. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/readers/__init__.py +0 -0
  148. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/readers/aave_v3.py +0 -0
  149. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/readers/aave_v4.py +0 -0
  150. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/readers/compound_v3.py +0 -0
  151. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/readers/hypercore.py +0 -0
  152. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/readers/hypercore_outcome.py +0 -0
  153. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/readers/oracle_mapping.py +0 -0
  154. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/readers/oracle_mapping_nodes.py +0 -0
  155. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/readers/oracle_mapping_reader.py +0 -0
  156. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/readers/position_manager.py +0 -0
  157. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/readers/ramses_v2.py +0 -0
  158. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
  159. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/readers/unpriceable.py +0 -0
  160. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/substrates.py +0 -0
  161. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/types.py +0 -0
  162. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/validation.py +0 -0
  163. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/vault_data.py +0 -0
  164. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/vault_erc20.py +0 -0
  165. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/vault_info.py +0 -0
  166. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/vault_managers.py +0 -0
  167. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/vault_positions.py +0 -0
  168. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/src/ipor_fusion/vault_reads.py +0 -0
  169. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/UniswapV3UniversalRouter.py +0 -0
  170. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/_crosschain.py +0 -0
  171. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/_crosschain_lifecycle.py +0 -0
  172. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/_crosschain_recovery.py +0 -0
  173. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/_euler_v2.py +0 -0
  174. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/_event_args.py +0 -0
  175. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/_fake_rpc.py +0 -0
  176. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/_foundry.py +0 -0
  177. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/_golden.py +0 -0
  178. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/_guide.py +0 -0
  179. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/_hypercore_model.py +0 -0
  180. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/_hypercore_shadow.py +0 -0
  181. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/_multicall.py +0 -0
  182. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/_oracle_mapping_fake.py +0 -0
  183. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/_simulate.py +0 -0
  184. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/_validation.py +0 -0
  185. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/addresses.py +0 -0
  186. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/conftest.py +0 -0
  187. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/constants.py +0 -0
  188. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/hypercore_hip3_flow.json +0 -0
  189. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/hypercore_market55.json +0 -0
  190. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/market_golden/meta_morpho_v1.json +0 -0
  191. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/market_golden/meta_morpho_v1.mcp.json +0 -0
  192. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/market_golden/meta_morpho_v2.json +0 -0
  193. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/market_golden/meta_morpho_v2.mcp.json +0 -0
  194. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/market_golden/morpho_api/market.json +0 -0
  195. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/market_golden/morpho_api/vault_v1.json +0 -0
  196. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/market_golden/morpho_api/vault_v2.json +0 -0
  197. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/market_golden/morpho_api/vault_v2_not_found.json +0 -0
  198. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/market_golden/morpho_blue.json +0 -0
  199. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/market_golden/morpho_blue.mcp.json +0 -0
  200. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/market_golden/morpho_blue_api_error.json +0 -0
  201. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/market_golden/morpho_blue_api_error.mcp.json +0 -0
  202. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/market_golden/morpho_blue_no_api.json +0 -0
  203. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/market_golden/morpho_blue_no_api.mcp.json +0 -0
  204. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/oracle_mapping_golden/mapping.json +0 -0
  205. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/oracle_mapping_golden/mapping.mcp.json +0 -0
  206. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/simulate_v1_request.json +0 -0
  207. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/vault_info_golden/clean.json +0 -0
  208. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/vault_info_golden/clean.mcp.json +0 -0
  209. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/vault_info_golden/clean.txt +0 -0
  210. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/vault_info_golden/deployment_error.json +0 -0
  211. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/vault_info_golden/deployment_error.mcp.json +0 -0
  212. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/vault_info_golden/deployment_error.txt +0 -0
  213. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/vault_info_golden/fetched.cli.json +0 -0
  214. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/vault_info_golden/fetched.json +0 -0
  215. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/vault_info_golden/fetched.mcp.json +0 -0
  216. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/vault_info_golden/full.json +0 -0
  217. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/vault_info_golden/full.mcp.json +0 -0
  218. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/vault_info_golden/full.txt +0 -0
  219. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/vault_info_golden/rich.json +0 -0
  220. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/vault_info_golden/rich.mcp.json +0 -0
  221. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/fixtures/vault_info_golden/rich.txt +0 -0
  222. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_about.py +0 -0
  223. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_access_manager.py +0 -0
  224. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cache.py +0 -0
  225. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_chains.py +0 -0
  226. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cli_changelog.py +0 -0
  227. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cli_commands.py +0 -0
  228. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cli_config_store.py +0 -0
  229. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cli_helpers.py +0 -0
  230. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cli_hypercore.py +0 -0
  231. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cli_market_golden.py +0 -0
  232. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cli_market_morpho_blue.py +0 -0
  233. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cli_oracle_mapping.py +0 -0
  234. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cli_oracle_mapping_golden.py +0 -0
  235. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cli_pending_requests_scan.py +0 -0
  236. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cli_role_accounts.py +0 -0
  237. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cli_vault_info_golden.py +0 -0
  238. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cli_vault_predates_getters.py +0 -0
  239. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_cli_vault_validate.py +0 -0
  240. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_contract_call.py +0 -0
  241. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_contract_encoder.py +0 -0
  242. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_crosschain_ccip_events.py +0 -0
  243. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_crosschain_ccip_indexer.py +0 -0
  244. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_crosschain_ccip_quote.py +0 -0
  245. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_crosschain_chainlink.py +0 -0
  246. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_crosschain_contracts.py +0 -0
  247. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_crosschain_encoding.py +0 -0
  248. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_crosschain_errors.py +0 -0
  249. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_crosschain_lane.py +0 -0
  250. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_crosschain_layering.py +0 -0
  251. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_crosschain_readiness.py +0 -0
  252. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_crosschain_readiness_report.py +0 -0
  253. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_crosschain_transport.py +0 -0
  254. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_docs_typing.py +0 -0
  255. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_erc20.py +0 -0
  256. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_error_hierarchy.py +0 -0
  257. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_examples_composed_hypercore.py +0 -0
  258. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_examples_crosschain.py +0 -0
  259. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_examples_euler_looping_arbitrum.py +0 -0
  260. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_examples_vaults.py +0 -0
  261. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_explorer.py +0 -0
  262. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_external_state_events.py +0 -0
  263. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_external_state_executor.py +0 -0
  264. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_fee_manager.py +0 -0
  265. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_fuse_encoding.py +0 -0
  266. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_fusion_instance.py +0 -0
  267. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_guide.py +0 -0
  268. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_hypercore_deployment.py +0 -0
  269. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_hypercore_events.py +0 -0
  270. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_hypercore_flow.py +0 -0
  271. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_hypercore_live.py +0 -0
  272. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_hypercore_outcome.py +0 -0
  273. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_hypercore_readers.py +0 -0
  274. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_hypercore_simulation.py +0 -0
  275. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_logs.py +0 -0
  276. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_mcp_hypercore.py +0 -0
  277. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_mcp_models.py +0 -0
  278. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_mcp_server.py +0 -0
  279. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_mcp_vault_validate.py +0 -0
  280. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_multicall.py +0 -0
  281. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_oracle.py +0 -0
  282. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_oracle_mapping.py +0 -0
  283. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_plasma_vault.py +0 -0
  284. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_public_api.py +0 -0
  285. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_public_type_reachability.py +0 -0
  286. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_readiness_selection.py +0 -0
  287. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_revert_decoding.py +0 -0
  288. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_rewards_manager.py +0 -0
  289. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_roles.py +0 -0
  290. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_sdk_layering.py +0 -0
  291. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
  292. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
  293. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_claim_morpho_rewards.py +0 -0
  294. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_crosschain_canary.py +0 -0
  295. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_crosschain_hypercore.py +0 -0
  296. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_crosschain_hyperevm.py +0 -0
  297. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_crosschain_lifecycle.py +0 -0
  298. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_euler_v2_batch_base.py +0 -0
  299. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
  300. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
  301. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
  302. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
  303. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_examples_arbitrum.py +0 -0
  304. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_examples_base.py +0 -0
  305. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_examples_crosschain.py +0 -0
  306. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_external_state_executor_base.py +0 -0
  307. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
  308. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_looping_aave_v3_base.py +0 -0
  309. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
  310. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_morpho_blue.py +0 -0
  311. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_pilot_v3.py +0 -0
  312. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
  313. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_pilot_v5_ramses.py +0 -0
  314. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
  315. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
  316. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_readers_integration.py +0 -0
  317. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_release_funds.py +0 -0
  318. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_swap_on_base.py +0 -0
  319. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulate_vault_from_scratch_base.py +0 -0
  320. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulation_errors.py +0 -0
  321. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_simulation_observation.py +0 -0
  322. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_solidity_compiler.py +0 -0
  323. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_solidity_mirrors.py +0 -0
  324. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_substrates.py +0 -0
  325. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_types_and_events.py +0 -0
  326. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_unpriceable_tokens.py +0 -0
  327. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_validation.py +0 -0
  328. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_vault_data_block.py +0 -0
  329. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_vault_dep_graph.py +0 -0
  330. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_vault_info_fetched_golden.py +0 -0
  331. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_vault_info_onchain_base.py +0 -0
  332. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
  333. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_vault_simulator_blocks.py +0 -0
  334. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_web3_context.py +0 -0
  335. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/test_withdraw_manager.py +0 -0
  336. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/typed_client/consumer.py +0 -0
  337. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/tests/typed_client/rejected.py +0 -0
  338. {ipor_fusion-4.0.0.dev191 → ipor_fusion-4.0.0.dev194}/uv.lock +0 -0
@@ -950,6 +950,16 @@ and `log_index` was passed through as given (a hex string from a raw log); the e
950
950
  These apply to every caller, type-checked or not. Changes described in full above
951
951
  are listed with a link.
952
952
 
953
+ - **Morpho shares convert to assets as Morpho Blue does.** The position breakdown
954
+ (`MorphoReader.read_position_breakdown`, the `vault info` Morpho rows) and the Morpho
955
+ lending health follow `SharesMathLib`: integer math with 1e6 virtual shares and one
956
+ virtual asset, borrow rounded up, supply rounded down, on the market totals Morpho
957
+ stores (interest accrued since the market's last update is not included). 3.x
958
+ converted borrow shares by dividing by `total_shares + 1` in floating point and
959
+ supply shares without the virtual offsets, so large positions lost their low digits
960
+ and small or empty markets could be off by orders of magnitude: expect materially
961
+ different numbers where they were wrong.
962
+
953
963
  - **MCP `outputSchema` describes every nested block.** The tool output is
954
964
  byte-identical; the schemas of `vault_info`, `vault_oracle_mapping`,
955
965
  `market_morpho_blue` and `market_meta_morpho` replace each free-form object with
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ipor-fusion
3
- Version: 4.0.0.dev191
3
+ Version: 4.0.0.dev194
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ipor-fusion"
3
- version = "4.0.0.dev191"
3
+ version = "4.0.0.dev194"
4
4
  description = "The IPOR Fusion SDK for Python"
5
5
  authors = [
6
6
  { name = "Adam Mydlarz", email = "amydlarz@gmail.com" },
@@ -7,7 +7,6 @@ for lending positions held by Plasma Vaults.
7
7
  from __future__ import annotations
8
8
 
9
9
  import logging
10
- import math
11
10
  from concurrent.futures import ThreadPoolExecutor
12
11
  from dataclasses import dataclass
13
12
 
@@ -24,6 +23,7 @@ from ipor_fusion.readers.aave_v4 import AaveV4OracleReader, AaveV4SpokeReader
24
23
  from ipor_fusion.readers.morpho import (
25
24
  MorphoReader,
26
25
  morpho_blue_address,
26
+ to_assets_up,
27
27
  )
28
28
  from ipor_fusion.substrates import decode_substrate, market_name
29
29
  from ipor_fusion.types import (
@@ -145,13 +145,6 @@ def _call_morpho_oracle_price(ctx: Web3Context, oracle_address: ChecksumAddress)
145
145
  return price
146
146
 
147
147
 
148
- def _shares_to_assets_up(shares: int, total_assets: int, total_shares: int) -> int:
149
- """Convert shares to assets, rounding up (Morpho convention)."""
150
- if total_shares == 0:
151
- return shares
152
- return math.ceil(shares * (total_assets + 1) / (total_shares + 1))
153
-
154
-
155
148
  def _compute_morpho_market_health(
156
149
  ctx: Web3Context,
157
150
  reader: MorphoReader,
@@ -197,7 +190,7 @@ def _compute_morpho_market_health(
197
190
  _logger.debug("Failed to read Morpho oracle price for %s", morpho_market_id)
198
191
  return None
199
192
 
200
- borrowed = _shares_to_assets_up(
193
+ borrowed = to_assets_up(
201
194
  position.borrow_shares, market.total_borrow_assets, market.total_borrow_shares
202
195
  )
203
196
 
@@ -62,6 +62,26 @@ def morpho_blue_address(chain_id: ChainId) -> ChecksumAddress:
62
62
  )
63
63
 
64
64
 
65
+ # Morpho Blue's SharesMathLib: virtual shares and assets offset every
66
+ # conversion, so a market's first depositor cannot inflate the share price.
67
+ VIRTUAL_SHARES = 10**6
68
+ VIRTUAL_ASSETS = 1
69
+
70
+
71
+ def to_assets_down(shares: int, total_assets: int, total_shares: int) -> Amount:
72
+ """``SharesMathLib.toAssetsDown``: supply shares to assets, rounded down."""
73
+ return Amount(
74
+ shares * (total_assets + VIRTUAL_ASSETS) // (total_shares + VIRTUAL_SHARES)
75
+ )
76
+
77
+
78
+ def to_assets_up(shares: int, total_assets: int, total_shares: int) -> Amount:
79
+ """``SharesMathLib.toAssetsUp``: borrow shares to assets, rounded up."""
80
+ numerator = shares * (total_assets + VIRTUAL_ASSETS)
81
+ denominator = total_shares + VIRTUAL_SHARES
82
+ return Amount((numerator + denominator - 1) // denominator)
83
+
84
+
65
85
  @dataclass(slots=True)
66
86
  class MorphoMarket:
67
87
  """On-chain state of a Morpho Blue lending market."""
@@ -206,22 +226,12 @@ class MorphoReader(ContractWrapper):
206
226
  params_read = batch.add(self.market_params(market_id))
207
227
  batch.run()
208
228
  pos, market, params = pos_read.value, market_read.value, params_read.value
209
- if market.total_borrow_shares > 0:
210
- borrow_assets = math.ceil(
211
- pos.borrow_shares
212
- * (market.total_borrow_assets + 1)
213
- / (market.total_borrow_shares + 1)
214
- )
215
- else:
216
- borrow_assets = 0
217
- if market.total_supply_shares > 0:
218
- supply_assets = (
219
- pos.supply_shares
220
- * market.total_supply_assets
221
- // market.total_supply_shares
222
- )
223
- else:
224
- supply_assets = 0
229
+ borrow_assets = to_assets_up(
230
+ pos.borrow_shares, market.total_borrow_assets, market.total_borrow_shares
231
+ )
232
+ supply_assets = to_assets_down(
233
+ pos.supply_shares, market.total_supply_assets, market.total_supply_shares
234
+ )
225
235
  return MorphoPositionBreakdown(
226
236
  market_id=market_id,
227
237
  loan_token=params.loan_token,
@@ -22,10 +22,14 @@ from ipor_fusion.readers.lending_health import (
22
22
  _compute_aave_market_health,
23
23
  _compute_aave_v4_market_health,
24
24
  _compute_morpho_market_health,
25
- _shares_to_assets_up,
26
25
  fetch_vault_lending_health,
27
26
  )
28
- from ipor_fusion.readers.morpho import MorphoReader, morpho_blue_address
27
+ from ipor_fusion.readers.morpho import (
28
+ MorphoReader,
29
+ morpho_blue_address,
30
+ to_assets_down,
31
+ to_assets_up,
32
+ )
29
33
  from ipor_fusion.types import ChainId, MorphoBlueMarketId
30
34
 
31
35
  VAULT_ADDR = Web3.to_checksum_address("0x1111111111111111111111111111111111111111")
@@ -100,22 +104,44 @@ def _aave_account_data(health_factor_wad: int) -> bytes:
100
104
  )
101
105
 
102
106
 
103
- # ── shares_to_assets_up ──────────────────────────────────────────────
104
-
105
-
106
- class TestSharesToAssetsUp:
107
- def test_zero_shares(self):
108
- assert _shares_to_assets_up(0, 1000, 1000) == 0
107
+ # ── SharesMathLib ─────────────────────────────────────────────────────
109
108
 
110
- def test_zero_total_shares(self):
111
- assert _shares_to_assets_up(100, 1000, 0) == 100
109
+ # Vectors worked by hand from Morpho Blue's SharesMathLib (VIRTUAL_SHARES = 1e6,
110
+ # VIRTUAL_ASSETS = 1): toAssetsDown = shares * (assets + 1) / (shares_total + 1e6)
111
+ # rounded down, toAssetsUp the same rounded up (mulDivUp).
112
112
 
113
- def test_rounds_up(self):
114
- # 100 * (1001) / (1001) = 100, but with non-round: 3 * 1001 / 4 = 750.75 → 751
115
- assert _shares_to_assets_up(3, 1000, 3) == 751
116
113
 
117
- def test_exact_division(self):
118
- assert _shares_to_assets_up(500, 1000, 1000) == 500
114
+ class TestSharesMath:
115
+ def test_zero_shares(self):
116
+ assert to_assets_up(0, 1000, 1000) == 0
117
+ assert to_assets_down(0, 1000, 1000) == 0
118
+
119
+ def test_an_empty_market_still_divides_by_the_virtual_shares(self):
120
+ # 100 * 1001 / 1_000_000 = 0.1001
121
+ assert to_assets_up(100, 1000, 0) == 1
122
+ assert to_assets_down(100, 1000, 0) == 0
123
+
124
+ def test_a_tiny_pool_is_dominated_by_the_virtual_shares(self):
125
+ # 3 * 1001 / 1_000_003 = 0.003003
126
+ assert to_assets_up(3, 1000, 3) == 1
127
+ assert to_assets_down(3, 1000, 3) == 0
128
+
129
+ def test_realistic_share_scale_converts_back_to_assets(self):
130
+ # Shares minted at 1e6 per asset, then 250 assets of interest:
131
+ # 500e6 * 1_500_251 / (1.5e12 + 1e6) = 500.0833..., so up 501, down 500.
132
+ assert to_assets_up(500 * 10**6, 1_500_250, 1_500_000 * 10**6) == 501
133
+ assert to_assets_down(500 * 10**6, 1_500_250, 1_500_000 * 10**6) == 500
134
+
135
+ def test_large_values_keep_integer_precision(self):
136
+ # shares / total_shares = 1 / 1000 of 987654321987654321987 assets (+1):
137
+ # 987654321987654321.988 before the virtual-share correction, so the
138
+ # exact results straddle ...321 / ...322; a float division loses the
139
+ # last two digits (it gave 987654321987654272).
140
+ shares = 123456789123456789123456789
141
+ total_shares = shares * 1000
142
+ assets = 987654321987654321987
143
+ assert to_assets_up(shares, assets, total_shares) == 987654321987654322
144
+ assert to_assets_down(shares, assets, total_shares) == 987654321987654321
119
145
 
120
146
 
121
147
  # ── LendingMarketHealth properties ───────────────────────────────────
@@ -290,8 +316,8 @@ class TestComputeMorphoMarketHealth:
290
316
  reader, ctx = _make_morpho_reader()
291
317
 
292
318
  # 50% LTV scenario:
293
- # borrow_shares=500, total_borrow_assets=1000, total_borrow_shares=1000
294
- # → borrowed ≈ 500
319
+ # borrow_shares=500e6, total_borrow_assets=1000, total_borrow_shares=1000e6
320
+ # (Morpho mints 1e6 shares per asset) → borrowed = 500
295
321
  # collateral=1000, oracle_price=1e36 (1:1 price)
296
322
  # → collateral_value = 1000
297
323
  # → current_ltv = 500/1000 = 0.5
@@ -300,11 +326,11 @@ class TestComputeMorphoMarketHealth:
300
326
  ctx.call.side_effect = sequenced(
301
327
  [
302
328
  # position
303
- encode(["uint256", "uint128", "uint128"], [0, 500, 1000]),
329
+ encode(["uint256", "uint128", "uint128"], [0, 500 * 10**6, 1000]),
304
330
  # market
305
331
  encode(
306
332
  ["uint128", "uint128", "uint128", "uint128", "uint128", "uint128"],
307
- [2000, 2000, 1000, 1000, 1700000000, 0],
333
+ [2000, 2000 * 10**6, 1000, 1000 * 10**6, 1700000000, 0],
308
334
  ),
309
335
  # market_params
310
336
  encode(
@@ -336,10 +362,10 @@ class TestComputeMorphoMarketHealth:
336
362
  # borrowed ≈ 830, collateral=1000, oracle_price=1e36
337
363
  ctx.call.side_effect = sequenced(
338
364
  [
339
- encode(["uint256", "uint128", "uint128"], [0, 830, 1000]),
365
+ encode(["uint256", "uint128", "uint128"], [0, 830 * 10**6, 1000]),
340
366
  encode(
341
367
  ["uint128", "uint128", "uint128", "uint128", "uint128", "uint128"],
342
- [2000, 2000, 1000, 1000, 1700000000, 0],
368
+ [2000, 2000 * 10**6, 1000, 1000 * 10**6, 1700000000, 0],
343
369
  ),
344
370
  encode(
345
371
  ["address", "address", "address", "address", "uint256"],
@@ -320,13 +320,15 @@ class TestAaveV3FuseReaderPool:
320
320
  class TestMorphoReaderPositionBreakdown:
321
321
  def test_position_breakdown_converts_shares_to_assets(self):
322
322
  reader, ctx = _make_reader(MorphoReader)
323
- # position(): supply_shares=1000, borrow_shares=500, collateral=42
324
- position_raw = encode(["uint256", "uint128", "uint128"], [1000, 500, 42])
325
- # market(): supply_assets=2_000_000, supply_shares=2_000_000,
326
- # borrow_assets=1_500_000, borrow_shares=1_500_000
323
+ # position(): supply_shares=1000e6, borrow_shares=500e6, collateral=42
324
+ position_raw = encode(
325
+ ["uint256", "uint128", "uint128"], [1000 * 10**6, 500 * 10**6, 42]
326
+ )
327
+ # market(): supply 2_000_100 assets / 2_000_000e6 shares,
328
+ # borrow 1_500_250 assets / 1_500_000e6 shares (accrued interest)
327
329
  market_raw = encode(
328
330
  ["uint128", "uint128", "uint128", "uint128", "uint128", "uint128"],
329
- [2_000_000, 2_000_000, 1_500_000, 1_500_000, 1700000000, 0],
331
+ [2_000_100, 2_000_000 * 10**6, 1_500_250, 1_500_000 * 10**6, 1700000000, 0],
330
332
  )
331
333
  params_raw = encode(
332
334
  ["address", "address", "address", "address", "uint256"],
@@ -341,9 +343,10 @@ class TestMorphoReaderPositionBreakdown:
341
343
  assert result.loan_token == TOKEN_A
342
344
  assert result.collateral_token == TOKEN_B
343
345
  assert result.collateral == 42
344
- # borrow_assets = ceil(500 * (1_500_000+1) / (1_500_000+1)) = 500
345
- assert result.borrow_assets == 500
346
- # supply_assets = 1000 * 2_000_000 // 2_000_000 = 1000
346
+ # SharesMathLib.toAssetsUp: ceil(500e6 * 1_500_251 / (1_500_000e6 + 1e6))
347
+ # = ceil(500.0833...) = 501
348
+ assert result.borrow_assets == 501
349
+ # toAssetsDown: 1000e6 * 2_000_101 // (2_000_000e6 + 1e6) = 1000 (1000.0495...)
347
350
  assert result.supply_assets == 1000
348
351
 
349
352
  def test_position_breakdown_handles_empty_market(self):