@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/Cargo.toml
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "oft-core"
|
|
3
|
+
version = "0.0.1"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
publish = false
|
|
6
|
+
|
|
7
|
+
[lib]
|
|
8
|
+
crate-type = ["rlib"]
|
|
9
|
+
doctest = false
|
|
10
|
+
|
|
11
|
+
[dependencies]
|
|
12
|
+
soroban-sdk = { version = "25.1.1", features = ["hazmat-address", "hazmat-crypto"] }
|
|
13
|
+
endpoint-v2 = { path = "dependencies/protocol-stellar-v2/endpoint-v2", default-features = false, features = ["library"] }
|
|
14
|
+
utils = { path = "dependencies/common-utils-stellar-contracts" }
|
|
15
|
+
common-macros = { path = "dependencies/common-utils-macros-stellar-contracts" }
|
|
16
|
+
oapp = { path = "dependencies/oapp-stellar-contracts" }
|
|
17
|
+
|
|
18
|
+
[dev-dependencies]
|
|
19
|
+
soroban-sdk = { version = "25.1.1", features = ["hazmat-address", "hazmat-crypto", "testutils"] }
|
|
20
|
+
simple-message-lib = { path = "dependencies/protocol-stellar-v2/message-libs/simple-message-lib" }
|
|
21
|
+
message-lib-common = { path = "dependencies/protocol-stellar-v2/message-libs/message-lib-common", features = ["testutils"] }
|
|
22
|
+
endpoint-v2 = { path = "dependencies/protocol-stellar-v2/endpoint-v2", features = ["testutils"] }
|
|
23
|
+
utils = { path = "dependencies/common-utils-stellar-contracts", features = ["testutils"] }
|
|
24
|
+
oapp-macros = { path = "dependencies/oapp-macros-stellar-contracts" }
|
|
25
|
+
|
|
26
|
+
[profile.release]
|
|
27
|
+
opt-level = "z"
|
|
28
|
+
overflow-checks = true
|
|
29
|
+
debug = 0
|
|
30
|
+
strip = "symbols"
|
|
31
|
+
debug-assertions = false
|
|
32
|
+
panic = "abort"
|
|
33
|
+
codegen-units = 1
|
|
34
|
+
lto = true
|
|
35
|
+
|
|
36
|
+
[profile.release-with-logs]
|
|
37
|
+
inherits = "release"
|
|
38
|
+
debug-assertions = true
|
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Copyright (c) 2026 - LayerZero Labs Ltd.
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any
|
|
4
|
+
person obtaining a copy of this software and associated
|
|
5
|
+
documentation files (the "Software"), to deal in the
|
|
6
|
+
Software without restriction, including without
|
|
7
|
+
limitation the rights to use, copy, modify, merge,
|
|
8
|
+
publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software
|
|
10
|
+
is furnished to do so, subject to the following
|
|
11
|
+
conditions:
|
|
12
|
+
The above copyright notice and this permission notice
|
|
13
|
+
shall be included in all copies or substantial portions
|
|
14
|
+
of the Software.
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
|
16
|
+
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
17
|
+
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
18
|
+
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
|
19
|
+
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
|
22
|
+
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
23
|
+
DEALINGS IN THE SOFTWARE.
|
package/clippy.toml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Clippy configuration for Stellar contracts
|
|
2
|
+
|
|
3
|
+
# Set the too_many_arguments threshold to 11.
|
|
4
|
+
# This aligns with Stellar: contract functions are limited to 10 parameters, plus 1 for 'env'.
|
|
5
|
+
# (Default is 7; raised here to prevent unnecessary clippy warnings on valid contract interfaces.)
|
|
6
|
+
too-many-arguments-threshold = 11
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@layerzerolabs/oft-core-stellar-contracts",
|
|
3
|
+
"version": "0.2.122",
|
|
4
|
+
"private": false,
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"files": [
|
|
7
|
+
"src",
|
|
8
|
+
"Cargo.toml",
|
|
9
|
+
"rust-toolchain.toml",
|
|
10
|
+
"rustfmt.toml",
|
|
11
|
+
"clippy.toml"
|
|
12
|
+
],
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@layerzerolabs/common-utils-macros-stellar-contracts": "0.2.122",
|
|
15
|
+
"@layerzerolabs/oapp-stellar-contracts": "0.2.122",
|
|
16
|
+
"@layerzerolabs/common-utils-stellar-contracts": "0.2.122",
|
|
17
|
+
"@layerzerolabs/protocol-stellar-v2": "0.2.122",
|
|
18
|
+
"@layerzerolabs/oapp-macros-stellar-contracts": "0.2.122"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@layerzerolabs/build-utils-rust": "0.2.122",
|
|
22
|
+
"@layerzerolabs/vm-tooling-stellar": "0.2.122"
|
|
23
|
+
},
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public",
|
|
26
|
+
"registry": "https://registry.npmjs.org/"
|
|
27
|
+
},
|
|
28
|
+
"externalRepoConfig": {
|
|
29
|
+
"targets": [
|
|
30
|
+
"audit-external",
|
|
31
|
+
"console-pen-test",
|
|
32
|
+
"monorepo-external",
|
|
33
|
+
"onesig-client"
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
"implicitDependencies": {
|
|
37
|
+
"@layerzerolabs/oapp-stellar-contracts": "workspace:*",
|
|
38
|
+
"@layerzerolabs/protocol-stellar-v2": "workspace:*",
|
|
39
|
+
"@layerzerolabs/common-utils-stellar-contracts": "workspace:*",
|
|
40
|
+
"@layerzerolabs/common-utils-macros-stellar-contracts": "workspace:*",
|
|
41
|
+
"@layerzerolabs/oapp-macros-stellar-contracts": "workspace:*"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "pnpm resolve-dependencies && pnpm exec lz-tool --script \"cargo build --release\" stellar",
|
|
45
|
+
"clean": "rm -rf ./dependencies ./target ./node_modules",
|
|
46
|
+
"format": "pnpm exec lz-tool --script \"cargo fmt\" stellar",
|
|
47
|
+
"lint": "pnpm resolve-dependencies && pnpm exec lz-tool --script \"cargo clippy -- -D warnings\" stellar",
|
|
48
|
+
"lint:fix": "pnpm resolve-dependencies && pnpm exec lz-tool --script \"cargo clippy --fix --allow-dirty --allow-staged && cargo fmt\" stellar",
|
|
49
|
+
"resolve-dependencies": "pnpm exec build-utils-rust resolve",
|
|
50
|
+
"test": "pnpm resolve-dependencies && pnpm exec lz-tool --script \"cargo nextest run\" stellar",
|
|
51
|
+
"test:snapshot:check": "pnpm exec turbo-snapshot check",
|
|
52
|
+
"test:snapshot:update": "pnpm exec turbo-snapshot update"
|
|
53
|
+
}
|
|
54
|
+
}
|
package/rustfmt.toml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
format_macro_bodies = true
|
|
2
|
+
max_width = 120
|
|
3
|
+
format_macro_matchers = true
|
|
4
|
+
format_strings = true
|
|
5
|
+
imports_granularity = "Crate"
|
|
6
|
+
match_arm_blocks = false
|
|
7
|
+
reorder_impl_items = true
|
|
8
|
+
group_imports = "StdExternalCrate"
|
|
9
|
+
use_field_init_shorthand = true
|
|
10
|
+
use_small_heuristics = "Max"
|
|
11
|
+
wrap_comments = true
|
|
12
|
+
format_code_in_doc_comments = true
|
|
13
|
+
|
|
14
|
+
# most of these are unstable, so we enable them
|
|
15
|
+
unstable_features = true
|
package/src/codec/mod.rs
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
use soroban_sdk::{Bytes, BytesN, Env};
|
|
2
|
+
use utils::{buffer_reader::BufferReader, buffer_writer::BufferWriter};
|
|
3
|
+
|
|
4
|
+
/// Decoded compose message containing transfer context and payload execution
|
|
5
|
+
#[derive(Clone, Debug)]
|
|
6
|
+
pub struct OFTComposeMsg {
|
|
7
|
+
/// Unique sequence number for the cross-chain message packet
|
|
8
|
+
pub nonce: u64,
|
|
9
|
+
/// Source endpoint ID where the transfer originated
|
|
10
|
+
pub src_eid: u32,
|
|
11
|
+
/// Amount received in local decimals
|
|
12
|
+
pub amount_ld: i128,
|
|
13
|
+
/// Address that initiated the compose call on the source chain
|
|
14
|
+
pub compose_from: BytesN<32>,
|
|
15
|
+
/// Custom payload for compose logic execution
|
|
16
|
+
pub compose_msg: Bytes,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
impl OFTComposeMsg {
|
|
20
|
+
/// Encodes the OFTComposeMsg struct into Bytes.
|
|
21
|
+
///
|
|
22
|
+
/// # Arguments
|
|
23
|
+
/// * `env` - The Soroban environment
|
|
24
|
+
///
|
|
25
|
+
/// # Returns
|
|
26
|
+
/// Encoded bytes representation of the compose message
|
|
27
|
+
pub fn encode(&self, env: &Env) -> Bytes {
|
|
28
|
+
let mut writer = BufferWriter::new(env);
|
|
29
|
+
writer
|
|
30
|
+
.write_u64(self.nonce)
|
|
31
|
+
.write_u32(self.src_eid)
|
|
32
|
+
.write_i128(self.amount_ld)
|
|
33
|
+
.write_bytes_n(&self.compose_from)
|
|
34
|
+
.write_bytes(&self.compose_msg)
|
|
35
|
+
.to_bytes()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/// Decodes Bytes into an OFTComposeMsg struct.
|
|
39
|
+
///
|
|
40
|
+
/// # Arguments
|
|
41
|
+
/// * `bytes` - The encoded bytes to decode
|
|
42
|
+
///
|
|
43
|
+
/// # Returns
|
|
44
|
+
/// Decoded OFTComposeMsg struct
|
|
45
|
+
pub fn decode(bytes: &Bytes) -> Self {
|
|
46
|
+
let mut reader = BufferReader::new(bytes);
|
|
47
|
+
let nonce = reader.read_u64();
|
|
48
|
+
let src_eid = reader.read_u32();
|
|
49
|
+
let amount_ld = reader.read_i128();
|
|
50
|
+
let compose_from = reader.read_bytes_n::<32>();
|
|
51
|
+
let compose_msg = reader.read_bytes_until_end();
|
|
52
|
+
|
|
53
|
+
OFTComposeMsg { nonce, src_eid, amount_ld, compose_from, compose_msg }
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
use soroban_sdk::{Bytes, BytesN, Env};
|
|
2
|
+
use utils::{buffer_reader::BufferReader, buffer_writer::BufferWriter};
|
|
3
|
+
|
|
4
|
+
/// Decoded OFT message containing transfer details and optional compose data.
|
|
5
|
+
///
|
|
6
|
+
/// Wire format:
|
|
7
|
+
/// ```text
|
|
8
|
+
/// [send_to: 32 bytes][amount_sd: 8 bytes][compose_from: 32 bytes (optional)][compose_msg: variable (optional)]
|
|
9
|
+
/// ```
|
|
10
|
+
#[derive(Clone, Debug)]
|
|
11
|
+
pub struct OFTMessage {
|
|
12
|
+
/// Recipient address on the destination chain
|
|
13
|
+
pub send_to: BytesN<32>,
|
|
14
|
+
/// Amount to transfer in shared decimals
|
|
15
|
+
pub amount_sd: u64,
|
|
16
|
+
/// Optional compose data for cross-chain composed calls
|
|
17
|
+
pub compose: Option<ComposeData>,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/// Initiator address and payload for a cross-chain composed call.
|
|
21
|
+
#[derive(Clone, Debug)]
|
|
22
|
+
pub struct ComposeData {
|
|
23
|
+
/// Address that initiated the compose call
|
|
24
|
+
pub from: BytesN<32>,
|
|
25
|
+
/// Compose message payload
|
|
26
|
+
pub msg: Bytes,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
impl OFTMessage {
|
|
30
|
+
/// Encodes the OFTMessage into Bytes.
|
|
31
|
+
pub fn encode(&self, env: &Env) -> Bytes {
|
|
32
|
+
let mut writer = BufferWriter::new(env);
|
|
33
|
+
writer.write_bytes_n(&self.send_to).write_u64(self.amount_sd);
|
|
34
|
+
|
|
35
|
+
if let Some(ref compose_data) = self.compose {
|
|
36
|
+
writer.write_bytes_n(&compose_data.from).write_bytes(&compose_data.msg);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
writer.to_bytes()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/// Decodes Bytes into an OFTMessage.
|
|
43
|
+
pub fn decode(message: &Bytes) -> Self {
|
|
44
|
+
let mut reader = BufferReader::new(message);
|
|
45
|
+
let send_to = reader.read_bytes_n::<32>();
|
|
46
|
+
let amount_sd = reader.read_u64();
|
|
47
|
+
|
|
48
|
+
let compose = if reader.remaining_len() > 0 {
|
|
49
|
+
let from = reader.read_bytes_n::<32>();
|
|
50
|
+
let msg = reader.read_bytes_until_end();
|
|
51
|
+
Some(ComposeData { from, msg })
|
|
52
|
+
} else {
|
|
53
|
+
None
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
OFTMessage { send_to, amount_sd, compose }
|
|
57
|
+
}
|
|
58
|
+
}
|
package/src/errors.rs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
use common_macros::contract_error;
|
|
2
|
+
|
|
3
|
+
// OFT library error codes: 3000-3099
|
|
4
|
+
// See docs/error-spec.md for allocation rules
|
|
5
|
+
|
|
6
|
+
/// OFTError: 3000-3099
|
|
7
|
+
#[contract_error]
|
|
8
|
+
pub enum OFTError {
|
|
9
|
+
InvalidAddress = 3000,
|
|
10
|
+
InvalidAmount,
|
|
11
|
+
InvalidLocalDecimals,
|
|
12
|
+
NotInitialized,
|
|
13
|
+
Overflow,
|
|
14
|
+
SlippageExceeded,
|
|
15
|
+
}
|
package/src/events.rs
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
use soroban_sdk::{contractevent, Address, BytesN};
|
|
2
|
+
|
|
3
|
+
#[contractevent]
|
|
4
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
5
|
+
pub struct OFTSent {
|
|
6
|
+
#[topic]
|
|
7
|
+
pub guid: BytesN<32>,
|
|
8
|
+
#[topic]
|
|
9
|
+
pub dst_eid: u32,
|
|
10
|
+
#[topic]
|
|
11
|
+
pub from: Address,
|
|
12
|
+
pub amount_sent_ld: i128,
|
|
13
|
+
pub amount_received_ld: i128,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
#[contractevent]
|
|
17
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
18
|
+
pub struct OFTReceived {
|
|
19
|
+
#[topic]
|
|
20
|
+
pub guid: BytesN<32>,
|
|
21
|
+
#[topic]
|
|
22
|
+
pub src_eid: u32,
|
|
23
|
+
#[topic]
|
|
24
|
+
pub to: Address,
|
|
25
|
+
pub amount_received_ld: i128,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#[contractevent]
|
|
29
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
30
|
+
pub struct MsgInspectorSet {
|
|
31
|
+
pub inspector: Option<Address>,
|
|
32
|
+
}
|
package/src/lib.rs
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#![no_std]
|
|
2
|
+
|
|
3
|
+
pub mod events;
|
|
4
|
+
pub mod storage;
|
|
5
|
+
pub mod utils;
|
|
6
|
+
|
|
7
|
+
mod codec;
|
|
8
|
+
mod errors;
|
|
9
|
+
mod oft_core;
|
|
10
|
+
mod types;
|
|
11
|
+
|
|
12
|
+
pub use codec::*;
|
|
13
|
+
pub use errors::*;
|
|
14
|
+
pub use oft_core::*;
|
|
15
|
+
pub use types::*;
|
|
16
|
+
|
|
17
|
+
#[cfg(test)]
|
|
18
|
+
#[path = "../integration-tests/mod.rs"]
|
|
19
|
+
mod integration_tests;
|
|
20
|
+
|
|
21
|
+
#[cfg(test)]
|
|
22
|
+
mod tests;
|