Skip to main content

ERC20PermitMod

ERC-2612 permit and domain separator logic

Key Features
  • Provides internal functions for ERC-2612 permit logic.
  • Includes DOMAIN_SEPARATOR() for signature validation.
  • Leverages diamond storage pattern for state management.
  • Functions are internal, intended for use by other facets.
Module Usage

This module provides internal functions for use in your custom facets. Import it to access shared logic and storage.

Overview

This module provides internal functions for managing ERC-2612 permit logic and domain separators within a diamond. Facets can import this module to handle permit validation and signature encoding, leveraging shared diamond storage. The domain separator ensures signature uniqueness per contract and chain ID, preventing replay attacks.


Storage

ERC20PermitStorage

storage-location: erc8042:compose.erc20.permit

Definition
struct ERC20PermitStorage {
mapping(address owner => uint256) nonces;
}

ERC20Storage

storage-location: erc8042:compose.erc20

Definition
struct ERC20Storage {
mapping(address owner => uint256 balance) balanceOf;
uint256 totalSupply;
mapping(address owner => mapping(address spender => uint256 allowance)) allowance;
uint8 decimals;
string name;
}

State Variables

PropertyTypeDescription
ERC20_STORAGE_POSITIONbytes32Diamond storage slot position for this module (Value: keccak256("compose.erc20"))
STORAGE_POSITIONbytes32Diamond storage slot position for this module (Value: keccak256("compose.erc20.permit"))

Functions

DOMAIN_SEPARATOR

Returns the domain separator used in the encoding of the signature for {permit}. This value is unique to a contract and chain ID combination to prevent replay attacks.

function DOMAIN_SEPARATOR() view returns (bytes32);

Returns:

PropertyTypeDescription
-bytes32The domain separator.

getERC20Storage

function getERC20Storage() pure returns (ERC20Storage storage s);

getPermitStorage

function getPermitStorage() pure returns (ERC20PermitStorage storage s);

permit

Validates a permit signature and sets allowance. Emits Approval event; must be emitted by the calling facet/contract.

function permit(address _owner, address _spender, uint256 _value, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s) ;

Parameters:

PropertyTypeDescription
_owneraddressToken owner.
_spenderaddressToken spender.
_valueuint256Allowance value.
_deadlineuint256Permit's time deadline.

Events

Errors

Best Practices

Best Practice
  • Use the permit function within a facet that manages ERC-20 allowances.
  • Call DOMAIN_SEPARATOR() to obtain the correct domain separator for signature generation.
  • Ensure the calling facet emits the Approval event after a successful permit validation.

Integration Notes

Shared Storage

This module interacts with diamond storage via the ERC20_STORAGE_POSITION slot, identified by keccak256("compose.erc20"). The ERC20PermitStorage and ERC20Storage structs are utilized. Changes to state, such as allowance updates after permit validation, are managed by the calling facet, ensuring composability within the diamond storage pattern.

Was this helpful?
Last updated: