@@ -78,7 +78,7 @@ pub struct ProxyDefinition<AccountId, ProxyType, BlockNumber> {
78
78
/// The maximun amount that can be transferred by this proxy.
79
79
pub max_amount : Option < BalanceOf < T > > ,
80
80
/// The block number until which the limit is valid.
81
- pub valid_unil : BlockNumber ,
81
+ pub valid_until : BlockNumber ,
82
82
}
83
83
84
84
/// Details surrounding a specific instance of an announcement to make a call.
@@ -92,6 +92,26 @@ pub struct Announcement<AccountId, Hash, BlockNumber> {
92
92
height : BlockNumber ,
93
93
}
94
94
95
+ /// The type of deposit
96
+ #[ derive(
97
+ Encode ,
98
+ Decode ,
99
+ Clone ,
100
+ Copy ,
101
+ Eq ,
102
+ PartialEq ,
103
+ RuntimeDebug ,
104
+ MaxEncodedLen ,
105
+ TypeInfo ,
106
+ DecodeWithMemTracking ,
107
+ ) ]
108
+ pub enum DepositKind {
109
+ /// Proxy registration deposit
110
+ Proxies ,
111
+ /// Announcement deposit
112
+ Announcements ,
113
+ }
114
+
95
115
#[ frame:: pallet]
96
116
pub mod pallet {
97
117
use super :: * ;
@@ -147,17 +167,16 @@ pub mod pallet {
147
167
#[ pallet:: constant]
148
168
type MaxProxies : Get < u32 > ;
149
169
170
+ #[ pallet:: constant]
171
+ type MaxTransferAmount : Get < BalanceOf < Self > > ;
172
+
150
173
/// Weight information for extrinsics in this pallet.
151
174
type WeightInfo : WeightInfo ;
152
175
153
176
/// The maximum amount of time-delayed announcements that are allowed to be pending.
154
177
#[ pallet:: constant]
155
178
type MaxPending : Get < u32 > ;
156
179
157
- #[ pallet:: constant]
158
- type MaxTransferAmount : Get < BalanceOf < Self > > ;
159
-
160
-
161
180
/// The type of hash used for hashing the call.
162
181
type CallHasher : Hash ;
163
182
@@ -252,12 +271,10 @@ pub mod pallet {
252
271
delegate : AccountIdLookupOf < T > ,
253
272
proxy_type : T :: ProxyType ,
254
273
delay : BlockNumberFor < T > ,
255
- max_amount : Option < BalanceOf < T > > ,
256
- valid_unil : BlockNumberFor < T > ,
257
274
) -> DispatchResult {
258
275
let who = ensure_signed ( origin) ?;
259
276
let delegate = T :: Lookup :: lookup ( delegate) ?;
260
- Self :: add_proxy_delegate ( & who, delegate, proxy_type, delay, max_amount , valid_unil )
277
+ Self :: add_proxy_delegate ( & who, delegate, proxy_type, delay)
261
278
}
262
279
263
280
/// Unregister a proxy account for the sender.
@@ -319,16 +336,14 @@ pub mod pallet {
319
336
proxy_type : T :: ProxyType ,
320
337
delay : BlockNumberFor < T > ,
321
338
index : u16 ,
322
- max_amount : Option < BalanceOf < T > > ,
323
- valid_unil : BlockNumberFor < T > ,
324
339
) -> DispatchResult {
325
340
let who = ensure_signed ( origin) ?;
326
341
327
342
let pure = Self :: pure_account ( & who, & proxy_type, index, None ) ;
328
343
ensure ! ( !Proxies :: <T >:: contains_key( & pure) , Error :: <T >:: Duplicate ) ;
329
344
330
345
let proxy_def =
331
- ProxyDefinition { delegate : who. clone ( ) , proxy_type : proxy_type. clone ( ) , delay, max_amount , valid_unil } ;
346
+ ProxyDefinition { delegate : who. clone ( ) , proxy_type : proxy_type. clone ( ) , delay } ;
332
347
let bounded_proxies: BoundedVec < _ , T :: MaxProxies > =
333
348
vec ! [ proxy_def] . try_into ( ) . map_err ( |_| Error :: < T > :: TooMany ) ?;
334
349
@@ -541,6 +556,105 @@ pub mod pallet {
541
556
542
557
Ok ( ( ) )
543
558
}
559
+
560
+ /// Poke / Adjust deposits made for proxies and announcements based on current values.
561
+ /// This can be used by accounts to possibly lower their locked amount.
562
+ ///
563
+ /// The dispatch origin for this call must be _Signed_.
564
+ ///
565
+ /// The transaction fee is waived if the deposit amount has changed.
566
+ ///
567
+ /// Emits `DepositPoked` if successful.
568
+ #[ pallet:: call_index( 10 ) ]
569
+ #[ pallet:: weight( T :: WeightInfo :: poke_deposit( ) ) ]
570
+ pub fn poke_deposit ( origin : OriginFor < T > ) -> DispatchResultWithPostInfo {
571
+ let who = ensure_signed ( origin) ?;
572
+ let mut deposit_updated = false ;
573
+
574
+ // Check and update proxy deposits
575
+ Proxies :: < T > :: try_mutate_exists ( & who, |maybe_proxies| -> DispatchResult {
576
+ let ( proxies, old_deposit) = maybe_proxies. take ( ) . unwrap_or_default ( ) ;
577
+ let maybe_new_deposit = Self :: rejig_deposit (
578
+ & who,
579
+ old_deposit,
580
+ T :: ProxyDepositBase :: get ( ) ,
581
+ T :: ProxyDepositFactor :: get ( ) ,
582
+ proxies. len ( ) ,
583
+ ) ?;
584
+
585
+ match maybe_new_deposit {
586
+ Some ( new_deposit) if new_deposit != old_deposit => {
587
+ * maybe_proxies = Some ( ( proxies, new_deposit) ) ;
588
+ deposit_updated = true ;
589
+ Self :: deposit_event ( Event :: DepositPoked {
590
+ who : who. clone ( ) ,
591
+ kind : DepositKind :: Proxies ,
592
+ old_deposit,
593
+ new_deposit,
594
+ } ) ;
595
+ } ,
596
+ Some ( _) => {
597
+ * maybe_proxies = Some ( ( proxies, old_deposit) ) ;
598
+ } ,
599
+ None => {
600
+ * maybe_proxies = None ;
601
+ if !old_deposit. is_zero ( ) {
602
+ deposit_updated = true ;
603
+ Self :: deposit_event ( Event :: DepositPoked {
604
+ who : who. clone ( ) ,
605
+ kind : DepositKind :: Proxies ,
606
+ old_deposit,
607
+ new_deposit : BalanceOf :: < T > :: zero ( ) ,
608
+ } ) ;
609
+ }
610
+ } ,
611
+ }
612
+ Ok ( ( ) )
613
+ } ) ?;
614
+
615
+ // Check and update announcement deposits
616
+ Announcements :: < T > :: try_mutate_exists ( & who, |maybe_announcements| -> DispatchResult {
617
+ let ( announcements, old_deposit) = maybe_announcements. take ( ) . unwrap_or_default ( ) ;
618
+ let maybe_new_deposit = Self :: rejig_deposit (
619
+ & who,
620
+ old_deposit,
621
+ T :: AnnouncementDepositBase :: get ( ) ,
622
+ T :: AnnouncementDepositFactor :: get ( ) ,
623
+ announcements. len ( ) ,
624
+ ) ?;
625
+
626
+ match maybe_new_deposit {
627
+ Some ( new_deposit) if new_deposit != old_deposit => {
628
+ * maybe_announcements = Some ( ( announcements, new_deposit) ) ;
629
+ deposit_updated = true ;
630
+ Self :: deposit_event ( Event :: DepositPoked {
631
+ who : who. clone ( ) ,
632
+ kind : DepositKind :: Announcements ,
633
+ old_deposit,
634
+ new_deposit,
635
+ } ) ;
636
+ } ,
637
+ Some ( _) => {
638
+ * maybe_announcements = Some ( ( announcements, old_deposit) ) ;
639
+ } ,
640
+ None => {
641
+ * maybe_announcements = None ;
642
+ if !old_deposit. is_zero ( ) {
643
+ deposit_updated = true ;
644
+ Self :: deposit_event ( Event :: DepositPoked {
645
+ who : who. clone ( ) ,
646
+ kind : DepositKind :: Announcements ,
647
+ old_deposit,
648
+ new_deposit : BalanceOf :: < T > :: zero ( ) ,
649
+ } ) ;
650
+ }
651
+ } ,
652
+ }
653
+ Ok ( ( ) )
654
+ } ) ?;
655
+
656
+ Ok ( if deposit_updated { Pays :: No . into ( ) } else { Pays :: Yes . into ( ) } )
657
+ }
544
658
}
545
659
546
660
#[ pallet:: event]
@@ -572,6 +686,13 @@ pub mod pallet {
572
686
proxy_type : T :: ProxyType ,
573
687
delay : BlockNumberFor < T > ,
574
688
} ,
689
+ /// A deposit stored for proxies or announcements was poked / updated.
690
+ DepositPoked {
691
+ who : T :: AccountId ,
692
+ kind : DepositKind ,
693
+ old_deposit : BalanceOf < T > ,
694
+ new_deposit : BalanceOf < T > ,
695
+ } ,
575
696
}
576
697
577
698
#[ pallet:: error]
@@ -709,24 +830,14 @@ impl<T: Config> Pallet<T> {
709
830
proxy_type : T :: ProxyType ,
710
831
delay : BlockNumberFor < T > ,
711
832
max_amount : Option < BalanceOf < T > > ,
712
- valid_unil : BlockNumberFor < T > ,
833
+ valid_until : BlockNumberFor < T >
713
834
) -> DispatchResult {
714
835
ensure ! ( delegator != & delegatee, Error :: <T >:: NoSelfProxy ) ;
715
836
Proxies :: < T > :: try_mutate ( delegator, |( ref mut proxies, ref mut deposit) | {
716
837
let proxy_def = ProxyDefinition {
717
838
delegate : delegatee. clone ( ) ,
718
839
proxy_type : proxy_type. clone ( ) ,
719
840
delay,
720
- max_amount : if proxy_type == ProxyType :: AnyWithLimit {
721
- max_amount
722
- } else {
723
- None
724
- } ,
725
- valid_unil : if proxy_type = ProxyType :: AnyWithLimit {
726
- valid_unil
727
- } else {
728
- None
729
- } ,
730
841
} ;
731
842
let i = proxies. binary_search ( & proxy_def) . err ( ) . ok_or ( Error :: < T > :: Duplicate ) ?;
732
843
proxies. try_insert ( i, proxy_def) . map_err ( |_| Error :: < T > :: TooMany ) ?;
@@ -819,9 +930,16 @@ impl<T: Config> Pallet<T> {
819
930
let new_deposit =
820
931
if len == 0 { BalanceOf :: < T > :: zero ( ) } else { base + factor * ( len as u32 ) . into ( ) } ;
821
932
if new_deposit > old_deposit {
822
- T :: Currency :: reserve ( who, new_deposit - old_deposit) ?;
933
+ T :: Currency :: reserve ( who, new_deposit. saturating_sub ( old_deposit) ) ?;
823
934
} else if new_deposit < old_deposit {
824
- T :: Currency :: unreserve ( who, old_deposit - new_deposit) ;
935
+ let excess = old_deposit. saturating_sub ( new_deposit) ;
936
+ let remaining_unreserved = T :: Currency :: unreserve ( who, excess) ;
937
+ if !remaining_unreserved. is_zero ( ) {
938
+ defensive ! (
939
+ "Failed to unreserve full amount. (Requested, Actual)" ,
940
+ ( excess, excess. saturating_sub( remaining_unreserved) )
941
+ ) ;
942
+ }
825
943
}
826
944
Ok ( if len == 0 { None } else { Some ( new_deposit) } )
827
945
}
@@ -884,24 +1002,22 @@ impl<T: Config> Pallet<T> {
884
1002
Some ( Call :: remove_proxies { .. } ) | Some ( Call :: kill_pure { .. } )
885
1003
if def. proxy_type != T :: ProxyType :: default ( ) =>
886
1004
false ,
887
- // Enforce the max_amount and duration limits for `AnyWithLimit` proxies.
1005
+
888
1006
if def. proxy_type == ProxyType :: AnyWithLimit {
889
- if let Some ( Call :: Balances ( BalancesCall :: transfer_allow_death { value, .. } ) ) = c. is_sub_type( ) {
1007
+ if let Some ( Call :: Balances ( BalancesCall :: transfer_allow_death { value, .. } ) ) = c {
1008
+ // Check the proxy's max_amount limit
890
1009
if let Some ( max_amount) = def. max_amount {
891
1010
if * value > max_amount {
892
- return false ;
1011
+ return false ; // Reject the call if it exceeds the proxy's limit
893
1012
}
894
1013
}
895
- // Check the duration limit
896
- if let Some ( duration) = def. duration {
897
- let current_block = T :: BlockNumberProvider :: current_block_number ( ) ;
898
- if current_block > def. delay + valid_unil {
899
- return false ;
900
- }
1014
+ // Check the global MaxTransferAmount limit
1015
+ if * value > T :: MaxTransferAmount :: get( ) {
1016
+ return false ; // Reject the call if it exceeds the global limit
901
1017
}
902
1018
}
903
- def. proxy_type . filter ( c) ,
904
1019
}
1020
+ def. proxy_type . filter ( c) ,
905
1021
}
906
1022
} ) ;
907
1023
let e = call. dispatch ( origin) ;
@@ -916,4 +1032,4 @@ impl<T: Config> Pallet<T> {
916
1032
let ( _, old_deposit) = Proxies :: < T > :: take ( & delegator) ;
917
1033
T :: Currency :: unreserve ( & delegator, old_deposit) ;
918
1034
}
919
- }
1035
+ }
0 commit comments