@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.
- package/.turbo/turbo-build.log +347 -271
- package/.turbo/turbo-lint.log +277 -208
- package/.turbo/turbo-test.log +1700 -1370
- package/Cargo.lock +22 -51
- package/Cargo.toml +6 -1
- package/contracts/common-macros/src/auth.rs +10 -9
- package/contracts/common-macros/src/contract_ttl.rs +1 -4
- package/contracts/common-macros/src/error.rs +1 -3
- package/contracts/common-macros/src/lib.rs +65 -61
- package/contracts/common-macros/src/storage.rs +212 -65
- package/contracts/common-macros/src/tests/auth.rs +75 -6
- package/contracts/common-macros/src/tests/contract_ttl.rs +383 -350
- package/contracts/common-macros/src/tests/error.rs +9 -21
- package/contracts/common-macros/src/tests/lz_contract.rs +80 -0
- package/contracts/common-macros/src/tests/mod.rs +2 -0
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +20 -3
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +28 -1
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contractimpl_code.snap +8 -43
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contracttrait_code.snap +6 -29
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__lz_contract__snapshot_generated_lz_contract_code.snap +31 -0
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_extendable__snapshot_generated_ttl_extendable_code.snap +8 -0
- package/contracts/common-macros/src/tests/storage/extract_fields.rs +87 -0
- package/contracts/common-macros/src/tests/storage/gen_accessor_methods.rs +223 -0
- package/contracts/common-macros/src/tests/storage/gen_args.rs +65 -0
- package/contracts/common-macros/src/tests/storage/gen_enum_variant.rs +78 -0
- package/contracts/common-macros/src/tests/storage/gen_key.rs +108 -0
- package/contracts/common-macros/src/tests/storage/gen_params.rs +105 -0
- package/contracts/common-macros/src/tests/{storage.rs → storage/generate_storage.rs} +54 -129
- package/contracts/common-macros/src/tests/storage/is_primitive_type.rs +48 -0
- package/contracts/common-macros/src/tests/storage/mod.rs +16 -0
- package/contracts/common-macros/src/tests/storage/parse_default.rs +164 -0
- package/contracts/common-macros/src/tests/storage/parse_name.rs +159 -0
- package/contracts/common-macros/src/tests/storage/parse_no_ttl_extension.rs +124 -0
- package/contracts/common-macros/src/tests/storage/parse_storage_type.rs +174 -0
- package/contracts/common-macros/src/tests/storage/snapshots/common_macros__tests__storage__generate_storage__snapshot_generated_storage_code.snap +412 -0
- package/contracts/common-macros/src/tests/storage/storage_kind.rs +39 -0
- package/contracts/common-macros/src/tests/storage/test_setup.rs +25 -0
- package/contracts/common-macros/src/tests/storage/validate_attrs.rs +138 -0
- package/contracts/common-macros/src/tests/storage/variant_config.rs +226 -0
- package/contracts/common-macros/src/tests/test_helpers.rs +4 -10
- package/contracts/common-macros/src/tests/ttl_configurable.rs +2 -2
- package/contracts/common-macros/src/tests/ttl_extendable.rs +32 -0
- package/contracts/common-macros/src/tests/upgradeable.rs +118 -2
- package/contracts/common-macros/src/ttl_configurable.rs +1 -4
- package/contracts/common-macros/src/upgradeable.rs +21 -3
- package/contracts/endpoint-v2/Cargo.toml +0 -4
- package/contracts/endpoint-v2/src/endpoint_v2.rs +37 -17
- package/contracts/endpoint-v2/src/errors.rs +26 -1
- package/contracts/endpoint-v2/src/interfaces/layerzero_endpoint_v2.rs +1 -1
- package/contracts/endpoint-v2/src/interfaces/message_lib_manager.rs +4 -4
- package/contracts/endpoint-v2/src/interfaces/messaging_composer.rs +2 -2
- package/contracts/endpoint-v2/src/lib.rs +0 -1
- package/contracts/endpoint-v2/src/message_lib_manager.rs +39 -8
- package/contracts/endpoint-v2/src/messaging_channel.rs +36 -4
- package/contracts/endpoint-v2/src/messaging_composer.rs +18 -4
- package/contracts/endpoint-v2/src/storage.rs +9 -1
- package/contracts/endpoint-v2/src/tests/endpoint_setup.rs +2 -2
- package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +1 -1
- package/contracts/endpoint-v2/src/tests/endpoint_v2/require_oapp_auth.rs +2 -2
- package/contracts/endpoint-v2/src/tests/message_lib_manager/register_library.rs +3 -3
- package/contracts/endpoint-v2/src/tests/message_lib_manager/require_receive_lib_for_eid.rs +5 -5
- package/contracts/endpoint-v2/src/tests/message_lib_manager/require_registered.rs +2 -2
- package/contracts/endpoint-v2/src/tests/message_lib_manager/require_send_lib_for_eid.rs +5 -5
- package/contracts/endpoint-v2/src/tests/message_lib_manager/require_supported_eid.rs +3 -3
- package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +1 -1
- package/contracts/endpoint-v2/src/tests/messaging_composer/clear_compose.rs +4 -3
- package/contracts/endpoint-v2/src/tests/messaging_composer/lz_compose_alert.rs +7 -2
- package/contracts/endpoint-v2/src/tests/messaging_composer/mod.rs +4 -0
- package/contracts/endpoint-v2/src/tests/messaging_composer/send_compose.rs +7 -2
- package/contracts/layerzero-views/src/layerzero_view.rs +0 -1
- package/contracts/layerzero-views/src/tests/mod.rs +1 -0
- package/contracts/layerzero-views/src/tests/types_tests.rs +31 -0
- package/contracts/layerzero-views/src/types.rs +2 -3
- package/contracts/macro-integration-tests/tests/runtime/contract_ttl/constructor.rs +61 -0
- package/contracts/macro-integration-tests/tests/runtime/contract_ttl/contract_impl_ttl_extension.rs +97 -0
- package/contracts/macro-integration-tests/tests/runtime/contract_ttl/contract_trait_ttl_extension.rs +99 -0
- package/contracts/macro-integration-tests/tests/runtime/contract_ttl/mod.rs +3 -0
- package/contracts/macro-integration-tests/tests/runtime/lz_contract/mod.rs +5 -0
- package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_default.rs +86 -0
- package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_multisig.rs +47 -0
- package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_multisig_upgradeable.rs +77 -0
- package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_upgradeable.rs +114 -0
- package/contracts/macro-integration-tests/tests/runtime/lz_contract/wrapper_upgradeable_no_migration.rs +105 -0
- package/contracts/macro-integration-tests/tests/runtime/multisig/admin_entrypoints.rs +242 -0
- package/contracts/macro-integration-tests/tests/runtime/multisig/mod.rs +9 -0
- package/contracts/macro-integration-tests/tests/runtime/multisig/self_auth.rs +54 -0
- package/contracts/macro-integration-tests/tests/runtime/ownable/initialization.rs +13 -0
- package/contracts/macro-integration-tests/tests/runtime/ownable/mod.rs +1 -0
- package/contracts/macro-integration-tests/tests/runtime/ownable/ownership_transfer.rs +70 -1
- package/contracts/macro-integration-tests/tests/runtime/ownable/two_step_transfer.rs +219 -0
- package/contracts/macro-integration-tests/tests/runtime/storage/keyed_roundtrip.rs +41 -0
- package/contracts/macro-integration-tests/tests/runtime/storage/ttl_extension.rs +48 -16
- package/contracts/macro-integration-tests/tests/runtime/storage/unkeyed_roundtrip.rs +10 -0
- package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/configuration.rs +96 -3
- package/contracts/macro-integration-tests/tests/runtime/ttl_configurable/freeze.rs +4 -0
- package/contracts/macro-integration-tests/tests/runtime/ttl_extendable/extend_instance_ttl.rs +64 -0
- package/contracts/macro-integration-tests/tests/runtime/ttl_extendable/mod.rs +16 -0
- package/contracts/macro-integration-tests/tests/runtime/upgradeable/migrate_guard_and_state.rs +305 -0
- package/contracts/macro-integration-tests/tests/runtime/upgradeable/mod.rs +3 -0
- package/contracts/macro-integration-tests/tests/runtime/upgradeable/no_migration.rs +59 -0
- package/contracts/macro-integration-tests/tests/runtime/upgradeable/upgrade_then_migrate.rs +88 -0
- package/contracts/macro-integration-tests/tests/runtime.rs +5 -0
- package/contracts/macro-integration-tests/tests/ui/contract_impl/fail/not_impl_item.rs +6 -0
- package/contracts/macro-integration-tests/tests/ui/contract_impl/fail/not_impl_item.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/contract_impl/pass/basic.rs +102 -0
- package/contracts/macro-integration-tests/tests/ui/contract_trait/fail/not_a_trait.rs +6 -0
- package/contracts/macro-integration-tests/tests/ui/contract_trait/fail/not_a_trait.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/contract_trait/pass/basic.rs +83 -0
- package/contracts/macro-integration-tests/tests/ui/error/fail/discriminant_too_large.rs +11 -0
- package/contracts/macro-integration-tests/tests/ui/error/fail/discriminant_too_large.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/error/fail/non_enum_input.rs +11 -0
- package/contracts/macro-integration-tests/tests/ui/error/fail/non_enum_input.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/error/pass/basic.rs +22 -0
- package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/invalid_option.rs +6 -0
- package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/invalid_option.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/multisig_rejects_ownable_api.rs +20 -0
- package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/multisig_rejects_ownable_api.stderr +20 -0
- package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/not_a_struct.rs +8 -0
- package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/not_a_struct.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_invalid_inner_option.rs +10 -0
- package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_invalid_inner_option.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_missing_internal.rs +20 -0
- package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_missing_internal.stderr +86 -0
- package/contracts/macro-integration-tests/tests/ui/lz_contract/pass/basic.rs +45 -0
- package/contracts/macro-integration-tests/tests/ui/lz_contract/pass/multisig.rs +34 -0
- package/contracts/macro-integration-tests/tests/ui/lz_contract/pass/multisig_upgradeable.rs +30 -0
- package/contracts/macro-integration-tests/tests/ui/lz_contract/pass/upgradeable.rs +39 -0
- package/contracts/macro-integration-tests/tests/ui/lz_contract/pass/upgradeable_no_migration.rs +28 -0
- package/contracts/macro-integration-tests/tests/ui/multisig/fail/non_struct_input.rs +8 -0
- package/contracts/macro-integration-tests/tests/ui/multisig/fail/non_struct_input.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/multisig/fail/rejects_ownable_api.rs +20 -0
- package/contracts/macro-integration-tests/tests/ui/multisig/fail/rejects_ownable_api.stderr +12 -0
- package/contracts/macro-integration-tests/tests/ui/multisig/fail/rejects_ownable_trait.rs +20 -0
- package/contracts/macro-integration-tests/tests/ui/multisig/fail/rejects_ownable_trait.stderr +5 -0
- package/contracts/macro-integration-tests/tests/ui/multisig/pass/basic.rs +49 -0
- package/contracts/macro-integration-tests/tests/ui/ownable/fail/non_struct_input.rs +8 -0
- package/contracts/macro-integration-tests/tests/ui/ownable/fail/non_struct_input.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_auth.rs +19 -0
- package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_auth.stderr +12 -0
- package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_env.rs +1 -1
- package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_env.stderr +0 -8
- package/contracts/macro-integration-tests/tests/ui/ownable/pass/basic.rs +39 -0
- package/contracts/macro-integration-tests/tests/ui/ownable/pass/only_auth_env_param_variants.rs +7 -1
- package/contracts/macro-integration-tests/tests/ui/storage/fail/invalid_storage_type_param.stderr +1 -1
- package/contracts/macro-integration-tests/tests/ui/storage/fail/missing_storage_type_param.stderr +1 -1
- package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_default_values.rs +11 -0
- package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_default_values.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_name_attrs.rs +11 -0
- package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_name_attrs.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_no_ttl_extension.rs +11 -0
- package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_no_ttl_extension.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/storage/fail/multiple_type_params.stderr +1 -1
- package/contracts/macro-integration-tests/tests/ui/storage/fail/no_ttl_extension_rejects_args.rs +13 -0
- package/contracts/macro-integration-tests/tests/ui/storage/fail/no_ttl_extension_rejects_args.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/storage/pass/api_surface.rs +102 -0
- package/contracts/macro-integration-tests/tests/ui/storage/pass/basic.rs +43 -0
- package/contracts/macro-integration-tests/tests/ui/storage/pass/multi_key.rs +38 -0
- package/contracts/macro-integration-tests/tests/ui/ttl_configurable/fail/missing_auth_trait.rs +14 -0
- package/contracts/macro-integration-tests/tests/ui/ttl_configurable/fail/missing_auth_trait.stderr +71 -0
- package/contracts/macro-integration-tests/tests/ui/ttl_configurable/fail/non_struct_input.rs +8 -0
- package/contracts/macro-integration-tests/tests/ui/ttl_configurable/fail/non_struct_input.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/ttl_configurable/pass/{minimal_contract.rs → basic.rs} +2 -0
- package/contracts/macro-integration-tests/tests/ui/ttl_configurable/pass/multisig_contract.rs +28 -0
- package/contracts/macro-integration-tests/tests/ui/ttl_configurable/pass/ownable_contract.rs +32 -0
- package/contracts/macro-integration-tests/tests/ui/ttl_extendable/fail/non_struct_input.rs +8 -0
- package/contracts/macro-integration-tests/tests/ui/ttl_extendable/fail/non_struct_input.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/ttl_extendable/pass/basic.rs +23 -0
- package/contracts/macro-integration-tests/tests/ui/ttl_extendable/pass/no_user_contractimpl.rs +21 -0
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/attr_args.rs +11 -0
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/attr_args.stderr +29 -0
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_auth_trait.rs +20 -0
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_auth_trait.stderr +71 -0
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_upgradeable_internal.rs +10 -0
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_upgradeable_internal.stderr +79 -0
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/non_struct_input.rs +8 -0
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/non_struct_input.stderr +7 -0
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/basic.rs +43 -0
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/multisig_contract.rs +35 -0
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/no_migration.rs +30 -0
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/no_user_contractimpl.rs +29 -0
- package/contracts/macro-integration-tests/tests/ui_contract_impl.rs +12 -0
- package/contracts/macro-integration-tests/tests/ui_contract_trait.rs +12 -0
- package/contracts/macro-integration-tests/tests/ui_lz_contract.rs +11 -0
- package/contracts/macro-integration-tests/tests/ui_multisig.rs +11 -0
- package/contracts/macro-integration-tests/tests/ui_ttl_extendable.rs +12 -0
- package/contracts/macro-integration-tests/tests/ui_upgradeable.rs +11 -0
- package/contracts/message-libs/blocked-message-lib/Cargo.toml +1 -1
- package/contracts/message-libs/blocked-message-lib/src/lib.rs +4 -1
- package/contracts/message-libs/blocked-message-lib/src/tests/blocked_message_lib_tests.rs +108 -0
- package/contracts/message-libs/blocked-message-lib/src/tests/mod.rs +4 -0
- package/contracts/message-libs/blocked-message-lib/src/tests/setup.rs +40 -0
- package/contracts/message-libs/simple-message-lib/src/lib.rs +1 -1
- package/contracts/message-libs/simple-message-lib/src/tests/mod.rs +2 -0
- package/contracts/message-libs/simple-message-lib/src/tests/setup.rs +124 -0
- package/contracts/message-libs/simple-message-lib/src/tests/simple_message_lib_tests.rs +309 -0
- package/contracts/message-libs/uln-302/src/errors.rs +21 -0
- package/contracts/message-libs/uln-302/src/interfaces/receive_uln.rs +1 -1
- package/contracts/message-libs/uln-302/src/receive_uln.rs +6 -4
- package/contracts/message-libs/uln-302/src/send_uln.rs +15 -6
- package/contracts/message-libs/uln-302/src/storage.rs +5 -5
- package/contracts/message-libs/uln-302/src/tests/uln302/get_config.rs +71 -0
- package/contracts/message-libs/uln-302/src/tests/uln302/mod.rs +1 -0
- package/contracts/message-libs/uln-302/src/uln302.rs +3 -0
- package/contracts/oapps/counter/Cargo.toml +2 -0
- package/contracts/oapps/counter/integration_tests/mod.rs +1 -0
- package/contracts/oapps/counter/integration_tests/setup_sml.rs +6 -4
- package/contracts/oapps/counter/integration_tests/setup_uln.rs +12 -5
- package/contracts/oapps/counter/integration_tests/test_with_blocked.rs +67 -0
- package/contracts/oapps/counter/src/tests/mod.rs +1 -0
- package/contracts/oapps/counter/src/tests/test_u256_ext.rs +48 -0
- package/contracts/oapps/oapp/src/lib.rs +0 -3
- package/contracts/oapps/oapp/src/tests/mod.rs +1 -0
- package/contracts/oapps/oft/integration-tests/setup.rs +2 -3
- package/contracts/oapps/oft/src/lib.rs +3 -0
- package/contracts/oapps/oft/src/tests/extensions/mod.rs +3 -0
- package/contracts/oapps/oft/src/tests/extensions/oft_fee.rs +240 -0
- package/contracts/oapps/oft/src/tests/extensions/pausable.rs +141 -0
- package/contracts/oapps/oft/src/tests/extensions/rate_limiter.rs +447 -0
- package/contracts/oapps/oft/src/tests/mod.rs +2 -0
- package/contracts/oapps/oft/src/tests/oft_types/lock_unlock.rs +180 -0
- package/contracts/oapps/oft/src/tests/oft_types/mod.rs +1 -0
- package/contracts/oapps/oft-core/integration-tests/setup.rs +2 -3
- package/contracts/oapps/oft-core/src/lib.rs +2 -2
- package/contracts/oapps/oft-core/src/tests/mod.rs +1 -1
- package/contracts/oapps/oft-core/src/tests/{test_oft_version.rs → test_oft_version_and_approval.rs} +9 -0
- package/contracts/oapps/oft-core/src/tests/test_utils.rs +0 -43
- package/contracts/upgrader/src/tests/test_upgrader.rs +18 -0
- package/contracts/utils/src/auth.rs +2 -2
- package/contracts/utils/src/buffer_reader.rs +61 -10
- package/contracts/utils/src/buffer_writer.rs +35 -20
- package/contracts/utils/src/bytes_ext.rs +1 -2
- package/contracts/utils/src/errors.rs +5 -3
- package/contracts/utils/src/multisig.rs +59 -36
- package/contracts/utils/src/option_ext.rs +3 -3
- package/contracts/utils/src/ownable.rs +12 -6
- package/contracts/utils/src/tests/auth.rs +179 -0
- package/contracts/utils/src/tests/buffer_reader.rs +203 -1
- package/contracts/utils/src/tests/buffer_writer.rs +176 -5
- package/contracts/utils/src/tests/mod.rs +2 -0
- package/contracts/utils/src/tests/multisig.rs +170 -141
- package/contracts/utils/src/tests/option_ext.rs +1 -1
- package/contracts/utils/src/tests/ownable.rs +156 -161
- package/contracts/utils/src/tests/test_helper.rs +21 -1
- package/contracts/utils/src/tests/testing_utils.rs +84 -2
- package/contracts/utils/src/tests/ttl_configurable.rs +66 -86
- package/contracts/utils/src/tests/ttl_extendable.rs +64 -0
- package/contracts/utils/src/tests/upgradeable.rs +115 -6
- package/contracts/utils/src/ttl_configurable.rs +22 -12
- package/contracts/utils/src/ttl_extendable.rs +1 -3
- package/contracts/utils/src/upgradeable.rs +21 -24
- package/contracts/workers/dvn/src/auth.rs +1 -1
- package/contracts/workers/dvn/src/interfaces/dvn.rs +2 -2
- package/contracts/workers/dvn/src/storage.rs +1 -1
- package/contracts/workers/dvn/src/tests/auth.rs +136 -3
- package/contracts/workers/dvn/src/tests/mod.rs +0 -1
- package/contracts/workers/dvn/src/tests/setup.rs +4 -10
- package/contracts/workers/executor-helper/src/tests/executor_helper.rs +279 -0
- package/contracts/workers/executor-helper/src/tests/setup.rs +106 -1
- package/contracts/workers/worker/src/worker.rs +1 -1
- package/docs/oft-guide.md +5 -5
- package/package.json +5 -7
- package/sdk/.turbo/turbo-test.log +662 -466
- package/sdk/LICENSE +23 -0
- package/sdk/dist/generated/bml.d.ts +101 -106
- package/sdk/dist/generated/bml.js +108 -26
- package/sdk/dist/generated/counter.d.ts +123 -484
- package/sdk/dist/generated/counter.js +103 -25
- package/sdk/dist/generated/dvn.d.ts +141 -699
- package/sdk/dist/generated/dvn.js +106 -28
- package/sdk/dist/generated/dvn_fee_lib.d.ts +31 -248
- package/sdk/dist/generated/dvn_fee_lib.js +27 -24
- package/sdk/dist/generated/endpoint.d.ts +158 -836
- package/sdk/dist/generated/endpoint.js +107 -29
- package/sdk/dist/generated/executor.d.ts +139 -671
- package/sdk/dist/generated/executor.js +106 -28
- package/sdk/dist/generated/executor_fee_lib.d.ts +109 -264
- package/sdk/dist/generated/executor_fee_lib.js +106 -28
- package/sdk/dist/generated/executor_helper.d.ts +95 -92
- package/sdk/dist/generated/executor_helper.js +103 -25
- package/sdk/dist/generated/layerzero_view.d.ts +178 -335
- package/sdk/dist/generated/layerzero_view.js +172 -33
- package/sdk/dist/generated/oft.d.ts +137 -680
- package/sdk/dist/generated/oft.js +103 -25
- package/sdk/dist/generated/price_feed.d.ts +45 -444
- package/sdk/dist/generated/price_feed.js +27 -24
- package/sdk/dist/generated/sml.d.ts +119 -428
- package/sdk/dist/generated/sml.js +103 -25
- package/sdk/dist/generated/treasury.d.ts +109 -288
- package/sdk/dist/generated/treasury.js +103 -25
- package/sdk/dist/generated/uln302.d.ts +190 -527
- package/sdk/dist/generated/uln302.js +170 -31
- package/sdk/dist/generated/upgrader.d.ts +14 -34
- package/sdk/dist/generated/upgrader.js +24 -21
- package/sdk/package.json +3 -4
- package/sdk/test/counter-sml.test.ts +218 -142
- package/sdk/test/counter-uln.test.ts +189 -145
- package/sdk/test/oft-sml.test.ts +173 -156
- package/sdk/test/suites/constants.ts +7 -1
- package/sdk/test/suites/globalSetup.ts +140 -74
- package/sdk/turbo.json +1 -1
- package/tools/ts-bindings-gen/Cargo.toml +4 -4
- package/tools/ts-bindings-gen/src/main.rs +4 -0
- package/turbo.json +3 -0
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__storage__snapshot_generated_storage_code.snap +0 -1072
- package/contracts/endpoint-v2/src/constants.rs +0 -52
- package/contracts/macro-integration-tests/tests/ui/error/fail/attr_not_empty.rs +0 -12
- package/contracts/macro-integration-tests/tests/ui/error/fail/attr_not_empty.stderr +0 -7
- package/contracts/macro-integration-tests/tests/ui/error/pass/attr_on_variant_allowed.rs +0 -20
- package/contracts/macro-integration-tests/tests/ui/error/pass/basic_auto_discriminants.rs +0 -15
- package/contracts/macro-integration-tests/tests/ui/error/pass/mixed_discriminants.rs +0 -16
- package/contracts/macro-integration-tests/tests/ui/ownable/pass/minimal_contract.rs +0 -26
- package/contracts/macro-integration-tests/tests/ui/ownable/pass/namespacing_and_imports.rs +0 -21
- package/contracts/macro-integration-tests/tests/ui/storage/fail/storage_attr_rejects_args.rs +0 -12
- package/contracts/macro-integration-tests/tests/ui/storage/fail/storage_attr_rejects_args.stderr +0 -7
- package/contracts/macro-integration-tests/tests/ui/storage/pass/default_value_on_variant.rs +0 -14
- package/contracts/macro-integration-tests/tests/ui/storage/pass/enum_instance_unit_basic.rs +0 -14
- package/contracts/macro-integration-tests/tests/ui/storage/pass/enum_persistent_named_fields_keyed.rs +0 -16
- package/contracts/macro-integration-tests/tests/ui/storage/pass/enum_temporary_unit_option.rs +0 -15
- package/contracts/macro-integration-tests/tests/ui/storage/pass/name_override.rs +0 -14
- package/contracts/macro-integration-tests/tests/ui/storage/pass/no_auto_ttl_extension.rs +0 -19
- package/contracts/macro-integration-tests/tests/ui/storage/pass/ttl_provider_basic.rs +0 -15
- package/contracts/message-libs/simple-message-lib/src/test.rs +0 -280
- package/contracts/oapps/oapp/src/macro_tests/mod.rs +0 -1
- package/contracts/workers/dvn/src/tests/multisig/mod.rs +0 -3
- package/contracts/workers/dvn/src/tests/multisig/set_signer.rs +0 -132
- package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +0 -109
- package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +0 -106
- /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 `
|
|
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 `
|
|
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
|
-
///
|
|
12
|
-
|
|
13
|
-
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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
|
-
///
|
|
6
|
-
|
|
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
|
-
|
|
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
|
|
64
|
-
pub fn
|
|
65
|
-
self.buffer.append(
|
|
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
|
-
///
|
|
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
|
}
|
|
@@ -27,7 +27,8 @@ pub enum TtlConfigurableError {
|
|
|
27
27
|
/// OwnableError: 1030-1039
|
|
28
28
|
#[contract_error]
|
|
29
29
|
pub enum OwnableError {
|
|
30
|
-
|
|
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
|
-
///
|
|
53
|
+
/// MultiSigError: 1060-1069
|
|
53
54
|
#[contract_error]
|
|
54
|
-
pub enum
|
|
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::
|
|
4
|
-
errors::
|
|
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
|
-
//
|
|
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
|
-
//
|
|
30
|
+
// MultiSig storage
|
|
31
31
|
// ===========================================================================
|
|
32
32
|
|
|
33
|
-
/// Storage keys for
|
|
33
|
+
/// Storage keys for MultiSig.
|
|
34
34
|
#[storage]
|
|
35
|
-
pub enum
|
|
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
|
-
//
|
|
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
|
-
/// `
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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,
|
|
120
|
-
assert_with_error!(env, signatures.len() >= threshold,
|
|
126
|
+
assert_with_error!(env, threshold > 0, MultiSigError::ZeroThreshold);
|
|
127
|
+
assert_with_error!(env, signatures.len() >= threshold, MultiSigError::SignatureError);
|
|
121
128
|
|
|
122
|
-
let signers =
|
|
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
|
-
|
|
137
|
+
MultiSigError::UnsortedSigners
|
|
131
138
|
);
|
|
132
|
-
assert_with_error!(env, signers.iter().any(|s| s == signer),
|
|
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, !
|
|
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
|
-
|
|
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]),
|
|
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 =
|
|
173
|
-
assert_with_error!(env, !signers.iter().any(|s| &s == signer),
|
|
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
|
-
|
|
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 =
|
|
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(),
|
|
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() >=
|
|
196
|
-
|
|
218
|
+
signers.len() >= MultiSigStorage::threshold(env),
|
|
219
|
+
MultiSigError::TotalSignersLessThanThreshold
|
|
197
220
|
);
|
|
198
221
|
|
|
199
222
|
// Update signers list
|
|
200
|
-
|
|
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,
|
|
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
|
-
|
|
213
|
-
|
|
235
|
+
MultiSigStorage::signers(env).len() >= threshold,
|
|
236
|
+
MultiSigError::TotalSignersLessThanThreshold
|
|
214
237
|
);
|
|
215
238
|
|
|
216
239
|
// Update threshold
|
|
217
|
-
|
|
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<
|
|
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<
|
|
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:
|
|
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) {
|