Skip to content

Commit 102a8f2

Browse files
authored
cleanup liquid staking (#1592)
Signed-off-by: Cheng JIANG <alex_cj96@foxmail.com>
1 parent 840baed commit 102a8f2

6 files changed

Lines changed: 79 additions & 58 deletions

File tree

pallets/crowdloans/src/lib.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -966,9 +966,7 @@ pub mod pallet {
966966
);
967967

968968
'outer: for kind in [Contributed, Flying, Pending] {
969-
for (who, (amount, referral_code)) in
970-
Self::contribution_iterator(vault.trie_index, kind)
971-
{
969+
for (who, (amount, _)) in Self::contribution_iterator(vault.trie_index, kind) {
972970
if refund_count >= T::RemoveKeysLimit::get() {
973971
all_refunded = false;
974972
break 'outer;
@@ -994,7 +992,7 @@ pub mod pallet {
994992
&who,
995993
&mut vault,
996994
amount,
997-
Some(referral_code.clone()),
995+
None,
998996
ArithmeticKind::Subtraction,
999997
kind,
1000998
)?;

pallets/liquid-staking/src/distribution.rs

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,64 +7,71 @@ use sp_std::vec::Vec;
77
pub struct AverageDistribution;
88
impl<Balance: BalanceT + FixedPointOperand> DistributionStrategy<Balance> for AverageDistribution {
99
fn get_bond_distributions(
10-
bonding_amounts: &mut Vec<(DerivativeIndex, Balance)>,
10+
bonded_amounts: Vec<(DerivativeIndex, Balance)>,
1111
input: Balance,
1212
cap: Balance,
1313
min_nominator_bond: Balance,
1414
) -> Vec<(DerivativeIndex, Balance)> {
15-
let length = TryInto::<Balance>::try_into(bonding_amounts.len()).unwrap_or_default();
15+
let length = TryInto::<Balance>::try_into(bonded_amounts.len()).unwrap_or_default();
1616
if length.is_zero() {
1717
return Default::default();
1818
}
19+
1920
let mut distributions: Vec<(DerivativeIndex, Balance)> = vec![];
2021
let amount = input.checked_div(&length).unwrap_or_default();
21-
for (index, bonded) in bonding_amounts.iter() {
22-
if amount.saturating_add(*bonded) < min_nominator_bond {
22+
for (index, bonded) in bonded_amounts.into_iter() {
23+
if amount.saturating_add(bonded) < min_nominator_bond {
24+
continue;
25+
}
26+
let amount = cap.saturating_sub(bonded).min(amount);
27+
if amount.is_zero() {
2328
continue;
2429
}
25-
let amount = cap.saturating_sub(*bonded).min(amount);
26-
distributions.push((*index, amount));
30+
distributions.push((index, amount));
2731
}
2832

2933
distributions
3034
}
3135

3236
fn get_unbond_distributions(
33-
bonding_amounts: &mut Vec<(DerivativeIndex, Balance)>,
37+
bonded_amounts: Vec<(DerivativeIndex, Balance)>,
3438
input: Balance,
3539
_cap: Balance,
3640
min_nominator_bond: Balance,
3741
) -> Vec<(DerivativeIndex, Balance)> {
38-
let length = TryInto::<Balance>::try_into(bonding_amounts.len()).unwrap_or_default();
42+
let length = TryInto::<Balance>::try_into(bonded_amounts.len()).unwrap_or_default();
3943
if length.is_zero() {
4044
return Default::default();
4145
}
46+
4247
let mut distributions: Vec<(DerivativeIndex, Balance)> = vec![];
4348
let amount = input.checked_div(&length).unwrap_or_default();
44-
for (index, bonded) in bonding_amounts.iter() {
49+
for (index, bonded) in bonded_amounts.into_iter() {
4550
if bonded.saturating_sub(amount) < min_nominator_bond {
4651
continue;
4752
}
48-
distributions.push((*index, amount));
53+
distributions.push((index, amount));
4954
}
5055

5156
distributions
5257
}
5358

5459
fn get_rebond_distributions(
55-
unbonding_amounts: &mut Vec<(DerivativeIndex, Balance, Balance)>,
60+
unbonding_bonded_amounts: Vec<(DerivativeIndex, Balance, Balance)>,
5661
input: Balance,
5762
_cap: Balance,
5863
_min_nominator_bond: Balance,
5964
) -> Vec<(DerivativeIndex, Balance)> {
60-
let length = TryInto::<Balance>::try_into(unbonding_amounts.len()).unwrap_or_default();
65+
let length =
66+
TryInto::<Balance>::try_into(unbonding_bonded_amounts.len()).unwrap_or_default();
6167
if length.is_zero() {
6268
return Default::default();
6369
}
70+
6471
let mut distributions: Vec<(DerivativeIndex, Balance)> = vec![];
6572
let amount = input.checked_div(&length).unwrap_or_default();
66-
for (index, _, _) in unbonding_amounts.iter() {
67-
distributions.push((*index, amount));
73+
for (index, _, _) in unbonding_bonded_amounts.into_iter() {
74+
distributions.push((index, amount));
6875
}
6976

7077
distributions
@@ -76,86 +83,86 @@ impl<Balance: BalanceT + FixedPointOperand> DistributionStrategy<Balance>
7683
for MaximizationDistribution
7784
{
7885
fn get_bond_distributions(
79-
bonding_amounts: &mut Vec<(DerivativeIndex, Balance)>,
86+
mut bonded_amounts: Vec<(DerivativeIndex, Balance)>,
8087
input: Balance,
8188
cap: Balance,
8289
min_nominator_bond: Balance,
8390
) -> Vec<(DerivativeIndex, Balance)> {
84-
//ascending sequence
85-
bonding_amounts.sort_by(|a, b| a.1.cmp(&b.1));
91+
// ascending sequence
92+
bonded_amounts.sort_by(|a, b| a.1.cmp(&b.1));
8693

8794
let mut distributions: Vec<(DerivativeIndex, Balance)> = vec![];
8895
let mut remain = input;
8996

90-
for (index, bonded) in bonding_amounts.iter() {
97+
for (index, bonded) in bonded_amounts.into_iter() {
9198
if remain.is_zero() {
9299
break;
93100
}
94-
let amount = cap.saturating_sub(*bonded).min(remain);
101+
let amount = cap.saturating_sub(bonded).min(remain);
95102
if amount.is_zero() {
96103
// `bonding_amounts` is an ascending sequence
97104
// if occurs an item that exceed the cap, the items after this one must all be exceeded
98105
break;
99106
}
100107

101-
if amount.saturating_add(*bonded) < min_nominator_bond {
108+
if amount.saturating_add(bonded) < min_nominator_bond {
102109
continue;
103110
}
104111

105-
distributions.push((*index, amount));
112+
distributions.push((index, amount));
106113
remain = remain.saturating_sub(amount);
107114
}
108115

109116
distributions
110117
}
111118

112119
fn get_unbond_distributions(
113-
bonding_amounts: &mut Vec<(DerivativeIndex, Balance)>,
120+
mut bonded_amounts: Vec<(DerivativeIndex, Balance)>,
114121
input: Balance,
115122
_cap: Balance,
116123
min_nominator_bond: Balance,
117124
) -> Vec<(DerivativeIndex, Balance)> {
118125
// descending sequence
119-
bonding_amounts.sort_by(|a, b| b.1.cmp(&a.1));
126+
bonded_amounts.sort_by(|a, b| b.1.cmp(&a.1));
120127

121128
let mut distributions: Vec<(DerivativeIndex, Balance)> = vec![];
122129
let mut remain = input;
123130

124-
for (index, bonded) in bonding_amounts.iter() {
131+
for (index, bonded) in bonded_amounts.into_iter() {
125132
if remain.is_zero() {
126133
break;
127134
}
128135
let amount = remain.min(bonded.saturating_sub(min_nominator_bond));
129136
if amount.is_zero() {
130137
continue;
131138
}
132-
distributions.push((*index, amount));
139+
distributions.push((index, amount));
133140
remain = remain.saturating_sub(amount);
134141
}
135142

136143
distributions
137144
}
138145
fn get_rebond_distributions(
139-
unbonding_amounts: &mut Vec<(DerivativeIndex, Balance, Balance)>,
146+
mut unbonding_bonded_amounts: Vec<(DerivativeIndex, Balance, Balance)>,
140147
input: Balance,
141148
cap: Balance,
142149
_min_nominator_bond: Balance,
143150
) -> Vec<(DerivativeIndex, Balance)> {
144151
// descending sequence
145-
unbonding_amounts.sort_by(|a, b| b.1.cmp(&a.1));
152+
unbonding_bonded_amounts.sort_by(|a, b| b.1.cmp(&a.1));
146153

147154
let mut distributions: Vec<(DerivativeIndex, Balance)> = vec![];
148155
let mut remain = input;
149156

150-
for (index, unlocking, active) in unbonding_amounts.iter() {
157+
for (index, unbonding, bonded) in unbonding_bonded_amounts.into_iter() {
151158
if remain.is_zero() {
152159
break;
153160
}
154-
let amount = remain.min(*unlocking).min(cap.saturating_sub(*active));
161+
let amount = remain.min(unbonding).min(cap.saturating_sub(bonded));
155162
if amount.is_zero() {
156163
continue;
157164
}
158-
distributions.push((*index, amount));
165+
distributions.push((index, amount));
159166
remain = remain.saturating_sub(amount);
160167
}
161168

pallets/liquid-staking/src/lib.rs

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -799,12 +799,17 @@ pub mod pallet {
799799

800800
Self::do_update_ledger(derivative_index, |ledger| {
801801
ensure!(
802-
!Self::is_updated(derivative_index),
802+
!Self::is_updated(derivative_index)
803+
|| !XcmRequests::<T>::iter().count().is_zero(),
803804
Error::<T>::StakingLedgerLocked
804805
);
806+
// only allow to feed rewards
807+
// slashes should be handled properly offchain
805808
ensure!(
806-
ledger.active >= T::MinNominatorBond::get(),
807-
Error::<T>::InsufficientBond
809+
staking_ledger.total > ledger.total
810+
&& staking_ledger.active > ledger.active
811+
&& staking_ledger.unlocking == ledger.unlocking,
812+
Error::<T>::InvalidStakingLedger
808813
);
809814
let key = Self::get_staking_ledger_key(derivative_index);
810815
let value = staking_ledger.encode();
@@ -895,10 +900,9 @@ pub mod pallet {
895900

896901
/// Get total unclaimed
897902
pub fn get_total_unclaimed(staking_currency: AssetIdOf<T>) -> BalanceOf<T> {
898-
let matching_pool = Self::matching_pool();
899903
T::Assets::reducible_balance(staking_currency, &Self::account_id(), false)
900904
.saturating_sub(Self::total_reserves())
901-
.saturating_sub(matching_pool.total_stake_amount.total)
905+
.saturating_sub(Self::matching_pool().total_stake_amount.total)
902906
}
903907

904908
/// Derivative of parachain's account
@@ -919,11 +923,18 @@ pub mod pallet {
919923
Self::staking_ledger(&index).map_or(Zero::zero(), |ledger| ledger.active)
920924
}
921925

922-
// fn unbonding_of(index: DerivativeIndex) -> BalanceOf<T> {
923-
// Self::staking_ledger(&index).map_or(Zero::zero(), |ledger| {
924-
// ledger.total.saturating_sub(ledger.active)
925-
// })
926-
// }
926+
fn unbonding_of(index: DerivativeIndex) -> BalanceOf<T> {
927+
let current_era = Self::current_era();
928+
Self::staking_ledger(&index).map_or(Zero::zero(), |ledger| {
929+
ledger.unlocking.iter().fold(Zero::zero(), |acc, chunk| {
930+
if chunk.era > current_era {
931+
acc.saturating_add(chunk.value)
932+
} else {
933+
acc
934+
}
935+
})
936+
})
937+
}
927938

928939
fn unbonded_of(index: DerivativeIndex) -> BalanceOf<T> {
929940
let current_era = Self::current_era();
@@ -940,7 +951,6 @@ pub mod pallet {
940951

941952
fn get_total_unbonding() -> BalanceOf<T> {
942953
StakingLedgers::<T>::iter_values().fold(Zero::zero(), |acc, ledger| {
943-
// FIXME: Confirm if it's better to calculate total unlocking amount
944954
acc.saturating_add(ledger.total.saturating_sub(ledger.active))
945955
})
946956
}
@@ -1275,12 +1285,13 @@ pub mod pallet {
12751285
if total_amount.is_zero() {
12761286
return Ok(());
12771287
}
1278-
let mut amounts: Vec<(DerivativeIndex, BalanceOf<T>)> = T::DerivativeIndexList::get()
1288+
1289+
let amounts: Vec<(DerivativeIndex, BalanceOf<T>)> = T::DerivativeIndexList::get()
12791290
.iter()
12801291
.map(|&index| (index, Self::bonded_of(index)))
12811292
.collect();
12821293
let distributions = T::DistributionStrategy::get_bond_distributions(
1283-
&mut amounts,
1294+
amounts,
12841295
total_amount,
12851296
Self::staking_ledger_cap(),
12861297
T::MinNominatorBond::get(),
@@ -1298,12 +1309,13 @@ pub mod pallet {
12981309
if total_amount.is_zero() {
12991310
return Ok(());
13001311
}
1301-
let mut amounts: Vec<(DerivativeIndex, BalanceOf<T>)> = T::DerivativeIndexList::get()
1312+
1313+
let amounts: Vec<(DerivativeIndex, BalanceOf<T>)> = T::DerivativeIndexList::get()
13021314
.iter()
13031315
.map(|&index| (index, Self::bonded_of(index)))
13041316
.collect();
13051317
let distributions = T::DistributionStrategy::get_unbond_distributions(
1306-
&mut amounts,
1318+
amounts,
13071319
total_amount,
13081320
Self::staking_ledger_cap(),
13091321
T::MinNominatorBond::get(),
@@ -1321,13 +1333,14 @@ pub mod pallet {
13211333
if total_amount.is_zero() {
13221334
return Ok(());
13231335
}
1324-
let mut amounts: Vec<(DerivativeIndex, BalanceOf<T>, BalanceOf<T>)> =
1336+
1337+
let amounts: Vec<(DerivativeIndex, BalanceOf<T>, BalanceOf<T>)> =
13251338
T::DerivativeIndexList::get()
13261339
.iter()
1327-
.map(|&index| (index, Self::unbonded_of(index), Self::bonded_of(index)))
1340+
.map(|&index| (index, Self::unbonding_of(index), Self::bonded_of(index)))
13281341
.collect();
13291342
let distributions = T::DistributionStrategy::get_rebond_distributions(
1330-
&mut amounts,
1343+
amounts,
13311344
total_amount,
13321345
Self::staking_ledger_cap(),
13331346
T::MinNominatorBond::get(),
@@ -1450,7 +1463,6 @@ pub mod pallet {
14501463
#[require_transactional]
14511464
fn do_update_exchange_rate() -> DispatchResult {
14521465
let matching_ledger = Self::matching_pool();
1453-
//TODO: use ledger.total or ledger.active?
14541466
let total_bonded = Self::get_total_active_bonded();
14551467
let issuance = T::Assets::total_issuance(Self::liquid_currency()?);
14561468
if issuance.is_zero() {
@@ -1556,7 +1568,6 @@ pub mod pallet {
15561568
derivative_index: DerivativeIndex,
15571569
amount: BalanceOf<T>,
15581570
) -> DispatchResult {
1559-
// FIXME: confirm use ledger.active or ledger.total
15601571
ensure!(
15611572
Self::bonded_of(derivative_index).saturating_add(amount)
15621573
<= Self::staking_ledger_cap(),

pallets/traits/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,19 @@ pub trait ValidationDataProvider {
9090
/// Distribute liquidstaking asset to multi-accounts
9191
pub trait DistributionStrategy<Balance> {
9292
fn get_bond_distributions(
93-
active_bonded_amount: &mut Vec<(DerivativeIndex, Balance)>,
93+
bonded_amounts: Vec<(DerivativeIndex, Balance)>,
9494
input: Balance,
9595
cap: Balance,
9696
min_nominator_bond: Balance,
9797
) -> Vec<(DerivativeIndex, Balance)>;
9898
fn get_unbond_distributions(
99-
active_bonded_amount: &mut Vec<(DerivativeIndex, Balance)>,
99+
bonded_amounts: Vec<(DerivativeIndex, Balance)>,
100100
input: Balance,
101101
cap: Balance,
102102
min_nominator_bond: Balance,
103103
) -> Vec<(DerivativeIndex, Balance)>;
104104
fn get_rebond_distributions(
105-
unlocking_amount: &mut Vec<(DerivativeIndex, Balance, Balance)>,
105+
unbonding_bonded_amounts: Vec<(DerivativeIndex, Balance, Balance)>,
106106
input: Balance,
107107
cap: Balance,
108108
min_nominator_bond: Balance,

pallets/xcm-helper/src/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::*;
22
use crate::mock::{Call as TestCall, *};
33
use frame_support::{assert_noop, assert_ok};
4-
use pallet_traits::ump::*;
4+
55
use primitives::tokens::DOT;
66
use sp_runtime::traits::{One, Zero};
77

primitives/src/tokens.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,20 @@ pub const LP_USDT_HKO: CurrencyId = 5000;
7474
pub const LP_KSM_USDT: CurrencyId = 5001;
7575
pub const LP_KSM_HKO: CurrencyId = 5002;
7676
pub const LP_KSM_SKSM: CurrencyId = 5003;
77+
pub const LP_KSM_CKSM_20_27: CurrencyId = 5004;
7778

7879
pub const LP_USDT_PARA: CurrencyId = 6000;
7980
pub const LP_DOT_USDT: CurrencyId = 6001;
8081
pub const LP_DOT_PARA: CurrencyId = 6002;
8182
pub const LP_DOT_SDOT: CurrencyId = 6003;
83+
pub const LP_DOT_CDOT_6_13: CurrencyId = 6004;
84+
pub const LP_DOT_CDOT_7_14: CurrencyId = 6005;
85+
pub const LP_PARA_CDOT_6_13: CurrencyId = 6006;
8286

8387
// Crowdloan Derivative
8488
pub const CKSM_15_22: CurrencyId = 100150022;
8589
pub const CKSM_20_27: CurrencyId = 100200027;
90+
pub const CKSM_21_28: CurrencyId = 100210028;
8691
pub const CDOT_6_13: CurrencyId = 200060013;
8792
pub const CDOT_7_14: CurrencyId = 200070014;
8893
pub const CDOT_8_15: CurrencyId = 200080015;

0 commit comments

Comments
 (0)