@layerzerolabs/protocol-stellar-v2 0.2.33 → 0.2.35
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 +351 -367
- package/.turbo/turbo-lint.log +220 -223
- package/.turbo/turbo-test.log +1993 -1796
- package/Cargo.lock +10 -10
- package/Cargo.toml +1 -1
- package/contracts/common-macros/src/storage.rs +7 -5
- package/contracts/common-macros/src/tests/storage/snapshots/common_macros__tests__storage__generate_storage__snapshot_generated_storage_code.snap +3 -3
- package/contracts/endpoint-v2/src/endpoint_v2.rs +5 -4
- package/contracts/endpoint-v2/src/interfaces/messaging_channel.rs +7 -8
- package/contracts/endpoint-v2/src/messaging_channel.rs +78 -45
- package/contracts/endpoint-v2/src/storage.rs +8 -3
- package/contracts/endpoint-v2/src/tests/endpoint_setup.rs +2 -2
- package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +12 -15
- package/contracts/endpoint-v2/src/tests/endpoint_v2/verifiable.rs +46 -9
- package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +7 -23
- package/contracts/endpoint-v2/src/tests/messaging_channel/clear_payload.rs +23 -20
- package/contracts/endpoint-v2/src/tests/messaging_channel/inbound.rs +94 -1
- package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_nonce.rs +17 -15
- package/contracts/endpoint-v2/src/tests/messaging_channel/mod.rs +1 -1
- package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +48 -13
- package/contracts/endpoint-v2/src/tests/messaging_channel/pending_inbound_nonces.rs +111 -0
- package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +15 -25
- package/contracts/layerzero-views/src/layerzero_view.rs +2 -2
- package/contracts/layerzero-views/src/tests/layerzero_view_tests.rs +3 -4
- package/contracts/layerzero-views/src/tests/setup.rs +0 -21
- package/contracts/message-libs/blocked-message-lib/src/lib.rs +4 -4
- package/contracts/message-libs/uln-302/src/send_uln.rs +5 -5
- package/contracts/oapps/counter/src/counter.rs +6 -0
- package/contracts/oapps/oapp/src/oapp_sender.rs +3 -2
- package/contracts/oapps/oft/integration-tests/extensions/test_oft_fee.rs +5 -11
- package/contracts/oapps/oft/integration-tests/extensions/test_pausable.rs +7 -14
- package/contracts/oapps/oft/integration-tests/extensions/test_rate_limiter.rs +11 -22
- package/contracts/oapps/oft/integration-tests/setup.rs +59 -7
- package/contracts/oapps/oft/integration-tests/utils.rs +28 -2
- package/contracts/oapps/oft/src/extensions/oft_fee.rs +5 -0
- package/contracts/oapps/oft/src/interfaces/mintable.rs +14 -0
- package/contracts/oapps/oft/src/interfaces/mod.rs +2 -2
- package/contracts/oapps/oft/src/oft.rs +8 -7
- package/contracts/oapps/oft/src/oft_types/mint_burn.rs +8 -8
- package/contracts/oapps/oft/src/oft_types/mod.rs +3 -4
- package/contracts/oapps/oft/src/tests/extensions/rate_limiter.rs +7 -5
- package/contracts/oapps/sac-manager/src/errors.rs +14 -0
- package/contracts/{sac-manager → oapps/sac-manager}/src/lib.rs +0 -4
- package/contracts/oapps/sac-manager/src/sac_manager.rs +115 -0
- package/contracts/oapps/sac-manager/src/storage.rs +20 -0
- package/contracts/{sac-manager → oapps/sac-manager}/src/tests/mod.rs +0 -4
- package/contracts/oapps/sac-manager/src/tests/sac_manager/clawback.rs +86 -0
- package/contracts/oapps/sac-manager/src/tests/sac_manager/mint.rs +58 -0
- package/contracts/{sac-manager → oapps/sac-manager}/src/tests/sac_manager/mod.rs +1 -3
- package/contracts/oapps/sac-manager/src/tests/sac_manager/set_minter.rs +69 -0
- package/contracts/oapps/sac-manager/src/tests/sac_manager/test_helper.rs +18 -0
- package/contracts/oapps/sac-manager/src/tests/sac_manager/view_functions.rs +28 -0
- package/contracts/{sac-manager → oapps/sac-manager}/src/tests/test_helper.rs +16 -59
- package/docs/layerzero-v2-on-stellar.md +46 -2
- package/package.json +8 -3
- package/sdk/.turbo/turbo-test.log +424 -429
- package/sdk/dist/generated/bml.d.ts +3 -3
- package/sdk/dist/generated/bml.js +3 -3
- package/sdk/dist/generated/counter.d.ts +32 -3
- package/sdk/dist/generated/counter.js +6 -3
- package/sdk/dist/generated/dvn.d.ts +3 -3
- package/sdk/dist/generated/dvn.js +3 -3
- package/sdk/dist/generated/dvn_fee_lib.d.ts +2 -2
- package/sdk/dist/generated/dvn_fee_lib.js +2 -2
- package/sdk/dist/generated/endpoint.d.ts +12 -13
- package/sdk/dist/generated/endpoint.js +7 -7
- package/sdk/dist/generated/executor.d.ts +3 -3
- package/sdk/dist/generated/executor.js +3 -3
- package/sdk/dist/generated/executor_fee_lib.d.ts +2 -2
- package/sdk/dist/generated/executor_fee_lib.js +2 -2
- package/sdk/dist/generated/executor_helper.d.ts +2 -2
- package/sdk/dist/generated/executor_helper.js +2 -2
- package/sdk/dist/generated/layerzero_view.d.ts +3 -3
- package/sdk/dist/generated/layerzero_view.js +3 -3
- package/sdk/dist/generated/oft.d.ts +32 -3
- package/sdk/dist/generated/oft.js +7 -4
- package/sdk/dist/generated/price_feed.d.ts +3 -3
- package/sdk/dist/generated/price_feed.js +3 -3
- package/sdk/dist/generated/sac_manager.d.ts +47 -318
- package/sdk/dist/generated/sac_manager.js +24 -129
- package/sdk/dist/generated/sml.d.ts +2 -2
- package/sdk/dist/generated/sml.js +2 -2
- package/sdk/dist/generated/treasury.d.ts +2 -2
- package/sdk/dist/generated/treasury.js +2 -2
- package/sdk/dist/generated/uln302.d.ts +3 -3
- package/sdk/dist/generated/uln302.js +3 -3
- package/sdk/dist/generated/upgrader.d.ts +2 -2
- package/sdk/dist/generated/upgrader.js +2 -2
- package/sdk/package.json +6 -1
- package/sdk/test/oft-sml.test.ts +72 -36
- package/sdk/test/sac-manager-redistribution.test.ts +38 -182
- package/contracts/endpoint-v2/src/tests/messaging_channel/lazy_inbound_nonce.rs +0 -39
- package/contracts/oapps/oft/src/interfaces/mint_burnable.rs +0 -18
- package/contracts/sac-manager/src/errors.rs +0 -18
- package/contracts/sac-manager/src/extensions/mod.rs +0 -6
- package/contracts/sac-manager/src/extensions/redistribution.rs +0 -109
- package/contracts/sac-manager/src/extensions/supply_control/mod.rs +0 -488
- package/contracts/sac-manager/src/extensions/supply_control/rate_limit.rs +0 -126
- package/contracts/sac-manager/src/interfaces/mod.rs +0 -3
- package/contracts/sac-manager/src/interfaces/sac_manager.rs +0 -52
- package/contracts/sac-manager/src/sac_manager.rs +0 -193
- package/contracts/sac-manager/src/storage.rs +0 -20
- package/contracts/sac-manager/src/tests/redistribution/mod.rs +0 -1
- package/contracts/sac-manager/src/tests/redistribution/redistribute_funds.rs +0 -82
- package/contracts/sac-manager/src/tests/sac_manager/admin_mint.rs +0 -206
- package/contracts/sac-manager/src/tests/sac_manager/burn.rs +0 -215
- package/contracts/sac-manager/src/tests/sac_manager/clawback.rs +0 -209
- package/contracts/sac-manager/src/tests/sac_manager/mint.rs +0 -252
- package/contracts/sac-manager/src/tests/sac_manager/set_oft_address.rs +0 -47
- package/contracts/sac-manager/src/tests/sac_manager/test_helper.rs +0 -75
- package/contracts/sac-manager/src/tests/sac_manager/view_functions.rs +0 -60
- package/contracts/sac-manager/src/tests/supply_control/enumerable_set.rs +0 -256
- package/contracts/sac-manager/src/tests/supply_control/mod.rs +0 -8
- package/contracts/sac-manager/src/tests/supply_control/refill.rs +0 -90
- package/contracts/sac-manager/src/tests/supply_control/set_mint_whitelist.rs +0 -245
- package/contracts/sac-manager/src/tests/supply_control/set_supply_controller.rs +0 -267
- package/contracts/sac-manager/src/tests/supply_control/set_supply_controller_manager.rs +0 -122
- package/contracts/sac-manager/src/tests/supply_control/test_helper.rs +0 -38
- package/contracts/sac-manager/src/tests/supply_control/update_allow_any_mint_burn.rs +0 -114
- package/contracts/sac-manager/src/tests/supply_control/update_limit_config.rs +0 -257
- /package/contracts/{sac-manager → oapps/sac-manager}/Cargo.toml +0 -0
- /package/contracts/{sac-manager → oapps/sac-manager}/src/tests/sac_manager/set_admin.rs +0 -0
- /package/contracts/{sac-manager → oapps/sac-manager}/src/tests/sac_manager/set_authorized.rs +0 -0
|
@@ -53,7 +53,7 @@ fn test_skip_requires_auth_even_when_caller_is_receiver() {
|
|
|
53
53
|
endpoint_client.skip(&receiver, &receiver, &src_eid, &sender, &nonce);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
// Successful skip updates inbound
|
|
56
|
+
// Successful skip updates inbound nonce and emits InboundNonceSkipped
|
|
57
57
|
#[test]
|
|
58
58
|
fn test_skip_success() {
|
|
59
59
|
let context = setup();
|
|
@@ -65,13 +65,10 @@ fn test_skip_success() {
|
|
|
65
65
|
let sender = BytesN::from_array(env, &[1u8; 32]);
|
|
66
66
|
let nonce = 1;
|
|
67
67
|
|
|
68
|
-
// Verify initial state: lazy inbound nonce should be 0.
|
|
69
|
-
let initial_lazy_nonce = endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender);
|
|
70
|
-
assert_eq!(initial_lazy_nonce, 0, "Initial lazy inbound nonce should be 0");
|
|
71
|
-
|
|
72
68
|
// Initially, inbound nonce should be 0.
|
|
73
69
|
let initial_nonce = endpoint_client.inbound_nonce(&receiver, &src_eid, &sender);
|
|
74
70
|
assert_eq!(initial_nonce, 0);
|
|
71
|
+
assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
|
|
75
72
|
|
|
76
73
|
// Skip nonce 1 (expected nonce is initial_nonce + 1 = 1).
|
|
77
74
|
skip_with_auth(&context, &receiver, &receiver, src_eid, &sender, nonce);
|
|
@@ -86,10 +83,7 @@ fn test_skip_success() {
|
|
|
86
83
|
// Verify inbound nonce reflects the skip via public interface.
|
|
87
84
|
let updated_nonce = endpoint_client.inbound_nonce(&receiver, &src_eid, &sender);
|
|
88
85
|
assert_eq!(updated_nonce, nonce);
|
|
89
|
-
|
|
90
|
-
// Verify lazy inbound nonce was updated.
|
|
91
|
-
let lazy_nonce = endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender);
|
|
92
|
-
assert_eq!(lazy_nonce, nonce);
|
|
86
|
+
assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
|
|
93
87
|
}
|
|
94
88
|
|
|
95
89
|
// Multiple sequential skips update to the latest nonce
|
|
@@ -111,13 +105,10 @@ fn test_skip_multiple_nonces() {
|
|
|
111
105
|
let nonce2 = 2;
|
|
112
106
|
skip_with_auth(&context, &receiver, &receiver, src_eid, &sender, nonce2);
|
|
113
107
|
|
|
114
|
-
// Verify lazy inbound nonce was updated to nonce2.
|
|
115
|
-
let lazy_nonce = endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender);
|
|
116
|
-
assert_eq!(lazy_nonce, nonce2);
|
|
117
|
-
|
|
118
108
|
// Verify inbound nonce reflects the latest skip.
|
|
119
109
|
let updated_nonce = endpoint_client.inbound_nonce(&receiver, &src_eid, &sender);
|
|
120
110
|
assert_eq!(updated_nonce, nonce2);
|
|
111
|
+
assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
|
|
121
112
|
}
|
|
122
113
|
|
|
123
114
|
// Delegate authorization (delegate(receiver) is allowed)
|
|
@@ -146,9 +137,8 @@ fn test_skip_with_delegate() {
|
|
|
146
137
|
InboundNonceSkipped { src_eid, sender: sender.clone(), receiver: receiver.clone(), nonce },
|
|
147
138
|
);
|
|
148
139
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
assert_eq!(lazy_nonce, nonce);
|
|
140
|
+
assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), nonce);
|
|
141
|
+
assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
|
|
152
142
|
}
|
|
153
143
|
|
|
154
144
|
// Path isolation (receiver/src_eid/sender are isolated)
|
|
@@ -176,11 +166,11 @@ fn test_skip_different_paths() {
|
|
|
176
166
|
// Skip for different senders.
|
|
177
167
|
skip_with_auth(&context, &receiver1, &receiver1, src_eid1, &sender2, nonce);
|
|
178
168
|
|
|
179
|
-
// Verify all paths have independent
|
|
180
|
-
assert_eq!(endpoint_client.
|
|
181
|
-
assert_eq!(endpoint_client.
|
|
182
|
-
assert_eq!(endpoint_client.
|
|
183
|
-
assert_eq!(endpoint_client.
|
|
169
|
+
// Verify all paths have independent inbound nonces.
|
|
170
|
+
assert_eq!(endpoint_client.inbound_nonce(&receiver1, &src_eid1, &sender1), nonce);
|
|
171
|
+
assert_eq!(endpoint_client.inbound_nonce(&receiver2, &src_eid1, &sender1), nonce);
|
|
172
|
+
assert_eq!(endpoint_client.inbound_nonce(&receiver1, &src_eid2, &sender1), nonce);
|
|
173
|
+
assert_eq!(endpoint_client.inbound_nonce(&receiver1, &src_eid1, &sender2), nonce);
|
|
184
174
|
}
|
|
185
175
|
|
|
186
176
|
// Invalid nonce rejection (must match expected nonce)
|
|
@@ -224,10 +214,10 @@ fn test_skip_next_nonce_accounts_for_verified_payload_hashes() {
|
|
|
224
214
|
let result = endpoint_client.try_skip(&receiver, &receiver, &src_eid, &sender, &1);
|
|
225
215
|
assert_eq!(result.err().unwrap().ok().unwrap(), EndpointError::InvalidNonce.into());
|
|
226
216
|
|
|
227
|
-
// Skipping 2 should succeed and advance
|
|
217
|
+
// Skipping 2 should succeed and advance inbound nonce to 2.
|
|
228
218
|
skip_with_auth(&context, &receiver, &receiver, src_eid, &sender, 2);
|
|
229
|
-
assert_eq!(endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender), 2);
|
|
230
219
|
assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 2);
|
|
220
|
+
assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
|
|
231
221
|
|
|
232
222
|
// skip() does not clear any existing payload hashes.
|
|
233
223
|
assert_eq!(endpoint_client.inbound_payload_hash(&receiver, &src_eid, &sender, &1), Some(payload_hash_1));
|
|
@@ -251,8 +241,8 @@ fn test_skip_closes_gap_and_advances_inbound_nonce() {
|
|
|
251
241
|
|
|
252
242
|
// Skip nonce 1 to close the gap. This should allow inbound_nonce to advance to 2.
|
|
253
243
|
skip_with_auth(&context, &receiver, &receiver, src_eid, &sender, 1);
|
|
254
|
-
assert_eq!(endpoint_client.lazy_inbound_nonce(&receiver, &src_eid, &sender), 1);
|
|
255
244
|
assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 2);
|
|
245
|
+
assert!(endpoint_client.pending_inbound_nonces(&receiver, &src_eid, &sender).is_empty());
|
|
256
246
|
|
|
257
247
|
// Payload hash at nonce 2 remains intact.
|
|
258
248
|
assert_eq!(endpoint_client.inbound_payload_hash(&receiver, &src_eid, &sender, &2), Some(payload_hash_2));
|
|
@@ -271,7 +261,7 @@ fn test_skip_rejects_repeated_same_nonce() {
|
|
|
271
261
|
|
|
272
262
|
// Skip nonce 1 successfully.
|
|
273
263
|
skip_with_auth(&context, &receiver, &receiver, src_eid, &sender, 1);
|
|
274
|
-
assert_eq!(endpoint_client.
|
|
264
|
+
assert_eq!(endpoint_client.inbound_nonce(&receiver, &src_eid, &sender), 1);
|
|
275
265
|
|
|
276
266
|
// Skipping nonce 1 again should fail since the next expected nonce is now 2.
|
|
277
267
|
context.mock_auth(&receiver, "skip", (&receiver, &receiver, &src_eid, &sender, &1u64));
|
|
@@ -104,9 +104,9 @@ impl LayerZeroView {
|
|
|
104
104
|
let empty_hash = empty_payload_hash(env);
|
|
105
105
|
let nil_hash = nil_payload_hash(env);
|
|
106
106
|
|
|
107
|
-
// Executed: payload hash has been cleared (None) and nonce <=
|
|
107
|
+
// Executed: payload hash has been cleared (None) and nonce <= inbound_nonce
|
|
108
108
|
if payload_hash.is_none()
|
|
109
|
-
&& origin.nonce <= messaging_channel.
|
|
109
|
+
&& origin.nonce <= messaging_channel.inbound_nonce(receiver, &origin.src_eid, &origin.sender)
|
|
110
110
|
{
|
|
111
111
|
return ExecutionState::Executed;
|
|
112
112
|
}
|
|
@@ -206,9 +206,9 @@ fn test_executable_state_executed() {
|
|
|
206
206
|
let receiver = test_setup.register_oapp();
|
|
207
207
|
let sender = soroban_sdk::Address::generate(&test_setup.env);
|
|
208
208
|
|
|
209
|
-
// Clear payload hash (None) and set
|
|
209
|
+
// Clear payload hash (None) and set inbound_nonce >= nonce = Executed
|
|
210
210
|
test_setup.set_payload_hash(&receiver, REMOTE_EID, &sender, 1, &None);
|
|
211
|
-
test_setup.
|
|
211
|
+
test_setup.set_inbound_nonce(&receiver, REMOTE_EID, &sender, 1);
|
|
212
212
|
|
|
213
213
|
let origin = Origin { src_eid: REMOTE_EID, sender: address_to_bytes32(&sender), nonce: 1 };
|
|
214
214
|
|
|
@@ -262,9 +262,8 @@ fn test_executable_multiple_nonces_in_sequence() {
|
|
|
262
262
|
assert_eq!(test_setup.view_client.executable(&origin_2, &receiver), ExecutionState::VerifiedButNotExecutable);
|
|
263
263
|
assert_eq!(test_setup.view_client.executable(&origin_3, &receiver), ExecutionState::VerifiedButNotExecutable);
|
|
264
264
|
|
|
265
|
-
// Now execute nonce 1 (
|
|
265
|
+
// Now execute nonce 1 (clear payload hash, advance inbound_nonce)
|
|
266
266
|
test_setup.set_payload_hash(&receiver, REMOTE_EID, &sender, 1, &None);
|
|
267
|
-
test_setup.set_lazy_inbound_nonce(&receiver, REMOTE_EID, &sender, 1);
|
|
268
267
|
test_setup.set_inbound_nonce(&receiver, REMOTE_EID, &sender, 2);
|
|
269
268
|
|
|
270
269
|
assert_eq!(test_setup.view_client.executable(&origin_1, &receiver), ExecutionState::Executed);
|
|
@@ -30,7 +30,6 @@ mod endpoint_storage {
|
|
|
30
30
|
Initializable(Address, u32, BytesN<32>),
|
|
31
31
|
Verifiable(Address, u32, BytesN<32>),
|
|
32
32
|
// State for executable tests
|
|
33
|
-
LazyInboundNonce(Address, u32, BytesN<32>),
|
|
34
33
|
InboundNonce(Address, u32, BytesN<32>),
|
|
35
34
|
InboundPayloadHash(Address, u32, BytesN<32>, u64),
|
|
36
35
|
ReceiveLibrary(Address, u32),
|
|
@@ -91,13 +90,6 @@ impl MockEndpoint {
|
|
|
91
90
|
.set(&endpoint_storage::MockEndpointStorage::Verifiable(receiver.clone(), *src_eid, sender.clone()), value);
|
|
92
91
|
}
|
|
93
92
|
|
|
94
|
-
pub fn set_lazy_inbound_nonce(env: &Env, receiver: &Address, src_eid: &u32, sender: &BytesN<32>, nonce: &u64) {
|
|
95
|
-
env.storage().persistent().set(
|
|
96
|
-
&endpoint_storage::MockEndpointStorage::LazyInboundNonce(receiver.clone(), *src_eid, sender.clone()),
|
|
97
|
-
nonce,
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
93
|
pub fn set_inbound_nonce(env: &Env, receiver: &Address, src_eid: &u32, sender: &BytesN<32>, nonce: &u64) {
|
|
102
94
|
env.storage().persistent().set(
|
|
103
95
|
&endpoint_storage::MockEndpointStorage::InboundNonce(receiver.clone(), *src_eid, sender.clone()),
|
|
@@ -135,13 +127,6 @@ impl MockEndpoint {
|
|
|
135
127
|
// Getters required by LayerZeroView
|
|
136
128
|
// =========================================================================
|
|
137
129
|
|
|
138
|
-
pub fn lazy_inbound_nonce(env: &Env, receiver: &Address, src_eid: &u32, sender: &BytesN<32>) -> u64 {
|
|
139
|
-
env.storage()
|
|
140
|
-
.persistent()
|
|
141
|
-
.get(&endpoint_storage::MockEndpointStorage::LazyInboundNonce(receiver.clone(), *src_eid, sender.clone()))
|
|
142
|
-
.unwrap_or(0)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
130
|
pub fn inbound_nonce(env: &Env, receiver: &Address, src_eid: &u32, sender: &BytesN<32>) -> u64 {
|
|
146
131
|
env.storage()
|
|
147
132
|
.persistent()
|
|
@@ -282,12 +267,6 @@ impl<'a> TestSetup<'a> {
|
|
|
282
267
|
self.endpoint_client.set_verifiable(receiver, &src_eid, &sender_bytes32, &value);
|
|
283
268
|
}
|
|
284
269
|
|
|
285
|
-
/// Set lazy inbound nonce (marks messages up to this nonce as processed).
|
|
286
|
-
pub fn set_lazy_inbound_nonce(&self, receiver: &Address, src_eid: u32, sender: &Address, nonce: u64) {
|
|
287
|
-
let sender_bytes32 = address_to_bytes32(sender);
|
|
288
|
-
self.endpoint_client.set_lazy_inbound_nonce(receiver, &src_eid, &sender_bytes32, &nonce);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
270
|
/// Set inbound nonce (marks messages up to this nonce as verified and executable).
|
|
292
271
|
pub fn set_inbound_nonce(&self, receiver: &Address, src_eid: u32, sender: &Address, nonce: u64) {
|
|
293
272
|
let sender_bytes32 = address_to_bytes32(sender);
|
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
#[cfg(test)]
|
|
16
16
|
mod tests;
|
|
17
17
|
|
|
18
|
-
use common_macros::
|
|
18
|
+
use common_macros::contract_error;
|
|
19
19
|
use endpoint_v2::{
|
|
20
20
|
FeesAndPacket, IMessageLib, ISendLib, MessageLibType, MessageLibVersion, MessagingFee, OutboundPacket,
|
|
21
21
|
SetConfigParam,
|
|
22
22
|
};
|
|
23
|
-
use soroban_sdk::{contract, panic_with_error, Address, Bytes, Env, Vec};
|
|
23
|
+
use soroban_sdk::{contract, contractimpl, panic_with_error, Address, Bytes, Env, Vec};
|
|
24
24
|
|
|
25
25
|
#[contract_error]
|
|
26
26
|
pub enum BlockedMessageLibError {
|
|
@@ -31,7 +31,7 @@ pub enum BlockedMessageLibError {
|
|
|
31
31
|
#[contract]
|
|
32
32
|
pub struct BlockedMessageLib;
|
|
33
33
|
|
|
34
|
-
#[
|
|
34
|
+
#[contractimpl]
|
|
35
35
|
impl IMessageLib for BlockedMessageLib {
|
|
36
36
|
/// Always panics - config modification is not supported.
|
|
37
37
|
fn set_config(env: &Env, _oapp: &Address, _param: &Vec<SetConfigParam>) {
|
|
@@ -59,7 +59,7 @@ impl IMessageLib for BlockedMessageLib {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
#[
|
|
62
|
+
#[contractimpl]
|
|
63
63
|
impl ISendLib for BlockedMessageLib {
|
|
64
64
|
/// Always panics - quoting is blocked.
|
|
65
65
|
fn quote(env: &Env, _packet: &OutboundPacket, _options: &Bytes, _pay_in_zro: bool) -> MessagingFee {
|
|
@@ -45,7 +45,7 @@ impl ISendLib for Uln302 {
|
|
|
45
45
|
|
|
46
46
|
// Treasury fee
|
|
47
47
|
let workers_fee = executor_fee + dvns_fee;
|
|
48
|
-
let (_, treasury_fee) = Self::quote_treasury(env, &packet.sender, packet.dst_eid,
|
|
48
|
+
let (_, treasury_fee) = Self::quote_treasury(env, &packet.sender, packet.dst_eid, workers_fee, pay_in_zro);
|
|
49
49
|
|
|
50
50
|
if pay_in_zro {
|
|
51
51
|
MessagingFee { native_fee: workers_fee, zro_fee: treasury_fee }
|
|
@@ -91,7 +91,7 @@ impl ISendLib for Uln302 {
|
|
|
91
91
|
// Treasury fee
|
|
92
92
|
let total_worker_fee = native_fee_recipients.iter().map(|fee| fee.amount).sum();
|
|
93
93
|
let (treasury_addr, treasury_fee) =
|
|
94
|
-
Self::quote_treasury(env, &packet.sender, packet.dst_eid,
|
|
94
|
+
Self::quote_treasury(env, &packet.sender, packet.dst_eid, total_worker_fee, pay_in_zro);
|
|
95
95
|
|
|
96
96
|
// Handle ZRO fee recipients
|
|
97
97
|
let mut zro_fee_recipients = vec![env];
|
|
@@ -280,12 +280,12 @@ impl Uln302 {
|
|
|
280
280
|
env: &Env,
|
|
281
281
|
sender: &Address,
|
|
282
282
|
dst_eid: u32,
|
|
283
|
-
workers_fee:
|
|
284
|
-
pay_in_zro:
|
|
283
|
+
workers_fee: i128,
|
|
284
|
+
pay_in_zro: bool,
|
|
285
285
|
) -> (Address, i128) {
|
|
286
286
|
let treasury_addr = Self::treasury(env);
|
|
287
287
|
let treasury_fee =
|
|
288
|
-
LayerZeroTreasuryClient::new(env, &treasury_addr).get_fee(sender, &dst_eid, workers_fee, pay_in_zro);
|
|
288
|
+
LayerZeroTreasuryClient::new(env, &treasury_addr).get_fee(sender, &dst_eid, &workers_fee, &pay_in_zro);
|
|
289
289
|
assert_with_error!(env, treasury_fee >= 0, Uln302Error::InvalidFee);
|
|
290
290
|
(treasury_addr, treasury_fee)
|
|
291
291
|
}
|
|
@@ -67,6 +67,12 @@ impl Counter {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
#[only_auth]
|
|
71
|
+
pub fn withdraw(env: &Env, to: &Address, amount: i128) {
|
|
72
|
+
let native_token = LayerZeroEndpointV2Client::new(env, &Self::endpoint(env)).native_token();
|
|
73
|
+
TokenClient::new(env, &native_token).transfer(&env.current_contract_address(), to, &amount);
|
|
74
|
+
}
|
|
75
|
+
|
|
70
76
|
// ============================================================================================
|
|
71
77
|
// View functions
|
|
72
78
|
// ============================================================================================
|
|
@@ -3,7 +3,7 @@ use crate::{
|
|
|
3
3
|
oapp_core::{endpoint_client, get_peer_or_panic, OAppCore},
|
|
4
4
|
};
|
|
5
5
|
use endpoint_v2::{MessagingFee, MessagingParams, MessagingReceipt};
|
|
6
|
-
use soroban_sdk::{token::TokenClient, Address, Bytes, Env};
|
|
6
|
+
use soroban_sdk::{contracttype, token::TokenClient, Address, Bytes, Env};
|
|
7
7
|
use utils::option_ext::OptionExt;
|
|
8
8
|
|
|
9
9
|
/// The version of the OAppSender implementation.
|
|
@@ -22,7 +22,8 @@ pub const SENDER_VERSION: u64 = 1;
|
|
|
22
22
|
/// - `Verified` — Caller asserts that `require_auth()` has already been called.
|
|
23
23
|
/// Use this to avoid a duplicate `require_auth()` node in the Soroban auth tree
|
|
24
24
|
/// (e.g., when the same address was already authorized as the message sender).
|
|
25
|
-
#[
|
|
25
|
+
#[contracttype]
|
|
26
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
26
27
|
pub enum FeePayer {
|
|
27
28
|
/// The fee payer has **not** been authorized yet.
|
|
28
29
|
/// `__lz_send` will call `fee_payer.require_auth()` before transferring fees.
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
use crate::integration_tests::{
|
|
9
9
|
setup::{create_recipient_address, decode_packet, setup, wire_endpoint, wire_oft, TestSetup},
|
|
10
10
|
utils::{
|
|
11
|
-
address_to_peer_bytes32, create_send_param, lz_receive, mint_to, quote_oft, quote_send,
|
|
11
|
+
address_to_peer_bytes32, create_send_param, lz_receive, mint_oft_token_to, mint_to, quote_oft, quote_send,
|
|
12
12
|
scan_packet_sent_event, send, send_with_fee, set_default_fee_bps, set_fee_bps, set_fee_deposit_address,
|
|
13
|
-
token_balance,
|
|
13
|
+
token_balance, validate_packet,
|
|
14
14
|
},
|
|
15
15
|
};
|
|
16
16
|
use soroban_sdk::{testutils::Address as _, token::TokenClient, Address};
|
|
@@ -26,10 +26,8 @@ fn test_cross_chain_with_zero_fee() {
|
|
|
26
26
|
let receiver = create_recipient_address(&env);
|
|
27
27
|
let executor = Address::generate(&env);
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
mint_oft_token_to(&env, &chain_a, &sender, 10_000_000);
|
|
30
30
|
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
31
|
-
transfer_sac_admin(&env, &chain_a.owner, &chain_a.oft_token, &chain_a.oft.address);
|
|
32
|
-
transfer_sac_admin(&env, &chain_b.owner, &chain_b.oft_token, &chain_b.oft.address);
|
|
33
31
|
|
|
34
32
|
let to = address_to_peer_bytes32(&receiver);
|
|
35
33
|
let send_param = create_send_param(&env, chain_b.eid, 1_000_000, 0, &to);
|
|
@@ -63,10 +61,8 @@ fn test_cross_chain_with_fee() {
|
|
|
63
61
|
let receiver = create_recipient_address(&env);
|
|
64
62
|
let executor = Address::generate(&env);
|
|
65
63
|
|
|
66
|
-
|
|
64
|
+
mint_oft_token_to(&env, &chain_a, &sender, 10_000_000);
|
|
67
65
|
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
68
|
-
transfer_sac_admin(&env, &chain_a.owner, &chain_a.oft_token, &chain_a.oft.address);
|
|
69
|
-
transfer_sac_admin(&env, &chain_b.owner, &chain_b.oft_token, &chain_b.oft.address);
|
|
70
66
|
|
|
71
67
|
// Enable 1% fee (100 bps)
|
|
72
68
|
set_fee_deposit_address(&env, &chain_a, &chain_a.fee_collector);
|
|
@@ -116,10 +112,8 @@ fn test_cross_chain_with_destination_specific_fee() {
|
|
|
116
112
|
let receiver = create_recipient_address(&env);
|
|
117
113
|
let executor = Address::generate(&env);
|
|
118
114
|
|
|
119
|
-
|
|
115
|
+
mint_oft_token_to(&env, &chain_a, &sender, 10_000_000);
|
|
120
116
|
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
121
|
-
transfer_sac_admin(&env, &chain_a.owner, &chain_a.oft_token, &chain_a.oft.address);
|
|
122
|
-
transfer_sac_admin(&env, &chain_b.owner, &chain_b.oft_token, &chain_b.oft.address);
|
|
123
117
|
|
|
124
118
|
// Set default fee 1% and destination-specific fee 2% for chain_b
|
|
125
119
|
set_fee_deposit_address(&env, &chain_a, &chain_a.fee_collector);
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
use crate::integration_tests::{
|
|
7
7
|
setup::{create_recipient_address, decode_packet, setup, wire_endpoint, wire_oft, TestSetup},
|
|
8
8
|
utils::{
|
|
9
|
-
address_to_peer_bytes32, create_send_param, is_paused, lz_receive, mint_to, quote_oft,
|
|
10
|
-
scan_packet_sent_event, send, set_paused,
|
|
9
|
+
address_to_peer_bytes32, create_send_param, is_paused, lz_receive, mint_oft_token_to, mint_to, quote_oft,
|
|
10
|
+
quote_send, scan_packet_sent_event, send, set_paused, try_lz_receive, try_send, validate_packet,
|
|
11
11
|
},
|
|
12
12
|
};
|
|
13
13
|
use soroban_sdk::{testutils::Address as _, token::TokenClient, Address};
|
|
@@ -22,11 +22,9 @@ fn test_send_succeeds_when_unpaused() {
|
|
|
22
22
|
let sender = Address::generate(&env);
|
|
23
23
|
let receiver = create_recipient_address(&env);
|
|
24
24
|
|
|
25
|
-
// Mint tokens
|
|
26
|
-
|
|
25
|
+
// Mint tokens (SAC admin is already the mock wrapper from setup)
|
|
26
|
+
mint_oft_token_to(&env, &chain_a, &sender, 10_000_000);
|
|
27
27
|
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
28
|
-
transfer_sac_admin(&env, &chain_a.owner, &chain_a.oft_token, &chain_a.oft.address);
|
|
29
|
-
transfer_sac_admin(&env, &chain_b.owner, &chain_b.oft_token, &chain_b.oft.address);
|
|
30
28
|
|
|
31
29
|
// Default state should be unpaused
|
|
32
30
|
assert!(!is_paused(&chain_a));
|
|
@@ -63,9 +61,8 @@ fn test_send_fails_when_paused() {
|
|
|
63
61
|
let sender = Address::generate(&env);
|
|
64
62
|
let receiver = create_recipient_address(&env);
|
|
65
63
|
|
|
66
|
-
|
|
64
|
+
mint_oft_token_to(&env, &chain_a, &sender, 10_000_000);
|
|
67
65
|
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
68
|
-
transfer_sac_admin(&env, &chain_a.owner, &chain_a.oft_token, &chain_a.oft.address);
|
|
69
66
|
|
|
70
67
|
let to = address_to_peer_bytes32(&receiver);
|
|
71
68
|
let send_param = create_send_param(&env, chain_b.eid, 1_000_000, 0, &to);
|
|
@@ -94,10 +91,8 @@ fn test_receive_fails_when_paused() {
|
|
|
94
91
|
let receiver = create_recipient_address(&env);
|
|
95
92
|
let executor = Address::generate(&env);
|
|
96
93
|
|
|
97
|
-
|
|
94
|
+
mint_oft_token_to(&env, &chain_a, &sender, 10_000_000);
|
|
98
95
|
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
99
|
-
transfer_sac_admin(&env, &chain_a.owner, &chain_a.oft_token, &chain_a.oft.address);
|
|
100
|
-
transfer_sac_admin(&env, &chain_b.owner, &chain_b.oft_token, &chain_b.oft.address);
|
|
101
96
|
|
|
102
97
|
// Send from chain_a to chain_b
|
|
103
98
|
let to = address_to_peer_bytes32(&receiver);
|
|
@@ -130,10 +125,8 @@ fn test_cross_chain_succeeds_after_unpause() {
|
|
|
130
125
|
let receiver = create_recipient_address(&env);
|
|
131
126
|
let executor = Address::generate(&env);
|
|
132
127
|
|
|
133
|
-
|
|
128
|
+
mint_oft_token_to(&env, &chain_a, &sender, 10_000_000);
|
|
134
129
|
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
135
|
-
transfer_sac_admin(&env, &chain_a.owner, &chain_a.oft_token, &chain_a.oft.address);
|
|
136
|
-
transfer_sac_admin(&env, &chain_b.owner, &chain_b.oft_token, &chain_b.oft.address);
|
|
137
130
|
|
|
138
131
|
// Pause and then unpause
|
|
139
132
|
set_paused(&env, &chain_a, true);
|
|
@@ -7,9 +7,9 @@ use crate::extensions::rate_limiter::{Direction, Mode};
|
|
|
7
7
|
use crate::integration_tests::{
|
|
8
8
|
setup::{create_recipient_address, decode_packet, setup, wire_endpoint, wire_oft, TestSetup},
|
|
9
9
|
utils::{
|
|
10
|
-
address_to_peer_bytes32, advance_time, create_send_param, lz_receive, mint_to, quote_oft,
|
|
11
|
-
rate_limit_capacity, rate_limit_in_flight, scan_packet_sent_event, send, set_rate_limit,
|
|
12
|
-
|
|
10
|
+
address_to_peer_bytes32, advance_time, create_send_param, lz_receive, mint_oft_token_to, mint_to, quote_oft,
|
|
11
|
+
quote_send, rate_limit_capacity, rate_limit_in_flight, scan_packet_sent_event, send, set_rate_limit,
|
|
12
|
+
set_rate_limit_with_mode, try_send, validate_packet,
|
|
13
13
|
},
|
|
14
14
|
};
|
|
15
15
|
use soroban_sdk::{testutils::Address as _, token::TokenClient, Address};
|
|
@@ -25,10 +25,8 @@ fn test_send_without_rate_limit() {
|
|
|
25
25
|
let receiver = create_recipient_address(&env);
|
|
26
26
|
let executor = Address::generate(&env);
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
mint_oft_token_to(&env, &chain_a, &sender, 100_000_000);
|
|
29
29
|
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
30
|
-
transfer_sac_admin(&env, &chain_a.owner, &chain_a.oft_token, &chain_a.oft.address);
|
|
31
|
-
transfer_sac_admin(&env, &chain_b.owner, &chain_b.oft_token, &chain_b.oft.address);
|
|
32
30
|
|
|
33
31
|
// Default capacity should be i128::MAX (unlimited)
|
|
34
32
|
let capacity = rate_limit_capacity(&chain_a, &Direction::Outbound, chain_b.eid);
|
|
@@ -62,10 +60,8 @@ fn test_send_within_rate_limit() {
|
|
|
62
60
|
let receiver = create_recipient_address(&env);
|
|
63
61
|
let executor = Address::generate(&env);
|
|
64
62
|
|
|
65
|
-
|
|
63
|
+
mint_oft_token_to(&env, &chain_a, &sender, 100_000_000);
|
|
66
64
|
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
67
|
-
transfer_sac_admin(&env, &chain_a.owner, &chain_a.oft_token, &chain_a.oft.address);
|
|
68
|
-
transfer_sac_admin(&env, &chain_b.owner, &chain_b.oft_token, &chain_b.oft.address);
|
|
69
65
|
|
|
70
66
|
// Set rate limit: 10M per 3600 seconds (1 hour)
|
|
71
67
|
set_rate_limit(&env, &chain_a, &Direction::Outbound, chain_b.eid, 10_000_000, 3600);
|
|
@@ -112,9 +108,8 @@ fn test_send_exceeds_rate_limit() {
|
|
|
112
108
|
let sender = Address::generate(&env);
|
|
113
109
|
let receiver = create_recipient_address(&env);
|
|
114
110
|
|
|
115
|
-
|
|
111
|
+
mint_oft_token_to(&env, &chain_a, &sender, 100_000_000);
|
|
116
112
|
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
117
|
-
transfer_sac_admin(&env, &chain_a.owner, &chain_a.oft_token, &chain_a.oft.address);
|
|
118
113
|
|
|
119
114
|
// Set rate limit: 1M per 3600 seconds
|
|
120
115
|
set_rate_limit(&env, &chain_a, &Direction::Outbound, chain_b.eid, 1_000_000, 3600);
|
|
@@ -140,10 +135,8 @@ fn test_rate_limit_decay() {
|
|
|
140
135
|
let receiver = create_recipient_address(&env);
|
|
141
136
|
let executor = Address::generate(&env);
|
|
142
137
|
|
|
143
|
-
|
|
138
|
+
mint_oft_token_to(&env, &chain_a, &sender, 100_000_000);
|
|
144
139
|
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
145
|
-
transfer_sac_admin(&env, &chain_a.owner, &chain_a.oft_token, &chain_a.oft.address);
|
|
146
|
-
transfer_sac_admin(&env, &chain_b.owner, &chain_b.oft_token, &chain_b.oft.address);
|
|
147
140
|
|
|
148
141
|
// Set rate limit: 10M per 1000 seconds
|
|
149
142
|
set_rate_limit(&env, &chain_a, &Direction::Outbound, chain_b.eid, 10_000_000, 1000);
|
|
@@ -199,12 +192,10 @@ fn test_gross_mode_does_not_release() {
|
|
|
199
192
|
let executor = Address::generate(&env);
|
|
200
193
|
|
|
201
194
|
// Setup tokens for both chains
|
|
202
|
-
|
|
195
|
+
mint_oft_token_to(&env, &chain_a, &sender_a, 100_000_000);
|
|
203
196
|
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender_a, 10_000_000_000);
|
|
204
|
-
|
|
197
|
+
mint_oft_token_to(&env, &chain_b, &sender_b, 100_000_000);
|
|
205
198
|
mint_to(&env, &chain_b.owner, &chain_b.native_token, &sender_b, 10_000_000_000);
|
|
206
|
-
transfer_sac_admin(&env, &chain_a.owner, &chain_a.oft_token, &chain_a.oft.address);
|
|
207
|
-
transfer_sac_admin(&env, &chain_b.owner, &chain_b.oft_token, &chain_b.oft.address);
|
|
208
199
|
|
|
209
200
|
// Set Gross mode rate limit on chain_a outbound: 10M per 3600 seconds
|
|
210
201
|
set_rate_limit_with_mode(&env, &chain_a, &Direction::Outbound, chain_b.eid, 10_000_000, 3600, Mode::Gross);
|
|
@@ -267,12 +258,10 @@ fn test_net_mode_does_release() {
|
|
|
267
258
|
let executor = Address::generate(&env);
|
|
268
259
|
|
|
269
260
|
// Setup tokens for both chains
|
|
270
|
-
|
|
261
|
+
mint_oft_token_to(&env, &chain_a, &sender_a, 100_000_000);
|
|
271
262
|
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender_a, 10_000_000_000);
|
|
272
|
-
|
|
263
|
+
mint_oft_token_to(&env, &chain_b, &sender_b, 100_000_000);
|
|
273
264
|
mint_to(&env, &chain_b.owner, &chain_b.native_token, &sender_b, 10_000_000_000);
|
|
274
|
-
transfer_sac_admin(&env, &chain_a.owner, &chain_a.oft_token, &chain_a.oft.address);
|
|
275
|
-
transfer_sac_admin(&env, &chain_b.owner, &chain_b.oft_token, &chain_b.oft.address);
|
|
276
265
|
|
|
277
266
|
// Set Net mode rate limit on chain_a outbound: 10M per 3600 seconds
|
|
278
267
|
set_rate_limit_with_mode(&env, &chain_a, &Direction::Outbound, chain_b.eid, 10_000_000, 3600, Mode::Net);
|
|
@@ -12,12 +12,40 @@ use crate::{
|
|
|
12
12
|
use endpoint_v2::{EndpointV2, EndpointV2Client};
|
|
13
13
|
use simple_message_lib::{SimpleMessageLib, SimpleMessageLibClient};
|
|
14
14
|
use soroban_sdk::{
|
|
15
|
-
contract, contractimpl, log,
|
|
15
|
+
contract, contractimpl, contracttype, log,
|
|
16
16
|
testutils::{Address as _, MockAuth, MockAuthInvoke},
|
|
17
|
-
token::TokenClient,
|
|
17
|
+
token::{StellarAssetClient, TokenClient},
|
|
18
18
|
Address, BytesN, Env, IntoVal,
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Mock SAC Wrapper - implements Mintable for integration tests
|
|
23
|
+
// ============================================================================
|
|
24
|
+
// Wraps a Stellar Asset Contract (SAC). The wrapper is set as SAC admin and
|
|
25
|
+
// implements mint(env, to, amount, operation) so the OFT uses it for credit (mint).
|
|
26
|
+
// OFT burns on the token directly; this mock still has burn for completeness.
|
|
27
|
+
|
|
28
|
+
#[contracttype]
|
|
29
|
+
pub enum MockSacWrapperKey {
|
|
30
|
+
Sac,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
#[contract]
|
|
34
|
+
pub struct MockSacWrapper;
|
|
35
|
+
|
|
36
|
+
#[contractimpl]
|
|
37
|
+
impl MockSacWrapper {
|
|
38
|
+
pub fn __constructor(env: &Env, sac: Address) {
|
|
39
|
+
env.storage().instance().set(&MockSacWrapperKey::Sac, &sac);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/// Mintable::mint - mints on the underlying SAC (wrapper must be SAC admin).
|
|
43
|
+
pub fn mint(env: &Env, to: &Address, amount: i128, _operation: &Address) {
|
|
44
|
+
let sac: Address = env.storage().instance().get(&MockSacWrapperKey::Sac).unwrap();
|
|
45
|
+
StellarAssetClient::new(env, &sac).mint(to, &amount);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
21
49
|
// ============================================================================
|
|
22
50
|
// Dummy Recipient - used to create valid contract addresses for recipients
|
|
23
51
|
// ============================================================================
|
|
@@ -45,7 +73,10 @@ pub struct ChainSetup<'a> {
|
|
|
45
73
|
pub owner: Address,
|
|
46
74
|
pub native_token: Address,
|
|
47
75
|
pub zro_token: Address,
|
|
76
|
+
/// Underlying SAC for the OFT token (used for balance, transfer, mint_to).
|
|
48
77
|
pub oft_token: Address,
|
|
78
|
+
/// Mock SAC wrapper implementing Mintable; OFT uses it for mint on credit.
|
|
79
|
+
pub sac_wrapper: Address,
|
|
49
80
|
pub endpoint: EndpointV2Client<'a>,
|
|
50
81
|
pub sml: SimpleMessageLibClient<'a>,
|
|
51
82
|
pub oft: OFTClient<'a>,
|
|
@@ -72,9 +103,20 @@ fn setup_chain<'a>(env: &Env) -> ChainSetup<'a> {
|
|
|
72
103
|
let zro_sac = env.register_stellar_asset_contract_v2(owner.clone());
|
|
73
104
|
let zro_token = zro_sac.address();
|
|
74
105
|
|
|
75
|
-
// Create OFT token
|
|
106
|
+
// Create OFT token (SAC) and a mock SAC wrapper that implements Mintable.
|
|
76
107
|
let oft_sac = env.register_stellar_asset_contract_v2(owner.clone());
|
|
77
108
|
let oft_token = oft_sac.address();
|
|
109
|
+
let sac_wrapper_address = env.register(MockSacWrapper, (&oft_token,));
|
|
110
|
+
env.mock_auths(&[MockAuth {
|
|
111
|
+
address: &owner,
|
|
112
|
+
invoke: &MockAuthInvoke {
|
|
113
|
+
contract: &oft_token,
|
|
114
|
+
fn_name: "set_admin",
|
|
115
|
+
args: (&sac_wrapper_address,).into_val(env),
|
|
116
|
+
sub_invokes: &[],
|
|
117
|
+
},
|
|
118
|
+
}]);
|
|
119
|
+
StellarAssetClient::new(env, &oft_token).set_admin(&sac_wrapper_address);
|
|
78
120
|
|
|
79
121
|
let eid: u32 = 30400; // Test EID
|
|
80
122
|
let endpoint_address = env.register(EndpointV2, (&owner, eid, &native_token));
|
|
@@ -82,9 +124,8 @@ fn setup_chain<'a>(env: &Env) -> ChainSetup<'a> {
|
|
|
82
124
|
let sml_address = env.register(SimpleMessageLib, (&owner, &endpoint_address, &fee_recipient));
|
|
83
125
|
let delegate: Option<Address> = Some(owner.clone());
|
|
84
126
|
let shared_decimals: u32 = 6; // Default shared decimals
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
let mode = OftType::MintBurn(oft_token.clone());
|
|
127
|
+
// MintBurn with SAC wrapper: OFT uses wrapper for mint on credit; burn is on token directly.
|
|
128
|
+
let mode = OftType::MintBurn(sac_wrapper_address.clone());
|
|
88
129
|
let oft_address = env.register(OFT, (&oft_token, &shared_decimals, &mode, &owner, &endpoint_address, &delegate));
|
|
89
130
|
|
|
90
131
|
let endpoint = EndpointV2Client::new(env, &endpoint_address);
|
|
@@ -104,7 +145,18 @@ fn setup_chain<'a>(env: &Env) -> ChainSetup<'a> {
|
|
|
104
145
|
endpoint.set_zro(&zro_token);
|
|
105
146
|
|
|
106
147
|
register_library(env, &owner, &endpoint, &sml.address);
|
|
107
|
-
ChainSetup {
|
|
148
|
+
ChainSetup {
|
|
149
|
+
eid,
|
|
150
|
+
owner,
|
|
151
|
+
native_token,
|
|
152
|
+
zro_token,
|
|
153
|
+
oft_token,
|
|
154
|
+
sac_wrapper: sac_wrapper_address,
|
|
155
|
+
endpoint,
|
|
156
|
+
sml,
|
|
157
|
+
oft,
|
|
158
|
+
fee_collector,
|
|
159
|
+
}
|
|
108
160
|
}
|
|
109
161
|
|
|
110
162
|
pub fn setup<'a>() -> TestSetup<'a> {
|