@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
|
@@ -14,7 +14,8 @@ pub struct MockEndpoint;
|
|
|
14
14
|
#[contractimpl]
|
|
15
15
|
impl MockEndpoint {
|
|
16
16
|
pub fn __constructor(env: Env, zro_token: &Address, native_token: &Address) {
|
|
17
|
-
|
|
17
|
+
// Store as Option<Address> so zro() can return None when unavailable.
|
|
18
|
+
env.storage().instance().set(&symbol_short!("zro"), &Some(zro_token.clone()));
|
|
18
19
|
env.storage().instance().set(&symbol_short!("ntk"), native_token);
|
|
19
20
|
}
|
|
20
21
|
|
|
@@ -27,6 +28,11 @@ impl MockEndpoint {
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
pub fn send(env: Env, _sender: Address, params: MessagingParams, _refund_address: Address) -> MessagingReceipt {
|
|
31
|
+
// Record last send call for assertions
|
|
32
|
+
env.storage().instance().set(&symbol_short!("snds"), &_sender);
|
|
33
|
+
env.storage().instance().set(&symbol_short!("sndp"), ¶ms);
|
|
34
|
+
env.storage().instance().set(&symbol_short!("sndr"), &_refund_address);
|
|
35
|
+
|
|
30
36
|
// Return mock receipt
|
|
31
37
|
MessagingReceipt {
|
|
32
38
|
guid: BytesN::from_array(&env, &[1u8; 32]),
|
|
@@ -35,14 +41,26 @@ impl MockEndpoint {
|
|
|
35
41
|
}
|
|
36
42
|
}
|
|
37
43
|
|
|
44
|
+
pub fn last_send(env: Env) -> (Address, MessagingParams, Address) {
|
|
45
|
+
(
|
|
46
|
+
env.storage().instance().get(&symbol_short!("snds")).unwrap(),
|
|
47
|
+
env.storage().instance().get(&symbol_short!("sndp")).unwrap(),
|
|
48
|
+
env.storage().instance().get(&symbol_short!("sndr")).unwrap(),
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
38
52
|
pub fn zro(env: Env) -> Option<Address> {
|
|
39
|
-
// Return a mock ZRO token address
|
|
40
|
-
env.storage().instance().get(&symbol_short!("zro")).
|
|
53
|
+
// Return a mock ZRO token address (or None if not set)
|
|
54
|
+
env.storage().instance().get(&symbol_short!("zro")).unwrap_or(None)
|
|
41
55
|
}
|
|
42
56
|
|
|
43
57
|
pub fn native_token(env: Env) -> Address {
|
|
44
58
|
env.storage().instance().get(&symbol_short!("ntk")).unwrap()
|
|
45
59
|
}
|
|
60
|
+
|
|
61
|
+
pub fn set_zro(env: Env, zro: &Option<Address>) {
|
|
62
|
+
env.storage().instance().set(&symbol_short!("zro"), zro);
|
|
63
|
+
}
|
|
46
64
|
}
|
|
47
65
|
|
|
48
66
|
#[oapp_macros::oapp]
|
|
@@ -101,12 +119,12 @@ const UNSET_EID: u32 = 999;
|
|
|
101
119
|
|
|
102
120
|
struct TestSetup<'a> {
|
|
103
121
|
env: Env,
|
|
104
|
-
#[allow(dead_code)]
|
|
105
122
|
token_admin: Address,
|
|
106
123
|
endpoint: Address,
|
|
107
|
-
#[allow(dead_code)]
|
|
108
124
|
owner: Address,
|
|
109
125
|
oapp_client: DummyOAppSenderClient<'a>,
|
|
126
|
+
native_token: Address,
|
|
127
|
+
zro_token: Address,
|
|
110
128
|
native_token_client: TokenClient<'a>,
|
|
111
129
|
native_token_admin_client: StellarAssetClient<'a>,
|
|
112
130
|
zro_token_admin_client: StellarAssetClient<'a>,
|
|
@@ -142,41 +160,124 @@ fn setup<'a>() -> TestSetup<'a> {
|
|
|
142
160
|
native_token_client,
|
|
143
161
|
native_token_admin_client,
|
|
144
162
|
zro_token_admin_client,
|
|
163
|
+
native_token,
|
|
164
|
+
zro_token,
|
|
145
165
|
owner,
|
|
146
166
|
oapp_client,
|
|
147
167
|
}
|
|
148
168
|
}
|
|
149
169
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
170
|
+
fn set_peer_with_auth(
|
|
171
|
+
env: &Env,
|
|
172
|
+
owner: &Address,
|
|
173
|
+
oapp_client: &DummyOAppSenderClient<'_>,
|
|
174
|
+
eid: u32,
|
|
175
|
+
peer: &BytesN<32>,
|
|
176
|
+
) {
|
|
156
177
|
let peer_option = Some(peer.clone());
|
|
157
178
|
env.mock_auths(&[MockAuth {
|
|
158
|
-
address:
|
|
179
|
+
address: owner,
|
|
159
180
|
invoke: &MockAuthInvoke {
|
|
160
181
|
contract: &oapp_client.address,
|
|
161
182
|
fn_name: "set_peer",
|
|
162
|
-
args: (&
|
|
183
|
+
args: (&eid, &peer_option).into_val(env),
|
|
163
184
|
sub_invokes: &[],
|
|
164
185
|
},
|
|
165
186
|
}]);
|
|
166
|
-
oapp_client.set_peer(&
|
|
187
|
+
oapp_client.set_peer(&eid, &peer_option);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
fn mint_to(
|
|
191
|
+
env: &Env,
|
|
192
|
+
token_admin: &Address,
|
|
193
|
+
token: &Address,
|
|
194
|
+
token_admin_client: &StellarAssetClient<'_>,
|
|
195
|
+
to: &Address,
|
|
196
|
+
amount: i128,
|
|
197
|
+
) {
|
|
198
|
+
env.mock_auths(&[MockAuth {
|
|
199
|
+
address: token_admin,
|
|
200
|
+
invoke: &MockAuthInvoke {
|
|
201
|
+
contract: token,
|
|
202
|
+
fn_name: "mint",
|
|
203
|
+
args: (to, amount).into_val(env),
|
|
204
|
+
sub_invokes: &[],
|
|
205
|
+
},
|
|
206
|
+
}]);
|
|
207
|
+
token_admin_client.mint(to, &amount);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
fn mock_send_auth(
|
|
211
|
+
env: &Env,
|
|
212
|
+
sender: &Address,
|
|
213
|
+
oapp_client: &DummyOAppSenderClient<'_>,
|
|
214
|
+
dst_eid: u32,
|
|
215
|
+
message: &Bytes,
|
|
216
|
+
options: &Bytes,
|
|
217
|
+
fee: &MessagingFee,
|
|
218
|
+
refund_address: &Address,
|
|
219
|
+
native_token: &Address,
|
|
220
|
+
endpoint: &Address,
|
|
221
|
+
zro_token: &Address,
|
|
222
|
+
) {
|
|
223
|
+
let native_transfer = MockAuthInvoke {
|
|
224
|
+
contract: native_token,
|
|
225
|
+
fn_name: "transfer",
|
|
226
|
+
args: (sender, endpoint, &fee.native_fee).into_val(env),
|
|
227
|
+
sub_invokes: &[],
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
if fee.zro_fee > 0 {
|
|
231
|
+
let zro_transfer = MockAuthInvoke {
|
|
232
|
+
contract: zro_token,
|
|
233
|
+
fn_name: "transfer",
|
|
234
|
+
args: (sender, endpoint, &fee.zro_fee).into_val(env),
|
|
235
|
+
sub_invokes: &[],
|
|
236
|
+
};
|
|
237
|
+
let sub_invokes = [native_transfer, zro_transfer];
|
|
238
|
+
env.mock_auths(&[MockAuth {
|
|
239
|
+
address: sender,
|
|
240
|
+
invoke: &MockAuthInvoke {
|
|
241
|
+
contract: &oapp_client.address,
|
|
242
|
+
fn_name: "send",
|
|
243
|
+
args: (sender, &dst_eid, message, options, fee, refund_address).into_val(env),
|
|
244
|
+
sub_invokes: &sub_invokes,
|
|
245
|
+
},
|
|
246
|
+
}]);
|
|
247
|
+
} else {
|
|
248
|
+
let sub_invokes = [native_transfer];
|
|
249
|
+
env.mock_auths(&[MockAuth {
|
|
250
|
+
address: sender,
|
|
251
|
+
invoke: &MockAuthInvoke {
|
|
252
|
+
contract: &oapp_client.address,
|
|
253
|
+
fn_name: "send",
|
|
254
|
+
args: (sender, &dst_eid, message, options, fee, refund_address).into_val(env),
|
|
255
|
+
sub_invokes: &sub_invokes,
|
|
256
|
+
},
|
|
257
|
+
}]);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
#[test]
|
|
262
|
+
fn test_quote_with_peer_set() {
|
|
263
|
+
let TestSetup { env, owner, oapp_client, .. } = setup();
|
|
264
|
+
|
|
265
|
+
// Set peer for destination
|
|
266
|
+
let peer = BytesN::from_array(&env, &[1; 32]);
|
|
267
|
+
set_peer_with_auth(&env, &owner, &oapp_client, REMOTE_EID, &peer);
|
|
167
268
|
|
|
168
269
|
let message = Bytes::from_array(&env, &[1, 2, 3, 4, 5]);
|
|
169
270
|
let options = Bytes::from_array(&env, &[6, 7, 8]);
|
|
170
271
|
|
|
171
272
|
// Test quote without ZRO
|
|
172
273
|
let fee = oapp_client.quote(&REMOTE_EID, &message, &options, &false);
|
|
173
|
-
|
|
274
|
+
assert_eq!(fee.native_fee, 1000);
|
|
174
275
|
assert_eq!(fee.zro_fee, 0);
|
|
175
276
|
|
|
176
277
|
// Test quote with ZRO
|
|
177
278
|
let fee_with_zro = oapp_client.quote(&REMOTE_EID, &message, &options, &true);
|
|
178
|
-
|
|
179
|
-
|
|
279
|
+
assert_eq!(fee_with_zro.native_fee, 1000);
|
|
280
|
+
assert_eq!(fee_with_zro.zro_fee, 500);
|
|
180
281
|
}
|
|
181
282
|
|
|
182
283
|
#[test]
|
|
@@ -193,80 +294,158 @@ fn test_quote_without_peer_panics() {
|
|
|
193
294
|
|
|
194
295
|
#[test]
|
|
195
296
|
fn test_lz_send_native_only() {
|
|
196
|
-
let TestSetup {
|
|
197
|
-
|
|
198
|
-
|
|
297
|
+
let TestSetup {
|
|
298
|
+
env,
|
|
299
|
+
oapp_client,
|
|
300
|
+
endpoint,
|
|
301
|
+
native_token,
|
|
302
|
+
zro_token,
|
|
303
|
+
native_token_client,
|
|
304
|
+
native_token_admin_client,
|
|
305
|
+
token_admin,
|
|
306
|
+
owner,
|
|
307
|
+
..
|
|
308
|
+
} = setup();
|
|
199
309
|
|
|
200
310
|
// Setup peer
|
|
201
311
|
let peer = BytesN::from_array(&env, &[2; 32]);
|
|
202
|
-
|
|
312
|
+
set_peer_with_auth(&env, &owner, &oapp_client, REMOTE_EID, &peer);
|
|
203
313
|
|
|
204
|
-
// Setup sender with funds
|
|
205
314
|
let sender = Address::generate(&env);
|
|
206
|
-
|
|
207
|
-
native_token_admin_client.mint(&sender, &initial_balance);
|
|
315
|
+
mint_to(&env, &token_admin, &native_token, &native_token_admin_client, &sender, 1000i128);
|
|
208
316
|
|
|
209
317
|
let message = Bytes::from_array(&env, &[1, 2, 3]);
|
|
210
318
|
let options = Bytes::from_array(&env, &[]);
|
|
211
319
|
let refund_address = Address::generate(&env);
|
|
212
|
-
|
|
213
320
|
let fee = MessagingFee { native_fee: 1000, zro_fee: 0 };
|
|
214
321
|
|
|
215
|
-
|
|
322
|
+
mock_send_auth(
|
|
323
|
+
&env,
|
|
324
|
+
&sender,
|
|
325
|
+
&oapp_client,
|
|
326
|
+
REMOTE_EID,
|
|
327
|
+
&message,
|
|
328
|
+
&options,
|
|
329
|
+
&fee,
|
|
330
|
+
&refund_address,
|
|
331
|
+
&native_token,
|
|
332
|
+
&endpoint,
|
|
333
|
+
&zro_token,
|
|
334
|
+
);
|
|
216
335
|
let receipt = oapp_client.send(&sender, &REMOTE_EID, &message, &options, &fee, &refund_address);
|
|
217
336
|
|
|
218
|
-
// Verify receipt
|
|
219
337
|
assert_eq!(receipt.nonce, 1);
|
|
220
|
-
assert_eq!(receipt.fee.native_fee,
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
assert_eq!(
|
|
338
|
+
assert_eq!(receipt.fee.native_fee, 1000);
|
|
339
|
+
assert_eq!(receipt.fee.zro_fee, 0);
|
|
340
|
+
|
|
341
|
+
// Assert the endpoint received the correct send params
|
|
342
|
+
let endpoint_client = MockEndpointClient::new(&env, &endpoint);
|
|
343
|
+
let (endpoint_sender, params, refund) = endpoint_client.last_send();
|
|
344
|
+
assert_eq!(endpoint_sender, oapp_client.address);
|
|
345
|
+
assert_eq!(params.dst_eid, REMOTE_EID);
|
|
346
|
+
assert_eq!(params.receiver, peer);
|
|
347
|
+
assert_eq!(params.message, message);
|
|
348
|
+
assert_eq!(params.options, options);
|
|
349
|
+
assert_eq!(params.pay_in_zro, false);
|
|
350
|
+
assert_eq!(refund, refund_address);
|
|
351
|
+
|
|
352
|
+
assert_eq!(native_token_client.balance(&sender), 0);
|
|
353
|
+
assert_eq!(native_token_client.balance(&endpoint), 1000);
|
|
354
|
+
assert_eq!(TokenClient::new(&env, &zro_token).balance(&endpoint), 0);
|
|
228
355
|
}
|
|
229
356
|
|
|
230
357
|
#[test]
|
|
231
358
|
fn test_lz_send_with_zro() {
|
|
232
|
-
let TestSetup {
|
|
233
|
-
|
|
234
|
-
|
|
359
|
+
let TestSetup {
|
|
360
|
+
env,
|
|
361
|
+
oapp_client,
|
|
362
|
+
endpoint,
|
|
363
|
+
native_token,
|
|
364
|
+
zro_token,
|
|
365
|
+
native_token_client,
|
|
366
|
+
native_token_admin_client,
|
|
367
|
+
zro_token_admin_client,
|
|
368
|
+
token_admin,
|
|
369
|
+
owner,
|
|
370
|
+
..
|
|
371
|
+
} = setup();
|
|
235
372
|
|
|
236
373
|
// Setup peer
|
|
237
374
|
let peer = BytesN::from_array(&env, &[3; 32]);
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
// Setup sender with both native and ZRO funds
|
|
241
|
-
let fee = MessagingFee { native_fee: 1000, zro_fee: 500 };
|
|
375
|
+
set_peer_with_auth(&env, &owner, &oapp_client, REMOTE_EID, &peer);
|
|
242
376
|
|
|
243
377
|
let sender = Address::generate(&env);
|
|
244
|
-
|
|
245
|
-
|
|
378
|
+
let fee = MessagingFee { native_fee: 1000, zro_fee: 500 };
|
|
379
|
+
mint_to(&env, &token_admin, &native_token, &native_token_admin_client, &sender, fee.native_fee);
|
|
380
|
+
mint_to(&env, &token_admin, &zro_token, &zro_token_admin_client, &sender, fee.zro_fee);
|
|
246
381
|
|
|
247
|
-
let message = Bytes::from_array(&env, &[
|
|
248
|
-
let options = Bytes::from_array(&env, &[
|
|
382
|
+
let message = Bytes::from_array(&env, &[4, 5, 6]);
|
|
383
|
+
let options = Bytes::from_array(&env, &[7]);
|
|
249
384
|
let refund_address = Address::generate(&env);
|
|
250
385
|
|
|
251
|
-
|
|
386
|
+
mock_send_auth(
|
|
387
|
+
&env,
|
|
388
|
+
&sender,
|
|
389
|
+
&oapp_client,
|
|
390
|
+
REMOTE_EID,
|
|
391
|
+
&message,
|
|
392
|
+
&options,
|
|
393
|
+
&fee,
|
|
394
|
+
&refund_address,
|
|
395
|
+
&native_token,
|
|
396
|
+
&endpoint,
|
|
397
|
+
&zro_token,
|
|
398
|
+
);
|
|
252
399
|
let receipt = oapp_client.send(&sender, &REMOTE_EID, &message, &options, &fee, &refund_address);
|
|
253
400
|
|
|
254
|
-
assert_eq!(receipt.
|
|
401
|
+
assert_eq!(receipt.nonce, 1);
|
|
402
|
+
assert_eq!(receipt.fee.native_fee, 1000);
|
|
403
|
+
assert_eq!(receipt.fee.zro_fee, 500);
|
|
404
|
+
|
|
405
|
+
// Assert the endpoint received the correct send params
|
|
406
|
+
let endpoint_client = MockEndpointClient::new(&env, &endpoint);
|
|
407
|
+
let (endpoint_sender, params, refund) = endpoint_client.last_send();
|
|
408
|
+
assert_eq!(endpoint_sender, oapp_client.address);
|
|
409
|
+
assert_eq!(params.dst_eid, REMOTE_EID);
|
|
410
|
+
assert_eq!(params.receiver, peer);
|
|
411
|
+
assert_eq!(params.message, message);
|
|
412
|
+
assert_eq!(params.options, options);
|
|
413
|
+
assert_eq!(params.pay_in_zro, true);
|
|
414
|
+
assert_eq!(refund, refund_address);
|
|
415
|
+
|
|
416
|
+
assert_eq!(native_token_client.balance(&sender), 0);
|
|
417
|
+
assert_eq!(native_token_client.balance(&endpoint), 1000);
|
|
418
|
+
|
|
419
|
+
let zro_token_client = TokenClient::new(&env, &zro_token);
|
|
420
|
+
assert_eq!(zro_token_client.balance(&sender), 0);
|
|
421
|
+
assert_eq!(zro_token_client.balance(&endpoint), 500);
|
|
255
422
|
}
|
|
256
423
|
|
|
257
424
|
#[test]
|
|
258
425
|
fn test_pay_native() {
|
|
259
|
-
let TestSetup { env, oapp_client, endpoint, native_token_admin_client, .. } = setup();
|
|
260
|
-
|
|
261
|
-
env.mock_all_auths();
|
|
426
|
+
let TestSetup { env, oapp_client, endpoint, native_token, native_token_admin_client, token_admin, .. } = setup();
|
|
262
427
|
|
|
263
428
|
let payer = Address::generate(&env);
|
|
264
429
|
let payment_amount = 2000i128;
|
|
265
430
|
|
|
266
431
|
// Fund the payer
|
|
267
|
-
|
|
432
|
+
mint_to(&env, &token_admin, &native_token, &native_token_admin_client, &payer, payment_amount);
|
|
268
433
|
|
|
269
434
|
// Make payment
|
|
435
|
+
env.mock_auths(&[MockAuth {
|
|
436
|
+
address: &payer,
|
|
437
|
+
invoke: &MockAuthInvoke {
|
|
438
|
+
contract: &oapp_client.address,
|
|
439
|
+
fn_name: "pay_native_fee",
|
|
440
|
+
args: (&payer, &payment_amount).into_val(&env),
|
|
441
|
+
sub_invokes: &[MockAuthInvoke {
|
|
442
|
+
contract: &native_token,
|
|
443
|
+
fn_name: "transfer",
|
|
444
|
+
args: (&payer, &endpoint, &payment_amount).into_val(&env),
|
|
445
|
+
sub_invokes: &[],
|
|
446
|
+
}],
|
|
447
|
+
},
|
|
448
|
+
}]);
|
|
270
449
|
oapp_client.pay_native_fee(&payer, &payment_amount);
|
|
271
450
|
|
|
272
451
|
// Verify balances
|
|
@@ -277,9 +456,7 @@ fn test_pay_native() {
|
|
|
277
456
|
#[test]
|
|
278
457
|
#[should_panic(expected = "balance is not sufficient to spend")]
|
|
279
458
|
fn test_pay_native_insufficient_balance() {
|
|
280
|
-
let TestSetup { env, oapp_client, native_token_admin_client, .. } = setup();
|
|
281
|
-
|
|
282
|
-
env.mock_all_auths();
|
|
459
|
+
let TestSetup { env, oapp_client, endpoint, native_token, native_token_admin_client, token_admin, .. } = setup();
|
|
283
460
|
|
|
284
461
|
let balance = 500i128;
|
|
285
462
|
let payment_amount = 1000i128;
|
|
@@ -287,8 +464,106 @@ fn test_pay_native_insufficient_balance() {
|
|
|
287
464
|
let payer = Address::generate(&env);
|
|
288
465
|
|
|
289
466
|
// Fund with less than required
|
|
290
|
-
|
|
467
|
+
mint_to(&env, &token_admin, &native_token, &native_token_admin_client, &payer, balance);
|
|
291
468
|
|
|
292
469
|
// This should panic due to insufficient balance
|
|
470
|
+
env.mock_auths(&[MockAuth {
|
|
471
|
+
address: &payer,
|
|
472
|
+
invoke: &MockAuthInvoke {
|
|
473
|
+
contract: &oapp_client.address,
|
|
474
|
+
fn_name: "pay_native_fee",
|
|
475
|
+
args: (&payer, &payment_amount).into_val(&env),
|
|
476
|
+
sub_invokes: &[MockAuthInvoke {
|
|
477
|
+
contract: &native_token,
|
|
478
|
+
fn_name: "transfer",
|
|
479
|
+
args: (&payer, &endpoint, &payment_amount).into_val(&env),
|
|
480
|
+
sub_invokes: &[],
|
|
481
|
+
}],
|
|
482
|
+
},
|
|
483
|
+
}]);
|
|
293
484
|
oapp_client.pay_native_fee(&payer, &payment_amount);
|
|
294
485
|
}
|
|
486
|
+
|
|
487
|
+
#[test]
|
|
488
|
+
fn test_pay_zro_success() {
|
|
489
|
+
let TestSetup { env, oapp_client, endpoint, zro_token, zro_token_admin_client, token_admin, .. } = setup();
|
|
490
|
+
|
|
491
|
+
let payer = Address::generate(&env);
|
|
492
|
+
let payment_amount = 500i128;
|
|
493
|
+
mint_to(&env, &token_admin, &zro_token, &zro_token_admin_client, &payer, payment_amount);
|
|
494
|
+
|
|
495
|
+
env.mock_auths(&[MockAuth {
|
|
496
|
+
address: &payer,
|
|
497
|
+
invoke: &MockAuthInvoke {
|
|
498
|
+
contract: &oapp_client.address,
|
|
499
|
+
fn_name: "pay_zro_fee",
|
|
500
|
+
args: (&payer, &payment_amount).into_val(&env),
|
|
501
|
+
sub_invokes: &[MockAuthInvoke {
|
|
502
|
+
contract: &zro_token,
|
|
503
|
+
fn_name: "transfer",
|
|
504
|
+
args: (&payer, &endpoint, &payment_amount).into_val(&env),
|
|
505
|
+
sub_invokes: &[],
|
|
506
|
+
}],
|
|
507
|
+
},
|
|
508
|
+
}]);
|
|
509
|
+
oapp_client.pay_zro_fee(&payer, &payment_amount);
|
|
510
|
+
|
|
511
|
+
assert_eq!(zro_token_admin_client.balance(&payer), 0);
|
|
512
|
+
assert_eq!(zro_token_admin_client.balance(&endpoint), payment_amount);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
#[test]
|
|
516
|
+
#[should_panic(expected = "balance is not sufficient to spend")]
|
|
517
|
+
fn test_pay_zro_insufficient_balance() {
|
|
518
|
+
let TestSetup { env, oapp_client, endpoint, zro_token, zro_token_admin_client, token_admin, .. } = setup();
|
|
519
|
+
|
|
520
|
+
let payer = Address::generate(&env);
|
|
521
|
+
let balance = 100i128;
|
|
522
|
+
let payment_amount = 500i128;
|
|
523
|
+
|
|
524
|
+
// Fund with less than required
|
|
525
|
+
mint_to(&env, &token_admin, &zro_token, &zro_token_admin_client, &payer, balance);
|
|
526
|
+
|
|
527
|
+
env.mock_auths(&[MockAuth {
|
|
528
|
+
address: &payer,
|
|
529
|
+
invoke: &MockAuthInvoke {
|
|
530
|
+
contract: &oapp_client.address,
|
|
531
|
+
fn_name: "pay_zro_fee",
|
|
532
|
+
args: (&payer, &payment_amount).into_val(&env),
|
|
533
|
+
sub_invokes: &[MockAuthInvoke {
|
|
534
|
+
contract: &zro_token,
|
|
535
|
+
fn_name: "transfer",
|
|
536
|
+
args: (&payer, &endpoint, &payment_amount).into_val(&env),
|
|
537
|
+
sub_invokes: &[],
|
|
538
|
+
}],
|
|
539
|
+
},
|
|
540
|
+
}]);
|
|
541
|
+
oapp_client.pay_zro_fee(&payer, &payment_amount);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
#[test]
|
|
545
|
+
fn test_pay_zro_unavailable_returns_error() {
|
|
546
|
+
let TestSetup { env, oapp_client, endpoint, zro_token, .. } = setup();
|
|
547
|
+
|
|
548
|
+
let endpoint_client = MockEndpointClient::new(&env, &endpoint);
|
|
549
|
+
endpoint_client.set_zro(&None);
|
|
550
|
+
|
|
551
|
+
let payer = Address::generate(&env);
|
|
552
|
+
let payment_amount = 500i128;
|
|
553
|
+
|
|
554
|
+
env.mock_auths(&[MockAuth {
|
|
555
|
+
address: &payer,
|
|
556
|
+
invoke: &MockAuthInvoke {
|
|
557
|
+
contract: &oapp_client.address,
|
|
558
|
+
fn_name: "pay_zro_fee",
|
|
559
|
+
args: (&payer, &payment_amount).into_val(&env),
|
|
560
|
+
sub_invokes: &[],
|
|
561
|
+
},
|
|
562
|
+
}]);
|
|
563
|
+
let result = oapp_client.try_pay_zro_fee(&payer, &payment_amount);
|
|
564
|
+
assert_eq!(result.err().unwrap().ok().unwrap(), OAppError::ZroTokenUnavailable.into());
|
|
565
|
+
|
|
566
|
+
// Ensure we did not transfer any ZRO accidentally
|
|
567
|
+
let token_client = TokenClient::new(&env, &zro_token);
|
|
568
|
+
assert_eq!(token_client.balance(&payer), 0);
|
|
569
|
+
}
|
|
@@ -6,6 +6,10 @@ use utils::{option_ext::OptionExt, ownable::Ownable};
|
|
|
6
6
|
/// Used as denominator in fee calculations
|
|
7
7
|
const BASE_FEE_BPS: u64 = 10_000;
|
|
8
8
|
|
|
9
|
+
// =========================================================================
|
|
10
|
+
// Storage
|
|
11
|
+
// =========================================================================
|
|
12
|
+
|
|
9
13
|
#[storage]
|
|
10
14
|
pub enum OFTFeeStorage {
|
|
11
15
|
#[instance(u64)]
|
|
@@ -19,14 +23,22 @@ pub enum OFTFeeStorage {
|
|
|
19
23
|
FeeDepositAddress,
|
|
20
24
|
}
|
|
21
25
|
|
|
26
|
+
// =========================================================================
|
|
27
|
+
// Errors
|
|
28
|
+
// =========================================================================
|
|
29
|
+
|
|
22
30
|
#[contract_error]
|
|
23
31
|
pub enum OFTFeeError {
|
|
24
|
-
InvalidFeeBps =
|
|
32
|
+
InvalidFeeBps = 3100,
|
|
25
33
|
InvalidFeeDepositAddress,
|
|
26
34
|
NotFound,
|
|
27
35
|
SameValue,
|
|
28
36
|
}
|
|
29
37
|
|
|
38
|
+
// =========================================================================
|
|
39
|
+
// Events
|
|
40
|
+
// =========================================================================
|
|
41
|
+
|
|
30
42
|
#[contractevent]
|
|
31
43
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
32
44
|
pub struct DefaultFeeBpsSet {
|
|
@@ -52,8 +64,12 @@ pub struct FeeDepositAddressSet {
|
|
|
52
64
|
pub fee_deposit_address: Address,
|
|
53
65
|
}
|
|
54
66
|
|
|
67
|
+
// =========================================================================
|
|
68
|
+
// Trait With Default Implementations
|
|
69
|
+
// =========================================================================
|
|
70
|
+
|
|
55
71
|
#[contract_trait]
|
|
56
|
-
pub trait OFTFee: OFTFeeInternal + Ownable
|
|
72
|
+
pub trait OFTFee: OFTFeeInternal + Ownable {
|
|
57
73
|
#[only_auth]
|
|
58
74
|
fn set_default_fee_bps(env: &Env, default_fee_bps: u64) {
|
|
59
75
|
assert_with_error!(env, default_fee_bps <= BASE_FEE_BPS, OFTFeeError::InvalidFeeBps);
|
|
@@ -2,6 +2,10 @@ use common_macros::{contract_error, contract_trait, only_auth, storage};
|
|
|
2
2
|
use soroban_sdk::{assert_with_error, contractevent, Env};
|
|
3
3
|
use utils::ownable::Ownable;
|
|
4
4
|
|
|
5
|
+
// =========================================================================
|
|
6
|
+
// Storage
|
|
7
|
+
// =========================================================================
|
|
8
|
+
|
|
5
9
|
#[storage]
|
|
6
10
|
pub enum OFTPausableStorage {
|
|
7
11
|
#[instance(bool)]
|
|
@@ -9,24 +13,35 @@ pub enum OFTPausableStorage {
|
|
|
9
13
|
Paused,
|
|
10
14
|
}
|
|
11
15
|
|
|
16
|
+
// =========================================================================
|
|
17
|
+
// Errors
|
|
18
|
+
// =========================================================================
|
|
19
|
+
|
|
12
20
|
#[contract_error]
|
|
13
21
|
pub enum OFTPausableError {
|
|
14
|
-
Paused =
|
|
22
|
+
Paused = 3110,
|
|
15
23
|
PauseStatusUnchanged,
|
|
16
24
|
}
|
|
17
25
|
|
|
26
|
+
// =========================================================================
|
|
27
|
+
// Events
|
|
28
|
+
// =========================================================================
|
|
29
|
+
|
|
18
30
|
#[contractevent]
|
|
19
31
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
20
32
|
pub struct PausedSet {
|
|
21
33
|
pub paused: bool,
|
|
22
34
|
}
|
|
23
35
|
|
|
36
|
+
// =========================================================================
|
|
37
|
+
// Trait With Default Implementations
|
|
38
|
+
// =========================================================================
|
|
39
|
+
|
|
24
40
|
#[contract_trait]
|
|
25
|
-
pub trait OFTPausable: OFTPausableInternal + Ownable
|
|
41
|
+
pub trait OFTPausable: OFTPausableInternal + Ownable {
|
|
26
42
|
#[only_auth]
|
|
27
43
|
fn set_paused(env: &Env, paused: bool) {
|
|
28
|
-
|
|
29
|
-
assert_with_error!(env, current_paused != paused, OFTPausableError::PauseStatusUnchanged);
|
|
44
|
+
assert_with_error!(env, Self::is_paused(env) != paused, OFTPausableError::PauseStatusUnchanged);
|
|
30
45
|
OFTPausableStorage::set_paused(env, &paused);
|
|
31
46
|
PausedSet { paused }.publish(env);
|
|
32
47
|
}
|