Next iteration of thirdweb smart contracts. Install hooks in core contracts.
📣 Call for feedback: These contracts are NOT AUDITED. This design update is WIP and we encourage opening an issue with feedback.
Clone the repo:
git clone https://github.com/thirdweb-dev/contracts-next.git
Install dependencies:
forge install && yarn
Run benchmark comparison tests:
forge test --mc Thirdweb # or Manifold / Zora
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
Action | Gas consumption | Transaction |
---|---|---|
Mint 1 token (token ID 0 ) |
145_373 | ref |
Mint 1 token (token ID >0 ) |
116_173 | ref |
Mint 10 tokens (including token ID 0 ) |
365_414 | ref |
Mint 10 tokens (not including token ID 0 ) |
331_214 | ref |
Transfer token | 64_389 | ref |
Install 1 hook | 105_455 | ref |
Install 5 hooks | 191_918 | ref |
Uninstall 1 hook | 43_468 | ref |
Uninstall 5 hooks | 57_839 | ref |
Note:
- 'Minting tokens' benchmarks use the
AllowlistMintHook
contract as thebeforeMint
hook. All token minting benchmarks include distributing non-zero primary sale value and platform fee. - All hooks used in these benchmarks are minimal clone proxy contracts pointing to hook contract implementations.
Action | Thirdweb (Hooks) | Thirdweb Drop | Zora | Manifold |
---|---|---|---|---|
Deploy (developer-facing) | 213_434 tx | 719_842 tx | 499_968 tx | 232_917 tx |
Claim 1 token | 149_142 tx | 196_540 tx | 160_447 tx | 184_006 tx |
Transfer token | 59_587 tx | 76_102 tx | 71_362 tx | 69_042 tx |
Setup token metadata | 60_217 tx | 47_528 tx | 54_612 tx | 29_789 tx |
Developers deploy non-upgradeable minimal clones of token core contracts e.g. the ERC-721 Core contract.
- This contract is initializable, and meant to be used with proxy contracts.
- Implements the token standard (and the respective token metadata standard).
- Uses the role based permission model of the
Permission
contract. - Implements the
HookInstaller
interface.
Core contracts are deliberately written as non-upgradeable foundations that contain minimal code with fixed behaviour. These contracts are meant to be extended by developers using hooks.
Hooks are an external call made to a contract that implements the IHook
interface.
The purpose of hooks is to allow developers to extend their contract's functionality by running custom logic right before a token is minted, transferred, burned, or approved, or for returning a token's metadata or royalty info.
For example, there is a fixed, defined set of 6 ERC-721 hooks:
- BeforeMint: called before a token is minted in the ERC721Core.mint call.
- BeforeTransfer: called before a token is transferred in the ERC721.transferFrom call.
- BeforeBurn: called before a token is burned in the ERC721.burn call.
- BeforeApprove: called before the ERC721.approve and ERC721.setApprovalForAll call.
- Token URI: called when the ERC721Metadata.tokenURI function is called.
- Royalty: called when the ERC2981.royaltyInfo function is called.
Developers can install hooks into their core contracts, and uninstall hooks at any time. On installation, a hook contract tells the hook consumer which hook functions it implements -- the hook consumer maps all these hook functions to the mentioned hook contract as their implemention.
thirdweb will publish upgradeable, 'shared state' hooks for developers (see src/hooks).
These hook contracts are designed to be used by developers as a shared resource, and are upgradeable by thirdweb. This allows thirdweb to make beacon upgrades to developer contracts using these hooks.
At any point, developers can opt to use any custom, non-thirdweb hooks along with their core contract. Without the involvement on delegateCall based upgradeability, writing hooks should be accessible for more developers, and we expect to form a vibrant hooks ecosystem.
That said, opting out of using hooks where thirdweb has upgrade authority also means that thirdweb will not be able to perform beacon upgrades to those hooks in the event of a security incident.
If you have any feedback, please create an issue or reach out to us at [email protected].