Skip to main content

ERC-20 Permit Module

Manage ERC-2612 permit signatures and domain separators

Key Features
  • Provides internal functions for ERC-2612 permit functionality.
  • Manages unique domain separators to prevent replay attacks.
  • Interacts with diamond storage for allowance updates.
  • No external dependencies, promoting composability.
Module Usage

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

Overview

This module manages ERC-2612 permit logic, including domain separators and signature validation for allowance approvals. Facets can use this module to implement the permit functionality, ensuring unique domain separators per contract and chain ID to prevent replay attacks. Changes to allowances made via permit are recorded in diamond storage and are visible to all facets.

Storage

ERC20MetadataStorage

storage-location: erc8042:erc20.metadata

Definition
struct ERC20MetadataStorage {
string name;
}

ERC20Storage

storage-location: erc8042:erc20

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

NoncesStorage

storage-location: erc8042:nonces

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

State Variables

PropertyTypeDescription
ERC20_METADATA_STORAGE_POSITIONbytes32Diamond storage slot position for this module (Value: keccak256("erc20.metadata"))
ERC20_STORAGE_POSITIONbytes32Diamond storage slot position for this module (Value: keccak256("erc20"))
STORAGE_POSITIONbytes32Diamond storage slot position for this module (Value: keccak256("nonces"))

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.

getERC20MetadataStorage

function getERC20MetadataStorage() pure returns (ERC20MetadataStorage storage s);

getERC20Storage

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

getPermitStorage

function getPermitStorage() pure returns (NoncesStorage 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
  • Ensure the calling facet correctly emits the Approval event after a successful permit call.
  • Verify that the DOMAIN_SEPARATOR used by the module is correctly initialized and unique to the contract and chain ID.
  • Handle the ERC2612InvalidSignature and ERC20InvalidSpender errors to provide appropriate feedback to users.

Integration Notes

Shared Storage

This module interacts with diamond storage to manage permit-related state, specifically related to allowances and nonces. The permit function updates allowance values directly in the shared diamond storage. The DOMAIN_SEPARATOR function is crucial for signature verification and ensures that permits are specific to the contract instance and chain. Changes made via the permit function are immediately visible to any other facet that reads the allowance state from the diamond storage.

Was this helpful?
Last updated:

Newsletter

Get notified about releases, feature announcements, and technical deep-dives on building smart contracts with Compose.

No spam. Unsubscribe anytime.