Skip to main content

unc_contract_standards/storage_management/
mod.rs

1use unc_sdk::{unc, AccountId, UncToken};
2
3#[unc(serializers=[borsh, json])]
4pub struct StorageBalance {
5    pub total: UncToken,
6    pub available: UncToken,
7}
8
9#[unc(serializers=[borsh, json])]
10pub struct StorageBalanceBounds {
11    pub min: UncToken,
12    pub max: Option<UncToken>,
13}
14
15/// Ensures that when fungible token storage grows by collections adding entries,
16/// the storage is be paid by the caller. This ensures that storage cannot grow to a point
17/// that the FT contract runs out of Ⓝ.
18/// Takes name of the Contract struct, the inner field for the token and optional method name to
19/// call when the account was closed.
20///
21/// # Examples
22///
23/// ```
24/// use unc_sdk::{unc, PanicOnDefault, AccountId, UncToken, log};
25/// use unc_sdk::collections::LazyOption;
26/// use unc_sdk::json_types::U128;
27/// use unc_contract_standards::fungible_token::FungibleToken;
28/// use unc_contract_standards::storage_management::{
29///     StorageBalance, StorageBalanceBounds, StorageManagement,
30/// };
31/// use unc_contract_standards::fungible_token::metadata::FungibleTokenMetadata;
32///
33/// #[unc(contract_state)]
34/// #[derive(PanicOnDefault)]
35/// pub struct Contract {
36///     token: FungibleToken,
37///     metadata: LazyOption<FungibleTokenMetadata>,
38/// }
39///
40/// #[unc]
41/// impl StorageManagement for Contract {
42///     #[payable]
43///     fn storage_deposit(
44///         &mut self,
45///         account_id: Option<AccountId>,
46///         registration_only: Option<bool>,
47///     ) -> StorageBalance {
48///         self.token.storage_deposit(account_id, registration_only)
49///     }
50///
51///     #[payable]
52///     fn storage_withdraw(&mut self, amount: Option<UncToken>) -> StorageBalance {
53///         self.token.storage_withdraw(amount)
54///     }
55///
56///     #[payable]
57///     fn storage_unregister(&mut self, force: Option<bool>) -> bool {
58///         #[allow(unused_variables)]
59///         if let Some((account_id, balance)) = self.token.internal_storage_unregister(force) {
60///             log!("Closed @{} with {}", account_id, balance);
61///             true
62///         } else {
63///             false
64///         }
65///     }
66///
67///     fn storage_balance_bounds(&self) -> StorageBalanceBounds {
68///         self.token.storage_balance_bounds()
69///     }
70///
71///     fn storage_balance_of(&self, account_id: AccountId) -> Option<StorageBalance> {
72///         self.token.storage_balance_of(account_id)
73///     }
74/// }
75///
76/// ```
77///
78pub trait StorageManagement {
79    // if `registration_only=true` MUST refund above the minimum balance if the account didn't exist and
80    //     refund full deposit if the account exists.
81    fn storage_deposit(
82        &mut self,
83        account_id: Option<AccountId>,
84        registration_only: Option<bool>,
85    ) -> StorageBalance;
86
87    /// Withdraw specified amount of available Ⓝ for predecessor account.
88    ///
89    /// This method is safe to call. It MUST NOT remove data.
90    ///
91    /// `amount` is sent as a string representing an unsigned 128-bit integer. If
92    /// omitted, contract MUST refund full `available` balance. If `amount` exceeds
93    /// predecessor account's available balance, contract MUST panic.
94    ///
95    /// If predecessor account not registered, contract MUST panic.
96    ///
97    /// MUST require exactly 1 attoUNC attached balance to prevent restricted
98    /// function-call access-key call (UX wallet security)
99    ///
100    /// Returns the StorageBalance structure showing updated balances.
101    fn storage_withdraw(&mut self, amount: Option<UncToken>) -> StorageBalance;
102
103    /// Unregisters the predecessor account and returns the storage UNC deposit back.
104    ///
105    /// If the predecessor account is not registered, the function MUST return `false` without panic.
106    ///
107    /// If `force=true` the function SHOULD ignore account balances (burn them) and close the account.
108    /// Otherwise, MUST panic if caller has a positive registered balance (eg token holdings) or
109    ///     the contract doesn't support force unregistration.
110    /// MUST require exactly 1 attoUNC attached balance to prevent restricted function-call access-key call
111    /// (UX wallet security)
112    /// Returns `true` iff the account was unregistered.
113    /// Returns `false` iff account was not registered before.
114    fn storage_unregister(&mut self, force: Option<bool>) -> bool;
115
116    fn storage_balance_bounds(&self) -> StorageBalanceBounds;
117
118    fn storage_balance_of(&self, account_id: AccountId) -> Option<StorageBalance>;
119}