ipor-fusion 4.1.0.dev35__tar.gz → 4.1.0.dev38__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 (361) hide show
  1. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/PKG-INFO +1 -1
  2. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/pyproject.toml +1 -1
  3. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/oracle_mapping.py +26 -9
  4. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/vault_data.py +21 -3
  5. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_commands.py +36 -9
  6. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_oracle_mapping.py +20 -0
  7. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_vault_data_block.py +11 -1
  8. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.claude-plugin/marketplace.json +0 -0
  9. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.claude-plugin/plugin.json +0 -0
  10. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.env.example +0 -0
  11. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.gemini/settings.json +0 -0
  12. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.git-blame-ignore-revs +0 -0
  13. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.github/workflows/cd.yml +0 -0
  14. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.github/workflows/ci.yml +0 -0
  15. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.github/workflows/commit-lint.yml +0 -0
  16. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.github/workflows/notify-slack.yml +0 -0
  17. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.github/workflows/python-build.yml +0 -0
  18. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.github/workflows/python-publish.yml +0 -0
  19. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.github/workflows/release.yml +0 -0
  20. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.github/workflows/report-slack.yml +0 -0
  21. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.gitignore +0 -0
  22. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.mcp.json +0 -0
  23. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.pre-commit-config.yaml +0 -0
  24. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/.python-version +0 -0
  25. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/AGENTS.md +0 -0
  26. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/CHANGELOG.md +0 -0
  27. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/CLAUDE.md +0 -0
  28. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/CODEOWNERS +0 -0
  29. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/LICENSE +0 -0
  30. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/MIGRATION_4.md +0 -0
  31. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/README.md +0 -0
  32. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/build.sh +0 -0
  33. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/examples/CONTRIBUTING.md +0 -0
  34. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/examples/README.md +0 -0
  35. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/examples/advanced_euler_v2_credit_market_base.py +0 -0
  36. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/examples/advanced_euler_v2_looping_arbitrum.py +0 -0
  37. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +0 -0
  38. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/examples/external_state_margin_leg_base.py +0 -0
  39. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/examples/hypercore_vault_official_deployment_hyperevm.py +0 -0
  40. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/examples/simple_aave_v3_supply_base.py +0 -0
  41. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/pytest.ini +0 -0
  42. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/scripts/commit-check.sh +0 -0
  43. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/scripts/fusion_error_signatures.py +0 -0
  44. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/skills/ipor-deploy-vault/SKILL.md +0 -0
  45. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/__init__.py +0 -0
  46. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/about.py +0 -0
  47. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cache.py +0 -0
  48. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/chains.py +0 -0
  49. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cli/__init__.py +0 -0
  50. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cli/address_cmd.py +0 -0
  51. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
  52. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cli/config_cmd.py +0 -0
  53. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cli/config_store.py +0 -0
  54. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cli/main.py +0 -0
  55. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cli/market_cmd.py +0 -0
  56. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cli/options.py +0 -0
  57. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cli/oracle_mapping_view.py +0 -0
  58. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cli/preflight_cmd.py +0 -0
  59. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cli/vault_cmd.py +0 -0
  60. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cli/vault_health.py +0 -0
  61. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cli/vault_info_view.py +0 -0
  62. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
  63. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/cli/vault_rendering.py +0 -0
  64. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/config/__init__.py +0 -0
  65. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/config/roles.py +0 -0
  66. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/__init__.py +0 -0
  67. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/access.py +0 -0
  68. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/address.py +0 -0
  69. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/context.py +0 -0
  70. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/context_manager.py +0 -0
  71. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/contract.py +0 -0
  72. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/erc20.py +0 -0
  73. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/external_state_executor.py +0 -0
  74. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/fee_manager.py +0 -0
  75. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/fuse.py +0 -0
  76. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/fuse_action.py +0 -0
  77. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/fuse_decoding.py +0 -0
  78. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/fusion_factory.py +0 -0
  79. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/logs.py +0 -0
  80. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/multicall.py +0 -0
  81. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/oracle.py +0 -0
  82. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/plasma_vault.py +0 -0
  83. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/rewards_manager.py +0 -0
  84. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/simulation.py +0 -0
  85. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/simulation_result.py +0 -0
  86. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/core/withdraw_manager.py +0 -0
  87. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/__init__.py +0 -0
  88. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
  89. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/ccip/chainlink.py +0 -0
  90. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/ccip/codec.py +0 -0
  91. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/ccip/contracts.py +0 -0
  92. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
  93. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/ccip/indexer.py +0 -0
  94. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/ccip/lane.py +0 -0
  95. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/ccip/quote.py +0 -0
  96. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/ccip/transport.py +0 -0
  97. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/contracts.py +0 -0
  98. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/discovery.py +0 -0
  99. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/errors.py +0 -0
  100. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/fuses/__init__.py +0 -0
  101. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/fuses/base.py +0 -0
  102. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/fuses/ccip.py +0 -0
  103. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/fuses/stargate.py +0 -0
  104. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/lane.py +0 -0
  105. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/logs.py +0 -0
  106. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/messages.py +0 -0
  107. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/simulation.py +0 -0
  108. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
  109. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/stargate/contracts.py +0 -0
  110. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/stargate/lane.py +0 -0
  111. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/stargate/layerzero.py +0 -0
  112. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/stargate/transport.py +0 -0
  113. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/crosschain/transport.py +0 -0
  114. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/dependency_graph.py +0 -0
  115. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/entry_cli.py +0 -0
  116. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/entry_mcp.py +0 -0
  117. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/errors.py +0 -0
  118. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/explorer.py +0 -0
  119. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/field_docs.py +0 -0
  120. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/__init__.py +0 -0
  121. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/aave_v3.py +0 -0
  122. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/async_action.py +0 -0
  123. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/base.py +0 -0
  124. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/compound_v3.py +0 -0
  125. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/erc4626.py +0 -0
  126. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/euler_v2.py +0 -0
  127. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/events.py +0 -0
  128. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/external_state.py +0 -0
  129. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/external_state_event_decoding.py +0 -0
  130. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
  131. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
  132. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/hypercore.py +0 -0
  133. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/hypercore_event_decoding.py +0 -0
  134. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/hypercore_pre_hooks.py +0 -0
  135. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/merkl.py +0 -0
  136. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/morpho.py +0 -0
  137. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
  138. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
  139. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fuses/universal.py +0 -0
  140. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/fusion_errors.py +0 -0
  141. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/guide/__init__.py +0 -0
  142. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/guide/architecture.md +0 -0
  143. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/guide/glossary.md +0 -0
  144. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/guide/invariants.md +0 -0
  145. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/guide/quickstart.md +0 -0
  146. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/hypercore/__init__.py +0 -0
  147. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/market_ids.py +0 -0
  148. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/market_info.py +0 -0
  149. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/mcp/__init__.py +0 -0
  150. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/mcp/guide.py +0 -0
  151. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/mcp/models.py +0 -0
  152. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/mcp/server.py +0 -0
  153. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/morpho_api.py +0 -0
  154. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/preflight.py +0 -0
  155. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/py.typed +0 -0
  156. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/__init__.py +0 -0
  157. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/aave_v3.py +0 -0
  158. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/aave_v4.py +0 -0
  159. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/compound_v3.py +0 -0
  160. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/euler_v2.py +0 -0
  161. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/hypercore.py +0 -0
  162. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/hypercore_outcome.py +0 -0
  163. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/lending_health.py +0 -0
  164. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/morpho.py +0 -0
  165. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/oracle_mapping_nodes.py +0 -0
  166. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/oracle_mapping_reader.py +0 -0
  167. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/position_manager.py +0 -0
  168. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/ramses_v2.py +0 -0
  169. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
  170. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/readers/unpriceable.py +0 -0
  171. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/registry.py +0 -0
  172. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/substrates.py +0 -0
  173. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/types.py +0 -0
  174. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/validation.py +0 -0
  175. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/vault_erc20.py +0 -0
  176. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/vault_info.py +0 -0
  177. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/vault_managers.py +0 -0
  178. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/vault_positions.py +0 -0
  179. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/src/ipor_fusion/vault_reads.py +0 -0
  180. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/UniswapV3UniversalRouter.py +0 -0
  181. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_addresses.py +0 -0
  182. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_crosschain.py +0 -0
  183. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_crosschain_lifecycle.py +0 -0
  184. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_crosschain_recovery.py +0 -0
  185. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_euler_v2.py +0 -0
  186. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_event_args.py +0 -0
  187. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_fake_rpc.py +0 -0
  188. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_foundry.py +0 -0
  189. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_golden.py +0 -0
  190. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_guide.py +0 -0
  191. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_hypercore_model.py +0 -0
  192. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_hypercore_shadow.py +0 -0
  193. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_live.py +0 -0
  194. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_multicall.py +0 -0
  195. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_oracle_mapping_fake.py +0 -0
  196. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_simulate.py +0 -0
  197. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/_validation.py +0 -0
  198. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/addresses.py +0 -0
  199. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/conftest.py +0 -0
  200. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/constants.py +0 -0
  201. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/hypercore_hip3_flow.json +0 -0
  202. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/hypercore_market55.json +0 -0
  203. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/hypercore_official.json +0 -0
  204. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/market_golden/meta_morpho_v1.json +0 -0
  205. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/market_golden/meta_morpho_v1.mcp.json +0 -0
  206. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/market_golden/meta_morpho_v2.json +0 -0
  207. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/market_golden/meta_morpho_v2.mcp.json +0 -0
  208. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/market_golden/morpho_api/market.json +0 -0
  209. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/market_golden/morpho_api/vault_v1.json +0 -0
  210. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/market_golden/morpho_api/vault_v2.json +0 -0
  211. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/market_golden/morpho_api/vault_v2_not_found.json +0 -0
  212. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/market_golden/morpho_blue.json +0 -0
  213. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/market_golden/morpho_blue.mcp.json +0 -0
  214. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/market_golden/morpho_blue_api_error.json +0 -0
  215. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/market_golden/morpho_blue_api_error.mcp.json +0 -0
  216. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/market_golden/morpho_blue_no_api.json +0 -0
  217. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/market_golden/morpho_blue_no_api.mcp.json +0 -0
  218. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/oracle_mapping_golden/mapping.json +0 -0
  219. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/oracle_mapping_golden/mapping.mcp.json +0 -0
  220. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/simulate_v1_request.json +0 -0
  221. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/vault_info_golden/clean.json +0 -0
  222. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/vault_info_golden/clean.mcp.json +0 -0
  223. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/vault_info_golden/clean.txt +0 -0
  224. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/vault_info_golden/deployment_error.json +0 -0
  225. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/vault_info_golden/deployment_error.mcp.json +0 -0
  226. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/vault_info_golden/deployment_error.txt +0 -0
  227. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/vault_info_golden/fetched.cli.json +0 -0
  228. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/vault_info_golden/fetched.json +0 -0
  229. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/vault_info_golden/fetched.mcp.json +0 -0
  230. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/vault_info_golden/full.json +0 -0
  231. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/vault_info_golden/full.mcp.json +0 -0
  232. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/vault_info_golden/full.txt +0 -0
  233. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/vault_info_golden/rich.json +0 -0
  234. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/vault_info_golden/rich.mcp.json +0 -0
  235. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/fixtures/vault_info_golden/rich.txt +0 -0
  236. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_about.py +0 -0
  237. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_access_manager.py +0 -0
  238. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_addresses_helper.py +0 -0
  239. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cache.py +0 -0
  240. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_chains.py +0 -0
  241. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_address.py +0 -0
  242. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_changelog.py +0 -0
  243. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_config_store.py +0 -0
  244. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_helpers.py +0 -0
  245. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_hypercore.py +0 -0
  246. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_lending_health.py +0 -0
  247. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_market_golden.py +0 -0
  248. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_market_morpho_blue.py +0 -0
  249. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_mcp_parity.py +0 -0
  250. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_oracle_mapping.py +0 -0
  251. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_oracle_mapping_golden.py +0 -0
  252. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_pending_requests_scan.py +0 -0
  253. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_preflight.py +0 -0
  254. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_role_accounts.py +0 -0
  255. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_vault_info_golden.py +0 -0
  256. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_vault_predates_getters.py +0 -0
  257. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_cli_vault_validate.py +0 -0
  258. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_contract_call.py +0 -0
  259. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_contract_encoder.py +0 -0
  260. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_crosschain_ccip_events.py +0 -0
  261. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_crosschain_ccip_indexer.py +0 -0
  262. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_crosschain_ccip_quote.py +0 -0
  263. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_crosschain_chainlink.py +0 -0
  264. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_crosschain_contracts.py +0 -0
  265. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_crosschain_encoding.py +0 -0
  266. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_crosschain_errors.py +0 -0
  267. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_crosschain_lane.py +0 -0
  268. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_crosschain_layering.py +0 -0
  269. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_crosschain_transport.py +0 -0
  270. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_docs_typing.py +0 -0
  271. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_erc20.py +0 -0
  272. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_error_hierarchy.py +0 -0
  273. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_examples_crosschain.py +0 -0
  274. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_examples_euler_looping_arbitrum.py +0 -0
  275. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_examples_hypercore_hyperevm.py +0 -0
  276. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_examples_vaults.py +0 -0
  277. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_explorer.py +0 -0
  278. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_external_state_events.py +0 -0
  279. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_external_state_executor.py +0 -0
  280. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_fee_manager.py +0 -0
  281. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_fuse_decoding.py +0 -0
  282. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_fuse_encoding.py +0 -0
  283. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_fusion_errors.py +0 -0
  284. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_fusion_instance.py +0 -0
  285. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_governance_wrappers.py +0 -0
  286. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_guide.py +0 -0
  287. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_hypercore_deployment.py +0 -0
  288. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_hypercore_events.py +0 -0
  289. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_hypercore_flow.py +0 -0
  290. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_hypercore_live.py +0 -0
  291. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_hypercore_outcome.py +0 -0
  292. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_hypercore_pre_hooks.py +0 -0
  293. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_hypercore_readers.py +0 -0
  294. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_hypercore_simulation.py +0 -0
  295. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_logs.py +0 -0
  296. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_mcp_address.py +0 -0
  297. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_mcp_hypercore.py +0 -0
  298. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_mcp_models.py +0 -0
  299. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_mcp_preflight.py +0 -0
  300. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_mcp_server.py +0 -0
  301. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_mcp_vault_validate.py +0 -0
  302. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_multicall.py +0 -0
  303. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_oracle.py +0 -0
  304. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_plasma_vault.py +0 -0
  305. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_preflight.py +0 -0
  306. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_public_api.py +0 -0
  307. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_public_type_reachability.py +0 -0
  308. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_reader_encoding.py +0 -0
  309. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_registry.py +0 -0
  310. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_revert_decoding.py +0 -0
  311. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_rewards_manager.py +0 -0
  312. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_roles.py +0 -0
  313. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_sdk_layering.py +0 -0
  314. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
  315. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
  316. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_claim_morpho_rewards.py +0 -0
  317. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_crosschain_hyperevm.py +0 -0
  318. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_euler_v2_batch_base.py +0 -0
  319. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
  320. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
  321. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
  322. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
  323. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_examples_arbitrum.py +0 -0
  324. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_examples_base.py +0 -0
  325. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_examples_crosschain.py +0 -0
  326. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_examples_hyperevm.py +0 -0
  327. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_external_state_executor_base.py +0 -0
  328. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
  329. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_looping_aave_v3_base.py +0 -0
  330. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
  331. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_morpho_blue.py +0 -0
  332. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_pilot_v3.py +0 -0
  333. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
  334. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_pilot_v5_ramses.py +0 -0
  335. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
  336. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
  337. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_preflight_base.py +0 -0
  338. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_readers_integration.py +0 -0
  339. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_release_funds.py +0 -0
  340. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_swap_on_base.py +0 -0
  341. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_timelock_base.py +0 -0
  342. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulate_vault_from_scratch_base.py +0 -0
  343. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulation_errors.py +0 -0
  344. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_simulation_observation.py +0 -0
  345. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_solidity_compiler.py +0 -0
  346. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_solidity_mirrors.py +0 -0
  347. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_substrates.py +0 -0
  348. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_types_and_events.py +0 -0
  349. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_unpriceable_tokens.py +0 -0
  350. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_validation.py +0 -0
  351. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_vault_dep_graph.py +0 -0
  352. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_vault_info_fetched_golden.py +0 -0
  353. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_vault_info_onchain_base.py +0 -0
  354. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
  355. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_vault_reconciliation_onchain_base.py +0 -0
  356. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_vault_simulator_blocks.py +0 -0
  357. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_web3_context.py +0 -0
  358. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/test_withdraw_manager.py +0 -0
  359. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/typed_client/consumer.py +0 -0
  360. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/tests/typed_client/rejected.py +0 -0
  361. {ipor_fusion-4.1.0.dev35 → ipor_fusion-4.1.0.dev38}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ipor-fusion
3
- Version: 4.1.0.dev35
3
+ Version: 4.1.0.dev38
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.1.0.dev35"
3
+ version = "4.1.0.dev38"
4
4
  description = "The IPOR Fusion SDK for Python"
5
5
  authors = [
6
6
  { name = "Adam Mydlarz", email = "amydlarz@gmail.com" },
@@ -236,15 +236,32 @@ def _resolve_middleware_fallback(
236
236
  node.source_type = TYPE_MIDDLEWARE_FALLBACK
237
237
  node.status = "resolved"
238
238
  if underlying_middleware is not None:
239
- # Same asset, different oracle — must not be in `visited` yet; runaway
240
- # manager→manager chains are bounded by max_depth instead.
241
- dep = _resolve(
242
- reader.delegate(underlying_middleware),
243
- asset,
244
- depth + 1,
245
- visited,
246
- max_depth,
247
- )
239
+ # Same asset, different oracle: the asset key is not in `visited` yet,
240
+ # so the hop is keyed by (oracle, asset) — a manager chain that loops
241
+ # back ends as a cycle instead of running to max_depth.
242
+ hop = f"{underlying_middleware.lower()}/{asset.lower()}"
243
+ if hop in visited:
244
+ return _partial(
245
+ asset,
246
+ symbol,
247
+ decimals,
248
+ source,
249
+ TYPE_UNKNOWN,
250
+ "cycle_detected",
251
+ [label],
252
+ price,
253
+ )
254
+ visited.add(hop)
255
+ try:
256
+ dep = _resolve(
257
+ reader.delegate(underlying_middleware),
258
+ asset,
259
+ depth + 1,
260
+ visited,
261
+ max_depth,
262
+ )
263
+ finally:
264
+ visited.discard(hop)
248
265
  node.dependencies = [dep]
249
266
  # dep re-resolves the same asset, so drop its leading label from the path.
250
267
  node.path = [label, "middleware fallback", *dep.path[1:]]
@@ -312,7 +312,21 @@ def resolve_token_decimals(ctx: Web3Context, address: HexAddress) -> Decimals |
312
312
  return decimals
313
313
 
314
314
 
315
- def _block_timestamp(ctx: Web3Context, block: int) -> Timestamp:
315
+ def _latest_head(ctx: Web3Context) -> tuple[int, Timestamp]:
316
+ """The latest block's number and timestamp from one read.
317
+
318
+ Reading the head number first and the block by number second can reach a
319
+ node behind a load balancer that has not seen that block yet.
320
+ """
321
+ head = ctx.web3.eth.get_block("latest")
322
+ return head["number"], head["timestamp"]
323
+
324
+
325
+ def _block_timestamp(
326
+ ctx: Web3Context, block: int, known: Timestamp | None
327
+ ) -> Timestamp:
328
+ if known is not None:
329
+ return known
316
330
  return ctx.web3.eth.get_block(block)["timestamp"]
317
331
 
318
332
 
@@ -634,14 +648,18 @@ def fetch_vault_data(
634
648
  ensure_supported_chain(ctx.chain_id)
635
649
  if block is None:
636
650
  block = _pinned_default_block(ctx)
637
- resolved_block = ctx.web3.eth.block_number if block is None else block
638
651
  is_latest = block is None
652
+ head_timestamp: Timestamp | None = None
653
+ if block is None:
654
+ resolved_block, head_timestamp = _latest_head(ctx)
655
+ else:
656
+ resolved_block = block
639
657
  ctx = ctx.at_block(resolved_block)
640
658
  plasma_vault = PlasmaVault(vault)
641
659
  with ThreadPoolExecutor() as pool:
642
660
  # Independent pipelines, each a short chain of batched reads; none of
643
661
  # them waits on a pool future, so they cannot starve the pool.
644
- f_timestamp = pool.submit(_block_timestamp, ctx, resolved_block)
662
+ f_timestamp = pool.submit(_block_timestamp, ctx, resolved_block, head_timestamp)
645
663
  f_vault = pool.submit(_fetch_vault_reads, ctx, plasma_vault)
646
664
  f_fees = pool.submit(_fetch_fee_data, ctx, plasma_vault)
647
665
  f_withdraw = pool.submit(_fetch_withdraw_manager, ctx, plasma_vault)
@@ -443,7 +443,10 @@ class TestVaultInfo:
443
443
  mock_ctx.cache = NullCache()
444
444
  mock_ctx.web3.eth.block_number = 12345678
445
445
  mock_ctx.default_block = "latest"
446
- mock_ctx.web3.eth.get_block.return_value = {"timestamp": 1700000000}
446
+ mock_ctx.web3.eth.get_block.return_value = {
447
+ "number": 12345678,
448
+ "timestamp": 1700000000,
449
+ }
447
450
  mock_ctx.chain_id = 1
448
451
  mock_ctx.at_block.return_value = mock_ctx
449
452
  mock_ctx_cls.from_url.return_value = mock_ctx
@@ -573,7 +576,10 @@ class TestVaultInfo:
573
576
  mock_ctx.cache = NullCache()
574
577
  mock_ctx.web3.eth.block_number = 12345678
575
578
  mock_ctx.default_block = "latest"
576
- mock_ctx.web3.eth.get_block.return_value = {"timestamp": 1700000000}
579
+ mock_ctx.web3.eth.get_block.return_value = {
580
+ "number": 12345678,
581
+ "timestamp": 1700000000,
582
+ }
577
583
  mock_ctx.chain_id = 1
578
584
  mock_ctx.at_block.return_value = mock_ctx
579
585
  mock_ctx_cls.from_url.return_value = mock_ctx
@@ -654,7 +660,10 @@ class TestVaultInfo:
654
660
  mock_ctx.cache = NullCache()
655
661
  mock_ctx.web3.eth.block_number = 100
656
662
  mock_ctx.default_block = "latest"
657
- mock_ctx.web3.eth.get_block.return_value = {"timestamp": 1700000000}
663
+ mock_ctx.web3.eth.get_block.return_value = {
664
+ "number": 100,
665
+ "timestamp": 1700000000,
666
+ }
658
667
  mock_ctx.chain_id = 1
659
668
  mock_ctx.at_block.return_value = mock_ctx
660
669
  mock_ctx_cls.from_url.return_value = mock_ctx
@@ -723,7 +732,10 @@ class TestVaultInfo:
723
732
  mock_ctx.cache = NullCache()
724
733
  mock_ctx.web3.eth.block_number = 100
725
734
  mock_ctx.default_block = "latest"
726
- mock_ctx.web3.eth.get_block.return_value = {"timestamp": 1700000000}
735
+ mock_ctx.web3.eth.get_block.return_value = {
736
+ "number": 100,
737
+ "timestamp": 1700000000,
738
+ }
727
739
  mock_ctx.chain_id = 1
728
740
  mock_ctx.at_block.return_value = mock_ctx
729
741
  mock_ctx_cls.from_url.return_value = mock_ctx
@@ -804,7 +816,10 @@ class TestVaultInfo:
804
816
  mock_ctx.cache = NullCache()
805
817
  mock_ctx.web3.eth.block_number = 100
806
818
  mock_ctx.default_block = "latest"
807
- mock_ctx.web3.eth.get_block.return_value = {"timestamp": 1700000000}
819
+ mock_ctx.web3.eth.get_block.return_value = {
820
+ "number": 100,
821
+ "timestamp": 1700000000,
822
+ }
808
823
  mock_ctx.web3.eth.get_transaction.return_value = {"blockNumber": 18500000}
809
824
  mock_ctx.chain_id = 1
810
825
  mock_ctx.at_block.return_value = mock_ctx
@@ -875,7 +890,10 @@ class TestVaultInfo:
875
890
  mock_ctx.cache = NullCache()
876
891
  mock_ctx.web3.eth.block_number = 100
877
892
  mock_ctx.default_block = "latest"
878
- mock_ctx.web3.eth.get_block.return_value = {"timestamp": 1700000000}
893
+ mock_ctx.web3.eth.get_block.return_value = {
894
+ "number": 100,
895
+ "timestamp": 1700000000,
896
+ }
879
897
  mock_ctx.chain_id = 1
880
898
  mock_ctx.at_block.return_value = mock_ctx
881
899
  mock_ctx_cls.from_url.return_value = mock_ctx
@@ -986,7 +1004,10 @@ class TestVaultInfoJson:
986
1004
  mock_ctx.chain_id = 1
987
1005
  mock_ctx.web3.eth.block_number = 12345678
988
1006
  mock_ctx.default_block = "latest"
989
- mock_ctx.web3.eth.get_block.return_value = {"timestamp": 1700000000}
1007
+ mock_ctx.web3.eth.get_block.return_value = {
1008
+ "number": 12345678,
1009
+ "timestamp": 1700000000,
1010
+ }
990
1011
  mock_ctx.chain_id = 1
991
1012
  mock_ctx.at_block.return_value = mock_ctx
992
1013
  mock_ctx_cls.from_url.return_value = mock_ctx
@@ -1165,7 +1186,10 @@ class TestVaultInfoJson:
1165
1186
  mock_ctx.cache = NullCache()
1166
1187
  mock_ctx.web3.eth.block_number = 100
1167
1188
  mock_ctx.default_block = "latest"
1168
- mock_ctx.web3.eth.get_block.return_value = {"timestamp": 1700000000}
1189
+ mock_ctx.web3.eth.get_block.return_value = {
1190
+ "number": 100,
1191
+ "timestamp": 1700000000,
1192
+ }
1169
1193
  mock_ctx.web3.eth.get_transaction.return_value = {"blockNumber": 18500000}
1170
1194
  mock_ctx.chain_id = 1
1171
1195
  mock_ctx.at_block.return_value = mock_ctx
@@ -1246,7 +1270,10 @@ class TestVaultInfoJson:
1246
1270
  mock_ctx.cache = NullCache()
1247
1271
  mock_ctx.web3.eth.block_number = 100
1248
1272
  mock_ctx.default_block = "latest"
1249
- mock_ctx.web3.eth.get_block.return_value = {"timestamp": 1700000000}
1273
+ mock_ctx.web3.eth.get_block.return_value = {
1274
+ "number": 100,
1275
+ "timestamp": 1700000000,
1276
+ }
1250
1277
  mock_ctx.chain_id = 1
1251
1278
  mock_ctx.at_block.return_value = mock_ctx
1252
1279
  mock_ctx_cls.from_url.return_value = mock_ctx
@@ -636,6 +636,26 @@ class TestResolve:
636
636
  "chainlink_feed_registry": None,
637
637
  }
638
638
 
639
+ def test_manager_delegating_to_itself_ends_as_a_cycle(self):
640
+ r = FakeReader()
641
+ weth = addr(1)
642
+ mw = addr(0x51)
643
+ zero = Web3.to_checksum_address(om.ZERO_ADDRESS)
644
+ r.symbols[weth] = "WETH"
645
+ r.decimals[weth] = 18
646
+ r.sources[weth] = zero
647
+ r.prices[weth] = Price(asset=weth, amount=2_000 * 10**18, decimals=18)
648
+ r.underlying_mw = mw
649
+ r.delegated = r # the manager names itself as its underlying middleware
650
+
651
+ node = om.resolve_asset(r, weth, max_depth=50)
652
+
653
+ # one hop back to the same manager, not 50 down to max_depth
654
+ (dep,) = node.dependencies
655
+ assert dep.reason == "cycle_detected"
656
+ assert not dep.dependencies
657
+ assert node.status == "partially_resolved"
658
+
639
659
  def test_zero_underlying_middleware_treated_as_absent(self):
640
660
  r = FakeReader()
641
661
  asset = addr(1)
@@ -5,7 +5,7 @@ import pytest
5
5
  from ipor_fusion import Web3Context
6
6
  from ipor_fusion.cache import NullCache
7
7
  from ipor_fusion.types import ChainId
8
- from ipor_fusion.vault_data import _pinned_default_block
8
+ from ipor_fusion.vault_data import _latest_head, _pinned_default_block
9
9
 
10
10
 
11
11
  def _ctx() -> tuple[Web3Context, MagicMock]:
@@ -32,3 +32,13 @@ def test_tag_or_hash_resolves_to_its_number_once(tag: str):
32
32
  ctx, web3 = _ctx()
33
33
  assert _pinned_default_block(ctx.at_block(tag)) == 4242 # type: ignore[arg-type]
34
34
  web3.eth.get_block.assert_called_once_with(tag)
35
+
36
+
37
+ def test_latest_head_reads_number_and_timestamp_in_one_call():
38
+ # The head number and then get_block(number) can reach a node behind a
39
+ # load balancer that has not seen that block yet.
40
+ web3 = MagicMock()
41
+ web3.eth.get_block.return_value = {"number": 4242, "timestamp": 1_700_000_000}
42
+ ctx = Web3Context(web3, ChainId(1), cache=NullCache())
43
+ assert _latest_head(ctx) == (4242, 1_700_000_000)
44
+ web3.eth.get_block.assert_called_once_with("latest")