Skip to content

Commit

Permalink
Remove increase / decrease and MAX allowance from ERC20
Browse files Browse the repository at this point in the history
  • Loading branch information
tarrencev committed Feb 14, 2024
1 parent 64c8306 commit 20500f6
Show file tree
Hide file tree
Showing 7 changed files with 6 additions and 519 deletions.
174 changes: 0 additions & 174 deletions token/src/components/tests/token/erc20/test_erc20_allowance.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -91,34 +91,6 @@ fn test_erc20_allowance_approve_to_zero() {
state.erc20_allowance.approve(ZERO(), VALUE);
}


//
// update_allowance (increase_allowance, decrease_allowance)
//

#[test]
#[available_gas(100000000)]
fn test_erc20_allowance_update_allowance() {
let (world, mut state) = STATE();

testing::set_caller_address(OWNER());

state.erc20_allowance.approve(SPENDER(), VALUE);
utils::drop_event(ZERO());

state.erc20_allowance.update_allowance(OWNER(), SPENDER(), 0, SUPPLY);
assert(
state.erc20_allowance.allowance(OWNER(), SPENDER()) == VALUE + SUPPLY,
'should be VALUE+SUPPLY'
);
assert_only_event_approval(ZERO(), OWNER(), SPENDER(), VALUE + SUPPLY);

state.erc20_allowance.update_allowance(OWNER(), SPENDER(), VALUE, 0);
assert(state.erc20_allowance.allowance(OWNER(), SPENDER()) == SUPPLY, 'should be SUPPLY');
assert_only_event_approval(ZERO(), OWNER(), SPENDER(), SUPPLY);
}


//
// spend_allowance
//
Expand Down Expand Up @@ -159,149 +131,3 @@ fn test_erc20_allowance_spend_allowance_with_max_allowance() {

utils::assert_no_events_left(ZERO());
}


//
// increase_allowance & increaseAllowance
//

#[test]
#[available_gas(25000000)]
fn test_erc20_allowance_increase_allowance() {
let (world, mut state) = STATE();

testing::set_caller_address(OWNER());
state.erc20_allowance.approve(SPENDER(), VALUE);
utils::drop_event(ZERO());

assert(state.erc20_allowance.increase_allowance(SPENDER(), VALUE), 'Should return true');

assert_only_event_approval(ZERO(), OWNER(), SPENDER(), VALUE * 2);
assert(
state.erc20_allowance.allowance(OWNER(), SPENDER()) == VALUE * 2, 'Should be amount * 2'
);
}

#[test]
#[available_gas(25000000)]
#[should_panic(expected: ('ERC20: approve to 0',))]
fn test_erc20_allowance_increase_allowance_to_zero_address() {
let (world, mut state) = STATE();

testing::set_caller_address(OWNER());
state.erc20_allowance.increase_allowance(ZERO(), VALUE);
}

#[test]
#[available_gas(25000000)]
#[should_panic(expected: ('ERC20: approve from 0',))]
fn test_erc20_allowance_increase_allowance_from_zero_address() {
let (world, mut state) = STATE();
state.erc20_allowance.increase_allowance(SPENDER(), VALUE);
}

#[test]
#[available_gas(25000000)]
fn test_erc20_allowance_increaseAllowance() {
let (world, mut state) = STATE();

testing::set_caller_address(OWNER());
state.erc20_allowance.approve(SPENDER(), VALUE);
utils::drop_event(ZERO());

assert(state.erc20_allowance.increaseAllowance(SPENDER(), VALUE), 'Should return true');

assert_only_event_approval(ZERO(), OWNER(), SPENDER(), 2 * VALUE);
assert(
state.erc20_allowance.allowance(OWNER(), SPENDER()) == VALUE * 2, 'Should be amount * 2'
);
}

#[test]
#[available_gas(25000000)]
#[should_panic(expected: ('ERC20: approve to 0',))]
fn test_erc20_allowance_increaseAllowance_to_zero_address() {
let (world, mut state) = STATE();

testing::set_caller_address(OWNER());
state.erc20_allowance.increaseAllowance(ZERO(), VALUE);
}

#[test]
#[available_gas(25000000)]
#[should_panic(expected: ('ERC20: approve from 0',))]
fn test_erc20_allowance_increaseAllowance_from_zero_address() {
let (world, mut state) = STATE();
state.erc20_allowance.increaseAllowance(SPENDER(), VALUE);
}

//
// decrease_allowance & decreaseAllowance
//

#[test]
#[available_gas(25000000)]
fn test_erc20_allowance_decrease_allowance() {
let (world, mut state) = STATE();

testing::set_caller_address(OWNER());
state.erc20_allowance.approve(SPENDER(), VALUE);
utils::drop_event(ZERO());

assert(state.erc20_allowance.decrease_allowance(SPENDER(), VALUE), 'Should return true');

assert_only_event_approval(ZERO(), OWNER(), SPENDER(), 0);
assert(state.erc20_allowance.allowance(OWNER(), SPENDER()) == VALUE - VALUE, 'Should be 0');
}

#[test]
#[available_gas(25000000)]
#[should_panic(expected: ('u256_sub Overflow',))]
fn test_erc20_allowance_decrease_allowance_to_zero_address() {
let (world, mut state) = STATE();

testing::set_caller_address(OWNER());
state.erc20_allowance.decrease_allowance(ZERO(), VALUE);
}

#[test]
#[available_gas(25000000)]
#[should_panic(expected: ('u256_sub Overflow',))]
fn test_erc20_allowance_decrease_allowance_from_zero_address() {
let (world, mut state) = STATE();
state.erc20_allowance.decrease_allowance(SPENDER(), VALUE);
}

#[test]
#[available_gas(25000000)]
fn test_erc20_allowance_decreaseAllowance() {
let (world, mut state) = STATE();

testing::set_caller_address(OWNER());
state.erc20_allowance.approve(SPENDER(), VALUE);
utils::drop_event(ZERO());

assert(state.erc20_allowance.decreaseAllowance(SPENDER(), VALUE), 'Should return true');

assert_only_event_approval(ZERO(), OWNER(), SPENDER(), 0);
assert(state.erc20_allowance.allowance(OWNER(), SPENDER()) == VALUE - VALUE, 'Should be 0');
}

#[test]
#[available_gas(25000000)]
#[should_panic(expected: ('u256_sub Overflow',))]
fn test_erc20_allowance_decreaseAllowance_to_zero_address() {
let (world, mut state) = STATE();

testing::set_caller_address(OWNER());
state.erc20_allowance.decreaseAllowance(ZERO(), VALUE);
}

#[test]
#[available_gas(25000000)]
#[should_panic(expected: ('u256_sub Overflow',))]
fn test_erc20_allowance_decreaseAllowance_from_zero_address() {
let (world, mut state) = STATE();
state.erc20_allowance.decreaseAllowance(SPENDER(), VALUE);
}

81 changes: 3 additions & 78 deletions token/src/components/token/erc20/erc20_allowance.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,6 @@ trait IERC20Allowance<TState> {
fn approve(ref self: TState, spender: ContractAddress, amount: u256) -> bool;
}

#[starknet::interface]
trait IERC20SafeAllowance<TState> {
fn increase_allowance(ref self: TState, spender: ContractAddress, added_value: u256) -> bool;
fn decrease_allowance(
ref self: TState, spender: ContractAddress, subtracted_value: u256
) -> bool;
}

#[starknet::interface]
trait IERC20SafeAllowanceCamel<TState> {
fn increaseAllowance(ref self: TState, spender: ContractAddress, addedValue: u256) -> bool;
fn decreaseAllowance(ref self: TState, spender: ContractAddress, subtractedValue: u256) -> bool;
}

///
/// ERC20Allowance Component
///
Expand Down Expand Up @@ -100,52 +86,6 @@ mod erc20_allowance_component {
}
}

#[embeddable_as(ERC20SafeAllowanceImpl)]
impl ERC20SafeAllowance<
TContractState,
+HasComponent<TContractState>,
+IWorldProvider<TContractState>,
+Drop<TContractState>
> of IERC20SafeAllowance<ComponentState<TContractState>> {
fn increase_allowance(
ref self: ComponentState<TContractState>, spender: ContractAddress, added_value: u256
) -> bool {
self.update_allowance(get_caller_address(), spender, 0, added_value);
true
}

fn decrease_allowance(
ref self: ComponentState<TContractState>,
spender: ContractAddress,
subtracted_value: u256
) -> bool {
self.update_allowance(get_caller_address(), spender, subtracted_value, 0);
true
}
}

#[embeddable_as(ERC20SafeAllowanceCamelImpl)]
impl ERC20SafeAllowanceCamel<
TContractState,
+HasComponent<TContractState>,
+IWorldProvider<TContractState>,
+Drop<TContractState>
> of IERC20SafeAllowanceCamel<ComponentState<TContractState>> {
fn increaseAllowance(
ref self: ComponentState<TContractState>, spender: ContractAddress, addedValue: u256
) -> bool {
self.increase_allowance(spender, addedValue)
}

fn decreaseAllowance(
ref self: ComponentState<TContractState>,
spender: ContractAddress,
subtractedValue: u256
) -> bool {
self.decrease_allowance(spender, subtractedValue)
}
}

///
/// Internal
///
Expand Down Expand Up @@ -179,31 +119,16 @@ mod erc20_allowance_component {
self.emit_event(approval_event);
}

fn update_allowance(
ref self: ComponentState<TContractState>,
owner: ContractAddress,
spender: ContractAddress,
subtract: u256,
add: u256
) {
let mut allowance = self.get_allowance(owner, spender);
// adding and subtracting is fewer steps than if
allowance.amount = allowance.amount - subtract;
allowance.amount = allowance.amount + add;
self.set_allowance(allowance);
}

// use in transfer_from
fn spend_allowance(
ref self: ComponentState<TContractState>,
owner: ContractAddress,
spender: ContractAddress,
amount: u256
) {
let current_allowance = self.get_allowance(owner, spender).amount;
if current_allowance != BoundedInt::max() {
self.update_allowance(owner, spender, amount, 0);
}
let mut allowance = self.get_allowance(owner, spender);
allowance.amount = allowance.amount - amount;
self.set_allowance(allowance);
}

fn emit_event<S, +traits::Into<S, Event>, +Drop<S>, +Clone<S>>(
Expand Down
51 changes: 3 additions & 48 deletions token/src/erc20/erc20.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -141,36 +141,6 @@ mod ERC20 {
}
}

#[abi(embed_v0)]
fn increase_allowance(
ref self: ContractState, spender: ContractAddress, added_value: u256
) -> bool {
self.update_allowance(get_caller_address(), spender, 0, added_value);
true
}

#[abi(embed_v0)]
fn increaseAllowance(
ref self: ContractState, spender: ContractAddress, addedValue: u256
) -> bool {
increase_allowance(ref self, spender, addedValue)
}

#[abi(embed_v0)]
fn decrease_allowance(
ref self: ContractState, spender: ContractAddress, subtracted_value: u256
) -> bool {
self.update_allowance(get_caller_address(), spender, subtracted_value, 0);
true
}

#[abi(embed_v0)]
fn decreaseAllowance(
ref self: ContractState, spender: ContractAddress, subtractedValue: u256
) -> bool {
decrease_allowance(ref self, spender, subtractedValue)
}

//
// Internal
//
Expand Down Expand Up @@ -216,20 +186,6 @@ mod ERC20 {
get!(self.world(), (get_contract_address(), owner, spender), ERC20Allowance)
}

fn update_allowance(
ref self: ContractState,
owner: ContractAddress,
spender: ContractAddress,
subtract: u256,
add: u256
) {
let mut allowance = self.get_allowance(owner, spender);
// adding and subtracting is fewer steps than if
allowance.amount = allowance.amount - subtract;
allowance.amount = allowance.amount + add;
self.set_allowance(allowance);
}

fn set_allowance(ref self: ContractState, allowance: ERC20Allowance) {
assert(!allowance.owner.is_zero(), Errors::APPROVE_FROM_ZERO);
assert(!allowance.spender.is_zero(), Errors::APPROVE_TO_ZERO);
Expand Down Expand Up @@ -298,10 +254,9 @@ mod ERC20 {
fn _spend_allowance(
ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256
) {
let current_allowance = self.get_allowance(owner, spender).amount;
if current_allowance != BoundedInt::max() {
self.update_allowance(owner, spender, amount, 0);
}
let mut allowance = self.get_allowance(owner, spender);
allowance.amount = allowance.amount - amount;
self.set_allowance(allowance);
}
}
}
Loading

0 comments on commit 20500f6

Please sign in to comment.