While I was looking into the Uniswap v4 smart contracts I saw that the PoolManager extends to the ERC-6909 standard. Given that I was unfamiliar with this multi token standard, I decided to dig into the topic. Let’s dive into the standard.
Hybrid Allowance-Operator Permission Scheme
The ERC6909 standard introduces a hybrid permission scheme that combines the flexibility of allowances (similar to ERC20) with the scalability of operator approvals (similar to ERC1155). This approach allows for more granular control over token transfers while maintaining the ability to manage multiple token types efficiently.
Allowances
- Allowances enable an external account (spender) to transfer tokens of a specific token ID on behalf of the token owner.
- This is useful for scenarios where a user wants to grant limited permissions to another account for a specific token type.
- The allowance is defined per token ID, allowing for fine-grained control over which tokens can be transferred and in what amounts.
Operators
- Operators are granted full transfer permissions for all token IDs for a user.
- This is useful for scenarios where a user wants to delegate full control over their tokens to another account, such as a marketplace or a custodial service.
- Operators can manage all token types for the user, providing a scalable solution for managing multiple tokens.
Permission Related Functions
ERC-6909
Below we can see the permission related function signatures form the standard:
function allowance(address owner, address spender, uint256 id) external view returns (uint256 amount);
function isOperator(address owner, address spender) external view returns (bool status);
function approve(address spender, uint256 id, uint256 amount) external returns (bool success);
function setOperator(address spender, bool approved) external returns (bool success);
ERC-1155
This contrasts with the ERC-1155 standard, where the permission related functions are:
function setApprovalForAll(address _operator, bool _approved) external;
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
ERC-721
Or in the ERC-721:
function getApproved(uint256 _tokenId) external view returns (address);
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
function approve(address _approved, uint256 _tokenId) external payable;
function setApprovalForAll(address _operator, bool _approved) external;
ERC-20
Or lastly, the ERC-20 standard:
function approve(address _spender, uint256 _value) public returns (bool success)
function allowance(address _owner, address _spender) public view returns (uint256 remaining)
Contract: https://github.com/seaona/contracts/blob/main/ERC6909-Solmate.sol