From 01cdad137fd267dfa953481a1f5467d4aa59a0bd Mon Sep 17 00:00:00 2001 From: maxnorm Date: Tue, 30 Dec 2025 20:11:24 +0000 Subject: [PATCH] docs: auto-generate docs pages from NatSpec --- website/docs/library/_category_.json | 10 + .../AccessControl/AccessControlFacet.mdx | 558 ++++++++++++++ .../access/AccessControl/AccessControlMod.mdx | 483 ++++++++++++ .../access/AccessControl/_category_.json | 10 + .../library/access/AccessControl/index.mdx | 29 + .../AccessControlPausableFacet.mdx | 351 +++++++++ .../AccessControlPausableMod.mdx | 352 +++++++++ .../AccessControlPausable/_category_.json | 10 + .../access/AccessControlPausable/index.mdx | 29 + .../AccessControlTemporalFacet.mdx | 431 +++++++++++ .../AccessControlTemporalMod.mdx | 508 +++++++++++++ .../AccessControlTemporal/_category_.json | 10 + .../access/AccessControlTemporal/index.mdx | 29 + .../docs/library/access/Owner/OwnerFacet.mdx | 213 ++++++ .../docs/library/access/Owner/OwnerMod.mdx | 284 +++++++ .../docs/library/access/Owner/_category_.json | 10 + website/docs/library/access/Owner/index.mdx | 29 + .../OwnerTwoSteps/OwnerTwoStepsFacet.mdx | 251 ++++++ .../access/OwnerTwoSteps/OwnerTwoStepsMod.mdx | 330 ++++++++ .../access/OwnerTwoSteps/_category_.json | 10 + .../library/access/OwnerTwoSteps/index.mdx | 29 + website/docs/library/access/_category_.json | 10 + website/docs/library/access/index.mdx | 50 ++ .../library/diamond/DiamondInspectFacet.mdx | 185 +++++ .../library/diamond/DiamondLoupeFacet.mdx | 243 ++++++ website/docs/library/diamond/DiamondMod.mdx | 271 +++++++ .../library/diamond/DiamondUpgradeFacet.mdx | 511 +++++++++++++ .../library/diamond/DiamondUpgradeMod.mdx | 570 ++++++++++++++ website/docs/library/diamond/_category_.json | 10 + .../diamond/example/ExampleDiamond.mdx | 173 +++++ .../library/diamond/example/_category_.json | 10 + .../docs/library/diamond/example/index.mdx | 22 + website/docs/library/diamond/index.mdx | 57 ++ website/docs/library/index.mdx | 51 ++ .../interfaceDetection/ERC165/ERC165Facet.mdx | 158 ++++ .../interfaceDetection/ERC165/ERC165Mod.mdx | 163 ++++ .../interfaceDetection/ERC165/_category_.json | 10 + .../interfaceDetection/ERC165/index.mdx | 29 + .../interfaceDetection/_category_.json | 10 + .../docs/library/interfaceDetection/index.mdx | 22 + .../library/token/ERC1155/ERC1155Facet.mdx | 684 +++++++++++++++++ .../docs/library/token/ERC1155/ERC1155Mod.mdx | 634 +++++++++++++++ .../library/token/ERC1155/_category_.json | 10 + website/docs/library/token/ERC1155/index.mdx | 29 + .../token/ERC20/ERC20/ERC20BurnFacet.mdx | 267 +++++++ .../library/token/ERC20/ERC20/ERC20Facet.mdx | 564 ++++++++++++++ .../library/token/ERC20/ERC20/ERC20Mod.mdx | 452 +++++++++++ .../library/token/ERC20/ERC20/_category_.json | 10 + .../docs/library/token/ERC20/ERC20/index.mdx | 36 + .../ERC20Bridgeable/ERC20BridgeableFacet.mdx | 419 ++++++++++ .../ERC20Bridgeable/ERC20BridgeableMod.mdx | 465 +++++++++++ .../ERC20/ERC20Bridgeable/_category_.json | 10 + .../token/ERC20/ERC20Bridgeable/index.mdx | 29 + .../ERC20/ERC20Permit/ERC20PermitFacet.mdx | 340 +++++++++ .../ERC20/ERC20Permit/ERC20PermitMod.mdx | 294 +++++++ .../token/ERC20/ERC20Permit/_category_.json | 10 + .../library/token/ERC20/ERC20Permit/index.mdx | 29 + .../docs/library/token/ERC20/_category_.json | 10 + website/docs/library/token/ERC20/index.mdx | 36 + .../token/ERC6909/ERC6909/ERC6909Facet.mdx | 537 +++++++++++++ .../token/ERC6909/ERC6909/ERC6909Mod.mdx | 563 ++++++++++++++ .../token/ERC6909/ERC6909/_category_.json | 10 + .../library/token/ERC6909/ERC6909/index.mdx | 29 + .../library/token/ERC6909/_category_.json | 10 + website/docs/library/token/ERC6909/index.mdx | 22 + .../token/ERC721/ERC721/ERC721BurnFacet.mdx | 224 ++++++ .../token/ERC721/ERC721/ERC721Facet.mdx | 646 ++++++++++++++++ .../library/token/ERC721/ERC721/ERC721Mod.mdx | 391 ++++++++++ .../token/ERC721/ERC721/_category_.json | 10 + .../library/token/ERC721/ERC721/index.mdx | 36 + .../ERC721EnumerableBurnFacet.mdx | 197 +++++ .../ERC721EnumerableFacet.mdx | 719 ++++++++++++++++++ .../ERC721Enumerable/ERC721EnumerableMod.mdx | 392 ++++++++++ .../ERC721/ERC721Enumerable/_category_.json | 10 + .../token/ERC721/ERC721Enumerable/index.mdx | 36 + .../docs/library/token/ERC721/_category_.json | 10 + website/docs/library/token/ERC721/index.mdx | 29 + .../library/token/Royalty/RoyaltyFacet.mdx | 207 +++++ .../docs/library/token/Royalty/RoyaltyMod.mdx | 381 ++++++++++ .../library/token/Royalty/_category_.json | 10 + website/docs/library/token/Royalty/index.mdx | 29 + website/docs/library/token/_category_.json | 10 + website/docs/library/token/index.mdx | 50 ++ .../docs/library/utils/NonReentrancyMod.mdx | 154 ++++ website/docs/library/utils/_category_.json | 10 + website/docs/library/utils/index.mdx | 22 + 86 files changed, 15593 insertions(+) create mode 100644 website/docs/library/_category_.json create mode 100644 website/docs/library/access/AccessControl/AccessControlFacet.mdx create mode 100644 website/docs/library/access/AccessControl/AccessControlMod.mdx create mode 100644 website/docs/library/access/AccessControl/_category_.json create mode 100644 website/docs/library/access/AccessControl/index.mdx create mode 100644 website/docs/library/access/AccessControlPausable/AccessControlPausableFacet.mdx create mode 100644 website/docs/library/access/AccessControlPausable/AccessControlPausableMod.mdx create mode 100644 website/docs/library/access/AccessControlPausable/_category_.json create mode 100644 website/docs/library/access/AccessControlPausable/index.mdx create mode 100644 website/docs/library/access/AccessControlTemporal/AccessControlTemporalFacet.mdx create mode 100644 website/docs/library/access/AccessControlTemporal/AccessControlTemporalMod.mdx create mode 100644 website/docs/library/access/AccessControlTemporal/_category_.json create mode 100644 website/docs/library/access/AccessControlTemporal/index.mdx create mode 100644 website/docs/library/access/Owner/OwnerFacet.mdx create mode 100644 website/docs/library/access/Owner/OwnerMod.mdx create mode 100644 website/docs/library/access/Owner/_category_.json create mode 100644 website/docs/library/access/Owner/index.mdx create mode 100644 website/docs/library/access/OwnerTwoSteps/OwnerTwoStepsFacet.mdx create mode 100644 website/docs/library/access/OwnerTwoSteps/OwnerTwoStepsMod.mdx create mode 100644 website/docs/library/access/OwnerTwoSteps/_category_.json create mode 100644 website/docs/library/access/OwnerTwoSteps/index.mdx create mode 100644 website/docs/library/access/_category_.json create mode 100644 website/docs/library/access/index.mdx create mode 100644 website/docs/library/diamond/DiamondInspectFacet.mdx create mode 100644 website/docs/library/diamond/DiamondLoupeFacet.mdx create mode 100644 website/docs/library/diamond/DiamondMod.mdx create mode 100644 website/docs/library/diamond/DiamondUpgradeFacet.mdx create mode 100644 website/docs/library/diamond/DiamondUpgradeMod.mdx create mode 100644 website/docs/library/diamond/_category_.json create mode 100644 website/docs/library/diamond/example/ExampleDiamond.mdx create mode 100644 website/docs/library/diamond/example/_category_.json create mode 100644 website/docs/library/diamond/example/index.mdx create mode 100644 website/docs/library/diamond/index.mdx create mode 100644 website/docs/library/index.mdx create mode 100644 website/docs/library/interfaceDetection/ERC165/ERC165Facet.mdx create mode 100644 website/docs/library/interfaceDetection/ERC165/ERC165Mod.mdx create mode 100644 website/docs/library/interfaceDetection/ERC165/_category_.json create mode 100644 website/docs/library/interfaceDetection/ERC165/index.mdx create mode 100644 website/docs/library/interfaceDetection/_category_.json create mode 100644 website/docs/library/interfaceDetection/index.mdx create mode 100644 website/docs/library/token/ERC1155/ERC1155Facet.mdx create mode 100644 website/docs/library/token/ERC1155/ERC1155Mod.mdx create mode 100644 website/docs/library/token/ERC1155/_category_.json create mode 100644 website/docs/library/token/ERC1155/index.mdx create mode 100644 website/docs/library/token/ERC20/ERC20/ERC20BurnFacet.mdx create mode 100644 website/docs/library/token/ERC20/ERC20/ERC20Facet.mdx create mode 100644 website/docs/library/token/ERC20/ERC20/ERC20Mod.mdx create mode 100644 website/docs/library/token/ERC20/ERC20/_category_.json create mode 100644 website/docs/library/token/ERC20/ERC20/index.mdx create mode 100644 website/docs/library/token/ERC20/ERC20Bridgeable/ERC20BridgeableFacet.mdx create mode 100644 website/docs/library/token/ERC20/ERC20Bridgeable/ERC20BridgeableMod.mdx create mode 100644 website/docs/library/token/ERC20/ERC20Bridgeable/_category_.json create mode 100644 website/docs/library/token/ERC20/ERC20Bridgeable/index.mdx create mode 100644 website/docs/library/token/ERC20/ERC20Permit/ERC20PermitFacet.mdx create mode 100644 website/docs/library/token/ERC20/ERC20Permit/ERC20PermitMod.mdx create mode 100644 website/docs/library/token/ERC20/ERC20Permit/_category_.json create mode 100644 website/docs/library/token/ERC20/ERC20Permit/index.mdx create mode 100644 website/docs/library/token/ERC20/_category_.json create mode 100644 website/docs/library/token/ERC20/index.mdx create mode 100644 website/docs/library/token/ERC6909/ERC6909/ERC6909Facet.mdx create mode 100644 website/docs/library/token/ERC6909/ERC6909/ERC6909Mod.mdx create mode 100644 website/docs/library/token/ERC6909/ERC6909/_category_.json create mode 100644 website/docs/library/token/ERC6909/ERC6909/index.mdx create mode 100644 website/docs/library/token/ERC6909/_category_.json create mode 100644 website/docs/library/token/ERC6909/index.mdx create mode 100644 website/docs/library/token/ERC721/ERC721/ERC721BurnFacet.mdx create mode 100644 website/docs/library/token/ERC721/ERC721/ERC721Facet.mdx create mode 100644 website/docs/library/token/ERC721/ERC721/ERC721Mod.mdx create mode 100644 website/docs/library/token/ERC721/ERC721/_category_.json create mode 100644 website/docs/library/token/ERC721/ERC721/index.mdx create mode 100644 website/docs/library/token/ERC721/ERC721Enumerable/ERC721EnumerableBurnFacet.mdx create mode 100644 website/docs/library/token/ERC721/ERC721Enumerable/ERC721EnumerableFacet.mdx create mode 100644 website/docs/library/token/ERC721/ERC721Enumerable/ERC721EnumerableMod.mdx create mode 100644 website/docs/library/token/ERC721/ERC721Enumerable/_category_.json create mode 100644 website/docs/library/token/ERC721/ERC721Enumerable/index.mdx create mode 100644 website/docs/library/token/ERC721/_category_.json create mode 100644 website/docs/library/token/ERC721/index.mdx create mode 100644 website/docs/library/token/Royalty/RoyaltyFacet.mdx create mode 100644 website/docs/library/token/Royalty/RoyaltyMod.mdx create mode 100644 website/docs/library/token/Royalty/_category_.json create mode 100644 website/docs/library/token/Royalty/index.mdx create mode 100644 website/docs/library/token/_category_.json create mode 100644 website/docs/library/token/index.mdx create mode 100644 website/docs/library/utils/NonReentrancyMod.mdx create mode 100644 website/docs/library/utils/_category_.json create mode 100644 website/docs/library/utils/index.mdx diff --git a/website/docs/library/_category_.json b/website/docs/library/_category_.json new file mode 100644 index 00000000..04125e1e --- /dev/null +++ b/website/docs/library/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Library", + "position": 4, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/index" + } +} diff --git a/website/docs/library/access/AccessControl/AccessControlFacet.mdx b/website/docs/library/access/AccessControl/AccessControlFacet.mdx new file mode 100644 index 00000000..da7f801d --- /dev/null +++ b/website/docs/library/access/AccessControl/AccessControlFacet.mdx @@ -0,0 +1,558 @@ +--- +sidebar_position: 2 +title: "AccessControlFacet" +description: "Manages roles and permissions within a diamond" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/access/AccessControl/AccessControlFacet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Manages roles and permissions within a diamond + + + +- Exposes standard ERC-173 access control functions. +- Integrates with diamond storage pattern for state management. +- Provides `requireRole` for inline permission checks. +- Supports batch granting and revoking of roles. + + +## Overview + +This facet implements role-based access control within a diamond. It provides functions to grant, revoke, and check roles for accounts, routing calls through the diamond proxy and utilizing diamond storage. Developers integrate this facet to enforce permissions on diamond functions. + +--- + +## Storage + +### AccessControlStorage + + +{`struct AccessControlStorage { + mapping(address account => mapping(bytes32 role => bool hasRole)) hasRole; + mapping(bytes32 role => bytes32 adminRole) adminRole; +}`} + + +### State Variables + + + +## Functions + +### hasRole + +Returns if an account has a role. + + +{`function hasRole(bytes32 _role, address _account) external view returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### requireRole + +Checks if an account has a required role. Reverts with AccessControlUnauthorizedAccount If the account does not have the role. + + +{`function requireRole(bytes32 _role, address _account) external view;`} + + +**Parameters:** + + + +--- +### getRoleAdmin + +Returns the admin role for a role. + + +{`function getRoleAdmin(bytes32 _role) external view returns (bytes32);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### setRoleAdmin + +Sets the admin role for a role. Emits a RoleAdminChanged event. Reverts with AccessControlUnauthorizedAccount If the caller is not the current admin of the role. + + +{`function setRoleAdmin(bytes32 _role, bytes32 _adminRole) external;`} + + +**Parameters:** + + + +--- +### grantRole + +Grants a role to an account. Emits a RoleGranted event. Reverts with AccessControlUnauthorizedAccount If the caller is not the admin of the role. + + +{`function grantRole(bytes32 _role, address _account) external;`} + + +**Parameters:** + + + +--- +### revokeRole + +Revokes a role from an account. Emits a RoleRevoked event. Reverts with AccessControlUnauthorizedAccount If the caller is not the admin of the role. + + +{`function revokeRole(bytes32 _role, address _account) external;`} + + +**Parameters:** + + + +--- +### grantRoleBatch + +Grants a role to multiple accounts in a single transaction. Emits a RoleGranted event for each newly granted account. Reverts with AccessControlUnauthorizedAccount If the caller is not the admin of the role. + + +{`function grantRoleBatch(bytes32 _role, address[] calldata _accounts) external;`} + + +**Parameters:** + + + +--- +### revokeRoleBatch + +Revokes a role from multiple accounts in a single transaction. Emits a RoleRevoked event for each account the role is revoked from. Reverts with AccessControlUnauthorizedAccount If the caller is not the admin of the role. + + +{`function revokeRoleBatch(bytes32 _role, address[] calldata _accounts) external;`} + + +**Parameters:** + + + +--- +### renounceRole + +Renounces a role from the caller. Emits a RoleRevoked event. Reverts with AccessControlUnauthorizedSender If the caller is not the account to renounce the role from. + + +{`function renounceRole(bytes32 _role, address _account) external;`} + + +**Parameters:** + + + +## Events + + + +
+ Emitted when the admin role for a role is changed. +
+ +
+ Signature: + +{`event RoleAdminChanged(bytes32 indexed _role, bytes32 indexed _previousAdminRole, bytes32 indexed _newAdminRole);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when a role is granted to an account. +
+ +
+ Signature: + +{`event RoleGranted(bytes32 indexed _role, address indexed _account, address indexed _sender);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when a role is revoked from an account. +
+ +
+ Signature: + +{`event RoleRevoked(bytes32 indexed _role, address indexed _account, address indexed _sender);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when the account does not have a specific role. +
+ +
+ Signature: + +error AccessControlUnauthorizedAccount(address _account, bytes32 _role); + +
+
+ +
+ Thrown when the sender is not the account to renounce the role from. +
+ +
+ Signature: + +error AccessControlUnauthorizedSender(address _sender, address _account); + +
+
+
+ + + + +## Best Practices + + +- Initialize role admin relationships during diamond deployment. +- Enforce role checks on sensitive functions using `requireRole`. +- Grant and revoke roles using the batch functions for gas efficiency when applicable. + + +## Security Considerations + + +All state-changing functions (`setRoleAdmin`, `grantRole`, `revokeRole`, `grantRoleBatch`, `revokeRoleBatch`, `renounceRole`) revert if the caller does not possess the required admin role for the target role. `renounceRole` reverts if the caller is not the account specified. Follow standard Solidity security practices for input validation. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/access/AccessControl/AccessControlMod.mdx b/website/docs/library/access/AccessControl/AccessControlMod.mdx new file mode 100644 index 00000000..4f8ac474 --- /dev/null +++ b/website/docs/library/access/AccessControl/AccessControlMod.mdx @@ -0,0 +1,483 @@ +--- +sidebar_position: 1 +title: "AccessControlMod" +description: "Role-based access control for diamonds" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/access/AccessControl/AccessControlMod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Role-based access control for diamonds + + + +- Exposes `internal` functions for role management. +- Utilizes the diamond storage pattern for shared state. +- No external dependencies, promoting composability. +- Emits events for `RoleGranted`, `RoleRevoked`, and `RoleAdminChanged`. + + + +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 role-based access control within a diamond. Facets can import this module to enforce permissions and manage roles using shared diamond storage. Changes to roles are immediately visible to all facets interacting with the same storage. + +--- + +## Storage + +### AccessControlStorage + + +{`struct AccessControlStorage { + mapping(address account => mapping(bytes32 role => bool hasRole)) hasRole; + mapping(bytes32 role => bytes32 adminRole) adminRole; +}`} + + +### State Variables + + + +## Functions + +### getStorage + +Returns the storage for the AccessControl. + + +{`function getStorage() pure returns (AccessControlStorage storage _s);`} + + +**Returns:** + + + +--- +### grantRole + +function to grant a role to an account. + + +{`function grantRole(bytes32 _role, address _account) returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### hasRole + +function to check if an account has a role. + + +{`function hasRole(bytes32 _role, address _account) view returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### requireRole + +function to check if an account has a required role. Reverts with AccessControlUnauthorizedAccount If the account does not have the role. + + +{`function requireRole(bytes32 _role, address _account) view;`} + + +**Parameters:** + + + +--- +### revokeRole + +function to revoke a role from an account. + + +{`function revokeRole(bytes32 _role, address _account) returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### setRoleAdmin + +function to set the admin role for a role. + + +{`function setRoleAdmin(bytes32 _role, bytes32 _adminRole) ;`} + + +**Parameters:** + + + +## Events + + + +
+ Emitted when the admin role for a role is changed. +
+ +
+ Signature: + +{`event RoleAdminChanged(bytes32 indexed _role, bytes32 indexed _previousAdminRole, bytes32 indexed _newAdminRole);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when a role is granted to an account. +
+ +
+ Signature: + +{`event RoleGranted(bytes32 indexed _role, address indexed _account, address indexed _sender);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when a role is revoked from an account. +
+ +
+ Signature: + +{`event RoleRevoked(bytes32 indexed _role, address indexed _account, address indexed _sender);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when the account does not have a specific role. +
+ +
+ Signature: + +error AccessControlUnauthorizedAccount(address _account, bytes32 _role); + +
+
+
+ + + + +## Best Practices + + +- Use `requireRole` within facets to enforce access control before executing sensitive operations. +- Ensure `AccessControlStorage` is correctly initialized and accessible via the diamond storage pattern. +- When revoking roles, verify the caller has the necessary permissions to perform the action. + + +## Integration Notes + + +This module manages access control state within diamond storage at the position identified by `keccak256("compose.accesscontrol")`. All functions interact directly with the `AccessControlStorage` struct. Changes made via `grantRole`, `revokeRole`, or `setRoleAdmin` are immediately reflected for all facets that access this storage position. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/access/AccessControl/_category_.json b/website/docs/library/access/AccessControl/_category_.json new file mode 100644 index 00000000..1504700a --- /dev/null +++ b/website/docs/library/access/AccessControl/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Access Control", + "position": 3, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/access/AccessControl/index" + } +} diff --git a/website/docs/library/access/AccessControl/index.mdx b/website/docs/library/access/AccessControl/index.mdx new file mode 100644 index 00000000..6e9bf11e --- /dev/null +++ b/website/docs/library/access/AccessControl/index.mdx @@ -0,0 +1,29 @@ +--- +title: "Access Control" +description: "Role-based access control (RBAC) pattern." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + Role-based access control (RBAC) pattern. + + + + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/access/AccessControlPausable/AccessControlPausableFacet.mdx b/website/docs/library/access/AccessControlPausable/AccessControlPausableFacet.mdx new file mode 100644 index 00000000..f8192a80 --- /dev/null +++ b/website/docs/library/access/AccessControlPausable/AccessControlPausableFacet.mdx @@ -0,0 +1,351 @@ +--- +sidebar_position: 2 +title: "AccessControlPausableFacet" +description: "Manages role-based pausing and access control" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/access/AccessControlPausable/AccessControlPausableFacet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Manages role-based pausing and access control + + + +- Enables temporary pausing of specific roles. +- Provides external functions for role management within a diamond. +- Integrates with the diamond storage pattern for state management. +- Implements specific error types for unauthorized access and paused roles. + + +## Overview + +This facet implements role-based pausing and access control within a diamond. It allows specific roles to be temporarily disabled and enforces access checks through the diamond proxy. Developers integrate this facet to manage operational states and permissions for different roles. + +--- + +## Storage + +### AccessControlStorage + + +{`struct AccessControlStorage { + mapping(address account => mapping(bytes32 role => bool hasRole)) hasRole; + mapping(bytes32 role => bytes32 adminRole) adminRole; +}`} + + +--- +### AccessControlPausableStorage + + +{`struct AccessControlPausableStorage { + mapping(bytes32 role => bool paused) pausedRoles; +}`} + + +### State Variables + + + +## Functions + +### isRolePaused + +Returns if a role is paused. + + +{`function isRolePaused(bytes32 _role) external view returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### pauseRole + +Temporarily disables a role, preventing all accounts from using it. Only the admin of the role can pause it. Emits a RolePaused event. Reverts with AccessControlUnauthorizedAccount If the caller is not the admin of the role. + + +{`function pauseRole(bytes32 _role) external;`} + + +**Parameters:** + + + +--- +### unpauseRole + +Re-enables a role that was previously paused. Only the admin of the role can unpause it. Emits a RoleUnpaused event. Reverts with AccessControlUnauthorizedAccount If the caller is not the admin of the role. + + +{`function unpauseRole(bytes32 _role) external;`} + + +**Parameters:** + + + +--- +### requireRoleNotPaused + +Checks if an account has a role and if the role is not paused. - Reverts with AccessControlUnauthorizedAccount If the account does not have the role. - Reverts with AccessControlRolePaused If the role is paused. + + +{`function requireRoleNotPaused(bytes32 _role, address _account) external view;`} + + +**Parameters:** + + + +## Events + + + +
+ Event emitted when a role is paused. +
+ +
+ Signature: + +{`event RolePaused(bytes32 indexed _role, address indexed _account);`} + +
+ +
+ Parameters: + +
+
+ +
+ Event emitted when a role is unpaused. +
+ +
+ Signature: + +{`event RoleUnpaused(bytes32 indexed _role, address indexed _account);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when the account does not have a specific role. +
+ +
+ Signature: + +error AccessControlUnauthorizedAccount(address _account, bytes32 _role); + +
+
+ +
+ Thrown when a role is paused and an operation requiring that role is attempted. +
+ +
+ Signature: + +error AccessControlRolePaused(bytes32 _role); + +
+
+
+ + + + +## Best Practices + + +- Initialize role administration and pausing capabilities during diamond deployment. +- Enforce role pausing and access control checks on sensitive functions via `requireRoleNotPaused`. +- Ensure the `AccessControlPausableMod` module is correctly configured for role management. + + +## Security Considerations + + +The `pauseRole` and `unpauseRole` functions are restricted to the admin of the role, preventing unauthorized pausing or unpausing. The `requireRoleNotPaused` function reverts with `AccessControlUnauthorizedAccount` if the caller lacks the role or `AccessControlRolePaused` if the role is paused. Input validation is handled by the underlying access control mechanisms and the explicit checks within the functions. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/access/AccessControlPausable/AccessControlPausableMod.mdx b/website/docs/library/access/AccessControlPausable/AccessControlPausableMod.mdx new file mode 100644 index 00000000..2fec7bc9 --- /dev/null +++ b/website/docs/library/access/AccessControlPausable/AccessControlPausableMod.mdx @@ -0,0 +1,352 @@ +--- +sidebar_position: 1 +title: "AccessControlPausableMod" +description: "Access Control Pausable module for Compose diamonds" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/access/AccessControlPausable/AccessControlPausableMod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Access Control Pausable module for Compose diamonds + + + +- All functions are `internal` for use in custom facets +- Follows diamond storage pattern (EIP-8042) +- Compatible with ERC-2535 diamonds +- No external dependencies or `using` directives + + + +This module provides internal functions for use in your custom facets. Import it to access shared logic and storage. + + +## Overview + +Access Control Pausable module for Compose diamonds + +--- + +## Storage + +### AccessControlPausableStorage + + +{`struct AccessControlPausableStorage { + mapping(bytes32 role => bool paused) pausedRoles; +}`} + + +--- +### AccessControlStorage + + +{`struct AccessControlStorage { + mapping(address account => mapping(bytes32 role => bool hasRole)) hasRole; + mapping(bytes32 role => bytes32 adminRole) adminRole; +}`} + + +### State Variables + + + +## Functions + +### getAccessControlStorage + +Returns the storage for AccessControl. + + +{`function getAccessControlStorage() pure returns (AccessControlStorage storage s);`} + + +**Returns:** + + + +--- +### getStorage + +Returns the storage for AccessControlPausable. + + +{`function getStorage() pure returns (AccessControlPausableStorage storage s);`} + + +**Returns:** + + + +--- +### isRolePaused + +function to check if a role is paused. + + +{`function isRolePaused(bytes32 _role) view returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### pauseRole + +function to pause a role. + + +{`function pauseRole(bytes32 _role) ;`} + + +**Parameters:** + + + +--- +### requireRoleNotPaused + +function to check if an account has a role and if the role is not paused. **Notes:** - Reverts with AccessControlUnauthorizedAccount If the account does not have the role. - Reverts with AccessControlRolePaused If the role is paused. + + +{`function requireRoleNotPaused(bytes32 _role, address _account) view;`} + + +**Parameters:** + + + +--- +### unpauseRole + +function to unpause a role. + + +{`function unpauseRole(bytes32 _role) ;`} + + +**Parameters:** + + + +## Events + + + +
+ Event emitted when a role is paused. +
+ +
+ Signature: + +{`event RolePaused(bytes32 indexed _role, address indexed _account);`} + +
+ +
+ Parameters: + +
+
+ +
+ Event emitted when a role is unpaused. +
+ +
+ Signature: + +{`event RoleUnpaused(bytes32 indexed _role, address indexed _account);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when a role is paused and an operation requiring that role is attempted. +
+ +
+ Signature: + +error AccessControlRolePaused(bytes32 _role); + +
+
+ +
+ Thrown when the account does not have a specific role. +
+ +
+ Signature: + +error AccessControlUnauthorizedAccount(address _account, bytes32 _role); + +
+
+
+ +## Integration Notes + + +This module accesses shared diamond storage, so changes made through this module are immediately visible to facets using the same storage pattern. All functions are internal as per Compose conventions. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/access/AccessControlPausable/_category_.json b/website/docs/library/access/AccessControlPausable/_category_.json new file mode 100644 index 00000000..96418b00 --- /dev/null +++ b/website/docs/library/access/AccessControlPausable/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Pausable Access Control", + "position": 4, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/access/AccessControlPausable/index" + } +} diff --git a/website/docs/library/access/AccessControlPausable/index.mdx b/website/docs/library/access/AccessControlPausable/index.mdx new file mode 100644 index 00000000..55bdc77d --- /dev/null +++ b/website/docs/library/access/AccessControlPausable/index.mdx @@ -0,0 +1,29 @@ +--- +title: "Pausable Access Control" +description: "RBAC with pause functionality." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + RBAC with pause functionality. + + + + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/access/AccessControlTemporal/AccessControlTemporalFacet.mdx b/website/docs/library/access/AccessControlTemporal/AccessControlTemporalFacet.mdx new file mode 100644 index 00000000..21c094e9 --- /dev/null +++ b/website/docs/library/access/AccessControlTemporal/AccessControlTemporalFacet.mdx @@ -0,0 +1,431 @@ +--- +sidebar_position: 2 +title: "AccessControlTemporalFacet" +description: "Grants and revokes roles with expiry timestamps" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/access/AccessControlTemporal/AccessControlTemporalFacet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Grants and revokes roles with expiry timestamps + + + +- Manages time-bound role assignments. +- Integrates with the diamond storage pattern. +- Exposes functions for granting, revoking, and checking role expiry. +- Emits events for role granting and revocation. + + +## Overview + +This facet implements temporal role-based access control within a diamond. It exposes functions to grant roles with specific expiry dates and to revoke them. Calls are routed through the diamond proxy, enabling dynamic access management. Developers add this facet to manage time-bound permissions for accounts. + +--- + +## Storage + +### AccessControlStorage + + +{`struct AccessControlStorage { + mapping(address account => mapping(bytes32 role => bool hasRole)) hasRole; + mapping(bytes32 role => bytes32 adminRole) adminRole; +}`} + + +--- +### AccessControlTemporalStorage + + +{`struct AccessControlTemporalStorage { + mapping(address account => mapping(bytes32 role => uint256 expiryTimestamp)) roleExpiry; +}`} + + +### State Variables + + + +## Functions + +### getRoleExpiry + +Returns the expiry timestamp for a role assignment. + + +{`function getRoleExpiry(bytes32 _role, address _account) external view returns (uint256);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### isRoleExpired + +Checks if a role assignment has expired. + + +{`function isRoleExpired(bytes32 _role, address _account) external view returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### grantRoleWithExpiry + +Grants a role to an account with an expiry timestamp. Only the admin of the role can grant it with expiry. Emits a RoleGrantedWithExpiry event. Reverts with AccessControlUnauthorizedAccount If the caller is not the admin of the role. + + +{`function grantRoleWithExpiry(bytes32 _role, address _account, uint256 _expiresAt) external;`} + + +**Parameters:** + + + +--- +### revokeTemporalRole + +Revokes a temporal role from an account. Only the admin of the role can revoke it. Emits a TemporalRoleRevoked event. Reverts with AccessControlUnauthorizedAccount If the caller is not the admin of the role. + + +{`function revokeTemporalRole(bytes32 _role, address _account) external;`} + + +**Parameters:** + + + +--- +### requireValidRole + +Checks if an account has a valid (non-expired) role. - Reverts with AccessControlUnauthorizedAccount If the account does not have the role. - Reverts with AccessControlRoleExpired If the role has expired. + + +{`function requireValidRole(bytes32 _role, address _account) external view;`} + + +**Parameters:** + + + +## Events + + + +
+ Event emitted when a role is granted with an expiry timestamp. +
+ +
+ Signature: + +{`event RoleGrantedWithExpiry( + bytes32 indexed _role, address indexed _account, uint256 _expiresAt, address indexed _sender +);`} + +
+ +
+ Parameters: + +
+
+ +
+ Event emitted when a temporal role is revoked. +
+ +
+ Signature: + +{`event TemporalRoleRevoked(bytes32 indexed _role, address indexed _account, address indexed _sender);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when the account does not have a specific role. +
+ +
+ Signature: + +error AccessControlUnauthorizedAccount(address _account, bytes32 _role); + +
+
+ +
+ Thrown when a role has expired. +
+ +
+ Signature: + +error AccessControlRoleExpired(bytes32 _role, address _account); + +
+
+
+ + + + +## Best Practices + + +- Grant roles with expiry during diamond initialization or via authorized functions. +- Revoke temporal roles when they are no longer needed before their expiry. +- Ensure the caller has the necessary administrative privileges to grant or revoke roles. + + +## Security Considerations + + +All functions that modify role assignments (`grantRoleWithExpiry`, `revokeTemporalRole`) require the caller to be the administrator of the role, enforced by the `AccessControlUnauthorizedAccount` error. The `requireValidRole` function checks for both role existence and expiry, reverting with `AccessControlRoleExpired` if a role has passed its expiry timestamp. Follow standard Solidity security practices for input validation. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/access/AccessControlTemporal/AccessControlTemporalMod.mdx b/website/docs/library/access/AccessControlTemporal/AccessControlTemporalMod.mdx new file mode 100644 index 00000000..e7009754 --- /dev/null +++ b/website/docs/library/access/AccessControlTemporal/AccessControlTemporalMod.mdx @@ -0,0 +1,508 @@ +--- +sidebar_position: 1 +title: "AccessControlTemporalMod" +description: "Manage time-bound role assignments within a diamond" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/access/AccessControlTemporal/AccessControlTemporalMod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Manage time-bound role assignments within a diamond + + + +- Manages time-bound role assignments using diamond storage. +- Provides `grantRoleWithExpiry`, `isRoleExpired`, and `requireValidRole` functions. +- All functions are `internal` and designed for facet composition. +- Compatible with the diamond storage pattern (EIP-8042). + + + +This module provides internal functions for use in your custom facets. Import it to access shared logic and storage. + + +## Overview + +This module provides functions to grant roles with expiry timestamps and check their validity. Facets can integrate this module to implement time-limited permissions using shared diamond storage. Changes to role expiry are immediately visible to all facets interacting with the same storage. + +--- + +## Storage + +### AccessControlStorage + + +{`struct AccessControlStorage { + mapping(address account => mapping(bytes32 role => bool hasRole)) hasRole; + mapping(bytes32 role => bytes32 adminRole) adminRole; +}`} + + +--- +### AccessControlTemporalStorage + + +{`struct AccessControlTemporalStorage { + mapping(address account => mapping(bytes32 role => uint256 expiryTimestamp)) roleExpiry; +}`} + + +### State Variables + + + +## Functions + +### getAccessControlStorage + +Returns the storage for AccessControl. + + +{`function getAccessControlStorage() pure returns (AccessControlStorage storage s);`} + + +**Returns:** + + + +--- +### getRoleExpiry + +function to get the expiry timestamp for a role assignment. + + +{`function getRoleExpiry(bytes32 _role, address _account) view returns (uint256);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### getStorage + +Returns the storage for AccessControlTemporal. + + +{`function getStorage() pure returns (AccessControlTemporalStorage storage s);`} + + +**Returns:** + + + +--- +### grantRoleWithExpiry + +function to grant a role with an expiry timestamp. + + +{`function grantRoleWithExpiry(bytes32 _role, address _account, uint256 _expiresAt) returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### isRoleExpired + +function to check if a role assignment has expired. + + +{`function isRoleExpired(bytes32 _role, address _account) view returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### requireValidRole + +function to check if an account has a valid (non-expired) role. **Notes:** - Reverts with AccessControlUnauthorizedAccount If the account does not have the role. - Reverts with AccessControlRoleExpired If the role has expired. + + +{`function requireValidRole(bytes32 _role, address _account) view;`} + + +**Parameters:** + + + +--- +### revokeTemporalRole + +function to revoke a temporal role. + + +{`function revokeTemporalRole(bytes32 _role, address _account) returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +## Events + + + +
+ Event emitted when a role is granted with an expiry timestamp. +
+ +
+ Signature: + +{`event RoleGrantedWithExpiry( +bytes32 indexed _role, address indexed _account, uint256 _expiresAt, address indexed _sender +);`} + +
+ +
+ Parameters: + +
+
+ +
+ Event emitted when a temporal role is revoked. +
+ +
+ Signature: + +{`event TemporalRoleRevoked(bytes32 indexed _role, address indexed _account, address indexed _sender);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when a role has expired. +
+ +
+ Signature: + +error AccessControlRoleExpired(bytes32 _role, address _account); + +
+
+ +
+ Thrown when the account does not have a specific role. +
+ +
+ Signature: + +error AccessControlUnauthorizedAccount(address _account, bytes32 _role); + +
+
+
+ + + + +## Best Practices + + +- Call `requireValidRole` before executing sensitive operations to enforce time-bound access. +- Use `grantRoleWithExpiry` to set clear expiration times for temporary permissions. +- Handle `AccessControlRoleExpired` and `AccessControlUnauthorizedAccount` errors returned by `requireValidRole`. + + +## Integration Notes + + +This module utilizes diamond storage at the `ACCESS_CONTROL_STORAGE_POSITION` (keccak256("compose.accesscontrol")) to manage temporal role assignments. The `AccessControlTemporalStorage` struct is stored here. Functions within this module directly read from and write to this shared storage, making changes immediately visible to all facets that access the same storage position. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/access/AccessControlTemporal/_category_.json b/website/docs/library/access/AccessControlTemporal/_category_.json new file mode 100644 index 00000000..834b0b18 --- /dev/null +++ b/website/docs/library/access/AccessControlTemporal/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Temporal Access Control", + "position": 5, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/access/AccessControlTemporal/index" + } +} diff --git a/website/docs/library/access/AccessControlTemporal/index.mdx b/website/docs/library/access/AccessControlTemporal/index.mdx new file mode 100644 index 00000000..933fa160 --- /dev/null +++ b/website/docs/library/access/AccessControlTemporal/index.mdx @@ -0,0 +1,29 @@ +--- +title: "Temporal Access Control" +description: "Time-limited role-based access control." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + Time-limited role-based access control. + + + + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/access/Owner/OwnerFacet.mdx b/website/docs/library/access/Owner/OwnerFacet.mdx new file mode 100644 index 00000000..959cd330 --- /dev/null +++ b/website/docs/library/access/Owner/OwnerFacet.mdx @@ -0,0 +1,213 @@ +--- +sidebar_position: 2 +title: "OwnerFacet" +description: "Manages contract ownership and transfers" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/access/Owner/OwnerFacet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Manages contract ownership and transfers + + + +- Provides external functions for ownership management. +- Uses diamond storage for owner state. +- Minimal dependencies, focusing solely on ownership. +- Compatible with ERC-2535 diamond standard. + + +## Overview + +This facet implements ownership management for a diamond. It exposes functions to view the current owner, transfer ownership, and renounce ownership. Developers integrate this facet to establish a clear owner for administrative actions within the diamond. + +--- + +## Storage + +### OwnerStorage + + +{`struct OwnerStorage { + address owner; +}`} + + +### State Variables + + + +## Functions + +### owner + +Get the address of the owner + + +{`function owner() external view returns (address);`} + + +**Returns:** + + + +--- +### transferOwnership + +Set the address of the new owner of the contract Set _newOwner to address(0) to renounce any ownership. + + +{`function transferOwnership(address _newOwner) external;`} + + +**Parameters:** + + + +--- +### renounceOwnership + + +{`function renounceOwnership() external;`} + + +## Events + + + + +
+ Signature: + +{`event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);`} + +
+ +
+
+ +## Errors + + + + +
+ Signature: + +error OwnerUnauthorizedAccount(); + +
+
+
+ + + + +## Best Practices + + +- Initialize the owner address during diamond deployment. +- Enforce that only the owner can call state-changing functions like `transferOwnership` and `renounceOwnership`. +- Use `transferOwnership` to safely delegate control to a new owner. + + +## Security Considerations + + +All state-changing functions (`transferOwnership`, `renounceOwnership`) are protected by access control, ensuring only the current owner can execute them. The `transferOwnership` function allows setting the new owner to address(0) to effectively renounce ownership, preventing future administrative actions. Input validation for `_newOwner` is handled internally. Follow standard Solidity security practices. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/access/Owner/OwnerMod.mdx b/website/docs/library/access/Owner/OwnerMod.mdx new file mode 100644 index 00000000..e4c647b0 --- /dev/null +++ b/website/docs/library/access/Owner/OwnerMod.mdx @@ -0,0 +1,284 @@ +--- +sidebar_position: 1 +title: "OwnerMod" +description: "Manage contract ownership using diamond storage" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/access/Owner/OwnerMod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Manage contract ownership using diamond storage + + + +- Provides internal functions for owner management. +- Utilizes diamond storage for shared ownership state. +- Enforces owner-only access control via `requireOwner()`. +- Compatible with ERC-2535 diamonds. + + + +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 contract ownership based on ERC-173. Facets can import this module to enforce owner-only access or transfer ownership using shared diamond storage. Changes to ownership are immediately reflected across all facets interacting with the same storage. + +--- + +## Storage + +### OwnerStorage + +storage-location: erc8042:compose.owner + + +{`struct OwnerStorage { + address owner; +}`} + + +### State Variables + + + +## Functions + +### getStorage + +Returns a pointer to the ERC-173 storage struct. Uses inline assembly to access the storage slot defined by STORAGE_POSITION. + + +{`function getStorage() pure returns (OwnerStorage storage s);`} + + +**Returns:** + + + +--- +### owner + +Get the address of the owner + + +{`function owner() view returns (address);`} + + +**Returns:** + + + +--- +### requireOwner + +Reverts if the caller is not the owner. + + +{`function requireOwner() view;`} + + +--- +### setContractOwner + + +{`function setContractOwner(address _initialOwner) ;`} + + +**Parameters:** + + + +--- +### transferOwnership + +Set the address of the new owner of the contract Set _newOwner to address(0) to renounce any ownership. + + +{`function transferOwnership(address _newOwner) ;`} + + +**Parameters:** + + + +## Events + + + +
+ This emits when ownership of a contract changes. +
+ +
+ Signature: + +{`event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);`} + +
+ +
+
+ +## Errors + + + + +
+ Signature: + +error OwnerAlreadyRenounced(); + +
+
+ + +
+ Signature: + +error OwnerUnauthorizedAccount(); + +
+
+
+ + + + +## Best Practices + + +- Call `requireOwner()` before executing sensitive operations. +- Use `transferOwnership()` to safely delegate contract control. +- Be aware that `transferOwnership(address(0))` renounces ownership. + + +## Integration Notes + + +This module manages ownership state within the diamond storage pattern at the slot identified by `STORAGE_POSITION` (`keccak256(\"compose.owner\")`). The `OwnerStorage` struct, containing the `owner` field, is accessed via inline assembly. All facets that import and utilize `OwnerMod` will interact with this shared storage, ensuring consistent ownership visibility across the diamond. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/access/Owner/_category_.json b/website/docs/library/access/Owner/_category_.json new file mode 100644 index 00000000..2ddf56c9 --- /dev/null +++ b/website/docs/library/access/Owner/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Owner", + "position": 1, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/access/Owner/index" + } +} diff --git a/website/docs/library/access/Owner/index.mdx b/website/docs/library/access/Owner/index.mdx new file mode 100644 index 00000000..05dc3c35 --- /dev/null +++ b/website/docs/library/access/Owner/index.mdx @@ -0,0 +1,29 @@ +--- +title: "Owner" +description: "Single-owner access control pattern." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + Single-owner access control pattern. + + + + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/access/OwnerTwoSteps/OwnerTwoStepsFacet.mdx b/website/docs/library/access/OwnerTwoSteps/OwnerTwoStepsFacet.mdx new file mode 100644 index 00000000..97e668b9 --- /dev/null +++ b/website/docs/library/access/OwnerTwoSteps/OwnerTwoStepsFacet.mdx @@ -0,0 +1,251 @@ +--- +sidebar_position: 2 +title: "OwnerTwoStepsFacet" +description: "Manages contract ownership and transfers" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/access/OwnerTwoSteps/OwnerTwoStepsFacet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Manages contract ownership and transfers + + + +- Manages ownership using a two-step transfer process. +- Exposes public view functions for current and pending owner status. +- Utilizes diamond storage for ownership state. +- Enforces access control via internal checks. + + +## Overview + +This facet implements ownership management for a diamond, enabling secure transfer of control. It exposes functions to view the current and pending owner, initiate ownership transfers, and accept them. Developers integrate this facet to provide a clear ownership hierarchy within their diamond. + +--- + +## Storage + +### OwnerStorage + + +{`struct OwnerStorage { + address owner; +}`} + + +--- +### PendingOwnerStorage + + +{`struct PendingOwnerStorage { + address pendingOwner; +}`} + + +### State Variables + + + +## Functions + +### owner + +Get the address of the owner + + +{`function owner() external view returns (address);`} + + +**Returns:** + + + +--- +### pendingOwner + +Get the address of the pending owner + + +{`function pendingOwner() external view returns (address);`} + + +**Returns:** + + + +--- +### transferOwnership + +Set the address of the new owner of the contract + + +{`function transferOwnership(address _newOwner) external;`} + + +**Parameters:** + + + +--- +### acceptOwnership + + +{`function acceptOwnership() external;`} + + +--- +### renounceOwnership + + +{`function renounceOwnership() external;`} + + +## Events + + + + +
+ Signature: + +{`event OwnershipTransferStarted(address indexed _previousOwner, address indexed _newOwner);`} + +
+ +
+ + +
+ Signature: + +{`event OwnershipTransferred(address indexed _previousOwner, address indexed _newOwner);`} + +
+ +
+
+ +## Errors + + + + +
+ Signature: + +error OwnerUnauthorizedAccount(); + +
+
+
+ + + + +## Best Practices + + +- Initialize the owner during diamond deployment. +- Use `transferOwnership` to propose a new owner. +- The new owner must call `acceptOwnership` to finalize the transfer. +- Use `renounceOwnership` only if the contract becomes obsolete or ownership is not required. + + +## Security Considerations + + +The `transferOwnership` function requires the caller to be the current owner. The `acceptOwnership` function requires the caller to be the pending owner. Direct calls to owner-modifying functions from unauthorized accounts will revert with `OwnerUnauthorizedAccount`. Follow standard Solidity security practices for input validation. + + +
+ +
+ + diff --git a/website/docs/library/access/OwnerTwoSteps/OwnerTwoStepsMod.mdx b/website/docs/library/access/OwnerTwoSteps/OwnerTwoStepsMod.mdx new file mode 100644 index 00000000..3621409e --- /dev/null +++ b/website/docs/library/access/OwnerTwoSteps/OwnerTwoStepsMod.mdx @@ -0,0 +1,330 @@ +--- +sidebar_position: 1 +title: "OwnerTwoStepsMod" +description: "Two-step ownership transfer for contract ownership" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/access/OwnerTwoSteps/OwnerTwoStepsMod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Two-step ownership transfer for contract ownership + + + +- Implements a secure two-step ownership transfer process. +- All management functions are `internal`, designed for use within facets. +- Leverages diamond storage for owner and pending owner state. +- Provides explicit checks for owner and pending owner roles. + + + +This module provides internal functions for use in your custom facets. Import it to access shared logic and storage. + + +## Overview + +This module provides a two-step ownership transfer mechanism, ensuring that contract ownership changes are deliberate and secure. Facets can integrate this module to manage ownership securely using shared diamond storage. The two-step process prevents accidental ownership loss or unauthorized takeovers. + +--- + +## Storage + +### OwnerStorage + +storage-location: erc8042:compose.owner + + +{`struct OwnerStorage { + address owner; +}`} + + +--- +### PendingOwnerStorage + +storage-location: erc8042:compose.owner.pending + + +{`struct PendingOwnerStorage { + address pendingOwner; +}`} + + +### State Variables + + + +## Functions + +### acceptOwnership + +Finalizes ownership transfer; must be called by the pending owner. + + +{`function acceptOwnership() ;`} + + +--- +### getOwnerStorage + +Returns a pointer to the Owner storage struct. Uses inline assembly to access the storage slot defined by OWNER_STORAGE_POSITION. + + +{`function getOwnerStorage() pure returns (OwnerStorage storage s);`} + + +**Returns:** + + + +--- +### getPendingOwnerStorage + +Returns a pointer to the PendingOwner storage struct. Uses inline assembly to access the storage slot defined by PENDING_OWNER_STORAGE_POSITION. + + +{`function getPendingOwnerStorage() pure returns (PendingOwnerStorage storage s);`} + + +**Returns:** + + + +--- +### owner + +Returns the current owner. + + +{`function owner() view returns (address);`} + + +--- +### pendingOwner + +Returns the pending owner (if any). + + +{`function pendingOwner() view returns (address);`} + + +--- +### renounceOwnership + +Renounce ownership of the contract Sets the owner to address(0), disabling all functions restricted to the owner. + + +{`function renounceOwnership() ;`} + + +--- +### requireOwner + +Reverts if the caller is not the owner. + + +{`function requireOwner() view;`} + + +--- +### transferOwnership + +Initiates a two-step ownership transfer. + + +{`function transferOwnership(address _newOwner) ;`} + + +**Parameters:** + + + +## Events + + + +
+ Emitted when ownership transfer is initiated (pending owner set). +
+ +
+ Signature: + +{`event OwnershipTransferStarted(address indexed _previousOwner, address indexed _newOwner);`} + +
+ +
+ +
+ Emitted when ownership transfer is finalized. +
+ +
+ Signature: + +{`event OwnershipTransferred(address indexed _previousOwner, address indexed _newOwner);`} + +
+ +
+
+ +## Errors + + + + +
+ Signature: + +error OwnerAlreadyRenounced(); + +
+
+ + +
+ Signature: + +error OwnerUnauthorizedAccount(); + +
+
+
+ + + + +## Best Practices + + +- Ensure `transferOwnership` is called by the current owner. +- Verify that `acceptOwnership` is called by the pending owner to finalize the transfer. +- Use `requireOwner` before executing critical state-changing functions that only the owner should perform. + + +## Integration Notes + + +This module manages owner and pending owner state within dedicated storage slots. `OWNER_STORAGE_POSITION` is used for the `OwnerStorage` struct, and `PENDING_OWNER_STORAGE_POSITION` for `PendingOwnerStorage`. These are accessed via inline assembly, ensuring compatibility with the diamond storage pattern (EIP-8042). Any facet interacting with these storage slots will see the updated owner and pending owner values immediately. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/access/OwnerTwoSteps/_category_.json b/website/docs/library/access/OwnerTwoSteps/_category_.json new file mode 100644 index 00000000..90b66a92 --- /dev/null +++ b/website/docs/library/access/OwnerTwoSteps/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Two-Step Owner", + "position": 2, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/access/OwnerTwoSteps/index" + } +} diff --git a/website/docs/library/access/OwnerTwoSteps/index.mdx b/website/docs/library/access/OwnerTwoSteps/index.mdx new file mode 100644 index 00000000..b47b46a7 --- /dev/null +++ b/website/docs/library/access/OwnerTwoSteps/index.mdx @@ -0,0 +1,29 @@ +--- +title: "Two-Step Owner" +description: "Two-step ownership transfer pattern." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + Two-step ownership transfer pattern. + + + + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/access/_category_.json b/website/docs/library/access/_category_.json new file mode 100644 index 00000000..cbc9d5ba --- /dev/null +++ b/website/docs/library/access/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Access Control", + "position": 2, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/access/index" + } +} diff --git a/website/docs/library/access/index.mdx b/website/docs/library/access/index.mdx new file mode 100644 index 00000000..1e83a09d --- /dev/null +++ b/website/docs/library/access/index.mdx @@ -0,0 +1,50 @@ +--- +title: "Access Control" +description: "Access control patterns for permission management in Compose diamonds." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + Access control patterns for permission management in Compose diamonds. + + + + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/diamond/DiamondInspectFacet.mdx b/website/docs/library/diamond/DiamondInspectFacet.mdx new file mode 100644 index 00000000..2f8e9cf6 --- /dev/null +++ b/website/docs/library/diamond/DiamondInspectFacet.mdx @@ -0,0 +1,185 @@ +--- +sidebar_position: 510 +title: "DiamondInspectFacet" +description: "Inspect diamond storage and facet mappings" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/diamond/DiamondInspectFacet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Inspect diamond storage and facet mappings + + + +- Provides read-only access to diamond's internal mappings. +- Exposes functions to retrieve facet addresses by selector. +- Returns all function selector to facet address pairs. +- Facilitates diamond introspection and debugging. + + +## Overview + +This facet provides read-only access to the diamond's internal state, including storage layout and facet mappings. It exposes functions to query the address of a facet handling a specific function selector and to retrieve all function-to-facet mappings. Developers use this facet to understand diamond composition and debug routing. + +--- + +## Storage + +### FacetAndPosition + + +{`struct FacetAndPosition { + address facet; + uint32 position; +}`} + + +--- +### DiamondStorage + + +{`struct DiamondStorage { + mapping(bytes4 functionSelector => FacetAndPosition) facetAndPosition; + /** + * Array of all function selectors that can be called in the diamond. + */ + bytes4[] selectors; +}`} + + +--- +### FunctionFacetPair + + +{`struct FunctionFacetPair { + bytes4 selector; + address facet; +}`} + + +### State Variables + + + +## Functions + +### facetAddress + +Gets the facet address that handles the given selector. If facet is not found return address(0). + + +{`function facetAddress(bytes4 _functionSelector) external view returns (address facet);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### functionFacetPairs + +Returns an array of all function selectors and their corresponding facet addresses. Iterates through the diamond's stored selectors and pairs each with its facet. + + +{`function functionFacetPairs() external view returns (FunctionFacetPair[] memory pairs);`} + + +**Returns:** + + + + + + +## Best Practices + + +- Use this facet for diagnostic and inspection purposes only. +- Do not rely on facet addresses returned by `facetAddress` for critical logic, as they can change during upgrades. +- Verify that the diamond has been properly initialized with this facet. + + +## Security Considerations + + +This facet is read-only and does not modify state. Standard Solidity security practices apply. Ensure the diamond is correctly configured to prevent unexpected behavior. + + +
+ +
+ + diff --git a/website/docs/library/diamond/DiamondLoupeFacet.mdx b/website/docs/library/diamond/DiamondLoupeFacet.mdx new file mode 100644 index 00000000..e9dfbf1e --- /dev/null +++ b/website/docs/library/diamond/DiamondLoupeFacet.mdx @@ -0,0 +1,243 @@ +--- +sidebar_position: 4 +title: "DiamondLoupeFacet" +description: "Inspect diamond facets and function selectors" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/diamond/DiamondLoupeFacet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Inspect diamond facets and function selectors + + + +- Exposes external view functions for diamond introspection. +- Uses optimized memory management for efficient querying. +- Self-contained with no external dependencies beyond the diamond storage. +- Compatible with ERC-2535 diamond standard. + + +## Overview + +This facet provides introspection capabilities for a diamond, allowing developers to query facet addresses and the function selectors they support. It routes calls through the diamond proxy, accessing shared storage to retrieve this metadata. Add this facet to enable developers to understand the diamond's functional composition. + +--- + +## Storage + +### FacetAndPosition + + +{`struct FacetAndPosition { + address facet; + uint32 position; +}`} + + +--- +### DiamondStorage + + +{`struct DiamondStorage { + mapping(bytes4 functionSelector => FacetAndPosition) facetAndPosition; + /** + * Array of all function selectors that can be called in the diamond. + */ + bytes4[] selectors; +}`} + + +--- +### Facet + + +{`struct Facet { + address facet; + bytes4[] functionSelectors; +}`} + + +### State Variables + + + +## Functions + +### facetFunctionSelectors + +Gets all the function selectors supported by a specific facet. Returns the set of selectors that this diamond currently routes to the given facet address. How it works: 1. Iterates through the diamond’s global selector list (s.selectors) — i.e., the selectors that have been added to this diamond. 2. For each selector, reads its facet address from diamond storage (s.facetAndPosition[selector].facet) and compares it to `_facet`. 3. When it matches, writes the selector into a preallocated memory array and increments a running count. 4. After the scan, updates the logical length of the result array with assembly to the exact number of matches. Why this approach: - Single-pass O(n) scan over all selectors keeps the logic simple and predictable. - Preallocating to the maximum possible size (total selector count) avoids repeated reallocations while building the result. - Trimming the array length at the end yields an exactly sized return value. + + +{`function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetSelectors);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### facetAddresses + +Get all the facet addresses used by a diamond. This function returns the unique set of facet addresses that provide functionality to the diamond. How it works:** 1. Uses a memory-based hash map to group facet addresses by the last byte of the address, reducing linear search costs from O(n²) to approximately O(n) for most cases. 2. Reuses the selectors array memory space to store the unique facet addresses, avoiding an extra memory allocation for the intermediate array. The selectors array is overwritten with facet addresses as we iterate. 3. For each selector, looks up its facet address and checks if we've seen this address before by searching the appropriate hash map bucket. 4. If the facet is new (not found in the bucket), expands the bucket by 4 slots if it's full or empty, then adds the facet to both the bucket and the return array. 5. If the facet was already seen, skips it to maintain uniqueness. 6. Finally, sets the correct length of the return array to match the number of unique facets found. Why this approach:** - Hash mapping by last address byte provides O(1) average-case bucket lookup instead of scanning all previously-found facets linearly for each selector. - Growing in fixed-size chunks (4 for buckets) keeps reallocations infrequent and prevents over-allocation, while keeping bucket sizes small for sparse key distributions. - Reusing the selectors array memory eliminates one memory allocation and reduces total memory usage, which saves gas. - This design is optimized for diamonds with many selectors across many facets, where the original O(n²) nested loop approach becomes prohibitively expensive. - The 256-bucket hash map trades a small fixed memory cost for dramatic algorithmic improvement in worst-case scenarios. + + +{`function facetAddresses() external view returns (address[] memory allFacets);`} + + +**Returns:** + + + +--- +### facets + +Gets all facets and their selectors. Returns each unique facet address currently used by the diamond and the list of function selectors that the diamond maps to that facet. How it works:** 1. Uses a memory-based hash map to group facets by the last byte of their address, reducing linear search costs from O(n²) to approximately O(n) for most cases. 2. Reuses the selectors array memory space to store pointers to Facet structs, avoiding an extra memory allocation for the intermediate array. 3. For each selector, looks up its facet address and checks if we've seen this facet before by searching the appropriate hash map bucket. 4. If the facet is new, expands the bucket by 4 slots if it's full or empty, creates a Facet struct with a 16-slot selector array, and stores a pointer to it in both the bucket and the facet pointers array. 5. If the facet exists, expands its selector array by 16 slots if full, then appends the selector to the array. 6. Finally, copies all Facet structs from their pointers into a properly-sized return array. Why this approach:** - Hash mapping by last address byte provides O(1) average-case bucket lookup instead of scanning all previously-found facets linearly. - Growing in fixed-size chunks (4 for buckets, 16 for selector arrays) keeps reallocations infrequent and prevents over-allocation. - Reusing the selectors array memory reduces total memory usage and allocation. - This design is optimized for diamonds with many facets and many selectors, where the original O(n²) nested loop approach becomes prohibitively expensive. + + +{`function facets() external view returns (Facet[] memory facetsAndSelectors);`} + + +**Returns:** + + + + + + +## Best Practices + + +- Ensure this facet is added to the diamond during initialization. +- Use the exposed functions to understand the diamond's current implementation and upgrade status. +- Avoid exposing sensitive internal storage details through custom implementations. + + +## Security Considerations + + +This facet is read-only and does not modify state, thus posing minimal direct security risks. However, ensure that the underlying diamond storage is not compromised, as this facet directly reads from it. Follow standard Solidity security practices for all custom extensions or modifications. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/diamond/DiamondMod.mdx b/website/docs/library/diamond/DiamondMod.mdx new file mode 100644 index 00000000..88493a67 --- /dev/null +++ b/website/docs/library/diamond/DiamondMod.mdx @@ -0,0 +1,271 @@ +--- +sidebar_position: 1 +title: "DiamondMod" +description: "Manages diamond facets and function routing" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/diamond/DiamondMod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Manages diamond facets and function routing + + + +- Internal functions for facet management and routing. +- Utilizes EIP-8042 diamond storage pattern. +- Supports dynamic function dispatch via `diamondFallback`. +- No external dependencies, promoting composability. + + + +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 diamond facets and routing function calls. Facets import this module to add themselves and their functions to the diamond's registry. The `diamondFallback` function enables dynamic dispatch to the correct facet based on function selectors, crucial for upgradeability and composition within the diamond storage pattern. + +--- + +## Storage + +### DiamondStorage + +storage-location: erc8042:erc8109.diamond + + +{`struct DiamondStorage { + mapping(bytes4 functionSelector => FacetAndPosition) facetAndPosition; + /** + * \`selectors\` contains all function selectors that can be called in the diamond. + */ + bytes4[] selectors; +}`} + + +--- +### FacetAndPosition + + +{`struct FacetAndPosition { + address facet; + uint32 position; +}`} + + +--- +### FacetFunctions + + +{`struct FacetFunctions { + address facet; + bytes4[] selectors; +}`} + + +### State Variables + + + +## Functions + +### addFacets + +Adds facets and their function selectors to the diamond. Only supports adding functions during diamond deployment. + + +{`function addFacets(FacetFunctions[] memory _facets) ;`} + + +**Parameters:** + + + +--- +### diamondFallback + +Find facet for function that is called and execute the function if a facet is found and return any value. + + +{`function diamondFallback() ;`} + + +--- +### getStorage + + +{`function getStorage() pure returns (DiamondStorage storage s);`} + + +## Events + + + +
+ Emitted when a function is added to a diamond. +
+ +
+ Signature: + +{`event DiamondFunctionAdded(bytes4 indexed _selector, address indexed _facet);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + + +
+ Signature: + +error CannotAddFunctionToDiamondThatAlreadyExists(bytes4 _selector); + +
+
+ + +
+ Signature: + +error FunctionNotFound(bytes4 _selector); + +
+
+ + +
+ Signature: + +error NoBytecodeAtAddress(address _contractAddress); + +
+
+
+ + + + +## Best Practices + + +- Ensure `addFacets` is called only during diamond initialization to prevent re-registration. +- Verify that function selectors do not conflict when adding new facets to prevent `CannotAddFunctionToDiamondThatAlreadyExists` errors. +- Handle potential `FunctionNotFound` errors when calling `diamondFallback` if the target function selector is not registered. + + +## Integration Notes + + +This module interacts with diamond storage using the `DIAMOND_STORAGE_POSITION` key. It manages the registration of facet addresses and their associated function selectors within the `DiamondStorage` struct. Changes made via `addFacets` are immediately reflected in the diamond's routing logic, enabling dynamic dispatch through `diamondFallback`. The `getStorage` function is a pure utility to retrieve the storage position. + + +
+ +
+ + diff --git a/website/docs/library/diamond/DiamondUpgradeFacet.mdx b/website/docs/library/diamond/DiamondUpgradeFacet.mdx new file mode 100644 index 00000000..b1178e28 --- /dev/null +++ b/website/docs/library/diamond/DiamondUpgradeFacet.mdx @@ -0,0 +1,511 @@ +--- +sidebar_position: 510 +title: "DiamondUpgradeFacet" +description: "Manages diamond upgrades and function registrations" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/diamond/DiamondUpgradeFacet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Manages diamond upgrades and function registrations + + + +- Manages diamond upgrades by adding, replacing, and removing functions. +- Supports delegate calls for executing arbitrary logic within the diamond context. +- Emits events for all significant upgrade operations. +- Integrates with Compose's storage pattern for owner management. + + +## Overview + +This facet provides core functionality for upgrading and managing facets within a Compose diamond. It allows for adding, replacing, and removing functions, as well as executing arbitrary delegate calls and setting diamond metadata. Developers use this facet to control the diamond's upgradeability and function registry. + +--- + +## Storage + +### OwnerStorage + + +{`struct OwnerStorage { + address owner; +}`} + + +--- +### FacetAndPosition + + +{`struct FacetAndPosition { + address facet; + uint32 position; +}`} + + +--- +### DiamondStorage + + +{`struct DiamondStorage { + mapping(bytes4 functionSelector => FacetAndPosition) facetAndPosition; + /** + * Array of all function selectors that can be called in the diamond + */ + bytes4[] selectors; +}`} + + +--- +### FacetFunctions + + +{`struct FacetFunctions { + address facet; + bytes4[] selectors; +}`} + + +### State Variables + + + +## Functions + +### upgradeDiamond + +--- +### Function Changes: + +--- +### DelegateCall: + +--- +### Metadata: + +If _tag is non-zero or if _metadata.length > 0 then the `DiamondMetadata` event is emitted. + + +{`function upgradeDiamond( + FacetFunctions[] calldata _addFunctions, + FacetFunctions[] calldata _replaceFunctions, + bytes4[] calldata _removeFunctions, + address _delegate, + bytes calldata _functionCall, + bytes32 _tag, + bytes calldata _metadata +) external;`} + + +**Parameters:** + + + +## Events + + + +
+ Emitted when a function is added to a diamond. +
+ +
+ Signature: + +{`event DiamondFunctionAdded(bytes4 indexed _selector, address indexed _facet);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when changing the facet that will handle calls to a function. +
+ +
+ Signature: + +{`event DiamondFunctionReplaced(bytes4 indexed _selector, address indexed _oldFacet, address indexed _newFacet);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when a function is removed from a diamond. +
+ +
+ Signature: + +{`event DiamondFunctionRemoved(bytes4 indexed _selector, address indexed _oldFacet);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when a diamond's constructor function or function from a facet makes a `delegatecall`. +
+ +
+ Signature: + +{`event DiamondDelegateCall(address indexed _delegate, bytes _functionCall);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted to record information about a diamond. This event records any arbitrary metadata. The format of `_tag` and `_data` are not specified by the standard. +
+ +
+ Signature: + +{`event DiamondMetadata(bytes32 indexed _tag, bytes _data);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + + +
+ Signature: + +error OwnerUnauthorizedAccount(); + +
+
+ + +
+ Signature: + +error NoSelectorsProvidedForFacet(address _facet); + +
+
+ + +
+ Signature: + +error NoBytecodeAtAddress(address _contractAddress); + +
+
+ + +
+ Signature: + +error CannotAddFunctionToDiamondThatAlreadyExists(bytes4 _selector); + +
+
+ + +
+ Signature: + +error CannotReplaceFunctionThatDoesNotExist(bytes4 _selector); + +
+
+ + +
+ Signature: + +error CannotRemoveFunctionThatDoesNotExist(bytes4 _selector); + +
+
+ + +
+ Signature: + +error CannotReplaceFunctionWithTheSameFacet(bytes4 _selector); + +
+
+ + +
+ Signature: + +error DelegateCallReverted(address _delegate, bytes _functionCall); + +
+
+ + +
+ Signature: + +error CannotReplaceImmutableFunction(bytes4 _selector); + +
+
+ + +
+ Signature: + +error CannotRemoveImmutableFunction(bytes4 _selector); + +
+
+
+ + + + +## Best Practices + + +- Ensure the caller has the necessary permissions to execute upgrade functions. +- Verify function selectors and facet addresses before calling upgrade functions. +- Use the `DiamondMetadata` event to track changes to diamond metadata. + + +## Security Considerations + + +All functions that modify the diamond's state (e.g., `upgradeDiamond`, `addFunctions`, `replaceFunctions`, `removeFunctions`, `setMetadata`) must be protected by appropriate access control mechanisms, typically managed by an owner role. The `delegateCall` function should be used with extreme caution due to the potential for reentrancy and state manipulation. Input validation on function selectors and facet addresses is critical. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/diamond/DiamondUpgradeMod.mdx b/website/docs/library/diamond/DiamondUpgradeMod.mdx new file mode 100644 index 00000000..ea2d05d7 --- /dev/null +++ b/website/docs/library/diamond/DiamondUpgradeMod.mdx @@ -0,0 +1,570 @@ +--- +sidebar_position: 500 +title: "DiamondUpgradeMod" +description: "Manage diamond facets and delegate calls" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/diamond/DiamondUpgradeMod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Manage diamond facets and delegate calls + + + +- Manages facet additions, replacements, and removals on a diamond. +- Supports delegate calls for state manipulation during upgrades. +- Emits detailed events for upgrade actions (add, replace, remove, delegate call, metadata). +- Includes specific errors to prevent invalid state transitions. + + + +This module provides internal functions for use in your custom facets. Import it to access shared logic and storage. + + +## Overview + +This module provides functions to add, replace, and remove facets on a diamond. It facilitates diamond upgrades by composing facets and managing their selectors. Internal delegate calls can also be executed for state modifications or initialization during upgrades. Changes made through this module are applied directly to the diamond's facet registry, impacting all facets interacting with the diamond. + +--- + +## Storage + +### DiamondStorage + +storage-location: erc8042:erc8109.diamond + + +{`struct DiamondStorage { + mapping(bytes4 functionSelector => FacetAndPosition) facetAndPosition; + /** + * Array of all function selectors that can be called in the diamond + */ + bytes4[] selectors; +}`} + + +--- +### FacetAndPosition + +Data stored for each function selector Facet address of function selector Position of selector in the 'bytes4[] selectors' array + + +{`struct FacetAndPosition { + address facet; + uint32 position; +}`} + + +--- +### FacetFunctions + + +{`struct FacetFunctions { + address facet; + bytes4[] selectors; +}`} + + +### State Variables + + + +## Functions + +### addFunctions + + +{`function addFunctions(address _facet, bytes4[] calldata _functionSelectors) ;`} + + +**Parameters:** + + + +--- +### getDiamondStorage + + +{`function getDiamondStorage() pure returns (DiamondStorage storage s);`} + + +--- +### removeFunctions + + +{`function removeFunctions(bytes4[] calldata _functionSelectors) ;`} + + +**Parameters:** + + + +--- +### replaceFunctions + + +{`function replaceFunctions(address _facet, bytes4[] calldata _functionSelectors) ;`} + + +**Parameters:** + + + +--- +### upgradeDiamond + +Upgrade the diamond by adding, replacing, or removing functions. - `_addFunctions` maps new selectors to their facet implementations. - `_replaceFunctions` updates existing selectors to new facet addresses. - `_removeFunctions` removes selectors from the diamond. Functions added first, then replaced, then removed. These events are emitted to record changes to functions: - `DiamondFunctionAdded` - `DiamondFunctionReplaced` - `DiamondFunctionRemoved` If `_delegate` is non-zero, the diamond performs a `delegatecall` to `_delegate` using `_functionCall`. The `DiamondDelegateCall` event is emitted. The `delegatecall` is done to alter a diamond's state or to initialize, modify, or remove state after an upgrade. However, if `_delegate` is zero, no `delegatecall` is made and no `DiamondDelegateCall` event is emitted. If _tag is non-zero or if _metadata.length > 0 then the `DiamondMetadata` event is emitted. + + +{`function upgradeDiamond( +FacetFunctions[] calldata _addFunctions, +FacetFunctions[] calldata _replaceFunctions, +bytes4[] calldata _removeFunctions, +address _delegate, +bytes calldata _functionCall, +bytes32 _tag, +bytes calldata _metadata +) ;`} + + +**Parameters:** + + + +## Events + + + +
+ Emitted when a diamond's constructor function or function from a facet makes a `delegatecall`. +
+ +
+ Signature: + +{`event DiamondDelegateCall(address indexed _delegate, bytes _functionCall);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when a function is added to a diamond. +
+ +
+ Signature: + +{`event DiamondFunctionAdded(bytes4 indexed _selector, address indexed _facet);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when a function is removed from a diamond. +
+ +
+ Signature: + +{`event DiamondFunctionRemoved(bytes4 indexed _selector, address indexed _oldFacet);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when changing the facet that will handle calls to a function. +
+ +
+ Signature: + +{`event DiamondFunctionReplaced(bytes4 indexed _selector, address indexed _oldFacet, address indexed _newFacet);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted to record information about a diamond. This event records any arbitrary metadata. The format of `_tag` and `_data` are not specified by the standard. +
+ +
+ Signature: + +{`event DiamondMetadata(bytes32 indexed _tag, bytes _data);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + + +
+ Signature: + +error CannotAddFunctionToDiamondThatAlreadyExists(bytes4 _selector); + +
+
+ + +
+ Signature: + +error CannotRemoveFunctionThatDoesNotExist(bytes4 _selector); + +
+
+ + +
+ Signature: + +error CannotRemoveImmutableFunction(bytes4 _selector); + +
+
+ + +
+ Signature: + +error CannotReplaceFunctionThatDoesNotExist(bytes4 _selector); + +
+
+ + +
+ Signature: + +error CannotReplaceFunctionWithTheSameFacet(bytes4 _selector); + +
+
+ + +
+ Signature: + +error CannotReplaceImmutableFunction(bytes4 _selector); + +
+
+ + +
+ Signature: + +error DelegateCallReverted(address _delegate, bytes _functionCall); + +
+
+ + +
+ Signature: + +error NoBytecodeAtAddress(address _contractAddress); + +
+
+ +
+ The functions below detect and revert with the following errors. +
+ +
+ Signature: + +error NoSelectorsProvidedForFacet(address _facet); + +
+
+
+ + + + +## Best Practices + + +- Ensure selector uniqueness before adding or replacing facets to avoid collisions. +- Verify that immutable functions are not targeted for removal or replacement. +- Handle errors such as `CannotAddFunctionToDiamondThatAlreadyExists` and `DelegateCallReverted` for robust upgrade processes. + + +## Integration Notes + + +This module interacts directly with the diamond's storage, identified by `DIAMOND_STORAGE_POSITION` which maps to `keccak256(\"erc8109.diamond\")`. It utilizes the `DiamondStorage` struct to manage facet mappings. All functions operate internally, modifying the diamond's facet registry. Changes are immediately effective for all facets interacting with the diamond. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/diamond/_category_.json b/website/docs/library/diamond/_category_.json new file mode 100644 index 00000000..26c8cc37 --- /dev/null +++ b/website/docs/library/diamond/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Diamond Core", + "position": 1, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/diamond/index" + } +} diff --git a/website/docs/library/diamond/example/ExampleDiamond.mdx b/website/docs/library/diamond/example/ExampleDiamond.mdx new file mode 100644 index 00000000..667ab5bc --- /dev/null +++ b/website/docs/library/diamond/example/ExampleDiamond.mdx @@ -0,0 +1,173 @@ +--- +sidebar_position: 510 +title: "ExampleDiamond" +description: "Initializes a diamond with facets and owner" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/diamond/example/ExampleDiamond.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Initializes a diamond with facets and owner + + + +- Initializes diamond with an owner and a set of facets. +- Maps function selectors to facet addresses for call routing. +- Designed for initial diamond setup. + + +## Overview + +This constructor function initializes a diamond contract by registering provided facets and setting the diamond's owner. It maps function selectors to their respective facet addresses, enabling the diamond proxy to route calls correctly. Developers use this during deployment to configure the diamond's initial functionality. + +--- + +## Storage + +## Functions + +### constructor + +Struct to hold facet address and its function selectors. struct FacetFunctions { address facet; bytes4[] selectors; } Initializes the diamond contract with facets, owner and other data. Adds all provided facets to the diamond's function selector mapping and sets the contract owner. Each facet in the array will have its function selectors registered to enable delegatecall routing. + + +{`constructor(DiamondMod.FacetFunctions[] memory _facets, address _diamondOwner) ;`} + + +**Parameters:** + + + +--- +### fallback + + +{`fallback() external payable;`} + + +--- +### receive + + +{`receive() external payable;`} + + + + + +## Best Practices + + +- Use the constructor only during initial diamond deployment. +- Ensure the `_facets` array contains valid facet addresses and their respective function selectors. +- Verify that the `_diamondOwner` is set correctly for administrative control. + + +## Security Considerations + + +The constructor is intended for deployment only. Ensure proper access control is implemented in separate facets for functions that modify diamond state after initialization. Validate all input parameters to prevent unexpected behavior or state corruption. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/diamond/example/_category_.json b/website/docs/library/diamond/example/_category_.json new file mode 100644 index 00000000..8e4d0ed5 --- /dev/null +++ b/website/docs/library/diamond/example/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "example", + "position": 99, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/diamond/example/index" + } +} diff --git a/website/docs/library/diamond/example/index.mdx b/website/docs/library/diamond/example/index.mdx new file mode 100644 index 00000000..925e7ada --- /dev/null +++ b/website/docs/library/diamond/example/index.mdx @@ -0,0 +1,22 @@ +--- +title: "example" +description: "example components for Compose diamonds." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + example components for Compose diamonds. + + + + } + size="medium" + /> + diff --git a/website/docs/library/diamond/index.mdx b/website/docs/library/diamond/index.mdx new file mode 100644 index 00000000..660a6e20 --- /dev/null +++ b/website/docs/library/diamond/index.mdx @@ -0,0 +1,57 @@ +--- +title: "Diamond Core" +description: "Core diamond proxy functionality for ERC-2535 diamonds." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + Core diamond proxy functionality for ERC-2535 diamonds. + + + + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/index.mdx b/website/docs/library/index.mdx new file mode 100644 index 00000000..a664d292 --- /dev/null +++ b/website/docs/library/index.mdx @@ -0,0 +1,51 @@ +--- +title: "Library" +description: "API reference for all Compose modules and facets." +sidebar_class_name: "hidden" +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + API reference for all Compose modules and facets. + + + + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/interfaceDetection/ERC165/ERC165Facet.mdx b/website/docs/library/interfaceDetection/ERC165/ERC165Facet.mdx new file mode 100644 index 00000000..9bc28650 --- /dev/null +++ b/website/docs/library/interfaceDetection/ERC165/ERC165Facet.mdx @@ -0,0 +1,158 @@ +--- +sidebar_position: 410 +title: "ERC165Facet" +description: "ERC-165 interface detection for diamonds" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/interfaceDetection/ERC165/ERC165Facet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +ERC-165 interface detection for diamonds + + + +- Implements ERC-165 standard for interface detection. +- Exposes `supportsInterface` function via diamond proxy. +- Utilizes internal assembly for direct storage access. +- No external dependencies beyond core Compose contracts. + + +## Overview + +This facet implements ERC-165 interface detection within a diamond. It exposes the `supportsInterface` function, allowing external contracts to query which interfaces the diamond proxy supports. The facet accesses shared ERC-165 storage to provide accurate interface information, integrating seamlessly with the diamond's composable architecture. + +--- + +## Storage + +### ERC165Storage + + +{`struct ERC165Storage { + /** + * @notice Mapping of interface IDs to whether they are supported + */ + mapping(bytes4 => bool) supportedInterfaces; +}`} + + +### State Variables + + + +## Functions + +### supportsInterface + +Query if a contract implements an interface This function checks if the diamond supports the given interface ID + + +{`function supportsInterface(bytes4 _interfaceId) external view returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + + + + +## Best Practices + + +- Ensure the `ERC165Facet` is added to the diamond during initialization. +- Calls to `supportsInterface` are routed through the diamond proxy. +- The `ERC165Storage` struct is correctly initialized and managed. + + +## Security Considerations + + +The `supportsInterface` function is `external` and `view`, posing no reentrancy risk. Input validation is minimal as `bytes4` is a fixed-size type. Access control is not applicable as the function is read-only. Ensure the `ERC165Storage` is correctly bound to its designated storage slot. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/interfaceDetection/ERC165/ERC165Mod.mdx b/website/docs/library/interfaceDetection/ERC165/ERC165Mod.mdx new file mode 100644 index 00000000..49e73665 --- /dev/null +++ b/website/docs/library/interfaceDetection/ERC165/ERC165Mod.mdx @@ -0,0 +1,163 @@ +--- +sidebar_position: 1 +title: "ERC165Mod" +description: "Register and detect supported ERC-165 interfaces" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/interfaceDetection/ERC165/ERC165Mod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Register and detect supported ERC-165 interfaces + + + +- Provides internal functions for ERC-165 interface management. +- Utilizes diamond storage at `STORAGE_POSITION` for persistent interface registration. +- No external dependencies, promoting standalone facet functionality. + + + +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 registering and detecting ERC-165 supported interfaces. Facets can import this module to manage interface support using shared diamond storage. This ensures consistent interface detection across all facets within a diamond. + +--- + +## Storage + +### ERC165Storage + + +{`struct ERC165Storage { + /* + * @notice Mapping of interface IDs to whether they are supported + */ + mapping(bytes4 => bool) supportedInterfaces; +}`} + + +### State Variables + + + +## Functions + +### getStorage + +Returns a pointer to the ERC-165 storage struct. Uses inline assembly to bind the storage struct to the fixed storage position. + + +{`function getStorage() pure returns (ERC165Storage storage s);`} + + +**Returns:** + + + +--- +### registerInterface + +Register that a contract supports an interface Call this function during initialization to register supported interfaces. For example, in an ERC721 facet initialization, you would call: `LibERC165.registerInterface(type(IERC721).interfaceId)` + + +{`function registerInterface(bytes4 _interfaceId) ;`} + + +**Parameters:** + + + + + + +## Best Practices + + +- Call `registerInterface` during facet initialization to declare supported interfaces. +- Ensure interface IDs are correct and align with implemented functionality. +- Use `getStorage` to access the internal storage struct for read operations. + + +## Integration Notes + + +This module uses diamond storage at the `STORAGE_POSITION` defined by `keccak256(\"compose.erc165\")`. The `ERC165Storage` struct is bound to this slot using inline assembly. Any facet that imports and uses `ERC165Mod` will interact with the same shared storage, ensuring consistent interface detection across the diamond. + + +
+ +
+ + diff --git a/website/docs/library/interfaceDetection/ERC165/_category_.json b/website/docs/library/interfaceDetection/ERC165/_category_.json new file mode 100644 index 00000000..2396f18a --- /dev/null +++ b/website/docs/library/interfaceDetection/ERC165/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "ERC-165", + "position": 99, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/interfaceDetection/ERC165/index" + } +} diff --git a/website/docs/library/interfaceDetection/ERC165/index.mdx b/website/docs/library/interfaceDetection/ERC165/index.mdx new file mode 100644 index 00000000..a2fcda6a --- /dev/null +++ b/website/docs/library/interfaceDetection/ERC165/index.mdx @@ -0,0 +1,29 @@ +--- +title: "ERC-165" +description: "ERC-165 components for Compose diamonds." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + ERC-165 components for Compose diamonds. + + + + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/interfaceDetection/_category_.json b/website/docs/library/interfaceDetection/_category_.json new file mode 100644 index 00000000..a184d836 --- /dev/null +++ b/website/docs/library/interfaceDetection/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Interface Detection", + "position": 5, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/interfaceDetection/index" + } +} diff --git a/website/docs/library/interfaceDetection/index.mdx b/website/docs/library/interfaceDetection/index.mdx new file mode 100644 index 00000000..65448bd8 --- /dev/null +++ b/website/docs/library/interfaceDetection/index.mdx @@ -0,0 +1,22 @@ +--- +title: "Interface Detection" +description: "ERC-165 interface detection support." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + ERC-165 interface detection support. + + + + } + size="medium" + /> + diff --git a/website/docs/library/token/ERC1155/ERC1155Facet.mdx b/website/docs/library/token/ERC1155/ERC1155Facet.mdx new file mode 100644 index 00000000..55119e7c --- /dev/null +++ b/website/docs/library/token/ERC1155/ERC1155Facet.mdx @@ -0,0 +1,684 @@ +--- +sidebar_position: 2 +title: "ERC1155Facet" +description: "Manages ERC-1155 tokens within a diamond" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC1155/ERC1155Facet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Manages ERC-1155 tokens within a diamond + + + +- Exposes external functions for ERC-1155 token operations via diamond routing. +- Self-contained unit with no external dependencies or inheritance. +- Integrates with the diamond storage pattern for state management. +- Emits standard ERC-1155 events for tracking token activity. + + +## Overview + +This facet implements ERC-1155 token functionality as external functions within a diamond. It provides standard ERC-1155 operations, routing calls through the diamond proxy and interacting with shared diamond storage. Developers add this facet to expose fungible and non-fungible token capabilities while preserving upgradeability. + +--- + +## Storage + +### ERC1155Storage + + +{`struct ERC1155Storage { + mapping(uint256 id => mapping(address account => uint256 balance)) balanceOf; + mapping(address account => mapping(address operator => bool)) isApprovedForAll; + string uri; + string baseURI; + mapping(uint256 tokenId => string) tokenURIs; +}`} + + +### State Variables + + + +## Functions + +### uri + +Returns the URI for token type `_id`. If a token-specific URI is set in tokenURIs[_id], returns the concatenation of baseURI and tokenURIs[_id]. Note that baseURI is empty by default and must be set explicitly if concatenation is desired. If no token-specific URI is set, returns the default URI which applies to all token types. The default URI may contain the substring `{id}` which clients should replace with the actual token ID. + + +{`function uri(uint256 _id) external view returns (string memory);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### balanceOf + +Returns the amount of tokens of token type `id` owned by `account`. + + +{`function balanceOf(address _account, uint256 _id) external view returns (uint256);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### balanceOfBatch + +Batched version of balanceOf. + + +{`function balanceOfBatch(address[] calldata _accounts, uint256[] calldata _ids) + external + view + returns (uint256[] memory balances);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### setApprovalForAll + +Grants or revokes permission to `operator` to transfer the caller's tokens. Emits an ApprovalForAll event. + + +{`function setApprovalForAll(address _operator, bool _approved) external;`} + + +**Parameters:** + + + +--- +### isApprovedForAll + +Returns true if `operator` is approved to transfer `account`'s tokens. + + +{`function isApprovedForAll(address _account, address _operator) external view returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### safeTransferFrom + +Transfers `value` amount of token type `id` from `from` to `to`. Emits a TransferSingle event. + + +{`function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external;`} + + +**Parameters:** + + + +--- +### safeBatchTransferFrom + +Batched version of safeTransferFrom. Emits a TransferBatch event. + + +{`function safeBatchTransferFrom( + address _from, + address _to, + uint256[] calldata _ids, + uint256[] calldata _values, + bytes calldata _data +) external;`} + + +**Parameters:** + + + +## Events + + + +
+ Emitted when `value` amount of tokens of type `id` are transferred from `from` to `to` by `operator`. +
+ +
+ Signature: + +{`event TransferSingle( + address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value +);`} + +
+ +
+ Parameters: + +
+
+ +
+ Equivalent to multiple TransferSingle events, where `operator`, `from` and `to` are the same for all transfers. +
+ +
+ Signature: + +{`event TransferBatch( + address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values +);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when `account` grants or revokes permission to `operator` to transfer their tokens. +
+ +
+ Signature: + +{`event ApprovalForAll(address indexed _account, address indexed _operator, bool _approved);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when the URI for token type `id` changes to `value`. +
+ +
+ Signature: + +{`event URI(string _value, uint256 indexed _id);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Error indicating insufficient balance for a transfer. +
+ +
+ Signature: + +error ERC1155InsufficientBalance(address _sender, uint256 _balance, uint256 _needed, uint256 _tokenId); + +
+
+ +
+ Error indicating the sender address is invalid. +
+ +
+ Signature: + +error ERC1155InvalidSender(address _sender); + +
+
+ +
+ Error indicating the receiver address is invalid. +
+ +
+ Signature: + +error ERC1155InvalidReceiver(address _receiver); + +
+
+ +
+ Error indicating missing approval for an operator. +
+ +
+ Signature: + +error ERC1155MissingApprovalForAll(address _operator, address _owner); + +
+
+ +
+ Error indicating the approver address is invalid. +
+ +
+ Signature: + +error ERC1155InvalidApprover(address _approver); + +
+
+ +
+ Error indicating the operator address is invalid. +
+ +
+ Signature: + +error ERC1155InvalidOperator(address _operator); + +
+
+ +
+ Error indicating array length mismatch in batch operations. +
+ +
+ Signature: + +error ERC1155InvalidArrayLength(uint256 _idsLength, uint256 _valuesLength); + +
+
+
+ + + + +## Best Practices + + +- Initialize token URIs and other relevant state during diamond deployment. +- Enforce appropriate access control for functions that modify token approvals or transfers if required by your diamond's logic. +- Verify storage compatibility if upgrading the ERC1155Facet to prevent data loss or corruption. + + +## Security Considerations + + +All state-changing functions (`safeTransferFrom`, `safeBatchTransferFrom`, `setApprovalForAll`) must be appropriately protected by access control mechanisms within the diamond. Input validation is performed for token balances, receiver addresses, and array lengths. Follow standard Solidity security practices for external calls and reentrancy. Ensure the diamond's access control layer correctly governs calls to these functions. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC1155/ERC1155Mod.mdx b/website/docs/library/token/ERC1155/ERC1155Mod.mdx new file mode 100644 index 00000000..bef7e6ef --- /dev/null +++ b/website/docs/library/token/ERC1155/ERC1155Mod.mdx @@ -0,0 +1,634 @@ +--- +sidebar_position: 1 +title: "ERC1155Mod" +description: "Manages ERC-1155 token transfers and metadata within a diamond" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC1155/ERC1155Mod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Manages ERC-1155 token transfers and metadata within a diamond + + + +- Internal functions for minting, burning, and transferring ERC-1155 tokens. +- Supports batch operations for multiple token IDs and values. +- Implements safe transfer logic with ERC1155Receiver validation. +- Manages token URIs and base URIs through dedicated functions. + + + +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 minting, burning, and transferring ERC-1155 tokens. Facets can integrate this module to manage token balances and URIs using shared diamond storage. It ensures safe transfers by validating recipient contracts and handles batch operations for efficiency. + +--- + +## Storage + +### ERC1155Storage + +ERC-8042 compliant storage struct for ERC-1155 token data. storage-location: erc8042:compose.erc1155 + + +{`struct ERC1155Storage { + mapping(uint256 id => mapping(address account => uint256 balance)) balanceOf; + mapping(address account => mapping(address operator => bool)) isApprovedForAll; + string uri; + string baseURI; + mapping(uint256 tokenId => string) tokenURIs; +}`} + + +### State Variables + + + +## Functions + +### burn + +Burns a single token type from an address. Decreases the balance and emits a TransferSingle event. Reverts if the account has insufficient balance. + + +{`function burn(address _from, uint256 _id, uint256 _value) ;`} + + +**Parameters:** + + + +--- +### burnBatch + +Burns multiple token types from an address in a single transaction. Decreases balances for each token type and emits a TransferBatch event. Reverts if the account has insufficient balance for any token type. + + +{`function burnBatch(address _from, uint256[] memory _ids, uint256[] memory _values) ;`} + + +**Parameters:** + + + +--- +### getStorage + +Returns the ERC-1155 storage struct from the predefined diamond storage slot. Uses inline assembly to set the storage slot reference. + + +{`function getStorage() pure returns (ERC1155Storage storage s);`} + + +**Returns:** + + + +--- +### mint + +Mints a single token type to an address. Increases the balance and emits a TransferSingle event. Performs receiver validation if recipient is a contract. + + +{`function mint(address _to, uint256 _id, uint256 _value, bytes memory _data) ;`} + + +**Parameters:** + + + +--- +### mintBatch + +Mints multiple token types to an address in a single transaction. Increases balances for each token type and emits a TransferBatch event. Performs receiver validation if recipient is a contract. + + +{`function mintBatch(address _to, uint256[] memory _ids, uint256[] memory _values, bytes memory _data) ;`} + + +**Parameters:** + + + +--- +### safeBatchTransferFrom + +Safely transfers multiple token types from one address to another in a single transaction. Validates ownership, approval, and receiver address before updating balances for each token type. Performs ERC1155Receiver validation if recipient is a contract (safe transfer). Complies with EIP-1155 safe transfer requirements. + + +{`function safeBatchTransferFrom( +address _from, +address _to, +uint256[] memory _ids, +uint256[] memory _values, +address _operator +) ;`} + + +**Parameters:** + + + +--- +### safeTransferFrom + +Safely transfers a single token type from one address to another. Validates ownership, approval, and receiver address before updating balances. Performs ERC1155Receiver validation if recipient is a contract (safe transfer). Complies with EIP-1155 safe transfer requirements. + + +{`function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, address _operator) ;`} + + +**Parameters:** + + + +--- +### setBaseURI + +Sets the base URI prefix for token-specific URIs. The base URI is concatenated with token-specific URIs set via setTokenURI. Does not affect the default URI used when no token-specific URI is set. + + +{`function setBaseURI(string memory _baseURI) ;`} + + +**Parameters:** + + + +--- +### setTokenURI + +Sets the token-specific URI for a given token ID. Sets tokenURIs[_tokenId] to the provided string and emits a URI event with the full computed URI. The emitted URI is the concatenation of baseURI and the token-specific URI. + + +{`function setTokenURI(uint256 _tokenId, string memory _tokenURI) ;`} + + +**Parameters:** + + + +## Events + + + +
+ Emitted when multiple token types are transferred. +
+ +
+ Signature: + +{`event TransferBatch( +address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values +);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when a single token type is transferred. +
+ +
+ Signature: + +{`event TransferSingle( +address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value +);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when the URI for token type `_id` changes to `_value`. +
+ +
+ Signature: + +{`event URI(string _value, uint256 indexed _id);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ **Title:** LibERC1155 — ERC-1155 Library Provides internal functions and storage layout for ERC-1155 multi-token logic. Thrown when insufficient balance for a transfer or burn operation. Uses ERC-8042 for storage location standardization and ERC-6093 for error conventions. This library is intended to be used by custom facets to integrate with ERC-1155 functionality. +
+ +
+ Signature: + +error ERC1155InsufficientBalance(address _sender, uint256 _balance, uint256 _needed, uint256 _tokenId); + +
+
+ +
+ Thrown when array lengths don't match in batch operations. +
+ +
+ Signature: + +error ERC1155InvalidArrayLength(uint256 _idsLength, uint256 _valuesLength); + +
+
+ +
+ Thrown when the receiver address is invalid. +
+ +
+ Signature: + +error ERC1155InvalidReceiver(address _receiver); + +
+
+ +
+ Thrown when the sender address is invalid. +
+ +
+ Signature: + +error ERC1155InvalidSender(address _sender); + +
+
+ +
+ Thrown when missing approval for an operator. +
+ +
+ Signature: + +error ERC1155MissingApprovalForAll(address _operator, address _owner); + +
+
+
+ + + + +## Best Practices + + +- Ensure ownership and approvals are checked before performing transfers or burns. +- Validate receiver addresses for contract types to ensure safe transfers. +- Use `mintBatch` and `burnBatch` for efficient multi-token operations. + + +## Integration Notes + + +This module utilizes diamond storage at `keccak256("compose.erc1155")` to store ERC-1155 state, including token URIs and base URIs. All state modifications are performed via internal functions, ensuring that changes are immediately reflected across all facets interacting with this storage slot. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC1155/_category_.json b/website/docs/library/token/ERC1155/_category_.json new file mode 100644 index 00000000..cdb57d9a --- /dev/null +++ b/website/docs/library/token/ERC1155/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "ERC-1155", + "position": 3, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/token/ERC1155/index" + } +} diff --git a/website/docs/library/token/ERC1155/index.mdx b/website/docs/library/token/ERC1155/index.mdx new file mode 100644 index 00000000..e34739a6 --- /dev/null +++ b/website/docs/library/token/ERC1155/index.mdx @@ -0,0 +1,29 @@ +--- +title: "ERC-1155" +description: "ERC-1155 multi-token implementations." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + ERC-1155 multi-token implementations. + + + + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/token/ERC20/ERC20/ERC20BurnFacet.mdx b/website/docs/library/token/ERC20/ERC20/ERC20BurnFacet.mdx new file mode 100644 index 00000000..33d6e1d7 --- /dev/null +++ b/website/docs/library/token/ERC20/ERC20/ERC20BurnFacet.mdx @@ -0,0 +1,267 @@ +--- +sidebar_position: 3 +title: "ERC20BurnFacet" +description: "Burns ERC-20 tokens from caller or another account" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC20/ERC20/ERC20BurnFacet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Burns ERC-20 tokens from caller or another account + + + +- External functions for burning tokens. +- Emits `Transfer` event upon successful burn. +- Compatible with ERC-2535 diamond standard. +- Leverages diamond storage for state. + + +## Overview + +This facet implements ERC-20 token burning functionality within a diamond proxy. It provides external functions to destroy tokens, reducing the total supply. Developers integrate this facet to enable token destruction mechanisms, adhering to the diamond storage pattern for state management. + +--- + +## Storage + +### ERC20Storage + + +{`struct ERC20Storage { + mapping(address owner => uint256 balance) balanceOf; + uint256 totalSupply; + mapping(address owner => mapping(address spender => uint256 allowance)) allowance; +}`} + + +### State Variables + + + +## Functions + +### burn + +Burns (destroys) a specific amount of tokens from the caller's balance. Emits a Transfer event to the zero address. + + +{`function burn(uint256 _value) external;`} + + +**Parameters:** + + + +--- +### burnFrom + +Burns tokens from another account, deducting from the caller's allowance. Emits a Transfer event to the zero address. + + +{`function burnFrom(address _account, uint256 _value) external;`} + + +**Parameters:** + + + +## Events + + + +
+ Emitted when tokens are transferred between two addresses. +
+ +
+ Signature: + +{`event Transfer(address indexed _from, address indexed _to, uint256 _value);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when an account has insufficient balance for a transfer or burn. +
+ +
+ Signature: + +error ERC20InsufficientBalance(address _sender, uint256 _balance, uint256 _needed); + +
+
+ +
+ Thrown when a spender tries to use more than the approved allowance. +
+ +
+ Signature: + +error ERC20InsufficientAllowance(address _spender, uint256 _allowance, uint256 _needed); + +
+
+
+ + + + +## Best Practices + + +- Call `burn` or `burnFrom` through the diamond proxy address. +- Ensure necessary allowances are set before calling `burnFrom`. +- Verify the diamond is initialized with the `ERC20BurnFacet` before invoking its functions. + + +## Security Considerations + + +The `burn` function reduces the caller's balance. The `burnFrom` function requires an allowance to be set for the caller on the specified account. Both functions are protected against insufficient balance or allowance by reverting with `ERC20InsufficientBalance` or `ERC20InsufficientAllowance` errors respectively. Follow standard Solidity security practices. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC20/ERC20/ERC20Facet.mdx b/website/docs/library/token/ERC20/ERC20/ERC20Facet.mdx new file mode 100644 index 00000000..4610917d --- /dev/null +++ b/website/docs/library/token/ERC20/ERC20/ERC20Facet.mdx @@ -0,0 +1,564 @@ +--- +sidebar_position: 2 +title: "ERC20Facet" +description: "ERC-20 token functionality within a diamond" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC20/ERC20/ERC20Facet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +ERC-20 token functionality within a diamond + + + +- Exposes external view and state-changing functions for ERC-20 operations. +- Accesses token state via diamond storage using a predefined slot. +- Emits standard ERC-20 `Transfer` and `Approval` events. +- Implements ERC-20 error codes for common failure conditions. + + +## Overview + +This facet implements standard ERC-20 token functions, enabling token operations directly through the diamond proxy. It accesses shared storage for token state and routes external calls. Integrate this facet to expose token balances, transfers, and approvals while maintaining diamond upgradeability. + +--- + +## Storage + +### ERC20Storage + + +{`struct ERC20Storage { + mapping(address owner => uint256 balance) balanceOf; + uint256 totalSupply; + mapping(address owner => mapping(address spender => uint256 allowance)) allowance; + uint8 decimals; + string name; + string symbol; +}`} + + +### State Variables + + + +## Functions + +### name + +Returns the name of the token. + + +{`function name() external view returns (string memory);`} + + +**Returns:** + + + +--- +### symbol + +Returns the symbol of the token. + + +{`function symbol() external view returns (string memory);`} + + +**Returns:** + + + +--- +### decimals + +Returns the number of decimals used for token precision. + + +{`function decimals() external view returns (uint8);`} + + +**Returns:** + + + +--- +### totalSupply + +Returns the total supply of tokens. + + +{`function totalSupply() external view returns (uint256);`} + + +**Returns:** + + + +--- +### balanceOf + +Returns the balance of a specific account. + + +{`function balanceOf(address _account) external view returns (uint256);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### allowance + +Returns the remaining number of tokens that a spender is allowed to spend on behalf of an owner. + + +{`function allowance(address _owner, address _spender) external view returns (uint256);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### approve + +Approves a spender to transfer up to a certain amount of tokens on behalf of the caller. Emits an Approval event. + + +{`function approve(address _spender, uint256 _value) external returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### transfer + +Transfers tokens to another address. Emits a Transfer event. + + +{`function transfer(address _to, uint256 _value) external returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### transferFrom + +Transfers tokens on behalf of another account, provided sufficient allowance exists. Emits a Transfer event and decreases the spender's allowance. + + +{`function transferFrom(address _from, address _to, uint256 _value) external returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +## Events + + + +
+ Emitted when an approval is made for a spender by an owner. +
+ +
+ Signature: + +{`event Approval(address indexed _owner, address indexed _spender, uint256 _value);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when tokens are transferred between two addresses. +
+ +
+ Signature: + +{`event Transfer(address indexed _from, address indexed _to, uint256 _value);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when an account has insufficient balance for a transfer or burn. +
+ +
+ Signature: + +error ERC20InsufficientBalance(address _sender, uint256 _balance, uint256 _needed); + +
+
+ +
+ Thrown when the sender address is invalid (e.g., zero address). +
+ +
+ Signature: + +error ERC20InvalidSender(address _sender); + +
+
+ +
+ Thrown when the receiver address is invalid (e.g., zero address). +
+ +
+ Signature: + +error ERC20InvalidReceiver(address _receiver); + +
+
+ +
+ Thrown when a spender tries to use more than the approved allowance. +
+ +
+ Signature: + +error ERC20InsufficientAllowance(address _spender, uint256 _allowance, uint256 _needed); + +
+
+ +
+ Thrown when the spender address is invalid (e.g., zero address). +
+ +
+ Signature: + +error ERC20InvalidSpender(address _spender); + +
+
+
+ + + + +## Best Practices + + +- Initialize token name, symbol, decimals, and total supply during diamond deployment. +- Enforce access control for functions that modify token state (e.g., minting, if implemented by another facet). +- Ensure storage compatibility when upgrading to new versions of the ERC20Facet. + + +## Security Considerations + + +Input validation is critical for `transfer`, `transferFrom`, and `approve` functions to prevent common ERC-20 vulnerabilities such as insufficient balance or allowance. The `transferFrom` function must correctly decrease the spender's allowance. Follow standard Solidity security practices for reentrancy and access control on any associated minting or burning functions provided by other facets. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC20/ERC20/ERC20Mod.mdx b/website/docs/library/token/ERC20/ERC20/ERC20Mod.mdx new file mode 100644 index 00000000..cae948a3 --- /dev/null +++ b/website/docs/library/token/ERC20/ERC20/ERC20Mod.mdx @@ -0,0 +1,452 @@ +--- +sidebar_position: 1 +title: "ERC20Mod" +description: "Internal functions and storage for ERC-20 token logic" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC20/ERC20/ERC20Mod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Internal functions and storage for ERC-20 token logic + + + +- Provides essential ERC-20 internal functions: `mint`, `burn`, `transfer`, `transferFrom`, `approve`. +- Integrates with the diamond storage pattern at a dedicated storage position. +- No external dependencies or `using` directives, promoting explicit control flow. +- Functions are `internal`, designed for direct inclusion within custom facets. + + + +This module provides internal functions for use in your custom facets. Import it to access shared logic and storage. + + +## Overview + +This module exposes internal functions for core ERC-20 operations, including minting, burning, and transfers. Facets import this module to manage token balances and allowances using shared diamond storage. Its functions are designed for integration into custom facets, ensuring consistency across the diamond. + +--- + +## Storage + +### ERC20Storage + + +{`struct ERC20Storage { + mapping(address owner => uint256 balance) balanceOf; + uint256 totalSupply; + mapping(address owner => mapping(address spender => uint256 allowance)) allowance; + uint8 decimals; + string name; + string symbol; +}`} + + +### State Variables + + + +## Functions + +### approve + +Approves a spender to transfer tokens on behalf of the caller. Sets the allowance for the spender. + + +{`function approve(address _spender, uint256 _value) ;`} + + +**Parameters:** + + + +--- +### burn + +Burns tokens from a specified address. Decreases both total supply and the sender's balance. + + +{`function burn(address _account, uint256 _value) ;`} + + +**Parameters:** + + + +--- +### getStorage + +Returns a pointer to the ERC-20 storage struct. Uses inline assembly to bind the storage struct to the fixed storage position. + + +{`function getStorage() pure returns (ERC20Storage storage s);`} + + +**Returns:** + + + +--- +### mint + +Mints new tokens to a specified address. Increases both total supply and the recipient's balance. + + +{`function mint(address _account, uint256 _value) ;`} + + +**Parameters:** + + + +--- +### transfer + +Transfers tokens from the caller to another address. Updates balances directly without allowance mechanism. + + +{`function transfer(address _to, uint256 _value) ;`} + + +**Parameters:** + + + +--- +### transferFrom + +Transfers tokens from one address to another using an allowance. Deducts the spender's allowance and updates balances. + + +{`function transferFrom(address _from, address _to, uint256 _value) ;`} + + +**Parameters:** + + + +## Events + + + +
+ Emitted when an approval is made for a spender by an owner. +
+ +
+ Signature: + +{`event Approval(address indexed _owner, address indexed _spender, uint256 _value);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when tokens are transferred between addresses. +
+ +
+ Signature: + +{`event Transfer(address indexed _from, address indexed _to, uint256 _value);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when a spender tries to spend more than their allowance. +
+ +
+ Signature: + +error ERC20InsufficientAllowance(address _spender, uint256 _allowance, uint256 _needed); + +
+
+ +
+ Thrown when a sender attempts to transfer or burn more tokens than their balance. +
+ +
+ Signature: + +error ERC20InsufficientBalance(address _sender, uint256 _balance, uint256 _needed); + +
+
+ +
+ Thrown when the receiver address is invalid (e.g., zero address). +
+ +
+ Signature: + +error ERC20InvalidReceiver(address _receiver); + +
+
+ +
+ Thrown when the sender address is invalid (e.g., zero address). +
+ +
+ Signature: + +error ERC20InvalidSender(address _sender); + +
+
+ +
+ Thrown when the spender address is invalid (e.g., zero address). +
+ +
+ Signature: + +error ERC20InvalidSpender(address _spender); + +
+
+
+ + + + +## Best Practices + + +- Ensure all calls to `ERC20Mod` functions are protected by appropriate access control within your facet. +- Verify that the `ERC20Storage` struct layout is compatible when upgrading facets or adding new storage. +- Handle custom errors like `ERC20InsufficientBalance` and `ERC20InsufficientAllowance` explicitly in your facet logic. + + +## Integration Notes + + +This module utilizes the diamond storage pattern, referencing a specific storage position identified by `keccak256(\"compose.erc20\")`. All state modifications made through its internal functions (`mint`, `burn`, `transfer`, `transferFrom`, `approve`) directly update the shared `ERC20Storage` struct. These changes are immediately visible to all facets accessing the same storage position, enabling composable and consistent ERC-20 state management. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC20/ERC20/_category_.json b/website/docs/library/token/ERC20/ERC20/_category_.json new file mode 100644 index 00000000..bd8d3da5 --- /dev/null +++ b/website/docs/library/token/ERC20/ERC20/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "ERC-20", + "position": 1, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/token/ERC20/ERC20/index" + } +} diff --git a/website/docs/library/token/ERC20/ERC20/index.mdx b/website/docs/library/token/ERC20/ERC20/index.mdx new file mode 100644 index 00000000..b702c917 --- /dev/null +++ b/website/docs/library/token/ERC20/ERC20/index.mdx @@ -0,0 +1,36 @@ +--- +title: "ERC-20" +description: "ERC-20 fungible token implementations." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + ERC-20 fungible token implementations. + + + + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/token/ERC20/ERC20Bridgeable/ERC20BridgeableFacet.mdx b/website/docs/library/token/ERC20/ERC20Bridgeable/ERC20BridgeableFacet.mdx new file mode 100644 index 00000000..8ef1d032 --- /dev/null +++ b/website/docs/library/token/ERC20/ERC20Bridgeable/ERC20BridgeableFacet.mdx @@ -0,0 +1,419 @@ +--- +sidebar_position: 2 +title: "ERC20BridgeableFacet" +description: "Cross-chain ERC-20 token minting and burning" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC20/ERC20Bridgeable/ERC20BridgeableFacet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Cross-chain ERC-20 token minting and burning + + + +- Enables cross-chain minting and burning of ERC-20 tokens. +- Enforces access control via the `trusted-bridge` role. +- Integrates seamlessly with the diamond storage pattern. +- Functions are external, accessible via the diamond proxy. + + +## Overview + +This facet enables cross-chain ERC-20 token minting and burning operations within a diamond. It exposes functions to mint tokens to specific accounts and burn tokens from specified addresses, requiring the caller to possess the `trusted-bridge` role. This facet routes calls through the diamond proxy, interacting with shared diamond storage for token management. + +--- + +## Storage + +### ERC20Storage + + +{`struct ERC20Storage { + mapping(address owner => uint256 balance) balanceOf; + uint256 totalSupply; +}`} + + +--- +### AccessControlStorage + + +{`struct AccessControlStorage { + mapping(address account => mapping(bytes32 role => bool hasRole)) hasRole; +}`} + + +### State Variables + + + +## Functions + +### crosschainMint + +Cross-chain mint — callable only by an address having the `trusted-bridge` role. + + +{`function crosschainMint(address _account, uint256 _value) external;`} + + +**Parameters:** + + + +--- +### crosschainBurn + +Cross-chain burn — callable only by an address having the `trusted-bridge` role. + + +{`function crosschainBurn(address _from, uint256 _value) external;`} + + +**Parameters:** + + + +--- +### checkTokenBridge + +Internal check to check if the bridge (caller) is trusted. Reverts if caller is zero or not in the AccessControl `trusted-bridge` role. + + +{`function checkTokenBridge(address _caller) external view;`} + + +**Parameters:** + + + +## Events + + + +
+ Emitted when tokens are minted via a cross-chain bridge. +
+ +
+ Signature: + +{`event CrosschainMint(address indexed _to, uint256 _amount, address indexed _sender);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when a crosschain transfer burns tokens. +
+ +
+ Signature: + +{`event CrosschainBurn(address indexed _from, uint256 _amount, address indexed _sender);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when tokens are transferred between two addresses. +
+ +
+ Signature: + +{`event Transfer(address indexed _from, address indexed _to, uint256 _value);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Revert when a provided receiver is invalid(e.g,zero address) . +
+ +
+ Signature: + +error ERC20InvalidReciever(address _receiver); + +
+
+ +
+ Thrown when the sender address is invalid (e.g., zero address). +
+ +
+ Signature: + +error ERC20InvalidSender(address _sender); + +
+
+ +
+ Revert when caller is not a trusted bridge. +
+ +
+ Signature: + +error ERC20InvalidBridgeAccount(address _caller); + +
+
+ +
+ Revert when caller address is invalid. +
+ +
+ Signature: + +error ERC20InvalidCallerAddress(address _caller); + +
+
+ +
+ Thrown when the account does not have a specific role. +
+ +
+ Signature: + +error AccessControlUnauthorizedAccount(address _account, bytes32 _role); + +
+
+ + +
+ Signature: + +error ERC20InsufficientBalance(address _from, uint256 _accountBalance, uint256 _value); + +
+
+
+ + + + +## Best Practices + + +- Initialize the `trusted-bridge` role for authorized bridge contracts during diamond setup. +- Ensure the `ERC20BridgeableFacet` is correctly added to the diamond's facet registry. +- Verify that the diamond storage slot for ERC20 data is correctly configured. + + +## Security Considerations + + +Cross-chain operations require strict validation of the `trusted-bridge` role. The `crosschainMint` and `crosschainBurn` functions revert if the caller does not possess this role. Input validation is performed on recipient and sender addresses. Follow standard Solidity security practices for input validation and reentrancy. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC20/ERC20Bridgeable/ERC20BridgeableMod.mdx b/website/docs/library/token/ERC20/ERC20Bridgeable/ERC20BridgeableMod.mdx new file mode 100644 index 00000000..12de40c8 --- /dev/null +++ b/website/docs/library/token/ERC20/ERC20Bridgeable/ERC20BridgeableMod.mdx @@ -0,0 +1,465 @@ +--- +sidebar_position: 1 +title: "ERC20BridgeableMod" +description: "Cross-chain token transfers with trusted bridge authorization" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC20/ERC20Bridgeable/ERC20BridgeableMod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Cross-chain token transfers with trusted bridge authorization + + + +- Enables cross-chain minting and burning of tokens. +- Enforces `trusted-bridge` role for all cross-chain operations. +- Uses diamond storage pattern for state management. +- Functions are `internal` and intended for composition within facets. + + + +This module provides internal functions for use in your custom facets. Import it to access shared logic and storage. + + +## Overview + +This module enables cross-chain token minting and burning operations. Facets can import this module to integrate trusted bridge functionality, ensuring that only authorized addresses can initiate these sensitive cross-chain transactions. It utilizes diamond storage for managing ERC20 state and access control roles. + +--- + +## Storage + +### AccessControlStorage + + +{`struct AccessControlStorage { + mapping(address account => mapping(bytes32 role => bool hasRole)) hasRole; +}`} + + +--- +### ERC20Storage + +ERC-8042 compliant storage struct for ERC20 token data. storage-location: erc8042:compose.erc20 + + +{`struct ERC20Storage { + mapping(address owner => uint256 balance) balanceOf; + uint256 totalSupply; +}`} + + +### State Variables + + + +## Functions + +### checkTokenBridge + +Internal check to check if the bridge (caller) is trusted. Reverts if caller is zero or not in the AccessControl `trusted-bridge` role. + + +{`function checkTokenBridge(address _caller) view;`} + + +**Parameters:** + + + +--- +### crosschainBurn + +Cross-chain burn — callable only by an address having the `trusted-bridge` role. + + +{`function crosschainBurn(address _from, uint256 _value) ;`} + + +**Parameters:** + + + +--- +### crosschainMint + +Cross-chain mint — callable only by an address having the `trusted-bridge` role. + + +{`function crosschainMint(address _account, uint256 _value) ;`} + + +**Parameters:** + + + +--- +### getAccessControlStorage + +helper to return AccessControlStorage at its diamond slot + + +{`function getAccessControlStorage() pure returns (AccessControlStorage storage s);`} + + +--- +### getERC20Storage + +Returns the ERC20 storage struct from the predefined diamond storage slot. Uses inline assembly to set the storage slot reference. + + +{`function getERC20Storage() pure returns (ERC20Storage storage s);`} + + +**Returns:** + + + +## Events + + + +
+ Emitted when a crosschain transfer burns tokens. +
+ +
+ Signature: + +{`event CrosschainBurn(address indexed _from, uint256 _amount, address indexed _sender);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when tokens are minted via a cross-chain bridge. +
+ +
+ Signature: + +{`event CrosschainMint(address indexed _to, uint256 _amount, address indexed _sender);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when tokens are transferred between two addresses. +
+ +
+ Signature: + +{`event Transfer(address indexed _from, address indexed _to, uint256 _value);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when the account does not have a specific role. +
+ +
+ Signature: + +error AccessControlUnauthorizedAccount(address _account, bytes32 _role); + +
+
+ + +
+ Signature: + +error ERC20InsufficientBalance(address _from, uint256 _accountBalance, uint256 _value); + +
+
+ +
+ Revert when caller is not a trusted bridge. +
+ +
+ Signature: + +error ERC20InvalidBridgeAccount(address _caller); + +
+
+ +
+ Revert when caller address is invalid. +
+ +
+ Signature: + +error ERC20InvalidCallerAddress(address _caller); + +
+
+ +
+ /// @dev Uses ERC-8042 for storage location standardization and ERC-6093 for error conventions Revert when a provided receiver is invalid(e.g,zero address) . +
+ +
+ Signature: + +error ERC20InvalidReciever(address _receiver); + +
+
+ +
+ Thrown when the sender address is invalid (e.g., zero address). +
+ +
+ Signature: + +error ERC20InvalidSender(address _sender); + +
+
+
+ + + + +## Best Practices + + +- Ensure the caller possesses the `trusted-bridge` role before invoking `crosschainMint` or `crosschainBurn`. +- Always call `checkTokenBridge` to validate the caller's authorization before executing cross-chain operations. +- Verify that the `ERC20_STORAGE_POSITION` is correctly configured in the diamond's storage layout. + + +## Integration Notes + + +This module interacts with diamond storage at the `ERC20_STORAGE_POSITION`, which is deterministically set using `keccak256("compose.erc20")`. Functions like `crosschainMint` and `crosschainBurn` directly modify the ERC20 token balances stored within this shared diamond storage. Changes made via this module are immediately visible to all other facets that access the same storage slot. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC20/ERC20Bridgeable/_category_.json b/website/docs/library/token/ERC20/ERC20Bridgeable/_category_.json new file mode 100644 index 00000000..03768f44 --- /dev/null +++ b/website/docs/library/token/ERC20/ERC20Bridgeable/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "ERC-20 Bridgeable", + "position": 2, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/token/ERC20/ERC20Bridgeable/index" + } +} diff --git a/website/docs/library/token/ERC20/ERC20Bridgeable/index.mdx b/website/docs/library/token/ERC20/ERC20Bridgeable/index.mdx new file mode 100644 index 00000000..9042846b --- /dev/null +++ b/website/docs/library/token/ERC20/ERC20Bridgeable/index.mdx @@ -0,0 +1,29 @@ +--- +title: "ERC-20 Bridgeable" +description: "ERC-20 Bridgeable extension for ERC-20 tokens." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + ERC-20 Bridgeable extension for ERC-20 tokens. + + + + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/token/ERC20/ERC20Permit/ERC20PermitFacet.mdx b/website/docs/library/token/ERC20/ERC20Permit/ERC20PermitFacet.mdx new file mode 100644 index 00000000..72f8b449 --- /dev/null +++ b/website/docs/library/token/ERC20/ERC20Permit/ERC20PermitFacet.mdx @@ -0,0 +1,340 @@ +--- +sidebar_position: 2 +title: "ERC20PermitFacet" +description: "Implements EIP-2612 permit functionality for ERC-20 tokens." +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC20/ERC20Permit/ERC20PermitFacet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Implements EIP-2612 permit functionality for ERC-20 tokens. + + + +- Implements EIP-2612 permit for gasless approvals. +- Exposes `nonces`, `DOMAIN_SEPARATOR`, and `permit` functions. +- Utilizes diamond storage for nonce management. +- Self-contained facet with no external dependencies. + + +## Overview + +This facet implements EIP-2612 permit functionality, allowing token owners to grant allowances via signed messages. It exposes external functions for signature verification and allowance setting, integrating seamlessly with the diamond proxy. Developers add this facet to enable gasless approvals and enhance token usability within a diamond. + +--- + +## Storage + +### ERC20Storage + + +{`struct ERC20Storage { + mapping(address owner => uint256 balance) balanceOf; + uint256 totalSupply; + mapping(address owner => mapping(address spender => uint256 allowance)) allowance; + uint8 decimals; + string name; +}`} + + +--- +### ERC20PermitStorage + + +{`struct ERC20PermitStorage { + mapping(address owner => uint256) nonces; +}`} + + +### State Variables + + + +## Functions + +### nonces + +Returns the current nonce for an owner. This value changes each time a permit is used. + + +{`function nonces(address _owner) external view returns (uint256);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### 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() external view returns (bytes32);`} + + +**Returns:** + + + +--- +### permit + +Sets the allowance for a spender via a signature. This function implements EIP-2612 permit functionality. + + +{`function permit( + address _owner, + address _spender, + uint256 _value, + uint256 _deadline, + uint8 _v, + bytes32 _r, + bytes32 _s +) external;`} + + +**Parameters:** + + + +## Events + + + +
+ Emitted when an approval is made for a spender by an owner. +
+ +
+ Signature: + +{`event Approval(address indexed _owner, address indexed _spender, uint256 _value);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when a permit signature is invalid or expired. +
+ +
+ Signature: + +error ERC2612InvalidSignature( + address _owner, address _spender, uint256 _value, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s +); + +
+
+ +
+ Thrown when the spender address is invalid (e.g., zero address). +
+ +
+ Signature: + +error ERC20InvalidSpender(address _spender); + +
+
+
+ + + + +## Best Practices + + +- Initialize the ERC20PermitMod module and facet during diamond setup. +- Ensure the owner's signature is valid and meets the deadline before calling permit. +- Store the DOMAIN_SEPARATOR value to construct valid permit messages off-chain. + + +## Security Considerations + + +The `permit` function is protected against replay attacks by using nonces and a domain separator. Input validation for signature components (`v`, `r`, `s`) is crucial. Developers must ensure the `deadline` parameter is correctly set to prevent permits from expiring prematurely. Callers must verify the signature off-chain before submitting it to the `permit` function to prevent potential front-running or invalid state changes. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC20/ERC20Permit/ERC20PermitMod.mdx b/website/docs/library/token/ERC20/ERC20Permit/ERC20PermitMod.mdx new file mode 100644 index 00000000..f23d4dd0 --- /dev/null +++ b/website/docs/library/token/ERC20/ERC20Permit/ERC20PermitMod.mdx @@ -0,0 +1,294 @@ +--- +sidebar_position: 1 +title: "ERC20PermitMod" +description: "ERC-2612 permit and domain separator logic" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC20/ERC20Permit/ERC20PermitMod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +ERC-2612 permit and domain separator logic + + + +- Provides internal functions for ERC-2612 permit logic. +- Generates a chain-specific domain separator to prevent replay attacks. +- Utilizes diamond storage for state management. +- No external dependencies or `using` directives within the module itself. + + + +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 ERC-2612 permit validation and domain separator generation. Facets can import this module to handle signature-based approvals, ensuring replay protection through a unique domain separator. It utilizes shared diamond storage for its state. + +--- + +## Storage + +### ERC20PermitStorage + +storage-location: erc8042:compose.erc20.permit + + +{`struct ERC20PermitStorage { + mapping(address owner => uint256) nonces; +}`} + + +--- +### ERC20Storage + +storage-location: erc8042:compose.erc20 + + +{`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 + + + +## 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:** + + + +--- +### 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:** + + + +## Events + + + +
+ Emitted when an approval is made for a spender by an owner. +
+ +
+ Signature: + +{`event Approval(address indexed _owner, address indexed _spender, uint256 _value);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when the spender address is invalid (e.g., zero address). +
+ +
+ Signature: + +error ERC20InvalidSpender(address _spender); + +
+
+ +
+ Thrown when a permit signature is invalid or expired. +
+ +
+ Signature: + +error ERC2612InvalidSignature( +address _owner, address _spender, uint256 _value, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s +); + +
+
+
+ + + + +## Best Practices + + +- Ensure the caller properly constructs and validates the permit signature before passing it to the `permit` function. +- Handle the `ERC2612InvalidSignature` error to gracefully manage invalid signatures. +- Use the `DOMAIN_SEPARATOR` function to correctly generate the domain separator for signing permit requests. + + +## Integration Notes + + +This module interacts with diamond storage at the `ERC20_STORAGE_POSITION` slot, identified by `keccak256("compose.erc20")`. The `permit` function modifies allowance state within the shared ERC20Storage struct, which is implicitly managed by the diamond storage pattern. Changes made via this module are immediately visible to all facets reading from the same storage slot. + + +
+ +
+ + diff --git a/website/docs/library/token/ERC20/ERC20Permit/_category_.json b/website/docs/library/token/ERC20/ERC20Permit/_category_.json new file mode 100644 index 00000000..7932c4df --- /dev/null +++ b/website/docs/library/token/ERC20/ERC20Permit/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "ERC-20 Permit", + "position": 3, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/token/ERC20/ERC20Permit/index" + } +} diff --git a/website/docs/library/token/ERC20/ERC20Permit/index.mdx b/website/docs/library/token/ERC20/ERC20Permit/index.mdx new file mode 100644 index 00000000..1ef49955 --- /dev/null +++ b/website/docs/library/token/ERC20/ERC20Permit/index.mdx @@ -0,0 +1,29 @@ +--- +title: "ERC-20 Permit" +description: "ERC-20 Permit extension for ERC-20 tokens." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + ERC-20 Permit extension for ERC-20 tokens. + + + + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/token/ERC20/_category_.json b/website/docs/library/token/ERC20/_category_.json new file mode 100644 index 00000000..0e078cb1 --- /dev/null +++ b/website/docs/library/token/ERC20/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "ERC-20", + "position": 1, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/token/ERC20/index" + } +} diff --git a/website/docs/library/token/ERC20/index.mdx b/website/docs/library/token/ERC20/index.mdx new file mode 100644 index 00000000..2e3a8827 --- /dev/null +++ b/website/docs/library/token/ERC20/index.mdx @@ -0,0 +1,36 @@ +--- +title: "ERC-20" +description: "ERC-20 fungible token implementations." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + ERC-20 fungible token implementations. + + + + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/token/ERC6909/ERC6909/ERC6909Facet.mdx b/website/docs/library/token/ERC6909/ERC6909/ERC6909Facet.mdx new file mode 100644 index 00000000..ef80ee46 --- /dev/null +++ b/website/docs/library/token/ERC6909/ERC6909/ERC6909Facet.mdx @@ -0,0 +1,537 @@ +--- +sidebar_position: 2 +title: "ERC6909Facet" +description: "ERC-6909 token transfers and approvals" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC6909/ERC6909/ERC6909Facet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +ERC-6909 token transfers and approvals + + + +- Exposes external functions for ERC-6909 token operations within a diamond. +- Manages token balances, allowances, and operator status via diamond storage. +- Self-contained unit with no external dependencies or inheritance. + + +## Overview + +This facet implements ERC-6909 token functionality, including transfers, approvals, and operator management, within a diamond proxy. It provides external functions that route calls through the diamond, accessing shared storage. Developers add this facet to expose token capabilities while preserving diamond upgradeability. + +--- + +## Storage + +### ERC6909Storage + + +{`struct ERC6909Storage { + mapping(address owner => mapping(uint256 id => uint256 amount)) balanceOf; + mapping(address owner => mapping(address spender => mapping(uint256 id => uint256 amount))) allowance; + mapping(address owner => mapping(address spender => bool)) isOperator; +}`} + + +### State Variables + + + +## Functions + +### balanceOf + +Owner balance of an id. + + +{`function balanceOf(address _owner, uint256 _id) external view returns (uint256);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### allowance + +Spender allowance of an id. + + +{`function allowance(address _owner, address _spender, uint256 _id) external view returns (uint256);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### isOperator + +Checks if a spender is approved by an owner as an operator. + + +{`function isOperator(address _owner, address _spender) external view returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### transfer + +Transfers an amount of an id from the caller to a receiver. + + +{`function transfer(address _receiver, uint256 _id, uint256 _amount) external returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### transferFrom + +Transfers an amount of an id from a sender to a receiver. + + +{`function transferFrom(address _sender, address _receiver, uint256 _id, uint256 _amount) external returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### approve + +Approves an amount of an id to a spender. + + +{`function approve(address _spender, uint256 _id, uint256 _amount) external returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### setOperator + +Sets or removes a spender as an operator for the caller. + + +{`function setOperator(address _spender, bool _approved) external returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +## Events + + + + +
+ Signature: + +{`event Transfer( + address _caller, address indexed _sender, address indexed _receiver, uint256 indexed _id, uint256 _amount +);`} + +
+ +
+ + +
+ Signature: + +{`event OperatorSet(address indexed _owner, address indexed _spender, bool _approved);`} + +
+ +
+ + +
+ Signature: + +{`event Approval(address indexed _owner, address indexed _spender, uint256 indexed _id, uint256 _amount);`} + +
+ +
+
+ +## Errors + + + + +
+ Signature: + +error ERC6909InsufficientBalance(address _sender, uint256 _balance, uint256 _needed, uint256 _id); + +
+
+ + +
+ Signature: + +error ERC6909InsufficientAllowance(address _spender, uint256 _allowance, uint256 _needed, uint256 _id); + +
+
+ + +
+ Signature: + +error ERC6909InvalidReceiver(address _receiver); + +
+
+ + +
+ Signature: + +error ERC6909InvalidSender(address _sender); + +
+
+ + +
+ Signature: + +error ERC6909InvalidSpender(address _spender); + +
+
+
+ + + + +## Best Practices + + +- Initialize token state variables within the diamond's setup process. +- Enforce necessary access controls on state-changing functions if required by specific token logic. +- Verify storage compatibility with existing facets before upgrading the diamond. + + +## Security Considerations + + +Functions like `transfer` and `transferFrom` should follow the checks-effects-interactions pattern. Input validation on `_receiver`, `_sender`, `_amount`, and `_id` is critical. Ensure appropriate access controls are implemented if the token logic requires them. Reentrancy guards should be considered for external calls if this facet interacts with other contracts beyond standard token operations. Follow standard Solidity security practices. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC6909/ERC6909/ERC6909Mod.mdx b/website/docs/library/token/ERC6909/ERC6909/ERC6909Mod.mdx new file mode 100644 index 00000000..fedfd264 --- /dev/null +++ b/website/docs/library/token/ERC6909/ERC6909/ERC6909Mod.mdx @@ -0,0 +1,563 @@ +--- +sidebar_position: 1 +title: "ERC6909Mod" +description: "Internal functions for ERC-6909 multi-token logic" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC6909/ERC6909/ERC6909Mod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Internal functions for ERC-6909 multi-token logic + + + +- Provides internal functions for ERC-6909 token operations. +- Utilizes diamond storage pattern via `STORAGE_POSITION` for state management. +- No external dependencies or `using` directives, promoting explicit calls. +- Functions are designed for integration within custom diamond facets. + + + +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 minting, burning, transferring, and approving ERC-6909 tokens. Facets can import and utilize these functions to manage token logic within a diamond, leveraging shared diamond storage for state. Changes to token balances and approvals are immediately visible across all facets interacting with the same storage. + +--- + +## Storage + +### ERC6909Storage + +storage-location: erc8042:compose.erc6909 + + +{`struct ERC6909Storage { + mapping(address owner => mapping(uint256 id => uint256 amount)) balanceOf; + mapping(address owner => mapping(address spender => mapping(uint256 id => uint256 amount))) allowance; + mapping(address owner => mapping(address spender => bool)) isOperator; +}`} + + +### State Variables + + + +## Functions + +### approve + +Approves an amount of an id to a spender. + + +{`function approve(address _owner, address _spender, uint256 _id, uint256 _amount) ;`} + + +**Parameters:** + + + +--- +### burn + +Burns `_amount` of token id `_id` from `_from`. + + +{`function burn(address _from, uint256 _id, uint256 _amount) ;`} + + +**Parameters:** + + + +--- +### getStorage + +Returns a pointer to the ERC-6909 storage struct. Uses inline assembly to access the storage slot defined by STORAGE_POSITION. + + +{`function getStorage() pure returns (ERC6909Storage storage s);`} + + +**Returns:** + + + +--- +### mint + +Mints `_amount` of token id `_id` to `_to`. + + +{`function mint(address _to, uint256 _id, uint256 _amount) ;`} + + +**Parameters:** + + + +--- +### setOperator + +Sets or removes a spender as an operator for the caller. + + +{`function setOperator(address _owner, address _spender, bool _approved) ;`} + + +**Parameters:** + + + +--- +### transfer + +Transfers `_amount` of token id `_id` from `_from` to `_to`. Allowance is not deducted if it is `type(uint256).max` Allowance is not deducted if `_by` is an operator for `_from`. + + +{`function transfer(address _by, address _from, address _to, uint256 _id, uint256 _amount) ;`} + + +**Parameters:** + + + +## Events + + + +
+ Emitted when an approval occurs. +
+ +
+ Signature: + +{`event Approval(address indexed _owner, address indexed _spender, uint256 indexed _id, uint256 _amount);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when an operator is set. +
+ +
+ Signature: + +{`event OperatorSet(address indexed _owner, address indexed _spender, bool _approved);`} + +
+ +
+ Parameters: + +
+
+ +
+ Emitted when a transfer occurs. +
+ +
+ Signature: + +{`event Transfer( +address _caller, address indexed _sender, address indexed _receiver, uint256 indexed _id, uint256 _amount +);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when the spender has insufficient allowance. +
+ +
+ Signature: + +error ERC6909InsufficientAllowance(address _spender, uint256 _allowance, uint256 _needed, uint256 _id); + +
+
+ +
+ Thrown when the sender has insufficient balance. +
+ +
+ Signature: + +error ERC6909InsufficientBalance(address _sender, uint256 _balance, uint256 _needed, uint256 _id); + +
+
+ +
+ Thrown when the approver address is invalid. +
+ +
+ Signature: + +error ERC6909InvalidApprover(address _approver); + +
+
+ +
+ Thrown when the receiver address is invalid. +
+ +
+ Signature: + +error ERC6909InvalidReceiver(address _receiver); + +
+
+ +
+ Thrown when the sender address is invalid. +
+ +
+ Signature: + +error ERC6909InvalidSender(address _sender); + +
+
+ +
+ Thrown when the spender address is invalid. +
+ +
+ Signature: + +error ERC6909InvalidSpender(address _spender); + +
+
+
+ + + + +## Best Practices + + +- Ensure proper access control is implemented by the calling facet before executing any ERC6909Mod functions. +- Handle potential errors like `ERC6909InsufficientBalance`, `ERC6909InsufficientAllowance`, `ERC6909InvalidSender`, and `ERC6909InvalidReceiver`. +- Verify that the diamond storage layout remains compatible, especially when upgrading facets that utilize this module. + + +## Integration Notes + + +This module interacts with diamond storage at the slot identified by `STORAGE_POSITION`, which is defined as `keccak256(\"compose.erc6909\")`. The `getStorage()` function provides access to the `ERC6909Storage` struct. All state modifications made through functions like `mint`, `burn`, `transfer`, and `approve` are persistent and immediately visible to any facet that reads from the same storage position. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC6909/ERC6909/_category_.json b/website/docs/library/token/ERC6909/ERC6909/_category_.json new file mode 100644 index 00000000..d4d084dc --- /dev/null +++ b/website/docs/library/token/ERC6909/ERC6909/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "ERC-6909", + "position": 4, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/token/ERC6909/ERC6909/index" + } +} diff --git a/website/docs/library/token/ERC6909/ERC6909/index.mdx b/website/docs/library/token/ERC6909/ERC6909/index.mdx new file mode 100644 index 00000000..a4eeb825 --- /dev/null +++ b/website/docs/library/token/ERC6909/ERC6909/index.mdx @@ -0,0 +1,29 @@ +--- +title: "ERC-6909" +description: "ERC-6909 minimal multi-token implementations." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + ERC-6909 minimal multi-token implementations. + + + + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/token/ERC6909/_category_.json b/website/docs/library/token/ERC6909/_category_.json new file mode 100644 index 00000000..42f1101f --- /dev/null +++ b/website/docs/library/token/ERC6909/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "ERC-6909", + "position": 4, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/token/ERC6909/index" + } +} diff --git a/website/docs/library/token/ERC6909/index.mdx b/website/docs/library/token/ERC6909/index.mdx new file mode 100644 index 00000000..b91f1e51 --- /dev/null +++ b/website/docs/library/token/ERC6909/index.mdx @@ -0,0 +1,22 @@ +--- +title: "ERC-6909" +description: "ERC-6909 minimal multi-token implementations." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + ERC-6909 minimal multi-token implementations. + + + + } + size="medium" + /> + diff --git a/website/docs/library/token/ERC721/ERC721/ERC721BurnFacet.mdx b/website/docs/library/token/ERC721/ERC721/ERC721BurnFacet.mdx new file mode 100644 index 00000000..cc78dab5 --- /dev/null +++ b/website/docs/library/token/ERC721/ERC721/ERC721BurnFacet.mdx @@ -0,0 +1,224 @@ +--- +sidebar_position: 3 +title: "ERC721BurnFacet" +description: "Burns ERC-721 tokens within a diamond" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC721/ERC721/ERC721BurnFacet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Burns ERC-721 tokens within a diamond + + + +- Exposes an external `burn` function for token destruction. +- Utilizes inline assembly to access diamond storage via `getStorage()`. +- Self-contained, adhering to Compose facet design principles. +- Compatible with ERC-2535 diamond standard. + + +## Overview + +This facet implements ERC-721 token burning functionality for a diamond. It provides an external `burn` function that removes a token from existence, updating internal tracking mechanisms. Developers integrate this facet to offer token destruction capabilities while leveraging the diamond's upgradeability and shared storage. + +--- + +## Storage + +### ERC721Storage + + +{`struct ERC721Storage { + mapping(uint256 tokenId => address owner) ownerOf; + mapping(address owner => uint256 balance) balanceOf; + mapping(address owner => mapping(address operator => bool approved)) isApprovedForAll; + mapping(uint256 tokenId => address approved) approved; +}`} + + +### State Variables + + + +## Functions + +### burn + +Burns (destroys) a token, removing it from enumeration tracking. + + +{`function burn(uint256 _tokenId) external;`} + + +**Parameters:** + + + +## Events + + + + +
+ Signature: + +{`event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);`} + +
+ +
+ + +
+ Signature: + +{`event Approval(address indexed _owner, address indexed _to, uint256 indexed _tokenId);`} + +
+ +
+ + +
+ Signature: + +{`event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);`} + +
+ +
+
+ +## Errors + + + + +
+ Signature: + +error ERC721NonexistentToken(uint256 _tokenId); + +
+
+ + +
+ Signature: + +error ERC721InsufficientApproval(address _operator, uint256 _tokenId); + +
+
+
+ + + + +## Best Practices + + +- Initialize the facet and ensure its functions are correctly routed by the diamond proxy. +- Verify that the caller has the necessary permissions to burn the specified token. +- Ensure the `ERC721Storage` struct is correctly defined and accessible via `getStorage()`. + + +## Security Considerations + + +The `burn` function should be protected by appropriate access control mechanisms within the diamond to prevent unauthorized token destruction. The facet does not perform explicit reentrancy guards; implement these at the diamond level if necessary. Input validation for `_tokenId` is crucial to prevent burning non-existent tokens, which would revert with `ERC721NonexistentToken`. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC721/ERC721/ERC721Facet.mdx b/website/docs/library/token/ERC721/ERC721/ERC721Facet.mdx new file mode 100644 index 00000000..73566ae0 --- /dev/null +++ b/website/docs/library/token/ERC721/ERC721/ERC721Facet.mdx @@ -0,0 +1,646 @@ +--- +sidebar_position: 2 +title: "ERC721Facet" +description: "ERC-721 token management within a diamond" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC721/ERC721/ERC721Facet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +ERC-721 token management within a diamond + + + +- Exposes standard ERC-721 functions for external interaction via the diamond proxy. +- Manages token state using a dedicated storage slot within the diamond storage pattern. +- Self-contained unit with no external dependencies beyond standard Solidity types. +- Supports both basic and safe ERC-721 transfers. + + +## Overview + +This facet implements ERC-721 token functionality, including ownership, transfers, and approvals, as external functions within a diamond proxy. It leverages the diamond storage pattern to manage state and routes calls through the diamond's interface. Developers integrate this facet to provide standard ERC-721 capabilities while maintaining the upgradeability and modularity of the diamond. + +--- + +## Storage + +### ERC721Storage + + +{`struct ERC721Storage { + mapping(uint256 tokenId => address owner) ownerOf; + mapping(address owner => uint256 balance) balanceOf; + mapping(address owner => mapping(address operator => bool approved)) isApprovedForAll; + mapping(uint256 tokenId => address approved) approved; + string name; + string symbol; + string baseURI; +}`} + + +### State Variables + + + +## Functions + +### name + +Returns the token collection name. + + +{`function name() external view returns (string memory);`} + + +**Returns:** + + + +--- +### symbol + +Returns the token collection symbol. + + +{`function symbol() external view returns (string memory);`} + + +**Returns:** + + + +--- +### tokenURI + +Provide the metadata URI for a given token ID. + + +{`function tokenURI(uint256 _tokenId) external view returns (string memory);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### balanceOf + +Returns the number of tokens owned by a given address. + + +{`function balanceOf(address _owner) external view returns (uint256);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### ownerOf + +Returns the owner of a given token ID. + + +{`function ownerOf(uint256 _tokenId) public view returns (address);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### getApproved + +Returns the approved address for a given token ID. + + +{`function getApproved(uint256 _tokenId) external view returns (address);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### isApprovedForAll + +Returns true if an operator is approved to manage all of an owner's assets. + + +{`function isApprovedForAll(address _owner, address _operator) external view returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### approve + +Approves another address to transfer the given token ID. + + +{`function approve(address _to, uint256 _tokenId) external;`} + + +**Parameters:** + + + +--- +### setApprovalForAll + +Approves or revokes permission for an operator to manage all caller's assets. + + +{`function setApprovalForAll(address _operator, bool _approved) external;`} + + +**Parameters:** + + + +--- +### transferFrom + +Transfers a token from one address to another. + + +{`function transferFrom(address _from, address _to, uint256 _tokenId) external;`} + + +**Parameters:** + + + +--- +### safeTransferFrom + +Safely transfers a token, checking if the receiver can handle ERC-721 tokens. + + +{`function safeTransferFrom(address _from, address _to, uint256 _tokenId) external;`} + + +**Parameters:** + + + +--- +### safeTransferFrom + +Safely transfers a token with additional data. + + +{`function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata _data) external;`} + + +**Parameters:** + + + +## Events + + + + +
+ Signature: + +{`event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);`} + +
+ +
+ + +
+ Signature: + +{`event Approval(address indexed _owner, address indexed _to, uint256 indexed _tokenId);`} + +
+ +
+ + +
+ Signature: + +{`event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);`} + +
+ +
+
+ +## Errors + + + + +
+ Signature: + +error ERC721InvalidOwner(address _owner); + +
+
+ + +
+ Signature: + +error ERC721NonexistentToken(uint256 _tokenId); + +
+
+ + +
+ Signature: + +error ERC721IncorrectOwner(address _sender, uint256 _tokenId, address _owner); + +
+
+ + +
+ Signature: + +error ERC721InvalidSender(address _sender); + +
+
+ + +
+ Signature: + +error ERC721InvalidReceiver(address _receiver); + +
+
+ + +
+ Signature: + +error ERC721InsufficientApproval(address _operator, uint256 _tokenId); + +
+
+ + +
+ Signature: + +error ERC721InvalidApprover(address _approver); + +
+
+ + +
+ Signature: + +error ERC721InvalidOperator(address _operator); + +
+
+
+ + + + +## Best Practices + + +- Initialize the `name`, `symbol`, and `baseURI` within the `ERC721Storage` struct during diamond setup. +- Ensure that all state-changing functions (`approve`, `setApprovalForAll`, `transferFrom`, `safeTransferFrom`) are protected by appropriate access controls within the diamond. +- Verify storage compatibility before upgrading to ensure seamless state migration. + + +## Security Considerations + + +All state-changing functions (`approve`, `setApprovalForAll`, `transferFrom`, `safeTransferFrom`) must have access control enforced at the diamond level. Input validation is critical for `_tokenId`, `_owner`, `_to`, and `_operator` parameters to prevent errors like `ERC721NonexistentToken`, `ERC721InvalidOwner`, `ERC721InsufficientApproval`, and `ERC721InvalidApprover`. The `internalTransferFrom` function employs a checks-effects-interactions pattern to mitigate reentrancy risks. Follow standard Solidity security practices for all operations. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC721/ERC721/ERC721Mod.mdx b/website/docs/library/token/ERC721/ERC721/ERC721Mod.mdx new file mode 100644 index 00000000..b24bc767 --- /dev/null +++ b/website/docs/library/token/ERC721/ERC721/ERC721Mod.mdx @@ -0,0 +1,391 @@ +--- +sidebar_position: 1 +title: "ERC721Mod" +description: "Internal logic for ERC-721 token management" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC721/ERC721/ERC721Mod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Internal logic for ERC-721 token management + + + +- Provides `internal` functions for core ERC-721 operations: `mint`, `transferFrom`, `burn`. +- Uses the diamond storage pattern via `keccak256(\"compose.erc721\")` for state management. +- Emits `Transfer` events upon successful token operations. +- Includes custom errors for specific ERC-721 validation failures. + + + +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-721 tokens within a diamond proxy. Facets can import and utilize these functions to implement token minting, transfers, and burning. By leveraging diamond storage, these operations ensure state consistency across all facets interacting with the ERC-721 functionality. + +--- + +## Storage + +### ERC721Storage + + +{`struct ERC721Storage { + mapping(uint256 tokenId => address owner) ownerOf; + mapping(address owner => uint256 balance) balanceOf; + mapping(address owner => mapping(address operator => bool approved)) isApprovedForAll; + mapping(uint256 tokenId => address approved) approved; + string name; + string symbol; + string baseURI; +}`} + + +### State Variables + + + +## Functions + +### burn + +Burns (destroys) a specific ERC-721 token. Reverts if the token does not exist. Clears ownership and approval. + + +{`function burn(uint256 _tokenId) ;`} + + +**Parameters:** + + + +--- +### getStorage + +Returns the ERC-721 storage struct from its predefined slot. Uses inline assembly to access diamond storage location. + + +{`function getStorage() pure returns (ERC721Storage storage s);`} + + +**Returns:** + + + +--- +### mint + +Mints a new ERC-721 token to the specified address. Reverts if the receiver address is zero or if the token already exists. + + +{`function mint(address _to, uint256 _tokenId) ;`} + + +**Parameters:** + + + +--- +### setMetadata + + +{`function setMetadata(string memory _name, string memory _symbol, string memory _baseURI) ;`} + + +**Parameters:** + + + +--- +### transferFrom + +Transfers ownership of a token ID from one address to another. Validates ownership, approval, and receiver address before updating state. + + +{`function transferFrom(address _from, address _to, uint256 _tokenId) ;`} + + +**Parameters:** + + + +## Events + + + +
+ Emitted when ownership of a token changes, including minting and burning. +
+ +
+ Signature: + +{`event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when the sender is not the owner of the token. +
+ +
+ Signature: + +error ERC721IncorrectOwner(address _sender, uint256 _tokenId, address _owner); + +
+
+ +
+ Thrown when an operator lacks sufficient approval to manage a token. +
+ +
+ Signature: + +error ERC721InsufficientApproval(address _operator, uint256 _tokenId); + +
+
+ +
+ Thrown when the receiver address is invalid (e.g., zero address). +
+ +
+ Signature: + +error ERC721InvalidReceiver(address _receiver); + +
+
+ +
+ Thrown when the sender address is invalid (e.g., zero address). +
+ +
+ Signature: + +error ERC721InvalidSender(address _sender); + +
+
+ +
+ Thrown when attempting to interact with a non-existent token. +
+ +
+ Signature: + +error ERC721NonexistentToken(uint256 _tokenId); + +
+
+
+ + + + +## Best Practices + + +- Ensure the `ERC721Mod` instance is correctly initialized to point to the diamond's storage. +- Handle potential errors such as `ERC721NonexistentToken`, `ERC721IncorrectOwner`, and `ERC721InvalidReceiver` returned by module functions. +- Verify storage layout compatibility before upgrading facets that interact with this module. + + +## Integration Notes + + +This module reads and writes to diamond storage at the slot identified by `keccak256(\"compose.erc721\")`. The `getStorage()` function provides access to the `ERC721Storage` struct, which contains fields like `name`, `symbol`, and `baseURI`. Changes made to token state through functions like `mint`, `transferFrom`, and `burn` are immediately reflected in this shared storage, ensuring consistency for all facets operating on the same diamond. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC721/ERC721/_category_.json b/website/docs/library/token/ERC721/ERC721/_category_.json new file mode 100644 index 00000000..219beb4e --- /dev/null +++ b/website/docs/library/token/ERC721/ERC721/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "ERC-721", + "position": 2, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/token/ERC721/ERC721/index" + } +} diff --git a/website/docs/library/token/ERC721/ERC721/index.mdx b/website/docs/library/token/ERC721/ERC721/index.mdx new file mode 100644 index 00000000..88324178 --- /dev/null +++ b/website/docs/library/token/ERC721/ERC721/index.mdx @@ -0,0 +1,36 @@ +--- +title: "ERC-721" +description: "ERC-721 non-fungible token implementations." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + ERC-721 non-fungible token implementations. + + + + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/token/ERC721/ERC721Enumerable/ERC721EnumerableBurnFacet.mdx b/website/docs/library/token/ERC721/ERC721Enumerable/ERC721EnumerableBurnFacet.mdx new file mode 100644 index 00000000..91e72015 --- /dev/null +++ b/website/docs/library/token/ERC721/ERC721Enumerable/ERC721EnumerableBurnFacet.mdx @@ -0,0 +1,197 @@ +--- +sidebar_position: 3 +title: "ERC721EnumerableBurnFacet" +description: "ERC-721Enumerable Burn facet for Compose diamonds" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC721/ERC721Enumerable/ERC721EnumerableBurnFacet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +ERC-721Enumerable Burn facet for Compose diamonds + + + +- Self-contained facet with no imports or inheritance +- Only `external` and `internal` function visibility +- Follows Compose readability-first conventions +- Ready for diamond integration + + +## Overview + +ERC-721Enumerable Burn facet for Compose diamonds + +--- + +## Storage + +### ERC721EnumerableStorage + + +{`struct ERC721EnumerableStorage { + mapping(uint256 tokenId => address owner) ownerOf; + mapping(address owner => uint256[] ownerTokens) ownerTokens; + mapping(uint256 tokenId => uint256 ownerTokensIndex) ownerTokensIndex; + uint256[] allTokens; + mapping(uint256 tokenId => uint256 allTokensIndex) allTokensIndex; + mapping(address owner => mapping(address operator => bool approved)) isApprovedForAll; + mapping(uint256 tokenId => address approved) approved; +}`} + + +### State Variables + + + +## Functions + +### burn + +Burns (destroys) a token, removing it from enumeration tracking. + + +{`function burn(uint256 _tokenId) external;`} + + +**Parameters:** + + + +## Events + + + +
+ Emitted when ownership of a token changes, including burning. +
+ +
+ Signature: + +{`event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when attempting to interact with a non-existent token. +
+ +
+ Signature: + +error ERC721NonexistentToken(uint256 _tokenId); + +
+
+ +
+ Thrown when the caller lacks approval to operate on the token. +
+ +
+ Signature: + +error ERC721InsufficientApproval(address _operator, uint256 _tokenId); + +
+
+
+ +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC721/ERC721Enumerable/ERC721EnumerableFacet.mdx b/website/docs/library/token/ERC721/ERC721Enumerable/ERC721EnumerableFacet.mdx new file mode 100644 index 00000000..be42cb4c --- /dev/null +++ b/website/docs/library/token/ERC721/ERC721Enumerable/ERC721EnumerableFacet.mdx @@ -0,0 +1,719 @@ +--- +sidebar_position: 2 +title: "ERC721EnumerableFacet" +description: "ERC-721 token transfers and metadata within a diamond" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC721/ERC721Enumerable/ERC721EnumerableFacet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +ERC-721 token transfers and metadata within a diamond + + + +- Exposes external functions for ERC-721 standard operations. +- Manages token ownership, transfers, and approvals via diamond storage. +- Supports token metadata retrieval using `tokenURI`. +- Compliant with ERC-721 and ERC-2535 diamond standards. + + +## Overview + +This facet implements ERC-721 token functionality, including transfers, ownership, approvals, and metadata, as external functions within a diamond proxy. It routes calls through the diamond and accesses shared storage for token state. Developers add this facet to expose ERC-721 capabilities while preserving upgradeability and composability. + +--- + +## Storage + +### ERC721EnumerableStorage + + +{`struct ERC721EnumerableStorage { + mapping(uint256 tokenId => address owner) ownerOf; + mapping(address owner => uint256[] ownerTokens) ownerTokens; + mapping(uint256 tokenId => uint256 ownerTokensIndex) ownerTokensIndex; + uint256[] allTokens; + mapping(uint256 tokenId => uint256 allTokensIndex) allTokensIndex; + mapping(address owner => mapping(address operator => bool approved)) isApprovedForAll; + mapping(uint256 tokenId => address approved) approved; + string name; + string symbol; + string baseURI; +}`} + + +### State Variables + + + +## Functions + +### name + +Returns the name of the token collection. + + +{`function name() external view returns (string memory);`} + + +**Returns:** + + + +--- +### symbol + +Returns the symbol of the token collection. + + +{`function symbol() external view returns (string memory);`} + + +**Returns:** + + + +--- +### tokenURI + +Provide the metadata URI for a given token ID. + + +{`function tokenURI(uint256 _tokenId) external view returns (string memory);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### totalSupply + +Returns the total number of tokens in existence. + + +{`function totalSupply() external view returns (uint256);`} + + +**Returns:** + + + +--- +### balanceOf + +Returns the number of tokens owned by an address. + + +{`function balanceOf(address _owner) external view returns (uint256);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### ownerOf + +Returns the owner of a given token ID. + + +{`function ownerOf(uint256 _tokenId) public view returns (address);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### tokenOfOwnerByIndex + +Returns a token ID owned by a given address at a specific index. + + +{`function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### getApproved + +Returns the approved address for a given token ID. + + +{`function getApproved(uint256 _tokenId) external view returns (address);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### isApprovedForAll + +Returns whether an operator is approved for all tokens of an owner. + + +{`function isApprovedForAll(address _owner, address _operator) external view returns (bool);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### approve + +Approves another address to transfer a specific token ID. + + +{`function approve(address _to, uint256 _tokenId) external;`} + + +**Parameters:** + + + +--- +### setApprovalForAll + +Approves or revokes an operator to manage all tokens of the caller. + + +{`function setApprovalForAll(address _operator, bool _approved) external;`} + + +**Parameters:** + + + +--- +### transferFrom + +Transfers a token from one address to another. + + +{`function transferFrom(address _from, address _to, uint256 _tokenId) external;`} + + +**Parameters:** + + + +--- +### safeTransferFrom + +Safely transfers a token, checking for receiver contract compatibility. + + +{`function safeTransferFrom(address _from, address _to, uint256 _tokenId) external;`} + + +**Parameters:** + + + +--- +### safeTransferFrom + +Safely transfers a token with additional data. + + +{`function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata _data) external;`} + + +**Parameters:** + + + +## Events + + + + +
+ Signature: + +{`event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);`} + +
+ +
+ + +
+ Signature: + +{`event Approval(address indexed _owner, address indexed _to, uint256 indexed _tokenId);`} + +
+ +
+ + +
+ Signature: + +{`event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);`} + +
+ +
+
+ +## Errors + + + + +
+ Signature: + +error ERC721InvalidOwner(address _owner); + +
+
+ + +
+ Signature: + +error ERC721NonexistentToken(uint256 _tokenId); + +
+
+ + +
+ Signature: + +error ERC721IncorrectOwner(address _sender, uint256 _tokenId, address _owner); + +
+
+ + +
+ Signature: + +error ERC721InvalidSender(address _sender); + +
+
+ + +
+ Signature: + +error ERC721InvalidReceiver(address _receiver); + +
+
+ + +
+ Signature: + +error ERC721InsufficientApproval(address _operator, uint256 _tokenId); + +
+
+ + +
+ Signature: + +error ERC721InvalidApprover(address _approver); + +
+
+ + +
+ Signature: + +error ERC721InvalidOperator(address _operator); + +
+
+ + +
+ Signature: + +error ERC721OutOfBoundsIndex(address _owner, uint256 _index); + +
+
+
+ + + + +## Best Practices + + +- Initialize the `name`, `symbol`, and `baseURI` in the `ERC721EnumerableStorage` struct during diamond setup. +- Enforce ownership and approval checks within the `transferFrom`, `safeTransferFrom`, and `approve` functions. +- Verify that the `ERC721EnumerableStorage` is compatible before upgrading to a new facet version. + + +## Security Considerations + + +All state-changing functions (`approve`, `setApprovalForAll`, `transferFrom`, `safeTransferFrom`) must be protected by appropriate access control mechanisms, typically enforced by the diamond's access control facet. Input validation is crucial for `_tokenId`, `_owner`, `_to`, and `_operator` parameters to prevent errors like `ERC721NonexistentToken` or `ERC721InvalidReceiver`. The `safeTransferFrom` functions include checks for receiver contract compatibility to mitigate reentrancy risks. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC721/ERC721Enumerable/ERC721EnumerableMod.mdx b/website/docs/library/token/ERC721/ERC721Enumerable/ERC721EnumerableMod.mdx new file mode 100644 index 00000000..e35d86f1 --- /dev/null +++ b/website/docs/library/token/ERC721/ERC721Enumerable/ERC721EnumerableMod.mdx @@ -0,0 +1,392 @@ +--- +sidebar_position: 1 +title: "ERC721EnumerableMod" +description: "Manage ERC-721 tokens with enumeration logic" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/ERC721/ERC721Enumerable/ERC721EnumerableMod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Manage ERC-721 tokens with enumeration logic + + + +- Provides internal functions for ERC-721 minting, burning, and transfers. +- Maintains token enumeration order within diamond storage. +- Uses the diamond storage pattern at a predefined slot (`STORAGE_POSITION`). +- Functions are `internal` and designed for use within custom facets. + + + +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 minting, burning, and transferring ERC-721 tokens while maintaining enumeration order. Facets import this module to implement standard ERC-721 enumerable behavior using shared diamond storage. Changes made through this module are immediately visible to all facets accessing the same storage. + +--- + +## Storage + +### ERC721EnumerableStorage + + +{`struct ERC721EnumerableStorage { + mapping(uint256 tokenId => address owner) ownerOf; + mapping(address owner => uint256[] ownerTokens) ownerTokens; + mapping(uint256 tokenId => uint256 ownerTokensIndex) ownerTokensIndex; + uint256[] allTokens; + mapping(uint256 tokenId => uint256 allTokensIndex) allTokensIndex; + mapping(address owner => mapping(address operator => bool approved)) isApprovedForAll; + mapping(uint256 tokenId => address approved) approved; + string name; + string symbol; + string baseURI; +}`} + + +### State Variables + + + +## Functions + +### burn + +Burns (destroys) an existing ERC-721 token, removing it from enumeration lists. Reverts if the token does not exist or if the sender is not authorized. + + +{`function burn(uint256 _tokenId, address _sender) ;`} + + +**Parameters:** + + + +--- +### getStorage + +Returns the ERC-721 enumerable storage struct from its predefined slot. Uses inline assembly to point to the correct diamond storage position. + + +{`function getStorage() pure returns (ERC721EnumerableStorage storage s);`} + + +**Returns:** + + + +--- +### mint + +Mints a new ERC-721 token to the specified address, adding it to enumeration lists. Reverts if the receiver address is zero or if the token already exists. + + +{`function mint(address _to, uint256 _tokenId) ;`} + + +**Parameters:** + + + +--- +### transferFrom + +Transfers a token ID from one address to another, updating enumeration data. Validates ownership, approval, and receiver address before state updates. + + +{`function transferFrom(address _from, address _to, uint256 _tokenId, address _sender) ;`} + + +**Parameters:** + + + +## Events + + + +
+ Emitted when ownership of a token changes, including minting and burning. +
+ +
+ Signature: + +{`event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);`} + +
+ +
+ Parameters: + +
+
+
+ +## Errors + + + +
+ Thrown when the sender is not the owner of the token. +
+ +
+ Signature: + +error ERC721IncorrectOwner(address _sender, uint256 _tokenId, address _owner); + +
+
+ +
+ Thrown when an operator lacks approval to manage a token. +
+ +
+ Signature: + +error ERC721InsufficientApproval(address _operator, uint256 _tokenId); + +
+
+ +
+ Thrown when the receiver address is invalid. +
+ +
+ Signature: + +error ERC721InvalidReceiver(address _receiver); + +
+
+ +
+ Thrown when the sender address is invalid. +
+ +
+ Signature: + +error ERC721InvalidSender(address _sender); + +
+
+ +
+ Thrown when attempting to interact with a non-existent token. +
+ +
+ Signature: + +error ERC721NonexistentToken(uint256 _tokenId); + +
+
+
+ + + + +## Best Practices + + +- Ensure `msg.sender` or an approved address is passed correctly to `transferFrom` and `burn`. +- Handle potential errors like `ERC721NonexistentToken`, `ERC721IncorrectOwner`, and `ERC721InvalidReceiver`. +- Verify that the `_to` address in `mint` is not the zero address. + + +## Integration Notes + + +This module utilizes the diamond storage pattern, accessing its state at the slot identified by `keccak256(\"compose.erc721.enumerable\")`. All state modifications, such as minting or burning, are written directly to this shared storage location. Consequently, any facet that imports and interacts with the same storage slot will observe these changes immediately, ensuring consistent state across the diamond. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/ERC721/ERC721Enumerable/_category_.json b/website/docs/library/token/ERC721/ERC721Enumerable/_category_.json new file mode 100644 index 00000000..fdc633f9 --- /dev/null +++ b/website/docs/library/token/ERC721/ERC721Enumerable/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "ERC-721 Enumerable", + "position": 2, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/token/ERC721/ERC721Enumerable/index" + } +} diff --git a/website/docs/library/token/ERC721/ERC721Enumerable/index.mdx b/website/docs/library/token/ERC721/ERC721Enumerable/index.mdx new file mode 100644 index 00000000..eb0232c7 --- /dev/null +++ b/website/docs/library/token/ERC721/ERC721Enumerable/index.mdx @@ -0,0 +1,36 @@ +--- +title: "ERC-721 Enumerable" +description: "ERC-721 Enumerable extension for ERC-721 tokens." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + ERC-721 Enumerable extension for ERC-721 tokens. + + + + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/token/ERC721/_category_.json b/website/docs/library/token/ERC721/_category_.json new file mode 100644 index 00000000..8ee4f288 --- /dev/null +++ b/website/docs/library/token/ERC721/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "ERC-721", + "position": 2, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/token/ERC721/index" + } +} diff --git a/website/docs/library/token/ERC721/index.mdx b/website/docs/library/token/ERC721/index.mdx new file mode 100644 index 00000000..e3dc8b77 --- /dev/null +++ b/website/docs/library/token/ERC721/index.mdx @@ -0,0 +1,29 @@ +--- +title: "ERC-721" +description: "ERC-721 non-fungible token implementations." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + ERC-721 non-fungible token implementations. + + + + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/token/Royalty/RoyaltyFacet.mdx b/website/docs/library/token/Royalty/RoyaltyFacet.mdx new file mode 100644 index 00000000..33723763 --- /dev/null +++ b/website/docs/library/token/Royalty/RoyaltyFacet.mdx @@ -0,0 +1,207 @@ +--- +sidebar_position: 2 +title: "RoyaltyFacet" +description: "Returns royalty information for tokens" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/Royalty/RoyaltyFacet.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Returns royalty information for tokens + + + +- Implements ERC-2981 royalty standard. +- Provides a single external function for royalty information retrieval. +- Accesses royalty data from diamond storage. +- Compatible with ERC-2535 diamond standard. + + +## Overview + +This facet implements ERC-2981 royalty information retrieval within a diamond. It provides an external function to query royalty details for a specific token and sale price, falling back to default royalty settings when necessary. Developers add this facet to integrate royalty standards into their diamond proxy. + +--- + +## Storage + +### RoyaltyInfo + + +{`struct RoyaltyInfo { + address receiver; + uint96 royaltyFraction; +}`} + + +--- +### RoyaltyStorage + + +{`struct RoyaltyStorage { + RoyaltyInfo defaultRoyaltyInfo; + mapping(uint256 tokenId => RoyaltyInfo) tokenRoyaltyInfo; +}`} + + +### State Variables + + + +## Functions + +### royaltyInfo + +Returns royalty information for a given token and sale price. Returns token-specific royalty if set, otherwise falls back to default royalty. Royalty amount is calculated as a percentage of the sale price using basis points. Implements the ERC-2981 royaltyInfo function. + + +{`function royaltyInfo(uint256 _tokenId, uint256 _salePrice) + external + view + returns (address receiver, uint256 royaltyAmount);`} + + +**Parameters:** + + + +**Returns:** + + + + + + +## Best Practices + + +- Integrate the `RoyaltyFacet` into your diamond during deployment. +- Ensure the `RoyaltyFacet` is properly configured with default royalty information if applicable. +- Call the `royaltyInfo` function through the diamond proxy address to retrieve royalty details. + + +## Security Considerations + + +The `royaltyInfo` function is a view function and does not modify state. Input validation for `_tokenId` and `_salePrice` should be handled by the caller or the diamond proxy if specific constraints are required. Follow standard Solidity security practices for token and price handling. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/Royalty/RoyaltyMod.mdx b/website/docs/library/token/Royalty/RoyaltyMod.mdx new file mode 100644 index 00000000..0b2c33f8 --- /dev/null +++ b/website/docs/library/token/Royalty/RoyaltyMod.mdx @@ -0,0 +1,381 @@ +--- +sidebar_position: 1 +title: "RoyaltyMod" +description: "Manages ERC-2981 royalty information for NFTs" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/token/Royalty/RoyaltyMod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Manages ERC-2981 royalty information for NFTs + + + +- Implements ERC-2981 royalty standard logic. +- Manages default and token-specific royalty information. +- Uses diamond storage for shared state. +- Provides internal functions for facet integration. + + + +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-2981 royalty details. Facets can set, retrieve, and clear default and token-specific royalties using shared diamond storage. This enables consistent royalty enforcement across different facets within a diamond. + +--- + +## Storage + +### RoyaltyInfo + +Structure containing royalty information. **Properties** + + +{`struct RoyaltyInfo { + address receiver; + uint96 royaltyFraction; +}`} + + +--- +### RoyaltyStorage + +storage-location: erc8042:compose.erc2981 + + +{`struct RoyaltyStorage { + RoyaltyInfo defaultRoyaltyInfo; + mapping(uint256 tokenId => RoyaltyInfo) tokenRoyaltyInfo; +}`} + + +### State Variables + + + +## Functions + +### deleteDefaultRoyalty + +Removes default royalty information. After calling this function, royaltyInfo will return (address(0), 0) for tokens without specific royalty. + + +{`function deleteDefaultRoyalty() ;`} + + +--- +### getStorage + +Returns the royalty storage struct from its predefined slot. Uses inline assembly to access diamond storage location. + + +{`function getStorage() pure returns (RoyaltyStorage storage s);`} + + +**Returns:** + + + +--- +### resetTokenRoyalty + +Resets royalty information for a specific token to use the default setting. Clears token-specific royalty storage, causing fallback to default royalty. + + +{`function resetTokenRoyalty(uint256 _tokenId) ;`} + + +**Parameters:** + + + +--- +### royaltyInfo + +Queries royalty information for a given token and sale price. Returns token-specific royalty or falls back to default royalty. Royalty amount is calculated as a percentage of the sale price using basis points. Implements the ERC-2981 royaltyInfo function logic. + + +{`function royaltyInfo(uint256 _tokenId, uint256 _salePrice) view returns (address receiver, uint256 royaltyAmount);`} + + +**Parameters:** + + + +**Returns:** + + + +--- +### setDefaultRoyalty + +Sets the default royalty information that applies to all tokens. Validates receiver and fee, then updates default royalty storage. + + +{`function setDefaultRoyalty(address _receiver, uint96 _feeNumerator) ;`} + + +**Parameters:** + + + +--- +### setTokenRoyalty + +Sets royalty information for a specific token, overriding the default. Validates receiver and fee, then updates token-specific royalty storage. + + +{`function setTokenRoyalty(uint256 _tokenId, address _receiver, uint96 _feeNumerator) ;`} + + +**Parameters:** + + + +## Errors + + + +
+ Thrown when default royalty fee exceeds 100% (10000 basis points). +
+ +
+ Signature: + +error ERC2981InvalidDefaultRoyalty(uint256 _numerator, uint256 _denominator); + +
+
+ +
+ Thrown when default royalty receiver is the zero address. +
+ +
+ Signature: + +error ERC2981InvalidDefaultRoyaltyReceiver(address _receiver); + +
+
+ +
+ Thrown when token-specific royalty fee exceeds 100% (10000 basis points). +
+ +
+ Signature: + +error ERC2981InvalidTokenRoyalty(uint256 _tokenId, uint256 _numerator, uint256 _denominator); + +
+
+ +
+ Thrown when token-specific royalty receiver is the zero address. +
+ +
+ Signature: + +error ERC2981InvalidTokenRoyaltyReceiver(uint256 _tokenId, address _receiver); + +
+
+
+ + + + +## Best Practices + + +- Ensure proper validation of receiver addresses and fee numerators before setting royalties. +- Call `resetTokenRoyalty` to revert token-specific royalties to the default. +- Use `deleteDefaultRoyalty` only when no default royalty should be applied. + + +## Integration Notes + + +This module utilizes diamond storage at the `STORAGE_POSITION` defined by `keccak256(\"compose.erc2981\")`. The `RoyaltyStorage` struct, containing `defaultRoyaltyInfo`, is accessed and modified through internal functions. Changes made via `setDefaultRoyalty` and `setTokenRoyalty` are immediately reflected for all facets querying `royaltyInfo` due to the shared storage pattern. + + +
+ +
+ +
+ +
+ + diff --git a/website/docs/library/token/Royalty/_category_.json b/website/docs/library/token/Royalty/_category_.json new file mode 100644 index 00000000..cb6b460f --- /dev/null +++ b/website/docs/library/token/Royalty/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Royalty", + "position": 5, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/token/Royalty/index" + } +} diff --git a/website/docs/library/token/Royalty/index.mdx b/website/docs/library/token/Royalty/index.mdx new file mode 100644 index 00000000..7e1c8a5e --- /dev/null +++ b/website/docs/library/token/Royalty/index.mdx @@ -0,0 +1,29 @@ +--- +title: "Royalty" +description: "ERC-2981 royalty standard implementations." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + ERC-2981 royalty standard implementations. + + + + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/token/_category_.json b/website/docs/library/token/_category_.json new file mode 100644 index 00000000..3f26c2ce --- /dev/null +++ b/website/docs/library/token/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Token Standards", + "position": 3, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/token/index" + } +} diff --git a/website/docs/library/token/index.mdx b/website/docs/library/token/index.mdx new file mode 100644 index 00000000..e18f1fe8 --- /dev/null +++ b/website/docs/library/token/index.mdx @@ -0,0 +1,50 @@ +--- +title: "Token Standards" +description: "Token standard implementations for Compose diamonds." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + Token standard implementations for Compose diamonds. + + + + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + } + size="medium" + /> + diff --git a/website/docs/library/utils/NonReentrancyMod.mdx b/website/docs/library/utils/NonReentrancyMod.mdx new file mode 100644 index 00000000..6e6b6558 --- /dev/null +++ b/website/docs/library/utils/NonReentrancyMod.mdx @@ -0,0 +1,154 @@ +--- +sidebar_position: 1 +title: "NonReentrancyMod" +description: "Prevents reentrant calls within a diamond" +gitSource: "https://github.com/Perfect-Abstractions/Compose/tree/main/src/libraries/NonReentrancyMod.sol" +--- + +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Badge from '@site/src/components/ui/Badge'; +import Callout from '@site/src/components/ui/Callout'; +import CalloutBox from '@site/src/components/ui/CalloutBox'; +import Accordion, { AccordionGroup } from '@site/src/components/ui/Accordion'; +import PropertyTable from '@site/src/components/api/PropertyTable'; +import ExpandableCode from '@site/src/components/code/ExpandableCode'; +import CodeShowcase from '@site/src/components/code/CodeShowcase'; +import RelatedDocs from '@site/src/components/docs/RelatedDocs'; +import WasThisHelpful from '@site/src/components/docs/WasThisHelpful'; +import LastUpdated from '@site/src/components/docs/LastUpdated'; +import ReadingTime from '@site/src/components/docs/ReadingTime'; +import GradientText from '@site/src/components/ui/GradientText'; +import GradientButton from '@site/src/components/ui/GradientButton'; + + +Prevents reentrant calls within a diamond + + + +- Provides `enter()` and `exit()` internal functions. +- Protects against reentrant function calls. +- Uses a simple guard mechanism. +- Reverts with a custom `Reentrancy()` error upon detection. + + + +This module provides internal functions for use in your custom facets. Import it to access shared logic and storage. + + +## Overview + +This library provides internal functions to prevent reentrant calls within diamond facets. By using `enter` and `exit`, facets can ensure that a function execution is not interrupted by another call to the same function or another protected function within the same execution context. This guards against reentrancy attacks and ensures predictable state transitions. + +--- + +## Storage + +### State Variables + + + +## Functions + +### enter + +How to use as a library in user facets How to use as a modifier in user facets This unlocks the entry into a function + + +{`function enter() ;`} + + +--- +### exit + +This locks the entry into a function + + +{`function exit() ;`} + + +## Errors + + + +
+ Function selector - 0x43a0d067 +
+ +
+ Signature: + +error Reentrancy(); + +
+
+
+ + + + +## Best Practices + + +- Call `enter()` at the beginning of a function to prevent reentrancy. +- Call `exit()` at the end of a function to allow subsequent calls. +- Ensure `exit()` is always called, even in error paths if `enter()` succeeded, to prevent permanent locking (though `enter()` reverts on reentrancy, making this less critical for basic usage). +- Use custom errors for clarity and gas efficiency when handling reentrancy detection. + + +## Integration Notes + + +This library does not directly interact with diamond storage. It manages its state internally within the facet that imports and uses it. The `_nonReentrancyGuard` variable is typically declared as `internal` within the facet. Changes to this guard state are local to the calling facet's execution context and do not affect other facets or the diamond's shared storage. + + +
+ +
+ + diff --git a/website/docs/library/utils/_category_.json b/website/docs/library/utils/_category_.json new file mode 100644 index 00000000..d9c087be --- /dev/null +++ b/website/docs/library/utils/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Utilities", + "position": 4, + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "library/utils/index" + } +} diff --git a/website/docs/library/utils/index.mdx b/website/docs/library/utils/index.mdx new file mode 100644 index 00000000..68e2c8ec --- /dev/null +++ b/website/docs/library/utils/index.mdx @@ -0,0 +1,22 @@ +--- +title: "Utilities" +description: "Utility libraries and helpers for diamond development." +--- + +import DocCard, { DocCardGrid } from '@site/src/components/docs/DocCard'; +import DocSubtitle from '@site/src/components/docs/DocSubtitle'; +import Icon from '@site/src/components/ui/Icon'; + + + Utility libraries and helpers for diamond development. + + + + } + size="medium" + /> +