near_contract_standards/fungible_token/
storage_impl.rsuse crate::fungible_token::{Balance, FungibleToken};
use crate::storage_management::{StorageBalance, StorageBalanceBounds, StorageManagement};
use near_sdk::{assert_one_yocto, env, log, AccountId, NearToken, Promise};
impl FungibleToken {
pub fn internal_storage_unregister(
&mut self,
force: Option<bool>,
) -> Option<(AccountId, Balance)> {
assert_one_yocto();
let account_id = env::predecessor_account_id();
let force = force.unwrap_or(false);
if let Some(balance) = self.accounts.get(&account_id) {
if balance == 0 || force {
self.accounts.remove(&account_id);
self.total_supply -= balance;
Promise::new(account_id.clone()).transfer(
self.storage_balance_bounds().min.saturating_add(NearToken::from_yoctonear(1)),
);
Some((account_id, balance))
} else {
env::panic_str(
"Can't unregister the account with the positive balance without force",
)
}
} else {
log!("The account {} is not registered", &account_id);
None
}
}
fn internal_storage_balance_of(&self, account_id: &AccountId) -> Option<StorageBalance> {
if self.accounts.contains_key(account_id) {
Some(StorageBalance {
total: self.storage_balance_bounds().min,
available: NearToken::from_near(0),
})
} else {
None
}
}
}
impl StorageManagement for FungibleToken {
#[allow(unused_variables)]
fn storage_deposit(
&mut self,
account_id: Option<AccountId>,
registration_only: Option<bool>,
) -> StorageBalance {
let amount = env::attached_deposit();
let account_id = account_id.unwrap_or_else(env::predecessor_account_id);
if self.accounts.contains_key(&account_id) {
log!("The account is already registered, refunding the deposit");
if amount > NearToken::from_near(0) {
Promise::new(env::predecessor_account_id()).transfer(amount);
}
} else {
let min_balance = self.storage_balance_bounds().min;
if amount < min_balance {
env::panic_str("The attached deposit is less than the minimum storage balance");
}
self.internal_register_account(&account_id);
let refund = amount.saturating_sub(min_balance);
if refund > NearToken::from_near(0) {
Promise::new(env::predecessor_account_id()).transfer(refund);
}
}
self.internal_storage_balance_of(&account_id).unwrap()
}
fn storage_withdraw(&mut self, amount: Option<NearToken>) -> StorageBalance {
assert_one_yocto();
let predecessor_account_id = env::predecessor_account_id();
if let Some(storage_balance) = self.internal_storage_balance_of(&predecessor_account_id) {
match amount {
Some(amount) if amount > NearToken::from_near(0) => {
env::panic_str("The amount is greater than the available storage balance");
}
_ => storage_balance,
}
} else {
env::panic_str(
format!("The account {} is not registered", &predecessor_account_id).as_str(),
);
}
}
fn storage_unregister(&mut self, force: Option<bool>) -> bool {
self.internal_storage_unregister(force).is_some()
}
fn storage_balance_bounds(&self) -> StorageBalanceBounds {
let required_storage_balance =
env::storage_byte_cost().saturating_mul(self.account_storage_usage.into());
StorageBalanceBounds { min: required_storage_balance, max: Some(required_storage_balance) }
}
fn storage_balance_of(&self, account_id: AccountId) -> Option<StorageBalance> {
self.internal_storage_balance_of(&account_id)
}
}