@layerzerolabs/protocol-stellar-v2 0.2.65 → 0.2.67
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 +218 -299
- package/.turbo/turbo-lint.log +225 -98
- package/.turbo/turbo-test.log +2010 -1924
- package/Cargo.lock +0 -16
- package/Cargo.toml +0 -1
- package/contracts/oapps/oft/integration-tests/extensions/test_oft_fee.rs +22 -0
- package/contracts/oapps/oft/integration-tests/extensions/test_pausable.rs +9 -2
- package/contracts/oapps/oft/integration-tests/extensions/test_rate_limiter.rs +27 -2
- package/contracts/oapps/oft/integration-tests/setup.rs +22 -18
- package/contracts/oapps/oft/integration-tests/utils.rs +81 -34
- package/contracts/oapps/oft/src/extensions/oft_fee.rs +13 -0
- package/contracts/oapps/oft/src/oft.rs +10 -2
- package/package.json +4 -4
- package/sdk/.turbo/turbo-test.log +299 -307
- package/sdk/dist/generated/oft.d.ts +3 -3
- package/sdk/dist/generated/oft.js +3 -3
- package/sdk/node_modules/.bin/vitest +2 -2
- package/sdk/package.json +1 -1
- package/contracts/oapps/console-oft/Cargo.toml +0 -30
- package/contracts/oapps/console-oft/integration-tests/extensions/mod.rs +0 -5
- package/contracts/oapps/console-oft/integration-tests/extensions/test_combined.rs +0 -90
- package/contracts/oapps/console-oft/integration-tests/extensions/test_oft_fee.rs +0 -186
- package/contracts/oapps/console-oft/integration-tests/extensions/test_ownership.rs +0 -161
- package/contracts/oapps/console-oft/integration-tests/extensions/test_pausable.rs +0 -154
- package/contracts/oapps/console-oft/integration-tests/extensions/test_rate_limiter.rs +0 -479
- package/contracts/oapps/console-oft/integration-tests/mod.rs +0 -3
- package/contracts/oapps/console-oft/integration-tests/setup.rs +0 -303
- package/contracts/oapps/console-oft/integration-tests/utils.rs +0 -685
- package/contracts/oapps/console-oft/src/errors.rs +0 -7
- package/contracts/oapps/console-oft/src/extensions/mod.rs +0 -3
- package/contracts/oapps/console-oft/src/extensions/oft_fee.rs +0 -239
- package/contracts/oapps/console-oft/src/extensions/pausable.rs +0 -185
- package/contracts/oapps/console-oft/src/extensions/rate_limiter.rs +0 -478
- package/contracts/oapps/console-oft/src/interfaces/mintable.rs +0 -14
- package/contracts/oapps/console-oft/src/interfaces/mod.rs +0 -3
- package/contracts/oapps/console-oft/src/lib.rs +0 -26
- package/contracts/oapps/console-oft/src/oft.rs +0 -208
- package/contracts/oapps/console-oft/src/oft_access_control.rs +0 -93
- package/contracts/oapps/console-oft/src/oft_types/lock_unlock.rs +0 -50
- package/contracts/oapps/console-oft/src/oft_types/mint_burn.rs +0 -50
- package/contracts/oapps/console-oft/src/oft_types/mod.rs +0 -24
- package/contracts/oapps/console-oft/src/tests/extensions/mod.rs +0 -3
- package/contracts/oapps/console-oft/src/tests/extensions/oft_fee.rs +0 -255
- package/contracts/oapps/console-oft/src/tests/extensions/pausable.rs +0 -212
- package/contracts/oapps/console-oft/src/tests/extensions/rate_limiter.rs +0 -992
- package/contracts/oapps/console-oft/src/tests/mod.rs +0 -2
- package/contracts/oapps/console-oft/src/tests/oft_types/lock_unlock.rs +0 -185
- package/contracts/oapps/console-oft/src/tests/oft_types/mod.rs +0 -1
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
//! Combined extension e2e tests for OFT-STD.
|
|
2
|
-
//!
|
|
3
|
-
//! Tests verify the interaction between multiple extensions when enabled simultaneously.
|
|
4
|
-
|
|
5
|
-
use crate::integration_tests::{
|
|
6
|
-
setup::{create_recipient_address, decode_packet, setup, wire_endpoint, wire_oft, TestSetup},
|
|
7
|
-
utils::{
|
|
8
|
-
address_to_peer_bytes32, create_send_param, globally_disable_rate_limiter, lz_receive, mint_oft_token_to,
|
|
9
|
-
mint_to, outbound_rate_limit_usage, quote_oft, quote_send, scan_packet_sent_event, send_with_fee,
|
|
10
|
-
set_default_fee_bps, set_outbound_rate_limit, set_paused, try_send, validate_packet,
|
|
11
|
-
},
|
|
12
|
-
};
|
|
13
|
-
use soroban_sdk::{testutils::Address as _, token::TokenClient, Address};
|
|
14
|
-
|
|
15
|
-
/// Test fee + rate limit: rate limit consumes the post-fee amount (amount_received_ld)
|
|
16
|
-
#[test]
|
|
17
|
-
fn test_fee_plus_rate_limit() {
|
|
18
|
-
let TestSetup { env, chain_a, chain_b } = setup();
|
|
19
|
-
wire_endpoint(&env, &[&chain_a, &chain_b]);
|
|
20
|
-
wire_oft(&env, &[&chain_a, &chain_b]);
|
|
21
|
-
globally_disable_rate_limiter(&env, &chain_b);
|
|
22
|
-
|
|
23
|
-
let sender = Address::generate(&env);
|
|
24
|
-
let receiver = create_recipient_address(&env);
|
|
25
|
-
let executor = Address::generate(&env);
|
|
26
|
-
|
|
27
|
-
mint_oft_token_to(&env, &chain_a, &sender, 100_000_000);
|
|
28
|
-
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
29
|
-
|
|
30
|
-
// Enable 10% fee and outbound rate limit of 5M.
|
|
31
|
-
set_default_fee_bps(&env, &chain_a, 1_000); // 10%
|
|
32
|
-
set_outbound_rate_limit(&env, &chain_a, chain_b.eid, 5_000_000, 3600);
|
|
33
|
-
|
|
34
|
-
let to = address_to_peer_bytes32(&receiver);
|
|
35
|
-
let amount_ld = 2_000_000i128;
|
|
36
|
-
let send_param = create_send_param(&env, chain_b.eid, amount_ld, 0, &to);
|
|
37
|
-
let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
|
|
38
|
-
|
|
39
|
-
// Fee = 10% of 2M = 200,000; amount_received = 1,800,000
|
|
40
|
-
let expected_fee = 200_000i128;
|
|
41
|
-
assert_eq!(oft_receipt.amount_sent_ld, amount_ld);
|
|
42
|
-
assert_eq!(oft_receipt.amount_received_ld, amount_ld - expected_fee);
|
|
43
|
-
|
|
44
|
-
let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
|
|
45
|
-
send_with_fee(&env, &chain_a, &sender, &send_param, &fee, &sender, &oft_receipt, &chain_a.fee_collector);
|
|
46
|
-
|
|
47
|
-
// Scan events immediately after send
|
|
48
|
-
let packet_event = scan_packet_sent_event(&env, &chain_a.endpoint.address).unwrap();
|
|
49
|
-
validate_packet(&env, &chain_b, &packet_event);
|
|
50
|
-
let packet = decode_packet(&env, &packet_event.0);
|
|
51
|
-
|
|
52
|
-
// Rate limit usage = post-fee amount (amount_received_ld), not the gross amount
|
|
53
|
-
let usage = outbound_rate_limit_usage(&env, &chain_a, chain_b.eid);
|
|
54
|
-
assert_eq!(usage, oft_receipt.amount_received_ld);
|
|
55
|
-
|
|
56
|
-
// Fee was collected on source chain
|
|
57
|
-
let fee_collector_balance = TokenClient::new(&env, &chain_a.oft_token).balance(&chain_a.fee_collector);
|
|
58
|
-
assert_eq!(fee_collector_balance, expected_fee);
|
|
59
|
-
|
|
60
|
-
lz_receive(&env, &chain_b, &executor, &packet, &receiver, 0);
|
|
61
|
-
|
|
62
|
-
let receiver_balance = TokenClient::new(&env, &chain_b.oft_token).balance(&receiver);
|
|
63
|
-
assert_eq!(receiver_balance, oft_receipt.amount_received_ld);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/// Test pause + rate limit: paused overrides rate limit (send fails even if within rate limit)
|
|
67
|
-
#[test]
|
|
68
|
-
fn test_pause_overrides_rate_limit() {
|
|
69
|
-
let TestSetup { env, chain_a, chain_b } = setup();
|
|
70
|
-
wire_endpoint(&env, &[&chain_a, &chain_b]);
|
|
71
|
-
wire_oft(&env, &[&chain_a, &chain_b]);
|
|
72
|
-
|
|
73
|
-
let sender = Address::generate(&env);
|
|
74
|
-
let receiver = create_recipient_address(&env);
|
|
75
|
-
|
|
76
|
-
mint_oft_token_to(&env, &chain_a, &sender, 100_000_000);
|
|
77
|
-
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
78
|
-
|
|
79
|
-
set_outbound_rate_limit(&env, &chain_a, chain_b.eid, 10_000_000, 3600);
|
|
80
|
-
|
|
81
|
-
let to = address_to_peer_bytes32(&receiver);
|
|
82
|
-
let send_param = create_send_param(&env, chain_b.eid, 1_000_000, 0, &to);
|
|
83
|
-
let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
|
|
84
|
-
let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
|
|
85
|
-
|
|
86
|
-
// Pause — send should fail even though rate limit has plenty of capacity
|
|
87
|
-
set_paused(&env, &chain_a, true);
|
|
88
|
-
let success = try_send(&env, &chain_a, &sender, &send_param, &fee, &sender, &oft_receipt);
|
|
89
|
-
assert!(!success, "send should fail when paused, regardless of rate limit capacity");
|
|
90
|
-
}
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
//! OFT Fee extension e2e tests for OFT-STD.
|
|
2
|
-
//!
|
|
3
|
-
//! Tests verify that the OFTFee extension properly collects fees on cross-chain transfers.
|
|
4
|
-
//! Key behavior: at debit_view, apply fee first then remove dust.
|
|
5
|
-
//! - If fee is zero: amount_sent_ld == amount_received_ld
|
|
6
|
-
//! - If fee is non-zero: amount_sent_ld is unchanged (original amount)
|
|
7
|
-
|
|
8
|
-
use crate::integration_tests::{
|
|
9
|
-
setup::{create_recipient_address, decode_packet, setup, wire_endpoint, wire_oft, TestSetup},
|
|
10
|
-
utils::{
|
|
11
|
-
address_to_peer_bytes32, create_send_param, globally_disable_rate_limiter, lz_receive, mint_oft_token_to,
|
|
12
|
-
mint_to, quote_oft, quote_send, scan_packet_sent_event, send, send_with_fee, set_default_fee_bps, set_fee_bps,
|
|
13
|
-
set_outbound_rate_limit, token_balance, validate_packet,
|
|
14
|
-
},
|
|
15
|
-
};
|
|
16
|
-
use soroban_sdk::{testutils::Address as _, token::TokenClient, Address};
|
|
17
|
-
|
|
18
|
-
/// Test e2e cross-chain transfer with zero fee (default)
|
|
19
|
-
#[test]
|
|
20
|
-
fn test_cross_chain_with_zero_fee() {
|
|
21
|
-
let TestSetup { env, chain_a, chain_b } = setup();
|
|
22
|
-
wire_endpoint(&env, &[&chain_a, &chain_b]);
|
|
23
|
-
wire_oft(&env, &[&chain_a, &chain_b]);
|
|
24
|
-
globally_disable_rate_limiter(&env, &chain_a);
|
|
25
|
-
globally_disable_rate_limiter(&env, &chain_b);
|
|
26
|
-
|
|
27
|
-
let sender = Address::generate(&env);
|
|
28
|
-
let receiver = create_recipient_address(&env);
|
|
29
|
-
let executor = Address::generate(&env);
|
|
30
|
-
|
|
31
|
-
mint_oft_token_to(&env, &chain_a, &sender, 10_000_000);
|
|
32
|
-
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
33
|
-
|
|
34
|
-
let to = address_to_peer_bytes32(&receiver);
|
|
35
|
-
let send_param = create_send_param(&env, chain_b.eid, 1_000_000, 0, &to);
|
|
36
|
-
let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
|
|
37
|
-
|
|
38
|
-
// With zero fee, amount_sent_ld == amount_received_ld (after dust removal)
|
|
39
|
-
assert_eq!(oft_receipt.amount_sent_ld, oft_receipt.amount_received_ld);
|
|
40
|
-
|
|
41
|
-
let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
|
|
42
|
-
send(&env, &chain_a, &sender, &send_param, &fee, &sender, &oft_receipt);
|
|
43
|
-
|
|
44
|
-
let packet_event = scan_packet_sent_event(&env, &chain_a.endpoint.address).unwrap();
|
|
45
|
-
validate_packet(&env, &chain_b, &packet_event);
|
|
46
|
-
let packet = decode_packet(&env, &packet_event.0);
|
|
47
|
-
|
|
48
|
-
lz_receive(&env, &chain_b, &executor, &packet, &receiver, 0);
|
|
49
|
-
|
|
50
|
-
// Verify receiver got full amount (no fee)
|
|
51
|
-
let receiver_balance = TokenClient::new(&env, &chain_b.oft_token).balance(&receiver);
|
|
52
|
-
assert_eq!(receiver_balance, oft_receipt.amount_received_ld);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/// Test e2e cross-chain transfer with fee enabled
|
|
56
|
-
#[test]
|
|
57
|
-
fn test_cross_chain_with_fee() {
|
|
58
|
-
let TestSetup { env, chain_a, chain_b } = setup();
|
|
59
|
-
wire_endpoint(&env, &[&chain_a, &chain_b]);
|
|
60
|
-
wire_oft(&env, &[&chain_a, &chain_b]);
|
|
61
|
-
globally_disable_rate_limiter(&env, &chain_a);
|
|
62
|
-
globally_disable_rate_limiter(&env, &chain_b);
|
|
63
|
-
|
|
64
|
-
let sender = Address::generate(&env);
|
|
65
|
-
let receiver = create_recipient_address(&env);
|
|
66
|
-
let executor = Address::generate(&env);
|
|
67
|
-
|
|
68
|
-
mint_oft_token_to(&env, &chain_a, &sender, 10_000_000);
|
|
69
|
-
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
70
|
-
|
|
71
|
-
// Enable 1% fee (100 bps).
|
|
72
|
-
set_default_fee_bps(&env, &chain_a, 100);
|
|
73
|
-
|
|
74
|
-
let to = address_to_peer_bytes32(&receiver);
|
|
75
|
-
let amount_ld = 1_000_000i128;
|
|
76
|
-
let send_param = create_send_param(&env, chain_b.eid, amount_ld, 0, &to);
|
|
77
|
-
let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
|
|
78
|
-
|
|
79
|
-
// With fee, amount_sent_ld stays original, amount_received_ld is reduced
|
|
80
|
-
assert_eq!(oft_receipt.amount_sent_ld, amount_ld);
|
|
81
|
-
assert!(oft_receipt.amount_received_ld < amount_ld);
|
|
82
|
-
|
|
83
|
-
// Expected fee: 1% of 1,000,000 = 10,000
|
|
84
|
-
let expected_fee = 10_000i128;
|
|
85
|
-
let actual_fee = oft_receipt.amount_sent_ld - oft_receipt.amount_received_ld;
|
|
86
|
-
assert_eq!(actual_fee, expected_fee);
|
|
87
|
-
|
|
88
|
-
let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
|
|
89
|
-
send_with_fee(&env, &chain_a, &sender, &send_param, &fee, &sender, &oft_receipt, &chain_a.fee_collector);
|
|
90
|
-
|
|
91
|
-
// IMPORTANT: Scan events immediately after send, before any other operations
|
|
92
|
-
let packet_event = scan_packet_sent_event(&env, &chain_a.endpoint.address).unwrap();
|
|
93
|
-
validate_packet(&env, &chain_b, &packet_event);
|
|
94
|
-
let packet = decode_packet(&env, &packet_event.0);
|
|
95
|
-
|
|
96
|
-
// Verify fee was collected on source chain
|
|
97
|
-
let fee_collector_balance = token_balance(&env, &chain_a.oft_token, &chain_a.fee_collector);
|
|
98
|
-
assert_eq!(fee_collector_balance, expected_fee);
|
|
99
|
-
|
|
100
|
-
lz_receive(&env, &chain_b, &executor, &packet, &receiver, 0);
|
|
101
|
-
|
|
102
|
-
// Verify receiver got amount after fee
|
|
103
|
-
let receiver_balance = TokenClient::new(&env, &chain_b.oft_token).balance(&receiver);
|
|
104
|
-
assert_eq!(receiver_balance, oft_receipt.amount_received_ld);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/// Test e2e cross-chain transfer with destination-specific fee
|
|
108
|
-
#[test]
|
|
109
|
-
fn test_cross_chain_with_destination_specific_fee() {
|
|
110
|
-
let TestSetup { env, chain_a, chain_b } = setup();
|
|
111
|
-
wire_endpoint(&env, &[&chain_a, &chain_b]);
|
|
112
|
-
wire_oft(&env, &[&chain_a, &chain_b]);
|
|
113
|
-
globally_disable_rate_limiter(&env, &chain_a);
|
|
114
|
-
globally_disable_rate_limiter(&env, &chain_b);
|
|
115
|
-
|
|
116
|
-
let sender = Address::generate(&env);
|
|
117
|
-
let receiver = create_recipient_address(&env);
|
|
118
|
-
let executor = Address::generate(&env);
|
|
119
|
-
|
|
120
|
-
mint_oft_token_to(&env, &chain_a, &sender, 10_000_000);
|
|
121
|
-
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
122
|
-
|
|
123
|
-
// Set default fee 1% and destination-specific fee 2% for chain_b.
|
|
124
|
-
set_default_fee_bps(&env, &chain_a, 100); // 1%
|
|
125
|
-
set_fee_bps(&env, &chain_a, chain_b.eid, 200); // 2% for chain_b
|
|
126
|
-
|
|
127
|
-
let to = address_to_peer_bytes32(&receiver);
|
|
128
|
-
let amount_ld = 1_000_000i128;
|
|
129
|
-
let send_param = create_send_param(&env, chain_b.eid, amount_ld, 0, &to);
|
|
130
|
-
let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
|
|
131
|
-
|
|
132
|
-
// 2% fee on 1,000,000 = 20,000
|
|
133
|
-
let expected_fee = 20_000i128;
|
|
134
|
-
let actual_fee = oft_receipt.amount_sent_ld - oft_receipt.amount_received_ld;
|
|
135
|
-
assert_eq!(actual_fee, expected_fee);
|
|
136
|
-
|
|
137
|
-
let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
|
|
138
|
-
send_with_fee(&env, &chain_a, &sender, &send_param, &fee, &sender, &oft_receipt, &chain_a.fee_collector);
|
|
139
|
-
|
|
140
|
-
// IMPORTANT: Scan events immediately after send, before any other operations
|
|
141
|
-
let packet_event = scan_packet_sent_event(&env, &chain_a.endpoint.address).unwrap();
|
|
142
|
-
validate_packet(&env, &chain_b, &packet_event);
|
|
143
|
-
let packet = decode_packet(&env, &packet_event.0);
|
|
144
|
-
|
|
145
|
-
// Verify fee was collected
|
|
146
|
-
let fee_collector_balance = token_balance(&env, &chain_a.oft_token, &chain_a.fee_collector);
|
|
147
|
-
assert_eq!(fee_collector_balance, expected_fee);
|
|
148
|
-
|
|
149
|
-
lz_receive(&env, &chain_b, &executor, &packet, &receiver, 0);
|
|
150
|
-
|
|
151
|
-
// Verify receiver got correct amount
|
|
152
|
-
let receiver_balance = TokenClient::new(&env, &chain_b.oft_token).balance(&receiver);
|
|
153
|
-
assert_eq!(receiver_balance, oft_receipt.amount_received_ld);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/// Test quote_oft returns accurate OFTLimit and OFTFeeDetail under rate limit + fee
|
|
157
|
-
#[test]
|
|
158
|
-
fn test_quote_oft_reflects_rate_limit_and_fee() {
|
|
159
|
-
let TestSetup { env, chain_a, chain_b } = setup();
|
|
160
|
-
wire_endpoint(&env, &[&chain_a, &chain_b]);
|
|
161
|
-
wire_oft(&env, &[&chain_a, &chain_b]);
|
|
162
|
-
|
|
163
|
-
let sender = Address::generate(&env);
|
|
164
|
-
mint_oft_token_to(&env, &chain_a, &sender, 100_000_000);
|
|
165
|
-
|
|
166
|
-
// Set outbound rate limit = 5M and fee = 2%.
|
|
167
|
-
set_outbound_rate_limit(&env, &chain_a, chain_b.eid, 5_000_000, 3600);
|
|
168
|
-
set_default_fee_bps(&env, &chain_a, 200);
|
|
169
|
-
|
|
170
|
-
let to = address_to_peer_bytes32(&create_recipient_address(&env));
|
|
171
|
-
let send_param = create_send_param(&env, chain_b.eid, 3_000_000, 0, &to);
|
|
172
|
-
let (oft_limit, fee_details, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
|
|
173
|
-
|
|
174
|
-
// OFTLimit.max_amount_ld = back-calculated pre-fee max so post-fee fits the rate limit
|
|
175
|
-
// rate_limit_capacity=5M, fee=2%: max_send = 5M * 10000 / 9800 = 5,102,040
|
|
176
|
-
assert_eq!(oft_limit.max_amount_ld, 5_102_040);
|
|
177
|
-
|
|
178
|
-
// Fee detail should show 2% fee
|
|
179
|
-
assert!(!fee_details.is_empty());
|
|
180
|
-
let fee_detail = fee_details.first().unwrap();
|
|
181
|
-
assert_eq!(fee_detail.fee_amount_ld, 60_000); // 2% of 3M = 60,000
|
|
182
|
-
|
|
183
|
-
// OFTReceipt should reflect fee deduction
|
|
184
|
-
assert_eq!(oft_receipt.amount_sent_ld, 3_000_000);
|
|
185
|
-
assert_eq!(oft_receipt.amount_received_ld, 3_000_000 - 60_000);
|
|
186
|
-
}
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
//! Ownership & delegate sync integration tests for Console OFT.
|
|
2
|
-
//!
|
|
3
|
-
//! Verifies that:
|
|
4
|
-
//! - Single-step `transfer_ownership` is disabled.
|
|
5
|
-
//! - `renounce_ownership` is disabled.
|
|
6
|
-
//! - `set_delegate` is disabled.
|
|
7
|
-
//! - 2-step ownership transfer works and auto-syncs the endpoint delegate.
|
|
8
|
-
|
|
9
|
-
use crate::integration_tests::setup::{setup, TestSetup};
|
|
10
|
-
use crate::errors::OFTError;
|
|
11
|
-
use soroban_sdk::{
|
|
12
|
-
testutils::{Address as _, MockAuth, MockAuthInvoke},
|
|
13
|
-
Address, Env, IntoVal,
|
|
14
|
-
};
|
|
15
|
-
use utils::errors::OwnableError;
|
|
16
|
-
|
|
17
|
-
// ============================================================================
|
|
18
|
-
// Helpers
|
|
19
|
-
// ============================================================================
|
|
20
|
-
|
|
21
|
-
fn get_delegate(_env: &Env, setup: &crate::integration_tests::setup::ChainSetup<'_>) -> Option<Address> {
|
|
22
|
-
setup.endpoint.delegate(&setup.oft.address)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// ============================================================================
|
|
26
|
-
// Disabled operations
|
|
27
|
-
// ============================================================================
|
|
28
|
-
|
|
29
|
-
#[test]
|
|
30
|
-
fn test_transfer_ownership_disabled() {
|
|
31
|
-
let TestSetup { env, chain_a, .. } = setup();
|
|
32
|
-
|
|
33
|
-
let new_owner = Address::generate(&env);
|
|
34
|
-
env.mock_auths(&[MockAuth {
|
|
35
|
-
address: &chain_a.owner,
|
|
36
|
-
invoke: &MockAuthInvoke {
|
|
37
|
-
contract: &chain_a.oft.address,
|
|
38
|
-
fn_name: "transfer_ownership",
|
|
39
|
-
args: (&new_owner,).into_val(&env),
|
|
40
|
-
sub_invokes: &[],
|
|
41
|
-
},
|
|
42
|
-
}]);
|
|
43
|
-
let res = chain_a.oft.try_transfer_ownership(&new_owner);
|
|
44
|
-
assert_eq!(res.err().unwrap().ok().unwrap(), OFTError::Disabled.into());
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
#[test]
|
|
48
|
-
fn test_renounce_ownership_disabled() {
|
|
49
|
-
let TestSetup { env, chain_a, .. } = setup();
|
|
50
|
-
|
|
51
|
-
env.mock_auths(&[MockAuth {
|
|
52
|
-
address: &chain_a.owner,
|
|
53
|
-
invoke: &MockAuthInvoke {
|
|
54
|
-
contract: &chain_a.oft.address,
|
|
55
|
-
fn_name: "renounce_ownership",
|
|
56
|
-
args: ().into_val(&env),
|
|
57
|
-
sub_invokes: &[],
|
|
58
|
-
},
|
|
59
|
-
}]);
|
|
60
|
-
let res = chain_a.oft.try_renounce_ownership();
|
|
61
|
-
assert_eq!(res.err().unwrap().ok().unwrap(), OFTError::Disabled.into());
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
#[test]
|
|
65
|
-
fn test_set_delegate_disabled() {
|
|
66
|
-
let TestSetup { env, chain_a, .. } = setup();
|
|
67
|
-
|
|
68
|
-
let new_delegate: Option<Address> = Some(Address::generate(&env));
|
|
69
|
-
env.mock_auths(&[MockAuth {
|
|
70
|
-
address: &chain_a.owner,
|
|
71
|
-
invoke: &MockAuthInvoke {
|
|
72
|
-
contract: &chain_a.oft.address,
|
|
73
|
-
fn_name: "set_delegate",
|
|
74
|
-
args: (&new_delegate, &chain_a.owner).into_val(&env),
|
|
75
|
-
sub_invokes: &[],
|
|
76
|
-
},
|
|
77
|
-
}]);
|
|
78
|
-
let res = chain_a.oft.try_set_delegate(&new_delegate, &chain_a.owner);
|
|
79
|
-
assert_eq!(res.err().unwrap().ok().unwrap(), OFTError::Disabled.into());
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// ============================================================================
|
|
83
|
-
// 2-step ownership transfer with delegate sync
|
|
84
|
-
// ============================================================================
|
|
85
|
-
|
|
86
|
-
#[test]
|
|
87
|
-
fn test_two_step_transfer_syncs_delegate() {
|
|
88
|
-
let TestSetup { env, chain_a, .. } = setup();
|
|
89
|
-
let new_owner = Address::generate(&env);
|
|
90
|
-
let ttl = 1000u32;
|
|
91
|
-
|
|
92
|
-
// Verify initial state: owner == delegate
|
|
93
|
-
assert_eq!(chain_a.oft.owner(), Some(chain_a.owner.clone()));
|
|
94
|
-
assert_eq!(get_delegate(&env, &chain_a), Some(chain_a.owner.clone()));
|
|
95
|
-
|
|
96
|
-
// Step 1: begin_ownership_transfer (owner initiates)
|
|
97
|
-
env.mock_auths(&[MockAuth {
|
|
98
|
-
address: &chain_a.owner,
|
|
99
|
-
invoke: &MockAuthInvoke {
|
|
100
|
-
contract: &chain_a.oft.address,
|
|
101
|
-
fn_name: "begin_ownership_transfer",
|
|
102
|
-
args: (&new_owner, &ttl).into_val(&env),
|
|
103
|
-
sub_invokes: &[],
|
|
104
|
-
},
|
|
105
|
-
}]);
|
|
106
|
-
chain_a.oft.begin_ownership_transfer(&new_owner, &ttl);
|
|
107
|
-
|
|
108
|
-
// Owner and delegate unchanged during pending state
|
|
109
|
-
assert_eq!(chain_a.oft.owner(), Some(chain_a.owner.clone()));
|
|
110
|
-
assert_eq!(chain_a.oft.pending_owner(), Some(new_owner.clone()));
|
|
111
|
-
assert_eq!(get_delegate(&env, &chain_a), Some(chain_a.owner.clone()));
|
|
112
|
-
|
|
113
|
-
// Step 2: accept_ownership (new owner accepts)
|
|
114
|
-
env.mock_auths(&[MockAuth {
|
|
115
|
-
address: &new_owner,
|
|
116
|
-
invoke: &MockAuthInvoke {
|
|
117
|
-
contract: &chain_a.oft.address,
|
|
118
|
-
fn_name: "accept_ownership",
|
|
119
|
-
args: ().into_val(&env),
|
|
120
|
-
sub_invokes: &[MockAuthInvoke {
|
|
121
|
-
contract: &chain_a.endpoint.address,
|
|
122
|
-
fn_name: "set_delegate",
|
|
123
|
-
args: (&chain_a.oft.address, &Some(new_owner.clone())).into_val(&env),
|
|
124
|
-
sub_invokes: &[],
|
|
125
|
-
}],
|
|
126
|
-
},
|
|
127
|
-
}]);
|
|
128
|
-
chain_a.oft.accept_ownership();
|
|
129
|
-
|
|
130
|
-
// Verify: owner == delegate == new_owner
|
|
131
|
-
assert_eq!(chain_a.oft.owner(), Some(new_owner.clone()));
|
|
132
|
-
assert_eq!(chain_a.oft.pending_owner(), None);
|
|
133
|
-
assert_eq!(get_delegate(&env, &chain_a), Some(new_owner));
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
#[test]
|
|
137
|
-
fn test_accept_ownership_fails_without_pending_transfer() {
|
|
138
|
-
let TestSetup { env, chain_a, .. } = setup();
|
|
139
|
-
|
|
140
|
-
let random = Address::generate(&env);
|
|
141
|
-
env.mock_auths(&[MockAuth {
|
|
142
|
-
address: &random,
|
|
143
|
-
invoke: &MockAuthInvoke {
|
|
144
|
-
contract: &chain_a.oft.address,
|
|
145
|
-
fn_name: "accept_ownership",
|
|
146
|
-
args: ().into_val(&env),
|
|
147
|
-
sub_invokes: &[],
|
|
148
|
-
},
|
|
149
|
-
}]);
|
|
150
|
-
let res = chain_a.oft.try_accept_ownership();
|
|
151
|
-
assert_eq!(res.err().unwrap().ok().unwrap(), OwnableError::NoPendingTransfer.into());
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
#[test]
|
|
155
|
-
fn test_initial_owner_equals_delegate() {
|
|
156
|
-
let TestSetup { env, chain_a, .. } = setup();
|
|
157
|
-
|
|
158
|
-
let owner = chain_a.oft.owner().unwrap();
|
|
159
|
-
let delegate = get_delegate(&env, &chain_a).unwrap();
|
|
160
|
-
assert_eq!(owner, delegate);
|
|
161
|
-
}
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
//! Pausable extension e2e tests for OFT-STD.
|
|
2
|
-
//!
|
|
3
|
-
//! Tests verify that the Pausable extension properly blocks/allows send and receive
|
|
4
|
-
//! operations when the OFT is paused/unpaused. Uses real EndpointV2 and SimpleMessageLib.
|
|
5
|
-
|
|
6
|
-
use crate::integration_tests::{
|
|
7
|
-
setup::{create_recipient_address, decode_packet, setup, wire_endpoint, wire_oft, TestSetup},
|
|
8
|
-
utils::{
|
|
9
|
-
address_to_peer_bytes32, create_send_param, globally_disable_rate_limiter, is_paused, lz_receive,
|
|
10
|
-
mint_oft_token_to, mint_to, quote_oft, quote_send, scan_packet_sent_event, send, set_paused, try_send,
|
|
11
|
-
validate_packet,
|
|
12
|
-
},
|
|
13
|
-
};
|
|
14
|
-
use soroban_sdk::{testutils::Address as _, token::TokenClient, Address};
|
|
15
|
-
|
|
16
|
-
/// Test e2e send succeeds when unpaused (default state)
|
|
17
|
-
#[test]
|
|
18
|
-
fn test_send_succeeds_when_unpaused() {
|
|
19
|
-
let TestSetup { env, chain_a, chain_b } = setup();
|
|
20
|
-
wire_endpoint(&env, &[&chain_a, &chain_b]);
|
|
21
|
-
wire_oft(&env, &[&chain_a, &chain_b]);
|
|
22
|
-
globally_disable_rate_limiter(&env, &chain_a);
|
|
23
|
-
globally_disable_rate_limiter(&env, &chain_b);
|
|
24
|
-
|
|
25
|
-
let sender = Address::generate(&env);
|
|
26
|
-
let receiver = create_recipient_address(&env);
|
|
27
|
-
|
|
28
|
-
mint_oft_token_to(&env, &chain_a, &sender, 10_000_000);
|
|
29
|
-
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
30
|
-
|
|
31
|
-
assert!(!is_paused(&chain_a));
|
|
32
|
-
|
|
33
|
-
let to = address_to_peer_bytes32(&receiver);
|
|
34
|
-
let send_param = create_send_param(&env, chain_b.eid, 1_000_000, 0, &to);
|
|
35
|
-
let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
|
|
36
|
-
let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
|
|
37
|
-
|
|
38
|
-
send(&env, &chain_a, &sender, &send_param, &fee, &sender, &oft_receipt);
|
|
39
|
-
|
|
40
|
-
let packet_event = scan_packet_sent_event(&env, &chain_a.endpoint.address).unwrap();
|
|
41
|
-
validate_packet(&env, &chain_b, &packet_event);
|
|
42
|
-
let packet = decode_packet(&env, &packet_event.0);
|
|
43
|
-
|
|
44
|
-
let executor = Address::generate(&env);
|
|
45
|
-
lz_receive(&env, &chain_b, &executor, &packet, &receiver, 0);
|
|
46
|
-
|
|
47
|
-
let sender_balance = TokenClient::new(&env, &chain_a.oft_token).balance(&sender);
|
|
48
|
-
let receiver_balance = TokenClient::new(&env, &chain_b.oft_token).balance(&receiver);
|
|
49
|
-
assert_eq!(sender_balance, 10_000_000 - oft_receipt.amount_sent_ld);
|
|
50
|
-
assert_eq!(receiver_balance, oft_receipt.amount_received_ld);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/// Test e2e send fails when paused
|
|
54
|
-
#[test]
|
|
55
|
-
fn test_send_fails_when_paused() {
|
|
56
|
-
let TestSetup { env, chain_a, chain_b } = setup();
|
|
57
|
-
wire_endpoint(&env, &[&chain_a, &chain_b]);
|
|
58
|
-
wire_oft(&env, &[&chain_a, &chain_b]);
|
|
59
|
-
globally_disable_rate_limiter(&env, &chain_a);
|
|
60
|
-
globally_disable_rate_limiter(&env, &chain_b);
|
|
61
|
-
|
|
62
|
-
let sender = Address::generate(&env);
|
|
63
|
-
let receiver = create_recipient_address(&env);
|
|
64
|
-
|
|
65
|
-
mint_oft_token_to(&env, &chain_a, &sender, 10_000_000);
|
|
66
|
-
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
67
|
-
|
|
68
|
-
let to = address_to_peer_bytes32(&receiver);
|
|
69
|
-
let send_param = create_send_param(&env, chain_b.eid, 1_000_000, 0, &to);
|
|
70
|
-
let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
|
|
71
|
-
let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
|
|
72
|
-
|
|
73
|
-
set_paused(&env, &chain_a, true);
|
|
74
|
-
assert!(is_paused(&chain_a));
|
|
75
|
-
|
|
76
|
-
let success = try_send(&env, &chain_a, &sender, &send_param, &fee, &sender, &oft_receipt);
|
|
77
|
-
assert!(!success);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/// Test e2e receive succeeds even when destination is paused.
|
|
81
|
-
///
|
|
82
|
-
/// Matches EVM behavior: `whenNotPaused` is only on `_debit`, not `_credit`.
|
|
83
|
-
/// This prevents in-flight token lockups when a chain is paused mid-transfer.
|
|
84
|
-
#[test]
|
|
85
|
-
fn test_receive_succeeds_when_paused() {
|
|
86
|
-
let TestSetup { env, chain_a, chain_b } = setup();
|
|
87
|
-
wire_endpoint(&env, &[&chain_a, &chain_b]);
|
|
88
|
-
wire_oft(&env, &[&chain_a, &chain_b]);
|
|
89
|
-
globally_disable_rate_limiter(&env, &chain_a);
|
|
90
|
-
globally_disable_rate_limiter(&env, &chain_b);
|
|
91
|
-
|
|
92
|
-
let sender = Address::generate(&env);
|
|
93
|
-
let receiver = create_recipient_address(&env);
|
|
94
|
-
let executor = Address::generate(&env);
|
|
95
|
-
|
|
96
|
-
mint_oft_token_to(&env, &chain_a, &sender, 10_000_000);
|
|
97
|
-
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
98
|
-
|
|
99
|
-
let to = address_to_peer_bytes32(&receiver);
|
|
100
|
-
let send_param = create_send_param(&env, chain_b.eid, 1_000_000, 0, &to);
|
|
101
|
-
let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
|
|
102
|
-
let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
|
|
103
|
-
send(&env, &chain_a, &sender, &send_param, &fee, &sender, &oft_receipt);
|
|
104
|
-
|
|
105
|
-
let packet_event = scan_packet_sent_event(&env, &chain_a.endpoint.address).unwrap();
|
|
106
|
-
validate_packet(&env, &chain_b, &packet_event);
|
|
107
|
-
let packet = decode_packet(&env, &packet_event.0);
|
|
108
|
-
|
|
109
|
-
set_paused(&env, &chain_b, true);
|
|
110
|
-
assert!(is_paused(&chain_b));
|
|
111
|
-
|
|
112
|
-
lz_receive(&env, &chain_b, &executor, &packet, &receiver, 0);
|
|
113
|
-
|
|
114
|
-
let receiver_balance = TokenClient::new(&env, &chain_b.oft_token).balance(&receiver);
|
|
115
|
-
assert_eq!(receiver_balance, oft_receipt.amount_received_ld);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/// Test e2e cross-chain flow works after unpause
|
|
119
|
-
#[test]
|
|
120
|
-
fn test_cross_chain_succeeds_after_unpause() {
|
|
121
|
-
let TestSetup { env, chain_a, chain_b } = setup();
|
|
122
|
-
wire_endpoint(&env, &[&chain_a, &chain_b]);
|
|
123
|
-
wire_oft(&env, &[&chain_a, &chain_b]);
|
|
124
|
-
globally_disable_rate_limiter(&env, &chain_a);
|
|
125
|
-
globally_disable_rate_limiter(&env, &chain_b);
|
|
126
|
-
|
|
127
|
-
let sender = Address::generate(&env);
|
|
128
|
-
let receiver = create_recipient_address(&env);
|
|
129
|
-
let executor = Address::generate(&env);
|
|
130
|
-
|
|
131
|
-
mint_oft_token_to(&env, &chain_a, &sender, 10_000_000);
|
|
132
|
-
mint_to(&env, &chain_a.owner, &chain_a.native_token, &sender, 10_000_000_000);
|
|
133
|
-
|
|
134
|
-
set_paused(&env, &chain_a, true);
|
|
135
|
-
assert!(is_paused(&chain_a));
|
|
136
|
-
set_paused(&env, &chain_a, false);
|
|
137
|
-
assert!(!is_paused(&chain_a));
|
|
138
|
-
|
|
139
|
-
let to = address_to_peer_bytes32(&receiver);
|
|
140
|
-
let send_param = create_send_param(&env, chain_b.eid, 1_000_000, 0, &to);
|
|
141
|
-
let (_, _, oft_receipt) = quote_oft(&chain_a, &sender, &send_param);
|
|
142
|
-
let fee = quote_send(&env, &chain_a, &sender, &send_param, false);
|
|
143
|
-
|
|
144
|
-
send(&env, &chain_a, &sender, &send_param, &fee, &sender, &oft_receipt);
|
|
145
|
-
|
|
146
|
-
let packet_event = scan_packet_sent_event(&env, &chain_a.endpoint.address).unwrap();
|
|
147
|
-
validate_packet(&env, &chain_b, &packet_event);
|
|
148
|
-
let packet = decode_packet(&env, &packet_event.0);
|
|
149
|
-
|
|
150
|
-
lz_receive(&env, &chain_b, &executor, &packet, &receiver, 0);
|
|
151
|
-
|
|
152
|
-
let receiver_balance = TokenClient::new(&env, &chain_b.oft_token).balance(&receiver);
|
|
153
|
-
assert_eq!(receiver_balance, oft_receipt.amount_received_ld);
|
|
154
|
-
}
|