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 fn is_sufficient(asset: Self::AssetId) -> bool {
112 pallet_assets::Pallet::<T, I>::is_sufficient(asset)
113 }
114}
115
116impl<T: Config<I>, I: 'static> InspectFreeze<T::AccountId> for Pallet<T, I> {
117 type Id = T::RuntimeFreezeReason;
118
119 fn balance_frozen(asset: Self::AssetId, id: &Self::Id, who: &T::AccountId) -> Self::Balance {
120 let freezes = Freezes::<T, I>::get(asset, who);
121 freezes.into_iter().find(|l| &l.id == id).map_or(Zero::zero(), |l| l.amount)
122 }
123
124 fn can_freeze(asset: Self::AssetId, id: &Self::Id, who: &T::AccountId) -> bool {
125 let freezes = Freezes::<T, I>::get(asset, who);
126 !freezes.is_full() || freezes.into_iter().any(|i| i.id == *id)
127 }
128}
129
130impl<T: Config<I>, I: 'static> MutateFreeze<T::AccountId> for Pallet<T, I> {
131 fn set_freeze(
132 asset: Self::AssetId,
133 id: &Self::Id,
134 who: &T::AccountId,
135 amount: Self::Balance,
136 ) -> DispatchResult {
137 if amount.is_zero() {
138 return Self::thaw(asset, id, who);
139 }
140 let mut freezes = Freezes::<T, I>::get(asset.clone(), who);
141 if let Some(i) = freezes.iter_mut().find(|i| &i.id == id) {
142 i.amount = amount;
143 } else {
144 freezes
145 .try_push(IdAmount { id: *id, amount })
146 .map_err(|_| Error::<T, I>::TooManyFreezes)?;
147 }
148 Self::update_freezes(asset, who, freezes.as_bounded_slice())
149 }
150
151 fn extend_freeze(
152 asset: Self::AssetId,
153 id: &Self::Id,
154 who: &T::AccountId,
155 amount: Self::Balance,
156 ) -> DispatchResult {
157 if amount.is_zero() {
158 return Ok(());
159 }
160 let mut freezes = Freezes::<T, I>::get(asset.clone(), who);
161 if let Some(i) = freezes.iter_mut().find(|x| &x.id == id) {
162 i.amount = i.amount.max(amount);
163 } else {
164 freezes
165 .try_push(IdAmount { id: *id, amount })
166 .map_err(|_| Error::<T, I>::TooManyFreezes)?;
167 }
168 Self::update_freezes(asset, who, freezes.as_bounded_slice())
169 }
170
171 fn thaw(asset: Self::AssetId, id: &Self::Id, who: &T::AccountId) -> DispatchResult {
172 let mut freezes = Freezes::<T, I>::get(asset.clone(), who);
173 freezes.retain(|f| &f.id != id);
174 Self::update_freezes(asset, who, freezes.as_bounded_slice())
175 }
176}