You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A developer writes a **_Core_** smart contract as the foundation that can be customized by adding new parts and updating or removing these parts over time. These ‘parts’ are **_Extension_** smart contracts which any third-party developer can independently develop with reference to the **_Core_** smart contract as the known foundation to build around.
15
+
16
+
Both `/core` and `/extension` directories are their own forge projects where we develop the Core API of the architecture independently from the Extensions that use this Core API as a dependency.
17
+
18
+
# Install and Use
19
+
20
+
This project can currently be installed as a dependency in [foundry](https://book.getfoundry.sh/) projects. To install, run:
If you are in the root directory of the project, run:
40
60
41
61
```bash
42
-
# Install dependecies for hooks contracts
43
-
forge install
62
+
# Install dependecies for core contracts
63
+
forge install --root ./core
64
+
65
+
# Install dependecies for extension contracts
66
+
forge install --root ./extension
44
67
```
45
68
46
-
From within `/contracts`, run benchmark comparison tests:
69
+
<!--From within `/contracts`, run benchmark comparison tests:
47
70
48
71
```bash
49
72
# create a wallet for the benchmark (make sure there's enough gas funds)
@@ -57,103 +80,16 @@ From within `/contracts`, run gas snapshot:
57
80
58
81
```bash
59
82
forge snapshot --isolate --mp 'test/benchmark/*'
60
-
```
61
-
62
-
## Usage
63
-
64
-
You can find testnet deployments of this hooks design setup, and JS scripts to interact with an ERC-721 core contract and its hooks here: https://github.com/thirdweb-dev/contracts-next-scripts
65
-
66
-
# Benchmarks
67
-
68
-
### ERC-721 Core Benchmarks via transactions on Goerli
| Mint 1 token (token ID `0`) | 145_373 |[ref](https://goerli.etherscan.io/tx/0x1de1431200f6d39e9f4ddba3386e413078308a6eae1ebcc722884443b643d7d0)|
73
-
| Mint 1 token (token ID `>0`) | 116_173 |[ref](https://goerli.etherscan.io/tx/0xc38e82228a1f8cf877abfeeb28e3f294bb38b90f51cbb2df1c899f03fad4e355)|
74
-
| Mint 10 tokens (including token ID `0`) | 365_414 |[ref](https://goerli.etherscan.io/tx/0x1e8a79bd1806a3410a46f8d0ec0fcff099e3aeff6d4e64815c1f400ab092c77e)|
75
-
| Mint 10 tokens (not including token ID `0`) | 331_214 |[ref](https://goerli.etherscan.io/tx/0xe4ab2650f8827d52d2ec15956da910915b2b08f67d3f59ac8091da2fbd0369a0)|
76
-
| Transfer token | 64_389 |[ref](https://goerli.etherscan.io/tx/0x3ca2c4c74d6c8a4859fd78af5091c4dc4dc0fc0452202b18b611e4f0308c3673)|
- 'Minting tokens' benchmarks use the `AllowlistMintHook` contract as the `beforeMint` hook. All token minting benchmarks include distributing non-zero primary sale value and platform fee.
85
-
- All hooks used in these benchmarks are minimal clone proxy contracts pointing to hook contract implementations.
86
-
87
-
### ERC-721 Contracts Benchmarks Comparison via transactions on Sepolia
The _Hooks architecture_ contains two types of smart contracts:
99
-
100
-
1.**Core contract**
101
-
102
-
A minimal, non-upgradeable smart contract that contains functions and state/storage that are core to the contract’s identity.
103
-
104
-
2.**_Hook_ contract**
105
-
106
-
A stateful, upgradeable or non-upgradeable smart contract meant to be _installed_ into a core contract. It contains fixed number of pre-defined hook functions that are called during the execution of a core contract’s functions.
The goal of this _Hooks architecture_ is making upgradeability **_safer_**, **_more predictable and less likely to go wrong_** by giving developers:
111
-
112
-
- An API that contains a comprehensive, but fixed number of pre-defined points in a smart contract where developers can introduce customizations.
113
-
- Separation of state and logic that’s core to their contract, from state and logic that is ancillary i.e. providing assistance in updating the core state of the contract. (Core vs. Hook)
114
-
115
-
Core contracts are always non-upgradeable. However, considering a core contract and its _hooks_ together as one system — the _Hooks architecture_ allows for 3 different kinds of upgradeability setups:
116
-
117
-
-**Non-upgradeable**: Developer contracts are not upgradeable.
118
-
-**Self-managed upgradeable:** Only the developer is authorized to upgrade their (hook) contracts.
119
-
-**Managed upgradeable:** Developer authorizes a third party to upgrade their (hook) contracts.
120
-
121
-
## Token contracts in the Hooks architecture
122
-
123
-
We write one core contract implementation for each token type (ERC-20, ERC-721, ERC-1155). Developers deploy a token core contract for themselves and _install_ hooks into it.
124
-
125
-
All 3 token core contracts implement:
126
-
127
-
- The token standard itself. ([ERC-20](https://eips.ethereum.org/EIPS/eip-20) + [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612) Permit / [ERC-721](https://eips.ethereum.org/EIPS/eip-721) / [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155)).
128
-
-[HookInstaller](https://github.com/thirdweb-dev/contracts-next/blob/main/src/core/src/interface/IHookInstaller.sol) interface for installing hooks.
129
-
- A token standard specific `getAllHooks()` view function interface (e.g. [IERC20HookInstaller](https://github.com/thirdweb-dev/contracts-next/blob/main/src/core/src/interface/IERC20HookInstaller.sol))
130
-
-[EIP-173](https://eips.ethereum.org/EIPS/eip-173) Contract ownership standard
131
-
-[EIP-7572](https://eips.ethereum.org/EIPS/eip-7572) Contract-level metadata via `contractURI()` standard
132
-
- Multicall interface
133
-
- External mint() and burn() functions.
134
-
135
-
The token core contracts use the [solady implementations](https://github.com/Vectorized/solady) of the token standards, ownable and multicall contracts.
| beforeApprove (Approve) | ✅ called before a token is approved in the `ERC20Core.approve` call. | ✅ called before a token is approved in the `ERC721Core.approve` and `ERC721.setApprovalForAll` calls. | ✅ called before a token is approved in the `ERC1155.setApprovalForAll` call. |
142
-
| beforeBurn (Burn) | ✅ called before a token is burned in the `ERC20.burn` call. | ✅ called before a token is burned in the `ERC721.burn` call. | ✅ called before a token is burned in the `ERC1155.burn` call. |
143
-
| beforeMint (Minting) | ✅ called before a token is minted in the `ERC20Core.mint`| ✅ called before a token is minted in the `ERC721Core.mint`| ✅ called before a token is minted in the `ERC1155Core.mint`|
144
-
| beforeTransfer (Transfer) | ✅ called before a token is transferred in the `ERC20.transferFrom` call. | ✅ called before a token is transferred in the `ERC721.transferFrom` and `ERC721.safeTransferFrom` calls. | ✅ called before a token is transferred in the `ERC1155.transferFrom` and `ERC1155.safeTransferFrom` calls. |
145
-
| beforeBatchTransfer (Batch Transfer) | ❌ | ❌ | ✅ called once before a batch transfer of tokens in the `ERC1155.safeBatchTransferredFrom` call. |
146
-
| onRoyaltyInfo (EIP-2981 Royalty) | ❌ | ✅ Called to retrieve royalty info on `EIP2981.royaltyInfo` call | ✅ Called to retrieve royalty info on `EIP2981.royaltyInfo` call |
147
-
| onTokenURI (Token Metadata) | ❌ | ✅ Called to retrieve the metadata for a token on an `ERC721Metadata.tokenURI` call | ✅ Called to retrieve the metadata URI for a token on a `ERC1155Metadata.uri` call |
83
+
``` -->
148
84
149
-
##Feedback
85
+
# Feedback
150
86
151
87
If you have any feedback, please create an issue or reach out to us at [email protected].
0 commit comments