Skip to content

Commit

Permalink
first draft all tests for getCurrentCycle
Browse files Browse the repository at this point in the history
  • Loading branch information
amiecorso committed Oct 9, 2024
1 parent 2608e81 commit 03af888
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 19 deletions.
4 changes: 2 additions & 2 deletions test/base/Base.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ contract Base is Test {
bytes4 constant EIP1271_MAGIC_VALUE = 0x1626ba7e;
uint256 ownerPk = uint256(keccak256("owner"));
address owner = vm.addr(ownerPk);
uint256 permmissionSignerPk = uint256(keccak256("permissionSigner"));
address permissionSigner = vm.addr(permmissionSignerPk);
uint256 permissionSignerPk = uint256(keccak256("permissionSigner"));
address permissionSigner = vm.addr(permissionSignerPk);
uint256 p256PrivateKey = uint256(0x03d99692017473e2d631945a812607b23269d85721e0f370b8d3e7d29a874fd2);
bytes p256PublicKey =
hex"1c05286fe694493eae33312f2d2e0d0abeda8db76238b7a204be1fb87f54ce4228fef61ef4ac300f631657635c28e59bfb2fe71bce1634c81c65642042f6dc4d";
Expand Down
29 changes: 17 additions & 12 deletions test/base/SpendPermissionsBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,31 @@ pragma solidity ^0.8.23;
import {Test, console2} from "forge-std/Test.sol";

import {SpendPermissions} from "../../src/SpendPermissions.sol";

import {MockSpendPermissions} from "../mocks/MockSpendPermissions.sol";
import {Base} from "./Base.sol";

contract SpendPermissionsBase is Base {
address constant ETHER = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

contract SpendPermissionsBase {
MockSpendPermissions mockSpendPermissions;

function _initializeSpendPermissions() internal {
mockSpendPermissions = new MockSpendPermissions();
}

function _createRecurringAllowance(
address account,
address spender,
address token,
uint48 start,
uint48 end,
uint48 period,
uint160 allowance
) internal pure returns (SpendPermissions.RecurringAllowance memory) {
return SpendPermissions.RecurringAllowance(account, spender, token, start, end, period, allowance);
/**
* @dev Helper function to create a SpendPermissions.RecurringAllowance struct with happy path defaults
*/
function _createRecurringAllowance() internal view returns (SpendPermissions.RecurringAllowance memory) {
return SpendPermissions.RecurringAllowance({
account: address(account),
spender: permissionSigner,
token: ETHER,
start: uint48(vm.getBlockTimestamp()),
end: type(uint48).max,
period: 604800,
allowance: 1 ether
});
}

// we'll keep this around until we know we do or don't need it
Expand Down
2 changes: 1 addition & 1 deletion test/src/SpendPermissions/Debug.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity ^0.8.23;

import {Test, console2} from "forge-std/Test.sol";

import {SpendPermissions} from "../../../../src/SpendPermissions.sol";
import {SpendPermissions} from "../../../src/SpendPermissions.sol";

import {Base} from "../../base/Base.sol";

Expand Down
169 changes: 165 additions & 4 deletions test/src/SpendPermissions/getCurrentCycle.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,170 @@ contract GetCurrentCycleTest is Test, SpendPermissionsBase {
_initializeSpendPermissions();
}

function test_getCurrentCycle_revert_beforeRecurringAllowanceStart() public {}
function test_getCurrentCycle_revert_afterRecurringAllowanceEnd() public {}
function test_getCurrentCycle_success_lastCycleStillActive() public {}
function test_getCurrentCycle_success_determineCurrentCycle() public {}
function test_getCurrentCycle_revert_beforeRecurringAllowanceStart(uint48 start) public {
vm.assume(start > 0);

SpendPermissions.RecurringAllowance memory recurringAllowance = _createRecurringAllowance();
recurringAllowance.start = start;
vm.warp(start - 1);
vm.expectRevert(abi.encodeWithSelector(SpendPermissions.BeforeRecurringAllowanceStart.selector, start));
mockSpendPermissions.getCurrentCycle(recurringAllowance);
}

function test_getCurrentCycle_revert_afterRecurringAllowanceEnd(uint48 end) public {
vm.assume(end > 0);
vm.assume(end < type(uint48).max);

SpendPermissions.RecurringAllowance memory recurringAllowance = _createRecurringAllowance();
recurringAllowance.end = end;
vm.warp(end + 1);
vm.expectRevert(abi.encodeWithSelector(SpendPermissions.AfterRecurringAllowanceEnd.selector, end));
mockSpendPermissions.getCurrentCycle(recurringAllowance);
}

function test_getCurrentCycle_success_unusedAllowance(
address permissionSigner,
uint48 start,
uint48 end,
uint48 period,
uint160 allowance
) public {
vm.assume(start > 0);
vm.assume(end > 0);
vm.assume(start < end);
vm.assume(period > 0);
vm.assume(allowance > 0);

SpendPermissions.RecurringAllowance memory recurringAllowance = SpendPermissions.RecurringAllowance({
account: address(account),
spender: permissionSigner,
token: ETHER,
start: start,
end: end,
period: period,
allowance: allowance
});
vm.warp(start);
SpendPermissions.CycleUsage memory usage = mockSpendPermissions.getCurrentCycle(recurringAllowance);
bool endOverflow = uint256(start) + uint256(period) > type(uint48).max;
assertEq(usage.start, start);
assertEq(usage.end, _safeAdd(start, period));
assertEq(usage.spend, 0);
}

function test_getCurrentCycle_success_startOfPeriod(
address permissionSigner,
uint48 start,
uint48 end,
uint48 period,
uint160 allowance,
uint160 spend
) public {
vm.assume(start > 0);
vm.assume(end > 0);
vm.assume(start < end);
vm.assume(period > 0);
vm.assume(allowance > 0);
vm.assume(spend <= allowance);

SpendPermissions.RecurringAllowance memory recurringAllowance = SpendPermissions.RecurringAllowance({
account: address(account),
spender: permissionSigner,
token: ETHER,
start: start,
end: end,
period: period,
allowance: allowance
});

vm.prank(address(account));
mockSpendPermissions.approve(recurringAllowance);

vm.warp(start);
mockSpendPermissions.useRecurringAllowance(recurringAllowance, spend);
SpendPermissions.CycleUsage memory usage = mockSpendPermissions.getCurrentCycle(recurringAllowance);
assertEq(usage.start, start);
assertEq(usage.end, _safeAdd(start, period));
assertEq(usage.spend, spend);
}

function test_getCurrentCycle_success_endOfPeriod(
address permissionSigner,
uint48 start,
uint48 end,
uint48 period,
uint160 allowance,
uint160 spend
) public {
vm.assume(start > 0);
vm.assume(end > 0);
vm.assume(start < end);
vm.assume(period > 0);
vm.assume(period <= end - start); // is this an assumption we're comfortable making? (otherwise fuzz reverts
// with AfterRecurringAllowanceEnd)
vm.assume(allowance > 0);
vm.assume(spend <= allowance);

SpendPermissions.RecurringAllowance memory recurringAllowance = SpendPermissions.RecurringAllowance({
account: address(account),
spender: permissionSigner,
token: ETHER,
start: start,
end: end,
period: period,
allowance: allowance
});

vm.prank(address(account));
mockSpendPermissions.approve(recurringAllowance);

vm.warp(start);
mockSpendPermissions.useRecurringAllowance(recurringAllowance, spend);

vm.warp(_safeAdd(start, period) - 1);
SpendPermissions.CycleUsage memory usage = mockSpendPermissions.getCurrentCycle(recurringAllowance);
assertEq(usage.start, start);
assertEq(usage.end, _safeAdd(start, period));
assertEq(usage.spend, spend);
}

function test_getCurrentCycle_succes_resetsAfterPeriod(
address permissionSigner,
uint48 start,
uint48 end,
uint48 period,
uint160 allowance,
uint160 spend
) public {
vm.assume(start > 0);
vm.assume(end > 0);
vm.assume(start < end);
vm.assume(period > 0);
vm.assume(period <= end - start); // is this an assumption we're comfortable making? (otherwise fuzz reverts
// with AfterRecurringAllowanceEnd)
vm.assume(allowance > 0);
vm.assume(spend <= allowance);

SpendPermissions.RecurringAllowance memory recurringAllowance = SpendPermissions.RecurringAllowance({
account: address(account),
spender: permissionSigner,
token: ETHER,
start: start,
end: end,
period: period,
allowance: allowance
});

vm.prank(address(account));
mockSpendPermissions.approve(recurringAllowance);

vm.warp(start);
mockSpendPermissions.useRecurringAllowance(recurringAllowance, spend);

vm.warp(_safeAdd(start, period));
SpendPermissions.CycleUsage memory usage = mockSpendPermissions.getCurrentCycle(recurringAllowance);
assertEq(usage.start, _safeAdd(start, period));
assertEq(usage.end, _safeAdd(_safeAdd(start, period), period));
assertEq(usage.spend, 0);
}
}

0 comments on commit 03af888

Please sign in to comment.