Skip to content

Commit da36816

Browse files
committed
(test) Getters of Paymaster V3
1 parent 8d930db commit da36816

File tree

4 files changed

+147
-8
lines changed

4 files changed

+147
-8
lines changed

test/foundry/paymasterV3/AdminActionsTest.t.sol

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,6 @@ pragma solidity ^0.8.29;
55
import {BasePaymasterTest as Base} from "test/foundry/paymasterV3/BasePaymasterTest.t.sol";
66
import {IStakeManager} from "lib/account-abstractionV8/contracts/interfaces/IStakeManager.sol";
77

8-
struct DepositInfo {
9-
uint256 deposit;
10-
bool staked;
11-
uint112 stake;
12-
uint32 unstakeDelaySec;
13-
uint48 withdrawTime;
14-
}
15-
168
uint256 constant stakeAmount = 0.1 ether;
179
uint32 constant unstakeDelay = 8600;
1810

test/foundry/paymasterV3/BasePaymasterTest.t.sol

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity ^0.8.29;
33

4+
import {console2 as console} from "lib/forge-std/src/test.sol";
45
import {PaymasterDataTest as Data} from "test/foundry/paymasterV3/PaymasterDataTest.t.sol";
56
import {OPFPaymasterV3 as Paymaster} from "contracts/paymaster/PaymasterV3/OPFPaymasterV3.sol";
7+
import {PackedUserOperation} from "@account-abstraction-v8/interfaces/PackedUserOperation.sol";
68

79
contract BasePaymasterTest is Data {
810
Paymaster PM;
@@ -44,4 +46,34 @@ contract BasePaymasterTest is Data {
4446
function _warp(uint256 _time) internal {
4547
vm.warp(block.timestamp + _time);
4648
}
49+
50+
function _getHash(PackedUserOperation calldata _userOp, uint256 paymasterDataLength)
51+
internal
52+
view
53+
returns (bytes32)
54+
{
55+
bytes32 userOpHash = keccak256(
56+
abi.encode(
57+
_getSender(_userOp),
58+
_userOp.nonce,
59+
_userOp.accountGasLimits,
60+
_userOp.preVerificationGas,
61+
_userOp.gasFees,
62+
keccak256(_userOp.initCode),
63+
keccak256(_userOp.callData),
64+
keccak256(_userOp.paymasterAndData[:PAYMASTER_DATA_OFFSET + paymasterDataLength])
65+
)
66+
);
67+
68+
return keccak256(abi.encode(userOpHash, block.chainid));
69+
}
70+
71+
function _getSender(PackedUserOperation calldata userOp) internal pure returns (address) {
72+
address data;
73+
//read sender from userOp, which is first userOp member (saves 800 gas...)
74+
assembly {
75+
data := calldataload(userOp)
76+
}
77+
return address(uint160(data));
78+
}
4779
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity ^0.8.29;
4+
5+
import {IEntryPoint} from "@account-abstraction-v8/interfaces/IEntryPoint.sol";
6+
import {BasePaymasterTest as Base} from "test/foundry/paymasterV3/BasePaymasterTest.t.sol";
7+
import {PackedUserOperation} from "@account-abstraction-v8/interfaces/PackedUserOperation.sol";
8+
import {console2 as console} from "lib/forge-std/src/test.sol";
9+
10+
contract GettersTest is Base {
11+
function test_signerCount() public {
12+
uint256 sC = _signerCount();
13+
assertEq(sC, signers.length);
14+
}
15+
16+
function test_signerAt() public {
17+
uint256 sC = _signerCount();
18+
19+
for (uint256 i = 0; i < sC;) {
20+
address signer = PM.signerAt(i);
21+
assertEq(signer, signers[i]);
22+
unchecked {
23+
i++;
24+
}
25+
}
26+
}
27+
28+
function test_getSigners() public {
29+
address[] memory getSigners = PM.getSigners();
30+
31+
for (uint256 i = 0; i < getSigners.length;) {
32+
assertEq(getSigners[i], signers[i]);
33+
unchecked {
34+
i++;
35+
}
36+
}
37+
}
38+
39+
function test_OnwerAndManager() public {
40+
address getOwner = PM.OWNER();
41+
address getManager = PM.MANAGER();
42+
43+
assertEq(owner, getOwner);
44+
assertEq(manager, getManager);
45+
}
46+
47+
function test_getEP() public {
48+
IEntryPoint EP = PM.ENTRY_POINT_V8();
49+
assertEq(address(EP), address(ENTRY_POINT_V8));
50+
}
51+
52+
function test_getDeposit() public {
53+
uint256 getDeposit = PM.getDeposit();
54+
assertEq(getDeposit, 0);
55+
}
56+
57+
function test_getCostInToken() public {
58+
uint256 _actualGasCost = 100_000;
59+
uint256 _postOpGas = 80_000;
60+
uint256 _actualUserOpFeePerGas = 200_000;
61+
uint256 _exchangeRate = 4000_000;
62+
63+
uint256 actualRate = ((_actualGasCost + (_postOpGas * _actualUserOpFeePerGas)) * _exchangeRate) / 1e18;
64+
65+
uint256 getcost = PM.getCostInToken(_actualGasCost, _postOpGas, _actualUserOpFeePerGas, _exchangeRate);
66+
67+
assertEq(actualRate, getcost);
68+
}
69+
70+
function test_getHashModeVERIFYING_MODE() public {
71+
PackedUserOperation memory userOp = _getFreshUserOp();
72+
bytes memory paymasterAndData =
73+
new bytes(PAYMASTER_DATA_OFFSET + MODE_AND_ALLOW_ALL_BUNDLERS_LENGTH + VERIFYING_PAYMASTER_DATA_LENGTH);
74+
75+
bytes20 paymasterAddress = bytes20(address(PM));
76+
for (uint256 i = 0; i < 20; i++) {
77+
paymasterAndData[i] = paymasterAddress[i];
78+
}
79+
80+
userOp.paymasterAndData = paymasterAndData;
81+
this._testFetHashModeVERIFYING_MODE(userOp);
82+
}
83+
84+
function _testFetHashModeVERIFYING_MODE(PackedUserOperation calldata _userOp) external {
85+
bytes32 computeHash = _getHash(_userOp, MODE_AND_ALLOW_ALL_BUNDLERS_LENGTH + VERIFYING_PAYMASTER_DATA_LENGTH);
86+
bytes32 hash = PM.getHash(uint8(0), _userOp);
87+
assertEq(computeHash, hash);
88+
}
89+
90+
function _signerCount() internal view returns (uint256 counter) {
91+
counter = PM.signerCount();
92+
}
93+
}

test/foundry/paymasterV3/PaymasterDataTest.t.sol

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ pragma solidity ^0.8.29;
44

55
import {Test} from "lib/forge-std/src/Test.sol";
66
import {IEntryPoint} from "@account-abstraction-v8/interfaces/IEntryPoint.sol";
7+
import {UserOperationLib} from "@account-abstraction-v8/core/UserOperationLib.sol";
8+
import {PackedUserOperation} from "@account-abstraction-v8/interfaces/PackedUserOperation.sol";
79

810
contract PaymasterDataTest is Test {
911
IEntryPoint ENTRY_POINT_V8 = IEntryPoint(0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108);
@@ -14,16 +16,24 @@ contract PaymasterDataTest is Test {
1416
uint256[] signersPK;
1517
address[] signers;
1618

19+
uint256 senderPk;
20+
address sender;
21+
1722
uint256 constant signersLength = 3;
1823

1924
uint256 forkId;
2025
string SEPOLIA_RPC_URL = "https://eth-sepolia.g.alchemy.com/v2/EIOmdDtOw7ulufI5S27isOfZfW51PQXB";
2126

27+
uint8 immutable VERIFYING_PAYMASTER_DATA_LENGTH = 12;
28+
uint8 immutable MODE_AND_ALLOW_ALL_BUNDLERS_LENGTH = 1;
29+
uint256 immutable PAYMASTER_DATA_OFFSET = UserOperationLib.PAYMASTER_DATA_OFFSET;
30+
2231
function setUp() public virtual {
2332
forkId = vm.createFork(SEPOLIA_RPC_URL);
2433
vm.selectFork(forkId);
2534

2635
(owner, ownerPK) = makeAddrAndKey("owner");
36+
(sender, senderPk) = makeAddrAndKey("sender");
2737
(manager, managerPK) = makeAddrAndKey("manager");
2838

2939
for (uint256 i = 0; i < signersLength;) {
@@ -35,4 +45,16 @@ contract PaymasterDataTest is Test {
3545
}
3646
}
3747
}
48+
49+
function _getFreshUserOp() internal view returns (PackedUserOperation memory userOp) {
50+
userOp.sender = sender;
51+
userOp.nonce = 0;
52+
userOp.initCode = hex"";
53+
userOp.callData = hex"";
54+
userOp.accountGasLimits = hex"";
55+
userOp.preVerificationGas = 0;
56+
userOp.gasFees = hex"";
57+
userOp.paymasterAndData = hex"";
58+
userOp.signature = hex"";
59+
}
3860
}

0 commit comments

Comments
 (0)