Skip to content

Commit

Permalink
feat: add special paymaster list to still count towards limits
Browse files Browse the repository at this point in the history
  • Loading branch information
howydev committed Jul 10, 2024
1 parent 60e9a6f commit 0929d4a
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/plugins/BasePlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ abstract contract BasePlugin is ERC165, IPlugin {
return interfaceId == type(IPlugin).interfaceId || super.supportsInterface(interfaceId);
}

function _getSelectorAndCalldata(bytes calldata data) internal view returns (bytes4, bytes memory) {
function _getSelectorAndCalldata(bytes calldata data) internal pure returns (bytes4, bytes memory) {
if (bytes4(data[:4]) == IAccountExecute.executeUserOp.selector) {
(PackedUserOperation memory uo,) = abi.decode(data[4:], (PackedUserOperation, bytes32));
bytes4 selector;
Expand Down
18 changes: 14 additions & 4 deletions src/plugins/NativeTokenLimitPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import {BasePlugin, IERC165} from "./BasePlugin.sol";
/// @author ERC-6900 Authors
/// @notice This plugin supports a single total native token spend limit.
/// It tracks a total spend limit across UserOperation gas limits and native token transfers.
/// If a paymaster is used, UO gas would not cause the limit to decrease.

/// If a non whitelisted paymaster is used, UO gas would not cause the limit to decrease.
/// If a whitelisted paymaster is used, gas is still counted towards the limit
contract NativeTokenLimitPlugin is BasePlugin, IExecutionHook, IValidationHook {
using UserOperationLib for PackedUserOperation;
using EnumerableSet for EnumerableSet.Bytes32Set;
Expand All @@ -27,6 +27,9 @@ contract NativeTokenLimitPlugin is BasePlugin, IExecutionHook, IValidationHook {
string public constant AUTHOR = "ERC-6900 Authors";

mapping(uint256 funcIds => mapping(address account => uint256 limit)) public limits;
// Accounts should add paymasters that still use the accounts tokens here
// E.g. ERC20 paymasters that pull funds from the account
mapping(address paymaster => mapping(address account => bool allowed)) public specialPaymasters;

error ExceededNativeTokenLimit();
error ExceededNumberOfEntities();
Expand All @@ -35,13 +38,20 @@ contract NativeTokenLimitPlugin is BasePlugin, IExecutionHook, IValidationHook {
limits[functionId][msg.sender] = newLimit;
}

function updateSpecialPaymaster(address paymaster, bool allowed) external {
specialPaymasters[paymaster][msg.sender] = allowed;
}

/// @inheritdoc IValidationHook
function preUserOpValidationHook(uint8 functionId, PackedUserOperation calldata userOp, bytes32)
external
returns (uint256)
{
// Decrease limit only if no paymaster is used
if (userOp.paymasterAndData.length == 0) {
// Decrease limit only if no paymaster is used, or if its a special paymaster
if (
userOp.paymasterAndData.length == 0
|| specialPaymasters[address(bytes20(userOp.paymasterAndData[:20]))][msg.sender]
) {
uint256 vgl = UserOperationLib.unpackVerificationGasLimit(userOp);
uint256 cgl = UserOperationLib.unpackCallGasLimit(userOp);
uint256 totalGas = userOp.preVerificationGas + vgl + cgl;
Expand Down

0 comments on commit 0929d4a

Please sign in to comment.