paymaster should always call requireFromEntryPoint from validatePaymasterUserOp (#185)

* make internal _validatePaymasterUserOp the template method so we can add requireFromEntryPoint
* adding forced _requireFromEntryPoint
This commit is contained in:
Dror Tirosh
2023-01-25 15:42:21 +02:00
committed by GitHub
parent 1dfb17366f
commit c284f588ee
8 changed files with 25 additions and 20 deletions

View File

@@ -15,18 +15,20 @@ import "../interfaces/IEntryPoint.sol";
*/
abstract contract BasePaymaster is IPaymaster, Ownable {
IEntryPoint public entryPoint;
IEntryPoint immutable public entryPoint;
constructor(IEntryPoint _entryPoint) {
setEntryPoint(_entryPoint);
}
function setEntryPoint(IEntryPoint _entryPoint) public onlyOwner {
entryPoint = _entryPoint;
}
function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)
external virtual override returns (bytes memory context, uint256 sigTimeRange);
external override returns (bytes memory context, uint256 sigTimeRange) {
_requireFromEntryPoint();
return _validatePaymasterUserOp(userOp, userOpHash, maxCost);
}
function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)
internal virtual returns (bytes memory context, uint256 sigTimeRange);
function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external override {
_requireFromEntryPoint();

View File

@@ -122,8 +122,8 @@ contract DepositPaymaster is BasePaymaster {
* Note that the sender's balance is not checked. If it fails to pay from its balance,
* this deposit will be used to compensate the paymaster for the transaction.
*/
function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)
external view override returns (bytes memory context, uint256 sigTimeRange) {
function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)
internal view override returns (bytes memory context, uint256 sigTimeRange) {
(userOpHash);
// verificationGasLimit is dual-purposed, as gas limit for postOp. make sure it is high enough

View File

@@ -67,8 +67,8 @@ contract TokenPaymaster is BasePaymaster, ERC20 {
* verify the sender has enough tokens.
* (since the paymaster is also the token, there is no notion of "approval")
*/
function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 /*userOpHash*/, uint256 requiredPreFund)
external view override returns (bytes memory context, uint256 sigTimeRange) {
function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 /*userOpHash*/, uint256 requiredPreFund)
internal view override returns (bytes memory context, uint256 sigTimeRange) {
uint256 tokenPrefund = getTokenValueOfEth(requiredPreFund);
// verificationGasLimit is dual-purposed, as gas limit for postOp. make sure it is high enough

View File

@@ -53,8 +53,8 @@ contract VerifyingPaymaster is BasePaymaster {
* verify our external signer signed this request.
* the "paymasterAndData" is expected to be the paymaster and a signature over the entire request params
*/
function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 /*userOpHash*/, uint256 requiredPreFund)
external view override returns (bytes memory context, uint256 sigTimeRange) {
function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 /*userOpHash*/, uint256 requiredPreFund)
internal view override returns (bytes memory context, uint256 sigTimeRange) {
(requiredPreFund);
bytes32 hash = getHash(userOp);

View File

@@ -11,7 +11,8 @@ contract TestExpirePaymaster is BasePaymaster {
constructor(IEntryPoint _entryPoint) BasePaymaster(_entryPoint)
{}
function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint maxCost) external virtual override view
function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint maxCost)
internal virtual override view
returns (bytes memory context, uint256 sigTimeRange) {
(userOp, userOpHash, maxCost);
(uint64 validAfter, uint64 validUntil) = abi.decode(userOp.paymasterAndData[20 :], (uint64, uint64));

View File

@@ -14,11 +14,13 @@ contract TestPaymasterAcceptAll is BasePaymaster {
if (tx.origin != msg.sender) {
_transferOwnership(tx.origin);
}
}
function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint maxCost) external virtual override view
function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint maxCost)
internal virtual override view
returns (bytes memory context, uint256 sigTimeRange) {
(userOp, userOpHash, maxCost);
return ("", 0);
return ("", maxCost == 12345 ? 1 : 0);
}
}

View File

@@ -14,7 +14,7 @@ context('Minimal Paymaster', function () {
let paymasterAddress: string
before(async () => {
const paymasterInit = hexValue(new TestPaymasterAcceptAll__factory(ethersSigner).getDeployTransaction(g.entryPoint().address).data!)
const paymasterAddress = await new Create2Factory(ethers.provider, ethersSigner).deploy(paymasterInit, 0)
paymasterAddress = await new Create2Factory(ethers.provider, ethersSigner).deploy(paymasterInit, 0)
const paymaster = TestPaymasterAcceptAll__factory.connect(paymasterAddress, ethersSigner)
await paymaster.addStake(1, { value: 1 })
await g.entryPoint().depositTo(paymaster.address, { value: parseEther('10') })

View File

@@ -16,13 +16,13 @@
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple - diff from previous │ 11 │ │ 43780 │ 12735 ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple paymaster │ 1 │ 78111 │ │ ║
║ simple paymaster │ 1 │ 84411 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple paymaster with diff │ 2 │ │ 43585 │ 12540
║ simple paymaster with diff │ 2 │ │ 42598 │ 11553
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple paymaster │ 10 │ 470461 │ │ ║
║ simple paymaster │ 10 │ 467954 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple paymaster with diff │ 11 │ │ 43696 │ 12651
║ simple paymaster with diff │ 11 │ │ 42722 │ 11677
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ big tx 5k │ 1 │ 179846 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢