@layerzerolabs/protocol-stellar-v2 0.2.15 → 0.2.19

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 (262) hide show
  1. package/.turbo/turbo-build.log +365 -297
  2. package/.turbo/turbo-lint.log +142 -110
  3. package/.turbo/turbo-test.log +1273 -1222
  4. package/Cargo.lock +20 -5
  5. package/Cargo.toml +4 -1
  6. package/contracts/ERROR_SPEC.md +44 -0
  7. package/contracts/common-macros/src/auth.rs +113 -0
  8. package/contracts/common-macros/src/contract_ttl.rs +84 -0
  9. package/contracts/common-macros/src/lib.rs +181 -30
  10. package/contracts/common-macros/src/lz_contract.rs +83 -0
  11. package/contracts/common-macros/src/tests/{ownable.rs → auth.rs} +48 -15
  12. package/contracts/common-macros/src/tests/contract_ttl.rs +662 -0
  13. package/contracts/common-macros/src/tests/mod.rs +2 -2
  14. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +20 -0
  15. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +24 -0
  16. package/contracts/common-macros/src/tests/snapshots/{common_macros__tests__ownable__snapshot_only_owner_preserves_function_signature.snap → common_macros__tests__auth__snapshot_only_auth_preserves_function_signature.snap} +4 -4
  17. package/contracts/common-macros/src/tests/snapshots/{common_macros__tests__contract_impl__snapshot_generated_contract_impl_code.snap → common_macros__tests__contract_ttl__snapshot_generated_contractimpl_code.snap} +3 -3
  18. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contracttrait_code.snap +69 -0
  19. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +7 -21
  20. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +2 -2
  21. package/contracts/common-macros/src/ttl_configurable.rs +19 -34
  22. package/contracts/common-macros/src/ttl_extendable.rs +36 -0
  23. package/contracts/common-macros/src/upgradeable.rs +5 -5
  24. package/contracts/common-macros/src/utils.rs +9 -0
  25. package/contracts/endpoint-v2/src/constants.rs +4 -4
  26. package/contracts/endpoint-v2/src/endpoint_v2.rs +38 -40
  27. package/contracts/endpoint-v2/src/errors.rs +4 -3
  28. package/contracts/endpoint-v2/src/events.rs +1 -1
  29. package/contracts/endpoint-v2/src/message_lib_manager.rs +18 -5
  30. package/contracts/endpoint-v2/src/messaging_channel.rs +11 -1
  31. package/contracts/endpoint-v2/src/messaging_composer.rs +11 -1
  32. package/contracts/endpoint-v2/src/storage.rs +1 -1
  33. package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +3 -3
  34. package/contracts/endpoint-v2/src/tests/endpoint_v2/quote.rs +1 -1
  35. package/contracts/endpoint-v2/src/tests/endpoint_v2/require_oapp_auth.rs +2 -2
  36. package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +3 -3
  37. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +4 -4
  38. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_receive_lib_for_eid.rs +3 -3
  39. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_registered.rs +1 -1
  40. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_send_lib_for_eid.rs +3 -3
  41. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_supported_eid.rs +1 -1
  42. package/contracts/endpoint-v2/src/tests/messaging_channel/clear_payload.rs +4 -4
  43. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound.rs +1 -1
  44. package/contracts/layerzero-views/src/layerzero_view.rs +3 -6
  45. package/contracts/macro-integration-tests/tests/runtime/ownable/mod.rs +2 -2
  46. package/contracts/macro-integration-tests/tests/runtime/ownable/{only_owner_guard.rs → only_auth_guard.rs} +1 -1
  47. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/configuration.rs +1 -1
  48. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/freeze.rs +1 -1
  49. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/mod.rs +0 -1
  50. package/contracts/macro-integration-tests/tests/ui/ownable/fail/{only_owner_missing_env.rs → only_auth_missing_env.rs} +3 -3
  51. package/contracts/macro-integration-tests/tests/ui/ownable/fail/{only_owner_missing_env.stderr → only_auth_missing_env.stderr} +4 -4
  52. package/contracts/macro-integration-tests/tests/ui/ownable/pass/namespacing_and_imports.rs +2 -3
  53. package/contracts/macro-integration-tests/tests/ui/ownable/pass/{only_owner_env_param_variants.rs → only_auth_env_param_variants.rs} +9 -9
  54. package/contracts/macro-integration-tests/tests/ui/ttl_configurable/pass/minimal_contract.rs +6 -6
  55. package/contracts/message-libs/message-lib-common/src/errors.rs +7 -2
  56. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1/decode_packet_header.rs +3 -3
  57. package/contracts/message-libs/message-lib-common/src/tests/worker_options/append_lz_receive_option.rs +1 -2
  58. package/contracts/message-libs/message-lib-common/src/tests/worker_options/append_native_drop_option.rs +1 -2
  59. package/contracts/message-libs/message-lib-common/src/tests/worker_options/convert_legacy_options.rs +9 -9
  60. package/contracts/message-libs/message-lib-common/src/tests/worker_options/extract_type_3_options.rs +1 -1
  61. package/contracts/message-libs/message-lib-common/src/tests/worker_options/left_pad_to_bytes32.rs +1 -1
  62. package/contracts/message-libs/message-lib-common/src/tests/worker_options/split_worker_options.rs +2 -2
  63. package/contracts/message-libs/simple-message-lib/src/simple_message_lib.rs +7 -9
  64. package/contracts/message-libs/treasury/src/errors.rs +2 -2
  65. package/contracts/message-libs/treasury/src/events.rs +1 -1
  66. package/contracts/message-libs/treasury/src/interfaces/zro_fee_lib.rs +2 -2
  67. package/contracts/message-libs/treasury/src/storage.rs +1 -1
  68. package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +1 -1
  69. package/contracts/message-libs/treasury/src/treasury.rs +14 -16
  70. package/contracts/message-libs/uln-302/src/receive_uln.rs +13 -2
  71. package/contracts/message-libs/uln-302/src/send_uln.rs +24 -4
  72. package/contracts/message-libs/uln-302/src/uln302.rs +6 -24
  73. package/contracts/oapps/counter/Cargo.toml +14 -1
  74. package/contracts/oapps/counter/integration_tests/mod.rs +4 -1
  75. package/contracts/oapps/counter/integration_tests/{setup.rs → setup_sml.rs} +48 -80
  76. package/contracts/oapps/counter/integration_tests/setup_uln.rs +997 -0
  77. package/contracts/oapps/counter/integration_tests/signing.rs +62 -0
  78. package/contracts/oapps/counter/integration_tests/test_with_sml.rs +24 -55
  79. package/contracts/oapps/counter/integration_tests/test_with_uln.rs +314 -0
  80. package/contracts/oapps/counter/integration_tests/utils.rs +196 -53
  81. package/contracts/oapps/counter/src/counter.rs +67 -43
  82. package/contracts/oapps/counter/src/tests/mod.rs +0 -13
  83. package/contracts/oapps/counter/src/tests/test_counter.rs +5 -7
  84. package/contracts/oapps/oapp/src/errors.rs +5 -1
  85. package/contracts/oapps/oapp/src/macro_tests/test_macros.rs +93 -78
  86. package/contracts/oapps/oapp/src/oapp_core.rs +36 -21
  87. package/contracts/oapps/oapp/src/oapp_options_type3.rs +48 -12
  88. package/contracts/oapps/oapp/src/oapp_receiver.rs +106 -41
  89. package/contracts/oapps/oapp/src/oapp_sender.rs +26 -34
  90. package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +9 -8
  91. package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +25 -17
  92. package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +7 -7
  93. package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +14 -15
  94. package/contracts/oapps/oapp-macros/src/generators.rs +128 -0
  95. package/contracts/oapps/oapp-macros/src/lib.rs +113 -56
  96. package/contracts/oapps/oft/Cargo.toml +10 -7
  97. package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/test_oft_fee.rs +3 -4
  98. package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/test_pausable.rs +2 -3
  99. package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/test_rate_limiter.rs +1 -1
  100. package/contracts/oapps/oft/integration-tests/mod.rs +1 -1
  101. package/contracts/oapps/oft/integration-tests/setup.rs +29 -110
  102. package/contracts/oapps/oft/integration-tests/utils.rs +254 -21
  103. package/contracts/oapps/oft/src/extensions/oft_fee.rs +13 -14
  104. package/contracts/oapps/oft/src/extensions/pausable.rs +4 -4
  105. package/contracts/oapps/oft/src/extensions/rate_limiter.rs +5 -5
  106. package/contracts/oapps/oft/src/lib.rs +11 -13
  107. package/contracts/oapps/oft/src/oft.rs +147 -225
  108. package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +9 -13
  109. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +31 -14
  110. package/contracts/oapps/oft/src/oft_types/mod.rs +13 -0
  111. package/contracts/oapps/{oft-std → oft-core}/Cargo.toml +6 -4
  112. package/contracts/oapps/{oft-std → oft-core}/integration-tests/mod.rs +1 -1
  113. package/contracts/oapps/{oft-std → oft-core}/integration-tests/setup.rs +129 -30
  114. package/contracts/oapps/{oft → oft-core}/integration-tests/test_with_sml.rs +3 -3
  115. package/contracts/oapps/oft-core/integration-tests/utils.rs +201 -0
  116. package/contracts/oapps/oft-core/src/errors.rs +13 -0
  117. package/contracts/oapps/oft-core/src/lib.rs +18 -0
  118. package/contracts/oapps/oft-core/src/oft_core.rs +439 -0
  119. package/contracts/oapps/{oft → oft-core}/src/storage.rs +2 -0
  120. package/contracts/oapps/{oft → oft-core}/src/tests/mod.rs +0 -2
  121. package/contracts/oapps/{oft → oft-core}/src/tests/test_decimals.rs +2 -2
  122. package/contracts/oapps/{oft → oft-core}/src/tests/test_lz_receive.rs +7 -7
  123. package/contracts/oapps/{oft → oft-core}/src/tests/test_oft_msg_codec.rs +4 -5
  124. package/contracts/oapps/{oft → oft-core}/src/tests/test_resolve_address.rs +3 -3
  125. package/contracts/oapps/{oft → oft-core}/src/tests/test_utils.rs +78 -37
  126. package/contracts/oapps/oft-core/src/types.rs +58 -0
  127. package/contracts/oapps/{oft → oft-core}/src/utils.rs +1 -1
  128. package/contracts/upgrader/src/lib.rs +4 -4
  129. package/contracts/utils/src/auth.rs +44 -0
  130. package/contracts/utils/src/errors.rs +31 -5
  131. package/contracts/utils/src/lib.rs +3 -0
  132. package/contracts/utils/src/multisig.rs +211 -0
  133. package/contracts/utils/src/ownable.rs +137 -13
  134. package/contracts/utils/src/tests/buffer_reader.rs +6 -6
  135. package/contracts/utils/src/tests/buffer_writer.rs +6 -6
  136. package/contracts/utils/src/tests/bytes_ext.rs +2 -4
  137. package/contracts/utils/src/tests/mod.rs +1 -0
  138. package/contracts/utils/src/tests/multisig.rs +731 -0
  139. package/contracts/utils/src/tests/option_ext.rs +2 -5
  140. package/contracts/utils/src/tests/ownable.rs +456 -7
  141. package/contracts/utils/src/tests/ttl_configurable.rs +27 -16
  142. package/contracts/utils/src/tests/upgradeable.rs +4 -2
  143. package/contracts/utils/src/ttl_configurable.rs +23 -8
  144. package/contracts/utils/src/ttl_extendable.rs +27 -0
  145. package/contracts/utils/src/upgradeable.rs +2 -0
  146. package/contracts/workers/dvn/Cargo.toml +1 -1
  147. package/contracts/workers/dvn/src/auth.rs +7 -7
  148. package/contracts/workers/dvn/src/dvn.rs +10 -38
  149. package/contracts/workers/dvn/src/errors.rs +0 -7
  150. package/contracts/workers/dvn/src/events.rs +1 -14
  151. package/contracts/workers/dvn/src/interfaces/dvn.rs +2 -2
  152. package/contracts/workers/dvn/src/interfaces/mod.rs +0 -2
  153. package/contracts/workers/dvn/src/storage.rs +3 -13
  154. package/contracts/workers/dvn/src/tests/auth.rs +4 -4
  155. package/contracts/workers/dvn/src/tests/dvn.rs +1 -2
  156. package/contracts/workers/dvn/src/tests/multisig/set_signer.rs +7 -8
  157. package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +11 -8
  158. package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +11 -12
  159. package/contracts/workers/dvn/src/tests/setup.rs +5 -5
  160. package/contracts/workers/dvn-fee-lib/Cargo.toml +1 -1
  161. package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +3 -6
  162. package/contracts/workers/executor/src/auth.rs +80 -16
  163. package/contracts/workers/executor/src/executor.rs +5 -31
  164. package/contracts/workers/executor/src/storage.rs +2 -9
  165. package/contracts/workers/executor-fee-lib/Cargo.toml +1 -1
  166. package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +3 -6
  167. package/contracts/workers/executor-helper/Cargo.toml +1 -1
  168. package/contracts/workers/executor-helper/src/executor_helper.rs +53 -73
  169. package/contracts/workers/price-feed/Cargo.toml +1 -1
  170. package/contracts/workers/price-feed/src/price_feed.rs +7 -10
  171. package/contracts/workers/worker/src/errors.rs +4 -0
  172. package/contracts/workers/worker/src/tests/worker.rs +7 -6
  173. package/contracts/workers/worker/src/worker.rs +20 -16
  174. package/package.json +7 -5
  175. package/sdk/.turbo/turbo-build.log +1 -0
  176. package/sdk/.turbo/turbo-test.log +1019 -0
  177. package/sdk/dist/generated/bml.d.ts +95 -8
  178. package/sdk/dist/generated/bml.js +95 -36
  179. package/sdk/dist/generated/counter.d.ts +289 -44
  180. package/sdk/dist/generated/counter.js +119 -49
  181. package/sdk/dist/generated/dvn.d.ts +312 -229
  182. package/sdk/dist/generated/dvn.js +144 -83
  183. package/sdk/dist/generated/dvn_fee_lib.d.ts +258 -63
  184. package/sdk/dist/generated/dvn_fee_lib.js +95 -26
  185. package/sdk/dist/generated/endpoint.d.ts +219 -24
  186. package/sdk/dist/generated/endpoint.js +108 -41
  187. package/sdk/dist/generated/executor.d.ts +239 -87
  188. package/sdk/dist/generated/executor.js +135 -63
  189. package/sdk/dist/generated/executor_fee_lib.d.ts +278 -74
  190. package/sdk/dist/generated/executor_fee_lib.js +135 -59
  191. package/sdk/dist/generated/executor_helper.d.ts +163 -21
  192. package/sdk/dist/generated/executor_helper.js +124 -52
  193. package/sdk/dist/generated/oft.d.ts +1842 -0
  194. package/sdk/dist/generated/oft.js +345 -0
  195. package/sdk/dist/generated/price_feed.d.ts +258 -63
  196. package/sdk/dist/generated/price_feed.js +95 -26
  197. package/sdk/dist/generated/sml.d.ts +235 -34
  198. package/sdk/dist/generated/sml.js +126 -53
  199. package/sdk/dist/generated/treasury.d.ts +1016 -0
  200. package/sdk/dist/generated/treasury.js +248 -0
  201. package/sdk/dist/generated/uln302.d.ts +235 -34
  202. package/sdk/dist/generated/uln302.js +126 -53
  203. package/sdk/dist/generated/upgrader.d.ts +17 -2
  204. package/sdk/dist/generated/upgrader.js +19 -1
  205. package/sdk/dist/index.d.ts +2 -1
  206. package/sdk/dist/index.js +2 -1
  207. package/sdk/package.json +6 -3
  208. package/sdk/src/index.ts +2 -1
  209. package/sdk/test/counter-sml.test.ts +376 -0
  210. package/sdk/test/counter-uln.test.ts +493 -0
  211. package/sdk/test/{oft.test.ts → oft-sml.test.ts} +196 -321
  212. package/sdk/test/suites/constants.ts +22 -2
  213. package/sdk/test/suites/globalSetup.ts +450 -0
  214. package/sdk/test/suites/localnet.ts +23 -6
  215. package/sdk/test/upgrader.test.ts +7 -16
  216. package/sdk/test/utils.ts +558 -85
  217. package/sdk/turbo.json +8 -0
  218. package/sdk/vitest.config.ts +21 -0
  219. package/tools/ts-bindings-gen/Cargo.toml +2 -0
  220. package/tools/ts-bindings-gen/src/main.rs +52 -4
  221. package/contracts/common-macros/src/contract_impl.rs +0 -52
  222. package/contracts/common-macros/src/ownable.rs +0 -41
  223. package/contracts/common-macros/src/tests/contract_impl.rs +0 -386
  224. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_generated_ownable_code.snap +0 -12
  225. package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/extend_instance_ttl.rs +0 -50
  226. package/contracts/oapps/oapp-macros/src/oapp_core.rs +0 -41
  227. package/contracts/oapps/oapp-macros/src/oapp_full.rs +0 -21
  228. package/contracts/oapps/oapp-macros/src/oapp_options_type3.rs +0 -31
  229. package/contracts/oapps/oapp-macros/src/oapp_receiver.rs +0 -48
  230. package/contracts/oapps/oapp-macros/src/oapp_sender.rs +0 -21
  231. package/contracts/oapps/oapp-macros/src/util.rs +0 -107
  232. package/contracts/oapps/oft/src/constants.rs +0 -5
  233. package/contracts/oapps/oft/src/default_oft_impl.rs +0 -152
  234. package/contracts/oapps/oft/src/errors.rs +0 -8
  235. package/contracts/oapps/oft/src/interfaces/mint_burn_token.rs +0 -23
  236. package/contracts/oapps/oft/src/interfaces/mod.rs +0 -3
  237. package/contracts/oapps/oft/src/tests/extensions/mod.rs +0 -11
  238. package/contracts/oapps/oft/src/tests/extensions/setup.rs +0 -903
  239. package/contracts/oapps/oft/src/tests/extensions/test_oft_fee.rs +0 -749
  240. package/contracts/oapps/oft/src/tests/extensions/test_pausable.rs +0 -432
  241. package/contracts/oapps/oft/src/tests/extensions/test_rate_limiter.rs +0 -1078
  242. package/contracts/oapps/oft/src/types.rs +0 -38
  243. package/contracts/oapps/oft-std/integration-tests/utils.rs +0 -427
  244. package/contracts/oapps/oft-std/src/lib.rs +0 -16
  245. package/contracts/oapps/oft-std/src/oft.rs +0 -156
  246. package/contracts/workers/dvn/src/interfaces/multisig.rs +0 -56
  247. package/contracts/workers/dvn/src/multisig.rs +0 -157
  248. package/sdk/dist/generated/oft_std.d.ts +0 -1544
  249. package/sdk/dist/generated/oft_std.js +0 -271
  250. package/sdk/test/index.test.ts +0 -375
  251. /package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/mod.rs +0 -0
  252. /package/contracts/oapps/{oft → oft-core}/src/codec/mod.rs +0 -0
  253. /package/contracts/oapps/{oft → oft-core}/src/codec/oft_compose_msg_codec.rs +0 -0
  254. /package/contracts/oapps/{oft → oft-core}/src/codec/oft_msg_codec.rs +0 -0
  255. /package/contracts/oapps/{oft → oft-core}/src/events.rs +0 -0
  256. /package/contracts/oapps/{oft → oft-core}/src/tests/test_oft_compose_msg_codec.rs +0 -0
  257. /package/contracts/oapps/{oft → oft-core}/src/tests/test_oft_version.rs +0 -0
  258. /package/contracts/oapps/{oft → oft-core}/src/tests/test_quote_oft.rs +0 -0
  259. /package/contracts/oapps/{oft → oft-core}/src/tests/test_quote_send.rs +0 -0
  260. /package/contracts/oapps/{oft → oft-core}/src/tests/test_send.rs +0 -0
  261. /package/contracts/oapps/{oft → oft-core}/src/tests/test_token.rs +0 -0
  262. /package/sdk/test/suites/{testUpgradeable.ts → dummyContractClient.ts} +0 -0
@@ -1,13 +1,12 @@
1
- use crate::errors::OwnableError;
2
- use crate::option_ext::OptionExt;
3
- use common_macros::storage;
4
- use soroban_sdk::{assert_with_error, contractevent, contracttrait, Address, Env};
1
+ use crate::{self as utils, auth::Auth, errors::OwnableError, option_ext::OptionExt};
2
+ use common_macros::{contract_trait, storage};
3
+ use soroban_sdk::{assert_with_error, contractevent, Address, Env};
5
4
 
6
5
  // ===========================================================================
7
6
  // Ownable events
8
7
  // ===========================================================================
9
8
 
10
- /// Event emitted when ownership is transferred.
9
+ /// Event emitted when ownership is transferred (both single-step and two-step completion).
11
10
  #[contractevent]
12
11
  #[derive(Clone, Debug, Eq, PartialEq)]
13
12
  pub struct OwnershipTransferred {
@@ -15,6 +14,15 @@ pub struct OwnershipTransferred {
15
14
  pub new_owner: Address,
16
15
  }
17
16
 
17
+ /// Event emitted when a 2-step ownership transfer is proposed.
18
+ #[contractevent]
19
+ #[derive(Clone, Debug, Eq, PartialEq)]
20
+ pub struct OwnershipTransferring {
21
+ pub old_owner: Address,
22
+ pub new_owner: Address,
23
+ pub ttl: u32,
24
+ }
25
+
18
26
  /// Event emitted when ownership is renounced.
19
27
  #[contractevent]
20
28
  #[derive(Clone, Debug, Eq, PartialEq)]
@@ -31,6 +39,10 @@ pub struct OwnershipRenounced {
31
39
  pub enum OwnableStorage {
32
40
  #[instance(Address)]
33
41
  Owner,
42
+ /// Pending owner for 2-step transfer. Stored in temporary storage with TTL -
43
+ /// automatically expires if not accepted in time.
44
+ #[temporary(Address)]
45
+ PendingOwner,
34
46
  }
35
47
 
36
48
  // ===========================================================================
@@ -38,23 +50,129 @@ pub enum OwnableStorage {
38
50
  // ===========================================================================
39
51
 
40
52
  /// Trait for contracts with single-owner access control.
41
- #[contracttrait]
42
- pub trait Ownable: Sized {
53
+ ///
54
+ /// Extends `Auth` to provide owner-based authorization. The `Auth::authorizer()`
55
+ /// implementation should return the owner address for Ownable contracts.
56
+ ///
57
+ /// Supports both single-step and two-step ownership transfer:
58
+ /// - Single-step: `transfer_ownership` - Immediate transfer (use with caution)
59
+ /// - Two-step: `propose_ownership_transfer` + `accept_ownership` - Safer, requires new owner to accept
60
+ #[contract_trait]
61
+ pub trait Ownable: Sized + Auth {
62
+ // ===========================================================================
63
+ // View functions
64
+ // ===========================================================================
65
+
43
66
  /// Returns the current owner address, or None if no owner is set.
44
- fn owner(env: &soroban_sdk::Env) -> Option<soroban_sdk::Address> {
67
+ fn owner(env: &Env) -> Option<Address> {
45
68
  OwnableStorage::owner(env)
46
69
  }
47
70
 
48
- /// Transfers ownership to a new address. Requires current owner authorization.
49
- fn transfer_ownership(env: &soroban_sdk::Env, new_owner: &soroban_sdk::Address) {
71
+ /// Returns the pending owner address for 2-step transfer, or None if no transfer is pending.
72
+ fn pending_owner(env: &Env) -> Option<Address> {
73
+ OwnableStorage::pending_owner(env)
74
+ }
75
+
76
+ // ===========================================================================
77
+ // Single-step transfer (immediate)
78
+ // ===========================================================================
79
+
80
+ /// Transfers ownership immediately to a new address.
81
+ ///
82
+ /// Use with caution - if you transfer to a wrong address, ownership is lost forever.
83
+ /// Consider using `propose_ownership_transfer` instead.
84
+ ///
85
+ /// # Panics
86
+ /// - `OwnerNotSet` if no owner is currently set
87
+ /// - `TransferInProgress` if a 2-step transfer is in progress
88
+ fn transfer_ownership(env: &Env, new_owner: &Address) {
50
89
  let old_owner = enforce_owner_auth::<Self>(env);
90
+ assert_no_pending_transfer::<Self>(env);
91
+
51
92
  OwnableStorage::set_owner(env, new_owner);
52
93
  OwnershipTransferred { old_owner, new_owner: new_owner.clone() }.publish(env);
53
94
  }
54
95
 
55
- /// Permanently renounces ownership. Requires current owner authorization.
56
- fn renounce_ownership(env: &soroban_sdk::Env) {
96
+ // ===========================================================================
97
+ // Two-step transfer (safer)
98
+ // ===========================================================================
99
+
100
+ /// Proposes an ownership transfer to a new address.
101
+ ///
102
+ /// The new owner must call `accept_ownership()` within `ttl` ledgers
103
+ /// to complete the transfer. The pending transfer will automatically expire after.
104
+ ///
105
+ /// # Arguments
106
+ /// - `new_owner` - The proposed new owner
107
+ /// - `ttl` - Number of ledgers the new owner has to accept.
108
+ /// Use `0` to cancel a pending transfer (new_owner must match pending).
109
+ ///
110
+ /// # Panics
111
+ /// - `OwnerNotSet` if no owner is currently set
112
+ /// - `NoPendingTransfer` when cancelling and no pending transfer exists
113
+ /// - `InvalidTtl` if ttl exceeds max TTL
114
+ /// - `InvalidPendingOwner` when cancelling with wrong new_owner address
115
+ fn propose_ownership_transfer(env: &Env, new_owner: &Address, ttl: u32) {
57
116
  let old_owner = enforce_owner_auth::<Self>(env);
117
+
118
+ // Cancel case: ttl == 0
119
+ if ttl == 0 {
120
+ let pending = Self::pending_owner(env).unwrap_or_panic(env, OwnableError::NoPendingTransfer);
121
+
122
+ // Verify new_owner matches pending (prevents accidental cancellation)
123
+ assert_with_error!(env, pending == *new_owner, OwnableError::InvalidPendingOwner);
124
+
125
+ OwnableStorage::remove_pending_owner(env);
126
+ return;
127
+ }
128
+
129
+ // Initiate case: validate ttl
130
+ assert_with_error!(env, ttl <= env.storage().max_ttl(), OwnableError::InvalidTtl);
131
+
132
+ // Store pending owner with TTL
133
+ OwnableStorage::set_pending_owner(env, new_owner);
134
+ OwnableStorage::extend_pending_owner_ttl(env, ttl, ttl);
135
+
136
+ OwnershipTransferring { old_owner, new_owner: new_owner.clone(), ttl }.publish(env);
137
+ }
138
+
139
+ /// Accepts a pending 2-step ownership transfer.
140
+ ///
141
+ /// Must be called by the pending owner before the TTL expires.
142
+ ///
143
+ /// # Panics
144
+ /// - `NoPendingTransfer` if there is no pending transfer (or it expired)
145
+ fn accept_ownership(env: &Env) {
146
+ let new_owner = Self::pending_owner(env).unwrap_or_panic(env, OwnableError::NoPendingTransfer);
147
+
148
+ // Require authorization from the pending owner
149
+ new_owner.require_auth();
150
+
151
+ // Safe to unwrap: owner must exist if pending_owner exists because:
152
+ // 1. pending_owner can only be set via propose_ownership_transfer, which requires owner auth
153
+ // 2. renounce_ownership is blocked while a 2-step transfer is in progress
154
+ let old_owner = OwnableStorage::owner(env).unwrap();
155
+
156
+ // Transfer ownership
157
+ OwnableStorage::remove_pending_owner(env);
158
+ OwnableStorage::set_owner(env, &new_owner);
159
+
160
+ OwnershipTransferred { old_owner, new_owner }.publish(env);
161
+ }
162
+
163
+ // ===========================================================================
164
+ // Renounce
165
+ // ===========================================================================
166
+
167
+ /// Permanently renounces ownership.
168
+ ///
169
+ /// # Panics
170
+ /// - `OwnerNotSet` if no owner is currently set
171
+ /// - `TransferInProgress` if a 2-step transfer is in progress (cancel it first)
172
+ fn renounce_ownership(env: &Env) {
173
+ let old_owner = enforce_owner_auth::<Self>(env);
174
+ assert_no_pending_transfer::<Self>(env);
175
+
58
176
  OwnableStorage::remove_owner(env);
59
177
  OwnershipRenounced { old_owner }.publish(env);
60
178
  }
@@ -62,7 +180,7 @@ pub trait Ownable: Sized {
62
180
 
63
181
  /// Trait for initializing the owner of the contract.
64
182
  pub trait OwnableInitializer {
65
- fn init_owner(env: &soroban_sdk::Env, owner: &soroban_sdk::Address) {
183
+ fn init_owner(env: &Env, owner: &Address) {
66
184
  assert_with_error!(env, !OwnableStorage::has_owner(env), OwnableError::OwnerAlreadySet);
67
185
  OwnableStorage::set_owner(env, owner);
68
186
  }
@@ -84,3 +202,9 @@ pub fn enforce_owner_auth<T: Ownable>(env: &Env) -> Address {
84
202
  pub fn require_owner_auth<T: Ownable>(env: &Env) {
85
203
  let _ = enforce_owner_auth::<T>(env);
86
204
  }
205
+
206
+ /// Asserts that no 2-step ownership transfer is in progress.
207
+ /// Panics with `TransferInProgress` if a pending transfer exists.
208
+ fn assert_no_pending_transfer<T: Ownable>(env: &Env) {
209
+ assert_with_error!(env, T::pending_owner(env).is_none(), OwnableError::TransferInProgress);
210
+ }
@@ -1,11 +1,11 @@
1
+ use crate::{
2
+ buffer_reader::BufferReader,
3
+ buffer_writer::BufferWriter,
4
+ bytes_ext::BytesExt,
5
+ tests::test_helper::{assert_address_payload_matches, assert_panics_contains},
6
+ };
1
7
  use soroban_sdk::{address_payload::AddressPayload, testutils::Address as _, Address, Bytes, BytesN, Env};
2
8
 
3
- use crate::buffer_reader::BufferReader;
4
- use crate::buffer_writer::BufferWriter;
5
- use crate::bytes_ext::BytesExt;
6
-
7
- use crate::tests::test_helper::{assert_address_payload_matches, assert_panics_contains};
8
-
9
9
  type ReaderStep = fn(&mut BufferReader);
10
10
 
11
11
  fn assert_reader_panics_contains(case: &str, raw: &[u8], step: ReaderStep, expected_substring: &str) {
@@ -1,11 +1,11 @@
1
+ use crate::{
2
+ buffer_reader::BufferReader,
3
+ buffer_writer::BufferWriter,
4
+ bytes_ext::BytesExt,
5
+ tests::test_helper::assert_address_payload_matches,
6
+ };
1
7
  use soroban_sdk::{address_payload::AddressPayload, testutils::Address as _, Address, Bytes, BytesN, Env, U256};
2
8
 
3
- use crate::buffer_reader::BufferReader;
4
- use crate::buffer_writer::BufferWriter;
5
- use crate::bytes_ext::BytesExt;
6
-
7
- use crate::tests::test_helper::assert_address_payload_matches;
8
-
9
9
  /// Helper to test U256 write/read roundtrip
10
10
  fn test_u256_roundtrip(env: &Env, value: &soroban_sdk::U256) {
11
11
  let mut writer = BufferWriter::new(env);
@@ -1,15 +1,13 @@
1
+ use crate::{bytes_ext::BytesExt, tests::test_helper::assert_panics_contains};
1
2
  use soroban_sdk::{Bytes, Env};
2
3
 
3
- use crate::bytes_ext::BytesExt;
4
- use crate::tests::test_helper::assert_panics_contains;
5
-
6
4
  // ============================================
7
5
  // Helper functions
8
6
  // ============================================
9
7
 
10
8
  /// Helper to assert that `to_array::<N>()` panics with BytesExtError::LengthMismatch (1400)
11
9
  fn assert_to_array_panics<const N: usize>(case: &str, raw: &[u8]) {
12
- const EXPECTED: &str = "Error(Contract, #1400)";
10
+ const EXPECTED: &str = "Error(Contract, #1040)"; // LengthMismatch
13
11
  assert_panics_contains(case, EXPECTED, || {
14
12
  let env = Env::default();
15
13
  let bytes = Bytes::from_slice(&env, raw);
@@ -1,6 +1,7 @@
1
1
  mod buffer_reader;
2
2
  mod buffer_writer;
3
3
  mod bytes_ext;
4
+ mod multisig;
4
5
  mod option_ext;
5
6
  mod ownable;
6
7
  mod test_helper;