Skip to content

Commit 1982199

Browse files
committed
check allowance expiration before increasing or decreasing it
1 parent b76b4b4 commit 1982199

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed

src/contract.rs

+23-5
Original file line numberDiff line numberDiff line change
@@ -993,9 +993,7 @@ fn use_allowance<S: Storage>(
993993
) -> StdResult<()> {
994994
let mut allowance = read_allowance(storage, owner, spender)?;
995995

996-
if allowance.expiration.map(|ex| ex < env.block.time) == Some(true) && allowance.amount != 0 {
997-
allowance.amount = 0;
998-
write_allowance(storage, owner, spender, allowance)?;
996+
if allowance.is_expired_at(&env.block) {
999997
return Err(insufficient_allowance(0, amount));
1000998
}
1001999
if let Some(new_allowance) = allowance.amount.checked_sub(amount) {
@@ -1338,7 +1336,17 @@ fn try_increase_allowance<S: Storage, A: Api, Q: Querier>(
13381336
let spender_address = deps.api.canonical_address(&spender)?;
13391337

13401338
let mut allowance = read_allowance(&deps.storage, &owner_address, &spender_address)?;
1341-
allowance.amount = allowance.amount.saturating_add(amount.u128());
1339+
1340+
// If the previous allowance has expired, reset the allowance.
1341+
// Without this users can take advantage of an expired allowance given to
1342+
// them long ago.
1343+
if allowance.is_expired_at(&env.block) {
1344+
allowance.amount = amount.u128();
1345+
allowance.expiration = None;
1346+
} else {
1347+
allowance.amount = allowance.amount.saturating_add(amount.u128());
1348+
}
1349+
13421350
if expiration.is_some() {
13431351
allowance.expiration = expiration;
13441352
}
@@ -1373,7 +1381,17 @@ fn try_decrease_allowance<S: Storage, A: Api, Q: Querier>(
13731381
let spender_address = deps.api.canonical_address(&spender)?;
13741382

13751383
let mut allowance = read_allowance(&deps.storage, &owner_address, &spender_address)?;
1376-
allowance.amount = allowance.amount.saturating_sub(amount.u128());
1384+
1385+
// If the previous allowance has expired, reset the allowance.
1386+
// Without this users can take advantage of an expired allowance given to
1387+
// them long ago.
1388+
if allowance.is_expired_at(&env.block) {
1389+
allowance.amount = 0;
1390+
allowance.expiration = None;
1391+
} else {
1392+
allowance.amount = allowance.amount.saturating_sub(amount.u128());
1393+
}
1394+
13771395
if expiration.is_some() {
13781396
allowance.expiration = expiration;
13791397
}

src/state.rs

+9
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,15 @@ pub struct Allowance {
303303
pub expiration: Option<u64>,
304304
}
305305

306+
impl Allowance {
307+
pub fn is_expired_at(&self, block: &cosmwasm_std::BlockInfo) -> bool {
308+
match self.expiration {
309+
Some(time) => block.time >= time,
310+
None => false, // allowance has no expiration
311+
}
312+
}
313+
}
314+
306315
pub fn read_allowance<S: Storage>(
307316
store: &S,
308317
owner: &CanonicalAddr,

0 commit comments

Comments
 (0)