@layerzerolabs/protocol-stellar-v2 0.2.18 → 0.2.20
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 +303 -253
- package/.turbo/turbo-lint.log +66 -65
- package/.turbo/turbo-test.log +1312 -1282
- package/Cargo.lock +21 -8
- package/Cargo.toml +2 -0
- package/contracts/ERROR_SPEC.md +9 -2
- package/contracts/common-macros/src/contract_ttl.rs +18 -7
- package/contracts/common-macros/src/lib.rs +4 -4
- package/contracts/common-macros/src/tests/contract_ttl.rs +1 -1
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contractimpl_code.snap +2 -1
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +7 -12
- package/contracts/common-macros/src/upgradeable.rs +15 -21
- package/contracts/message-libs/uln-302/src/events.rs +4 -0
- package/contracts/message-libs/uln-302/src/send_uln.rs +23 -7
- package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +38 -64
- package/contracts/oapps/counter/Cargo.toml +1 -0
- package/contracts/oapps/counter/integration_tests/setup_uln.rs +1 -1
- package/contracts/oapps/oapp/src/oapp_receiver.rs +1 -1
- package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +113 -65
- package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +111 -82
- package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +293 -65
- package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +331 -56
- package/contracts/oapps/oft/Cargo.toml +10 -7
- package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/test_oft_fee.rs +3 -4
- package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/test_pausable.rs +2 -3
- package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/test_rate_limiter.rs +1 -1
- package/contracts/oapps/oft/integration-tests/mod.rs +1 -1
- package/contracts/oapps/oft/integration-tests/setup.rs +28 -127
- package/contracts/oapps/oft/integration-tests/utils.rs +254 -21
- package/contracts/oapps/oft/src/extensions/oft_fee.rs +23 -8
- package/contracts/oapps/oft/src/extensions/pausable.rs +19 -4
- package/contracts/oapps/oft/src/extensions/rate_limiter.rs +52 -28
- package/contracts/oapps/oft/src/lib.rs +10 -14
- package/contracts/oapps/oft/src/oft.rs +143 -193
- package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +9 -11
- package/contracts/oapps/oft/src/oft_types/mint_burn.rs +12 -14
- package/contracts/oapps/oft/src/oft_types/mod.rs +13 -0
- package/contracts/oapps/{oft-std → oft-core}/Cargo.toml +6 -4
- package/contracts/oapps/{oft-std → oft-core}/integration-tests/mod.rs +1 -1
- package/contracts/oapps/{oft-std → oft-core}/integration-tests/setup.rs +126 -29
- package/contracts/oapps/{oft → oft-core}/integration-tests/test_with_sml.rs +3 -3
- package/contracts/oapps/oft-core/integration-tests/utils.rs +201 -0
- package/contracts/oapps/oft-core/src/lib.rs +18 -0
- package/contracts/oapps/oft-core/src/oft_core.rs +479 -0
- package/contracts/oapps/{oft → oft-core}/src/tests/mod.rs +0 -2
- package/contracts/oapps/{oft → oft-core}/src/tests/test_lz_receive.rs +7 -7
- package/contracts/oapps/{oft → oft-core}/src/tests/test_oft_msg_codec.rs +4 -4
- package/contracts/oapps/{oft → oft-core}/src/tests/test_resolve_address.rs +3 -3
- package/contracts/oapps/{oft → oft-core}/src/tests/test_utils.rs +46 -27
- package/contracts/oapps/{oft → oft-core}/src/utils.rs +1 -1
- package/contracts/upgrader/src/lib.rs +30 -57
- package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract1.wasm +0 -0
- package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract2.wasm +0 -0
- package/contracts/upgrader/src/tests/test_upgrader.rs +44 -35
- package/contracts/utils/src/buffer_reader.rs +1 -0
- package/contracts/utils/src/errors.rs +8 -2
- package/contracts/utils/src/ownable.rs +125 -3
- package/contracts/utils/src/tests/option_ext.rs +1 -1
- package/contracts/utils/src/tests/ownable.rs +445 -7
- package/contracts/utils/src/tests/ttl_configurable.rs +2 -2
- package/contracts/utils/src/tests/upgradeable.rs +372 -175
- package/contracts/utils/src/ttl_configurable.rs +3 -3
- package/contracts/utils/src/upgradeable.rs +48 -23
- package/contracts/workers/dvn/Cargo.toml +1 -0
- package/contracts/workers/dvn/src/auth.rs +12 -42
- package/contracts/workers/dvn/src/dvn.rs +16 -31
- package/contracts/workers/dvn/src/errors.rs +0 -1
- package/contracts/workers/dvn/src/interfaces/dvn.rs +35 -0
- package/contracts/workers/dvn/src/lib.rs +4 -3
- package/contracts/workers/dvn/src/tests/auth.rs +1 -1
- package/contracts/workers/dvn/src/tests/dvn.rs +19 -15
- package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +2 -4
- package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +1 -3
- package/contracts/workers/dvn/src/tests/setup.rs +5 -9
- package/contracts/workers/dvn-fee-lib/Cargo.toml +1 -1
- package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +3 -5
- package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +2 -3
- package/contracts/workers/executor/Cargo.toml +1 -0
- package/contracts/workers/executor/src/executor.rs +15 -26
- package/contracts/workers/executor-fee-lib/Cargo.toml +2 -1
- package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +63 -5
- package/contracts/workers/executor-fee-lib/src/executor_option.rs +28 -1
- package/contracts/workers/executor-fee-lib/src/lib.rs +3 -0
- package/contracts/workers/executor-fee-lib/src/tests/executor_fee_lib.rs +701 -0
- package/contracts/workers/executor-fee-lib/src/tests/executor_option.rs +370 -0
- package/contracts/workers/executor-fee-lib/src/tests/mod.rs +4 -0
- package/contracts/workers/executor-fee-lib/src/tests/setup.rs +60 -0
- package/contracts/workers/executor-helper/src/lib.rs +3 -0
- package/contracts/workers/executor-helper/src/tests/executor_helper.rs +184 -0
- package/contracts/workers/executor-helper/src/tests/mod.rs +2 -0
- package/contracts/workers/executor-helper/src/tests/setup.rs +366 -0
- package/contracts/workers/fee-lib-interfaces/Cargo.toml +14 -0
- package/contracts/workers/{worker/src/interfaces/mod.rs → fee-lib-interfaces/src/lib.rs} +4 -3
- package/contracts/workers/price-feed/Cargo.toml +2 -1
- package/contracts/workers/price-feed/src/events.rs +1 -1
- package/contracts/workers/price-feed/src/lib.rs +3 -0
- package/contracts/workers/price-feed/src/price_feed.rs +6 -12
- package/contracts/workers/price-feed/src/storage.rs +1 -1
- package/contracts/workers/price-feed/src/tests/mod.rs +2 -0
- package/contracts/workers/price-feed/src/tests/price_feed.rs +869 -0
- package/contracts/workers/price-feed/src/tests/setup.rs +70 -0
- package/contracts/workers/price-feed/src/types.rs +1 -1
- package/contracts/workers/worker/src/errors.rs +0 -3
- package/contracts/workers/worker/src/lib.rs +0 -2
- package/contracts/workers/worker/src/storage.rs +32 -29
- package/contracts/workers/worker/src/tests/setup.rs +1 -7
- package/contracts/workers/worker/src/tests/worker.rs +50 -42
- package/contracts/workers/worker/src/worker.rs +49 -58
- package/package.json +4 -5
- package/sdk/.turbo/turbo-test.log +229 -217
- package/sdk/dist/generated/bml.d.ts +39 -1
- package/sdk/dist/generated/bml.js +33 -8
- package/sdk/dist/generated/counter.d.ts +131 -3
- package/sdk/dist/generated/counter.js +41 -10
- package/sdk/dist/generated/dvn.d.ts +431 -362
- package/sdk/dist/generated/dvn.js +80 -55
- package/sdk/dist/generated/dvn_fee_lib.d.ts +327 -251
- package/sdk/dist/generated/dvn_fee_lib.js +55 -57
- package/sdk/dist/generated/endpoint.d.ts +131 -3
- package/sdk/dist/generated/endpoint.js +41 -10
- package/sdk/dist/generated/executor.d.ts +503 -339
- package/sdk/dist/generated/executor.js +80 -48
- package/sdk/dist/generated/executor_fee_lib.d.ts +395 -319
- package/sdk/dist/generated/executor_fee_lib.js +54 -56
- package/sdk/dist/generated/executor_helper.d.ts +53 -187
- package/sdk/dist/generated/executor_helper.js +47 -29
- package/sdk/dist/generated/layerzero_view.d.ts +1271 -0
- package/sdk/dist/generated/layerzero_view.js +294 -0
- package/sdk/dist/generated/oft.d.ts +1851 -0
- package/sdk/dist/generated/oft.js +347 -0
- package/sdk/dist/generated/price_feed.d.ts +329 -253
- package/sdk/dist/generated/price_feed.js +55 -57
- package/sdk/dist/generated/sml.d.ts +131 -3
- package/sdk/dist/generated/sml.js +41 -10
- package/sdk/dist/generated/treasury.d.ts +131 -3
- package/sdk/dist/generated/treasury.js +41 -10
- package/sdk/dist/generated/uln302.d.ts +131 -3
- package/sdk/dist/generated/uln302.js +43 -12
- package/sdk/dist/generated/upgrader.d.ts +201 -15
- package/sdk/dist/generated/upgrader.js +99 -1
- package/sdk/dist/index.d.ts +2 -2
- package/sdk/dist/index.js +3 -3
- package/sdk/package.json +3 -2
- package/sdk/src/index.ts +3 -3
- package/sdk/test/oft-sml.test.ts +20 -20
- package/sdk/test/upgrader.test.ts +2 -3
- package/sdk/turbo.json +8 -0
- package/tools/ts-bindings-gen/Cargo.toml +2 -0
- package/tools/ts-bindings-gen/src/main.rs +53 -5
- package/turbo.json +0 -2
- package/contracts/oapps/oft/src/interfaces/mint_burn_token.rs +0 -23
- package/contracts/oapps/oft/src/interfaces/mod.rs +0 -3
- package/contracts/oapps/oft/src/oft_impl.rs +0 -201
- package/contracts/oapps/oft/src/tests/extensions/mod.rs +0 -11
- package/contracts/oapps/oft/src/tests/extensions/setup.rs +0 -917
- package/contracts/oapps/oft/src/tests/extensions/test_oft_fee.rs +0 -751
- package/contracts/oapps/oft/src/tests/extensions/test_pausable.rs +0 -434
- package/contracts/oapps/oft/src/tests/extensions/test_rate_limiter.rs +0 -1080
- package/contracts/oapps/oft-std/integration-tests/utils.rs +0 -427
- package/contracts/oapps/oft-std/src/lib.rs +0 -16
- package/contracts/oapps/oft-std/src/oft.rs +0 -174
- package/sdk/dist/generated/oft_std.d.ts +0 -1722
- package/sdk/dist/generated/oft_std.js +0 -316
- package/sdk/dist/wasm/blocked-message-lib.d.ts +0 -1
- package/sdk/dist/wasm/blocked-message-lib.js +0 -2
- package/sdk/dist/wasm/counter.d.ts +0 -1
- package/sdk/dist/wasm/counter.js +0 -2
- package/sdk/dist/wasm/dvn-fee-lib.d.ts +0 -1
- package/sdk/dist/wasm/dvn-fee-lib.js +0 -2
- package/sdk/dist/wasm/dvn.d.ts +0 -1
- package/sdk/dist/wasm/dvn.js +0 -2
- package/sdk/dist/wasm/endpoint-v2.d.ts +0 -1
- package/sdk/dist/wasm/endpoint-v2.js +0 -2
- package/sdk/dist/wasm/executor-fee-lib.d.ts +0 -1
- package/sdk/dist/wasm/executor-fee-lib.js +0 -2
- package/sdk/dist/wasm/executor-helper.d.ts +0 -1
- package/sdk/dist/wasm/executor-helper.js +0 -2
- package/sdk/dist/wasm/executor.d.ts +0 -1
- package/sdk/dist/wasm/executor.js +0 -2
- package/sdk/dist/wasm/layerzero-views.d.ts +0 -1
- package/sdk/dist/wasm/layerzero-views.js +0 -2
- package/sdk/dist/wasm/oft-std.d.ts +0 -1
- package/sdk/dist/wasm/oft-std.js +0 -2
- package/sdk/dist/wasm/price-feed.d.ts +0 -1
- package/sdk/dist/wasm/price-feed.js +0 -2
- package/sdk/dist/wasm/simple-message-lib.d.ts +0 -1
- package/sdk/dist/wasm/simple-message-lib.js +0 -2
- package/sdk/dist/wasm/treasury.d.ts +0 -1
- package/sdk/dist/wasm/treasury.js +0 -2
- package/sdk/dist/wasm/uln302.d.ts +0 -1
- package/sdk/dist/wasm/uln302.js +0 -2
- package/sdk/dist/wasm/upgrader.d.ts +0 -1
- package/sdk/dist/wasm/upgrader.js +0 -2
- package/sdk/dist/wasm.d.ts +0 -15
- package/sdk/dist/wasm.js +0 -15
- /package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/mod.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/codec/mod.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/codec/oft_compose_msg_codec.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/codec/oft_msg_codec.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/errors.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/events.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/storage.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_decimals.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_oft_compose_msg_codec.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_oft_version.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_quote_oft.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_quote_send.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_send.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_token.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/types.rs +0 -0
- /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/dvn_fee_lib.rs +0 -0
- /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/executor_fee_lib.rs +0 -0
- /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/price_feed.rs +0 -0
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
//! OFT - traits and implementations for Omnichain Fungible Tokens.
|
|
2
|
+
//!
|
|
3
|
+
//! This module provides:
|
|
4
|
+
//! - `OFTInternal`: Internal methods NOT exposed as contract entrypoints (`__debit`, `__credit`, `__initialize_oft`, etc.)
|
|
5
|
+
//! - `OFTCore`: Public methods exposed as contract entrypoints (using `#[contracttrait]`)
|
|
6
|
+
//! - `impl_oft_lz_receive!`: Macro to implement `LzReceiveInternal` with default OFT receive logic
|
|
7
|
+
//! - Helper functions: `lz_receive` for handling incoming cross-chain transfers
|
|
8
|
+
//!
|
|
9
|
+
//! ## Usage
|
|
10
|
+
//!
|
|
11
|
+
//! ```ignore
|
|
12
|
+
//! use oapp_macros::oapp;
|
|
13
|
+
//! use oft_core::{OFTInternal, OFTCore, impl_oft_lz_receive};
|
|
14
|
+
//!
|
|
15
|
+
//! #[oapp]
|
|
16
|
+
//! pub struct MyOFT;
|
|
17
|
+
//!
|
|
18
|
+
//! #[contractimpl]
|
|
19
|
+
//! impl MyOFT {
|
|
20
|
+
//! pub fn __constructor(env: &Env, token: &Address, owner: &Address, endpoint: &Address, delegate: &Option<Address>) {
|
|
21
|
+
//! Self::__initialize_oft(env, owner, token, endpoint, delegate, 6)
|
|
22
|
+
//! }
|
|
23
|
+
//! }
|
|
24
|
+
//!
|
|
25
|
+
//! // Public methods - exposed as contract entrypoints
|
|
26
|
+
//! #[contractimpl(contracttrait)]
|
|
27
|
+
//! impl OFTCore for MyOFT {}
|
|
28
|
+
//!
|
|
29
|
+
//! // Internal methods - NOT exposed as contract entrypoints
|
|
30
|
+
//! // IMPORTANT: Do NOT use #[contractimpl] here to keep methods internal
|
|
31
|
+
//! impl OFTInternal for MyOFT {
|
|
32
|
+
//! fn __debit(env: &Env, sender: &Address, amount_ld: i128, min_amount_ld: i128, dst_eid: u32) -> OFTReceipt {
|
|
33
|
+
//! // Your debit logic (e.g., burn or lock tokens)
|
|
34
|
+
//! oft_core::oft_types::mint_burn::debit::<Self>(env, sender, amount_ld, min_amount_ld, dst_eid)
|
|
35
|
+
//! }
|
|
36
|
+
//!
|
|
37
|
+
//! fn __credit(env: &Env, to: &Address, amount_ld: i128, src_eid: u32) -> i128 {
|
|
38
|
+
//! // Your credit logic (e.g., mint or unlock tokens)
|
|
39
|
+
//! oft_core::oft_types::mint_burn::credit::<Self>(env, to, amount_ld, src_eid)
|
|
40
|
+
//! }
|
|
41
|
+
//! }
|
|
42
|
+
//!
|
|
43
|
+
//! // LzReceiveInternal - use the macro for default OFT receive logic
|
|
44
|
+
//! impl_oft_lz_receive!(MyOFT);
|
|
45
|
+
//! ```
|
|
46
|
+
|
|
47
|
+
use crate::{
|
|
48
|
+
self as oft_core,
|
|
49
|
+
codec::{oft_compose_msg_codec::OFTComposeMsg, oft_msg_codec::OFTMessage},
|
|
50
|
+
errors::OFTError,
|
|
51
|
+
events::{self, OFTSent},
|
|
52
|
+
storage::OFTStorage,
|
|
53
|
+
types::{self, OFTFeeDetail, OFTLimit, OFTReceipt, SendParam},
|
|
54
|
+
utils as oft_utils,
|
|
55
|
+
};
|
|
56
|
+
use common_macros::contract_trait;
|
|
57
|
+
use endpoint_v2::{MessagingComposerClient, MessagingFee, MessagingReceipt};
|
|
58
|
+
use oapp::{
|
|
59
|
+
oapp_core::{initialize_oapp, OAppCore},
|
|
60
|
+
oapp_options_type3::OAppOptionsType3,
|
|
61
|
+
oapp_receiver::OAppReceiver,
|
|
62
|
+
oapp_sender::OAppSenderInternal,
|
|
63
|
+
};
|
|
64
|
+
use soroban_sdk::{assert_with_error, token::TokenClient, vec, Address, Bytes, Env, Vec};
|
|
65
|
+
use utils::{option_ext::OptionExt, ownable::OwnableInitializer};
|
|
66
|
+
|
|
67
|
+
// ===========================================================================
|
|
68
|
+
// OFTInternal Trait (NOT exposed as contract entrypoints)
|
|
69
|
+
// ===========================================================================
|
|
70
|
+
|
|
71
|
+
/// Internal OFT trait containing methods that should NOT be exposed as contract entrypoints.
|
|
72
|
+
///
|
|
73
|
+
/// **IMPORTANT**: Implement this trait WITHOUT the `#[contractimpl]` macro to keep
|
|
74
|
+
/// `__debit`, `__credit`, and other internal methods private to the contract.
|
|
75
|
+
///
|
|
76
|
+
/// ```ignore
|
|
77
|
+
/// // Correct - methods stay internal
|
|
78
|
+
/// impl OFTInternal for MyOFT { ... }
|
|
79
|
+
///
|
|
80
|
+
/// // WRONG - would expose methods as entrypoints
|
|
81
|
+
/// #[contractimpl]
|
|
82
|
+
/// impl OFTInternal for MyOFT { ... }
|
|
83
|
+
/// ```
|
|
84
|
+
///
|
|
85
|
+
/// This trait extends all OApp supertraits and contains both the token operations
|
|
86
|
+
/// and the internal sending logic. `OFTCore` serves only as an entrypoint wrapper.
|
|
87
|
+
pub trait OFTInternal: OAppCore + OAppReceiver + OAppSenderInternal + OAppOptionsType3 + OwnableInitializer {
|
|
88
|
+
// =========================================================================
|
|
89
|
+
// Initialization
|
|
90
|
+
// =========================================================================
|
|
91
|
+
|
|
92
|
+
/// Initializes the OFT (Omnichain Fungible Token) contract.
|
|
93
|
+
///
|
|
94
|
+
/// Sets up the OApp infrastructure and configures decimal conversion for cross-chain transfers.
|
|
95
|
+
/// The `shared_decimals` parameter defines the common decimal precision used across all chains,
|
|
96
|
+
/// enabling consistent token amounts regardless of each chain's native token decimals.
|
|
97
|
+
///
|
|
98
|
+
/// # Arguments
|
|
99
|
+
/// * `owner` - The address that will own this OFT contract
|
|
100
|
+
/// * `token` - The underlying token contract address (must implement SEP-41 token interface)
|
|
101
|
+
/// * `endpoint` - The LayerZero endpoint address for cross-chain messaging
|
|
102
|
+
/// * `delegate` - Optional delegate address for endpoint configuration permissions
|
|
103
|
+
/// * `shared_decimals` - The shared decimal precision for cross-chain compatibility (must be <= local decimals)
|
|
104
|
+
///
|
|
105
|
+
/// # Panics
|
|
106
|
+
/// * `OFTError::InvalidLocalDecimals` - If the token's local decimals are less than `shared_decimals`
|
|
107
|
+
fn __initialize_oft(
|
|
108
|
+
env: &Env,
|
|
109
|
+
owner: &Address,
|
|
110
|
+
token: &Address,
|
|
111
|
+
endpoint: &Address,
|
|
112
|
+
delegate: &Option<Address>,
|
|
113
|
+
shared_decimals: u32,
|
|
114
|
+
) {
|
|
115
|
+
// Initialize OApp (includes owner initialization)
|
|
116
|
+
initialize_oapp::<Self>(env, owner, endpoint, delegate);
|
|
117
|
+
|
|
118
|
+
let local_decimals = TokenClient::new(env, token).decimals();
|
|
119
|
+
assert_with_error!(env, local_decimals >= shared_decimals, OFTError::InvalidLocalDecimals);
|
|
120
|
+
|
|
121
|
+
// Initialize OFT storage
|
|
122
|
+
OFTStorage::set_token(env, token);
|
|
123
|
+
OFTStorage::set_decimal_conversion_rate(env, &10_i128.pow(local_decimals - shared_decimals));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// =========================================================================
|
|
127
|
+
// Required Methods (no defaults - user MUST implement)
|
|
128
|
+
// =========================================================================
|
|
129
|
+
|
|
130
|
+
/// Debits tokens from the specified address for cross-chain transfer.
|
|
131
|
+
///
|
|
132
|
+
/// # Arguments
|
|
133
|
+
/// * `from` - The address to debit the tokens from
|
|
134
|
+
/// * `amount_ld` - The amount of tokens to send in local decimals
|
|
135
|
+
/// * `min_amount_ld` - The minimum amount to send in local decimals
|
|
136
|
+
/// * `dst_eid` - The destination chain ID
|
|
137
|
+
///
|
|
138
|
+
/// # Returns
|
|
139
|
+
/// `OFTReceipt` containing the amount sent and amount received
|
|
140
|
+
fn __debit(env: &Env, from: &Address, amount_ld: i128, min_amount_ld: i128, dst_eid: u32) -> OFTReceipt;
|
|
141
|
+
|
|
142
|
+
/// Credits tokens to recipient after receiving cross-chain transfer.
|
|
143
|
+
///
|
|
144
|
+
/// # Arguments
|
|
145
|
+
/// * `to` - The address to credit tokens to
|
|
146
|
+
/// * `amount_ld` - Amount in local decimals to credit
|
|
147
|
+
/// * `src_eid` - Source endpoint ID
|
|
148
|
+
///
|
|
149
|
+
/// # Returns
|
|
150
|
+
/// The amount actually credited
|
|
151
|
+
fn __credit(env: &Env, to: &Address, amount_ld: i128, src_eid: u32) -> i128;
|
|
152
|
+
|
|
153
|
+
// =========================================================================
|
|
154
|
+
// Optional Methods (have defaults - override as needed)
|
|
155
|
+
// =========================================================================
|
|
156
|
+
|
|
157
|
+
// ----- Quote Methods -----
|
|
158
|
+
|
|
159
|
+
/// Quotes an OFT transfer without executing.
|
|
160
|
+
///
|
|
161
|
+
/// The default implementation has no send limits (`min_amount_ld: 0`, `max_amount_ld: i128::MAX`)
|
|
162
|
+
/// and no fee details (empty vector). Override this method to implement custom limits or fees.
|
|
163
|
+
///
|
|
164
|
+
/// # Arguments
|
|
165
|
+
/// * `send_param` - The send parameters to quote
|
|
166
|
+
///
|
|
167
|
+
/// # Returns
|
|
168
|
+
/// A tuple of (transfer limits, fee details, estimated receipt)
|
|
169
|
+
fn __quote_oft(env: &Env, send_param: &SendParam) -> (OFTLimit, Vec<OFTFeeDetail>, OFTReceipt) {
|
|
170
|
+
let limit = OFTLimit { min_amount_ld: 0, max_amount_ld: i128::MAX };
|
|
171
|
+
let fee_details = vec![env];
|
|
172
|
+
let oft_receipt = Self::__debit_view(env, send_param.amount_ld, send_param.min_amount_ld, send_param.dst_eid);
|
|
173
|
+
(limit, fee_details, oft_receipt)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/// Quotes the LayerZero messaging fee for a send operation.
|
|
177
|
+
///
|
|
178
|
+
/// # Arguments
|
|
179
|
+
/// * `from` - The address initiating the transfer
|
|
180
|
+
/// * `send_param` - The send parameters to quote
|
|
181
|
+
/// * `pay_in_zro` - Whether to pay the fee in ZRO token
|
|
182
|
+
///
|
|
183
|
+
/// # Returns
|
|
184
|
+
/// The messaging fee required for the transfer
|
|
185
|
+
fn __quote_send(env: &Env, from: &Address, send_param: &SendParam, pay_in_zro: bool) -> MessagingFee {
|
|
186
|
+
let OFTReceipt { amount_received_ld, .. } =
|
|
187
|
+
Self::__debit_view(env, send_param.amount_ld, send_param.min_amount_ld, send_param.dst_eid);
|
|
188
|
+
|
|
189
|
+
let (msg, options) = Self::__build_msg_and_options(env, from, send_param, amount_received_ld);
|
|
190
|
+
Self::__quote(env, send_param.dst_eid, &msg, &options, pay_in_zro)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// ----- Send Method -----
|
|
194
|
+
|
|
195
|
+
/// Executes a cross-chain token transfer via LayerZero.
|
|
196
|
+
///
|
|
197
|
+
/// Debits tokens from the `from` address, builds the message, and sends via the endpoint.
|
|
198
|
+
/// The `from` address must be authenticated.
|
|
199
|
+
///
|
|
200
|
+
/// # Arguments
|
|
201
|
+
/// * `from` - The address sending tokens (must authorize)
|
|
202
|
+
/// * `send_param` - The send parameters (destination, recipient, amount, options)
|
|
203
|
+
/// * `fee` - The messaging fee to pay
|
|
204
|
+
/// * `refund_address` - The address to refund excess fees to
|
|
205
|
+
///
|
|
206
|
+
/// # Returns
|
|
207
|
+
/// A tuple of (messaging receipt, OFT receipt with amounts)
|
|
208
|
+
fn __send(
|
|
209
|
+
env: &Env,
|
|
210
|
+
from: &Address,
|
|
211
|
+
send_param: &SendParam,
|
|
212
|
+
fee: &MessagingFee,
|
|
213
|
+
refund_address: &Address,
|
|
214
|
+
) -> (MessagingReceipt, OFTReceipt) {
|
|
215
|
+
from.require_auth();
|
|
216
|
+
|
|
217
|
+
let oft_receipt = Self::__debit(env, from, send_param.amount_ld, send_param.min_amount_ld, send_param.dst_eid);
|
|
218
|
+
|
|
219
|
+
let (msg, options) = Self::__build_msg_and_options(env, from, send_param, oft_receipt.amount_received_ld);
|
|
220
|
+
let msg_receipt = Self::__lz_send(env, send_param.dst_eid, &msg, &options, from, fee, refund_address);
|
|
221
|
+
|
|
222
|
+
OFTSent {
|
|
223
|
+
guid: msg_receipt.guid.clone(),
|
|
224
|
+
dst_eid: send_param.dst_eid,
|
|
225
|
+
from: from.clone(),
|
|
226
|
+
amount_sent_ld: oft_receipt.amount_sent_ld,
|
|
227
|
+
amount_received_ld: oft_receipt.amount_received_ld,
|
|
228
|
+
}
|
|
229
|
+
.publish(env);
|
|
230
|
+
|
|
231
|
+
(msg_receipt, oft_receipt)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// ----- View/Helper Methods -----
|
|
235
|
+
|
|
236
|
+
/// Simulates a debit operation without executing, used for quoting.
|
|
237
|
+
///
|
|
238
|
+
/// The default implementation does not charge any fee, so `amount_sent_ld` equals
|
|
239
|
+
/// `amount_received_ld` (after dust removal). Override this method to implement
|
|
240
|
+
/// custom fee logic.
|
|
241
|
+
///
|
|
242
|
+
/// # Arguments
|
|
243
|
+
/// * `amount_ld` - The amount of tokens to send in local decimals
|
|
244
|
+
/// * `min_amount_ld` - The minimum amount to send in local decimals (slippage protection)
|
|
245
|
+
/// * `dst_eid` - The destination chain ID (unused in default implementation)
|
|
246
|
+
///
|
|
247
|
+
/// # Returns
|
|
248
|
+
/// `OFTReceipt` containing the amount sent and amount received after dust removal
|
|
249
|
+
///
|
|
250
|
+
/// # Panics
|
|
251
|
+
/// * `OFTError::SlippageExceeded` - If `amount_received_ld` is less than `min_amount_ld`
|
|
252
|
+
fn __debit_view(env: &Env, amount_ld: i128, min_amount_ld: i128, _dst_eid: u32) -> OFTReceipt {
|
|
253
|
+
let conversion_rate = Self::__decimal_conversion_rate(env);
|
|
254
|
+
let amount_sent_ld = oft_utils::remove_dust(amount_ld, conversion_rate);
|
|
255
|
+
let amount_received_ld = amount_sent_ld;
|
|
256
|
+
|
|
257
|
+
assert_with_error!(env, amount_received_ld >= min_amount_ld, OFTError::SlippageExceeded);
|
|
258
|
+
|
|
259
|
+
OFTReceipt { amount_sent_ld, amount_received_ld }
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/// Builds OFT message and combines options for cross-chain transfer.
|
|
263
|
+
///
|
|
264
|
+
/// # Arguments
|
|
265
|
+
/// * `from` - The address initiating the transfer
|
|
266
|
+
/// * `send_param` - The send parameters including destination, recipient, and options
|
|
267
|
+
/// * `receive_amount_ld` - The amount to be received in local decimals (after dust removal)
|
|
268
|
+
///
|
|
269
|
+
/// # Returns
|
|
270
|
+
/// A tuple of (encoded message, combined options)
|
|
271
|
+
fn __build_msg_and_options(
|
|
272
|
+
env: &Env,
|
|
273
|
+
from: &Address,
|
|
274
|
+
send_param: &SendParam,
|
|
275
|
+
receive_amount_ld: i128,
|
|
276
|
+
) -> (Bytes, Bytes) {
|
|
277
|
+
let has_compose = !send_param.compose_msg.is_empty();
|
|
278
|
+
let conversion_rate = Self::__decimal_conversion_rate(env);
|
|
279
|
+
let (msg, _) = OFTMessage {
|
|
280
|
+
send_to: send_param.to.clone(),
|
|
281
|
+
amount_sd: oft_utils::to_sd(env, receive_amount_ld, conversion_rate),
|
|
282
|
+
compose_from: if has_compose { Some(oft_utils::address_payload(from)) } else { None },
|
|
283
|
+
compose_msg: if has_compose { Some(send_param.compose_msg.clone()) } else { None },
|
|
284
|
+
}
|
|
285
|
+
.encode(env);
|
|
286
|
+
let msg_type = if has_compose { types::SEND_AND_CALL } else { types::SEND };
|
|
287
|
+
|
|
288
|
+
(msg, Self::combine_options(env, send_param.dst_eid, msg_type, &send_param.extra_options))
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// ----- Storage Accessors -----
|
|
292
|
+
|
|
293
|
+
/// Retrieves the token address associated with this OFT.
|
|
294
|
+
fn __token(env: &Env) -> Address {
|
|
295
|
+
OFTStorage::token(env).unwrap_or_panic(env, OFTError::NotInitialized)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/// Retrieves the decimal conversion rate used for cross-chain normalization.
|
|
299
|
+
fn __decimal_conversion_rate(env: &Env) -> i128 {
|
|
300
|
+
OFTStorage::decimal_conversion_rate(env).unwrap_or_panic(env, OFTError::NotInitialized)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/// Retrieves the shared decimals used for cross-chain normalization.
|
|
304
|
+
fn __shared_decimals(env: &Env) -> u32 {
|
|
305
|
+
let token = Self::__token(env);
|
|
306
|
+
let local_decimals = TokenClient::new(env, &token).decimals();
|
|
307
|
+
let conversion_rate = Self::__decimal_conversion_rate(env);
|
|
308
|
+
local_decimals - conversion_rate.ilog10()
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// ===========================================================================
|
|
313
|
+
// OFTCore Trait (exposed as contract entrypoints)
|
|
314
|
+
// ===========================================================================
|
|
315
|
+
|
|
316
|
+
/// The public OFT trait defining the cross-chain token transfer interface.
|
|
317
|
+
///
|
|
318
|
+
/// This trait is marked with `#[contracttrait]` so all its methods are exposed as
|
|
319
|
+
/// contract entrypoints. Users implement this with `#[contractimpl(contracttrait)]`.
|
|
320
|
+
///
|
|
321
|
+
/// This trait only exposes entrypoints. All internal logic is in `OFTInternal`.
|
|
322
|
+
#[contract_trait(client_name = "OFTClient")]
|
|
323
|
+
pub trait OFTCore: OFTInternal {
|
|
324
|
+
/// Retrieves the token address associated with this OFT.
|
|
325
|
+
fn token(env: &soroban_sdk::Env) -> soroban_sdk::Address {
|
|
326
|
+
Self::__token(env)
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/// Returns OFT version as (major, minor).
|
|
330
|
+
fn oft_version(_env: &soroban_sdk::Env) -> (u64, u64) {
|
|
331
|
+
(1, 1)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/// Retrieves the shared decimals used for cross-chain normalization.
|
|
335
|
+
fn shared_decimals(env: &soroban_sdk::Env) -> u32 {
|
|
336
|
+
Self::__shared_decimals(env)
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/// Retrieves the decimal conversion rate used for cross-chain normalization.
|
|
340
|
+
fn decimal_conversion_rate(env: &soroban_sdk::Env) -> i128 {
|
|
341
|
+
Self::__decimal_conversion_rate(env)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/// Whether a separate token approval is required before sending.
|
|
345
|
+
///
|
|
346
|
+
/// Helps wallet implementers determine integration requirements.
|
|
347
|
+
///
|
|
348
|
+
/// # Returns
|
|
349
|
+
/// - `true` if a separate token approval step is required
|
|
350
|
+
/// - `false` if no separate approval is needed
|
|
351
|
+
fn approval_required(_env: &soroban_sdk::Env) -> bool {
|
|
352
|
+
false
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/// Quotes an OFT transfer without executing.
|
|
356
|
+
///
|
|
357
|
+
/// # Returns
|
|
358
|
+
/// (OFTLimit, fee details, receipt with estimated amounts)
|
|
359
|
+
fn quote_oft(
|
|
360
|
+
env: &soroban_sdk::Env,
|
|
361
|
+
send_param: &oft_core::types::SendParam,
|
|
362
|
+
) -> (oft_core::types::OFTLimit, soroban_sdk::Vec<oft_core::types::OFTFeeDetail>, oft_core::types::OFTReceipt) {
|
|
363
|
+
Self::__quote_oft(env, send_param)
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/// Quotes a send operation including LayerZero messaging fees.
|
|
367
|
+
fn quote_send(
|
|
368
|
+
env: &soroban_sdk::Env,
|
|
369
|
+
from: &soroban_sdk::Address,
|
|
370
|
+
send_param: &oft_core::types::SendParam,
|
|
371
|
+
pay_in_zro: bool,
|
|
372
|
+
) -> endpoint_v2::MessagingFee {
|
|
373
|
+
Self::__quote_send(env, from, send_param, pay_in_zro)
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/// Sends tokens cross-chain to another endpoint.
|
|
377
|
+
///
|
|
378
|
+
/// From must be authenticated.
|
|
379
|
+
///
|
|
380
|
+
/// # Returns
|
|
381
|
+
/// (MessagingReceipt, OFTReceipt)
|
|
382
|
+
fn send(
|
|
383
|
+
env: &soroban_sdk::Env,
|
|
384
|
+
from: &soroban_sdk::Address,
|
|
385
|
+
send_param: &oft_core::types::SendParam,
|
|
386
|
+
fee: &endpoint_v2::MessagingFee,
|
|
387
|
+
refund_address: &soroban_sdk::Address,
|
|
388
|
+
) -> (endpoint_v2::MessagingReceipt, oft_core::types::OFTReceipt) {
|
|
389
|
+
Self::__send(env, from, send_param, fee, refund_address)
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// ===========================================================================
|
|
394
|
+
// LzReceive Handler (called by OAppReceiver)
|
|
395
|
+
// ===========================================================================
|
|
396
|
+
|
|
397
|
+
/// Implements `LzReceiveInternal` for an OFT contract using the default OFT receive logic.
|
|
398
|
+
///
|
|
399
|
+
/// This macro generates the boilerplate `LzReceiveInternal` implementation that delegates
|
|
400
|
+
/// to `oft_core::lz_receive`, which handles decoding the OFT message, crediting tokens
|
|
401
|
+
/// to the recipient, and optionally queuing compose messages.
|
|
402
|
+
///
|
|
403
|
+
/// # Usage
|
|
404
|
+
///
|
|
405
|
+
/// ```ignore
|
|
406
|
+
/// use oft_core::impl_oft_lz_receive;
|
|
407
|
+
///
|
|
408
|
+
/// #[oapp]
|
|
409
|
+
/// pub struct MyOFT;
|
|
410
|
+
///
|
|
411
|
+
/// impl OFTInternal for MyOFT {
|
|
412
|
+
/// // ... implement __debit and __credit ...
|
|
413
|
+
/// }
|
|
414
|
+
///
|
|
415
|
+
/// // Instead of manually implementing LzReceiveInternal:
|
|
416
|
+
/// impl_oft_lz_receive!(MyOFT);
|
|
417
|
+
/// ```
|
|
418
|
+
#[macro_export]
|
|
419
|
+
macro_rules! impl_oft_lz_receive {
|
|
420
|
+
($contract:ty) => {
|
|
421
|
+
impl oapp::oapp_receiver::LzReceiveInternal for $contract {
|
|
422
|
+
fn __lz_receive(
|
|
423
|
+
env: &soroban_sdk::Env,
|
|
424
|
+
origin: &endpoint_v2::Origin,
|
|
425
|
+
guid: &soroban_sdk::BytesN<32>,
|
|
426
|
+
message: &soroban_sdk::Bytes,
|
|
427
|
+
extra_data: &soroban_sdk::Bytes,
|
|
428
|
+
executor: &soroban_sdk::Address,
|
|
429
|
+
value: i128,
|
|
430
|
+
) {
|
|
431
|
+
oft_core::lz_receive::<Self>(env, executor, origin, guid, message, extra_data, value)
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/// Handles incoming cross-chain OFT transfer from LayerZero endpoint.
|
|
438
|
+
///
|
|
439
|
+
/// Credits tokens to the recipient and optionally queues a compose message.
|
|
440
|
+
///
|
|
441
|
+
/// # Arguments
|
|
442
|
+
/// * `executor` - The address of the executor handling the message (unused in default implementation)
|
|
443
|
+
/// * `origin` - The origin information (source chain, sender, nonce)
|
|
444
|
+
/// * `guid` - The unique message identifier
|
|
445
|
+
/// * `message` - The encoded OFT message payload
|
|
446
|
+
/// * `extra_data` - Additional data (unused in default implementation)
|
|
447
|
+
/// * `value` - The native token value sent with the message (unused in default implementation)
|
|
448
|
+
pub fn lz_receive<T: OFTInternal>(
|
|
449
|
+
env: &soroban_sdk::Env,
|
|
450
|
+
_executor: &soroban_sdk::Address,
|
|
451
|
+
origin: &endpoint_v2::Origin,
|
|
452
|
+
guid: &soroban_sdk::BytesN<32>,
|
|
453
|
+
message: &soroban_sdk::Bytes,
|
|
454
|
+
_extra_data: &soroban_sdk::Bytes,
|
|
455
|
+
_value: i128,
|
|
456
|
+
) {
|
|
457
|
+
let oft_msg = OFTMessage::decode(message);
|
|
458
|
+
let send_to = oft_utils::resolve_address(env, &oft_msg.send_to);
|
|
459
|
+
|
|
460
|
+
let conversion_rate = T::__decimal_conversion_rate(env);
|
|
461
|
+
let amount_received_ld =
|
|
462
|
+
T::__credit(env, &send_to, oft_utils::to_ld(oft_msg.amount_sd, conversion_rate), origin.src_eid);
|
|
463
|
+
|
|
464
|
+
if oft_msg.is_composed() {
|
|
465
|
+
let compose_msg = OFTComposeMsg {
|
|
466
|
+
nonce: origin.nonce,
|
|
467
|
+
src_eid: origin.src_eid,
|
|
468
|
+
amount_ld: amount_received_ld,
|
|
469
|
+
compose_from: oft_msg.compose_from.unwrap(),
|
|
470
|
+
compose_msg: oft_msg.compose_msg.unwrap(),
|
|
471
|
+
}
|
|
472
|
+
.encode(env);
|
|
473
|
+
|
|
474
|
+
let endpoint_client = MessagingComposerClient::new(env, &T::endpoint(env));
|
|
475
|
+
endpoint_client.send_compose(&env.current_contract_address(), &send_to, guid, &0, &compose_msg);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
events::OFTReceived { guid: guid.clone(), src_eid: origin.src_eid, to: send_to, amount_received_ld }.publish(env);
|
|
479
|
+
}
|
|
@@ -5,7 +5,7 @@ use crate::{
|
|
|
5
5
|
create_origin, create_recipient_address, encode_oft_message, encode_oft_message_with_compose,
|
|
6
6
|
generate_g_address, OFTTestSetupBuilder,
|
|
7
7
|
},
|
|
8
|
-
utils::
|
|
8
|
+
utils::address_payload,
|
|
9
9
|
};
|
|
10
10
|
use endpoint_v2::LayerZeroReceiverClient;
|
|
11
11
|
use soroban_sdk::{testutils::Address as _, Address, Bytes, BytesN, Env};
|
|
@@ -26,7 +26,7 @@ fn run_lz_receive_test(setup: &OFTTestSetup, recipient: &Address, amount_sd: u64
|
|
|
26
26
|
if setup.is_lock_unlock() { Some(setup.token_client.balance(&setup.oft.address)) } else { None };
|
|
27
27
|
|
|
28
28
|
// Create OFT message
|
|
29
|
-
let recipient_bytes32 =
|
|
29
|
+
let recipient_bytes32 = address_payload(recipient);
|
|
30
30
|
let message = encode_oft_message(env, &recipient_bytes32, amount_sd);
|
|
31
31
|
|
|
32
32
|
let guid = BytesN::from_array(env, &[1u8; 32]);
|
|
@@ -111,8 +111,8 @@ fn test_mint_burn_lz_receive_with_compose() {
|
|
|
111
111
|
setup.set_peer(src_eid, &peer);
|
|
112
112
|
|
|
113
113
|
// Create OFT message with compose
|
|
114
|
-
let recipient_bytes32 =
|
|
115
|
-
let compose_from =
|
|
114
|
+
let recipient_bytes32 = address_payload(&recipient);
|
|
115
|
+
let compose_from = address_payload(&sender_on_src);
|
|
116
116
|
let compose_msg = Bytes::from_array(&env, b"test compose payload");
|
|
117
117
|
let amount_sd = 1000000u64;
|
|
118
118
|
let message = encode_oft_message_with_compose(&env, &recipient_bytes32, amount_sd, &compose_from, &compose_msg);
|
|
@@ -204,8 +204,8 @@ fn test_lock_unlock_lz_receive_with_compose() {
|
|
|
204
204
|
setup.set_peer(src_eid, &peer);
|
|
205
205
|
|
|
206
206
|
// Create OFT message with compose
|
|
207
|
-
let recipient_bytes32 =
|
|
208
|
-
let compose_from =
|
|
207
|
+
let recipient_bytes32 = address_payload(&recipient);
|
|
208
|
+
let compose_from = address_payload(&sender_on_src);
|
|
209
209
|
let compose_msg = Bytes::from_array(&env, b"test compose payload");
|
|
210
210
|
let amount_sd = 1000000u64;
|
|
211
211
|
let message = encode_oft_message_with_compose(&env, &recipient_bytes32, amount_sd, &compose_from, &compose_msg);
|
|
@@ -261,7 +261,7 @@ fn test_lz_receive_without_giving_authorization() {
|
|
|
261
261
|
assert_eq!(setup.token_client.balance(&recipient), 0);
|
|
262
262
|
|
|
263
263
|
// Create OFT message
|
|
264
|
-
let recipient_bytes32 =
|
|
264
|
+
let recipient_bytes32 = address_payload(&recipient);
|
|
265
265
|
let amount_sd = 1000000u64; // 1 token in shared decimals
|
|
266
266
|
let message = encode_oft_message(&env, &recipient_bytes32, amount_sd);
|
|
267
267
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
use crate::{codec::oft_msg_codec::OFTMessage, utils::
|
|
1
|
+
use crate::{codec::oft_msg_codec::OFTMessage, utils::address_payload};
|
|
2
2
|
use soroban_sdk::{testutils::Address as _, Address, Bytes, BytesN, Env};
|
|
3
3
|
|
|
4
4
|
#[test]
|
|
@@ -33,7 +33,7 @@ fn test_encode_and_decode_with_compose() {
|
|
|
33
33
|
let msg = OFTMessage {
|
|
34
34
|
send_to: send_to_addr.clone(),
|
|
35
35
|
amount_sd: amount_sd_val,
|
|
36
|
-
compose_from: Some(
|
|
36
|
+
compose_from: Some(address_payload(&sender)),
|
|
37
37
|
compose_msg: Some(compose_msg_val),
|
|
38
38
|
};
|
|
39
39
|
let (encoded, has_compose) = msg.encode(&env);
|
|
@@ -66,7 +66,7 @@ fn test_is_composed_false_when_only_compose_from() {
|
|
|
66
66
|
let msg = OFTMessage {
|
|
67
67
|
send_to: send_to_addr,
|
|
68
68
|
amount_sd: amount_sd_val,
|
|
69
|
-
compose_from: Some(
|
|
69
|
+
compose_from: Some(address_payload(&sender)),
|
|
70
70
|
compose_msg: None,
|
|
71
71
|
};
|
|
72
72
|
|
|
@@ -105,7 +105,7 @@ fn test_is_composed_false_when_compose_msg_empty() {
|
|
|
105
105
|
let msg = OFTMessage {
|
|
106
106
|
send_to: send_to_addr.clone(),
|
|
107
107
|
amount_sd: amount_sd_val,
|
|
108
|
-
compose_from: Some(
|
|
108
|
+
compose_from: Some(address_payload(&sender)),
|
|
109
109
|
compose_msg: Some(empty_compose_msg),
|
|
110
110
|
};
|
|
111
111
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
use crate::{
|
|
2
2
|
tests::test_utils::{create_recipient_address, generate_g_address},
|
|
3
|
-
utils::{
|
|
3
|
+
utils::{address_payload, resolve_address},
|
|
4
4
|
};
|
|
5
5
|
use soroban_sdk::Env;
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ fn test_resolve_address_contract_exists() {
|
|
|
12
12
|
let contract_address = create_recipient_address(&env);
|
|
13
13
|
|
|
14
14
|
// Convert to bytes32
|
|
15
|
-
let bytes32 =
|
|
15
|
+
let bytes32 = address_payload(&contract_address);
|
|
16
16
|
|
|
17
17
|
// Resolve back - should return the same contract address
|
|
18
18
|
let resolved = resolve_address(&env, &bytes32);
|
|
@@ -28,7 +28,7 @@ fn test_resolve_address_contract_not_exists_fallback_to_g_address() {
|
|
|
28
28
|
let g_address = generate_g_address(&env);
|
|
29
29
|
|
|
30
30
|
// Convert to bytes32
|
|
31
|
-
let bytes32 =
|
|
31
|
+
let bytes32 = address_payload(&g_address);
|
|
32
32
|
|
|
33
33
|
// Resolve - should fallback to G-address since contract doesn't exist
|
|
34
34
|
let resolved = resolve_address(&env, &bytes32);
|