1use super::*;
25use frame::prelude::storage::StorageDoubleMap;
26use pallet_assets::FrozenBalance;
27
28impl<T: Config<I>, I: 'static> FrozenBalance<T::AssetId, T::AccountId, T::Balance>
32 for Pallet<T, I>
33{
34 fn frozen_balance(asset: T::AssetId, who: &T::AccountId) -> Option<T::Balance> {
35 FrozenBalances::<T, I>::get(asset, who)
36 }
37
38 fn died(asset: T::AssetId, who: &T::AccountId) {
39 defensive_assert!(
40 Freezes::<T, I>::get(asset.clone(), who).is_empty(),
41 "The list of Freezes should be empty before allowing an account to die"
42 );
43 defensive_assert!(
44 FrozenBalances::<T, I>::get(asset.clone(), who).is_none(),
45 "There should not be a frozen balance before allowing to die"
46 );
47
48 FrozenBalances::<T, I>::remove(asset.clone(), who);
49 Freezes::<T, I>::remove(asset, who);
50 }
51
52 fn contains_freezes(asset: T::AssetId) -> bool {
53 Freezes::<T, I>::contains_prefix(asset)
54 }
55}
56
57impl<T: Config<I>, I: 'static> Inspect<T::AccountId> for Pallet<T, I> {
62 type AssetId = T::AssetId;
63 type Balance = T::Balance;
64
65 fn total_issuance(asset: Self::AssetId) -> Self::Balance {
66 pallet_assets::Pallet::<T, I>::total_issuance(asset)
67 }
68
69 fn minimum_balance(asset: Self::AssetId) -> Self::Balance {
70 pallet_assets::Pallet::<T, I>::minimum_balance(asset)
71 }
72
73 fn total_balance(asset: Self::AssetId, who: &T::AccountId) -> Self::Balance {
74 pallet_assets::Pallet::<T, I>::total_balance(asset, who)
75 }
76
77 fn balance(asset: Self::AssetId, who: &T::AccountId) -> Self::Balance {
78 pallet_assets::Pallet::<T, I>::balance(asset, who)
79 }
80
81 fn reducible_balance(
82 asset: Self::AssetId,
83 who: &T::AccountId,
84 preservation: Preservation,
85 force: Fortitude,
86 ) -> Self::Balance {
87 pallet_assets::Pallet::<T, I>::reducible_balance(asset, who, preservation, force)
88 }
89
90 fn can_deposit(
91 asset: Self::AssetId,
92 who: &T::AccountId,
93 amount: Self::Balance,
94 provenance: Provenance,
95 ) -> DepositConsequence {
96 pallet_assets::Pallet::<T, I>::can_deposit(asset, who, amount, provenance)
97 }
98
99 fn can_withdraw(
100 asset: Self::AssetId,
101 who: &T::AccountId,
102 amount: Self::Balance,
103 ) -> WithdrawConsequence<Self::Balance> {
104 pallet_assets::Pallet::<T, I>::can_withdraw(asset, who, amount)
105 }
106
107 fn asset_exists(asset: Self::AssetId) -> bool {
108 pallet_assets::Pallet::<T, I>::asset_exists(asset)
109 }
110}
111
112impl<T: Config<I>, I: 'static> InspectFreeze<T::AccountId> for Pallet<T, I> {
113 type Id = T::RuntimeFreezeReason;
114
115 fn balance_frozen(asset: Self::AssetId, id: &Self::Id, who: &T::AccountId) -> Self::Balance {
116 let freezes = Freezes::<T, I>::get(asset, who);
117 freezes.into_iter().find(|l| &l.id == id).map_or(Zero::zero(), |l| l.amount)
118 }
119
120 fn can_freeze(asset: Self::AssetId, id: &Self::Id, who: &T::AccountId) -> bool {
121 let freezes = Freezes::<T, I>::get(asset, who);
122 !freezes.is_full() || freezes.into_iter().any(|i| i.id == *id)
123 }
124}
125
126impl<T: Config<I>, I: 'static> MutateFreeze<T::AccountId> for Pallet<T, I> {
127 fn set_freeze(
128 asset: Self::AssetId,
129 id: &Self::Id,
130 who: &T::AccountId,
131 amount: Self::Balance,
132 ) -> DispatchResult {
133 if amount.is_zero() {
134 return Self::thaw(asset, id, who);
135 }
136 let mut freezes = Freezes::<T, I>::get(asset.clone(), who);
137 if let Some(i) = freezes.iter_mut().find(|i| &i.id == id) {
138 i.amount = amount;
139 } else {
140 freezes
141 .try_push(IdAmount { id: *id, amount })
142 .map_err(|_| Error::<T, I>::TooManyFreezes)?;
143 }
144 Self::update_freezes(asset, who, freezes.as_bounded_slice())
145 }
146
147 fn extend_freeze(
148 asset: Self::AssetId,
149 id: &Self::Id,
150 who: &T::AccountId,
151 amount: Self::Balance,
152 ) -> DispatchResult {
153 if amount.is_zero() {
154 return Ok(());
155 }
156 let mut freezes = Freezes::<T, I>::get(asset.clone(), who);
157 if let Some(i) = freezes.iter_mut().find(|x| &x.id == id) {
158 i.amount = i.amount.max(amount);
159 } else {
160 freezes
161 .try_push(IdAmount { id: *id, amount })
162 .map_err(|_| Error::<T, I>::TooManyFreezes)?;
163 }
164 Self::update_freezes(asset, who, freezes.as_bounded_slice())
165 }
166
167 fn thaw(asset: Self::AssetId, id: &Self::Id, who: &T::AccountId) -> DispatchResult {
168 let mut freezes = Freezes::<T, I>::get(asset.clone(), who);
169 freezes.retain(|f| &f.id != id);
170 Self::update_freezes(asset, who, freezes.as_bounded_slice())
171 }
172}