From 19821995fbf57e26f9fb009724e847c7f4d07d97 Mon Sep 17 00:00:00 2001 From: Reuven Podmazo Date: Thu, 27 May 2021 16:30:01 +0300 Subject: [PATCH] check allowance expiration before increasing or decreasing it --- src/contract.rs | 28 +++++++++++++++++++++++----- src/state.rs | 9 +++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/contract.rs b/src/contract.rs index 6a8efcd..ac84031 100644 --- a/src/contract.rs +++ b/src/contract.rs @@ -993,9 +993,7 @@ fn use_allowance( ) -> StdResult<()> { let mut allowance = read_allowance(storage, owner, spender)?; - if allowance.expiration.map(|ex| ex < env.block.time) == Some(true) && allowance.amount != 0 { - allowance.amount = 0; - write_allowance(storage, owner, spender, allowance)?; + if allowance.is_expired_at(&env.block) { return Err(insufficient_allowance(0, amount)); } if let Some(new_allowance) = allowance.amount.checked_sub(amount) { @@ -1338,7 +1336,17 @@ fn try_increase_allowance( let spender_address = deps.api.canonical_address(&spender)?; let mut allowance = read_allowance(&deps.storage, &owner_address, &spender_address)?; - allowance.amount = allowance.amount.saturating_add(amount.u128()); + + // If the previous allowance has expired, reset the allowance. + // Without this users can take advantage of an expired allowance given to + // them long ago. + if allowance.is_expired_at(&env.block) { + allowance.amount = amount.u128(); + allowance.expiration = None; + } else { + allowance.amount = allowance.amount.saturating_add(amount.u128()); + } + if expiration.is_some() { allowance.expiration = expiration; } @@ -1373,7 +1381,17 @@ fn try_decrease_allowance( let spender_address = deps.api.canonical_address(&spender)?; let mut allowance = read_allowance(&deps.storage, &owner_address, &spender_address)?; - allowance.amount = allowance.amount.saturating_sub(amount.u128()); + + // If the previous allowance has expired, reset the allowance. + // Without this users can take advantage of an expired allowance given to + // them long ago. + if allowance.is_expired_at(&env.block) { + allowance.amount = 0; + allowance.expiration = None; + } else { + allowance.amount = allowance.amount.saturating_sub(amount.u128()); + } + if expiration.is_some() { allowance.expiration = expiration; } diff --git a/src/state.rs b/src/state.rs index 058c4e5..a9d9a6a 100644 --- a/src/state.rs +++ b/src/state.rs @@ -303,6 +303,15 @@ pub struct Allowance { pub expiration: Option, } +impl Allowance { + pub fn is_expired_at(&self, block: &cosmwasm_std::BlockInfo) -> bool { + match self.expiration { + Some(time) => block.time >= time, + None => false, // allowance has no expiration + } + } +} + pub fn read_allowance( store: &S, owner: &CanonicalAddr,