@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,427 +0,0 @@
|
|
|
1
|
-
//! Utility functions for OFT-STD integration tests.
|
|
2
|
-
|
|
3
|
-
use crate::integration_tests::setup::{decode_packet, ChainSetup};
|
|
4
|
-
use endpoint_v2::{MessagingFee, Origin, OutboundPacket};
|
|
5
|
-
use message_lib_common::packet_codec_v1;
|
|
6
|
-
use oft::extensions::rate_limiter::Direction;
|
|
7
|
-
use oft::types::{OFTFeeDetail, OFTLimit, OFTReceipt, SendParam};
|
|
8
|
-
use soroban_sdk::{
|
|
9
|
-
address_payload::AddressPayload,
|
|
10
|
-
testutils::{Events, Ledger, MockAuth, MockAuthInvoke},
|
|
11
|
-
token::StellarAssetClient,
|
|
12
|
-
xdr::ToXdr,
|
|
13
|
-
Address, Bytes, BytesN, Env, IntoVal, Map, Symbol, Val, Vec,
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
// ============================================================================
|
|
17
|
-
// Address Conversion Utilities
|
|
18
|
-
// ============================================================================
|
|
19
|
-
|
|
20
|
-
pub fn address_to_peer_bytes32(address: &Address) -> BytesN<32> {
|
|
21
|
-
match address.to_payload().unwrap() {
|
|
22
|
-
AddressPayload::ContractIdHash(payload) => payload,
|
|
23
|
-
AddressPayload::AccountIdPublicKeyEd25519(_) => panic!("peer must be a contract"),
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
pub fn peer_bytes32_to_address(env: &Env, bytes32: &BytesN<32>) -> Address {
|
|
28
|
-
AddressPayload::ContractIdHash(bytes32.clone()).to_address(env)
|
|
29
|
-
}
|
|
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
|
-
|
|
41
|
-
pub fn quote_oft(chain: &ChainSetup<'_>, send_param: &SendParam) -> (OFTLimit, Vec<OFTFeeDetail>, OFTReceipt) {
|
|
42
|
-
chain.oft.quote_oft(send_param)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
pub fn quote_send(
|
|
46
|
-
env: &Env,
|
|
47
|
-
chain: &ChainSetup<'_>,
|
|
48
|
-
sender: &Address,
|
|
49
|
-
send_param: &SendParam,
|
|
50
|
-
pay_in_zro: bool,
|
|
51
|
-
) -> MessagingFee {
|
|
52
|
-
env.mock_auths(&[MockAuth {
|
|
53
|
-
address: sender,
|
|
54
|
-
invoke: &MockAuthInvoke {
|
|
55
|
-
contract: &chain.oft.address,
|
|
56
|
-
fn_name: "quote_send",
|
|
57
|
-
args: (sender, send_param, &pay_in_zro).into_val(env),
|
|
58
|
-
sub_invokes: &[],
|
|
59
|
-
},
|
|
60
|
-
}]);
|
|
61
|
-
chain.oft.quote_send(sender, send_param, &pay_in_zro)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/// Send without fee (standard OFT send)
|
|
65
|
-
pub fn send(
|
|
66
|
-
env: &Env,
|
|
67
|
-
chain: &ChainSetup<'_>,
|
|
68
|
-
sender: &Address,
|
|
69
|
-
send_param: &SendParam,
|
|
70
|
-
fee: &MessagingFee,
|
|
71
|
-
refund_address: &Address,
|
|
72
|
-
oft_receipt: &OFTReceipt,
|
|
73
|
-
) {
|
|
74
|
-
env.mock_auths(&[MockAuth {
|
|
75
|
-
address: sender,
|
|
76
|
-
invoke: &MockAuthInvoke {
|
|
77
|
-
contract: &chain.oft.address,
|
|
78
|
-
fn_name: "send",
|
|
79
|
-
args: (sender, send_param, fee, refund_address).into_val(env),
|
|
80
|
-
sub_invokes: &[
|
|
81
|
-
MockAuthInvoke {
|
|
82
|
-
contract: &chain.native_token,
|
|
83
|
-
fn_name: "transfer",
|
|
84
|
-
args: (sender, &chain.endpoint.address, &fee.native_fee).into_val(env),
|
|
85
|
-
sub_invokes: &[],
|
|
86
|
-
},
|
|
87
|
-
MockAuthInvoke {
|
|
88
|
-
contract: &chain.oft_token,
|
|
89
|
-
fn_name: "burn",
|
|
90
|
-
args: (sender, &oft_receipt.amount_received_ld).into_val(env),
|
|
91
|
-
sub_invokes: &[],
|
|
92
|
-
},
|
|
93
|
-
],
|
|
94
|
-
},
|
|
95
|
-
}]);
|
|
96
|
-
chain.oft.send(sender, send_param, fee, refund_address);
|
|
97
|
-
}
|
|
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
|
-
|
|
181
|
-
pub fn validate_packet(env: &Env, chain: &ChainSetup<'_>, packet_event: &(Bytes, Bytes, Address)) {
|
|
182
|
-
let packet = decode_packet(env, &packet_event.0);
|
|
183
|
-
let encoded_header = packet_codec_v1::encode_packet_header(env, &packet);
|
|
184
|
-
let payload_hash = packet_codec_v1::payload_hash(env, &packet);
|
|
185
|
-
|
|
186
|
-
env.mock_auths(&[MockAuth {
|
|
187
|
-
address: &chain.owner,
|
|
188
|
-
invoke: &MockAuthInvoke {
|
|
189
|
-
contract: &chain.sml.address,
|
|
190
|
-
fn_name: "validate_packet",
|
|
191
|
-
args: (&encoded_header, &payload_hash).into_val(env),
|
|
192
|
-
sub_invokes: &[],
|
|
193
|
-
},
|
|
194
|
-
}]);
|
|
195
|
-
chain.sml.validate_packet(&encoded_header, &payload_hash);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
pub fn lz_receive(
|
|
199
|
-
env: &Env,
|
|
200
|
-
chain: &ChainSetup<'_>,
|
|
201
|
-
executor: &Address,
|
|
202
|
-
packet: &OutboundPacket,
|
|
203
|
-
recipient: &Address,
|
|
204
|
-
value: i128,
|
|
205
|
-
) {
|
|
206
|
-
let origin =
|
|
207
|
-
Origin { src_eid: packet.src_eid, sender: address_to_peer_bytes32(&packet.sender), nonce: packet.nonce };
|
|
208
|
-
let extra_options = recipient.to_xdr(env);
|
|
209
|
-
|
|
210
|
-
env.mock_auths(&[MockAuth {
|
|
211
|
-
address: executor,
|
|
212
|
-
invoke: &MockAuthInvoke {
|
|
213
|
-
contract: &chain.oft.address,
|
|
214
|
-
fn_name: "lz_receive",
|
|
215
|
-
args: (executor, &origin, &packet.guid, &packet.message, &extra_options, &value).into_val(env),
|
|
216
|
-
sub_invokes: &[],
|
|
217
|
-
},
|
|
218
|
-
}]);
|
|
219
|
-
endpoint_v2::LayerZeroReceiverClient::new(env, &chain.oft.address).lz_receive(
|
|
220
|
-
executor,
|
|
221
|
-
&origin,
|
|
222
|
-
&packet.guid,
|
|
223
|
-
&packet.message,
|
|
224
|
-
&extra_options,
|
|
225
|
-
&value,
|
|
226
|
-
);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
pub fn try_lz_receive(
|
|
230
|
-
env: &Env,
|
|
231
|
-
chain: &ChainSetup<'_>,
|
|
232
|
-
executor: &Address,
|
|
233
|
-
packet: &OutboundPacket,
|
|
234
|
-
recipient: &Address,
|
|
235
|
-
value: i128,
|
|
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);
|
|
240
|
-
|
|
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()
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// returns (encoded_payload, options, send_library)
|
|
256
|
-
pub fn scan_packet_sent_event(env: &Env, endpoint: &Address) -> Option<(Bytes, Bytes, Address)> {
|
|
257
|
-
let mut packet = None;
|
|
258
|
-
for (emitter, topics, data) in env.events().all() {
|
|
259
|
-
let packet_sent_symbol = Symbol::new(env, "packet_sent").to_val();
|
|
260
|
-
if emitter == *endpoint && topics.contains(packet_sent_symbol) {
|
|
261
|
-
let map: Map<Symbol, Val> = data.into_val(env);
|
|
262
|
-
|
|
263
|
-
let encoded_payload: Bytes = map.get(Symbol::new(env, "encoded_packet")).unwrap().into_val(env);
|
|
264
|
-
let options: Bytes = map.get(Symbol::new(env, "options")).unwrap().into_val(env);
|
|
265
|
-
let send_library: Address = map.get(Symbol::new(env, "send_library")).unwrap().into_val(env);
|
|
266
|
-
|
|
267
|
-
packet = Some((encoded_payload, options, send_library));
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
packet
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// ============================================================================
|
|
275
|
-
// Token Operations
|
|
276
|
-
// ============================================================================
|
|
277
|
-
|
|
278
|
-
pub fn mint_to(env: &Env, owner: &Address, token: &Address, to: &Address, amount: i128) {
|
|
279
|
-
env.mock_auths(&[MockAuth {
|
|
280
|
-
address: owner,
|
|
281
|
-
invoke: &MockAuthInvoke {
|
|
282
|
-
contract: token,
|
|
283
|
-
fn_name: "mint",
|
|
284
|
-
args: (to, amount).into_val(env),
|
|
285
|
-
sub_invokes: &[],
|
|
286
|
-
},
|
|
287
|
-
}]);
|
|
288
|
-
|
|
289
|
-
let sac = StellarAssetClient::new(env, token);
|
|
290
|
-
sac.mint(to, &amount);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
pub fn transfer_sac_admin(env: &Env, owner: &Address, token: &Address, new_admin: &Address) {
|
|
294
|
-
env.mock_auths(&[MockAuth {
|
|
295
|
-
address: owner,
|
|
296
|
-
invoke: &MockAuthInvoke {
|
|
297
|
-
contract: token,
|
|
298
|
-
fn_name: "set_admin",
|
|
299
|
-
args: (new_admin,).into_val(env),
|
|
300
|
-
sub_invokes: &[],
|
|
301
|
-
},
|
|
302
|
-
}]);
|
|
303
|
-
StellarAssetClient::new(env, token).set_admin(new_admin);
|
|
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(env: &Env, chain: &ChainSetup<'_>, direction: &Direction, dst_eid: u32, limit: i128, window_seconds: u64) {
|
|
379
|
-
env.mock_auths(&[MockAuth {
|
|
380
|
-
address: &chain.owner,
|
|
381
|
-
invoke: &MockAuthInvoke {
|
|
382
|
-
contract: &chain.oft.address,
|
|
383
|
-
fn_name: "set_rate_limit",
|
|
384
|
-
args: (direction, &dst_eid, &limit, &window_seconds).into_val(env),
|
|
385
|
-
sub_invokes: &[],
|
|
386
|
-
},
|
|
387
|
-
}]);
|
|
388
|
-
chain.oft.set_rate_limit(direction, &dst_eid, &limit, &window_seconds);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
pub fn rate_limit_capacity(chain: &ChainSetup<'_>, direction: &Direction, eid: u32) -> i128 {
|
|
392
|
-
chain.oft.rate_limit_capacity(direction, &eid)
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
pub fn rate_limit_in_flight(chain: &ChainSetup<'_>, direction: &Direction, eid: u32) -> i128 {
|
|
396
|
-
chain.oft.rate_limit_in_flight(direction, &eid)
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// ============================================================================
|
|
400
|
-
// Time Utilities
|
|
401
|
-
// ============================================================================
|
|
402
|
-
|
|
403
|
-
pub fn advance_time(env: &Env, seconds: u64) {
|
|
404
|
-
let current = env.ledger().timestamp();
|
|
405
|
-
env.ledger().set_timestamp(current + seconds);
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
#[allow(dead_code)]
|
|
409
|
-
pub fn set_timestamp(env: &Env, timestamp: u64) {
|
|
410
|
-
env.ledger().set_timestamp(timestamp);
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// ============================================================================
|
|
414
|
-
// SendParam Builder
|
|
415
|
-
// ============================================================================
|
|
416
|
-
|
|
417
|
-
pub fn create_send_param(env: &Env, dst_eid: u32, amount_ld: i128, min_amount_ld: i128, to: &BytesN<32>) -> SendParam {
|
|
418
|
-
SendParam {
|
|
419
|
-
dst_eid,
|
|
420
|
-
to: to.clone(),
|
|
421
|
-
amount_ld,
|
|
422
|
-
min_amount_ld,
|
|
423
|
-
extra_options: Bytes::new(env),
|
|
424
|
-
compose_msg: Bytes::new(env),
|
|
425
|
-
oft_cmd: Bytes::new(env),
|
|
426
|
-
}
|
|
427
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
#![no_std]
|
|
2
|
-
|
|
3
|
-
pub mod oft;
|
|
4
|
-
|
|
5
|
-
#[cfg(test)]
|
|
6
|
-
#[path = "../integration-tests/mod.rs"]
|
|
7
|
-
pub mod integration_tests;
|
|
8
|
-
|
|
9
|
-
pub use oft::*;
|
|
10
|
-
|
|
11
|
-
// Re-export extension types from the oft crate for convenience
|
|
12
|
-
pub use ::oft::extensions::{
|
|
13
|
-
oft_fee::{OFTFee, OFTFeeError},
|
|
14
|
-
pausable::{OFTPausable, OFTPausableError},
|
|
15
|
-
rate_limiter::{Direction, RateLimit, RateLimiter, RateLimitError},
|
|
16
|
-
};
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
use common_macros::{contract_impl, storage};
|
|
2
|
-
use endpoint_v2::Origin;
|
|
3
|
-
use oapp::oapp_receiver::LzReceiveInternal;
|
|
4
|
-
use oapp_macros::oapp;
|
|
5
|
-
use oft::{
|
|
6
|
-
errors::OFTError,
|
|
7
|
-
extensions::{
|
|
8
|
-
oft_fee::{OFTFee, OFTFeeInternal},
|
|
9
|
-
pausable::{OFTPausable, OFTPausableInternal},
|
|
10
|
-
rate_limiter::{Direction, RateLimiter, RateLimiterInternal},
|
|
11
|
-
},
|
|
12
|
-
initialize_oft,
|
|
13
|
-
oft::{OFTInternal, OFT},
|
|
14
|
-
oft_impl,
|
|
15
|
-
oft_types::{lock_unlock, mint_burn},
|
|
16
|
-
storage::OFTStorage,
|
|
17
|
-
types::{OFTFeeDetail, OFTLimit, OFTReceipt, SendParam},
|
|
18
|
-
utils::remove_dust,
|
|
19
|
-
};
|
|
20
|
-
use soroban_sdk::{assert_with_error, contracttype, Address, Bytes, BytesN, Env, Vec};
|
|
21
|
-
|
|
22
|
-
/// The mode of operation for the OFT contract
|
|
23
|
-
#[contracttype]
|
|
24
|
-
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
25
|
-
#[repr(u8)]
|
|
26
|
-
pub enum OFTMode {
|
|
27
|
-
/// Lock tokens on send, unlock on receive
|
|
28
|
-
LockUnlock = 0,
|
|
29
|
-
/// Burn tokens on send, mint on receive
|
|
30
|
-
MintBurn = 1,
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
#[storage]
|
|
34
|
-
enum OFTStdStorage {
|
|
35
|
-
#[instance(OFTMode)]
|
|
36
|
-
Mode,
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
#[oapp]
|
|
40
|
-
pub struct OFTStd;
|
|
41
|
-
|
|
42
|
-
#[contract_impl]
|
|
43
|
-
impl OFTStd {
|
|
44
|
-
pub fn __constructor(
|
|
45
|
-
env: &Env,
|
|
46
|
-
token: &Address,
|
|
47
|
-
owner: &Address,
|
|
48
|
-
endpoint: &Address,
|
|
49
|
-
delegate: &Option<Address>,
|
|
50
|
-
shared_decimals: u32,
|
|
51
|
-
mode: OFTMode,
|
|
52
|
-
) {
|
|
53
|
-
initialize_oft::<Self>(env, owner, token, endpoint, delegate, shared_decimals);
|
|
54
|
-
OFTStdStorage::set_mode(env, &mode);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/// Returns the mode of operation for this OFT (LockUnlock or MintBurn)
|
|
58
|
-
pub fn mode(env: &Env) -> OFTMode {
|
|
59
|
-
OFTStdStorage::mode(env).unwrap()
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/// LzReceiveInternal implementation using default OFT receive logic
|
|
64
|
-
impl LzReceiveInternal for OFTStd {
|
|
65
|
-
fn __lz_receive(
|
|
66
|
-
env: &Env,
|
|
67
|
-
origin: &Origin,
|
|
68
|
-
guid: &BytesN<32>,
|
|
69
|
-
message: &Bytes,
|
|
70
|
-
extra_data: &Bytes,
|
|
71
|
-
executor: &Address,
|
|
72
|
-
value: i128,
|
|
73
|
-
) {
|
|
74
|
-
oft_impl::lz_receive::<Self>(env, executor, origin, guid, message, extra_data, value)
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/// OFT trait implementation for standard OFT with extensions
|
|
79
|
-
#[contract_impl(contracttrait)]
|
|
80
|
-
impl OFT for OFTStd {
|
|
81
|
-
fn quote_oft(env: &Env, send_param: &SendParam) -> (OFTLimit, Vec<OFTFeeDetail>, OFTReceipt) {
|
|
82
|
-
Self::__assert_not_paused(env);
|
|
83
|
-
let (_, fee_details, oft_receipt) = oft_impl::quote_oft::<Self>(env, send_param);
|
|
84
|
-
let capacity = Self::rate_limit_capacity(env, &Direction::Outbound, send_param.dst_eid);
|
|
85
|
-
let oft_limit = OFTLimit { min_amount_ld: 0, max_amount_ld: capacity };
|
|
86
|
-
(oft_limit, fee_details, oft_receipt)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
fn quote_send(env: &Env, sender: &Address, send_param: &SendParam, pay_in_zro: bool) -> endpoint_v2::MessagingFee {
|
|
90
|
-
Self::__assert_not_paused(env);
|
|
91
|
-
oft_impl::quote_send::<Self>(env, sender, send_param, pay_in_zro)
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/// OFT behavior for standard OFT with extension hooks
|
|
96
|
-
impl OFTInternal for OFTStd {
|
|
97
|
-
fn __debit(env: &Env, sender: &Address, amount_ld: i128, min_amount_ld: i128, dst_eid: u32) -> OFTReceipt {
|
|
98
|
-
// 1. Pausable check
|
|
99
|
-
Self::__assert_not_paused(env);
|
|
100
|
-
|
|
101
|
-
// 2. Core debit logic (based on mode)
|
|
102
|
-
let oft_receipt = match Self::mode(env) {
|
|
103
|
-
OFTMode::LockUnlock => lock_unlock::debit::<Self>(env, sender, amount_ld, min_amount_ld, dst_eid),
|
|
104
|
-
OFTMode::MintBurn => mint_burn::debit::<Self>(env, sender, amount_ld, min_amount_ld, dst_eid),
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
// 3. Rate limit checks (using amount_received_ld - the actual cross-chain amount)
|
|
108
|
-
Self::__consume_rate_limit_capacity(env, &Direction::Outbound, dst_eid, oft_receipt.amount_received_ld);
|
|
109
|
-
Self::__release_rate_limit_capacity(env, &Direction::Inbound, dst_eid, oft_receipt.amount_received_ld);
|
|
110
|
-
|
|
111
|
-
// 4. Charge fee (amount_sent_ld - amount_received_ld)
|
|
112
|
-
Self::__charge_fee(env, &Self::token(env), sender, oft_receipt.amount_sent_ld - oft_receipt.amount_received_ld);
|
|
113
|
-
|
|
114
|
-
oft_receipt
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
fn __credit(env: &Env, to: &Address, amount_ld: i128, src_eid: u32) -> i128 {
|
|
118
|
-
// 1. Pausable check
|
|
119
|
-
Self::__assert_not_paused(env);
|
|
120
|
-
|
|
121
|
-
// 2. Core credit logic (based on mode)
|
|
122
|
-
let amount_credited = match Self::mode(env) {
|
|
123
|
-
OFTMode::LockUnlock => lock_unlock::credit::<Self>(env, to, amount_ld, src_eid),
|
|
124
|
-
OFTMode::MintBurn => mint_burn::credit::<Self>(env, to, amount_ld, src_eid),
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
// 3. Rate limit checks (using amount_credited - the actual credited amount)
|
|
128
|
-
Self::__consume_rate_limit_capacity(env, &Direction::Inbound, src_eid, amount_credited);
|
|
129
|
-
Self::__release_rate_limit_capacity(env, &Direction::Outbound, src_eid, amount_credited);
|
|
130
|
-
|
|
131
|
-
amount_credited
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
fn __debit_view(env: &Env, amount_ld: i128, min_amount_ld: i128, dst_eid: u32) -> OFTReceipt {
|
|
135
|
-
let conversion_rate = OFTStorage::decimal_conversion_rate(env).unwrap();
|
|
136
|
-
|
|
137
|
-
// CRITICAL: Apply fee first, then remove dust
|
|
138
|
-
let amount_after_fee = Self::__fee_view(env, dst_eid, amount_ld);
|
|
139
|
-
let amount_received_ld = remove_dust(amount_after_fee, conversion_rate);
|
|
140
|
-
|
|
141
|
-
// amount_sent_ld logic:
|
|
142
|
-
// - If no fee: amount_sent_ld = amount_received_ld (both reduced by dust)
|
|
143
|
-
// - If fee applied: amount_sent_ld = original amount_ld (unchanged)
|
|
144
|
-
// This is to align the behavior with the fee extensions on other VMs
|
|
145
|
-
let amount_sent_ld = if amount_after_fee == amount_ld { amount_received_ld } else { amount_ld };
|
|
146
|
-
|
|
147
|
-
assert_with_error!(env, amount_received_ld >= min_amount_ld, OFTError::SlippageExceeded);
|
|
148
|
-
|
|
149
|
-
OFTReceipt { amount_sent_ld, amount_received_ld }
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// ==================== Extension Trait Implementations ====================
|
|
154
|
-
|
|
155
|
-
/// Pausable extension - allows pausing/unpausing the OFT
|
|
156
|
-
/// Default state: unpaused (all operations allowed)
|
|
157
|
-
#[contract_impl(contracttrait)]
|
|
158
|
-
impl OFTPausable for OFTStd {}
|
|
159
|
-
|
|
160
|
-
impl OFTPausableInternal for OFTStd {}
|
|
161
|
-
|
|
162
|
-
/// OFT Fee extension - allows collecting fees on transfers
|
|
163
|
-
/// Default state: 0 BPS (no fee collected)
|
|
164
|
-
#[contract_impl(contracttrait)]
|
|
165
|
-
impl OFTFee for OFTStd {}
|
|
166
|
-
|
|
167
|
-
impl OFTFeeInternal for OFTStd {}
|
|
168
|
-
|
|
169
|
-
/// Rate Limiter extension - allows rate limiting transfers
|
|
170
|
-
/// Default state: not set (rate_limit_capacity returns i128::MAX)
|
|
171
|
-
#[contract_impl(contracttrait)]
|
|
172
|
-
impl RateLimiter for OFTStd {}
|
|
173
|
-
|
|
174
|
-
impl RateLimiterInternal for OFTStd {}
|