-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathallowance.rs
63 lines (56 loc) · 1.75 KB
/
allowance.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
use crate::storage_types::{AllowanceDataKey, AllowanceValue, DataKey};
use soroban_sdk::{Address, Env};
pub fn read_allowance(e: &Env, from: Address, spender: Address) -> AllowanceValue {
let key = DataKey::Allowance(AllowanceDataKey { from, spender });
if let Some(allowance) = e.storage().temporary().get::<_, AllowanceValue>(&key) {
if allowance.expiration_ledger < e.ledger().sequence() {
AllowanceValue {
amount: 0,
expiration_ledger: allowance.expiration_ledger,
}
} else {
allowance
}
} else {
AllowanceValue {
amount: 0,
expiration_ledger: 0,
}
}
}
pub fn write_allowance(
e: &Env,
from: Address,
spender: Address,
amount: i128,
expiration_ledger: u32,
) {
let allowance = AllowanceValue {
amount,
expiration_ledger,
};
if amount > 0 && expiration_ledger < e.ledger().sequence() {
panic!("expiration_ledger is less than ledger seq when amount > 0")
}
let key = DataKey::Allowance(AllowanceDataKey { from, spender });
e.storage().temporary().set(&key.clone(), &allowance);
if amount > 0 {
let live_for = expiration_ledger
.checked_sub(e.ledger().sequence())
.unwrap();
e.storage().temporary().extend_ttl(&key, live_for, live_for)
}
}
pub fn spend_allowance(e: &Env, from: Address, spender: Address, amount: i128) {
let allowance = read_allowance(e, from.clone(), spender.clone());
if allowance.amount < amount {
panic!("insufficient allowance");
}
write_allowance(
e,
from,
spender,
allowance.amount - amount,
allowance.expiration_ledger,
);
}