-
Notifications
You must be signed in to change notification settings - Fork 54
/
storage_impl.rs
94 lines (89 loc) · 3.57 KB
/
storage_impl.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use crate::*;
/// Implements users storage management for the pool.
#[near_bindgen]
impl StorageManagement for Contract {
#[payable]
fn storage_deposit(
&mut self,
account_id: Option<ValidAccountId>,
registration_only: Option<bool>,
) -> StorageBalance {
self.assert_contract_running();
let amount = env::attached_deposit();
let account_id = account_id
.map(|a| a.into())
.unwrap_or_else(|| env::predecessor_account_id());
let registration_only = registration_only.unwrap_or(false);
let min_balance = self.storage_balance_bounds().min.0;
let already_registered = self.accounts.contains_key(&account_id);
if amount < min_balance && !already_registered {
env::panic(ERR17_DEPOSIT_LESS_THAN_MIN_STORAGE.as_bytes());
}
if registration_only {
// Registration only setups the account but doesn't leave space for tokens.
if already_registered {
log!("ERR_ACC_REGISTERED");
if amount > 0 {
Promise::new(env::predecessor_account_id()).transfer(amount);
}
} else {
self.internal_register_account(&account_id, min_balance);
let refund = amount - min_balance;
if refund > 0 {
Promise::new(env::predecessor_account_id()).transfer(refund);
}
}
} else {
self.internal_register_account(&account_id, amount);
}
self.storage_balance_of(account_id.try_into().unwrap())
.unwrap()
}
#[payable]
fn storage_withdraw(&mut self, amount: Option<U128>) -> StorageBalance {
assert_one_yocto();
self.assert_contract_running();
let account_id = env::predecessor_account_id();
let amount = amount.unwrap_or(U128(0)).0;
let withdraw_amount = self.internal_storage_withdraw(&account_id, amount);
Promise::new(account_id.clone()).transfer(withdraw_amount);
self.storage_balance_of(account_id.try_into().unwrap())
.unwrap()
}
/// param force is unused here, just reserve it to keep interface standard
#[allow(unused_variables)]
#[payable]
fn storage_unregister(&mut self, force: Option<bool>) -> bool {
assert_one_yocto();
self.assert_contract_running();
let account_id = env::predecessor_account_id();
if let Some(account_deposit) = self.internal_get_account(&account_id) {
// [AUDITION_AMENDMENT] 2.1.1 Improper Account Unregistration
assert!(
account_deposit.tokens.is_empty() && account_deposit.legacy_tokens.is_empty() && account_deposit.shadow_records.is_empty(),
"{}", ERR18_TOKENS_NOT_EMPTY
);
self.accounts.remove(&account_id);
Promise::new(account_id.clone()).transfer(account_deposit.near_amount);
true
} else {
false
}
}
fn storage_balance_bounds(&self) -> StorageBalanceBounds {
StorageBalanceBounds {
min: Account::min_storage_usage().into(),
max: None,
}
}
fn storage_balance_of(&self, account_id: ValidAccountId) -> Option<StorageBalance> {
self.internal_get_account(account_id.as_ref())
.map(|account|
{
StorageBalance {
total: U128(account.near_amount),
available: U128(account.storage_available()),
}
})
}
}