@layerzerolabs/protocol-stellar-v2 0.2.10 → 0.2.12
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 +273 -219
- package/.turbo/turbo-lint.log +79 -107
- package/.turbo/turbo-test.log +1016 -840
- package/Cargo.lock +14 -6
- package/contracts/common-macros/src/contract_impl.rs +6 -3
- package/contracts/common-macros/src/error.rs +9 -17
- package/contracts/common-macros/src/lib.rs +4 -37
- package/contracts/common-macros/src/ownable.rs +9 -5
- package/contracts/common-macros/src/tests/contract_impl.rs +178 -86
- package/contracts/common-macros/src/tests/error.rs +168 -0
- package/contracts/common-macros/src/tests/mod.rs +2 -4
- package/contracts/common-macros/src/tests/ownable.rs +37 -60
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_impl__snapshot_generated_contract_impl_code.snap +16 -6
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__error__snapshot_generated_contract_error_code.snap +20 -0
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_generated_ownable_code.snap +3 -1
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_only_owner_preserves_function_signature.snap +12 -2
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +5 -1
- package/contracts/common-macros/src/tests/utils.rs +267 -0
- package/contracts/common-macros/src/ttl_configurable.rs +15 -12
- package/contracts/common-macros/src/utils.rs +35 -6
- package/contracts/endpoint-v2/src/endpoint_v2.rs +4 -4
- package/contracts/endpoint-v2/src/events.rs +40 -22
- package/contracts/endpoint-v2/src/interfaces/message_lib.rs +2 -2
- package/contracts/endpoint-v2/src/interfaces/message_lib_manager.rs +2 -2
- package/contracts/endpoint-v2/src/interfaces/messaging_channel.rs +2 -2
- package/contracts/endpoint-v2/src/interfaces/messaging_composer.rs +2 -2
- package/contracts/endpoint-v2/src/interfaces/send_lib.rs +2 -2
- package/contracts/endpoint-v2/src/message_lib_manager.rs +3 -3
- package/contracts/endpoint-v2/src/messaging_channel.rs +1 -1
- package/contracts/endpoint-v2/src/messaging_composer.rs +1 -1
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_lib_timeout.rs +4 -8
- package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_library.rs +3 -7
- package/contracts/message-libs/{block-message-lib → blocked-message-lib}/Cargo.toml +1 -1
- package/contracts/message-libs/treasury/src/events.rs +9 -6
- package/contracts/message-libs/uln-302/src/events.rs +19 -11
- package/contracts/message-libs/uln-302/src/interfaces/receive_uln.rs +2 -2
- package/contracts/message-libs/uln-302/src/interfaces/send_uln.rs +2 -2
- package/contracts/message-libs/uln-302/src/receive_uln.rs +2 -2
- package/contracts/message-libs/uln-302/src/send_uln.rs +3 -3
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/set_default_receive_uln_configs.rs +5 -5
- package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_send_uln_configs.rs +5 -5
- package/contracts/message-libs/uln-302/src/tests/setup.rs +3 -3
- package/contracts/message-libs/uln-302/src/types.rs +24 -24
- package/contracts/message-libs/uln-302/src/uln302.rs +2 -2
- package/contracts/oapp-macros/src/oapp_core.rs +1 -1
- package/contracts/oapps/counter/integration_tests/utils.rs +1 -1
- package/contracts/oapps/oapp/src/oapp_core.rs +4 -3
- package/contracts/oapps/oapp/src/oapp_options_type3.rs +4 -3
- package/contracts/oapps/oft/integration-tests/setup.rs +4 -3
- package/contracts/oapps/oft/integration-tests/utils.rs +1 -1
- package/contracts/oapps/oft/src/default_oft_impl.rs +146 -0
- package/contracts/oapps/oft/src/events.rs +5 -4
- package/contracts/oapps/oft/src/extensions/mod.rs +3 -0
- package/contracts/oapps/oft/src/extensions/oft_fee.rs +168 -0
- package/contracts/oapps/oft/src/extensions/pausable.rs +50 -0
- package/contracts/oapps/oft/src/extensions/rate_limiter.rs +200 -0
- package/contracts/oapps/oft/src/lib.rs +2 -3
- package/contracts/oapps/oft/src/oft.rs +16 -85
- package/contracts/oapps/oft/src/oft_types/mint_burn.rs +1 -1
- package/contracts/oapps/oft/src/tests/extensions/mod.rs +11 -0
- package/contracts/oapps/oft/src/tests/extensions/setup.rs +888 -0
- package/contracts/oapps/oft/src/tests/extensions/test_oft_fee.rs +749 -0
- package/contracts/oapps/oft/src/tests/extensions/test_pausable.rs +432 -0
- package/contracts/oapps/oft/src/tests/extensions/test_rate_limiter.rs +1078 -0
- package/contracts/oapps/oft/src/tests/mod.rs +2 -0
- package/contracts/oapps/oft/src/tests/test_utils.rs +24 -6
- package/contracts/oapps/{oft-mint-burn → oft-std}/Cargo.toml +1 -8
- package/contracts/oapps/oft-std/src/lib.rs +5 -0
- package/contracts/oapps/oft-std/src/oft.rs +59 -0
- package/contracts/utils/src/ownable.rs +8 -6
- package/contracts/utils/src/tests/ownable.rs +0 -63
- package/contracts/utils/src/tests/testing_utils.rs +7 -5
- package/contracts/utils/src/ttl.rs +21 -2
- package/contracts/workers/dvn/src/auth.rs +108 -30
- package/contracts/workers/dvn/src/dvn.rs +103 -33
- package/contracts/workers/dvn/src/errors.rs +10 -13
- package/contracts/workers/dvn/src/events.rs +7 -5
- package/contracts/workers/dvn/src/interfaces/dvn.rs +76 -3
- package/contracts/workers/dvn/src/interfaces/multisig.rs +41 -0
- package/contracts/workers/dvn/src/lib.rs +6 -8
- package/contracts/workers/dvn/src/multisig.rs +98 -72
- package/contracts/workers/dvn/src/storage.rs +9 -12
- package/contracts/workers/dvn/src/tests/auth.rs +56 -26
- package/contracts/workers/dvn/src/tests/dvn.rs +40 -41
- package/contracts/workers/dvn/src/tests/multisig/set_signer.rs +8 -8
- package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +9 -9
- package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +6 -6
- package/contracts/workers/dvn/src/tests/setup.rs +5 -5
- package/contracts/workers/dvn-fee-lib/Cargo.toml +2 -1
- package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +4 -3
- package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +8 -6
- package/contracts/workers/executor/src/auth.rs +93 -0
- package/contracts/workers/executor/src/events.rs +5 -4
- package/contracts/workers/executor/src/{lz_executor.rs → executor.rs} +30 -103
- package/contracts/workers/executor/src/interfaces/executor.rs +5 -2
- package/contracts/workers/executor/src/interfaces/mod.rs +1 -1
- package/contracts/workers/executor/src/lib.rs +6 -5
- package/contracts/workers/price-feed/Cargo.toml +21 -0
- package/contracts/workers/price-feed/src/errors.rs +9 -0
- package/contracts/workers/price-feed/src/events.rs +30 -0
- package/contracts/workers/price-feed/src/lib.rs +11 -0
- package/contracts/workers/price-feed/src/price_feed.rs +265 -0
- package/contracts/workers/price-feed/src/storage.rs +42 -0
- package/contracts/workers/price-feed/src/types.rs +59 -0
- package/contracts/workers/worker/src/events.rs +23 -13
- package/contracts/workers/worker/src/interfaces/dvn_fee_lib.rs +2 -1
- package/contracts/workers/worker/src/worker.rs +32 -21
- package/package.json +3 -3
- package/sdk/dist/generated/bml.js +24 -22
- package/sdk/dist/generated/counter.d.ts +102 -0
- package/sdk/dist/generated/counter.js +36 -24
- package/sdk/dist/generated/endpoint.js +24 -22
- package/sdk/dist/generated/sml.js +24 -22
- package/sdk/dist/generated/uln302.d.ts +1 -1
- package/sdk/dist/generated/uln302.js +34 -32
- package/sdk/package.json +1 -1
- package/sdk/test/index.test.ts +1 -1
- package/sdk/test/oft.test.ts +847 -0
- package/sdk/test/suites/scan.ts +20 -4
- package/tools/ts-bindings-gen/src/main.rs +2 -1
- package/contracts/common-macros/src/event.rs +0 -16
- package/contracts/oapps/oft/src/macro_tests/mod.rs +0 -2
- package/contracts/oapps/oft/src/macro_tests/test_all_default.rs +0 -41
- package/contracts/oapps/oft/src/macro_tests/test_override.rs +0 -83
- package/contracts/oapps/oft-mint-burn/src/lib.rs +0 -3
- package/contracts/oapps/oft-mint-burn/src/oft.rs +0 -28
- package/contracts/oapps/oft-mint-burn/src/tests/mod.rs +0 -1
- package/contracts/workers/dvn/src/types.rs +0 -26
- /package/contracts/message-libs/{block-message-lib → blocked-message-lib}/src/lib.rs +0 -0
|
@@ -1,27 +1,50 @@
|
|
|
1
|
+
//! LayerZero Decentralized Verifier Network (DVN) contract.
|
|
2
|
+
//!
|
|
3
|
+
//! The DVN is responsible for verifying cross-chain messages by providing
|
|
4
|
+
//! cryptographic attestations. It uses a multisig scheme with secp256k1
|
|
5
|
+
//! signatures for authorization and implements Soroban's custom account
|
|
6
|
+
//! interface for transaction signing.
|
|
7
|
+
|
|
1
8
|
use crate::{
|
|
2
|
-
errors::
|
|
3
|
-
events::SetDstConfig,
|
|
4
|
-
storage::DvnStorage,
|
|
5
|
-
types::{DstConfig, DstConfigParam},
|
|
6
|
-
IDVN,
|
|
9
|
+
errors::DvnError, events::SetDstConfig, storage::DvnStorage, Call, DstConfig, DstConfigParam, IMultisig, IDVN,
|
|
7
10
|
};
|
|
8
|
-
use common_macros::ttl_configurable;
|
|
11
|
+
use common_macros::{contract_impl, ttl_configurable};
|
|
9
12
|
use endpoint_v2::FeeRecipient;
|
|
10
13
|
use message_lib_common::interfaces::ILayerZeroDVN;
|
|
11
|
-
use soroban_sdk::{
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
use utils::{buffer_writer::BufferWriter, option_ext::OptionExt};
|
|
14
|
+
use soroban_sdk::{contract, xdr::ToXdr, Address, Bytes, BytesN, Env, Vec};
|
|
15
|
+
use utils::buffer_writer::BufferWriter;
|
|
16
|
+
use utils::option_ext::OptionExt;
|
|
15
17
|
use worker::{
|
|
16
18
|
assert_acl, assert_not_paused, assert_supported_message_lib, init_worker, require_admin_auth, set_admin_by_admin,
|
|
17
|
-
set_admin_by_owner,
|
|
19
|
+
set_admin_by_owner, DvnFeeLibClient, DvnFeeParams, Worker,
|
|
18
20
|
};
|
|
21
|
+
|
|
22
|
+
/// LayerZero DVN contract.
|
|
23
|
+
///
|
|
24
|
+
/// Implements multisig-based verification with custom account authorization.
|
|
25
|
+
/// The contract owns itself, allowing the multisig quorum to authorize operations.
|
|
19
26
|
#[contract]
|
|
20
27
|
#[ttl_configurable]
|
|
21
|
-
pub struct
|
|
28
|
+
pub struct LzDVN;
|
|
22
29
|
|
|
23
|
-
|
|
24
|
-
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Core Implementation
|
|
32
|
+
// ============================================================================
|
|
33
|
+
|
|
34
|
+
#[contract_impl]
|
|
35
|
+
impl LzDVN {
|
|
36
|
+
/// Initializes the DVN contract.
|
|
37
|
+
///
|
|
38
|
+
/// # Arguments
|
|
39
|
+
/// * `vid` - Verifier ID, unique identifier for this DVN
|
|
40
|
+
/// * `signers` - Initial multisig signers (20-byte Ethereum addresses)
|
|
41
|
+
/// * `threshold` - Minimum signatures required for multisig operations
|
|
42
|
+
/// * `admins` - Initial admin addresses for operational functions
|
|
43
|
+
/// * `supported_msglibs` - Message libraries this DVN supports (e.g., ULN302)
|
|
44
|
+
/// * `price_feed` - Price feed contract for fee calculations
|
|
45
|
+
/// * `default_multiplier_bps` - Default fee multiplier (10000 = 1x)
|
|
46
|
+
/// * `worker_fee_lib` - Fee library contract for computing DVN fees
|
|
47
|
+
/// * `deposit_address` - Address to receive fee payments
|
|
25
48
|
pub fn __constructor(
|
|
26
49
|
env: &Env,
|
|
27
50
|
vid: u32,
|
|
@@ -30,15 +53,22 @@ impl Dvn {
|
|
|
30
53
|
admins: &Vec<Address>,
|
|
31
54
|
supported_msglibs: &Vec<Address>,
|
|
32
55
|
price_feed: &Address,
|
|
33
|
-
worker_fee_lib: &Address,
|
|
34
56
|
default_multiplier_bps: u32,
|
|
57
|
+
worker_fee_lib: &Address,
|
|
35
58
|
deposit_address: &Address,
|
|
36
59
|
) {
|
|
37
|
-
init_multisig(env, signers, threshold);
|
|
60
|
+
Self::init_multisig(env, signers, threshold);
|
|
38
61
|
Self::init_owner(env, &env.current_contract_address());
|
|
39
|
-
init_worker::<Self>(
|
|
40
|
-
|
|
41
|
-
|
|
62
|
+
init_worker::<Self>(
|
|
63
|
+
env,
|
|
64
|
+
admins,
|
|
65
|
+
supported_msglibs,
|
|
66
|
+
price_feed,
|
|
67
|
+
default_multiplier_bps,
|
|
68
|
+
worker_fee_lib,
|
|
69
|
+
deposit_address,
|
|
70
|
+
);
|
|
71
|
+
|
|
42
72
|
DvnStorage::set_vid(env, &vid);
|
|
43
73
|
}
|
|
44
74
|
|
|
@@ -55,10 +85,13 @@ impl Dvn {
|
|
|
55
85
|
set_admin_by_admin::<Self>(env, caller, admin, active);
|
|
56
86
|
}
|
|
57
87
|
|
|
58
|
-
///
|
|
88
|
+
/// Allows the quorum to add/remove admins without requiring an admin signature.
|
|
59
89
|
///
|
|
60
|
-
///
|
|
90
|
+
/// This function bypasses the normal admin verification in `__check_auth`,
|
|
91
|
+
/// requiring only multisig quorum signatures. Must be called as a single
|
|
92
|
+
/// operation (cannot be bundled with other calls).
|
|
61
93
|
///
|
|
94
|
+
/// # Arguments
|
|
62
95
|
/// * `admin` - The address to set admin status for
|
|
63
96
|
/// * `active` - `true` to add admin, `false` to remove
|
|
64
97
|
pub fn quorum_change_admin(env: &Env, admin: &Address, active: bool) {
|
|
@@ -66,8 +99,13 @@ impl Dvn {
|
|
|
66
99
|
}
|
|
67
100
|
}
|
|
68
101
|
|
|
69
|
-
|
|
70
|
-
|
|
102
|
+
// ============================================================================
|
|
103
|
+
// IDVN Implementation
|
|
104
|
+
// ============================================================================
|
|
105
|
+
|
|
106
|
+
#[contract_impl]
|
|
107
|
+
impl IDVN for LzDVN {
|
|
108
|
+
/// Sets destination chain configurations. Requires admin authorization.
|
|
71
109
|
fn set_dst_config(env: &Env, admin: &Address, params: &Vec<DstConfigParam>) {
|
|
72
110
|
require_admin_auth::<Self>(env, admin);
|
|
73
111
|
for param in params {
|
|
@@ -77,17 +115,35 @@ impl IDVN for Dvn {
|
|
|
77
115
|
SetDstConfig { params: params.clone() }.publish(env);
|
|
78
116
|
}
|
|
79
117
|
|
|
80
|
-
|
|
81
|
-
|
|
118
|
+
/// Returns the destination configuration for a specific endpoint ID.
|
|
119
|
+
fn dst_config(env: &Env, dst_eid: u32) -> Option<DstConfig> {
|
|
120
|
+
DvnStorage::dst_config(env, dst_eid)
|
|
82
121
|
}
|
|
83
122
|
|
|
123
|
+
/// Returns the Verifier ID for this DVN.
|
|
84
124
|
fn vid(env: &Env) -> u32 {
|
|
85
125
|
DvnStorage::vid(env).unwrap()
|
|
86
126
|
}
|
|
127
|
+
|
|
128
|
+
/// Computes the hash of call data for multisig signing.
|
|
129
|
+
///
|
|
130
|
+
/// Off-chain signers use this to compute the hash they need to sign.
|
|
131
|
+
fn hash_call_data(env: &Env, vid: u32, expiration: u64, calls: &Vec<Call>) -> BytesN<32> {
|
|
132
|
+
let mut writer = BufferWriter::new(env);
|
|
133
|
+
let data = writer.write_u32(vid).write_u64(expiration).write_bytes(&calls.to_xdr(env)).to_bytes();
|
|
134
|
+
env.crypto().keccak256(&data).into()
|
|
135
|
+
}
|
|
87
136
|
}
|
|
88
137
|
|
|
89
|
-
|
|
90
|
-
|
|
138
|
+
// ============================================================================
|
|
139
|
+
// ILayerZeroDVN Implementation (Send Flow)
|
|
140
|
+
// ============================================================================
|
|
141
|
+
|
|
142
|
+
#[contract_impl]
|
|
143
|
+
impl ILayerZeroDVN for LzDVN {
|
|
144
|
+
/// Calculates the verification fee for a cross-chain message.
|
|
145
|
+
///
|
|
146
|
+
/// Called by the send library to quote DVN fees before sending.
|
|
91
147
|
fn get_fee(
|
|
92
148
|
env: &Env,
|
|
93
149
|
_send_lib: &Address,
|
|
@@ -101,7 +157,7 @@ impl ILayerZeroDVN for Dvn {
|
|
|
101
157
|
assert_not_paused::<Self>(env);
|
|
102
158
|
assert_acl::<Self>(env, sender);
|
|
103
159
|
|
|
104
|
-
let dst_config = Self::dst_config(env, dst_eid);
|
|
160
|
+
let dst_config = Self::dst_config(env, dst_eid).unwrap_or_panic(env, DvnError::EidNotSupported);
|
|
105
161
|
let params = DvnFeeParams {
|
|
106
162
|
sender: sender.clone(),
|
|
107
163
|
dst_eid,
|
|
@@ -115,9 +171,13 @@ impl ILayerZeroDVN for Dvn {
|
|
|
115
171
|
floor_margin_usd: dst_config.floor_margin_usd,
|
|
116
172
|
};
|
|
117
173
|
|
|
118
|
-
DvnFeeLibClient::new(env, &Self::worker_fee_lib(env)).get_fee(¶ms)
|
|
174
|
+
DvnFeeLibClient::new(env, &Self::worker_fee_lib(env)).get_fee(&env.current_contract_address(), ¶ms)
|
|
119
175
|
}
|
|
120
176
|
|
|
177
|
+
/// Assigns a verification job to this DVN and returns fee payment info.
|
|
178
|
+
///
|
|
179
|
+
/// Called by the send library when a message is sent. The DVN will later
|
|
180
|
+
/// verify the message on the destination chain.
|
|
121
181
|
fn assign_job(
|
|
122
182
|
env: &Env,
|
|
123
183
|
send_lib: &Address,
|
|
@@ -136,8 +196,18 @@ impl ILayerZeroDVN for Dvn {
|
|
|
136
196
|
}
|
|
137
197
|
}
|
|
138
198
|
|
|
139
|
-
|
|
140
|
-
|
|
199
|
+
// ============================================================================
|
|
200
|
+
// Worker Implementation
|
|
201
|
+
// ============================================================================
|
|
202
|
+
|
|
203
|
+
#[contract_impl(contracttrait)]
|
|
204
|
+
impl Worker for LzDVN {}
|
|
205
|
+
|
|
206
|
+
// ============================================================================
|
|
207
|
+
// Include SubModules
|
|
208
|
+
// ============================================================================
|
|
141
209
|
|
|
142
|
-
|
|
143
|
-
|
|
210
|
+
#[path = "auth.rs"]
|
|
211
|
+
pub mod auth;
|
|
212
|
+
#[path = "multisig.rs"]
|
|
213
|
+
pub mod multisig;
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
use common_macros::contract_error;
|
|
2
2
|
|
|
3
|
-
#[contract_error]
|
|
4
|
-
pub enum MultisigError {
|
|
5
|
-
ZeroThreshold,
|
|
6
|
-
TotalSignersLessThanThreshold,
|
|
7
|
-
InvalidSigner,
|
|
8
|
-
SignerAlreadyExists,
|
|
9
|
-
SignerNotFound,
|
|
10
|
-
UnsortedSigners,
|
|
11
|
-
SignatureError,
|
|
12
|
-
}
|
|
13
|
-
|
|
14
3
|
#[contract_error]
|
|
15
4
|
pub enum DvnError {
|
|
16
|
-
InvalidVid,
|
|
17
5
|
AuthDataExpired,
|
|
6
|
+
EidNotSupported,
|
|
18
7
|
HashAlreadyUsed,
|
|
8
|
+
InvalidSigner,
|
|
9
|
+
InvalidVid,
|
|
10
|
+
NonContractInvoke,
|
|
19
11
|
OnlyAdmin,
|
|
20
|
-
|
|
12
|
+
SignatureError,
|
|
13
|
+
SignerAlreadyExists,
|
|
14
|
+
SignerNotFound,
|
|
15
|
+
TotalSignersLessThanThreshold,
|
|
16
|
+
UnsortedSigners,
|
|
17
|
+
ZeroThreshold,
|
|
21
18
|
}
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
use crate::DstConfigParam;
|
|
2
|
-
use
|
|
3
|
-
use soroban_sdk::{BytesN, Vec};
|
|
2
|
+
use soroban_sdk::{contractevent, BytesN, Vec};
|
|
4
3
|
|
|
5
|
-
#[
|
|
4
|
+
#[contractevent]
|
|
5
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
6
6
|
pub struct SignerSet {
|
|
7
7
|
pub signer: BytesN<20>,
|
|
8
8
|
pub active: bool,
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
#[
|
|
11
|
+
#[contractevent]
|
|
12
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
12
13
|
pub struct ThresholdSet {
|
|
13
14
|
pub threshold: u32,
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
#[
|
|
17
|
+
#[contractevent]
|
|
18
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
17
19
|
pub struct SetDstConfig {
|
|
18
20
|
pub params: Vec<DstConfigParam>,
|
|
19
21
|
}
|
|
@@ -1,12 +1,85 @@
|
|
|
1
|
-
use crate::types::{DstConfig, DstConfigParam};
|
|
2
1
|
use crate::IMultisig;
|
|
3
2
|
use message_lib_common::interfaces::ILayerZeroDVN;
|
|
4
|
-
use soroban_sdk::{contractclient, Address, Env, Vec};
|
|
3
|
+
use soroban_sdk::{contractclient, contracttype, Address, BytesN, Env, Symbol, Val, Vec};
|
|
5
4
|
use worker::Worker;
|
|
6
5
|
|
|
6
|
+
/// Configuration for a destination chain.
|
|
7
|
+
///
|
|
8
|
+
/// Contains fee calculation parameters specific to each destination endpoint.
|
|
9
|
+
#[contracttype]
|
|
10
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
11
|
+
pub struct DstConfig {
|
|
12
|
+
/// Gas for verification on the destination chain.
|
|
13
|
+
pub gas: u128,
|
|
14
|
+
/// Fee multiplier in basis points (10000 = 100%).
|
|
15
|
+
/// If 0, the default multiplier from worker config is used.
|
|
16
|
+
pub multiplier_bps: u32,
|
|
17
|
+
/// Minimum fee margin in USD (scaled by native decimals rate).
|
|
18
|
+
pub floor_margin_usd: u128,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/// Parameter for setting destination chain configuration.
|
|
22
|
+
#[contracttype]
|
|
23
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
24
|
+
pub struct DstConfigParam {
|
|
25
|
+
/// The destination endpoint ID.
|
|
26
|
+
pub dst_eid: u32,
|
|
27
|
+
/// The configuration for this destination.
|
|
28
|
+
pub config: DstConfig,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/// Represents a single contract invocation for multisig authorization.
|
|
32
|
+
///
|
|
33
|
+
/// Used in `hash_call_data` to compute the hash that signers sign over.
|
|
34
|
+
#[contracttype]
|
|
35
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
36
|
+
pub struct Call {
|
|
37
|
+
/// Target contract address.
|
|
38
|
+
pub to: Address,
|
|
39
|
+
/// Function name to invoke.
|
|
40
|
+
pub func: Symbol,
|
|
41
|
+
/// Function arguments.
|
|
42
|
+
pub args: Vec<Val>,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/// DVN (Decentralized Verifier Network) contract interface.
|
|
46
|
+
///
|
|
47
|
+
/// Extends the LayerZero DVN interface with destination configuration management
|
|
48
|
+
/// and multisig capabilities for secure cross-chain message verification.
|
|
7
49
|
#[contractclient(name = "DVNClient")]
|
|
8
50
|
pub trait IDVN: ILayerZeroDVN + Worker + IMultisig {
|
|
51
|
+
/// Sets the configuration for one or more destination chains.
|
|
52
|
+
///
|
|
53
|
+
/// # Arguments
|
|
54
|
+
/// * `admin` - The admin address (must provide authorization)
|
|
55
|
+
/// * `params` - List of destination configurations to set
|
|
9
56
|
fn set_dst_config(env: &Env, admin: &Address, params: &Vec<DstConfigParam>);
|
|
10
|
-
|
|
57
|
+
|
|
58
|
+
/// Gets the configuration for a destination chain.
|
|
59
|
+
///
|
|
60
|
+
/// # Arguments
|
|
61
|
+
/// * `dst_eid` - The destination endpoint ID
|
|
62
|
+
///
|
|
63
|
+
/// # Returns
|
|
64
|
+
/// The destination configuration, or `None` if not configured
|
|
65
|
+
fn dst_config(env: &Env, dst_eid: u32) -> Option<DstConfig>;
|
|
66
|
+
|
|
67
|
+
/// Returns the verifier ID (VID) of this DVN.
|
|
68
|
+
///
|
|
69
|
+
/// The VID is a unique identifier used in multisig authentication.
|
|
11
70
|
fn vid(env: &Env) -> u32;
|
|
71
|
+
|
|
72
|
+
/// Computes the hash of call data for multisig signing.
|
|
73
|
+
///
|
|
74
|
+
/// Off-chain signers use this to compute the hash they need to sign.
|
|
75
|
+
/// The hash includes the VID, expiration, and the calls being authorized.
|
|
76
|
+
///
|
|
77
|
+
/// # Arguments
|
|
78
|
+
/// * `vid` - Verifier ID (must match contract's VID)
|
|
79
|
+
/// * `expiration` - Expiration timestamp for the authorization
|
|
80
|
+
/// * `calls` - The contract calls being authorized
|
|
81
|
+
///
|
|
82
|
+
/// # Returns
|
|
83
|
+
/// A 32-byte keccak256 hash to be signed by the multisig quorum
|
|
84
|
+
fn hash_call_data(env: &Env, vid: u32, expiration: u64, calls: &Vec<Call>) -> BytesN<32>;
|
|
12
85
|
}
|
|
@@ -1,15 +1,56 @@
|
|
|
1
1
|
use soroban_sdk::{contractclient, BytesN, Env, Vec};
|
|
2
2
|
|
|
3
|
+
/// Length of an ECDSA signature (64 bytes) plus recovery ID (1 byte).
|
|
3
4
|
pub const SIGNATURE_LENGTH: usize = 65;
|
|
4
5
|
|
|
6
|
+
/// Multisig interface for threshold-based signature verification.
|
|
7
|
+
///
|
|
8
|
+
/// Provides functionality to manage signers and verify that a sufficient
|
|
9
|
+
/// number of valid signatures (meeting the threshold) have signed a message.
|
|
5
10
|
#[contractclient(name = "MultiSigClient")]
|
|
6
11
|
pub trait IMultisig {
|
|
12
|
+
/// Adds or removes a signer from the multisig.
|
|
13
|
+
///
|
|
14
|
+
/// # Arguments
|
|
15
|
+
/// * `signer` - The 20-byte signer address (derived from secp256k1 public key)
|
|
16
|
+
/// * `active` - `true` to add, `false` to remove
|
|
7
17
|
fn set_signer(env: &Env, signer: &BytesN<20>, active: bool);
|
|
18
|
+
|
|
19
|
+
/// Returns all registered signers.
|
|
8
20
|
fn get_signers(env: &Env) -> Vec<BytesN<20>>;
|
|
21
|
+
|
|
22
|
+
/// Returns the total number of registered signers.
|
|
9
23
|
fn total_signers(env: &Env) -> u32;
|
|
24
|
+
|
|
25
|
+
/// Checks if an address is a registered signer.
|
|
10
26
|
fn is_signer(env: &Env, signer: &BytesN<20>) -> bool;
|
|
27
|
+
|
|
28
|
+
/// Returns the current signature threshold (quorum).
|
|
11
29
|
fn threshold(env: &Env) -> u32;
|
|
30
|
+
|
|
31
|
+
/// Sets the signature threshold (quorum).
|
|
32
|
+
///
|
|
33
|
+
/// The threshold must be greater than 0 and not exceed total signers.
|
|
12
34
|
fn set_threshold(env: &Env, threshold: u32);
|
|
35
|
+
|
|
36
|
+
/// Verifies signatures against the configured threshold.
|
|
37
|
+
///
|
|
38
|
+
/// # Arguments
|
|
39
|
+
/// * `hash` - The 32-byte message hash that was signed
|
|
40
|
+
/// * `signatures` - List of signatures to verify
|
|
41
|
+
///
|
|
42
|
+
/// # Panics
|
|
43
|
+
/// If fewer than `threshold` valid signatures from registered signers are provided.
|
|
13
44
|
fn verify_signatures(env: &Env, hash: &BytesN<32>, signatures: &Vec<BytesN<SIGNATURE_LENGTH>>);
|
|
45
|
+
|
|
46
|
+
/// Verifies signatures against a custom threshold.
|
|
47
|
+
///
|
|
48
|
+
/// # Arguments
|
|
49
|
+
/// * `hash` - The 32-byte message hash that was signed
|
|
50
|
+
/// * `signatures` - List of signatures to verify
|
|
51
|
+
/// * `threshold` - Custom threshold to use instead of the configured one
|
|
52
|
+
///
|
|
53
|
+
/// # Panics
|
|
54
|
+
/// If fewer than `threshold` valid signatures from registered signers are provided.
|
|
14
55
|
fn verify_n_signatures(env: &Env, hash: &BytesN<32>, signatures: &Vec<BytesN<SIGNATURE_LENGTH>>, threshold: u32);
|
|
15
56
|
}
|
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
#![no_std]
|
|
2
|
-
#[cfg(test)]
|
|
3
|
-
extern crate std;
|
|
4
2
|
|
|
5
|
-
mod errors;
|
|
3
|
+
pub mod errors;
|
|
6
4
|
pub mod events;
|
|
7
|
-
mod interfaces;
|
|
8
|
-
mod types;
|
|
5
|
+
pub mod interfaces;
|
|
9
6
|
|
|
10
|
-
pub use errors::*;
|
|
11
7
|
pub use interfaces::*;
|
|
12
|
-
pub use types::*;
|
|
13
8
|
|
|
14
9
|
cfg_if::cfg_if! {
|
|
15
10
|
if #[cfg(any(not(feature = "library"), feature = "testutils"))] {
|
|
16
11
|
mod storage;
|
|
17
12
|
mod dvn;
|
|
18
13
|
|
|
19
|
-
pub use dvn
|
|
14
|
+
pub use dvn::*;
|
|
20
15
|
}
|
|
21
16
|
}
|
|
22
17
|
|
|
18
|
+
#[cfg(test)]
|
|
19
|
+
extern crate std;
|
|
20
|
+
|
|
23
21
|
#[cfg(test)]
|
|
24
22
|
mod tests;
|