@layerzerolabs/protocol-stellar-v2 0.2.29 → 0.2.30
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 +371 -321
- package/.turbo/turbo-lint.log +211 -202
- package/.turbo/turbo-test.log +1766 -1673
- package/Cargo.lock +11 -1
- package/contracts/common-macros/src/lib.rs +0 -2
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +1 -0
- package/contracts/endpoint-v2/src/messaging_channel.rs +32 -3
- package/contracts/endpoint-v2/src/tests/endpoint_setup.rs +1 -1
- package/contracts/endpoint-v2/src/tests/messaging_channel/clear_payload.rs +1 -1
- package/contracts/endpoint-v2/src/tests/messaging_channel/inbound.rs +6 -6
- package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_payload_hash.rs +1 -1
- package/contracts/endpoint-v2/src/tests/messaging_channel/outbound.rs +16 -10
- package/contracts/macro-integration-tests/tests/runtime/oapp/options_type3.rs +10 -10
- package/contracts/macro-integration-tests/tests/runtime/oapp/receiver.rs +3 -3
- package/contracts/macro-integration-tests/tests/runtime/oapp/sender.rs +4 -3
- package/contracts/macro-integration-tests/tests/runtime/upgradeable/migrate_guard_and_state.rs +1 -57
- package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_missing_internal.stderr +0 -30
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.stderr +5 -3
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.stderr +6 -4
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.stderr +5 -3
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.stderr +5 -3
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_auth_trait.stderr +0 -30
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_upgradeable_internal.stderr +0 -30
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/basic.rs +0 -2
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/multisig_contract.rs +0 -2
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/no_migration.rs +0 -2
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/no_user_contractimpl.rs +1 -3
- package/contracts/message-libs/message-lib-common/src/packet_codec_v1.rs +3 -6
- package/contracts/message-libs/message-lib-common/src/tests/worker_options/extract_type_3_options.rs +10 -0
- package/contracts/message-libs/message-lib-common/src/worker_options.rs +6 -2
- package/contracts/message-libs/treasury/src/interfaces/zro_fee_lib.rs +3 -3
- package/contracts/message-libs/treasury/src/lib.rs +2 -1
- package/contracts/message-libs/treasury/src/tests/setup.rs +1 -1
- package/contracts/message-libs/treasury/src/treasury.rs +5 -2
- package/contracts/message-libs/uln-302/src/errors.rs +2 -0
- package/contracts/message-libs/uln-302/src/events.rs +3 -3
- package/contracts/message-libs/uln-302/src/interfaces/receive_uln.rs +8 -0
- package/contracts/message-libs/uln-302/src/lib.rs +2 -1
- package/contracts/message-libs/uln-302/src/receive_uln.rs +16 -13
- package/contracts/message-libs/uln-302/src/send_uln.rs +51 -24
- package/contracts/message-libs/uln-302/src/storage.rs +2 -2
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +45 -1
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/verifiable.rs +63 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_executor_config.rs +47 -2
- package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +50 -1
- package/contracts/message-libs/uln-302/src/uln302.rs +0 -8
- package/contracts/oapps/counter/Cargo.toml +4 -4
- package/contracts/oapps/counter/integration_tests/setup_uln.rs +22 -2
- package/contracts/oapps/counter/src/counter.rs +8 -8
- package/contracts/oapps/oapp/src/interfaces/oapp_msg_inspector.rs +33 -10
- package/contracts/oapps/oapp/src/lib.rs +6 -2
- package/contracts/oapps/oapp/src/oapp_core.rs +49 -24
- package/contracts/oapps/oapp/src/oapp_options_type3.rs +21 -14
- package/contracts/oapps/oapp/src/oapp_receiver.rs +17 -16
- package/contracts/oapps/oapp/src/oapp_sender.rs +66 -15
- package/contracts/oapps/oapp/src/tests/oapp_core.rs +5 -5
- package/contracts/oapps/oapp/src/tests/oapp_options_type3.rs +18 -18
- package/contracts/oapps/oapp/src/tests/oapp_receiver.rs +4 -4
- package/contracts/oapps/oapp/src/tests/oapp_sender.rs +3 -3
- package/contracts/oapps/oapp-macros/Cargo.toml +0 -1
- package/contracts/oapps/oapp-macros/src/generators.rs +87 -46
- package/contracts/oapps/oapp-macros/src/lib.rs +3 -61
- package/contracts/oapps/oapp-macros/src/tests/oapp.rs +9 -23
- package/contracts/oapps/oapp-macros/src/tests/parse_custom_impls.rs +15 -11
- package/contracts/oapps/oft/Cargo.toml +1 -1
- package/contracts/oapps/oft/integration-tests/extensions/test_oft_fee.rs +3 -3
- package/contracts/oapps/oft/integration-tests/extensions/test_pausable.rs +4 -4
- package/contracts/oapps/oft/integration-tests/extensions/test_rate_limiter.rs +144 -8
- package/contracts/oapps/oft/integration-tests/setup.rs +4 -2
- package/contracts/oapps/oft/integration-tests/utils.rs +25 -11
- package/contracts/oapps/oft/src/extensions/oft_fee.rs +65 -63
- package/contracts/oapps/oft/src/extensions/pausable.rs +2 -3
- package/contracts/oapps/oft/src/extensions/rate_limiter.rs +22 -5
- package/contracts/oapps/oft/src/interfaces/mint_burnable.rs +18 -0
- package/contracts/oapps/oft/src/interfaces/mod.rs +3 -0
- package/contracts/oapps/oft/src/lib.rs +4 -2
- package/contracts/oapps/oft/src/oft.rs +35 -36
- package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +13 -9
- package/contracts/oapps/oft/src/oft_types/mint_burn.rs +14 -9
- package/contracts/oapps/oft/src/oft_types/mod.rs +14 -12
- package/contracts/oapps/oft/src/tests/extensions/oft_fee.rs +28 -20
- package/contracts/oapps/oft/src/tests/extensions/rate_limiter.rs +136 -2
- package/contracts/oapps/oft/src/tests/oft_types/lock_unlock.rs +12 -8
- package/contracts/oapps/oft-core/integration-tests/setup.rs +8 -9
- package/contracts/oapps/oft-core/integration-tests/test_with_sml.rs +7 -6
- package/contracts/oapps/oft-core/integration-tests/utils.rs +5 -4
- package/contracts/oapps/oft-core/src/codec/oft_compose_msg_codec.rs +2 -2
- package/contracts/oapps/oft-core/src/codec/oft_msg_codec.rs +33 -37
- package/contracts/oapps/oft-core/src/errors.rs +2 -1
- package/contracts/oapps/oft-core/src/events.rs +6 -0
- package/contracts/oapps/oft-core/src/lib.rs +8 -4
- package/contracts/oapps/oft-core/src/oft_core.rs +205 -148
- package/contracts/oapps/oft-core/src/storage.rs +4 -2
- package/contracts/oapps/oft-core/src/tests/test_decimals.rs +2 -2
- package/contracts/oapps/oft-core/src/tests/test_lz_receive.rs +6 -6
- package/contracts/oapps/oft-core/src/tests/test_msg_inspector.rs +7 -6
- package/contracts/oapps/oft-core/src/tests/test_oft_msg_codec.rs +11 -82
- package/contracts/oapps/oft-core/src/tests/test_quote_oft.rs +13 -13
- package/contracts/oapps/oft-core/src/tests/test_quote_send.rs +1 -1
- package/contracts/oapps/oft-core/src/tests/test_resolve_address.rs +2 -2
- package/contracts/oapps/oft-core/src/tests/test_send.rs +22 -22
- package/contracts/oapps/oft-core/src/tests/test_utils.rs +20 -22
- package/contracts/oapps/oft-core/src/utils.rs +12 -8
- package/contracts/sac-manager/Cargo.toml +25 -0
- package/contracts/sac-manager/src/errors.rs +18 -0
- package/contracts/sac-manager/src/extensions/mod.rs +6 -0
- package/contracts/sac-manager/src/extensions/redistribution.rs +109 -0
- package/contracts/sac-manager/src/extensions/supply_control/mod.rs +488 -0
- package/contracts/sac-manager/src/extensions/supply_control/rate_limit.rs +126 -0
- package/contracts/sac-manager/src/interfaces/mod.rs +3 -0
- package/contracts/sac-manager/src/interfaces/sac_manager.rs +52 -0
- package/contracts/sac-manager/src/lib.rs +23 -0
- package/contracts/sac-manager/src/sac_manager.rs +193 -0
- package/contracts/sac-manager/src/storage.rs +20 -0
- package/contracts/sac-manager/src/tests/mod.rs +14 -0
- package/contracts/sac-manager/src/tests/redistribution/mod.rs +1 -0
- package/contracts/sac-manager/src/tests/redistribution/redistribute_funds.rs +82 -0
- package/contracts/sac-manager/src/tests/sac_manager/admin_mint.rs +206 -0
- package/contracts/sac-manager/src/tests/sac_manager/burn.rs +215 -0
- package/contracts/sac-manager/src/tests/sac_manager/clawback.rs +209 -0
- package/contracts/sac-manager/src/tests/sac_manager/mint.rs +252 -0
- package/contracts/sac-manager/src/tests/sac_manager/mod.rs +9 -0
- package/contracts/sac-manager/src/tests/sac_manager/set_admin.rs +36 -0
- package/contracts/sac-manager/src/tests/sac_manager/set_authorized.rs +43 -0
- package/contracts/sac-manager/src/tests/sac_manager/set_oft_address.rs +47 -0
- package/contracts/sac-manager/src/tests/sac_manager/test_helper.rs +75 -0
- package/contracts/sac-manager/src/tests/sac_manager/view_functions.rs +60 -0
- package/contracts/sac-manager/src/tests/supply_control/enumerable_set.rs +256 -0
- package/contracts/sac-manager/src/tests/supply_control/mod.rs +8 -0
- package/contracts/sac-manager/src/tests/supply_control/refill.rs +90 -0
- package/contracts/sac-manager/src/tests/supply_control/set_mint_whitelist.rs +245 -0
- package/contracts/sac-manager/src/tests/supply_control/set_supply_controller.rs +267 -0
- package/contracts/sac-manager/src/tests/supply_control/set_supply_controller_manager.rs +122 -0
- package/contracts/sac-manager/src/tests/supply_control/test_helper.rs +38 -0
- package/contracts/sac-manager/src/tests/supply_control/update_allow_any_mint_burn.rs +114 -0
- package/contracts/sac-manager/src/tests/supply_control/update_limit_config.rs +257 -0
- package/contracts/sac-manager/src/tests/test_helper.rs +190 -0
- package/contracts/upgrader/src/lib.rs +2 -1
- package/contracts/utils/src/errors.rs +0 -1
- package/contracts/utils/src/tests/upgradeable.rs +0 -66
- package/contracts/utils/src/upgradeable.rs +0 -18
- package/contracts/workers/dvn/src/dvn.rs +2 -2
- package/contracts/workers/dvn/src/interfaces/dvn.rs +2 -2
- package/contracts/workers/dvn/src/lib.rs +2 -1
- package/contracts/workers/dvn-fee-lib/src/lib.rs +3 -1
- package/contracts/workers/executor/src/auth.rs +42 -26
- package/contracts/workers/executor/src/executor.rs +28 -3
- package/contracts/workers/executor/src/lib.rs +4 -2
- package/contracts/workers/executor/src/storage.rs +21 -1
- package/contracts/workers/executor/src/tests/auth.rs +64 -20
- package/contracts/workers/executor/src/tests/executor.rs +1 -1
- package/contracts/workers/executor/src/tests/setup.rs +18 -0
- package/contracts/workers/executor-fee-lib/src/lib.rs +4 -1
- package/contracts/workers/executor-helper/src/executor_helper.rs +24 -10
- package/contracts/workers/executor-helper/src/tests/setup.rs +147 -34
- package/contracts/workers/price-feed/src/lib.rs +3 -1
- package/contracts/workers/worker/src/lib.rs +2 -1
- package/contracts/workers/worker/src/worker.rs +31 -17
- package/docs/oapp-guide.md +17 -8
- package/docs/oft-guide.md +3 -3
- package/package.json +3 -3
- package/sdk/.turbo/turbo-test.log +512 -351
- package/sdk/dist/generated/bml.d.ts +3 -9
- package/sdk/dist/generated/bml.js +6 -7
- package/sdk/dist/generated/counter.d.ts +22 -28
- package/sdk/dist/generated/counter.js +11 -12
- package/sdk/dist/generated/dvn.d.ts +36 -54
- package/sdk/dist/generated/dvn.js +10 -15
- package/sdk/dist/generated/dvn_fee_lib.d.ts +3 -21
- package/sdk/dist/generated/dvn_fee_lib.js +6 -11
- package/sdk/dist/generated/endpoint.d.ts +3 -9
- package/sdk/dist/generated/endpoint.js +6 -7
- package/sdk/dist/generated/executor.d.ts +80 -54
- package/sdk/dist/generated/executor.js +16 -16
- package/sdk/dist/generated/executor_fee_lib.d.ts +3 -21
- package/sdk/dist/generated/executor_fee_lib.js +6 -11
- package/sdk/dist/generated/executor_helper.d.ts +36 -42
- package/sdk/dist/generated/executor_helper.js +9 -10
- package/sdk/dist/generated/layerzero_view.d.ts +20 -32
- package/sdk/dist/generated/layerzero_view.js +25 -26
- package/sdk/dist/generated/oft.d.ts +147 -79
- package/sdk/dist/generated/oft.js +47 -54
- package/sdk/dist/generated/price_feed.d.ts +20 -38
- package/sdk/dist/generated/price_feed.js +15 -20
- package/sdk/dist/generated/sac_manager.d.ts +1309 -0
- package/sdk/dist/generated/sac_manager.js +484 -0
- package/sdk/dist/generated/sml.d.ts +3 -9
- package/sdk/dist/generated/sml.js +6 -7
- package/sdk/dist/generated/treasury.d.ts +3 -9
- package/sdk/dist/generated/treasury.js +8 -9
- package/sdk/dist/generated/uln302.d.ts +20 -20
- package/sdk/dist/generated/uln302.js +25 -22
- package/sdk/dist/generated/upgrader.d.ts +3 -9
- package/sdk/dist/generated/upgrader.js +6 -7
- package/sdk/dist/index.d.ts +1 -0
- package/sdk/dist/index.js +1 -0
- package/sdk/package.json +1 -1
- package/sdk/src/index.ts +1 -0
- package/sdk/test/oft-sml.test.ts +7 -5
- package/sdk/test/sac-manager-redistribution.test.ts +578 -0
- package/sdk/test/suites/globalSetup.ts +11 -6
- package/sdk/test/test_data/test_upgradeable_dvn.wasm +0 -0
- package/sdk/test/upgrader.test.ts +75 -202
- package/sdk/test/utils.ts +40 -0
- package/tools/ts-bindings-gen/src/main.rs +1 -0
|
@@ -4,7 +4,7 @@ use utils::{auth::Auth, option_ext::OptionExt};
|
|
|
4
4
|
|
|
5
5
|
/// Base fee in basis points (10,000 BPS = 100%)
|
|
6
6
|
/// Used as denominator in fee calculations
|
|
7
|
-
const BASE_FEE_BPS:
|
|
7
|
+
const BASE_FEE_BPS: u32 = 10_000;
|
|
8
8
|
|
|
9
9
|
// =========================================================================
|
|
10
10
|
// Storage
|
|
@@ -12,15 +12,14 @@ const BASE_FEE_BPS: u64 = 10_000;
|
|
|
12
12
|
|
|
13
13
|
#[storage]
|
|
14
14
|
pub enum OFTFeeStorage {
|
|
15
|
-
/// Default fee rate in basis points (
|
|
15
|
+
/// Default fee rate in basis points (1-10,000, where 10,000 = 100%)
|
|
16
16
|
/// Applied to destinations without specific fee configuration
|
|
17
|
-
///
|
|
18
|
-
#[instance(
|
|
19
|
-
#[default(0)]
|
|
17
|
+
/// Not set by default (effective rate is 0 when unset)
|
|
18
|
+
#[instance(u32)]
|
|
20
19
|
DefaultFeeBps,
|
|
21
20
|
|
|
22
21
|
/// Destination-specific fee rates mapped by endpoint ID (eid)
|
|
23
|
-
#[persistent(
|
|
22
|
+
#[persistent(u32)]
|
|
24
23
|
FeeBps { eid: u32 },
|
|
25
24
|
|
|
26
25
|
/// Address where collected fees will be deposited
|
|
@@ -46,7 +45,8 @@ pub enum OFTFeeError {
|
|
|
46
45
|
#[contractevent]
|
|
47
46
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
48
47
|
pub struct DefaultFeeBpsSet {
|
|
49
|
-
|
|
48
|
+
/// The default fee rate in basis points, or None if the default fee is removed
|
|
49
|
+
pub fee_bps: Option<u32>,
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
#[contractevent]
|
|
@@ -54,13 +54,14 @@ pub struct DefaultFeeBpsSet {
|
|
|
54
54
|
pub struct FeeBpsSet {
|
|
55
55
|
pub dst_eid: u32,
|
|
56
56
|
/// The fee rate in basis points, or None if the fee is removed
|
|
57
|
-
pub fee_bps: Option<
|
|
57
|
+
pub fee_bps: Option<u32>,
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
#[contractevent]
|
|
61
61
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
62
62
|
pub struct FeeDepositAddressSet {
|
|
63
|
-
|
|
63
|
+
/// The address to deposit fees to, or None to remove the fee deposit address
|
|
64
|
+
pub fee_deposit_address: Option<Address>,
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
// =========================================================================
|
|
@@ -73,49 +74,56 @@ pub trait OFTFee: OFTFeeInternal + Auth {
|
|
|
73
74
|
// Management Functions
|
|
74
75
|
// =========================================================================
|
|
75
76
|
|
|
76
|
-
/// Sets the default fee rate in basis points.
|
|
77
|
+
/// Sets or removes the default fee rate in basis points.
|
|
78
|
+
///
|
|
79
|
+
/// - `Some(n)`: sets the default fee to `n` basis points (must be >0 and <=10,000).
|
|
80
|
+
/// - `Some(0)`: rejected — use `None` to remove the default fee instead.
|
|
81
|
+
/// - `None`: removes the default fee (effective rate becomes 0).
|
|
77
82
|
#[only_auth]
|
|
78
|
-
fn set_default_fee_bps(env: &soroban_sdk::Env, default_fee_bps:
|
|
83
|
+
fn set_default_fee_bps(env: &soroban_sdk::Env, default_fee_bps: &Option<u32>) {
|
|
79
84
|
Self::__set_default_fee_bps(env, default_fee_bps);
|
|
80
85
|
}
|
|
81
86
|
|
|
82
87
|
/// Sets or removes the fee rate for a specific destination endpoint.
|
|
83
88
|
///
|
|
89
|
+
/// - `Some(0)`: explicitly sets zero fee for this destination, overriding the default fee.
|
|
90
|
+
/// - `None`: removes the per-destination override; falls back to the default fee.
|
|
91
|
+
///
|
|
84
92
|
/// # Arguments
|
|
85
93
|
/// * `dst_eid` - The destination endpoint ID
|
|
86
94
|
/// * `fee_bps` - The fee rate (0-10,000), or None to remove the fee configuration
|
|
87
95
|
#[only_auth]
|
|
88
|
-
fn set_fee_bps(env: &soroban_sdk::Env, dst_eid: u32, fee_bps: Option<
|
|
96
|
+
fn set_fee_bps(env: &soroban_sdk::Env, dst_eid: u32, fee_bps: &Option<u32>) {
|
|
89
97
|
Self::__set_fee_bps(env, dst_eid, fee_bps);
|
|
90
98
|
}
|
|
91
99
|
|
|
92
|
-
/// Sets the address where collected fees will be deposited.
|
|
100
|
+
/// Sets or removes the address where collected fees will be deposited.
|
|
93
101
|
#[only_auth]
|
|
94
|
-
fn set_fee_deposit_address(env: &soroban_sdk::Env, fee_deposit_address: soroban_sdk::Address) {
|
|
95
|
-
Self::__set_fee_deposit_address(env,
|
|
102
|
+
fn set_fee_deposit_address(env: &soroban_sdk::Env, fee_deposit_address: &Option<soroban_sdk::Address>) {
|
|
103
|
+
Self::__set_fee_deposit_address(env, fee_deposit_address);
|
|
96
104
|
}
|
|
97
105
|
|
|
98
106
|
// =========================================================================
|
|
99
107
|
// View Functions
|
|
100
108
|
// =========================================================================
|
|
101
109
|
|
|
102
|
-
/// Returns the default fee rate in basis points.
|
|
103
|
-
fn default_fee_bps(env: &soroban_sdk::Env) ->
|
|
110
|
+
/// Returns the default fee rate in basis points, if set.
|
|
111
|
+
fn default_fee_bps(env: &soroban_sdk::Env) -> Option<u32> {
|
|
104
112
|
Self::__default_fee_bps(env)
|
|
105
113
|
}
|
|
106
114
|
|
|
107
115
|
/// Returns the fee rate for a specific destination, if set.
|
|
108
|
-
fn fee_bps(env: &soroban_sdk::Env, dst_eid: u32) -> Option<
|
|
116
|
+
fn fee_bps(env: &soroban_sdk::Env, dst_eid: u32) -> Option<u32> {
|
|
109
117
|
Self::__fee_bps(env, dst_eid)
|
|
110
118
|
}
|
|
111
119
|
|
|
112
120
|
/// Returns the effective fee rate for a destination (destination-specific or default).
|
|
113
|
-
fn effective_fee_bps(env: &soroban_sdk::Env, dst_eid: u32) ->
|
|
121
|
+
fn effective_fee_bps(env: &soroban_sdk::Env, dst_eid: u32) -> u32 {
|
|
114
122
|
Self::__effective_fee_bps(env, dst_eid)
|
|
115
123
|
}
|
|
116
124
|
|
|
117
125
|
/// Returns the fee deposit address.
|
|
118
|
-
fn fee_deposit_address(env: &soroban_sdk::Env) -> soroban_sdk::Address {
|
|
126
|
+
fn fee_deposit_address(env: &soroban_sdk::Env) -> Option<soroban_sdk::Address> {
|
|
119
127
|
Self::__fee_deposit_address(env)
|
|
120
128
|
}
|
|
121
129
|
}
|
|
@@ -157,7 +165,8 @@ pub trait OFTFeeInternal {
|
|
|
157
165
|
/// * `fee_amount` - The fee amount to transfer
|
|
158
166
|
fn __charge_fee(env: &Env, token: &Address, from: &Address, fee_amount: i128) {
|
|
159
167
|
if fee_amount != 0 {
|
|
160
|
-
let fee_deposit =
|
|
168
|
+
let fee_deposit =
|
|
169
|
+
Self::__fee_deposit_address(env).unwrap_or_panic(env, OFTFeeError::InvalidFeeDepositAddress);
|
|
161
170
|
TokenClient::new(env, token).transfer(from, &fee_deposit, &fee_amount);
|
|
162
171
|
}
|
|
163
172
|
}
|
|
@@ -166,52 +175,49 @@ pub trait OFTFeeInternal {
|
|
|
166
175
|
// Management Functions
|
|
167
176
|
// =========================================================================
|
|
168
177
|
|
|
169
|
-
/// Sets the default fee rate in basis points.
|
|
178
|
+
/// Sets or removes the default fee rate in basis points.
|
|
170
179
|
///
|
|
171
180
|
/// # Arguments
|
|
172
|
-
/// * `default_fee_bps` - The default fee rate (0
|
|
173
|
-
fn __set_default_fee_bps(env: &Env, default_fee_bps:
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
181
|
+
/// * `default_fee_bps` - The default fee rate (>0 and <=10,000, where 10,000 = 100%) or None to remove the default fee rate
|
|
182
|
+
fn __set_default_fee_bps(env: &Env, default_fee_bps: &Option<u32>) {
|
|
183
|
+
let current = Self::__default_fee_bps(env);
|
|
184
|
+
assert_with_error!(env, current != *default_fee_bps, OFTFeeError::SameValue);
|
|
185
|
+
assert_with_error!(
|
|
186
|
+
env,
|
|
187
|
+
default_fee_bps.is_none_or(|bps| bps > 0 && bps <= BASE_FEE_BPS),
|
|
188
|
+
OFTFeeError::InvalidFeeBps
|
|
189
|
+
);
|
|
178
190
|
|
|
179
|
-
OFTFeeStorage::
|
|
180
|
-
|
|
181
|
-
DefaultFeeBpsSet { fee_bps: default_fee_bps }.publish(env);
|
|
191
|
+
OFTFeeStorage::set_or_remove_default_fee_bps(env, default_fee_bps);
|
|
192
|
+
DefaultFeeBpsSet { fee_bps: *default_fee_bps }.publish(env);
|
|
182
193
|
}
|
|
183
194
|
|
|
184
195
|
/// Sets or removes the fee rate for a specific destination endpoint.
|
|
185
196
|
///
|
|
197
|
+
/// - `Some(0)`: explicitly sets zero fee for this destination, overriding the default fee.
|
|
198
|
+
/// - `None`: removes the per-destination override; falls back to the default fee.
|
|
199
|
+
///
|
|
186
200
|
/// # Arguments
|
|
187
201
|
/// * `dst_eid` - The destination endpoint ID
|
|
188
202
|
/// * `fee_bps` - The fee rate (0-10,000), or None to remove the fee configuration
|
|
189
|
-
fn __set_fee_bps(env: &Env, dst_eid: u32, fee_bps: Option<
|
|
203
|
+
fn __set_fee_bps(env: &Env, dst_eid: u32, fee_bps: &Option<u32>) {
|
|
190
204
|
let current_fee_bps = Self::__fee_bps(env, dst_eid);
|
|
191
|
-
assert_with_error!(env, current_fee_bps != fee_bps, OFTFeeError::SameValue);
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
assert_with_error!(env, bps <= BASE_FEE_BPS, OFTFeeError::InvalidFeeBps);
|
|
196
|
-
OFTFeeStorage::set_fee_bps(env, dst_eid, &bps);
|
|
197
|
-
}
|
|
198
|
-
None => {
|
|
199
|
-
OFTFeeStorage::remove_fee_bps(env, dst_eid);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
205
|
+
assert_with_error!(env, current_fee_bps != *fee_bps, OFTFeeError::SameValue);
|
|
206
|
+
assert_with_error!(env, fee_bps.is_none_or(|bps| bps <= BASE_FEE_BPS), OFTFeeError::InvalidFeeBps);
|
|
207
|
+
|
|
208
|
+
OFTFeeStorage::set_or_remove_fee_bps(env, dst_eid, fee_bps);
|
|
202
209
|
|
|
203
|
-
FeeBpsSet { dst_eid, fee_bps }.publish(env);
|
|
210
|
+
FeeBpsSet { dst_eid, fee_bps: *fee_bps }.publish(env);
|
|
204
211
|
}
|
|
205
212
|
|
|
206
|
-
/// Sets the address where collected fees will be deposited.
|
|
213
|
+
/// Sets or removes the address where collected fees will be deposited.
|
|
207
214
|
///
|
|
208
215
|
/// # Arguments
|
|
209
|
-
/// * `fee_deposit_address` - The address to deposit fees to
|
|
210
|
-
fn __set_fee_deposit_address(env: &Env, fee_deposit_address: &Address) {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
OFTFeeStorage::set_fee_deposit_address(env, fee_deposit_address);
|
|
216
|
+
/// * `fee_deposit_address` - The address to deposit fees to, or None to remove the fee deposit address
|
|
217
|
+
fn __set_fee_deposit_address(env: &Env, fee_deposit_address: &Option<Address>) {
|
|
218
|
+
let current = Self::__fee_deposit_address(env);
|
|
219
|
+
assert_with_error!(env, current != *fee_deposit_address, OFTFeeError::SameValue);
|
|
220
|
+
OFTFeeStorage::set_or_remove_fee_deposit_address(env, fee_deposit_address);
|
|
215
221
|
FeeDepositAddressSet { fee_deposit_address: fee_deposit_address.clone() }.publish(env);
|
|
216
222
|
}
|
|
217
223
|
|
|
@@ -219,27 +225,23 @@ pub trait OFTFeeInternal {
|
|
|
219
225
|
// View Functions
|
|
220
226
|
// =========================================================================
|
|
221
227
|
|
|
222
|
-
/// Returns the effective fee rate for a destination (destination-specific or default).
|
|
223
|
-
fn __effective_fee_bps(env: &Env, dst_eid: u32) ->
|
|
224
|
-
|
|
225
|
-
OFTFeeStorage::fee_bps(env, dst_eid).unwrap()
|
|
226
|
-
} else {
|
|
227
|
-
OFTFeeStorage::default_fee_bps(env)
|
|
228
|
-
}
|
|
228
|
+
/// Returns the effective fee rate for a destination (destination-specific or default, 0 if neither).
|
|
229
|
+
fn __effective_fee_bps(env: &Env, dst_eid: u32) -> u32 {
|
|
230
|
+
Self::__fee_bps(env, dst_eid).or_else(|| Self::__default_fee_bps(env)).unwrap_or(0)
|
|
229
231
|
}
|
|
230
232
|
|
|
231
|
-
/// Returns the default fee rate in basis points.
|
|
232
|
-
fn __default_fee_bps(env: &Env) ->
|
|
233
|
+
/// Returns the default fee rate in basis points, if set.
|
|
234
|
+
fn __default_fee_bps(env: &Env) -> Option<u32> {
|
|
233
235
|
OFTFeeStorage::default_fee_bps(env)
|
|
234
236
|
}
|
|
235
237
|
|
|
236
238
|
/// Returns the fee rate for a specific destination, if set.
|
|
237
|
-
fn __fee_bps(env: &Env, dst_eid: u32) -> Option<
|
|
239
|
+
fn __fee_bps(env: &Env, dst_eid: u32) -> Option<u32> {
|
|
238
240
|
OFTFeeStorage::fee_bps(env, dst_eid)
|
|
239
241
|
}
|
|
240
242
|
|
|
241
243
|
/// Returns the fee deposit address.
|
|
242
|
-
fn __fee_deposit_address(env: &Env) -> Address {
|
|
243
|
-
OFTFeeStorage::fee_deposit_address(env)
|
|
244
|
+
fn __fee_deposit_address(env: &Env) -> Option<Address> {
|
|
245
|
+
OFTFeeStorage::fee_deposit_address(env)
|
|
244
246
|
}
|
|
245
247
|
}
|
|
@@ -9,7 +9,6 @@ use utils::auth::Auth;
|
|
|
9
9
|
#[storage]
|
|
10
10
|
pub enum OFTPausableStorage {
|
|
11
11
|
#[instance(bool)]
|
|
12
|
-
#[default(false)]
|
|
13
12
|
Paused,
|
|
14
13
|
}
|
|
15
14
|
|
|
@@ -84,7 +83,7 @@ pub trait OFTPausableInternal {
|
|
|
84
83
|
/// * `paused` - `true` to pause, `false` to unpause
|
|
85
84
|
fn __set_paused(env: &Env, paused: bool) {
|
|
86
85
|
assert_with_error!(env, Self::__is_paused(env) != paused, OFTPausableError::PauseStatusUnchanged);
|
|
87
|
-
OFTPausableStorage::
|
|
86
|
+
OFTPausableStorage::set_or_remove_paused(env, if paused { &Some(true) } else { &None });
|
|
88
87
|
PausedSet { paused }.publish(env);
|
|
89
88
|
}
|
|
90
89
|
|
|
@@ -94,6 +93,6 @@ pub trait OFTPausableInternal {
|
|
|
94
93
|
|
|
95
94
|
/// Returns the paused state of the OFT.
|
|
96
95
|
fn __is_paused(env: &Env) -> bool {
|
|
97
|
-
OFTPausableStorage::
|
|
96
|
+
OFTPausableStorage::has_paused(env)
|
|
98
97
|
}
|
|
99
98
|
}
|
|
@@ -15,12 +15,23 @@ pub enum Direction {
|
|
|
15
15
|
Outbound,
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
#[contracttype]
|
|
19
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
20
|
+
#[repr(u8)]
|
|
21
|
+
pub enum Mode {
|
|
22
|
+
/// Net rate limit: releases decrement in-flight amount
|
|
23
|
+
Net,
|
|
24
|
+
/// Gross rate limit: releases do not affect in-flight amount
|
|
25
|
+
Gross,
|
|
26
|
+
}
|
|
27
|
+
|
|
18
28
|
/// Configuration for rate limiting, used as input parameter.
|
|
19
29
|
#[contracttype]
|
|
20
30
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
21
31
|
pub struct RateLimitConfig {
|
|
22
32
|
pub limit: i128,
|
|
23
33
|
pub window_seconds: u64,
|
|
34
|
+
pub mode: Mode,
|
|
24
35
|
}
|
|
25
36
|
|
|
26
37
|
/// Internal storage struct for rate limit state.
|
|
@@ -30,6 +41,7 @@ pub struct RateLimitConfig {
|
|
|
30
41
|
/// - `config.window_seconds` defines how long it takes for the bucket to fully drain
|
|
31
42
|
/// - Tokens decay linearly over time: `decay = elapsed_time * limit / window_seconds`
|
|
32
43
|
/// - Current in-flight = `in_flight_on_last_update - decay` (clamped to 0)
|
|
44
|
+
/// - `config.mode` determines whether releases affect in-flight (Net) or not (Gross)
|
|
33
45
|
#[contracttype]
|
|
34
46
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
35
47
|
struct RateLimitState {
|
|
@@ -98,7 +110,7 @@ pub trait RateLimiter: RateLimiterInternal + Auth {
|
|
|
98
110
|
env: &soroban_sdk::Env,
|
|
99
111
|
direction: &oft::rate_limiter::Direction,
|
|
100
112
|
eid: u32,
|
|
101
|
-
config: Option<oft::rate_limiter::RateLimitConfig>,
|
|
113
|
+
config: &Option<oft::rate_limiter::RateLimitConfig>,
|
|
102
114
|
) {
|
|
103
115
|
Self::__set_rate_limit(env, direction, eid, config);
|
|
104
116
|
}
|
|
@@ -163,6 +175,7 @@ pub trait RateLimiterInternal {
|
|
|
163
175
|
|
|
164
176
|
/// Releases the specified amount back to the rate limit capacity.
|
|
165
177
|
/// Used internally by `__credit` to release outbound capacity on inbound messages.
|
|
178
|
+
/// Only releases for Net mode; Gross mode ignores releases.
|
|
166
179
|
fn __release_rate_limit_capacity(env: &Env, direction: &Direction, eid: u32, amount: i128) {
|
|
167
180
|
assert_with_error!(env, amount >= 0, RateLimitError::InvalidAmount);
|
|
168
181
|
|
|
@@ -170,6 +183,11 @@ pub trait RateLimiterInternal {
|
|
|
170
183
|
return;
|
|
171
184
|
};
|
|
172
185
|
|
|
186
|
+
// Gross mode does not release capacity
|
|
187
|
+
if state.config.mode == Mode::Gross {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
173
191
|
// Apply decay and update timestamp
|
|
174
192
|
let in_flight = calculate_decayed_in_flight(env, &state);
|
|
175
193
|
state.in_flight_on_last_update = (in_flight - amount).max(0);
|
|
@@ -188,10 +206,10 @@ pub trait RateLimiterInternal {
|
|
|
188
206
|
/// * `direction` - The direction (Inbound or Outbound)
|
|
189
207
|
/// * `eid` - The endpoint ID
|
|
190
208
|
/// * `config` - The rate limit configuration, or None to remove the rate limit
|
|
191
|
-
fn __set_rate_limit(env: &Env, direction: &Direction, eid: u32, config: Option<RateLimitConfig>) {
|
|
209
|
+
fn __set_rate_limit(env: &Env, direction: &Direction, eid: u32, config: &Option<RateLimitConfig>) {
|
|
192
210
|
let current_state = RateLimitStorage::rate_limit(env, direction, eid);
|
|
193
211
|
let current_config = current_state.as_ref().map(|s| s.config.clone());
|
|
194
|
-
assert_with_error!(env, current_config != config, RateLimitError::SameValue);
|
|
212
|
+
assert_with_error!(env, current_config != *config, RateLimitError::SameValue);
|
|
195
213
|
|
|
196
214
|
match config {
|
|
197
215
|
Some(cfg) => {
|
|
@@ -213,13 +231,12 @@ pub trait RateLimiterInternal {
|
|
|
213
231
|
};
|
|
214
232
|
|
|
215
233
|
RateLimitStorage::set_rate_limit(env, direction, eid, &state);
|
|
216
|
-
RateLimitSet { direction: direction.clone(), eid, config: Some(cfg) }.publish(env);
|
|
217
234
|
}
|
|
218
235
|
None => {
|
|
219
236
|
RateLimitStorage::remove_rate_limit(env, direction, eid);
|
|
220
|
-
RateLimitSet { direction: direction.clone(), eid, config: None }.publish(env);
|
|
221
237
|
}
|
|
222
238
|
}
|
|
239
|
+
RateLimitSet { direction: direction.clone(), eid, config: config.clone() }.publish(env);
|
|
223
240
|
}
|
|
224
241
|
|
|
225
242
|
// =========================================================================
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//! MintBurnable trait - the interface the OFT uses to mint/burn tokens.
|
|
2
|
+
//!
|
|
3
|
+
//! Any contract that implements `mint` and `burn` can serve as a mintburnable
|
|
4
|
+
|
|
5
|
+
use soroban_sdk::{contractclient, Address, Env};
|
|
6
|
+
|
|
7
|
+
/// The mint/burn interface for OFT MintBurn operations.
|
|
8
|
+
///
|
|
9
|
+
/// Both a raw Stellar Asset Contract (SAC) and a token wrapper satisfy this
|
|
10
|
+
/// interface, allowing the OFT to be agnostic about the underlying implementation.
|
|
11
|
+
#[contractclient(name = "MintBurnableClient")]
|
|
12
|
+
pub trait MintBurnable {
|
|
13
|
+
/// Mints `amount` tokens to `to`.
|
|
14
|
+
fn mint(env: &Env, to: &Address, amount: i128);
|
|
15
|
+
|
|
16
|
+
/// Burns `amount` tokens from `from`.
|
|
17
|
+
fn burn(env: &Env, from: &Address, amount: i128);
|
|
18
|
+
}
|
|
@@ -10,12 +10,10 @@ use crate::{
|
|
|
10
10
|
use common_macros::{contract_impl, storage};
|
|
11
11
|
use oapp_macros::oapp;
|
|
12
12
|
use oft_core::{
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
types::{OFTFeeDetail, OFTLimit, OFTReceipt, SendParam},
|
|
16
|
-
utils as oft_utils, OFTCore, OFTInternal,
|
|
13
|
+
impl_oft_lz_receive, utils as oft_utils, OFTCore, OFTError, OFTFeeDetail, OFTInternal, OFTLimit, OFTReceipt,
|
|
14
|
+
SendParam,
|
|
17
15
|
};
|
|
18
|
-
use soroban_sdk::{assert_with_error,
|
|
16
|
+
use soroban_sdk::{assert_with_error, Address, Bytes, Env, Vec};
|
|
19
17
|
|
|
20
18
|
// =========================================================================
|
|
21
19
|
// Storage
|
|
@@ -42,17 +40,17 @@ impl OFT {
|
|
|
42
40
|
pub fn __constructor(
|
|
43
41
|
env: &Env,
|
|
44
42
|
token: &Address,
|
|
45
|
-
owner: &Address,
|
|
46
|
-
endpoint: &Address,
|
|
47
|
-
delegate: &Option<Address>,
|
|
48
43
|
shared_decimals: u32,
|
|
49
44
|
oft_type: OftType,
|
|
45
|
+
owner: &Address,
|
|
46
|
+
endpoint: &Address,
|
|
47
|
+
delegate: &Address,
|
|
50
48
|
) {
|
|
51
|
-
Self::__initialize_oft(env,
|
|
49
|
+
Self::__initialize_oft(env, token, shared_decimals, owner, endpoint, delegate);
|
|
52
50
|
OFTStorage::set_oft_type(env, &oft_type);
|
|
53
51
|
}
|
|
54
52
|
|
|
55
|
-
/// Returns the type
|
|
53
|
+
/// Returns the OFT type with its target address and configuration.
|
|
56
54
|
pub fn oft_type(env: &Env) -> OftType {
|
|
57
55
|
OFTStorage::oft_type(env).unwrap()
|
|
58
56
|
}
|
|
@@ -61,22 +59,19 @@ impl OFT {
|
|
|
61
59
|
/// OFTCore trait implementation for standard OFT with extensions
|
|
62
60
|
#[contract_impl(contracttrait)]
|
|
63
61
|
impl OFTCore for OFT {
|
|
64
|
-
fn quote_oft(env: &Env, send_param: &SendParam) -> (OFTLimit, Vec<OFTFeeDetail>, OFTReceipt) {
|
|
65
|
-
let (
|
|
62
|
+
fn quote_oft(env: &Env, from: &Address, send_param: &SendParam) -> (OFTLimit, Vec<OFTFeeDetail>, OFTReceipt) {
|
|
63
|
+
let (mut limit, mut fee_details, receipt) = Self::__quote_oft(env, from, send_param);
|
|
66
64
|
|
|
67
65
|
// fee details (only include if there's an actual fee)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
} else {
|
|
72
|
-
vec![env]
|
|
66
|
+
if receipt.amount_sent_ld > receipt.amount_received_ld {
|
|
67
|
+
let fee_amount_ld = receipt.amount_sent_ld - receipt.amount_received_ld;
|
|
68
|
+
fee_details.push_back(OFTFeeDetail { fee_amount_ld, description: Bytes::from_slice(env, b"OFT Fee") });
|
|
73
69
|
};
|
|
74
70
|
|
|
75
71
|
// rate limit capacity
|
|
76
|
-
|
|
77
|
-
let oft_limit = OFTLimit { min_amount_ld: 0, max_amount_ld: capacity };
|
|
72
|
+
limit.max_amount_ld = Self::rate_limit_capacity(env, &Direction::Outbound, send_param.dst_eid);
|
|
78
73
|
|
|
79
|
-
(
|
|
74
|
+
(limit, fee_details, receipt)
|
|
80
75
|
}
|
|
81
76
|
}
|
|
82
77
|
|
|
@@ -85,9 +80,9 @@ impl OFTInternal for OFT {
|
|
|
85
80
|
/// Overrides default to add pausable check and fee calculation.
|
|
86
81
|
///
|
|
87
82
|
/// Dust handling (consistent with EVM):
|
|
88
|
-
/// - fee = 0: dust stays with sender
|
|
89
|
-
/// - fee > 0: dust
|
|
90
|
-
fn __debit_view(env: &Env, amount_ld: i128, min_amount_ld: i128, dst_eid: u32) ->
|
|
83
|
+
/// - fee = 0: dust stays with sender (amount_sent_ld has dust removed)
|
|
84
|
+
/// - fee > 0: dust is absorbed into the charged fee (amount_sent_ld is the full amount)
|
|
85
|
+
fn __debit_view(env: &Env, amount_ld: i128, min_amount_ld: i128, dst_eid: u32) -> (i128, i128) {
|
|
91
86
|
Self::__assert_not_paused(env);
|
|
92
87
|
|
|
93
88
|
let conversion_rate = Self::__decimal_conversion_rate(env);
|
|
@@ -99,32 +94,36 @@ impl OFTInternal for OFT {
|
|
|
99
94
|
(amount_sent_ld, amount_sent_ld)
|
|
100
95
|
} else {
|
|
101
96
|
// With fee: match EVM OFTFee behavior
|
|
102
|
-
// - dust
|
|
97
|
+
// - sender pays full amount_ld (no dust removed), dust is absorbed into the charged fee
|
|
103
98
|
let amount_received_ld = oft_utils::remove_dust(amount_ld - fee, conversion_rate);
|
|
104
99
|
(amount_ld, amount_received_ld)
|
|
105
100
|
};
|
|
106
101
|
|
|
107
102
|
assert_with_error!(env, amount_received_ld >= min_amount_ld, OFTError::SlippageExceeded);
|
|
108
103
|
|
|
109
|
-
|
|
104
|
+
(amount_sent_ld, amount_received_ld)
|
|
110
105
|
}
|
|
111
106
|
|
|
112
|
-
fn __debit(env: &Env, sender: &Address, amount_ld: i128, min_amount_ld: i128, dst_eid: u32) ->
|
|
107
|
+
fn __debit(env: &Env, sender: &Address, amount_ld: i128, min_amount_ld: i128, dst_eid: u32) -> (i128, i128) {
|
|
113
108
|
// Core debit logic (based on oft_type)
|
|
114
|
-
let
|
|
115
|
-
OftType::LockUnlock =>
|
|
116
|
-
|
|
109
|
+
let (amount_sent_ld, amount_received_ld) = match Self::oft_type(env) {
|
|
110
|
+
OftType::LockUnlock => {
|
|
111
|
+
lock_unlock::debit::<Self>(env, &Self::token(env), sender, amount_ld, min_amount_ld, dst_eid)
|
|
112
|
+
}
|
|
113
|
+
OftType::MintBurn(mint_burnable) => {
|
|
114
|
+
mint_burn::debit::<Self>(env, &mint_burnable, sender, amount_ld, min_amount_ld, dst_eid)
|
|
115
|
+
}
|
|
117
116
|
};
|
|
118
117
|
|
|
119
118
|
// Rate limit checks (using amount_received_ld - the actual cross-chain amount)
|
|
120
|
-
Self::__consume_rate_limit_capacity(env, &Direction::Outbound, dst_eid,
|
|
121
|
-
Self::__release_rate_limit_capacity(env, &Direction::Inbound, dst_eid,
|
|
119
|
+
Self::__consume_rate_limit_capacity(env, &Direction::Outbound, dst_eid, amount_received_ld);
|
|
120
|
+
Self::__release_rate_limit_capacity(env, &Direction::Inbound, dst_eid, amount_received_ld);
|
|
122
121
|
|
|
123
122
|
// Charge fee
|
|
124
|
-
let fee =
|
|
125
|
-
Self::__charge_fee(env, &Self::
|
|
123
|
+
let fee = amount_sent_ld - amount_received_ld;
|
|
124
|
+
Self::__charge_fee(env, &Self::token(env), sender, fee);
|
|
126
125
|
|
|
127
|
-
|
|
126
|
+
(amount_sent_ld, amount_received_ld)
|
|
128
127
|
}
|
|
129
128
|
|
|
130
129
|
fn __credit(env: &Env, to: &Address, amount_ld: i128, src_eid: u32) -> i128 {
|
|
@@ -133,8 +132,8 @@ impl OFTInternal for OFT {
|
|
|
133
132
|
|
|
134
133
|
// Core credit logic (based on mode)
|
|
135
134
|
let amount_credited = match Self::oft_type(env) {
|
|
136
|
-
OftType::LockUnlock => lock_unlock::credit::<Self>(env, to, amount_ld, src_eid),
|
|
137
|
-
OftType::MintBurn => mint_burn::credit::<Self>(env, to, amount_ld, src_eid),
|
|
135
|
+
OftType::LockUnlock => lock_unlock::credit::<Self>(env, &Self::token(env), to, amount_ld, src_eid),
|
|
136
|
+
OftType::MintBurn(mint_burnable) => mint_burn::credit::<Self>(env, &mint_burnable, to, amount_ld, src_eid),
|
|
138
137
|
};
|
|
139
138
|
|
|
140
139
|
// Rate limit checks
|
|
@@ -2,45 +2,49 @@
|
|
|
2
2
|
//!
|
|
3
3
|
//! This OFT type locks tokens in the contract on debit (send) and unlocks
|
|
4
4
|
//! tokens from the contract on credit (receive).
|
|
5
|
-
//!
|
|
5
|
+
//! Operates directly on the token via standard SEP-41 `transfer`.
|
|
6
6
|
|
|
7
|
-
use oft_core::
|
|
7
|
+
use oft_core::OFTCore;
|
|
8
8
|
use soroban_sdk::{token::TokenClient, Address, Env};
|
|
9
9
|
|
|
10
10
|
/// Debit tokens using LockUnlock OFT type (locks tokens in contract).
|
|
11
11
|
///
|
|
12
12
|
/// # Parameters
|
|
13
13
|
/// * `env` - The Soroban environment
|
|
14
|
+
/// * `token` - Address of the token
|
|
14
15
|
/// * `sender` - Address of the token sender
|
|
15
16
|
/// * `amount_ld` - Amount to debit in local decimals
|
|
16
17
|
/// * `min_amount_ld` - Minimum amount that must be received (for slippage protection)
|
|
17
18
|
/// * `dst_eid` - Destination endpoint ID
|
|
18
19
|
///
|
|
19
20
|
/// # Returns
|
|
20
|
-
/// `
|
|
21
|
+
/// * `amount_sent_ld` - The amount sent in local decimals
|
|
22
|
+
/// * `amount_received_ld` - The amount received in local decimals on the remote
|
|
21
23
|
pub fn debit<T: OFTCore>(
|
|
22
24
|
env: &Env,
|
|
25
|
+
token: &Address,
|
|
23
26
|
sender: &Address,
|
|
24
27
|
amount_ld: i128,
|
|
25
28
|
min_amount_ld: i128,
|
|
26
29
|
dst_eid: u32,
|
|
27
|
-
) ->
|
|
28
|
-
let
|
|
29
|
-
TokenClient::new(env,
|
|
30
|
-
|
|
30
|
+
) -> (i128, i128) {
|
|
31
|
+
let (amount_sent_ld, amount_received_ld) = T::__debit_view(env, amount_ld, min_amount_ld, dst_eid);
|
|
32
|
+
TokenClient::new(env, token).transfer(sender, env.current_contract_address(), &amount_received_ld);
|
|
33
|
+
(amount_sent_ld, amount_received_ld)
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
/// Credit tokens using LockUnlock OFT type (unlocks tokens from contract).
|
|
34
37
|
///
|
|
35
38
|
/// # Parameters
|
|
36
39
|
/// * `env` - The Soroban environment
|
|
40
|
+
/// * `token` - Address of the token
|
|
37
41
|
/// * `to` - Address of the token recipient
|
|
38
42
|
/// * `amount_ld` - Amount to credit in local decimals
|
|
39
43
|
/// * `_src_eid` - Source endpoint ID (unused)
|
|
40
44
|
///
|
|
41
45
|
/// # Returns
|
|
42
46
|
/// The amount credited
|
|
43
|
-
pub fn credit<T: OFTCore>(env: &Env, to: &Address, amount_ld: i128, _src_eid: u32) -> i128 {
|
|
44
|
-
TokenClient::new(env,
|
|
47
|
+
pub fn credit<T: OFTCore>(env: &Env, token: &Address, to: &Address, amount_ld: i128, _src_eid: u32) -> i128 {
|
|
48
|
+
TokenClient::new(env, token).transfer(&env.current_contract_address(), to, &amount_ld);
|
|
45
49
|
amount_ld
|
|
46
50
|
}
|