radix_engine_interface/blueprints/resource/
mod.rs

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