@layerzerolabs/protocol-stellar-v2 0.2.21 → 0.2.23

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 (328) hide show
  1. package/.turbo/turbo-build.log +347 -271
  2. package/.turbo/turbo-lint.log +277 -208
  3. package/.turbo/turbo-test.log +1700 -1370
  4. package/Cargo.lock +22 -51
  5. package/Cargo.toml +6 -1
  6. package/contracts/common-macros/src/auth.rs +10 -9
  7. package/contracts/common-macros/src/contract_ttl.rs +1 -4
  8. package/contracts/common-macros/src/error.rs +1 -3
  9. package/contracts/common-macros/src/lib.rs +65 -61
  10. package/contracts/common-macros/src/storage.rs +212 -65
  11. package/contracts/common-macros/src/tests/auth.rs +75 -6
  12. package/contracts/common-macros/src/tests/contract_ttl.rs +383 -350
  13. package/contracts/common-macros/src/tests/error.rs +9 -21
  14. package/contracts/common-macros/src/tests/lz_contract.rs +80 -0
  15. package/contracts/common-macros/src/tests/mod.rs +2 -0
  16. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +20 -3
  17. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +28 -1
  18. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contractimpl_code.snap +8 -43
  19. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contracttrait_code.snap +6 -29
  20. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__lz_contract__snapshot_generated_lz_contract_code.snap +31 -0
  21. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_extendable__snapshot_generated_ttl_extendable_code.snap +8 -0
  22. package/contracts/common-macros/src/tests/storage/extract_fields.rs +87 -0
  23. package/contracts/common-macros/src/tests/storage/gen_accessor_methods.rs +223 -0
  24. package/contracts/common-macros/src/tests/storage/gen_args.rs +65 -0
  25. package/contracts/common-macros/src/tests/storage/gen_enum_variant.rs +78 -0
  26. package/contracts/common-macros/src/tests/storage/gen_key.rs +108 -0
  27. package/contracts/common-macros/src/tests/storage/gen_params.rs +105 -0
  28. package/contracts/common-macros/src/tests/{storage.rs → storage/generate_storage.rs} +54 -129
  29. package/contracts/common-macros/src/tests/storage/is_primitive_type.rs +48 -0
  30. package/contracts/common-macros/src/tests/storage/mod.rs +16 -0
  31. package/contracts/common-macros/src/tests/storage/parse_default.rs +164 -0
  32. package/contracts/common-macros/src/tests/storage/parse_name.rs +159 -0
  33. package/contracts/common-macros/src/tests/storage/parse_no_ttl_extension.rs +124 -0
  34. package/contracts/common-macros/src/tests/storage/parse_storage_type.rs +174 -0
  35. package/contracts/common-macros/src/tests/storage/snapshots/common_macros__tests__storage__generate_storage__snapshot_generated_storage_code.snap +412 -0
  36. package/contracts/common-macros/src/tests/storage/storage_kind.rs +39 -0
  37. package/contracts/common-macros/src/tests/storage/test_setup.rs +25 -0
  38. package/contracts/common-macros/src/tests/storage/validate_attrs.rs +138 -0
  39. package/contracts/common-macros/src/tests/storage/variant_config.rs +226 -0
  40. package/contracts/common-macros/src/tests/test_helpers.rs +4 -10
  41. package/contracts/common-macros/src/tests/ttl_configurable.rs +2 -2
  42. package/contracts/common-macros/src/tests/ttl_extendable.rs +32 -0
  43. package/contracts/common-macros/src/tests/upgradeable.rs +118 -2
  44. package/contracts/common-macros/src/ttl_configurable.rs +1 -4
  45. package/contracts/common-macros/src/upgradeable.rs +21 -3
  46. package/contracts/endpoint-v2/Cargo.toml +0 -4
  47. package/contracts/endpoint-v2/src/endpoint_v2.rs +37 -17
  48. package/contracts/endpoint-v2/src/errors.rs +26 -1
  49. package/contracts/endpoint-v2/src/interfaces/layerzero_endpoint_v2.rs +1 -1
  50. package/contracts/endpoint-v2/src/interfaces/message_lib_manager.rs +4 -4
  51. package/contracts/endpoint-v2/src/interfaces/messaging_composer.rs +2 -2
  52. package/contracts/endpoint-v2/src/lib.rs +0 -1
  53. package/contracts/endpoint-v2/src/message_lib_manager.rs +39 -8
  54. package/contracts/endpoint-v2/src/messaging_channel.rs +36 -4
  55. package/contracts/endpoint-v2/src/messaging_composer.rs +18 -4
  56. package/contracts/endpoint-v2/src/storage.rs +9 -1
  57. package/contracts/endpoint-v2/src/tests/endpoint_setup.rs +2 -2
  58. package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +1 -1
  59. package/contracts/endpoint-v2/src/tests/endpoint_v2/require_oapp_auth.rs +2 -2
  60. package/contracts/endpoint-v2/src/tests/message_lib_manager/register_library.rs +3 -3
  61. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_receive_lib_for_eid.rs +5 -5
  62. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_registered.rs +2 -2
  63. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_send_lib_for_eid.rs +5 -5
  64. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_supported_eid.rs +3 -3
  65. package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +1 -1
  66. package/contracts/endpoint-v2/src/tests/messaging_composer/clear_compose.rs +4 -3
  67. package/contracts/endpoint-v2/src/tests/messaging_composer/lz_compose_alert.rs +7 -2
  68. package/contracts/endpoint-v2/src/tests/messaging_composer/mod.rs +4 -0
  69. package/contracts/endpoint-v2/src/tests/messaging_composer/send_compose.rs +7 -2
  70. package/contracts/layerzero-views/src/layerzero_view.rs +0 -1
  71. package/contracts/layerzero-views/src/tests/mod.rs +1 -0
  72. package/contracts/layerzero-views/src/tests/types_tests.rs +31 -0
  73. package/contracts/layerzero-views/src/types.rs +2 -3
  74. package/contracts/macro-integration-tests/tests/runtime/contract_ttl/constructor.rs +61 -0
  75. package/contracts/macro-integration-tests/tests/runtime/contract_ttl/contract_impl_ttl_extension.rs +97 -0
  76. package/contracts/macro-integration-tests/tests/runtime/contract_ttl/contract_trait_ttl_extension.rs +99 -0
  77. package/contracts/macro-integration-tests/tests/runtime/contract_ttl/mod.rs +3 -0
  78. package/contracts/macro-integration-tests/tests/runtime/lz_contract/mod.rs +5 -0
  79. package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_default.rs +86 -0
  80. package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_multisig.rs +47 -0
  81. package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_multisig_upgradeable.rs +77 -0
  82. package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_upgradeable.rs +114 -0
  83. package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_upgradeable_no_migration.rs +105 -0
  84. package/contracts/macro-integration-tests/tests/runtime/multisig/admin_entrypoints.rs +242 -0
  85. package/contracts/macro-integration-tests/tests/runtime/multisig/mod.rs +9 -0
  86. package/contracts/macro-integration-tests/tests/runtime/multisig/self_auth.rs +54 -0
  87. package/contracts/macro-integration-tests/tests/runtime/ownable/initialization.rs +13 -0
  88. package/contracts/macro-integration-tests/tests/runtime/ownable/mod.rs +1 -0
  89. package/contracts/macro-integration-tests/tests/runtime/ownable/ownership_transfer.rs +70 -1
  90. package/contracts/macro-integration-tests/tests/runtime/ownable/two_step_transfer.rs +219 -0
  91. package/contracts/macro-integration-tests/tests/runtime/storage/keyed_roundtrip.rs +41 -0
  92. package/contracts/macro-integration-tests/tests/runtime/storage/ttl_extension.rs +48 -16
  93. package/contracts/macro-integration-tests/tests/runtime/storage/unkeyed_roundtrip.rs +10 -0
  94. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/configuration.rs +96 -3
  95. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/freeze.rs +4 -0
  96. package/contracts/macro-integration-tests/tests/runtime/ttl_extendable/extend_instance_ttl.rs +64 -0
  97. package/contracts/macro-integration-tests/tests/runtime/ttl_extendable/mod.rs +16 -0
  98. package/contracts/macro-integration-tests/tests/runtime/upgradeable/migrate_guard_and_state.rs +305 -0
  99. package/contracts/macro-integration-tests/tests/runtime/upgradeable/mod.rs +3 -0
  100. package/contracts/macro-integration-tests/tests/runtime/upgradeable/no_migration.rs +59 -0
  101. package/contracts/macro-integration-tests/tests/runtime/upgradeable/upgrade_then_migrate.rs +88 -0
  102. package/contracts/macro-integration-tests/tests/runtime.rs +5 -0
  103. package/contracts/macro-integration-tests/tests/ui/contract_impl/fail/not_impl_item.rs +6 -0
  104. package/contracts/macro-integration-tests/tests/ui/contract_impl/fail/not_impl_item.stderr +7 -0
  105. package/contracts/macro-integration-tests/tests/ui/contract_impl/pass/basic.rs +102 -0
  106. package/contracts/macro-integration-tests/tests/ui/contract_trait/fail/not_a_trait.rs +6 -0
  107. package/contracts/macro-integration-tests/tests/ui/contract_trait/fail/not_a_trait.stderr +7 -0
  108. package/contracts/macro-integration-tests/tests/ui/contract_trait/pass/basic.rs +83 -0
  109. package/contracts/macro-integration-tests/tests/ui/error/fail/discriminant_too_large.rs +11 -0
  110. package/contracts/macro-integration-tests/tests/ui/error/fail/discriminant_too_large.stderr +7 -0
  111. package/contracts/macro-integration-tests/tests/ui/error/fail/non_enum_input.rs +11 -0
  112. package/contracts/macro-integration-tests/tests/ui/error/fail/non_enum_input.stderr +7 -0
  113. package/contracts/macro-integration-tests/tests/ui/error/pass/basic.rs +22 -0
  114. package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/invalid_option.rs +6 -0
  115. package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/invalid_option.stderr +7 -0
  116. package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/multisig_rejects_ownable_api.rs +20 -0
  117. package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/multisig_rejects_ownable_api.stderr +20 -0
  118. package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/not_a_struct.rs +8 -0
  119. package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/not_a_struct.stderr +7 -0
  120. package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_invalid_inner_option.rs +10 -0
  121. package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_invalid_inner_option.stderr +7 -0
  122. package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_missing_internal.rs +20 -0
  123. package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_missing_internal.stderr +86 -0
  124. package/contracts/macro-integration-tests/tests/ui/lz_contract/pass/basic.rs +45 -0
  125. package/contracts/macro-integration-tests/tests/ui/lz_contract/pass/multisig.rs +34 -0
  126. package/contracts/macro-integration-tests/tests/ui/lz_contract/pass/multisig_upgradeable.rs +30 -0
  127. package/contracts/macro-integration-tests/tests/ui/lz_contract/pass/upgradeable.rs +39 -0
  128. package/contracts/macro-integration-tests/tests/ui/lz_contract/pass/upgradeable_no_migration.rs +28 -0
  129. package/contracts/macro-integration-tests/tests/ui/multisig/fail/non_struct_input.rs +8 -0
  130. package/contracts/macro-integration-tests/tests/ui/multisig/fail/non_struct_input.stderr +7 -0
  131. package/contracts/macro-integration-tests/tests/ui/multisig/fail/rejects_ownable_api.rs +20 -0
  132. package/contracts/macro-integration-tests/tests/ui/multisig/fail/rejects_ownable_api.stderr +12 -0
  133. package/contracts/macro-integration-tests/tests/ui/multisig/fail/rejects_ownable_trait.rs +20 -0
  134. package/contracts/macro-integration-tests/tests/ui/multisig/fail/rejects_ownable_trait.stderr +5 -0
  135. package/contracts/macro-integration-tests/tests/ui/multisig/pass/basic.rs +49 -0
  136. package/contracts/macro-integration-tests/tests/ui/ownable/fail/non_struct_input.rs +8 -0
  137. package/contracts/macro-integration-tests/tests/ui/ownable/fail/non_struct_input.stderr +7 -0
  138. package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_auth.rs +19 -0
  139. package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_auth.stderr +12 -0
  140. package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_env.rs +1 -1
  141. package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_env.stderr +0 -8
  142. package/contracts/macro-integration-tests/tests/ui/ownable/pass/basic.rs +39 -0
  143. package/contracts/macro-integration-tests/tests/ui/ownable/pass/only_auth_env_param_variants.rs +7 -1
  144. package/contracts/macro-integration-tests/tests/ui/storage/fail/invalid_storage_type_param.stderr +1 -1
  145. package/contracts/macro-integration-tests/tests/ui/storage/fail/missing_storage_type_param.stderr +1 -1
  146. package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_default_values.rs +11 -0
  147. package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_default_values.stderr +7 -0
  148. package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_name_attrs.rs +11 -0
  149. package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_name_attrs.stderr +7 -0
  150. package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_no_ttl_extension.rs +11 -0
  151. package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_no_ttl_extension.stderr +7 -0
  152. package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_type_params.stderr +1 -1
  153. package/contracts/macro-integration-tests/tests/ui/storage/fail/no_ttl_extension_rejects_args.rs +13 -0
  154. package/contracts/macro-integration-tests/tests/ui/storage/fail/no_ttl_extension_rejects_args.stderr +7 -0
  155. package/contracts/macro-integration-tests/tests/ui/storage/pass/api_surface.rs +102 -0
  156. package/contracts/macro-integration-tests/tests/ui/storage/pass/basic.rs +43 -0
  157. package/contracts/macro-integration-tests/tests/ui/storage/pass/multi_key.rs +38 -0
  158. package/contracts/macro-integration-tests/tests/ui/ttl_configurable/fail/missing_auth_trait.rs +14 -0
  159. package/contracts/macro-integration-tests/tests/ui/ttl_configurable/fail/missing_auth_trait.stderr +71 -0
  160. package/contracts/macro-integration-tests/tests/ui/ttl_configurable/fail/non_struct_input.rs +8 -0
  161. package/contracts/macro-integration-tests/tests/ui/ttl_configurable/fail/non_struct_input.stderr +7 -0
  162. package/contracts/macro-integration-tests/tests/ui/ttl_configurable/pass/{minimal_contract.rs → basic.rs} +2 -0
  163. package/contracts/macro-integration-tests/tests/ui/ttl_configurable/pass/multisig_contract.rs +28 -0
  164. package/contracts/macro-integration-tests/tests/ui/ttl_configurable/pass/ownable_contract.rs +32 -0
  165. package/contracts/macro-integration-tests/tests/ui/ttl_extendable/fail/non_struct_input.rs +8 -0
  166. package/contracts/macro-integration-tests/tests/ui/ttl_extendable/fail/non_struct_input.stderr +7 -0
  167. package/contracts/macro-integration-tests/tests/ui/ttl_extendable/pass/basic.rs +23 -0
  168. package/contracts/macro-integration-tests/tests/ui/ttl_extendable/pass/no_user_contractimpl.rs +21 -0
  169. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/attr_args.rs +11 -0
  170. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/attr_args.stderr +29 -0
  171. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_auth_trait.rs +20 -0
  172. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_auth_trait.stderr +71 -0
  173. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_upgradeable_internal.rs +10 -0
  174. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_upgradeable_internal.stderr +79 -0
  175. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/non_struct_input.rs +8 -0
  176. package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/non_struct_input.stderr +7 -0
  177. package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/basic.rs +43 -0
  178. package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/multisig_contract.rs +35 -0
  179. package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/no_migration.rs +30 -0
  180. package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/no_user_contractimpl.rs +29 -0
  181. package/contracts/macro-integration-tests/tests/ui_contract_impl.rs +12 -0
  182. package/contracts/macro-integration-tests/tests/ui_contract_trait.rs +12 -0
  183. package/contracts/macro-integration-tests/tests/ui_lz_contract.rs +11 -0
  184. package/contracts/macro-integration-tests/tests/ui_multisig.rs +11 -0
  185. package/contracts/macro-integration-tests/tests/ui_ttl_extendable.rs +12 -0
  186. package/contracts/macro-integration-tests/tests/ui_upgradeable.rs +11 -0
  187. package/contracts/message-libs/blocked-message-lib/Cargo.toml +1 -1
  188. package/contracts/message-libs/blocked-message-lib/src/lib.rs +4 -1
  189. package/contracts/message-libs/blocked-message-lib/src/tests/blocked_message_lib_tests.rs +108 -0
  190. package/contracts/message-libs/blocked-message-lib/src/tests/mod.rs +4 -0
  191. package/contracts/message-libs/blocked-message-lib/src/tests/setup.rs +40 -0
  192. package/contracts/message-libs/simple-message-lib/src/lib.rs +1 -1
  193. package/contracts/message-libs/simple-message-lib/src/tests/mod.rs +2 -0
  194. package/contracts/message-libs/simple-message-lib/src/tests/setup.rs +124 -0
  195. package/contracts/message-libs/simple-message-lib/src/tests/simple_message_lib_tests.rs +309 -0
  196. package/contracts/message-libs/uln-302/src/errors.rs +21 -0
  197. package/contracts/message-libs/uln-302/src/interfaces/receive_uln.rs +1 -1
  198. package/contracts/message-libs/uln-302/src/receive_uln.rs +6 -4
  199. package/contracts/message-libs/uln-302/src/send_uln.rs +15 -6
  200. package/contracts/message-libs/uln-302/src/storage.rs +5 -5
  201. package/contracts/message-libs/uln-302/src/tests/uln302/get_config.rs +71 -0
  202. package/contracts/message-libs/uln-302/src/tests/uln302/mod.rs +1 -0
  203. package/contracts/message-libs/uln-302/src/uln302.rs +3 -0
  204. package/contracts/oapps/counter/Cargo.toml +2 -0
  205. package/contracts/oapps/counter/integration_tests/mod.rs +1 -0
  206. package/contracts/oapps/counter/integration_tests/setup_sml.rs +6 -4
  207. package/contracts/oapps/counter/integration_tests/setup_uln.rs +12 -5
  208. package/contracts/oapps/counter/integration_tests/test_with_blocked.rs +67 -0
  209. package/contracts/oapps/counter/src/tests/mod.rs +1 -0
  210. package/contracts/oapps/counter/src/tests/test_u256_ext.rs +48 -0
  211. package/contracts/oapps/oapp/src/lib.rs +0 -3
  212. package/contracts/oapps/oapp/src/tests/mod.rs +1 -0
  213. package/contracts/oapps/oft/integration-tests/setup.rs +2 -3
  214. package/contracts/oapps/oft/src/lib.rs +3 -0
  215. package/contracts/oapps/oft/src/tests/extensions/mod.rs +3 -0
  216. package/contracts/oapps/oft/src/tests/extensions/oft_fee.rs +240 -0
  217. package/contracts/oapps/oft/src/tests/extensions/pausable.rs +141 -0
  218. package/contracts/oapps/oft/src/tests/extensions/rate_limiter.rs +447 -0
  219. package/contracts/oapps/oft/src/tests/mod.rs +2 -0
  220. package/contracts/oapps/oft/src/tests/oft_types/lock_unlock.rs +180 -0
  221. package/contracts/oapps/oft/src/tests/oft_types/mod.rs +1 -0
  222. package/contracts/oapps/oft-core/integration-tests/setup.rs +2 -3
  223. package/contracts/oapps/oft-core/src/lib.rs +2 -2
  224. package/contracts/oapps/oft-core/src/tests/mod.rs +1 -1
  225. package/contracts/oapps/oft-core/src/tests/{test_oft_version.rs → test_oft_version_and_approval.rs} +9 -0
  226. package/contracts/oapps/oft-core/src/tests/test_utils.rs +0 -43
  227. package/contracts/upgrader/src/tests/test_upgrader.rs +18 -0
  228. package/contracts/utils/src/auth.rs +2 -2
  229. package/contracts/utils/src/buffer_reader.rs +61 -10
  230. package/contracts/utils/src/buffer_writer.rs +35 -20
  231. package/contracts/utils/src/bytes_ext.rs +1 -2
  232. package/contracts/utils/src/errors.rs +5 -3
  233. package/contracts/utils/src/multisig.rs +59 -36
  234. package/contracts/utils/src/option_ext.rs +3 -3
  235. package/contracts/utils/src/ownable.rs +12 -6
  236. package/contracts/utils/src/tests/auth.rs +179 -0
  237. package/contracts/utils/src/tests/buffer_reader.rs +203 -1
  238. package/contracts/utils/src/tests/buffer_writer.rs +176 -5
  239. package/contracts/utils/src/tests/mod.rs +2 -0
  240. package/contracts/utils/src/tests/multisig.rs +170 -141
  241. package/contracts/utils/src/tests/option_ext.rs +1 -1
  242. package/contracts/utils/src/tests/ownable.rs +156 -161
  243. package/contracts/utils/src/tests/test_helper.rs +21 -1
  244. package/contracts/utils/src/tests/testing_utils.rs +84 -2
  245. package/contracts/utils/src/tests/ttl_configurable.rs +66 -86
  246. package/contracts/utils/src/tests/ttl_extendable.rs +64 -0
  247. package/contracts/utils/src/tests/upgradeable.rs +115 -6
  248. package/contracts/utils/src/ttl_configurable.rs +22 -12
  249. package/contracts/utils/src/ttl_extendable.rs +1 -3
  250. package/contracts/utils/src/upgradeable.rs +21 -24
  251. package/contracts/workers/dvn/src/auth.rs +1 -1
  252. package/contracts/workers/dvn/src/interfaces/dvn.rs +2 -2
  253. package/contracts/workers/dvn/src/storage.rs +1 -1
  254. package/contracts/workers/dvn/src/tests/auth.rs +136 -3
  255. package/contracts/workers/dvn/src/tests/mod.rs +0 -1
  256. package/contracts/workers/dvn/src/tests/setup.rs +4 -10
  257. package/contracts/workers/executor-helper/src/tests/executor_helper.rs +279 -0
  258. package/contracts/workers/executor-helper/src/tests/setup.rs +106 -1
  259. package/contracts/workers/worker/src/worker.rs +1 -1
  260. package/docs/oft-guide.md +5 -5
  261. package/package.json +5 -7
  262. package/sdk/.turbo/turbo-test.log +662 -466
  263. package/sdk/LICENSE +23 -0
  264. package/sdk/dist/generated/bml.d.ts +101 -106
  265. package/sdk/dist/generated/bml.js +108 -26
  266. package/sdk/dist/generated/counter.d.ts +123 -484
  267. package/sdk/dist/generated/counter.js +103 -25
  268. package/sdk/dist/generated/dvn.d.ts +141 -699
  269. package/sdk/dist/generated/dvn.js +106 -28
  270. package/sdk/dist/generated/dvn_fee_lib.d.ts +31 -248
  271. package/sdk/dist/generated/dvn_fee_lib.js +27 -24
  272. package/sdk/dist/generated/endpoint.d.ts +158 -836
  273. package/sdk/dist/generated/endpoint.js +107 -29
  274. package/sdk/dist/generated/executor.d.ts +139 -671
  275. package/sdk/dist/generated/executor.js +106 -28
  276. package/sdk/dist/generated/executor_fee_lib.d.ts +109 -264
  277. package/sdk/dist/generated/executor_fee_lib.js +106 -28
  278. package/sdk/dist/generated/executor_helper.d.ts +95 -92
  279. package/sdk/dist/generated/executor_helper.js +103 -25
  280. package/sdk/dist/generated/layerzero_view.d.ts +178 -335
  281. package/sdk/dist/generated/layerzero_view.js +172 -33
  282. package/sdk/dist/generated/oft.d.ts +137 -680
  283. package/sdk/dist/generated/oft.js +103 -25
  284. package/sdk/dist/generated/price_feed.d.ts +45 -444
  285. package/sdk/dist/generated/price_feed.js +27 -24
  286. package/sdk/dist/generated/sml.d.ts +119 -428
  287. package/sdk/dist/generated/sml.js +103 -25
  288. package/sdk/dist/generated/treasury.d.ts +109 -288
  289. package/sdk/dist/generated/treasury.js +103 -25
  290. package/sdk/dist/generated/uln302.d.ts +190 -527
  291. package/sdk/dist/generated/uln302.js +170 -31
  292. package/sdk/dist/generated/upgrader.d.ts +14 -34
  293. package/sdk/dist/generated/upgrader.js +24 -21
  294. package/sdk/package.json +3 -4
  295. package/sdk/test/counter-sml.test.ts +218 -142
  296. package/sdk/test/counter-uln.test.ts +189 -145
  297. package/sdk/test/oft-sml.test.ts +173 -156
  298. package/sdk/test/suites/constants.ts +7 -1
  299. package/sdk/test/suites/globalSetup.ts +140 -74
  300. package/sdk/turbo.json +1 -1
  301. package/tools/ts-bindings-gen/Cargo.toml +4 -4
  302. package/tools/ts-bindings-gen/src/main.rs +4 -0
  303. package/turbo.json +3 -0
  304. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__storage__snapshot_generated_storage_code.snap +0 -1072
  305. package/contracts/endpoint-v2/src/constants.rs +0 -52
  306. package/contracts/macro-integration-tests/tests/ui/error/fail/attr_not_empty.rs +0 -12
  307. package/contracts/macro-integration-tests/tests/ui/error/fail/attr_not_empty.stderr +0 -7
  308. package/contracts/macro-integration-tests/tests/ui/error/pass/attr_on_variant_allowed.rs +0 -20
  309. package/contracts/macro-integration-tests/tests/ui/error/pass/basic_auto_discriminants.rs +0 -15
  310. package/contracts/macro-integration-tests/tests/ui/error/pass/mixed_discriminants.rs +0 -16
  311. package/contracts/macro-integration-tests/tests/ui/ownable/pass/minimal_contract.rs +0 -26
  312. package/contracts/macro-integration-tests/tests/ui/ownable/pass/namespacing_and_imports.rs +0 -21
  313. package/contracts/macro-integration-tests/tests/ui/storage/fail/storage_attr_rejects_args.rs +0 -12
  314. package/contracts/macro-integration-tests/tests/ui/storage/fail/storage_attr_rejects_args.stderr +0 -7
  315. package/contracts/macro-integration-tests/tests/ui/storage/pass/default_value_on_variant.rs +0 -14
  316. package/contracts/macro-integration-tests/tests/ui/storage/pass/enum_instance_unit_basic.rs +0 -14
  317. package/contracts/macro-integration-tests/tests/ui/storage/pass/enum_persistent_named_fields_keyed.rs +0 -16
  318. package/contracts/macro-integration-tests/tests/ui/storage/pass/enum_temporary_unit_option.rs +0 -15
  319. package/contracts/macro-integration-tests/tests/ui/storage/pass/name_override.rs +0 -14
  320. package/contracts/macro-integration-tests/tests/ui/storage/pass/no_auto_ttl_extension.rs +0 -19
  321. package/contracts/macro-integration-tests/tests/ui/storage/pass/ttl_provider_basic.rs +0 -15
  322. package/contracts/message-libs/simple-message-lib/src/test.rs +0 -280
  323. package/contracts/oapps/oapp/src/macro_tests/mod.rs +0 -1
  324. package/contracts/workers/dvn/src/tests/multisig/mod.rs +0 -3
  325. package/contracts/workers/dvn/src/tests/multisig/set_signer.rs +0 -132
  326. package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +0 -109
  327. package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +0 -106
  328. /package/contracts/oapps/oapp/src/{macro_tests → tests}/test_macros.rs +0 -0
@@ -536,11 +536,6 @@ impl<'a> OFTTestSetupBuilder<'a> {
536
536
  self
537
537
  }
538
538
 
539
- pub fn mint_burn(mut self) -> Self {
540
- self.oft_type = OFTType::MintBurn;
541
- self
542
- }
543
-
544
539
  pub fn lock_unlock(mut self) -> Self {
545
540
  self.oft_type = OFTType::LockUnlock;
546
541
  self
@@ -552,11 +547,6 @@ impl<'a> OFTTestSetupBuilder<'a> {
552
547
  self
553
548
  }
554
549
 
555
- pub fn with_contract_token(mut self) -> Self {
556
- self.token_type = TokenType::ContractToken;
557
- self
558
- }
559
-
560
550
  pub fn build(self) -> OFTTestSetup<'a> {
561
551
  let env = self.env;
562
552
  let native_fee = self.native_fee;
@@ -655,16 +645,6 @@ impl<'a> OFTTestSetup<'a> {
655
645
  OFTTestSetupBuilder::new(env).build()
656
646
  }
657
647
 
658
- /// Create a builder for customized test setup
659
- pub fn builder(env: &'a Env) -> OFTTestSetupBuilder<'a> {
660
- OFTTestSetupBuilder::new(env)
661
- }
662
-
663
- /// Returns true if this setup uses a MintBurn OFT
664
- pub fn is_mint_burn(&self) -> bool {
665
- self.oft_type == OFTType::MintBurn
666
- }
667
-
668
648
  /// Returns true if this setup uses a LockUnlock OFT
669
649
  pub fn is_lock_unlock(&self) -> bool {
670
650
  self.oft_type == OFTType::LockUnlock
@@ -886,27 +866,4 @@ impl<'a> OFTTestSetup<'a> {
886
866
  LayerZeroReceiverClient::new(self.env, &self.oft.address)
887
867
  .lz_receive(executor, origin, guid, message, extra_data, &value);
888
868
  }
889
-
890
- /// Try lz_receive with proper executor authentication (returns Result)
891
- pub fn try_lz_receive(
892
- &self,
893
- executor: &Address,
894
- origin: &Origin,
895
- guid: &BytesN<32>,
896
- message: &Bytes,
897
- extra_data: &Bytes,
898
- value: i128,
899
- ) -> Result<Result<(), soroban_sdk::ConversionError>, Result<soroban_sdk::Error, soroban_sdk::InvokeError>> {
900
- self.env.mock_auths(&[MockAuth {
901
- address: executor,
902
- invoke: &MockAuthInvoke {
903
- contract: &self.oft.address,
904
- fn_name: "lz_receive",
905
- args: (executor, origin, guid, message, extra_data, value).into_val(self.env),
906
- sub_invokes: &[],
907
- },
908
- }]);
909
- LayerZeroReceiverClient::new(self.env, &self.oft.address)
910
- .try_lz_receive(executor, origin, guid, message, extra_data, &value)
911
- }
912
869
  }
@@ -127,3 +127,21 @@ fn test_upgrade_with_upgrader() {
127
127
 
128
128
  assert_eq!(client_v2.counter2(), counter_value);
129
129
  }
130
+
131
+ #[test]
132
+ fn test_upgrade_without_migration_data_returns_error_for_non_unit_migration() {
133
+ let e = Env::default();
134
+ e.mock_all_auths_allowing_non_root_auth();
135
+
136
+ let owner = Address::generate(&e);
137
+ let contract_id = e.register(contract_v1::WASM, (&owner,));
138
+
139
+ let upgrader = e.register(Upgrader, ());
140
+ let upgrader_client = UpgraderClient::new(&e, &upgrader);
141
+
142
+ let new_wasm_hash = install_new_wasm(&e);
143
+ // The upgradeable WASM fixture requires non-unit migration data (u32).
144
+ // `Upgrader::upgrade` always passes empty `()` migration bytes, so this must fail.
145
+ let res = upgrader_client.try_upgrade(&contract_id, &new_wasm_hash);
146
+ assert_eq!(res.err().unwrap().unwrap(), utils::errors::UpgradeableError::InvalidMigrationData.into());
147
+ }
@@ -12,13 +12,13 @@ use soroban_sdk::{contractclient, Address, Env};
12
12
  /// Base trait for authorization.
13
13
  ///
14
14
  /// Provides the authorizer address for owner-protected operations. This trait
15
- /// is implemented by both `Ownable` (external owner) and `Multisig` (self-owning).
15
+ /// is implemented by both `Ownable` (external owner) and `MultiSig` (self-owning).
16
16
  #[contractclient(name = "AuthClient")]
17
17
  pub trait Auth: Sized {
18
18
  /// Returns the address that authorizes owner-protected operations.
19
19
  ///
20
20
  /// For `Ownable` contracts, this returns the stored owner address.
21
- /// For `Multisig` contracts, this returns the contract's own address
21
+ /// For `MultiSig` contracts, this returns the contract's own address
22
22
  /// (self-owning pattern).
23
23
  fn authorizer(env: &Env) -> Address;
24
24
  }
@@ -1,19 +1,27 @@
1
- use soroban_sdk::{
2
- address_payload::AddressPayload, assert_with_error, panic_with_error, Address, Bytes, BytesN, Env, U256,
3
- };
4
-
5
1
  use crate::{
6
2
  buffer_writer::{ACCOUNT_PAYLOAD_TYPE, CONTRACT_PAYLOAD_TYPE},
7
3
  bytes_ext::BytesExt,
8
4
  errors::BufferReaderError,
9
5
  };
6
+ use core::mem;
7
+ use soroban_sdk::{
8
+ address_payload::AddressPayload, assert_with_error, panic_with_error, Address, Bytes, BytesN, Env, I256, U256,
9
+ };
10
10
 
11
- /// Macro to generate read methods for primitive integer types (big-endian).
12
- macro_rules! impl_read_uint {
13
- ($($method:ident, $type:ty, $len:expr);* $(;)?) => {
11
+ /// Generates read methods for primitive integer types using big-endian byte order.
12
+ ///
13
+ /// Each generated method reads a fixed number of bytes from the buffer, converts them
14
+ /// from big-endian format to the target integer type, and advances the read position.
15
+ ///
16
+ /// # Syntax
17
+ /// ```ignore
18
+ /// impl_read_int!(method_name, Type; ...);
19
+ /// ```
20
+ macro_rules! impl_read_int {
21
+ ($($method:ident, $type:ty);* $(;)?) => {
14
22
  $(
15
23
  pub fn $method(&mut self) -> $type {
16
- <$type>::from_be_bytes(self.read_bytes($len).to_array())
24
+ <$type>::from_be_bytes(self.read_bytes(mem::size_of::<$type>() as u32).to_array())
17
25
  }
18
26
  )*
19
27
  };
@@ -23,6 +31,14 @@ macro_rules! impl_read_uint {
23
31
  ///
24
32
  /// Maintains a position cursor that advances as data is read.
25
33
  /// All integer reads are big-endian.
34
+ ///
35
+ /// # Example
36
+ /// ```ignore
37
+ /// let mut reader = BufferReader::new(&bytes);
38
+ /// let value = reader.read_u32();
39
+ /// let value = reader.read_bool();
40
+ /// let addr = reader.read_address();
41
+ /// ```
26
42
  pub struct BufferReader<'a> {
27
43
  buffer: &'a Bytes,
28
44
  pos: u32,
@@ -34,6 +50,7 @@ impl<'a> BufferReader<'a> {
34
50
  Self { buffer, pos: 0 }
35
51
  }
36
52
 
53
+ /// Sets the read position to an absolute byte offset.
37
54
  pub fn seek(&mut self, pos: u32) -> &mut Self {
38
55
  assert_with_error!(self.buffer.env(), pos <= self.buffer.len(), BufferReaderError::InvalidLength);
39
56
  self.pos = pos;
@@ -53,7 +70,9 @@ impl<'a> BufferReader<'a> {
53
70
  }
54
71
 
55
72
  // Generates: read_u8 (1 byte), read_u16 (2 bytes), read_u32 (4 bytes), read_u64 (8 bytes), read_u128 (16 bytes)
56
- impl_read_uint!(read_u8, u8, 1; read_u16, u16, 2; read_u32, u32, 4; read_u64, u64, 8; read_u128, u128, 16; read_i128, i128, 16);
73
+ impl_read_int!(read_u8, u8; read_u16, u16; read_u32, u32; read_u64, u64; read_u128, u128);
74
+ // Generate: read_i8 (1 byte), read_i16 (2 bytes), read_i32 (4 bytes), read_i64 (8 bytes), read_i128 (16 bytes)
75
+ impl_read_int!(read_i8, i8; read_i16, i16; read_i32, i32; read_i64, i64; read_i128, i128);
57
76
 
58
77
  /// Reads a boolean (1 byte, non-zero = true).
59
78
  pub fn read_bool(&mut self) -> bool {
@@ -65,6 +84,11 @@ impl<'a> BufferReader<'a> {
65
84
  U256::from_be_bytes(self.buffer.env(), &self.read_bytes(32))
66
85
  }
67
86
 
87
+ /// Reads a I256 (32 bytes, big-endian).
88
+ pub fn read_i256(&mut self) -> I256 {
89
+ I256::from_be_bytes(self.buffer.env(), &self.read_bytes(32))
90
+ }
91
+
68
92
  /// Reads a Stellar address (33 bytes: 1 type + 32 payload).
69
93
  pub fn read_address(&mut self) -> Address {
70
94
  let payload_type = self.read_u8();
@@ -79,7 +103,11 @@ impl<'a> BufferReader<'a> {
79
103
 
80
104
  /// Reads N bytes as a fixed-size BytesN<N>.
81
105
  pub fn read_bytes_n<const N: usize>(&mut self) -> BytesN<N> {
82
- BytesN::<N>::from_array(self.buffer.env(), &self.read_bytes(N as u32).to_array())
106
+ BytesN::<N>::from_array(self.buffer.env(), &self.read_array())
107
+ }
108
+
109
+ pub fn read_array<const N: usize>(&mut self) -> [u8; N] {
110
+ self.read_bytes(N as u32).to_array()
83
111
  }
84
112
 
85
113
  /// Reads `len` bytes from current position and advances.
@@ -141,3 +169,26 @@ impl<'a> BufferReader<'a> {
141
169
  Address::from_payload(self.buffer.env(), addr_payload)
142
170
  }
143
171
  }
172
+
173
+ #[cfg(test)]
174
+ mod tests {
175
+ use super::*;
176
+
177
+ #[test]
178
+ fn test_size_of_unsigned_integers() {
179
+ assert_eq!(mem::size_of::<u8>(), 1);
180
+ assert_eq!(mem::size_of::<u16>(), 2);
181
+ assert_eq!(mem::size_of::<u32>(), 4);
182
+ assert_eq!(mem::size_of::<u64>(), 8);
183
+ assert_eq!(mem::size_of::<u128>(), 16);
184
+ }
185
+
186
+ #[test]
187
+ fn test_size_of_signed_integers() {
188
+ assert_eq!(mem::size_of::<i8>(), 1);
189
+ assert_eq!(mem::size_of::<i16>(), 2);
190
+ assert_eq!(mem::size_of::<i32>(), 4);
191
+ assert_eq!(mem::size_of::<i64>(), 8);
192
+ assert_eq!(mem::size_of::<i128>(), 16);
193
+ }
194
+ }
@@ -1,9 +1,16 @@
1
- use soroban_sdk::{address_payload::AddressPayload, Address, Bytes, BytesN, Env, U256};
2
-
3
1
  use crate::{errors::BufferWriterError, option_ext::OptionExt};
2
+ use soroban_sdk::{address_payload::AddressPayload, Address, Bytes, BytesN, Env, I256, U256};
4
3
 
5
- /// Macro to generate write methods for primitive integer types (big-endian).
6
- macro_rules! impl_write_uint {
4
+ /// Generates write methods for primitive integer types using big-endian byte order.
5
+ ///
6
+ /// Each generated method writes a fixed number of bytes to the buffer, converts the
7
+ /// integer value to big-endian format, and advances the write position.
8
+ ///
9
+ /// # Syntax
10
+ /// ```ignore
11
+ /// impl_write_int!(method_name, Type; ...);
12
+ /// ```
13
+ macro_rules! impl_write_int {
7
14
  ($($method:ident, $type:ty);* $(;)?) => {
8
15
  $(
9
16
  pub fn $method(&mut self, value: $type) -> &mut Self {
@@ -47,7 +54,9 @@ impl BufferWriter {
47
54
  }
48
55
 
49
56
  // Generates: write_u8 (1 byte), write_u16 (2 bytes), write_u32 (4 bytes), write_u64 (8 bytes), write_u128 (16 bytes)
50
- impl_write_uint!(write_u8, u8; write_u16, u16; write_u32, u32; write_u64, u64; write_u128, u128; write_i128, i128);
57
+ impl_write_int!(write_u8, u8; write_u16, u16; write_u32, u32; write_u64, u64; write_u128, u128);
58
+ // Generate: write_i8 (1 byte), write_i16 (2 bytes), write_i32 (4 bytes), write_i64 (8 bytes), write_i128 (16 bytes)
59
+ impl_write_int!(write_i8, i8; write_i16, i16; write_i32, i32; write_i64, i64; write_i128, i128);
51
60
 
52
61
  /// Write a boolean value to the buffer (true as 1, false as 0).
53
62
  pub fn write_bool(&mut self, value: bool) -> &mut Self {
@@ -60,20 +69,9 @@ impl BufferWriter {
60
69
  self
61
70
  }
62
71
 
63
- /// Write a byte slice to the buffer (appends without length prefix).
64
- pub fn write_bytes(&mut self, bytes: &Bytes) -> &mut Self {
65
- self.buffer.append(bytes);
66
- self
67
- }
68
-
69
- pub fn write_array<const N: usize>(&mut self, array: &[u8; N]) -> &mut Self {
70
- self.buffer.extend_from_array(array);
71
- self
72
- }
73
-
74
- /// Write a fixed-size BytesN<N> to the buffer.
75
- pub fn write_bytes_n<const N: usize>(&mut self, bytes_n: &BytesN<N>) -> &mut Self {
76
- self.buffer.extend_from_array(&bytes_n.to_array());
72
+ /// Write a signed 256-bit integer in big-endian format.
73
+ pub fn write_i256(&mut self, value: I256) -> &mut Self {
74
+ self.buffer.append(&value.to_be_bytes());
77
75
  self
78
76
  }
79
77
 
@@ -89,7 +87,24 @@ impl BufferWriter {
89
87
  self.write_bytes_n(&payload)
90
88
  }
91
89
 
92
- /// Get the complete buffer as a Bytes, consuming the writer.
90
+ /// Write a byte slice to the buffer (appends without length prefix).
91
+ pub fn write_bytes(&mut self, bytes: &Bytes) -> &mut Self {
92
+ self.buffer.append(bytes);
93
+ self
94
+ }
95
+
96
+ /// Write a fixed-size BytesN<N> to the buffer.
97
+ pub fn write_bytes_n<const N: usize>(&mut self, bytes_n: &BytesN<N>) -> &mut Self {
98
+ self.buffer.extend_from_array(&bytes_n.to_array());
99
+ self
100
+ }
101
+
102
+ pub fn write_array<const N: usize>(&mut self, array: &[u8; N]) -> &mut Self {
103
+ self.buffer.extend_from_array(array);
104
+ self
105
+ }
106
+
107
+ /// Get the complete buffer as a Bytes.
93
108
  pub fn to_bytes(&self) -> Bytes {
94
109
  self.buffer.clone()
95
110
  }
@@ -1,6 +1,5 @@
1
- use soroban_sdk::{assert_with_error, Bytes};
2
-
3
1
  use crate::errors::BytesExtError;
2
+ use soroban_sdk::{assert_with_error, Bytes};
4
3
 
5
4
  /// Extension trait for `Bytes` to convert to fixed-size arrays
6
5
  pub trait BytesExt {
@@ -27,7 +27,8 @@ pub enum TtlConfigurableError {
27
27
  /// OwnableError: 1030-1039
28
28
  #[contract_error]
29
29
  pub enum OwnableError {
30
- InvalidPendingOwner = 1030,
30
+ InvalidAuthorizer = 1030,
31
+ InvalidPendingOwner,
31
32
  InvalidTtl,
32
33
  NoPendingTransfer,
33
34
  OwnerAlreadySet,
@@ -49,10 +50,11 @@ pub enum UpgradeableError {
49
50
  UpgradesFrozen,
50
51
  }
51
52
 
52
- /// MultisigError: 1060-1069
53
+ /// MultiSigError: 1060-1069
53
54
  #[contract_error]
54
- pub enum MultisigError {
55
+ pub enum MultiSigError {
55
56
  AlreadyInitialized = 1060,
57
+ InvalidAuthorizer,
56
58
  InvalidSigner,
57
59
  SignatureError,
58
60
  SignerAlreadyExists,
@@ -1,13 +1,13 @@
1
1
  use crate::{
2
2
  self as utils, // Alias for #[storage] macro's generated `utils::ttl_configurable` path
3
- auth::{self, Auth},
4
- errors::MultisigError,
3
+ auth::Auth,
4
+ errors::MultiSigError,
5
5
  };
6
6
  use common_macros::{contract_trait, storage};
7
7
  use soroban_sdk::{assert_with_error, contractevent, Bytes, BytesN, Env, Vec};
8
8
 
9
9
  // ===========================================================================
10
- // Multisig events
10
+ // MultiSig events
11
11
  // ===========================================================================
12
12
 
13
13
  /// Event emitted when a signer is added or removed.
@@ -27,39 +27,46 @@ pub struct ThresholdSet {
27
27
  }
28
28
 
29
29
  // ===========================================================================
30
- // Multisig storage
30
+ // MultiSig storage
31
31
  // ===========================================================================
32
32
 
33
- /// Storage keys for Multisig.
33
+ /// Storage keys for MultiSig.
34
34
  #[storage]
35
- pub enum MultisigStorage {
35
+ pub enum MultiSigStorage {
36
+ /// List of authorized signers as Ethereum-style addresses (20 bytes).
37
+ ///
38
+ /// Practically, multisig has 2-5 signers, so storing them in a single `Vec` is fine.
39
+ /// This makes `get_signers` trivial (just read the Vec), while `set_signer` is slightly
40
+ /// more complex (read-modify-write). Since reads are frequent and writes are rare,
41
+ /// this trade-off is acceptable.
36
42
  #[persistent(Vec<BytesN<20>>)]
37
43
  #[default(Vec::new(env))]
38
44
  Signers,
39
45
 
46
+ /// Minimum number of valid signatures required to authorize operations (quorum).
40
47
  #[instance(u32)]
41
48
  #[default(0)]
42
49
  Threshold,
43
50
  }
44
51
 
45
52
  // ===========================================================================
46
- // Multisig trait with default implementation
53
+ // MultiSig trait with default implementation
47
54
  // ===========================================================================
48
55
 
49
56
  /// Trait for contracts with secp256k1 multisig signature verification.
50
57
  ///
51
58
  /// Extends `Auth` to provide self-owning authorization. Contracts implementing
52
- /// `Multisig` should implement `Auth::authorizer()` to return `env.current_contract_address()`,
59
+ /// `MultiSig` should implement `Auth::authorizer()` to return `env.current_contract_address()`,
53
60
  /// allowing the multisig quorum to serve as the authorizer for owner-protected operations.
54
61
  #[contract_trait]
55
- pub trait Multisig: Auth {
62
+ pub trait MultiSig: Auth {
56
63
  // ===========================================================================
57
64
  // Mutation functions, only callable by the contract itself
58
65
  // ===========================================================================
59
66
 
60
67
  /// Adds or removes a signer from the multisig. Requires owner authorization.
61
68
  fn set_signer(env: &soroban_sdk::Env, signer: &soroban_sdk::BytesN<20>, active: bool) {
62
- auth::require_auth::<Self>(env);
69
+ enforce_multisig_auth::<Self>(env);
63
70
  match active {
64
71
  true => add_signer(env, signer),
65
72
  false => remove_signer(env, signer),
@@ -68,7 +75,7 @@ pub trait Multisig: Auth {
68
75
 
69
76
  /// Sets the signature threshold (quorum). Requires owner authorization.
70
77
  fn set_threshold(env: &soroban_sdk::Env, threshold: u32) {
71
- auth::require_auth::<Self>(env);
78
+ enforce_multisig_auth::<Self>(env);
72
79
  set_threshold(env, threshold);
73
80
  }
74
81
 
@@ -78,22 +85,22 @@ pub trait Multisig: Auth {
78
85
 
79
86
  /// Returns all registered signers.
80
87
  fn get_signers(env: &soroban_sdk::Env) -> soroban_sdk::Vec<soroban_sdk::BytesN<20>> {
81
- MultisigStorage::signers(env)
88
+ MultiSigStorage::signers(env)
82
89
  }
83
90
 
84
91
  /// Returns the total number of registered signers.
85
92
  fn total_signers(env: &soroban_sdk::Env) -> u32 {
86
- MultisigStorage::signers(env).len()
93
+ MultiSigStorage::signers(env).len()
87
94
  }
88
95
 
89
96
  /// Checks if an address is a registered signer.
90
97
  fn is_signer(env: &soroban_sdk::Env, signer: &soroban_sdk::BytesN<20>) -> bool {
91
- MultisigStorage::signers(env).iter().any(|s| &s == signer)
98
+ MultiSigStorage::signers(env).iter().any(|s| &s == signer)
92
99
  }
93
100
 
94
101
  /// Returns the current signature threshold (quorum).
95
102
  fn threshold(env: &soroban_sdk::Env) -> u32 {
96
- MultisigStorage::threshold(env)
103
+ MultiSigStorage::threshold(env)
97
104
  }
98
105
 
99
106
  // ===========================================================================
@@ -106,7 +113,7 @@ pub trait Multisig: Auth {
106
113
  digest: &soroban_sdk::BytesN<32>,
107
114
  signatures: &soroban_sdk::Vec<soroban_sdk::BytesN<65>>,
108
115
  ) {
109
- Self::verify_n_signatures(env, digest, signatures, MultisigStorage::threshold(env));
116
+ Self::verify_n_signatures(env, digest, signatures, MultiSigStorage::threshold(env));
110
117
  }
111
118
 
112
119
  /// Verifies signatures against a custom threshold.
@@ -116,10 +123,10 @@ pub trait Multisig: Auth {
116
123
  signatures: &soroban_sdk::Vec<soroban_sdk::BytesN<65>>,
117
124
  threshold: u32,
118
125
  ) {
119
- assert_with_error!(env, threshold > 0, MultisigError::ZeroThreshold);
120
- assert_with_error!(env, signatures.len() >= threshold, MultisigError::SignatureError);
126
+ assert_with_error!(env, threshold > 0, MultiSigError::ZeroThreshold);
127
+ assert_with_error!(env, signatures.len() >= threshold, MultiSigError::SignatureError);
121
128
 
122
- let signers = MultisigStorage::signers(env);
129
+ let signers = MultiSigStorage::signers(env);
123
130
  let mut last_signer: Option<BytesN<20>> = None;
124
131
  for signature in signatures.iter() {
125
132
  let signer = recover_signer(env, digest, &signature);
@@ -127,9 +134,9 @@ pub trait Multisig: Auth {
127
134
  assert_with_error!(
128
135
  env,
129
136
  last_signer.as_ref().is_none_or(|last| &signer > last),
130
- MultisigError::UnsortedSigners
137
+ MultiSigError::UnsortedSigners
131
138
  );
132
- assert_with_error!(env, signers.iter().any(|s| s == signer), MultisigError::SignerNotFound);
139
+ assert_with_error!(env, signers.iter().any(|s| s == signer), MultiSigError::SignerNotFound);
133
140
 
134
141
  last_signer = Some(signer);
135
142
  }
@@ -142,7 +149,7 @@ pub trait Multisig: Auth {
142
149
 
143
150
  /// Initializes multisig with signers and threshold. Called from contract constructors.
144
151
  pub fn init_multisig(env: &Env, signers: &Vec<BytesN<20>>, threshold: u32) {
145
- assert_with_error!(env, !MultisigStorage::has_signers(env), MultisigError::AlreadyInitialized);
152
+ assert_with_error!(env, !MultiSigStorage::has_signers(env), MultiSigError::AlreadyInitialized);
146
153
 
147
154
  signers.iter().for_each(|signer| add_signer(env, &signer));
148
155
  set_threshold(env, threshold);
@@ -151,13 +158,29 @@ pub fn init_multisig(env: &Env, signers: &Vec<BytesN<20>>, threshold: u32) {
151
158
  /// Recovers Ethereum-style signer address from secp256k1 signature (65 bytes: r + s + v).
152
159
  pub fn recover_signer(env: &Env, digest: &BytesN<32>, signature: &BytesN<65>) -> BytesN<20> {
153
160
  let sig_bytes: Bytes = signature.into();
161
+
162
+ // Extract recovery ID (v) - normalize from Ethereum's 27-30 range if needed
154
163
  let v = sig_bytes.get(64).unwrap();
155
164
  let recovery_id = if (27..=30).contains(&v) { v - 27 } else { v };
165
+
166
+ // Extract r,s components (first 64 bytes)
156
167
  let sig_rs: BytesN<64> = sig_bytes.slice(0..64).try_into().unwrap();
157
168
 
169
+ // Recover uncompressed public key (65 bytes with 0x04 prefix)
158
170
  let public_key = env.crypto_hazmat().secp256k1_recover(digest, &sig_rs, recovery_id as u32);
159
171
 
160
- Bytes::from(env.crypto().keccak256(&Bytes::from(public_key).slice(1..65))).slice(12..32).try_into().unwrap()
172
+ // Derive Ethereum address: keccak256(pubkey[1..65])[12..32]
173
+ let pubkey_body: Bytes = Bytes::from(public_key).slice(1..65);
174
+ let hash: Bytes = env.crypto().keccak256(&pubkey_body).into();
175
+ hash.slice(12..32).try_into().unwrap()
176
+ }
177
+
178
+ /// Enforces multisig authorization by requiring the contract's own address to authorize.
179
+ /// Panics with `InvalidAuthorizer` if the authorizer is not the contract's own address.
180
+ pub fn enforce_multisig_auth<T: MultiSig>(env: &Env) {
181
+ // Ensure the authorizer is the contract's own address
182
+ assert_with_error!(env, T::authorizer(env) == env.current_contract_address(), MultiSigError::InvalidAuthorizer);
183
+ env.current_contract_address().require_auth();
161
184
  }
162
185
 
163
186
  // ===========================================================================
@@ -167,24 +190,24 @@ pub fn recover_signer(env: &Env, digest: &BytesN<32>, signature: &BytesN<65>) ->
167
190
  /// Adds a new signer to the multisig.
168
191
  fn add_signer(env: &Env, signer: &BytesN<20>) {
169
192
  // Not allowed to add zero address as signer
170
- assert_with_error!(env, signer != &BytesN::from_array(env, &[0u8; 20]), MultisigError::InvalidSigner);
193
+ assert_with_error!(env, signer != &BytesN::from_array(env, &[0u8; 20]), MultiSigError::InvalidSigner);
171
194
  // Not allowed to add same signer twice
172
- let mut signers = MultisigStorage::signers(env);
173
- assert_with_error!(env, !signers.iter().any(|s| &s == signer), MultisigError::SignerAlreadyExists);
195
+ let mut signers = MultiSigStorage::signers(env);
196
+ assert_with_error!(env, !signers.iter().any(|s| &s == signer), MultiSigError::SignerAlreadyExists);
174
197
 
175
198
  // Add signer to list
176
199
  signers.push_back(signer.clone());
177
- MultisigStorage::set_signers(env, &signers);
200
+ MultiSigStorage::set_signers(env, &signers);
178
201
 
179
202
  SignerSet { signer: signer.clone(), active: true }.publish(env);
180
203
  }
181
204
 
182
205
  /// Removes a signer from the multisig.
183
206
  fn remove_signer(env: &Env, signer: &BytesN<20>) {
184
- let mut signers = MultisigStorage::signers(env);
207
+ let mut signers = MultiSigStorage::signers(env);
185
208
  let index = signers.first_index_of(signer);
186
209
  // Not allowed to remove non-existent signer
187
- assert_with_error!(env, index.is_some(), MultisigError::SignerNotFound);
210
+ assert_with_error!(env, index.is_some(), MultiSigError::SignerNotFound);
188
211
 
189
212
  // Remove signer from list
190
213
  signers.remove(index.unwrap());
@@ -192,12 +215,12 @@ fn remove_signer(env: &Env, signer: &BytesN<20>) {
192
215
  // Not allowed to remove signer if it would violate the threshold
193
216
  assert_with_error!(
194
217
  env,
195
- signers.len() >= MultisigStorage::threshold(env),
196
- MultisigError::TotalSignersLessThanThreshold
218
+ signers.len() >= MultiSigStorage::threshold(env),
219
+ MultiSigError::TotalSignersLessThanThreshold
197
220
  );
198
221
 
199
222
  // Update signers list
200
- MultisigStorage::set_signers(env, &signers);
223
+ MultiSigStorage::set_signers(env, &signers);
201
224
 
202
225
  SignerSet { signer: signer.clone(), active: false }.publish(env);
203
226
  }
@@ -205,16 +228,16 @@ fn remove_signer(env: &Env, signer: &BytesN<20>) {
205
228
  /// Sets the signature threshold (quorum).
206
229
  fn set_threshold(env: &Env, threshold: u32) {
207
230
  // Not allowed to set threshold to zero
208
- assert_with_error!(env, threshold > 0, MultisigError::ZeroThreshold);
231
+ assert_with_error!(env, threshold > 0, MultiSigError::ZeroThreshold);
209
232
  // Not allowed to set threshold to greater than the number of signers
210
233
  assert_with_error!(
211
234
  env,
212
- MultisigStorage::signers(env).len() >= threshold,
213
- MultisigError::TotalSignersLessThanThreshold
235
+ MultiSigStorage::signers(env).len() >= threshold,
236
+ MultiSigError::TotalSignersLessThanThreshold
214
237
  );
215
238
 
216
239
  // Update threshold
217
- MultisigStorage::set_threshold(env, &threshold);
240
+ MultiSigStorage::set_threshold(env, &threshold);
218
241
 
219
242
  ThresholdSet { threshold }.publish(env);
220
243
  }
@@ -1,4 +1,4 @@
1
- use soroban_sdk::{panic_with_error, Env};
1
+ use soroban_sdk::{panic_with_error, Env, Error};
2
2
 
3
3
  /// Extension trait for `Option<T>` that provides Soroban-specific unwrapping utilities.
4
4
  ///
@@ -20,13 +20,13 @@ pub trait OptionExt<T> {
20
20
  /// Panics with the specified error if the `Option` is `None`.
21
21
  fn unwrap_or_panic<E>(self, env: &Env, error: E) -> T
22
22
  where
23
- E: Into<soroban_sdk::Error>;
23
+ E: Into<Error>;
24
24
  }
25
25
 
26
26
  impl<T> OptionExt<T> for Option<T> {
27
27
  fn unwrap_or_panic<E>(self, env: &Env, error: E) -> T
28
28
  where
29
- E: Into<soroban_sdk::Error>,
29
+ E: Into<Error>,
30
30
  {
31
31
  match self {
32
32
  // Return the inner value if present
@@ -23,6 +23,14 @@ pub struct OwnershipTransferring {
23
23
  pub ttl: u32,
24
24
  }
25
25
 
26
+ /// Event emitted when a 2-step ownership transfer is cancelled.
27
+ #[contractevent]
28
+ #[derive(Clone, Debug, Eq, PartialEq)]
29
+ pub struct OwnershipTransferCancelled {
30
+ pub owner: Address,
31
+ pub cancelled_pending_owner: Address,
32
+ }
33
+
26
34
  /// Event emitted when ownership is renounced.
27
35
  #[contractevent]
28
36
  #[derive(Clone, Debug, Eq, PartialEq)]
@@ -58,7 +66,7 @@ pub enum OwnableStorage {
58
66
  /// - Single-step: `transfer_ownership` - Immediate transfer (use with caution)
59
67
  /// - Two-step: `propose_ownership_transfer` + `accept_ownership` - Safer, requires new owner to accept
60
68
  #[contract_trait]
61
- pub trait Ownable: Sized + Auth {
69
+ pub trait Ownable: Auth {
62
70
  // ===========================================================================
63
71
  // View functions
64
72
  // ===========================================================================
@@ -123,6 +131,7 @@ pub trait Ownable: Sized + Auth {
123
131
  assert_with_error!(env, pending == *new_owner, OwnableError::InvalidPendingOwner);
124
132
 
125
133
  OwnableStorage::remove_pending_owner(env);
134
+ OwnershipTransferCancelled { owner: old_owner, cancelled_pending_owner: pending }.publish(env);
126
135
  return;
127
136
  }
128
137
 
@@ -194,15 +203,12 @@ pub trait OwnableInitializer {
194
203
  /// Panics if no owner is set or authorization fails.
195
204
  pub fn enforce_owner_auth<T: Ownable>(env: &Env) -> Address {
196
205
  let owner = T::owner(env).unwrap_or_panic(env, OwnableError::OwnerNotSet);
206
+ // Ensure the owner is the same as the authorizer
207
+ assert_with_error!(env, owner == T::authorizer(env), OwnableError::InvalidAuthorizer);
197
208
  owner.require_auth();
198
209
  owner
199
210
  }
200
211
 
201
- /// Enforces owner authorization without returning the address.
202
- pub fn require_owner_auth<T: Ownable>(env: &Env) {
203
- let _ = enforce_owner_auth::<T>(env);
204
- }
205
-
206
212
  /// Asserts that no 2-step ownership transfer is in progress.
207
213
  /// Panics with `TransferInProgress` if a pending transfer exists.
208
214
  fn assert_no_pending_transfer<T: Ownable>(env: &Env) {