Skip to content

Commit b26eeba

Browse files
committed
Improved docs
1 parent 4071d15 commit b26eeba

File tree

3 files changed

+123
-7
lines changed

3 files changed

+123
-7
lines changed

website/docs/design/banned-solidity-features.mdx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,10 @@ function approve(address _spender, uint256 _value) public {
9494

9595
</Accordion>
9696

97-
<Accordion title="No external functions in Solidity libraries">
98-
99-
All Solidity module functions must be declared `internal`.
97+
<Accordion title="No Solidity libraries">
10098

10199
```solidity title="🚫 Not allowed"
102-
function transfer() external {
100+
library MyLib {
103101
...
104102
}
105103
```

website/docs/foundations/custom-facets.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ You can add your own `GameNFTFacet` that extends functionality while still shari
1818
/**
1919
* Your custom facet integrates with Compose using Modules
2020
*/
21-
import {ERC721Mod} from "compose/ERC721Mod.sol";
21+
import "compose/ERC721Mod" as ERC721Mod;
2222

2323
contract GameNFTFacet {
2424
function mintWithGameLogic(address player, uint256 tokenId) external {

website/docs/foundations/solidity-modules.mdx

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,124 @@ Compose uses clear naming patterns to distinguish Solidity file types:
2929
- Files ending in **`Diamond.sol`** (e.g., `ExampleDiamond.sol`) implement diamond contracts.
3030
- Files ending in **`Mod`** (e.g., `ERC20Mod.sol`) are **Solidity modules** — intended to be imported and used within facets or diamond contracts.
3131

32-
**Exception:**
33-
`DiamondMod.sol` is a **module**, not a diamond contract. It provides core diamond functionality that diamond contracts import.
32+
### Example Solidity Module
33+
34+
Here is an example of a Solidity module that implements contract ownership functionality:
35+
36+
```solidity
37+
// SPDX-License-Identifier: MIT
38+
pragma solidity >=0.8.30;
39+
40+
/*
41+
* @title ERC-173 Contract Ownership
42+
* @notice Provides internal functions and storage for owner management.
43+
*/
44+
45+
/**
46+
* @dev This emits when ownership of a contract changes.
47+
*/
48+
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
49+
50+
/*
51+
* @notice Thrown when a non-owner attempts an action restricted to owner.
52+
*/
53+
error OwnerUnauthorizedAccount();
54+
55+
bytes32 constant STORAGE_POSITION = keccak256("compose.owner");
56+
57+
/**
58+
* @custom:storage-location erc8042:compose.owner
59+
*/
60+
struct OwnerStorage {
61+
address owner;
62+
}
63+
64+
/**
65+
* @notice Returns a pointer to the ERC-173 storage struct.
66+
* @dev Uses inline assembly to access the storage slot defined by STORAGE_POSITION.
67+
* @return s The OwnerStorage struct in storage.
68+
*/
69+
function getStorage() pure returns (OwnerStorage storage s) {
70+
bytes32 position = STORAGE_POSITION;
71+
assembly {
72+
s.slot := position
73+
}
74+
}
75+
76+
function setContractOwner(address _initialOwner) {
77+
OwnerStorage storage s = getStorage();
78+
s.owner = _initialOwner;
79+
emit OwnershipTransferred(address(0), _initialOwner);
80+
}
81+
82+
83+
/**
84+
* @notice Reverts if the caller is not the owner.
85+
*/
86+
function requireOwner() view {
87+
if (getStorage().owner != msg.sender) {
88+
revert OwnerUnauthorizedAccount();
89+
}
90+
}
91+
```
92+
93+
Here is an example of a diamond contract that uses Solidity modules to implement ERC-2535 Diamonds:
94+
95+
```solidity
96+
// SPDX-License-Identifier: MIT
97+
pragma solidity >=0.8.30;
98+
99+
import "../DiamondMod.sol" as DiamondMod;
100+
import "../../access/Owner/OwnerMod.sol" as OwnerMod;
101+
import "../../token/ERC721/ERC721/ERC721Mod.sol" as ERC721Mod;
102+
import "../../interfaceDetection/ERC165/ERC165Mod.sol" as ERC165Mod;
103+
import {IERC721} from "../../interfaces/IERC721.sol";
104+
import {IERC721Metadata} from "../../interfaces/IERC721Metadata.sol";
105+
106+
contract ExampleDiamond {
107+
/**
108+
* @notice Struct to hold facet address and its function selectors.
109+
* struct FacetCut {
110+
* address facetAddress;
111+
* FacetCutAction action; // Add=0, Replace=1, Remove=2
112+
* bytes4[] functionSelectors;
113+
* }
114+
*/
115+
/**
116+
* @notice Initializes the diamond contract with facets, owner and other data.
117+
* @dev Adds all provided facets to the diamond's function selector mapping and sets the contract owner.
118+
* Each facet in the array will have its function selectors registered to enable delegatecall routing.
119+
* @param _facets Array of facet addresses and their corresponding function selectors to add to the diamond.
120+
* @param _diamondOwner Address that will be set as the owner of the diamond contract.
121+
*/
122+
constructor(DiamondMod.FacetCut[] memory _facets, address _diamondOwner) {
123+
DiamondMod.addFacets(_facets);
124+
125+
/*************************************
126+
* Initialize storage variables
127+
************************************/
128+
129+
/**
130+
* Setting the contract owner
131+
*/
132+
OwnerMod.setContractOwner(_diamondOwner);
133+
/**
134+
* Setting ERC721 token details
135+
*/
136+
ERC721Mod.setMetadata({_name: "ExampleDiamondNFT", _symbol: "EDN", _baseURI: "https://example.com/metadata/"});
137+
/**
138+
* Registering ERC165 interfaces
139+
*/
140+
ERC165Mod.registerInterface(type(IERC721).interfaceId);
141+
ERC165Mod.registerInterface(type(IERC721Metadata).interfaceId);
142+
}
143+
144+
fallback() external payable {
145+
DiamondMod.diamondFallback();
146+
}
147+
148+
receive() external payable {}
149+
}
150+
```
151+
34152

0 commit comments

Comments
 (0)