Skip to content

Commit 3915759

Browse files
authored
refactor(world): add default-reverting methods to Module (#3581)
1 parent b790181 commit 3915759

17 files changed

Lines changed: 94 additions & 75 deletions

File tree

.changeset/clean-apricots-hide.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@latticexyz/world-module-callwithsignature": patch
3+
"@latticexyz/world-module-erc20": patch
4+
"@latticexyz/world-module-metadata": patch
5+
"@latticexyz/world-modules": patch
6+
---
7+
8+
Removed unsupported install methods as these now automatically revert in the base `Module` contract.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
"@latticexyz/world": patch
3+
---
4+
5+
The base `Module` contract now includes default implementations of `install` and `installRoot` that immediately revert, avoiding the need to implement these manually in each module.
6+
7+
If you've written a module, you may need to update your install methods with `override` when using this new base contract.
8+
9+
```diff
10+
-function install(bytes memory) public {
11+
+function install(bytes memory) public override {
12+
```
13+
14+
```diff
15+
-function installRoot(bytes memory) public {
16+
+function installRoot(bytes memory) public override {
17+
```

docs/pages/guides/modules.mdx

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,7 @@ contract TimerModule is Module {
132132
ResourceId private immutable namespaceResource = WorldResourceIdLib.encodeNamespace(bytes14("timer"));
133133
ResourceId private immutable timerSystemResource = WorldResourceIdLib.encode(RESOURCE_SYSTEM, "timer", "TimerSystem");
134134
135-
function installRoot(bytes memory) public pure override {
136-
revert Module_RootInstallNotSupported();
137-
}
138-
139-
function install(bytes memory) public {
135+
function install(bytes memory) public override {
140136
IWorld world = IWorld(_world());
141137
142138
// Register the namespace.
@@ -210,15 +206,7 @@ We need these identifiers to register the namespace and `System`s.
210206
There is no point wasting gas on recalculating these values either, so it's best to do it once.
211207

212208
```solidity
213-
function installRoot(bytes memory) public pure override {
214-
revert Module_RootInstallNotSupported();
215-
}
216-
```
217-
218-
We do _not_ need root privileges, so it's best if we [don't have them](https://en.wikipedia.org/wiki/Principle_of_least_privilege).
219-
220-
```solidity
221-
function install(bytes memory) public {
209+
function install(bytes memory) public override {
222210
IWorld world = IWorld(_world());
223211
224212
// Register the namespace.

docs/pages/world/reference/internal/init-module.mdx

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,6 @@ _Registers core tables, systems, and function selectors in the World._
6060
function installRoot(bytes memory) public override;
6161
```
6262

63-
#### install
64-
65-
Non-root installation of the module.
66-
67-
_Installation is only supported at root level, so this function will always revert._
68-
69-
```solidity
70-
function install(bytes memory) public pure;
71-
```
72-
7363
#### \_registerTables
7464

7565
Register World's tables.

docs/pages/world/reference/module.mdx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,38 @@ function requireNotInstalled(address moduleAddress, bytes memory encodedArgs) in
7878
| --------------- | --------- | ------------------------------------------------------ |
7979
| `moduleAddress` | `address` | The address of the module. |
8080
| `encodedArgs` | `bytes` | The ABI encoded arguments for the module installation. |
81+
82+
#### installRoot
83+
84+
Installs the module as a root module.
85+
86+
_This function is invoked by the World contract during `installRootModule` process.
87+
The module expects to be called via the World contract and thus installs itself on the `msg.sender`._
88+
89+
```solidity
90+
function installRoot(bytes memory encodedArgs) public virtual;
91+
```
92+
93+
**Parameters**
94+
95+
| Name | Type | Description |
96+
| ------------- | ------- | ----------------------------------------------------------------------------- |
97+
| `encodedArgs` | `bytes` | The ABI encoded arguments that may be needed during the installation process. |
98+
99+
#### install
100+
101+
Installs the module.
102+
103+
_This function is invoked by the World contract during `installModule` process.
104+
The module expects to be called via the World contract and thus installs itself on the `msg.sender`.
105+
Logic might differ from `installRoot`, for example, this might accept namespace parameters._
106+
107+
```solidity
108+
function install(bytes memory encodedArgs) public virtual;
109+
```
110+
111+
**Parameters**
112+
113+
| Name | Type | Description |
114+
| ------------- | ------- | ----------------------------------------------------------------------------- |
115+
| `encodedArgs` | `bytes` | The ABI encoded arguments that may be needed during the installation process. |

packages/world-module-callwithsignature/src/CallWithSignatureModule.sol

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { DELEGATION_SYSTEM_ID } from "./constants.sol";
1414
contract CallWithSignatureModule is Module {
1515
CallWithSignatureSystem private immutable callWithSignatureSystem = new CallWithSignatureSystem();
1616

17-
function installRoot(bytes memory encodedArgs) public {
17+
function installRoot(bytes memory encodedArgs) public override {
1818
requireNotInstalled(__self, encodedArgs);
1919

2020
IBaseWorld world = IBaseWorld(_world());
@@ -41,8 +41,4 @@ contract CallWithSignatureModule is Module {
4141
);
4242
if (!success) revertWithBytes(data);
4343
}
44-
45-
function install(bytes memory) public pure {
46-
revert Module_NonRootInstallNotSupported();
47-
}
4844
}

packages/world-module-erc20/src/experimental/ERC20Module.sol

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ contract ERC20Module is Module {
1818
error ERC20Module_InvalidNamespace(bytes14 namespace);
1919
error ERC20Module_NamespaceAlreadyExists(bytes14 namespace);
2020

21-
function install(bytes memory encodedArgs) public {
21+
function install(bytes memory encodedArgs) public override {
2222
// TODO: we should probably check just for namespace, not for all args
2323
requireNotInstalled(__self, encodedArgs);
2424

@@ -52,10 +52,6 @@ contract ERC20Module is Module {
5252

5353
ERC20RegistryLib.register(world, namespaceId, address(token));
5454
}
55-
56-
function installRoot(bytes memory) public pure {
57-
revert Module_RootInstallNotSupported();
58-
}
5955
}
6056

6157
library ERC20RegistryLib {

packages/world-module-metadata/src/MetadataModule.sol

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,7 @@ contract MetadataModule is Module {
2222

2323
MetadataSystem private immutable metadataSystem = new MetadataSystem();
2424

25-
function installRoot(bytes memory) public pure {
26-
revert Module_RootInstallNotSupported();
27-
}
28-
29-
function install(bytes memory args) public {
25+
function install(bytes memory args) public override {
3026
// naive check to ensure this is only installed once
3127
// TODO: update this + deployer to be idempotent
3228
requireNotInstalled(__self, args);

packages/world-modules/src/modules/erc20-puppet/ERC20Module.sol

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { ERC20Metadata, ERC20MetadataData } from "./tables/ERC20Metadata.sol";
2424
contract ERC20Module is Module {
2525
error ERC20Module_InvalidNamespace(bytes14 namespace);
2626

27-
function install(bytes memory encodedArgs) public {
27+
function install(bytes memory encodedArgs) public override {
2828
// Require the module to not be installed with these args yet
2929
requireNotInstalled(__self, encodedArgs);
3030

@@ -58,10 +58,6 @@ contract ERC20Module is Module {
5858
}
5959
ERC20Registry.set(ERC20_REGISTRY_TABLE_ID, namespaceId, puppet);
6060
}
61-
62-
function installRoot(bytes memory) public pure {
63-
revert Module_RootInstallNotSupported();
64-
}
6561
}
6662

6763
library ERC20ModuleRegistrationLib {

packages/world-modules/src/modules/erc721-puppet/ERC721Module.sol

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { ERC721Metadata, ERC721MetadataData } from "./tables/ERC721Metadata.sol"
2727
contract ERC721Module is Module {
2828
error ERC721Module_InvalidNamespace(bytes14 namespace);
2929

30-
function install(bytes memory encodedArgs) public {
30+
function install(bytes memory encodedArgs) public override {
3131
// Require the module to not be installed with these args yet
3232
requireNotInstalled(__self, encodedArgs);
3333

@@ -61,10 +61,6 @@ contract ERC721Module is Module {
6161
}
6262
ERC721Registry.set(ERC721_REGISTRY_TABLE_ID, namespaceId, puppet);
6363
}
64-
65-
function installRoot(bytes memory) public pure {
66-
revert Module_RootInstallNotSupported();
67-
}
6864
}
6965

7066
library ERC721ModuleRegistrationLib {

0 commit comments

Comments
 (0)