@layerzerolabs/protocol-stellar-v2 0.2.18 → 0.2.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +303 -253
- package/.turbo/turbo-lint.log +66 -65
- package/.turbo/turbo-test.log +1312 -1282
- package/Cargo.lock +21 -8
- package/Cargo.toml +2 -0
- package/contracts/ERROR_SPEC.md +9 -2
- package/contracts/common-macros/src/contract_ttl.rs +18 -7
- package/contracts/common-macros/src/lib.rs +4 -4
- package/contracts/common-macros/src/tests/contract_ttl.rs +1 -1
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contractimpl_code.snap +2 -1
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +7 -12
- package/contracts/common-macros/src/upgradeable.rs +15 -21
- package/contracts/message-libs/uln-302/src/events.rs +4 -0
- package/contracts/message-libs/uln-302/src/send_uln.rs +23 -7
- package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +38 -64
- package/contracts/oapps/counter/Cargo.toml +1 -0
- package/contracts/oapps/counter/integration_tests/setup_uln.rs +1 -1
- package/contracts/oapps/oapp/src/oapp_receiver.rs +1 -1
- package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +113 -65
- package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +111 -82
- package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +293 -65
- package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +331 -56
- package/contracts/oapps/oft/Cargo.toml +10 -7
- package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/test_oft_fee.rs +3 -4
- package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/test_pausable.rs +2 -3
- package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/test_rate_limiter.rs +1 -1
- package/contracts/oapps/oft/integration-tests/mod.rs +1 -1
- package/contracts/oapps/oft/integration-tests/setup.rs +28 -127
- package/contracts/oapps/oft/integration-tests/utils.rs +254 -21
- package/contracts/oapps/oft/src/extensions/oft_fee.rs +23 -8
- package/contracts/oapps/oft/src/extensions/pausable.rs +19 -4
- package/contracts/oapps/oft/src/extensions/rate_limiter.rs +52 -28
- package/contracts/oapps/oft/src/lib.rs +10 -14
- package/contracts/oapps/oft/src/oft.rs +143 -193
- package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +9 -11
- package/contracts/oapps/oft/src/oft_types/mint_burn.rs +12 -14
- package/contracts/oapps/oft/src/oft_types/mod.rs +13 -0
- package/contracts/oapps/{oft-std → oft-core}/Cargo.toml +6 -4
- package/contracts/oapps/{oft-std → oft-core}/integration-tests/mod.rs +1 -1
- package/contracts/oapps/{oft-std → oft-core}/integration-tests/setup.rs +126 -29
- package/contracts/oapps/{oft → oft-core}/integration-tests/test_with_sml.rs +3 -3
- package/contracts/oapps/oft-core/integration-tests/utils.rs +201 -0
- package/contracts/oapps/oft-core/src/lib.rs +18 -0
- package/contracts/oapps/oft-core/src/oft_core.rs +479 -0
- package/contracts/oapps/{oft → oft-core}/src/tests/mod.rs +0 -2
- package/contracts/oapps/{oft → oft-core}/src/tests/test_lz_receive.rs +7 -7
- package/contracts/oapps/{oft → oft-core}/src/tests/test_oft_msg_codec.rs +4 -4
- package/contracts/oapps/{oft → oft-core}/src/tests/test_resolve_address.rs +3 -3
- package/contracts/oapps/{oft → oft-core}/src/tests/test_utils.rs +46 -27
- package/contracts/oapps/{oft → oft-core}/src/utils.rs +1 -1
- package/contracts/upgrader/src/lib.rs +30 -57
- package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract1.wasm +0 -0
- package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract2.wasm +0 -0
- package/contracts/upgrader/src/tests/test_upgrader.rs +44 -35
- package/contracts/utils/src/buffer_reader.rs +1 -0
- package/contracts/utils/src/errors.rs +8 -2
- package/contracts/utils/src/ownable.rs +125 -3
- package/contracts/utils/src/tests/option_ext.rs +1 -1
- package/contracts/utils/src/tests/ownable.rs +445 -7
- package/contracts/utils/src/tests/ttl_configurable.rs +2 -2
- package/contracts/utils/src/tests/upgradeable.rs +372 -175
- package/contracts/utils/src/ttl_configurable.rs +3 -3
- package/contracts/utils/src/upgradeable.rs +48 -23
- package/contracts/workers/dvn/Cargo.toml +1 -0
- package/contracts/workers/dvn/src/auth.rs +12 -42
- package/contracts/workers/dvn/src/dvn.rs +16 -31
- package/contracts/workers/dvn/src/errors.rs +0 -1
- package/contracts/workers/dvn/src/interfaces/dvn.rs +35 -0
- package/contracts/workers/dvn/src/lib.rs +4 -3
- package/contracts/workers/dvn/src/tests/auth.rs +1 -1
- package/contracts/workers/dvn/src/tests/dvn.rs +19 -15
- package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +2 -4
- package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +1 -3
- package/contracts/workers/dvn/src/tests/setup.rs +5 -9
- package/contracts/workers/dvn-fee-lib/Cargo.toml +1 -1
- package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +3 -5
- package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +2 -3
- package/contracts/workers/executor/Cargo.toml +1 -0
- package/contracts/workers/executor/src/executor.rs +15 -26
- package/contracts/workers/executor-fee-lib/Cargo.toml +2 -1
- package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +63 -5
- package/contracts/workers/executor-fee-lib/src/executor_option.rs +28 -1
- package/contracts/workers/executor-fee-lib/src/lib.rs +3 -0
- package/contracts/workers/executor-fee-lib/src/tests/executor_fee_lib.rs +701 -0
- package/contracts/workers/executor-fee-lib/src/tests/executor_option.rs +370 -0
- package/contracts/workers/executor-fee-lib/src/tests/mod.rs +4 -0
- package/contracts/workers/executor-fee-lib/src/tests/setup.rs +60 -0
- package/contracts/workers/executor-helper/src/lib.rs +3 -0
- package/contracts/workers/executor-helper/src/tests/executor_helper.rs +184 -0
- package/contracts/workers/executor-helper/src/tests/mod.rs +2 -0
- package/contracts/workers/executor-helper/src/tests/setup.rs +366 -0
- package/contracts/workers/fee-lib-interfaces/Cargo.toml +14 -0
- package/contracts/workers/{worker/src/interfaces/mod.rs → fee-lib-interfaces/src/lib.rs} +4 -3
- package/contracts/workers/price-feed/Cargo.toml +2 -1
- package/contracts/workers/price-feed/src/events.rs +1 -1
- package/contracts/workers/price-feed/src/lib.rs +3 -0
- package/contracts/workers/price-feed/src/price_feed.rs +6 -12
- package/contracts/workers/price-feed/src/storage.rs +1 -1
- package/contracts/workers/price-feed/src/tests/mod.rs +2 -0
- package/contracts/workers/price-feed/src/tests/price_feed.rs +869 -0
- package/contracts/workers/price-feed/src/tests/setup.rs +70 -0
- package/contracts/workers/price-feed/src/types.rs +1 -1
- package/contracts/workers/worker/src/errors.rs +0 -3
- package/contracts/workers/worker/src/lib.rs +0 -2
- package/contracts/workers/worker/src/storage.rs +32 -29
- package/contracts/workers/worker/src/tests/setup.rs +1 -7
- package/contracts/workers/worker/src/tests/worker.rs +50 -42
- package/contracts/workers/worker/src/worker.rs +49 -58
- package/package.json +4 -5
- package/sdk/.turbo/turbo-test.log +229 -217
- package/sdk/dist/generated/bml.d.ts +39 -1
- package/sdk/dist/generated/bml.js +33 -8
- package/sdk/dist/generated/counter.d.ts +131 -3
- package/sdk/dist/generated/counter.js +41 -10
- package/sdk/dist/generated/dvn.d.ts +431 -362
- package/sdk/dist/generated/dvn.js +80 -55
- package/sdk/dist/generated/dvn_fee_lib.d.ts +327 -251
- package/sdk/dist/generated/dvn_fee_lib.js +55 -57
- package/sdk/dist/generated/endpoint.d.ts +131 -3
- package/sdk/dist/generated/endpoint.js +41 -10
- package/sdk/dist/generated/executor.d.ts +503 -339
- package/sdk/dist/generated/executor.js +80 -48
- package/sdk/dist/generated/executor_fee_lib.d.ts +395 -319
- package/sdk/dist/generated/executor_fee_lib.js +54 -56
- package/sdk/dist/generated/executor_helper.d.ts +53 -187
- package/sdk/dist/generated/executor_helper.js +47 -29
- package/sdk/dist/generated/layerzero_view.d.ts +1271 -0
- package/sdk/dist/generated/layerzero_view.js +294 -0
- package/sdk/dist/generated/oft.d.ts +1851 -0
- package/sdk/dist/generated/oft.js +347 -0
- package/sdk/dist/generated/price_feed.d.ts +329 -253
- package/sdk/dist/generated/price_feed.js +55 -57
- package/sdk/dist/generated/sml.d.ts +131 -3
- package/sdk/dist/generated/sml.js +41 -10
- package/sdk/dist/generated/treasury.d.ts +131 -3
- package/sdk/dist/generated/treasury.js +41 -10
- package/sdk/dist/generated/uln302.d.ts +131 -3
- package/sdk/dist/generated/uln302.js +43 -12
- package/sdk/dist/generated/upgrader.d.ts +201 -15
- package/sdk/dist/generated/upgrader.js +99 -1
- package/sdk/dist/index.d.ts +2 -2
- package/sdk/dist/index.js +3 -3
- package/sdk/package.json +3 -2
- package/sdk/src/index.ts +3 -3
- package/sdk/test/oft-sml.test.ts +20 -20
- package/sdk/test/upgrader.test.ts +2 -3
- package/sdk/turbo.json +8 -0
- package/tools/ts-bindings-gen/Cargo.toml +2 -0
- package/tools/ts-bindings-gen/src/main.rs +53 -5
- package/turbo.json +0 -2
- package/contracts/oapps/oft/src/interfaces/mint_burn_token.rs +0 -23
- package/contracts/oapps/oft/src/interfaces/mod.rs +0 -3
- package/contracts/oapps/oft/src/oft_impl.rs +0 -201
- package/contracts/oapps/oft/src/tests/extensions/mod.rs +0 -11
- package/contracts/oapps/oft/src/tests/extensions/setup.rs +0 -917
- package/contracts/oapps/oft/src/tests/extensions/test_oft_fee.rs +0 -751
- package/contracts/oapps/oft/src/tests/extensions/test_pausable.rs +0 -434
- package/contracts/oapps/oft/src/tests/extensions/test_rate_limiter.rs +0 -1080
- package/contracts/oapps/oft-std/integration-tests/utils.rs +0 -427
- package/contracts/oapps/oft-std/src/lib.rs +0 -16
- package/contracts/oapps/oft-std/src/oft.rs +0 -174
- package/sdk/dist/generated/oft_std.d.ts +0 -1722
- package/sdk/dist/generated/oft_std.js +0 -316
- package/sdk/dist/wasm/blocked-message-lib.d.ts +0 -1
- package/sdk/dist/wasm/blocked-message-lib.js +0 -2
- package/sdk/dist/wasm/counter.d.ts +0 -1
- package/sdk/dist/wasm/counter.js +0 -2
- package/sdk/dist/wasm/dvn-fee-lib.d.ts +0 -1
- package/sdk/dist/wasm/dvn-fee-lib.js +0 -2
- package/sdk/dist/wasm/dvn.d.ts +0 -1
- package/sdk/dist/wasm/dvn.js +0 -2
- package/sdk/dist/wasm/endpoint-v2.d.ts +0 -1
- package/sdk/dist/wasm/endpoint-v2.js +0 -2
- package/sdk/dist/wasm/executor-fee-lib.d.ts +0 -1
- package/sdk/dist/wasm/executor-fee-lib.js +0 -2
- package/sdk/dist/wasm/executor-helper.d.ts +0 -1
- package/sdk/dist/wasm/executor-helper.js +0 -2
- package/sdk/dist/wasm/executor.d.ts +0 -1
- package/sdk/dist/wasm/executor.js +0 -2
- package/sdk/dist/wasm/layerzero-views.d.ts +0 -1
- package/sdk/dist/wasm/layerzero-views.js +0 -2
- package/sdk/dist/wasm/oft-std.d.ts +0 -1
- package/sdk/dist/wasm/oft-std.js +0 -2
- package/sdk/dist/wasm/price-feed.d.ts +0 -1
- package/sdk/dist/wasm/price-feed.js +0 -2
- package/sdk/dist/wasm/simple-message-lib.d.ts +0 -1
- package/sdk/dist/wasm/simple-message-lib.js +0 -2
- package/sdk/dist/wasm/treasury.d.ts +0 -1
- package/sdk/dist/wasm/treasury.js +0 -2
- package/sdk/dist/wasm/uln302.d.ts +0 -1
- package/sdk/dist/wasm/uln302.js +0 -2
- package/sdk/dist/wasm/upgrader.d.ts +0 -1
- package/sdk/dist/wasm/upgrader.js +0 -2
- package/sdk/dist/wasm.d.ts +0 -15
- package/sdk/dist/wasm.js +0 -15
- /package/contracts/oapps/{oft-std → oft}/integration-tests/extensions/mod.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/codec/mod.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/codec/oft_compose_msg_codec.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/codec/oft_msg_codec.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/errors.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/events.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/storage.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_decimals.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_oft_compose_msg_codec.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_oft_version.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_quote_oft.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_quote_send.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_send.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/tests/test_token.rs +0 -0
- /package/contracts/oapps/{oft → oft-core}/src/types.rs +0 -0
- /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/dvn_fee_lib.rs +0 -0
- /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/executor_fee_lib.rs +0 -0
- /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/price_feed.rs +0 -0
|
@@ -1,141 +1,39 @@
|
|
|
1
|
-
//! Integration test setup for OFT.
|
|
1
|
+
//! Integration test setup for OFT-STD with real EndpointV2 and SimpleMessageLib.
|
|
2
2
|
//!
|
|
3
|
-
//! This file contains
|
|
3
|
+
//! This file contains test setup utilities for OFT-STD with all extensions enabled.
|
|
4
4
|
|
|
5
|
-
extern crate self as oft;
|
|
6
5
|
extern crate std;
|
|
7
6
|
|
|
8
|
-
use crate::
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
use oft::{
|
|
13
|
-
initialize_oft,
|
|
14
|
-
oft::{OFTClient, OFTInternal, OFT},
|
|
15
|
-
oft_impl,
|
|
16
|
-
storage::OFTStorage,
|
|
17
|
-
types::OFTReceipt,
|
|
7
|
+
use crate::{
|
|
8
|
+
integration_tests::utils::{address_to_peer_bytes32, peer_bytes32_to_address},
|
|
9
|
+
oft::{OFTClient, OFT},
|
|
10
|
+
oft_types::OftType,
|
|
18
11
|
};
|
|
12
|
+
use endpoint_v2::{EndpointV2, EndpointV2Client};
|
|
19
13
|
use simple_message_lib::{SimpleMessageLib, SimpleMessageLibClient};
|
|
20
14
|
use soroban_sdk::{
|
|
21
|
-
contract, contractimpl,
|
|
15
|
+
contract, contractimpl, log,
|
|
22
16
|
testutils::{Address as _, MockAuth, MockAuthInvoke},
|
|
23
|
-
token::
|
|
24
|
-
Address,
|
|
17
|
+
token::TokenClient,
|
|
18
|
+
Address, BytesN, Env, IntoVal,
|
|
25
19
|
};
|
|
26
20
|
|
|
27
21
|
// ============================================================================
|
|
28
|
-
//
|
|
22
|
+
// Dummy Recipient - used to create valid contract addresses for recipients
|
|
29
23
|
// ============================================================================
|
|
30
24
|
|
|
31
|
-
#[oapp_macros::oapp]
|
|
32
|
-
pub struct TestOFT;
|
|
33
|
-
|
|
34
|
-
impl LzReceiveInternal for TestOFT {
|
|
35
|
-
fn __lz_receive(
|
|
36
|
-
env: &Env,
|
|
37
|
-
origin: &Origin,
|
|
38
|
-
guid: &BytesN<32>,
|
|
39
|
-
message: &Bytes,
|
|
40
|
-
extra_data: &Bytes,
|
|
41
|
-
executor: &Address,
|
|
42
|
-
value: i128,
|
|
43
|
-
) {
|
|
44
|
-
oft_impl::lz_receive::<Self>(env, executor, origin, guid, message, extra_data, value)
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
#[contract_impl]
|
|
49
|
-
impl TestOFT {
|
|
50
|
-
pub fn __constructor(
|
|
51
|
-
env: &Env,
|
|
52
|
-
token: &Address,
|
|
53
|
-
owner: &Address,
|
|
54
|
-
endpoint: &Address,
|
|
55
|
-
delegate: &Option<Address>,
|
|
56
|
-
shared_decimals: u32,
|
|
57
|
-
) {
|
|
58
|
-
initialize_oft::<Self>(env, owner, token, endpoint, delegate, shared_decimals)
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
#[contractimpl(contracttrait)]
|
|
63
|
-
impl OFT for TestOFT {}
|
|
64
|
-
|
|
65
|
-
impl OFTInternal for TestOFT {
|
|
66
|
-
fn __debit(env: &Env, sender: &Address, amount_ld: i128, min_amount_ld: i128, dst_eid: u32) -> OFTReceipt {
|
|
67
|
-
// Get the receipt (handles decimal conversion, fees, etc.)
|
|
68
|
-
let receipt = Self::__debit_view(env, amount_ld, min_amount_ld, dst_eid);
|
|
69
|
-
// Actually burn tokens from sender
|
|
70
|
-
StellarAssetClient::new(env, &OFTStorage::token(env).unwrap()).burn(sender, &receipt.amount_sent_ld);
|
|
71
|
-
receipt
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
fn __credit(env: &Env, to: &Address, amount_ld: i128, _src_eid: u32) -> i128 {
|
|
75
|
-
// Actually mint tokens to recipient
|
|
76
|
-
StellarAssetClient::new(env, &OFTStorage::token(env).unwrap()).mint(to, &amount_ld);
|
|
77
|
-
amount_ld
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// ============================================================================
|
|
82
|
-
// Dummy Composer for testing compose messages
|
|
83
|
-
// ============================================================================
|
|
84
|
-
|
|
85
|
-
#[contracttype]
|
|
86
|
-
pub struct ComposeMessage {
|
|
87
|
-
pub executor: Address,
|
|
88
|
-
pub from: Address,
|
|
89
|
-
pub guid: BytesN<32>,
|
|
90
|
-
pub index: u32,
|
|
91
|
-
pub message: Bytes,
|
|
92
|
-
pub extra_data: Bytes,
|
|
93
|
-
pub value: i128,
|
|
94
|
-
}
|
|
95
|
-
|
|
96
25
|
#[contract]
|
|
97
|
-
pub struct
|
|
26
|
+
pub struct DummyRecipient;
|
|
98
27
|
|
|
99
|
-
#[
|
|
100
|
-
impl
|
|
101
|
-
pub fn __constructor(
|
|
102
|
-
env.storage().instance().set(&symbol_short!("endpoint"), endpoint);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
pub fn compose_message(env: &Env) -> Option<ComposeMessage> {
|
|
106
|
-
env.storage().instance().get(&symbol_short!("msg"))
|
|
107
|
-
}
|
|
28
|
+
#[contractimpl]
|
|
29
|
+
impl DummyRecipient {
|
|
30
|
+
pub fn __constructor(_env: &Env) {}
|
|
108
31
|
}
|
|
109
32
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
executor: &Address,
|
|
115
|
-
from: &Address,
|
|
116
|
-
guid: &BytesN<32>,
|
|
117
|
-
index: u32,
|
|
118
|
-
message: &Bytes,
|
|
119
|
-
extra_data: &Bytes,
|
|
120
|
-
value: i128,
|
|
121
|
-
) {
|
|
122
|
-
let endpoint_address: Address = env.storage().instance().get(&symbol_short!("endpoint")).unwrap();
|
|
123
|
-
let endpoint = endpoint_v2::MessagingComposerClient::new(env, &endpoint_address);
|
|
124
|
-
endpoint.clear_compose(&env.current_contract_address(), from, guid, &index, message);
|
|
125
|
-
|
|
126
|
-
env.storage().instance().set(
|
|
127
|
-
&symbol_short!("msg"),
|
|
128
|
-
&ComposeMessage {
|
|
129
|
-
executor: executor.clone(),
|
|
130
|
-
from: from.clone(),
|
|
131
|
-
guid: guid.clone(),
|
|
132
|
-
index,
|
|
133
|
-
message: message.clone(),
|
|
134
|
-
extra_data: extra_data.clone(),
|
|
135
|
-
value,
|
|
136
|
-
},
|
|
137
|
-
);
|
|
138
|
-
}
|
|
33
|
+
/// Creates a valid recipient address by deploying a dummy contract.
|
|
34
|
+
/// Use this in tests when the address needs to pass the `.exists()` check.
|
|
35
|
+
pub fn create_recipient_address(env: &Env) -> Address {
|
|
36
|
+
env.register(DummyRecipient, ())
|
|
139
37
|
}
|
|
140
38
|
|
|
141
39
|
// ============================================================================
|
|
@@ -146,16 +44,16 @@ pub struct ChainSetup<'a> {
|
|
|
146
44
|
pub eid: u32,
|
|
147
45
|
pub owner: Address,
|
|
148
46
|
pub native_token: Address,
|
|
47
|
+
pub zro_token: Address,
|
|
149
48
|
pub oft_token: Address,
|
|
150
49
|
pub endpoint: EndpointV2Client<'a>,
|
|
151
50
|
pub sml: SimpleMessageLibClient<'a>,
|
|
152
51
|
pub oft: OFTClient<'a>,
|
|
153
|
-
pub
|
|
52
|
+
pub fee_collector: Address,
|
|
154
53
|
}
|
|
155
54
|
|
|
156
55
|
pub struct TestSetup<'a> {
|
|
157
56
|
pub env: Env,
|
|
158
|
-
|
|
159
57
|
pub chain_a: ChainSetup<'a>,
|
|
160
58
|
pub chain_b: ChainSetup<'a>,
|
|
161
59
|
}
|
|
@@ -163,9 +61,13 @@ pub struct TestSetup<'a> {
|
|
|
163
61
|
fn setup_chain<'a>(env: &Env) -> ChainSetup<'a> {
|
|
164
62
|
let owner = Address::generate(env);
|
|
165
63
|
|
|
64
|
+
// Create native token FIRST - this must match the endpoint's NATIVE_TOKEN constant
|
|
166
65
|
let sac = env.register_stellar_asset_contract_v2(owner.clone());
|
|
167
66
|
let native_token = sac.address();
|
|
168
67
|
|
|
68
|
+
// Generate fee_collector AFTER native_token to not affect the address derivation
|
|
69
|
+
let fee_collector = Address::generate(env);
|
|
70
|
+
|
|
169
71
|
// Create ZRO token
|
|
170
72
|
let zro_sac = env.register_stellar_asset_contract_v2(owner.clone());
|
|
171
73
|
let zro_token = zro_sac.address();
|
|
@@ -179,13 +81,12 @@ fn setup_chain<'a>(env: &Env) -> ChainSetup<'a> {
|
|
|
179
81
|
let sml_address = env.register(SimpleMessageLib, (&owner, &endpoint_address, &fee_recipient));
|
|
180
82
|
let delegate: Option<Address> = Some(owner.clone());
|
|
181
83
|
let shared_decimals: u32 = 6; // Default shared decimals
|
|
182
|
-
let
|
|
183
|
-
let
|
|
84
|
+
let mode = OftType::MintBurn;
|
|
85
|
+
let oft_address = env.register(OFT, (&oft_token, &owner, &endpoint_address, &delegate, &shared_decimals, &mode));
|
|
184
86
|
|
|
185
87
|
let endpoint = EndpointV2Client::new(env, &endpoint_address);
|
|
186
88
|
let sml = SimpleMessageLibClient::new(env, &sml_address);
|
|
187
89
|
let oft = OFTClient::new(env, &oft_address);
|
|
188
|
-
let composer = DummyComposerClient::new(env, &composer_address);
|
|
189
90
|
|
|
190
91
|
// Set ZRO token in endpoint
|
|
191
92
|
env.mock_auths(&[MockAuth {
|
|
@@ -202,7 +103,7 @@ fn setup_chain<'a>(env: &Env) -> ChainSetup<'a> {
|
|
|
202
103
|
register_library(env, &owner, &endpoint, &sml.address);
|
|
203
104
|
|
|
204
105
|
let eid = endpoint.eid();
|
|
205
|
-
ChainSetup { eid, owner, native_token, oft_token, endpoint, sml, oft,
|
|
106
|
+
ChainSetup { eid, owner, native_token, zro_token, oft_token, endpoint, sml, oft, fee_collector }
|
|
206
107
|
}
|
|
207
108
|
|
|
208
109
|
pub fn setup<'a>() -> TestSetup<'a> {
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
//! Utility functions for OFT-STD integration tests.
|
|
2
2
|
|
|
3
|
-
use crate::
|
|
4
|
-
|
|
5
|
-
integration_tests::setup::{decode_packet, ChainSetup},
|
|
6
|
-
types::{OFTFeeDetail, OFTLimit, OFTReceipt, SendParam},
|
|
7
|
-
};
|
|
3
|
+
use crate::extensions::rate_limiter::Direction;
|
|
4
|
+
use crate::integration_tests::setup::{decode_packet, ChainSetup};
|
|
8
5
|
use endpoint_v2::{MessagingFee, Origin, OutboundPacket};
|
|
9
6
|
use message_lib_common::packet_codec_v1;
|
|
7
|
+
use oft_core::types::{OFTFeeDetail, OFTLimit, OFTReceipt, SendParam};
|
|
10
8
|
use soroban_sdk::{
|
|
11
9
|
address_payload::AddressPayload,
|
|
12
|
-
testutils::{Events, MockAuth, MockAuthInvoke},
|
|
10
|
+
testutils::{Events, Ledger, MockAuth, MockAuthInvoke},
|
|
13
11
|
token::StellarAssetClient,
|
|
14
12
|
xdr::ToXdr,
|
|
15
13
|
Address, Bytes, BytesN, Env, IntoVal, Map, Symbol, Val, Vec,
|
|
16
14
|
};
|
|
17
15
|
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Address Conversion Utilities
|
|
18
|
+
// ============================================================================
|
|
19
|
+
|
|
18
20
|
pub fn address_to_peer_bytes32(address: &Address) -> BytesN<32> {
|
|
19
21
|
match address.to_payload().unwrap() {
|
|
20
22
|
AddressPayload::ContractIdHash(payload) => payload,
|
|
@@ -26,6 +28,16 @@ pub fn peer_bytes32_to_address(env: &Env, bytes32: &BytesN<32>) -> Address {
|
|
|
26
28
|
AddressPayload::ContractIdHash(bytes32.clone()).to_address(env)
|
|
27
29
|
}
|
|
28
30
|
|
|
31
|
+
#[allow(dead_code)]
|
|
32
|
+
pub fn create_recipient_address(env: &Env) -> Address {
|
|
33
|
+
let bytes = BytesN::from_array(env, &[0u8; 32]);
|
|
34
|
+
peer_bytes32_to_address(env, &bytes)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// OFT Core Operations
|
|
39
|
+
// ============================================================================
|
|
40
|
+
|
|
29
41
|
pub fn quote_oft(chain: &ChainSetup<'_>, send_param: &SendParam) -> (OFTLimit, Vec<OFTFeeDetail>, OFTReceipt) {
|
|
30
42
|
chain.oft.quote_oft(send_param)
|
|
31
43
|
}
|
|
@@ -49,6 +61,7 @@ pub fn quote_send(
|
|
|
49
61
|
chain.oft.quote_send(sender, send_param, &pay_in_zro)
|
|
50
62
|
}
|
|
51
63
|
|
|
64
|
+
/// Send without fee (standard OFT send)
|
|
52
65
|
pub fn send(
|
|
53
66
|
env: &Env,
|
|
54
67
|
chain: &ChainSetup<'_>,
|
|
@@ -83,6 +96,88 @@ pub fn send(
|
|
|
83
96
|
chain.oft.send(sender, send_param, fee, refund_address);
|
|
84
97
|
}
|
|
85
98
|
|
|
99
|
+
/// Send with fee (OFT fee extension enabled)
|
|
100
|
+
/// Order: transfer fee to deposit -> burn tokens -> transfer native fee
|
|
101
|
+
pub fn send_with_fee(
|
|
102
|
+
env: &Env,
|
|
103
|
+
chain: &ChainSetup<'_>,
|
|
104
|
+
sender: &Address,
|
|
105
|
+
send_param: &SendParam,
|
|
106
|
+
fee: &MessagingFee,
|
|
107
|
+
refund_address: &Address,
|
|
108
|
+
oft_receipt: &OFTReceipt,
|
|
109
|
+
fee_deposit_address: &Address,
|
|
110
|
+
) {
|
|
111
|
+
let fee_amount = oft_receipt.amount_sent_ld - oft_receipt.amount_received_ld;
|
|
112
|
+
env.mock_auths(&[MockAuth {
|
|
113
|
+
address: sender,
|
|
114
|
+
invoke: &MockAuthInvoke {
|
|
115
|
+
contract: &chain.oft.address,
|
|
116
|
+
fn_name: "send",
|
|
117
|
+
args: (sender, send_param, fee, refund_address).into_val(env),
|
|
118
|
+
sub_invokes: &[
|
|
119
|
+
MockAuthInvoke {
|
|
120
|
+
contract: &chain.oft_token,
|
|
121
|
+
fn_name: "transfer",
|
|
122
|
+
args: (sender, fee_deposit_address, &fee_amount).into_val(env),
|
|
123
|
+
sub_invokes: &[],
|
|
124
|
+
},
|
|
125
|
+
MockAuthInvoke {
|
|
126
|
+
contract: &chain.oft_token,
|
|
127
|
+
fn_name: "burn",
|
|
128
|
+
args: (sender, &oft_receipt.amount_received_ld).into_val(env),
|
|
129
|
+
sub_invokes: &[],
|
|
130
|
+
},
|
|
131
|
+
MockAuthInvoke {
|
|
132
|
+
contract: &chain.native_token,
|
|
133
|
+
fn_name: "transfer",
|
|
134
|
+
args: (sender, &chain.endpoint.address, &fee.native_fee).into_val(env),
|
|
135
|
+
sub_invokes: &[],
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
}]);
|
|
140
|
+
chain.oft.send(sender, send_param, fee, refund_address);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
pub fn try_send(
|
|
144
|
+
env: &Env,
|
|
145
|
+
chain: &ChainSetup<'_>,
|
|
146
|
+
sender: &Address,
|
|
147
|
+
send_param: &SendParam,
|
|
148
|
+
fee: &MessagingFee,
|
|
149
|
+
refund_address: &Address,
|
|
150
|
+
oft_receipt: &OFTReceipt,
|
|
151
|
+
) -> bool {
|
|
152
|
+
env.mock_auths(&[MockAuth {
|
|
153
|
+
address: sender,
|
|
154
|
+
invoke: &MockAuthInvoke {
|
|
155
|
+
contract: &chain.oft.address,
|
|
156
|
+
fn_name: "send",
|
|
157
|
+
args: (sender, send_param, fee, refund_address).into_val(env),
|
|
158
|
+
sub_invokes: &[
|
|
159
|
+
MockAuthInvoke {
|
|
160
|
+
contract: &chain.native_token,
|
|
161
|
+
fn_name: "transfer",
|
|
162
|
+
args: (sender, &chain.endpoint.address, &fee.native_fee).into_val(env),
|
|
163
|
+
sub_invokes: &[],
|
|
164
|
+
},
|
|
165
|
+
MockAuthInvoke {
|
|
166
|
+
contract: &chain.oft_token,
|
|
167
|
+
fn_name: "burn",
|
|
168
|
+
args: (sender, &oft_receipt.amount_received_ld).into_val(env),
|
|
169
|
+
sub_invokes: &[],
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
},
|
|
173
|
+
}]);
|
|
174
|
+
chain.oft.try_send(sender, send_param, fee, refund_address).is_ok()
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ============================================================================
|
|
178
|
+
// Packet Handling
|
|
179
|
+
// ============================================================================
|
|
180
|
+
|
|
86
181
|
pub fn validate_packet(env: &Env, chain: &ChainSetup<'_>, packet_event: &(Bytes, Bytes, Address)) {
|
|
87
182
|
let packet = decode_packet(env, &packet_event.0);
|
|
88
183
|
let encoded_header = packet_codec_v1::encode_packet_header(env, &packet);
|
|
@@ -131,26 +226,30 @@ pub fn lz_receive(
|
|
|
131
226
|
);
|
|
132
227
|
}
|
|
133
228
|
|
|
134
|
-
pub fn
|
|
229
|
+
pub fn try_lz_receive(
|
|
135
230
|
env: &Env,
|
|
136
231
|
chain: &ChainSetup<'_>,
|
|
137
232
|
executor: &Address,
|
|
138
233
|
packet: &OutboundPacket,
|
|
139
|
-
|
|
140
|
-
extra_data: &Bytes,
|
|
234
|
+
recipient: &Address,
|
|
141
235
|
value: i128,
|
|
142
|
-
) {
|
|
143
|
-
let
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
src_eid: packet.src_eid,
|
|
147
|
-
amount_ld: (oft_msg.amount_sd as i128).mul(chain.oft.decimal_conversion_rate()),
|
|
148
|
-
compose_from: oft_msg.compose_from.unwrap(),
|
|
149
|
-
compose_msg: oft_msg.compose_msg.unwrap(),
|
|
150
|
-
}
|
|
151
|
-
.encode(&env);
|
|
236
|
+
) -> bool {
|
|
237
|
+
let origin =
|
|
238
|
+
Origin { src_eid: packet.src_eid, sender: address_to_peer_bytes32(&packet.sender), nonce: packet.nonce };
|
|
239
|
+
let extra_options = recipient.to_xdr(env);
|
|
152
240
|
|
|
153
|
-
|
|
241
|
+
env.mock_auths(&[MockAuth {
|
|
242
|
+
address: executor,
|
|
243
|
+
invoke: &MockAuthInvoke {
|
|
244
|
+
contract: &chain.oft.address,
|
|
245
|
+
fn_name: "lz_receive",
|
|
246
|
+
args: (executor, &origin, &packet.guid, &packet.message, &extra_options, &value).into_val(env),
|
|
247
|
+
sub_invokes: &[],
|
|
248
|
+
},
|
|
249
|
+
}]);
|
|
250
|
+
endpoint_v2::LayerZeroReceiverClient::new(env, &chain.oft.address)
|
|
251
|
+
.try_lz_receive(executor, &origin, &packet.guid, &packet.message, &extra_options, &value)
|
|
252
|
+
.is_ok()
|
|
154
253
|
}
|
|
155
254
|
|
|
156
255
|
// returns (encoded_payload, options, send_library)
|
|
@@ -172,6 +271,10 @@ pub fn scan_packet_sent_event(env: &Env, endpoint: &Address) -> Option<(Bytes, B
|
|
|
172
271
|
packet
|
|
173
272
|
}
|
|
174
273
|
|
|
274
|
+
// ============================================================================
|
|
275
|
+
// Token Operations
|
|
276
|
+
// ============================================================================
|
|
277
|
+
|
|
175
278
|
pub fn mint_to(env: &Env, owner: &Address, token: &Address, to: &Address, amount: i128) {
|
|
176
279
|
env.mock_auths(&[MockAuth {
|
|
177
280
|
address: owner,
|
|
@@ -199,3 +302,133 @@ pub fn transfer_sac_admin(env: &Env, owner: &Address, token: &Address, new_admin
|
|
|
199
302
|
}]);
|
|
200
303
|
StellarAssetClient::new(env, token).set_admin(new_admin);
|
|
201
304
|
}
|
|
305
|
+
|
|
306
|
+
pub fn token_balance(env: &Env, token: &Address, account: &Address) -> i128 {
|
|
307
|
+
soroban_sdk::token::TokenClient::new(env, token).balance(account)
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// ============================================================================
|
|
311
|
+
// Pausable Extension Operations
|
|
312
|
+
// ============================================================================
|
|
313
|
+
|
|
314
|
+
pub fn set_paused(env: &Env, chain: &ChainSetup<'_>, paused: bool) {
|
|
315
|
+
env.mock_auths(&[MockAuth {
|
|
316
|
+
address: &chain.owner,
|
|
317
|
+
invoke: &MockAuthInvoke {
|
|
318
|
+
contract: &chain.oft.address,
|
|
319
|
+
fn_name: "set_paused",
|
|
320
|
+
args: (&paused,).into_val(env),
|
|
321
|
+
sub_invokes: &[],
|
|
322
|
+
},
|
|
323
|
+
}]);
|
|
324
|
+
chain.oft.set_paused(&paused);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
pub fn is_paused(chain: &ChainSetup<'_>) -> bool {
|
|
328
|
+
chain.oft.is_paused()
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// ============================================================================
|
|
332
|
+
// OFT Fee Extension Operations
|
|
333
|
+
// ============================================================================
|
|
334
|
+
|
|
335
|
+
pub fn set_fee_deposit_address(env: &Env, chain: &ChainSetup<'_>, deposit_address: &Address) {
|
|
336
|
+
env.mock_auths(&[MockAuth {
|
|
337
|
+
address: &chain.owner,
|
|
338
|
+
invoke: &MockAuthInvoke {
|
|
339
|
+
contract: &chain.oft.address,
|
|
340
|
+
fn_name: "set_fee_deposit_address",
|
|
341
|
+
args: (deposit_address,).into_val(env),
|
|
342
|
+
sub_invokes: &[],
|
|
343
|
+
},
|
|
344
|
+
}]);
|
|
345
|
+
chain.oft.set_fee_deposit_address(deposit_address);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
pub fn set_default_fee_bps(env: &Env, chain: &ChainSetup<'_>, fee_bps: u64) {
|
|
349
|
+
env.mock_auths(&[MockAuth {
|
|
350
|
+
address: &chain.owner,
|
|
351
|
+
invoke: &MockAuthInvoke {
|
|
352
|
+
contract: &chain.oft.address,
|
|
353
|
+
fn_name: "set_default_fee_bps",
|
|
354
|
+
args: (&fee_bps,).into_val(env),
|
|
355
|
+
sub_invokes: &[],
|
|
356
|
+
},
|
|
357
|
+
}]);
|
|
358
|
+
chain.oft.set_default_fee_bps(&fee_bps);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
pub fn set_fee_bps(env: &Env, chain: &ChainSetup<'_>, dst_eid: u32, fee_bps: u64) {
|
|
362
|
+
env.mock_auths(&[MockAuth {
|
|
363
|
+
address: &chain.owner,
|
|
364
|
+
invoke: &MockAuthInvoke {
|
|
365
|
+
contract: &chain.oft.address,
|
|
366
|
+
fn_name: "set_fee_bps",
|
|
367
|
+
args: (&dst_eid, &fee_bps).into_val(env),
|
|
368
|
+
sub_invokes: &[],
|
|
369
|
+
},
|
|
370
|
+
}]);
|
|
371
|
+
chain.oft.set_fee_bps(&dst_eid, &fee_bps);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// ============================================================================
|
|
375
|
+
// Rate Limiter Extension Operations
|
|
376
|
+
// ============================================================================
|
|
377
|
+
|
|
378
|
+
pub fn set_rate_limit(
|
|
379
|
+
env: &Env,
|
|
380
|
+
chain: &ChainSetup<'_>,
|
|
381
|
+
direction: &Direction,
|
|
382
|
+
dst_eid: u32,
|
|
383
|
+
limit: i128,
|
|
384
|
+
window_seconds: u64,
|
|
385
|
+
) {
|
|
386
|
+
env.mock_auths(&[MockAuth {
|
|
387
|
+
address: &chain.owner,
|
|
388
|
+
invoke: &MockAuthInvoke {
|
|
389
|
+
contract: &chain.oft.address,
|
|
390
|
+
fn_name: "set_rate_limit",
|
|
391
|
+
args: (direction, &dst_eid, &limit, &window_seconds).into_val(env),
|
|
392
|
+
sub_invokes: &[],
|
|
393
|
+
},
|
|
394
|
+
}]);
|
|
395
|
+
chain.oft.set_rate_limit(direction, &dst_eid, &limit, &window_seconds);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
pub fn rate_limit_capacity(chain: &ChainSetup<'_>, direction: &Direction, eid: u32) -> i128 {
|
|
399
|
+
chain.oft.rate_limit_capacity(direction, &eid)
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
pub fn rate_limit_in_flight(chain: &ChainSetup<'_>, direction: &Direction, eid: u32) -> i128 {
|
|
403
|
+
chain.oft.rate_limit_in_flight(direction, &eid)
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// ============================================================================
|
|
407
|
+
// Time Utilities
|
|
408
|
+
// ============================================================================
|
|
409
|
+
|
|
410
|
+
pub fn advance_time(env: &Env, seconds: u64) {
|
|
411
|
+
let current = env.ledger().timestamp();
|
|
412
|
+
env.ledger().set_timestamp(current + seconds);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
#[allow(dead_code)]
|
|
416
|
+
pub fn set_timestamp(env: &Env, timestamp: u64) {
|
|
417
|
+
env.ledger().set_timestamp(timestamp);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// ============================================================================
|
|
421
|
+
// SendParam Builder
|
|
422
|
+
// ============================================================================
|
|
423
|
+
|
|
424
|
+
pub fn create_send_param(env: &Env, dst_eid: u32, amount_ld: i128, min_amount_ld: i128, to: &BytesN<32>) -> SendParam {
|
|
425
|
+
SendParam {
|
|
426
|
+
dst_eid,
|
|
427
|
+
to: to.clone(),
|
|
428
|
+
amount_ld,
|
|
429
|
+
min_amount_ld,
|
|
430
|
+
extra_options: Bytes::new(env),
|
|
431
|
+
compose_msg: Bytes::new(env),
|
|
432
|
+
oft_cmd: Bytes::new(env),
|
|
433
|
+
}
|
|
434
|
+
}
|
|
@@ -6,6 +6,10 @@ use utils::{option_ext::OptionExt, ownable::Ownable};
|
|
|
6
6
|
/// Used as denominator in fee calculations
|
|
7
7
|
const BASE_FEE_BPS: u64 = 10_000;
|
|
8
8
|
|
|
9
|
+
// =========================================================================
|
|
10
|
+
// Storage
|
|
11
|
+
// =========================================================================
|
|
12
|
+
|
|
9
13
|
#[storage]
|
|
10
14
|
pub enum OFTFeeStorage {
|
|
11
15
|
#[instance(u64)]
|
|
@@ -19,14 +23,22 @@ pub enum OFTFeeStorage {
|
|
|
19
23
|
FeeDepositAddress,
|
|
20
24
|
}
|
|
21
25
|
|
|
26
|
+
// =========================================================================
|
|
27
|
+
// Errors
|
|
28
|
+
// =========================================================================
|
|
29
|
+
|
|
22
30
|
#[contract_error]
|
|
23
31
|
pub enum OFTFeeError {
|
|
24
|
-
InvalidFeeBps =
|
|
32
|
+
InvalidFeeBps = 3100,
|
|
25
33
|
InvalidFeeDepositAddress,
|
|
26
34
|
NotFound,
|
|
27
35
|
SameValue,
|
|
28
36
|
}
|
|
29
37
|
|
|
38
|
+
// =========================================================================
|
|
39
|
+
// Events
|
|
40
|
+
// =========================================================================
|
|
41
|
+
|
|
30
42
|
#[contractevent]
|
|
31
43
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
32
44
|
pub struct DefaultFeeBpsSet {
|
|
@@ -52,8 +64,12 @@ pub struct FeeDepositAddressSet {
|
|
|
52
64
|
pub fee_deposit_address: Address,
|
|
53
65
|
}
|
|
54
66
|
|
|
67
|
+
// =========================================================================
|
|
68
|
+
// Trait With Default Implementations
|
|
69
|
+
// =========================================================================
|
|
70
|
+
|
|
55
71
|
#[contract_trait]
|
|
56
|
-
pub trait OFTFee: OFTFeeInternal + Ownable
|
|
72
|
+
pub trait OFTFee: OFTFeeInternal + Ownable {
|
|
57
73
|
#[only_auth]
|
|
58
74
|
fn set_default_fee_bps(env: &Env, default_fee_bps: u64) {
|
|
59
75
|
assert_with_error!(env, default_fee_bps <= BASE_FEE_BPS, OFTFeeError::InvalidFeeBps);
|
|
@@ -118,15 +134,15 @@ pub trait OFTFee: OFTFeeInternal + Ownable + Sized {
|
|
|
118
134
|
/// Internal trait for OFT fee operations used by OFT hooks.
|
|
119
135
|
/// Contains only truly internal methods that are called from OFTInner implementations.
|
|
120
136
|
pub trait OFTFeeInternal {
|
|
121
|
-
/// Calculates the amount
|
|
122
|
-
/// Used internally by `__debit_view` to calculate
|
|
137
|
+
/// Calculates the fee amount for a given transfer (read-only).
|
|
138
|
+
/// Used internally by `__debit_view` to calculate the fee.
|
|
123
139
|
///
|
|
124
140
|
/// # Arguments
|
|
125
141
|
/// * `dst_eid` - Destination endpoint ID to determine which fee rate to apply
|
|
126
142
|
/// * `amount_ld` - The original amount in local decimals
|
|
127
143
|
///
|
|
128
144
|
/// # Returns
|
|
129
|
-
/// The
|
|
145
|
+
/// The fee amount to be deducted
|
|
130
146
|
fn __fee_view(env: &Env, dst_eid: u32, amount_ld: i128) -> i128 {
|
|
131
147
|
// Calculate effective fee (destination-specific or default)
|
|
132
148
|
let fee_bps = if OFTFeeStorage::has_fee_bps(env, dst_eid) {
|
|
@@ -135,7 +151,7 @@ pub trait OFTFeeInternal {
|
|
|
135
151
|
OFTFeeStorage::default_fee_bps(env)
|
|
136
152
|
};
|
|
137
153
|
if fee_bps == 0 {
|
|
138
|
-
return
|
|
154
|
+
return 0;
|
|
139
155
|
}
|
|
140
156
|
// Check that fee deposit address is set (required for fee collection)
|
|
141
157
|
assert_with_error!(
|
|
@@ -143,8 +159,7 @@ pub trait OFTFeeInternal {
|
|
|
143
159
|
OFTFeeStorage::fee_deposit_address(env).is_some(),
|
|
144
160
|
OFTFeeError::InvalidFeeDepositAddress
|
|
145
161
|
);
|
|
146
|
-
|
|
147
|
-
amount_ld - preliminary_fee
|
|
162
|
+
(amount_ld * fee_bps as i128) / BASE_FEE_BPS as i128
|
|
148
163
|
}
|
|
149
164
|
|
|
150
165
|
/// Charges the fee by transferring the fee amount from sender to the fee deposit address.
|
|
@@ -2,6 +2,10 @@ use common_macros::{contract_error, contract_trait, only_auth, storage};
|
|
|
2
2
|
use soroban_sdk::{assert_with_error, contractevent, Env};
|
|
3
3
|
use utils::ownable::Ownable;
|
|
4
4
|
|
|
5
|
+
// =========================================================================
|
|
6
|
+
// Storage
|
|
7
|
+
// =========================================================================
|
|
8
|
+
|
|
5
9
|
#[storage]
|
|
6
10
|
pub enum OFTPausableStorage {
|
|
7
11
|
#[instance(bool)]
|
|
@@ -9,24 +13,35 @@ pub enum OFTPausableStorage {
|
|
|
9
13
|
Paused,
|
|
10
14
|
}
|
|
11
15
|
|
|
16
|
+
// =========================================================================
|
|
17
|
+
// Errors
|
|
18
|
+
// =========================================================================
|
|
19
|
+
|
|
12
20
|
#[contract_error]
|
|
13
21
|
pub enum OFTPausableError {
|
|
14
|
-
Paused =
|
|
22
|
+
Paused = 3110,
|
|
15
23
|
PauseStatusUnchanged,
|
|
16
24
|
}
|
|
17
25
|
|
|
26
|
+
// =========================================================================
|
|
27
|
+
// Events
|
|
28
|
+
// =========================================================================
|
|
29
|
+
|
|
18
30
|
#[contractevent]
|
|
19
31
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
20
32
|
pub struct PausedSet {
|
|
21
33
|
pub paused: bool,
|
|
22
34
|
}
|
|
23
35
|
|
|
36
|
+
// =========================================================================
|
|
37
|
+
// Trait With Default Implementations
|
|
38
|
+
// =========================================================================
|
|
39
|
+
|
|
24
40
|
#[contract_trait]
|
|
25
|
-
pub trait OFTPausable: OFTPausableInternal + Ownable
|
|
41
|
+
pub trait OFTPausable: OFTPausableInternal + Ownable {
|
|
26
42
|
#[only_auth]
|
|
27
43
|
fn set_paused(env: &Env, paused: bool) {
|
|
28
|
-
|
|
29
|
-
assert_with_error!(env, current_paused != paused, OFTPausableError::PauseStatusUnchanged);
|
|
44
|
+
assert_with_error!(env, Self::is_paused(env) != paused, OFTPausableError::PauseStatusUnchanged);
|
|
30
45
|
OFTPausableStorage::set_paused(env, &paused);
|
|
31
46
|
PausedSet { paused }.publish(env);
|
|
32
47
|
}
|