templar_vault_kernel/restrictions/
mod.rs1#[cfg(feature = "borsh-schema")]
6use alloc::string::ToString;
7use alloc::vec::Vec;
8#[cfg(feature = "schemars")]
9use alloc::{borrow::ToOwned, boxed::Box, vec};
10
11use derive_more::IsVariant;
12
13use crate::types::Address;
14
15#[templar_vault_macros::vault_derive(borsh_schema, schemars)]
18#[derive(Clone, Copy, PartialEq, Eq)]
19pub enum RestrictionKind {
20 Paused,
22 Blacklisted,
24 NotWhitelisted,
26}
27
28#[templar_vault_macros::vault_derive(borsh, borsh_schema, postcard, schemars, serde)]
32#[derive(Clone, PartialEq, Eq, IsVariant)]
33pub enum Restrictions {
34 Paused,
36 #[cfg_attr(feature = "serde", serde(rename = "BlackList"))]
38 Blacklist(Vec<Address>),
39 #[cfg_attr(feature = "serde", serde(rename = "WhiteList"))]
41 Whitelist(Vec<Address>),
42}
43
44impl Restrictions {
45 #[inline]
46 fn normalize_addresses(addresses: &mut Vec<Address>) {
47 addresses.sort_unstable();
48 addresses.dedup();
49 }
50
51 #[must_use]
52 pub fn normalized(mut self) -> Self {
53 match &mut self {
54 Restrictions::Blacklist(addresses) | Restrictions::Whitelist(addresses) => {
55 Self::normalize_addresses(addresses);
56 }
57 Restrictions::Paused => {}
58 }
59 self
60 }
61
62 #[inline]
63 fn contains_address(addresses: &[Address], actor_id: &Address) -> bool {
64 if addresses.is_sorted() {
65 addresses.binary_search(actor_id).is_ok()
66 } else {
67 addresses.iter().any(|addr| addr == actor_id)
68 }
69 }
70
71 pub fn is_restricted(&self, actor_id: &Address, self_id: &Address) -> Option<RestrictionKind> {
80 match self {
81 Restrictions::Paused => Some(RestrictionKind::Paused),
82 Restrictions::Blacklist(blacklist) => {
83 if Self::contains_address(blacklist, actor_id) {
84 Some(RestrictionKind::Blacklisted)
85 } else {
86 None
87 }
88 }
89 Restrictions::Whitelist(whitelist) => {
90 if Self::contains_address(whitelist, actor_id) || actor_id == self_id {
91 None
92 } else {
93 Some(RestrictionKind::NotWhitelisted)
94 }
95 }
96 }
97 }
98
99 }
101
102#[cfg(test)]
103mod tests;