@layerzerolabs/protocol-stellar-v2 0.2.19 → 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 +245 -222
- package/.turbo/turbo-lint.log +77 -70
- package/.turbo/turbo-test.log +1385 -1221
- package/Cargo.lock +13 -3
- package/Cargo.toml +2 -0
- package/contracts/ERROR_SPEC.md +8 -1
- 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 +22 -6
- 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/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/src/extensions/oft_fee.rs +18 -2
- 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/oft.rs +29 -41
- package/contracts/oapps/oft/src/oft_types/mint_burn.rs +3 -25
- package/contracts/oapps/oft-core/integration-tests/setup.rs +2 -2
- package/contracts/oapps/oft-core/src/oft_core.rs +247 -207
- package/contracts/oapps/oft-core/src/tests/test_utils.rs +4 -4
- 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 +3 -1
- 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 +3 -3
- package/sdk/.turbo/turbo-test.log +220 -218
- package/sdk/dist/generated/bml.d.ts +12 -4
- package/sdk/dist/generated/bml.js +8 -6
- package/sdk/dist/generated/counter.d.ts +12 -4
- package/sdk/dist/generated/counter.js +8 -6
- package/sdk/dist/generated/dvn.d.ts +404 -365
- package/sdk/dist/generated/dvn.js +55 -53
- package/sdk/dist/generated/dvn_fee_lib.d.ts +224 -268
- package/sdk/dist/generated/dvn_fee_lib.js +22 -53
- package/sdk/dist/generated/endpoint.d.ts +12 -4
- package/sdk/dist/generated/endpoint.js +8 -6
- package/sdk/dist/generated/executor.d.ts +370 -326
- package/sdk/dist/generated/executor.js +47 -44
- package/sdk/dist/generated/executor_fee_lib.d.ts +258 -302
- package/sdk/dist/generated/executor_fee_lib.js +21 -52
- package/sdk/dist/generated/executor_helper.d.ts +26 -190
- package/sdk/dist/generated/executor_helper.js +22 -27
- 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 +49 -40
- package/sdk/dist/generated/oft.js +25 -23
- package/sdk/dist/generated/price_feed.d.ts +225 -269
- package/sdk/dist/generated/price_feed.js +22 -53
- package/sdk/dist/generated/sml.d.ts +12 -4
- package/sdk/dist/generated/sml.js +8 -6
- package/sdk/dist/generated/treasury.d.ts +12 -4
- package/sdk/dist/generated/treasury.js +8 -6
- package/sdk/dist/generated/uln302.d.ts +12 -4
- package/sdk/dist/generated/uln302.js +10 -8
- package/sdk/dist/generated/upgrader.d.ts +189 -18
- package/sdk/dist/generated/upgrader.js +84 -4
- package/sdk/dist/index.d.ts +1 -0
- package/sdk/dist/index.js +2 -0
- package/sdk/package.json +1 -1
- package/sdk/src/index.ts +3 -0
- package/sdk/test/oft-sml.test.ts +4 -4
- package/sdk/test/upgrader.test.ts +2 -3
- package/tools/ts-bindings-gen/src/main.rs +2 -1
- /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
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
use crate::{
|
|
2
|
-
self as oapp, errors::OAppError, oapp_core::OAppCoreStorage, oapp_receiver::LzReceiveInternal,
|
|
3
|
-
tests::test_oapp_core::DummyEndpoint,
|
|
4
|
-
};
|
|
1
|
+
use crate::{self as oapp, errors::OAppError, oapp_receiver::LzReceiveInternal};
|
|
5
2
|
use endpoint_v2::Origin;
|
|
6
|
-
use soroban_sdk::{
|
|
7
|
-
|
|
3
|
+
use soroban_sdk::{
|
|
4
|
+
contract, contractimpl, symbol_short,
|
|
5
|
+
testutils::{Address as _, MockAuth, MockAuthInvoke},
|
|
6
|
+
token::StellarAssetClient,
|
|
7
|
+
Address, Bytes, BytesN, Env, IntoVal,
|
|
8
|
+
};
|
|
8
9
|
|
|
9
10
|
#[oapp_macros::oapp]
|
|
10
11
|
pub struct DummyOAppReceiver;
|
|
@@ -28,24 +29,57 @@ impl DummyOAppReceiver {
|
|
|
28
29
|
pub fn __constructor(env: &Env, owner: &Address, endpoint: &Address) {
|
|
29
30
|
oapp::oapp_core::initialize_oapp::<Self>(env, owner, endpoint, &None);
|
|
30
31
|
}
|
|
31
|
-
|
|
32
|
-
pub fn assert_allowed_peer(env: &Env, origin: &Origin) {
|
|
33
|
-
let peer = OAppCoreStorage::peer(env, origin.src_eid).unwrap_or_panic(env, OAppError::NoPeer);
|
|
34
|
-
assert_with_error!(env, peer == origin.sender, OAppError::OnlyPeer);
|
|
35
|
-
}
|
|
36
32
|
}
|
|
37
33
|
|
|
38
34
|
const REMOTE_EID: u32 = 100;
|
|
39
35
|
const UNSET_EID: u32 = 999;
|
|
40
36
|
|
|
37
|
+
// Mock Endpoint (minimal subset used by oapp_receiver::verify_and_clear_payload)
|
|
38
|
+
|
|
39
|
+
#[contract]
|
|
40
|
+
pub struct MockEndpoint;
|
|
41
|
+
|
|
42
|
+
#[contractimpl]
|
|
43
|
+
impl MockEndpoint {
|
|
44
|
+
pub fn __constructor(env: Env, native_token: Address) {
|
|
45
|
+
env.storage().instance().set(&symbol_short!("ntk"), &native_token);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
pub fn set_delegate(_env: Env, _oapp: &Address, _delegate: &Option<Address>) {
|
|
49
|
+
// do nothing
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
pub fn native_token(env: Env) -> Address {
|
|
53
|
+
env.storage().instance().get(&symbol_short!("ntk")).unwrap()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
pub fn clear(env: Env, caller: Address, origin: Origin, receiver: Address, guid: BytesN<32>, message: Bytes) {
|
|
57
|
+
// Record last clear for assertions
|
|
58
|
+
env.storage().instance().set(&symbol_short!("clr_c"), &caller);
|
|
59
|
+
env.storage().instance().set(&symbol_short!("clr_o"), &origin);
|
|
60
|
+
env.storage().instance().set(&symbol_short!("clr_r"), &receiver);
|
|
61
|
+
env.storage().instance().set(&symbol_short!("clr_g"), &guid);
|
|
62
|
+
env.storage().instance().set(&symbol_short!("clr_m"), &message);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
pub fn last_clear(env: Env) -> (Address, Origin, Address, BytesN<32>, Bytes) {
|
|
66
|
+
(
|
|
67
|
+
env.storage().instance().get(&symbol_short!("clr_c")).unwrap(),
|
|
68
|
+
env.storage().instance().get(&symbol_short!("clr_o")).unwrap(),
|
|
69
|
+
env.storage().instance().get(&symbol_short!("clr_r")).unwrap(),
|
|
70
|
+
env.storage().instance().get(&symbol_short!("clr_g")).unwrap(),
|
|
71
|
+
env.storage().instance().get(&symbol_short!("clr_m")).unwrap(),
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
41
76
|
struct TestSetup<'a> {
|
|
42
77
|
env: Env,
|
|
43
|
-
#[allow(dead_code)]
|
|
44
78
|
owner: Address,
|
|
45
|
-
#[allow(dead_code)]
|
|
46
79
|
endpoint: Address,
|
|
47
|
-
|
|
80
|
+
token_admin: Address,
|
|
48
81
|
native_token: Address,
|
|
82
|
+
native_token_admin_client: StellarAssetClient<'a>,
|
|
49
83
|
oapp_client: DummyOAppReceiverClient<'a>,
|
|
50
84
|
}
|
|
51
85
|
|
|
@@ -53,15 +87,56 @@ fn setup<'a>() -> TestSetup<'a> {
|
|
|
53
87
|
let env = Env::default();
|
|
54
88
|
|
|
55
89
|
let owner = Address::generate(&env);
|
|
56
|
-
let
|
|
57
|
-
let
|
|
90
|
+
let token_admin = Address::generate(&env);
|
|
91
|
+
let native_token_sac = env.register_stellar_asset_contract_v2(token_admin.clone());
|
|
92
|
+
let native_token = native_token_sac.address();
|
|
93
|
+
let native_token_admin_client = StellarAssetClient::new(&env, &native_token);
|
|
94
|
+
|
|
95
|
+
let endpoint = env.register(MockEndpoint, (&native_token,));
|
|
58
96
|
let oapp = env.register(DummyOAppReceiver, (&owner, &endpoint));
|
|
59
97
|
let oapp_client = DummyOAppReceiverClient::new(&env, &oapp);
|
|
60
|
-
TestSetup { env, owner, endpoint, native_token, oapp_client }
|
|
98
|
+
TestSetup { env, owner, endpoint, token_admin, native_token, native_token_admin_client, oapp_client }
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
fn set_peer(env: &Env, owner: &Address, oapp_client: &DummyOAppReceiverClient<'_>, eid: u32, peer: &BytesN<32>) {
|
|
102
|
+
let peer_option = Some(peer.clone());
|
|
103
|
+
env.mock_auths(&[MockAuth {
|
|
104
|
+
address: owner,
|
|
105
|
+
invoke: &MockAuthInvoke {
|
|
106
|
+
contract: &oapp_client.address,
|
|
107
|
+
fn_name: "set_peer",
|
|
108
|
+
args: (&eid, &peer_option).into_val(env),
|
|
109
|
+
sub_invokes: &[],
|
|
110
|
+
},
|
|
111
|
+
}]);
|
|
112
|
+
oapp_client.set_peer(&eid, &peer_option);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
fn lz_receive(
|
|
116
|
+
env: &Env,
|
|
117
|
+
oapp_client: &DummyOAppReceiverClient<'_>,
|
|
118
|
+
executor: &Address,
|
|
119
|
+
origin: &Origin,
|
|
120
|
+
guid: &BytesN<32>,
|
|
121
|
+
message: &Bytes,
|
|
122
|
+
extra_data: &Bytes,
|
|
123
|
+
value: i128,
|
|
124
|
+
sub_invokes: &[MockAuthInvoke<'_>],
|
|
125
|
+
) {
|
|
126
|
+
env.mock_auths(&[MockAuth {
|
|
127
|
+
address: executor,
|
|
128
|
+
invoke: &MockAuthInvoke {
|
|
129
|
+
contract: &oapp_client.address,
|
|
130
|
+
fn_name: "lz_receive",
|
|
131
|
+
args: (executor, origin, guid, message, extra_data, value).into_val(env),
|
|
132
|
+
sub_invokes,
|
|
133
|
+
},
|
|
134
|
+
}]);
|
|
135
|
+
oapp_client.lz_receive(executor, origin, guid, message, extra_data, &value);
|
|
61
136
|
}
|
|
62
137
|
|
|
63
138
|
#[test]
|
|
64
|
-
fn
|
|
139
|
+
fn test_is_compose_msg_sender() {
|
|
65
140
|
let TestSetup { env, oapp_client, .. } = setup();
|
|
66
141
|
|
|
67
142
|
let origin = Origin { src_eid: REMOTE_EID, sender: BytesN::from_array(&env, &[1; 32]), nonce: 1 };
|
|
@@ -70,84 +145,237 @@ fn test_is_compose_msg_sender_same_contract() {
|
|
|
70
145
|
// Test with same contract address (should return true)
|
|
71
146
|
let result = oapp_client.is_compose_msg_sender(&origin, &message, &oapp_client.address);
|
|
72
147
|
assert_eq!(result, true);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
#[test]
|
|
76
|
-
fn test_is_compose_msg_sender_different_contract() {
|
|
77
|
-
let TestSetup { env, oapp_client, .. } = setup();
|
|
78
|
-
|
|
79
|
-
let origin = Origin { src_eid: REMOTE_EID, sender: BytesN::from_array(&env, &[1; 32]), nonce: 1 };
|
|
80
|
-
let message = Bytes::from_array(&env, &[1, 2, 3, 4]);
|
|
81
148
|
let different_sender = Address::generate(&env);
|
|
82
149
|
|
|
83
150
|
// Test with different sender address (should return false)
|
|
84
|
-
|
|
85
|
-
assert_eq!(result, false);
|
|
151
|
+
assert_eq!(oapp_client.is_compose_msg_sender(&origin, &message, &different_sender), false);
|
|
86
152
|
}
|
|
87
153
|
|
|
88
154
|
#[test]
|
|
89
|
-
fn
|
|
90
|
-
let TestSetup { env, oapp_client, .. } = setup();
|
|
91
|
-
|
|
155
|
+
fn test_allow_initialize_path_cases() {
|
|
156
|
+
let TestSetup { env, owner, oapp_client, .. } = setup();
|
|
157
|
+
|
|
158
|
+
// no peer set -> false
|
|
159
|
+
let origin_no_peer = Origin { src_eid: UNSET_EID, sender: BytesN::from_array(&env, &[5; 32]), nonce: 1 };
|
|
160
|
+
assert_eq!(oapp_client.allow_initialize_path(&origin_no_peer), false);
|
|
92
161
|
|
|
162
|
+
// set peer for REMOTE_EID
|
|
93
163
|
let peer_bytes: BytesN<32> = BytesN::from_array(&env, &[5; 32]);
|
|
94
|
-
|
|
164
|
+
set_peer(&env, &owner, &oapp_client, REMOTE_EID, &peer_bytes);
|
|
95
165
|
|
|
96
|
-
|
|
166
|
+
// matching -> true
|
|
167
|
+
let origin_match = Origin { src_eid: REMOTE_EID, sender: peer_bytes.clone(), nonce: 1 };
|
|
168
|
+
assert_eq!(oapp_client.allow_initialize_path(&origin_match), true);
|
|
97
169
|
|
|
98
|
-
|
|
99
|
-
|
|
170
|
+
// non-matching -> false
|
|
171
|
+
let origin_non_match = Origin { src_eid: REMOTE_EID, sender: BytesN::from_array(&env, &[6; 32]), nonce: 1 };
|
|
172
|
+
assert_eq!(oapp_client.allow_initialize_path(&origin_non_match), false);
|
|
100
173
|
}
|
|
101
174
|
|
|
102
175
|
#[test]
|
|
103
|
-
fn
|
|
104
|
-
let TestSetup { env, oapp_client, .. } = setup();
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
let
|
|
108
|
-
|
|
176
|
+
fn test_lz_receive_verifies_peer_and_calls_clear_value_zero() {
|
|
177
|
+
let TestSetup { env, owner, endpoint, oapp_client, .. } = setup();
|
|
178
|
+
|
|
179
|
+
// Configure peer
|
|
180
|
+
let peer: BytesN<32> = BytesN::from_array(&env, &[7; 32]);
|
|
181
|
+
set_peer(&env, &owner, &oapp_client, REMOTE_EID, &peer);
|
|
182
|
+
|
|
183
|
+
let executor = Address::generate(&env);
|
|
184
|
+
let origin = Origin { src_eid: REMOTE_EID, sender: peer, nonce: 1 };
|
|
185
|
+
let guid = BytesN::from_array(&env, &[2u8; 32]);
|
|
186
|
+
let message = Bytes::from_array(&env, &[1, 2, 3]);
|
|
187
|
+
let extra_data = Bytes::new(&env);
|
|
188
|
+
lz_receive(&env, &oapp_client, &executor, &origin, &guid, &message, &extra_data, 0, &[]);
|
|
189
|
+
|
|
190
|
+
let endpoint_client = MockEndpointClient::new(&env, &endpoint);
|
|
191
|
+
let (caller, cleared_origin, receiver, cleared_guid, cleared_message) = endpoint_client.last_clear();
|
|
192
|
+
assert_eq!(caller, oapp_client.address);
|
|
193
|
+
assert_eq!(cleared_origin, origin);
|
|
194
|
+
assert_eq!(receiver, oapp_client.address);
|
|
195
|
+
assert_eq!(cleared_guid, guid);
|
|
196
|
+
assert_eq!(cleared_message, message);
|
|
197
|
+
}
|
|
109
198
|
|
|
110
|
-
|
|
111
|
-
|
|
199
|
+
#[test]
|
|
200
|
+
fn test_lz_receive_transfers_native_token_when_value_positive() {
|
|
201
|
+
let TestSetup { env, owner, endpoint, native_token, native_token_admin_client, token_admin, oapp_client, .. } =
|
|
202
|
+
setup();
|
|
203
|
+
|
|
204
|
+
// Configure peer
|
|
205
|
+
let peer: BytesN<32> = BytesN::from_array(&env, &[9; 32]);
|
|
206
|
+
set_peer(&env, &owner, &oapp_client, REMOTE_EID, &peer);
|
|
207
|
+
|
|
208
|
+
let executor = Address::generate(&env);
|
|
209
|
+
let origin = Origin { src_eid: REMOTE_EID, sender: peer, nonce: 1 };
|
|
210
|
+
let guid = BytesN::from_array(&env, &[3u8; 32]);
|
|
211
|
+
let message = Bytes::from_array(&env, &[4, 5, 6]);
|
|
212
|
+
let extra_data = Bytes::new(&env);
|
|
213
|
+
let value: i128 = 123;
|
|
214
|
+
|
|
215
|
+
// Mint native token to executor (admin auth)
|
|
216
|
+
env.mock_auths(&[MockAuth {
|
|
217
|
+
address: &token_admin,
|
|
218
|
+
invoke: &MockAuthInvoke {
|
|
219
|
+
contract: &native_token,
|
|
220
|
+
fn_name: "mint",
|
|
221
|
+
args: (&executor, &value).into_val(&env),
|
|
222
|
+
sub_invokes: &[],
|
|
223
|
+
},
|
|
224
|
+
}]);
|
|
225
|
+
native_token_admin_client.mint(&executor, &value);
|
|
226
|
+
|
|
227
|
+
// lz_receive should transfer tokens from executor -> oapp
|
|
228
|
+
let transfer_invoke = MockAuthInvoke {
|
|
229
|
+
contract: &native_token,
|
|
230
|
+
fn_name: "transfer",
|
|
231
|
+
args: (&executor, &oapp_client.address, &value).into_val(&env),
|
|
232
|
+
sub_invokes: &[],
|
|
233
|
+
};
|
|
234
|
+
let sub_invokes = [transfer_invoke];
|
|
235
|
+
lz_receive(&env, &oapp_client, &executor, &origin, &guid, &message, &extra_data, value, &sub_invokes);
|
|
236
|
+
|
|
237
|
+
let endpoint_client = MockEndpointClient::new(&env, &endpoint);
|
|
238
|
+
// Asserts clear() was called (last_clear() will panic if not)
|
|
239
|
+
endpoint_client.last_clear();
|
|
240
|
+
|
|
241
|
+
let token_client = soroban_sdk::token::TokenClient::new(&env, &native_token);
|
|
242
|
+
assert_eq!(token_client.balance(&executor), 0);
|
|
243
|
+
assert_eq!(token_client.balance(&oapp_client.address), value);
|
|
244
|
+
}
|
|
112
245
|
|
|
113
|
-
|
|
114
|
-
|
|
246
|
+
#[test]
|
|
247
|
+
fn test_lz_receive_rejects_negative_value_and_does_not_clear() {
|
|
248
|
+
let TestSetup { env, owner, endpoint, native_token, native_token_admin_client, token_admin, oapp_client, .. } =
|
|
249
|
+
setup();
|
|
250
|
+
|
|
251
|
+
// Configure peer
|
|
252
|
+
let peer: BytesN<32> = BytesN::from_array(&env, &[9; 32]);
|
|
253
|
+
set_peer(&env, &owner, &oapp_client, REMOTE_EID, &peer);
|
|
254
|
+
|
|
255
|
+
let executor = Address::generate(&env);
|
|
256
|
+
let origin = Origin { src_eid: REMOTE_EID, sender: peer, nonce: 1 };
|
|
257
|
+
let guid = BytesN::from_array(&env, &[3u8; 32]);
|
|
258
|
+
let message = Bytes::from_array(&env, &[4, 5, 6]);
|
|
259
|
+
let extra_data = Bytes::new(&env);
|
|
260
|
+
let value: i128 = -123;
|
|
261
|
+
|
|
262
|
+
// Fund executor with a positive balance so the only failure is the negative amount.
|
|
263
|
+
env.mock_auths(&[MockAuth {
|
|
264
|
+
address: &token_admin,
|
|
265
|
+
invoke: &MockAuthInvoke {
|
|
266
|
+
contract: &native_token,
|
|
267
|
+
fn_name: "mint",
|
|
268
|
+
args: (&executor, &(-value)).into_val(&env),
|
|
269
|
+
sub_invokes: &[],
|
|
270
|
+
},
|
|
271
|
+
}]);
|
|
272
|
+
native_token_admin_client.mint(&executor, &(-value));
|
|
273
|
+
|
|
274
|
+
// lz_receive should attempt transfer with a negative value and fail.
|
|
275
|
+
let transfer_invoke = MockAuthInvoke {
|
|
276
|
+
contract: &native_token,
|
|
277
|
+
fn_name: "transfer",
|
|
278
|
+
args: (&executor, &oapp_client.address, &value).into_val(&env),
|
|
279
|
+
sub_invokes: &[],
|
|
280
|
+
};
|
|
281
|
+
let sub_invokes = [transfer_invoke];
|
|
282
|
+
env.mock_auths(&[MockAuth {
|
|
283
|
+
address: &executor,
|
|
284
|
+
invoke: &MockAuthInvoke {
|
|
285
|
+
contract: &oapp_client.address,
|
|
286
|
+
fn_name: "lz_receive",
|
|
287
|
+
args: (&executor, &origin, &guid, &message, &extra_data, &value).into_val(&env),
|
|
288
|
+
sub_invokes: &sub_invokes,
|
|
289
|
+
},
|
|
290
|
+
}]);
|
|
291
|
+
|
|
292
|
+
let result = oapp_client.try_lz_receive(&executor, &origin, &guid, &message, &extra_data, &value);
|
|
293
|
+
assert_eq!(result.err().unwrap().ok().unwrap(), soroban_sdk::Error::from_contract_error(8)); //negative amount is not allowed
|
|
294
|
+
|
|
295
|
+
// No balances changed.
|
|
296
|
+
let token_client = soroban_sdk::token::TokenClient::new(&env, &native_token);
|
|
297
|
+
assert_eq!(token_client.balance(&executor), -value);
|
|
298
|
+
assert_eq!(token_client.balance(&oapp_client.address), 0);
|
|
299
|
+
|
|
300
|
+
// Payload should not have been cleared.
|
|
301
|
+
let endpoint_client = MockEndpointClient::new(&env, &endpoint);
|
|
302
|
+
assert!(endpoint_client.try_last_clear().is_err());
|
|
115
303
|
}
|
|
116
304
|
|
|
117
305
|
#[test]
|
|
118
|
-
fn
|
|
306
|
+
fn test_next_nonce_defaults_to_zero() {
|
|
119
307
|
let TestSetup { env, oapp_client, .. } = setup();
|
|
308
|
+
let sender = BytesN::from_array(&env, &[1u8; 32]);
|
|
309
|
+
assert_eq!(oapp_client.next_nonce(&REMOTE_EID, &sender), 0);
|
|
310
|
+
}
|
|
120
311
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
312
|
+
#[test]
|
|
313
|
+
#[should_panic(expected = "HostError: Error(Auth, InvalidAction)")]
|
|
314
|
+
fn test_lz_receive_requires_executor_auth() {
|
|
315
|
+
let TestSetup { env, owner, oapp_client, .. } = setup();
|
|
316
|
+
|
|
317
|
+
let peer: BytesN<32> = BytesN::from_array(&env, &[7; 32]);
|
|
318
|
+
set_peer(&env, &owner, &oapp_client, REMOTE_EID, &peer);
|
|
319
|
+
|
|
320
|
+
// Call without executor auth mocked -> should fail at executor.require_auth()
|
|
321
|
+
let executor = Address::generate(&env);
|
|
322
|
+
let origin = Origin { src_eid: REMOTE_EID, sender: peer, nonce: 1 };
|
|
323
|
+
let guid = BytesN::from_array(&env, &[2u8; 32]);
|
|
324
|
+
let message = Bytes::from_array(&env, &[1, 2, 3]);
|
|
325
|
+
let extra_data = Bytes::new(&env);
|
|
326
|
+
oapp_client.lz_receive(&executor, &origin, &guid, &message, &extra_data, &0);
|
|
125
327
|
}
|
|
126
328
|
|
|
127
329
|
#[test]
|
|
128
|
-
fn
|
|
129
|
-
let TestSetup { env, oapp_client, .. } = setup();
|
|
130
|
-
env.mock_all_auths();
|
|
330
|
+
fn test_lz_receive_wrong_peer_returns_only_peer_error() {
|
|
331
|
+
let TestSetup { env, owner, oapp_client, .. } = setup();
|
|
131
332
|
|
|
132
|
-
let
|
|
133
|
-
|
|
333
|
+
let configured_peer: BytesN<32> = BytesN::from_array(&env, &[7; 32]);
|
|
334
|
+
set_peer(&env, &owner, &oapp_client, REMOTE_EID, &configured_peer);
|
|
134
335
|
|
|
336
|
+
let executor = Address::generate(&env);
|
|
135
337
|
let wrong_sender: BytesN<32> = BytesN::from_array(&env, &[8; 32]);
|
|
136
338
|
let origin = Origin { src_eid: REMOTE_EID, sender: wrong_sender, nonce: 1 };
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
let
|
|
339
|
+
let guid = BytesN::from_array(&env, &[2u8; 32]);
|
|
340
|
+
let message = Bytes::from_array(&env, &[1, 2, 3]);
|
|
341
|
+
let extra_data = Bytes::new(&env);
|
|
342
|
+
let value: i128 = 0;
|
|
343
|
+
|
|
344
|
+
env.mock_auths(&[MockAuth {
|
|
345
|
+
address: &executor,
|
|
346
|
+
invoke: &MockAuthInvoke {
|
|
347
|
+
contract: &oapp_client.address,
|
|
348
|
+
fn_name: "lz_receive",
|
|
349
|
+
args: (&executor, &origin, &guid, &message, &extra_data, &value).into_val(&env),
|
|
350
|
+
sub_invokes: &[],
|
|
351
|
+
},
|
|
352
|
+
}]);
|
|
353
|
+
let result = oapp_client.try_lz_receive(&executor, &origin, &guid, &message, &extra_data, &value);
|
|
140
354
|
assert_eq!(result.err().unwrap().ok().unwrap(), OAppError::OnlyPeer.into());
|
|
141
355
|
}
|
|
142
356
|
|
|
143
357
|
#[test]
|
|
144
|
-
fn
|
|
358
|
+
fn test_lz_receive_no_peer_returns_only_peer_error() {
|
|
145
359
|
let TestSetup { env, oapp_client, .. } = setup();
|
|
146
|
-
env.mock_all_auths();
|
|
147
360
|
|
|
148
|
-
let
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
let
|
|
152
|
-
|
|
361
|
+
let executor = Address::generate(&env);
|
|
362
|
+
let origin = Origin { src_eid: REMOTE_EID, sender: BytesN::from_array(&env, &[1; 32]), nonce: 1 };
|
|
363
|
+
let guid = BytesN::from_array(&env, &[2u8; 32]);
|
|
364
|
+
let message = Bytes::from_array(&env, &[1, 2, 3]);
|
|
365
|
+
let extra_data = Bytes::new(&env);
|
|
366
|
+
let value: i128 = 0;
|
|
367
|
+
|
|
368
|
+
env.mock_auths(&[MockAuth {
|
|
369
|
+
address: &executor,
|
|
370
|
+
invoke: &MockAuthInvoke {
|
|
371
|
+
contract: &oapp_client.address,
|
|
372
|
+
fn_name: "lz_receive",
|
|
373
|
+
args: (&executor, &origin, &guid, &message, &extra_data, &value).into_val(&env),
|
|
374
|
+
sub_invokes: &[],
|
|
375
|
+
},
|
|
376
|
+
}]);
|
|
377
|
+
|
|
378
|
+
// No peer configured -> should fail the peer check with OnlyPeer
|
|
379
|
+
let result = oapp_client.try_lz_receive(&executor, &origin, &guid, &message, &extra_data, &value);
|
|
380
|
+
assert_eq!(result.err().unwrap().ok().unwrap(), OAppError::OnlyPeer.into());
|
|
153
381
|
}
|