From e7f0e7143e3aa2568bc818c92e2d8d76ffdf89a6 Mon Sep 17 00:00:00 2001 From: Amie Corso Date: Tue, 15 Oct 2024 17:36:16 -0700 Subject: [PATCH] add test for permitAndSpend and ability to init w spendpermission as owner --- test/base/SpendPermissionManagerBase.sol | 7 +-- test/src/SpendPermissions/permit.t.sol | 4 +- .../src/SpendPermissions/permitAndSpend.t.sol | 58 +++++++++++++++++++ 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/test/base/SpendPermissionManagerBase.sol b/test/base/SpendPermissionManagerBase.sol index 33187e8..d3b2c23 100644 --- a/test/base/SpendPermissionManagerBase.sol +++ b/test/base/SpendPermissionManagerBase.sol @@ -53,7 +53,8 @@ contract SpendPermissionManagerBase is Base { function _signSpendPermission6492( SpendPermissionManager.SpendPermission memory spendPermission, uint256 ownerPk, - uint256 ownerIndex + uint256 ownerIndex, + bytes[] memory allInitialOwners ) internal view returns (bytes memory) { bytes32 spendPermissionHash = mockSpendPermissionManager.getHash(spendPermission); // construct replaySafeHash without relying on the account contract being deployed @@ -76,9 +77,7 @@ contract SpendPermissionManagerBase is Base { // wrap inner sig in 6492 format ====================== address factory = address(mockCoinbaseSmartWalletFactory); - bytes[] memory owners = new bytes[](1); - owners[0] = abi.encode(vm.addr(ownerPk)); - bytes memory factoryCallData = abi.encodeWithSignature("createAccount(bytes[],uint256)", owners, 0); + bytes memory factoryCallData = abi.encodeWithSignature("createAccount(bytes[],uint256)", allInitialOwners, 0); bytes memory eip6492Signature = abi.encode(factory, factoryCallData, wrappedSignature); eip6492Signature = abi.encodePacked(eip6492Signature, EIP6492_MAGIC_VALUE); return eip6492Signature; diff --git a/test/src/SpendPermissions/permit.t.sol b/test/src/SpendPermissions/permit.t.sol index fabc44f..c1121a6 100644 --- a/test/src/SpendPermissions/permit.t.sol +++ b/test/src/SpendPermissions/permit.t.sol @@ -189,7 +189,7 @@ contract PermitTest is SpendPermissionManagerBase { period: period, allowance: allowance }); - bytes memory signature = _signSpendPermission6492(spendPermission, ownerPk, 0); + bytes memory signature = _signSpendPermission6492(spendPermission, ownerPk, 0, owners); // verify that the account isn't deployed yet vm.assertEq(counterfactualAccount.code.length, 0); @@ -232,7 +232,7 @@ contract PermitTest is SpendPermissionManagerBase { period: period, allowance: allowance }); - bytes memory signature = _signSpendPermission6492(spendPermission, ownerPk, 0); + bytes memory signature = _signSpendPermission6492(spendPermission, ownerPk, 0, owners); // verify that the account is already deployed vm.assertGt(counterfactualAccount.code.length, 0); diff --git a/test/src/SpendPermissions/permitAndSpend.t.sol b/test/src/SpendPermissions/permitAndSpend.t.sol index 253c576..9e2918b 100644 --- a/test/src/SpendPermissions/permitAndSpend.t.sol +++ b/test/src/SpendPermissions/permitAndSpend.t.sol @@ -222,4 +222,62 @@ contract PermitAndSpendTest is SpendPermissionManagerBase { assertEq(usage.end, _safeAddUint48(start, period)); assertEq(usage.spend, spend); } + + function test_permitAndSpend_success_ether_eip6492( + uint128 ownerPk, + address spender, + address recipient, + uint48 start, + uint48 end, + uint48 period, + uint160 allowance, + uint160 spend + ) public { + assumePayable(recipient); + vm.assume(ownerPk != 0); + vm.assume(start > 0); + vm.assume(end > 0); + vm.assume(start < end); + vm.assume(period > 0); + vm.assume(spend > 0); + vm.assume(allowance > 0); + vm.assume(allowance >= spend); + address ownerAddress = vm.addr(ownerPk); + bytes[] memory owners = new bytes[](2); + owners[0] = abi.encode(ownerAddress); + owners[1] = abi.encode(address(mockSpendPermissionManager)); + address counterfactualAccount = mockCoinbaseSmartWalletFactory.getAddress(owners, 0); + vm.assume(recipient != counterfactualAccount); // otherwise balance checks can fail + + // create a 6492-compliant signature for the spend permission + SpendPermissionManager.SpendPermission memory spendPermission = SpendPermissionManager.SpendPermission({ + account: counterfactualAccount, + spender: spender, + token: NATIVE_TOKEN, + start: start, + end: end, + period: period, + allowance: allowance + }); + vm.deal(counterfactualAccount, allowance); + vm.deal(recipient, 0); + assertEq(counterfactualAccount.balance, allowance); + assertEq(recipient.balance, 0); + + bytes memory signature = _signSpendPermission6492(spendPermission, ownerPk, 0, owners); + // verify that the account isn't deployed yet + vm.assertEq(counterfactualAccount.code.length, 0); + + vm.warp(start); + + vm.startPrank(spender); + mockSpendPermissionManager.permitAndSpend(spendPermission, signature, recipient, spend); + + assertEq(counterfactualAccount.balance, allowance - spend); + assertEq(recipient.balance, spend); + SpendPermissionManager.PeriodSpend memory usage = mockSpendPermissionManager.getCurrentPeriod(spendPermission); + assertEq(usage.start, start); + assertEq(usage.end, _safeAddUint48(start, period)); + assertEq(usage.spend, spend); + } }