@@ -75,6 +75,10 @@ pub struct ProxyDefinition<AccountId, ProxyType, BlockNumber> {
75
75
/// The number of blocks that an announcement must be in place for before the corresponding
76
76
/// call may be dispatched. If zero, then no announcement is needed.
77
77
pub delay : BlockNumber ,
78
+ /// The maximun amount that can be transferred by this proxy.
79
+ pub max_amount : Option < BalanceOf < T > > ,
80
+ /// The block number until which the limit is valid.
81
+ pub valid_unil : BlockNumber ,
78
82
}
79
83
80
84
/// Details surrounding a specific instance of an announcement to make a call.
@@ -88,26 +92,6 @@ pub struct Announcement<AccountId, Hash, BlockNumber> {
88
92
height : BlockNumber ,
89
93
}
90
94
91
- /// The type of deposit
92
- #[ derive(
93
- Encode ,
94
- Decode ,
95
- Clone ,
96
- Copy ,
97
- Eq ,
98
- PartialEq ,
99
- RuntimeDebug ,
100
- MaxEncodedLen ,
101
- TypeInfo ,
102
- DecodeWithMemTracking ,
103
- ) ]
104
- pub enum DepositKind {
105
- /// Proxy registration deposit
106
- Proxies ,
107
- /// Announcement deposit
108
- Announcements ,
109
- }
110
-
111
95
#[ frame:: pallet]
112
96
pub mod pallet {
113
97
use super :: * ;
@@ -170,6 +154,10 @@ pub mod pallet {
170
154
#[ pallet:: constant]
171
155
type MaxPending : Get < u32 > ;
172
156
157
+ #[ pallet:: constant]
158
+ type MaxTransferAmount : Get < BalanceOf < Self > > ;
159
+
160
+
173
161
/// The type of hash used for hashing the call.
174
162
type CallHasher : Hash ;
175
163
@@ -264,10 +252,12 @@ pub mod pallet {
264
252
delegate : AccountIdLookupOf < T > ,
265
253
proxy_type : T :: ProxyType ,
266
254
delay : BlockNumberFor < T > ,
255
+ max_amount : Option < BalanceOf < T > > ,
256
+ valid_unil : BlockNumberFor < T > ,
267
257
) -> DispatchResult {
268
258
let who = ensure_signed ( origin) ?;
269
259
let delegate = T :: Lookup :: lookup ( delegate) ?;
270
- Self :: add_proxy_delegate ( & who, delegate, proxy_type, delay)
260
+ Self :: add_proxy_delegate ( & who, delegate, proxy_type, delay, max_amount , valid_unil )
271
261
}
272
262
273
263
/// Unregister a proxy account for the sender.
@@ -329,14 +319,16 @@ pub mod pallet {
329
319
proxy_type : T :: ProxyType ,
330
320
delay : BlockNumberFor < T > ,
331
321
index : u16 ,
322
+ max_amount : Option < BalanceOf < T > > ,
323
+ valid_unil : BlockNumberFor < T > ,
332
324
) -> DispatchResult {
333
325
let who = ensure_signed ( origin) ?;
334
326
335
327
let pure = Self :: pure_account ( & who, & proxy_type, index, None ) ;
336
328
ensure ! ( !Proxies :: <T >:: contains_key( & pure) , Error :: <T >:: Duplicate ) ;
337
329
338
330
let proxy_def =
339
- ProxyDefinition { delegate : who. clone ( ) , proxy_type : proxy_type. clone ( ) , delay } ;
331
+ ProxyDefinition { delegate : who. clone ( ) , proxy_type : proxy_type. clone ( ) , delay, max_amount , valid_unil } ;
340
332
let bounded_proxies: BoundedVec < _ , T :: MaxProxies > =
341
333
vec ! [ proxy_def] . try_into ( ) . map_err ( |_| Error :: < T > :: TooMany ) ?;
342
334
@@ -549,105 +541,6 @@ pub mod pallet {
549
541
550
542
Ok ( ( ) )
551
543
}
552
-
553
- /// Poke / Adjust deposits made for proxies and announcements based on current values.
554
- /// This can be used by accounts to possibly lower their locked amount.
555
- ///
556
- /// The dispatch origin for this call must be _Signed_.
557
- ///
558
- /// The transaction fee is waived if the deposit amount has changed.
559
- ///
560
- /// Emits `DepositPoked` if successful.
561
- #[ pallet:: call_index( 10 ) ]
562
- #[ pallet:: weight( T :: WeightInfo :: poke_deposit( ) ) ]
563
- pub fn poke_deposit ( origin : OriginFor < T > ) -> DispatchResultWithPostInfo {
564
- let who = ensure_signed ( origin) ?;
565
- let mut deposit_updated = false ;
566
-
567
- // Check and update proxy deposits
568
- Proxies :: < T > :: try_mutate_exists ( & who, |maybe_proxies| -> DispatchResult {
569
- let ( proxies, old_deposit) = maybe_proxies. take ( ) . unwrap_or_default ( ) ;
570
- let maybe_new_deposit = Self :: rejig_deposit (
571
- & who,
572
- old_deposit,
573
- T :: ProxyDepositBase :: get ( ) ,
574
- T :: ProxyDepositFactor :: get ( ) ,
575
- proxies. len ( ) ,
576
- ) ?;
577
-
578
- match maybe_new_deposit {
579
- Some ( new_deposit) if new_deposit != old_deposit => {
580
- * maybe_proxies = Some ( ( proxies, new_deposit) ) ;
581
- deposit_updated = true ;
582
- Self :: deposit_event ( Event :: DepositPoked {
583
- who : who. clone ( ) ,
584
- kind : DepositKind :: Proxies ,
585
- old_deposit,
586
- new_deposit,
587
- } ) ;
588
- } ,
589
- Some ( _) => {
590
- * maybe_proxies = Some ( ( proxies, old_deposit) ) ;
591
- } ,
592
- None => {
593
- * maybe_proxies = None ;
594
- if !old_deposit. is_zero ( ) {
595
- deposit_updated = true ;
596
- Self :: deposit_event ( Event :: DepositPoked {
597
- who : who. clone ( ) ,
598
- kind : DepositKind :: Proxies ,
599
- old_deposit,
600
- new_deposit : BalanceOf :: < T > :: zero ( ) ,
601
- } ) ;
602
- }
603
- } ,
604
- }
605
- Ok ( ( ) )
606
- } ) ?;
607
-
608
- // Check and update announcement deposits
609
- Announcements :: < T > :: try_mutate_exists ( & who, |maybe_announcements| -> DispatchResult {
610
- let ( announcements, old_deposit) = maybe_announcements. take ( ) . unwrap_or_default ( ) ;
611
- let maybe_new_deposit = Self :: rejig_deposit (
612
- & who,
613
- old_deposit,
614
- T :: AnnouncementDepositBase :: get ( ) ,
615
- T :: AnnouncementDepositFactor :: get ( ) ,
616
- announcements. len ( ) ,
617
- ) ?;
618
-
619
- match maybe_new_deposit {
620
- Some ( new_deposit) if new_deposit != old_deposit => {
621
- * maybe_announcements = Some ( ( announcements, new_deposit) ) ;
622
- deposit_updated = true ;
623
- Self :: deposit_event ( Event :: DepositPoked {
624
- who : who. clone ( ) ,
625
- kind : DepositKind :: Announcements ,
626
- old_deposit,
627
- new_deposit,
628
- } ) ;
629
- } ,
630
- Some ( _) => {
631
- * maybe_announcements = Some ( ( announcements, old_deposit) ) ;
632
- } ,
633
- None => {
634
- * maybe_announcements = None ;
635
- if !old_deposit. is_zero ( ) {
636
- deposit_updated = true ;
637
- Self :: deposit_event ( Event :: DepositPoked {
638
- who : who. clone ( ) ,
639
- kind : DepositKind :: Announcements ,
640
- old_deposit,
641
- new_deposit : BalanceOf :: < T > :: zero ( ) ,
642
- } ) ;
643
- }
644
- } ,
645
- }
646
- Ok ( ( ) )
647
- } ) ?;
648
-
649
- Ok ( if deposit_updated { Pays :: No . into ( ) } else { Pays :: Yes . into ( ) } )
650
- }
651
544
}
652
545
653
546
#[ pallet:: event]
@@ -679,13 +572,6 @@ pub mod pallet {
679
572
proxy_type : T :: ProxyType ,
680
573
delay : BlockNumberFor < T > ,
681
574
} ,
682
- /// A deposit stored for proxies or announcements was poked / updated.
683
- DepositPoked {
684
- who : T :: AccountId ,
685
- kind : DepositKind ,
686
- old_deposit : BalanceOf < T > ,
687
- new_deposit : BalanceOf < T > ,
688
- } ,
689
575
}
690
576
691
577
#[ pallet:: error]
@@ -706,6 +592,10 @@ pub mod pallet {
706
592
Unannounced ,
707
593
/// Cannot add self as proxy.
708
594
NoSelfProxy ,
595
+ /// The transfer amoun exceeds the allowed limit.
596
+ TransferLimitExceeded ,
597
+ /// The duration for the transfer limit has expired.
598
+ DurationExpired ,
709
599
}
710
600
711
601
/// The set of account proxies. Maps the account which has delegated to the accounts
@@ -818,13 +708,25 @@ impl<T: Config> Pallet<T> {
818
708
delegatee : T :: AccountId ,
819
709
proxy_type : T :: ProxyType ,
820
710
delay : BlockNumberFor < T > ,
711
+ max_amount : Option < BalanceOf < T > > ,
712
+ valid_unil : BlockNumberFor < T > ,
821
713
) -> DispatchResult {
822
714
ensure ! ( delegator != & delegatee, Error :: <T >:: NoSelfProxy ) ;
823
715
Proxies :: < T > :: try_mutate ( delegator, |( ref mut proxies, ref mut deposit) | {
824
716
let proxy_def = ProxyDefinition {
825
717
delegate : delegatee. clone ( ) ,
826
718
proxy_type : proxy_type. clone ( ) ,
827
719
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
+ } ,
828
730
} ;
829
731
let i = proxies. binary_search ( & proxy_def) . err ( ) . ok_or ( Error :: < T > :: Duplicate ) ?;
830
732
proxies. try_insert ( i, proxy_def) . map_err ( |_| Error :: < T > :: TooMany ) ?;
@@ -858,13 +760,25 @@ impl<T: Config> Pallet<T> {
858
760
delegatee : T :: AccountId ,
859
761
proxy_type : T :: ProxyType ,
860
762
delay : BlockNumberFor < T > ,
763
+ max_amount : Option < BalanceOf < T > > ,
764
+ valid_until : BlockNumberFor < T > ,
861
765
) -> DispatchResult {
862
766
Proxies :: < T > :: try_mutate_exists ( delegator, |x| {
863
767
let ( mut proxies, old_deposit) = x. take ( ) . ok_or ( Error :: < T > :: NotFound ) ?;
864
768
let proxy_def = ProxyDefinition {
865
769
delegate : delegatee. clone ( ) ,
866
770
proxy_type : proxy_type. clone ( ) ,
867
771
delay,
772
+ max_amount : if proxy_type == ProxyType :: AnyWithLimit {
773
+ max_amount
774
+ } else {
775
+ None
776
+ } ,
777
+ valid_until : if proxy_type == ProxyType :: AnytWithLimit {
778
+ valid_unil
779
+ } else {
780
+ None
781
+ } ,
868
782
} ;
869
783
let i = proxies. binary_search ( & proxy_def) . ok ( ) . ok_or ( Error :: < T > :: NotFound ) ?;
870
784
proxies. remove ( i) ;
@@ -905,16 +819,9 @@ impl<T: Config> Pallet<T> {
905
819
let new_deposit =
906
820
if len == 0 { BalanceOf :: < T > :: zero ( ) } else { base + factor * ( len as u32 ) . into ( ) } ;
907
821
if new_deposit > old_deposit {
908
- T :: Currency :: reserve ( who, new_deposit. saturating_sub ( old_deposit) ) ?;
822
+ T :: Currency :: reserve ( who, new_deposit - old_deposit) ?;
909
823
} else if new_deposit < old_deposit {
910
- let excess = old_deposit. saturating_sub ( new_deposit) ;
911
- let remaining_unreserved = T :: Currency :: unreserve ( who, excess) ;
912
- if !remaining_unreserved. is_zero ( ) {
913
- defensive ! (
914
- "Failed to unreserve full amount. (Requested, Actual)" ,
915
- ( excess, excess. saturating_sub( remaining_unreserved) )
916
- ) ;
917
- }
824
+ T :: Currency :: unreserve ( who, old_deposit - new_deposit) ;
918
825
}
919
826
Ok ( if len == 0 { None } else { Some ( new_deposit) } )
920
827
}
@@ -977,7 +884,24 @@ impl<T: Config> Pallet<T> {
977
884
Some ( Call :: remove_proxies { .. } ) | Some ( Call :: kill_pure { .. } )
978
885
if def. proxy_type != T :: ProxyType :: default ( ) =>
979
886
false ,
980
- _ => def. proxy_type . filter ( c) ,
887
+ // Enforce the max_amount and duration limits for `AnyWithLimit` proxies.
888
+ if def. proxy_type == ProxyType :: AnyWithLimit {
889
+ if let Some ( Call :: Balances ( BalancesCall :: transfer_allow_death { value, .. } ) ) = c. is_sub_type( ) {
890
+ if let Some ( max_amount) = def. max_amount {
891
+ if * value > max_amount {
892
+ return false ;
893
+ }
894
+ }
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
+ }
901
+ }
902
+ }
903
+ def. proxy_type . filter ( c) ,
904
+ }
981
905
}
982
906
} ) ;
983
907
let e = call. dispatch ( origin) ;
0 commit comments