@layerzerolabs/protocol-stellar-v2 0.2.65 → 0.2.66

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.
Files changed (48) hide show
  1. package/.turbo/turbo-build.log +218 -299
  2. package/.turbo/turbo-lint.log +225 -98
  3. package/.turbo/turbo-test.log +2010 -1924
  4. package/Cargo.lock +0 -16
  5. package/Cargo.toml +0 -1
  6. package/contracts/oapps/oft/integration-tests/extensions/test_oft_fee.rs +22 -0
  7. package/contracts/oapps/oft/integration-tests/extensions/test_pausable.rs +9 -2
  8. package/contracts/oapps/oft/integration-tests/extensions/test_rate_limiter.rs +27 -2
  9. package/contracts/oapps/oft/integration-tests/setup.rs +22 -18
  10. package/contracts/oapps/oft/integration-tests/utils.rs +81 -34
  11. package/contracts/oapps/oft/src/extensions/oft_fee.rs +13 -0
  12. package/contracts/oapps/oft/src/oft.rs +10 -2
  13. package/package.json +4 -4
  14. package/sdk/.turbo/turbo-test.log +299 -307
  15. package/sdk/dist/generated/oft.d.ts +3 -3
  16. package/sdk/dist/generated/oft.js +3 -3
  17. package/sdk/node_modules/.bin/vitest +2 -2
  18. package/sdk/package.json +1 -1
  19. package/contracts/oapps/console-oft/Cargo.toml +0 -30
  20. package/contracts/oapps/console-oft/integration-tests/extensions/mod.rs +0 -5
  21. package/contracts/oapps/console-oft/integration-tests/extensions/test_combined.rs +0 -90
  22. package/contracts/oapps/console-oft/integration-tests/extensions/test_oft_fee.rs +0 -186
  23. package/contracts/oapps/console-oft/integration-tests/extensions/test_ownership.rs +0 -161
  24. package/contracts/oapps/console-oft/integration-tests/extensions/test_pausable.rs +0 -154
  25. package/contracts/oapps/console-oft/integration-tests/extensions/test_rate_limiter.rs +0 -479
  26. package/contracts/oapps/console-oft/integration-tests/mod.rs +0 -3
  27. package/contracts/oapps/console-oft/integration-tests/setup.rs +0 -303
  28. package/contracts/oapps/console-oft/integration-tests/utils.rs +0 -685
  29. package/contracts/oapps/console-oft/src/errors.rs +0 -7
  30. package/contracts/oapps/console-oft/src/extensions/mod.rs +0 -3
  31. package/contracts/oapps/console-oft/src/extensions/oft_fee.rs +0 -239
  32. package/contracts/oapps/console-oft/src/extensions/pausable.rs +0 -185
  33. package/contracts/oapps/console-oft/src/extensions/rate_limiter.rs +0 -478
  34. package/contracts/oapps/console-oft/src/interfaces/mintable.rs +0 -14
  35. package/contracts/oapps/console-oft/src/interfaces/mod.rs +0 -3
  36. package/contracts/oapps/console-oft/src/lib.rs +0 -26
  37. package/contracts/oapps/console-oft/src/oft.rs +0 -208
  38. package/contracts/oapps/console-oft/src/oft_access_control.rs +0 -93
  39. package/contracts/oapps/console-oft/src/oft_types/lock_unlock.rs +0 -50
  40. package/contracts/oapps/console-oft/src/oft_types/mint_burn.rs +0 -50
  41. package/contracts/oapps/console-oft/src/oft_types/mod.rs +0 -24
  42. package/contracts/oapps/console-oft/src/tests/extensions/mod.rs +0 -3
  43. package/contracts/oapps/console-oft/src/tests/extensions/oft_fee.rs +0 -255
  44. package/contracts/oapps/console-oft/src/tests/extensions/pausable.rs +0 -212
  45. package/contracts/oapps/console-oft/src/tests/extensions/rate_limiter.rs +0 -992
  46. package/contracts/oapps/console-oft/src/tests/mod.rs +0 -2
  47. package/contracts/oapps/console-oft/src/tests/oft_types/lock_unlock.rs +0 -185
  48. 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
- }