radix_engine_interface/blueprints/resource/
mod.rs

1mod auth_zone;
2mod bucket;
3mod fungible;
4mod non_fungible;
5mod proof;
6mod proof_rule;
7mod resource;
8mod resource_manager;
9mod resource_type;
10mod role_assignment;
11mod vault;
12mod worktop;
13
14pub use auth_zone::*;
15pub use bucket::*;
16pub use fungible::*;
17pub use non_fungible::*;
18pub use proof::*;
19pub use proof_rule::*;
20pub use resource::*;
21pub use resource_manager::ResourceFeature::*;
22pub use resource_manager::*;
23pub use resource_type::*;
24pub use role_assignment::*;
25use sbor::Sbor;
26pub use vault::*;
27pub use worktop::*;
28
29#[cfg(feature = "fuzzing")]
30use arbitrary::Arbitrary;
31use radix_common::math::*;
32use radix_common::{ManifestSbor, ScryptoSbor};
33use sbor::rust::prelude::*;
34
35pub fn check_fungible_amount(amount: &Decimal, divisibility: u8) -> bool {
36    !amount.is_negative()
37        && amount.attos() % I192::from(10i128.pow((18 - divisibility).into())) == I192::from(0)
38}
39
40pub fn check_non_fungible_amount(amount: &Decimal) -> Result<u32, ()> {
41    // Integers between [0..u32::MAX]
42    u32::try_from(amount).map_err(|_| ())
43}
44
45#[macro_export]
46macro_rules! resource_roles {
47    (
48        $roles_struct:ident,
49        $actor_field:ident,
50        $updater_field:ident,
51        $actor_field_name:expr,
52        $updater_field_name:expr,
53        $default_rule:expr
54    ) => {
55        #[cfg_attr(feature = "fuzzing", derive(Arbitrary))]
56        #[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, ScryptoSbor, ManifestSbor)]
57        pub struct $roles_struct<T> {
58            pub $actor_field: T,
59            pub $updater_field: T,
60        }
61
62        impl $roles_struct<$crate::object_modules::role_assignment::RoleDefinition> {
63            pub fn to_role_init(self) -> $crate::blueprints::resource::RoleAssignmentInit {
64                let mut roles = $crate::blueprints::resource::RoleAssignmentInit::new();
65                roles.define_role($actor_field_name, self.$actor_field);
66                roles.define_role($updater_field_name, self.$updater_field);
67                roles
68            }
69        }
70
71        impl Default for $roles_struct<$crate::object_modules::role_assignment::RoleDefinition> {
72            fn default() -> Self {
73                Self {
74                    $actor_field: Some($default_rule),
75                    $updater_field: Some(AccessRule::DenyAll),
76                }
77            }
78        }
79    };
80}
81
82resource_roles!(
83    MintRoles,
84    minter,
85    minter_updater,
86    MINTER_ROLE,
87    MINTER_UPDATER_ROLE,
88    AccessRule::DenyAll
89);
90#[macro_export]
91macro_rules! mint_roles {
92    {$($role:ident => $rule:expr;)*} => ({
93        Some($crate::internal_roles_struct!(MintRoles, $($role => $rule;)*))
94    });
95}
96
97resource_roles!(
98    BurnRoles,
99    burner,
100    burner_updater,
101    BURNER_ROLE,
102    BURNER_UPDATER_ROLE,
103    AccessRule::DenyAll
104);
105#[macro_export]
106macro_rules! burn_roles {
107    {$($role:ident => $rule:expr;)*} => ({
108        Some($crate::internal_roles_struct!(BurnRoles, $($role => $rule;)*))
109    });
110}
111
112resource_roles!(
113    RecallRoles,
114    recaller,
115    recaller_updater,
116    RECALLER_ROLE,
117    RECALLER_UPDATER_ROLE,
118    AccessRule::DenyAll
119);
120#[macro_export]
121macro_rules! recall_roles {
122    {$($role:ident => $rule:expr;)*} => ({
123        Some($crate::internal_roles_struct!(RecallRoles, $($role => $rule;)*))
124    });
125}
126
127resource_roles!(
128    FreezeRoles,
129    freezer,
130    freezer_updater,
131    FREEZER_ROLE,
132    FREEZER_UPDATER_ROLE,
133    AccessRule::DenyAll
134);
135#[macro_export]
136macro_rules! freeze_roles {
137    {$($role:ident => $rule:expr;)*} => ({
138        Some($crate::internal_roles_struct!(FreezeRoles, $($role => $rule;)*))
139    });
140}
141
142resource_roles!(
143    WithdrawRoles,
144    withdrawer,
145    withdrawer_updater,
146    WITHDRAWER_ROLE,
147    WITHDRAWER_UPDATER_ROLE,
148    AccessRule::AllowAll
149);
150#[macro_export]
151macro_rules! withdraw_roles {
152    {$($role:ident => $rule:expr;)*} => ({
153        Some($crate::internal_roles_struct!(WithdrawRoles, $($role => $rule;)*))
154    });
155}
156
157resource_roles!(
158    DepositRoles,
159    depositor,
160    depositor_updater,
161    DEPOSITOR_ROLE,
162    DEPOSITOR_UPDATER_ROLE,
163    AccessRule::AllowAll
164);
165#[macro_export]
166macro_rules! deposit_roles {
167    {$($role:ident => $rule:expr;)*} => ({
168        Some($crate::internal_roles_struct!(DepositRoles, $($role => $rule;)*))
169    });
170}
171
172resource_roles!(
173    NonFungibleDataUpdateRoles,
174    non_fungible_data_updater,
175    non_fungible_data_updater_updater,
176    NON_FUNGIBLE_DATA_UPDATER_ROLE,
177    NON_FUNGIBLE_DATA_UPDATER_UPDATER_ROLE,
178    AccessRule::DenyAll
179);
180#[macro_export]
181macro_rules! non_fungible_data_update_roles {
182    {$($role:ident => $rule:expr;)*} => ({
183        Some($crate::internal_roles_struct!(NonFungibleDataUpdateRoles, $($role => $rule;)*))
184    });
185}
186
187/// Define the withdraw strategy when request amount does not match underlying
188/// resource divisibility.
189#[derive(Debug, Clone, Copy, PartialEq, Eq, Sbor)]
190pub enum WithdrawStrategy {
191    Exact,
192    Rounded(RoundingMode),
193}
194
195pub trait ForWithdrawal {
196    fn for_withdrawal(
197        &self,
198        divisibility: u8,
199        withdraw_strategy: WithdrawStrategy,
200    ) -> Option<Decimal>;
201}
202
203impl ForWithdrawal for Decimal {
204    fn for_withdrawal(
205        &self,
206        divisibility: u8,
207        withdraw_strategy: WithdrawStrategy,
208    ) -> Option<Decimal> {
209        match withdraw_strategy {
210            WithdrawStrategy::Exact => Some(self.clone()),
211            WithdrawStrategy::Rounded(mode) => self.checked_round(divisibility, mode),
212        }
213    }
214}
215
216impl Default for WithdrawStrategy {
217    fn default() -> Self {
218        Self::Exact
219    }
220}