Skip to main content

PimlicoERC20Paymaster

Git Source

Inherits: BasePaymaster

An ERC-4337 Paymaster contract by Pimlico which is able to sponsor gas fees in exchange for ERC20 tokens. The contract refunds excess tokens if the actual gas cost is lower than the initially provided amount. It also allows updating price configuration and withdrawing tokens by the contract owner. The contract uses an Oracle to fetch the latest token prices.

Inherits from BasePaymaster.

State Variables

priceDenominator

uint256 public constant priceDenominator = 1e6;

REFUND_POSTOP_COST

uint256 public constant REFUND_POSTOP_COST = 40000;

token

IERC20 public immutable token;

tokenDecimals

uint256 public immutable tokenDecimals;

tokenOracle

IOracle public immutable tokenOracle;

nativeAssetOracle

IOracle public immutable nativeAssetOracle;

previousPrice

uint192 public previousPrice;

priceMarkup

uint32 public priceMarkup;

priceUpdateThreshold

uint32 public priceUpdateThreshold;

Functions

constructor

Initializes the PimlicoERC20Paymaster contract with the given parameters.

constructor(
IERC20 _token,
IEntryPoint _entryPoint,
IOracle _tokenOracle,
IOracle _nativeAssetOracle,
address _owner,
uint8 _tokenDecimals
) BasePaymaster(_entryPoint);

Parameters

NameTypeDescription
_tokenIERC20The ERC20 token used for transaction fee payments.
_entryPointIEntryPointThe EntryPoint contract used in the Account Abstraction infrastructure.
_tokenOracleIOracleThe Oracle contract used to fetch the latest token prices.
_nativeAssetOracleIOracleThe Oracle contract used to fetch the latest native asset (ETH, Matic, Avax, etc.) prices.
_owneraddressThe address that will be set as the owner of the contract.
_tokenDecimalsuint8

updateConfig

Updates the price markup and price update threshold configurations.

function updateConfig(uint32 _priceMarkup, uint32 _updateThreshold) external onlyOwner;

Parameters

NameTypeDescription
_priceMarkupuint32The new price markup percentage (1e6 = 100%).
_updateThresholduint32The new price update threshold percentage (1e6 = 100%).

withdrawToken

Allows the contract owner to withdraw a specified amount of tokens from the contract.

function withdrawToken(address to, uint256 amount) external onlyOwner;

Parameters

NameTypeDescription
toaddressThe address to transfer the tokens to.
amountuint256The amount of tokens to transfer.

updatePrice

Updates the token price by fetching the latest price from the Oracle.

function updatePrice() external;

_validatePaymasterUserOp

Validates a paymaster user operation and calculates the required token amount for the transaction.

function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32, uint256 requiredPreFund)
internal
override
returns (bytes memory context, uint256 validationResult);

Parameters

NameTypeDescription
userOpUserOperationThe user operation data.
<none>bytes32
requiredPreFunduint256The amount of tokens required for pre-funding.

Returns

NameTypeDescription
contextbytesThe context containing the token amount and user sender address (if applicable).
validationResultuint256A uint256 value indicating the result of the validation (always 0 in this implementation).

_postOp

Performs post-operation tasks, such as updating the token price and refunding excess tokens.

This function is called after a user operation has been executed or reverted.

function _postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) internal override;

Parameters

NameTypeDescription
modePostOpModeThe post-operation mode (either successful or reverted).
contextbytesThe context containing the token amount and user sender address.
actualGasCostuint256The actual gas cost of the transaction.

fetchPrice

Fetches the latest price from the given Oracle.

This function is used to get the latest price from the tokenOracle or nativeAssetOracle.

function fetchPrice(IOracle _oracle) internal view returns (uint192 price);

Parameters

NameTypeDescription
_oracleIOracleThe Oracle contract to fetch the price from.

Returns

NameTypeDescription
priceuint192The latest price fetched from the Oracle.

Events

ConfigUpdated

event ConfigUpdated(uint32 priceMarkup, uint32 updateThreshold);

UserOperationSponsored

event UserOperationSponsored(address indexed user, uint256 actualTokenNeeded, uint256 actualGasCost);