@layerzerolabs/oft-core-stellar-contracts 0.2.122
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/Cargo.toml +38 -0
- package/LICENSE +23 -0
- package/clippy.toml +6 -0
- package/package.json +54 -0
- package/rust-toolchain.toml +4 -0
- package/rustfmt.toml +15 -0
- package/src/codec/mod.rs +2 -0
- package/src/codec/oft_compose_msg_codec.rs +55 -0
- package/src/codec/oft_msg_codec.rs +58 -0
- package/src/errors.rs +15 -0
- package/src/events.rs +32 -0
- package/src/lib.rs +22 -0
- package/src/oft_core.rs +594 -0
- package/src/storage.rs +19 -0
- package/src/tests/mod.rs +14 -0
- package/src/tests/test_decimals.rs +124 -0
- package/src/tests/test_lz_receive.rs +282 -0
- package/src/tests/test_msg_inspector.rs +324 -0
- package/src/tests/test_oft_compose_msg_codec.rs +68 -0
- package/src/tests/test_oft_msg_codec.rs +64 -0
- package/src/tests/test_oft_version_and_approval.rs +22 -0
- package/src/tests/test_quote_oft.rs +159 -0
- package/src/tests/test_quote_send.rs +195 -0
- package/src/tests/test_resolve_address.rs +37 -0
- package/src/tests/test_send.rs +915 -0
- package/src/tests/test_token.rs +47 -0
- package/src/tests/test_utils.rs +870 -0
- package/src/types.rs +58 -0
- package/src/utils.rs +71 -0
package/src/types.rs
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
use soroban_sdk::{contracttype, Bytes, BytesN};
|
|
2
|
+
|
|
3
|
+
/// Message type for simple OFT send
|
|
4
|
+
pub const SEND: u32 = 1;
|
|
5
|
+
|
|
6
|
+
/// Message type for OFT send with compose functionality
|
|
7
|
+
pub const SEND_AND_CALL: u32 = 2;
|
|
8
|
+
|
|
9
|
+
/// Parameters for sending OFT tokens cross-chain
|
|
10
|
+
#[contracttype]
|
|
11
|
+
#[derive(Clone, PartialEq, Eq, Debug)]
|
|
12
|
+
pub struct SendParam {
|
|
13
|
+
/// The destination endpoint ID
|
|
14
|
+
pub dst_eid: u32,
|
|
15
|
+
/// The recipient address on the destination chain (32 bytes)
|
|
16
|
+
pub to: BytesN<32>,
|
|
17
|
+
/// The amount to send in local decimals
|
|
18
|
+
pub amount_ld: i128,
|
|
19
|
+
/// The minimum amount to receive in local decimals (slippage protection)
|
|
20
|
+
pub min_amount_ld: i128,
|
|
21
|
+
/// Additional options for the LayerZero message (Optional)
|
|
22
|
+
pub extra_options: Bytes,
|
|
23
|
+
/// Compose message to execute on the destination (Optional)
|
|
24
|
+
pub compose_msg: Bytes,
|
|
25
|
+
/// OFT command for custom behavior (Optional)
|
|
26
|
+
pub oft_cmd: Bytes,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/// Transfer limits for OFT operations
|
|
30
|
+
#[contracttype]
|
|
31
|
+
#[derive(Clone, PartialEq, Eq, Debug)]
|
|
32
|
+
pub struct OFTLimit {
|
|
33
|
+
/// The minimum amount to send in local decimals
|
|
34
|
+
pub min_amount_ld: i128,
|
|
35
|
+
/// The maximum amount to send in local decimals
|
|
36
|
+
pub max_amount_ld: i128,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/// Receipt containing amounts sent and received in an OFT transfer
|
|
40
|
+
#[contracttype]
|
|
41
|
+
#[derive(Clone, PartialEq, Eq, Debug)]
|
|
42
|
+
pub struct OFTReceipt {
|
|
43
|
+
/// The amount sent in local decimals
|
|
44
|
+
pub amount_sent_ld: i128,
|
|
45
|
+
/// The amount received in local decimals on the remote
|
|
46
|
+
pub amount_received_ld: i128,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/// Details about fees charged in an OFT operation
|
|
50
|
+
#[contracttype]
|
|
51
|
+
#[derive(Clone, PartialEq, Eq, Debug)]
|
|
52
|
+
pub struct OFTFeeDetail {
|
|
53
|
+
/// The amount of the fee in local decimals. Positive values represent fees charged,
|
|
54
|
+
/// while negative values represent rewards given.
|
|
55
|
+
pub fee_amount_ld: i128,
|
|
56
|
+
/// The description of the fee
|
|
57
|
+
pub description: Bytes,
|
|
58
|
+
}
|
package/src/utils.rs
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
use crate::errors::OFTError;
|
|
2
|
+
use soroban_sdk::{address_payload::AddressPayload, assert_with_error, Address, BytesN, Env};
|
|
3
|
+
use utils::option_ext::OptionExt;
|
|
4
|
+
|
|
5
|
+
// =====================================================
|
|
6
|
+
// OFT Helper Functions
|
|
7
|
+
// =====================================================
|
|
8
|
+
|
|
9
|
+
/// Converts from shared decimals (SD) to local decimals (LD).
|
|
10
|
+
pub fn to_ld(amount_sd: u64, conversion_rate: i128) -> i128 {
|
|
11
|
+
(amount_sd as i128) * conversion_rate
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/// Converts from local decimals (LD) to shared decimals (SD).
|
|
15
|
+
pub fn to_sd(env: &Env, amount_ld: i128, conversion_rate: i128) -> u64 {
|
|
16
|
+
let amount_sd = amount_ld / conversion_rate;
|
|
17
|
+
assert_with_error!(env, amount_sd <= u64::MAX as i128, OFTError::Overflow);
|
|
18
|
+
amount_sd as u64
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/// Removes dust from amount based on decimal conversion rate.
|
|
22
|
+
pub fn remove_dust(amount_ld: i128, conversion_rate: i128) -> i128 {
|
|
23
|
+
(amount_ld / conversion_rate) * conversion_rate
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// =====================================================
|
|
27
|
+
// Address Helper Functions
|
|
28
|
+
// =====================================================
|
|
29
|
+
|
|
30
|
+
/// Extracts the 32-byte payload from an address.
|
|
31
|
+
///
|
|
32
|
+
/// This function extracts the raw 32-byte payload from a Stellar address,
|
|
33
|
+
/// which can be either a contract ID hash or an Ed25519 public key.
|
|
34
|
+
/// This payload can later be resolved back to an address using `resolve_address`.
|
|
35
|
+
///
|
|
36
|
+
/// # Arguments
|
|
37
|
+
/// * `address` - The Stellar address to extract the payload from
|
|
38
|
+
///
|
|
39
|
+
/// # Returns
|
|
40
|
+
/// A 32-byte payload (contract ID hash or Ed25519 public key)
|
|
41
|
+
pub fn address_payload(env: &Env, address: &Address) -> BytesN<32> {
|
|
42
|
+
match address.to_payload().unwrap_or_panic(env, OFTError::InvalidAddress) {
|
|
43
|
+
AddressPayload::ContractIdHash(payload) => payload,
|
|
44
|
+
AddressPayload::AccountIdPublicKeyEd25519(payload) => payload,
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/// Resolves a 32-byte payload back to a Stellar address.
|
|
49
|
+
///
|
|
50
|
+
/// Cross-chain messages only carry 32-byte addresses, but Stellar has two address types
|
|
51
|
+
/// (contract C-addresses and account G-addresses) that share the same 32-byte payload.
|
|
52
|
+
/// This function disambiguates by checking contract existence first, then falling back
|
|
53
|
+
/// to a G-address.
|
|
54
|
+
///
|
|
55
|
+
/// Sending tokens to a non-existent contract address is unlikely in practice — the sender
|
|
56
|
+
/// on the source chain is expected to deploy the destination contract beforehand.
|
|
57
|
+
///
|
|
58
|
+
/// # Arguments
|
|
59
|
+
/// * `env` - The Soroban environment
|
|
60
|
+
/// * `bytes32` - The 32-byte payload to resolve
|
|
61
|
+
///
|
|
62
|
+
/// # Returns
|
|
63
|
+
/// The resolved address (either contract or account address)
|
|
64
|
+
pub fn resolve_address(env: &Env, bytes32: &BytesN<32>) -> Address {
|
|
65
|
+
let contract_address = Address::from_payload(env, AddressPayload::ContractIdHash(bytes32.clone()));
|
|
66
|
+
if contract_address.exists() {
|
|
67
|
+
contract_address
|
|
68
|
+
} else {
|
|
69
|
+
Address::from_payload(env, AddressPayload::AccountIdPublicKeyEd25519(bytes32.clone()))
|
|
70
|
+
}
|
|
71
|
+
}
|