From c64ac4816a20a43f88a6a242d758e798f42b687a Mon Sep 17 00:00:00 2001 From: alvrs Date: Wed, 20 Sep 2023 12:54:00 +0100 Subject: [PATCH] feat(world): use ResourceId namespaceId for all methods acting on the namespace as a resource --- .changeset/real-students-exercise.md | 25 ++++ packages/store/src/ResourceId.sol | 2 +- packages/world/gas-report.json | 38 +++--- packages/world/mud.config.ts | 4 +- packages/world/src/AccessControl.sol | 2 +- packages/world/src/SystemCall.sol | 6 +- packages/world/src/World.sol | 4 +- packages/world/src/WorldResourceId.sol | 4 +- packages/world/src/factories/WorldFactory.sol | 4 +- .../interfaces/IAccessManagementSystem.sol | 2 +- .../src/interfaces/IBalanceTransferSystem.sol | 6 +- .../interfaces/IWorldRegistrationSystem.sol | 2 +- .../world/src/modules/core/CoreModule.sol | 8 +- .../AccessManagementSystem.sol | 6 +- .../implementations/BalanceTransferSystem.sol | 22 ++-- .../StoreRegistrationSystem.sol | 2 +- .../WorldRegistrationSystem.sol | 8 +- .../src/modules/core/tables/Balances.sol | 68 +++++------ packages/world/src/tables/NamespaceOwner.sol | 68 +++++------ packages/world/test/Factories.t.sol | 5 +- packages/world/test/World.t.sol | 56 +++++---- packages/world/test/WorldBalance.t.sol | 111 +++++++++--------- packages/world/test/WorldDynamicUpdate.t.sol | 2 - 23 files changed, 244 insertions(+), 211 deletions(-) create mode 100644 .changeset/real-students-exercise.md diff --git a/.changeset/real-students-exercise.md b/.changeset/real-students-exercise.md new file mode 100644 index 0000000000..25ac8a1a75 --- /dev/null +++ b/.changeset/real-students-exercise.md @@ -0,0 +1,25 @@ +--- +"@latticexyz/world": major +--- + +All `World` methods acting on namespaces as resources have been updated to use `ResourceId namespaceId` as parameter instead of `bytes14 namespace`. +The reason for this change is to make it clearer when a namespace is used as resource, as opposed to being part of another resource's ID. + +```diff ++ import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + +IBaseWorld { +- function registerNamespace(bytes14 namespace) external; ++ function registerNamespace(ResourceId namespaceId) external; + +- function transferOwnership(bytes14 namespace, address newOwner) external; ++ function transferOwnership(ResourceId namespaceId, address newOwner) external; + +- function transferBalanceToNamespace(bytes14 fromNamespace, bytes14 toNamespace, uint256 amount) external; ++ function transferBalanceToNamespace(ResourceId fromNamespaceId, ResourceId toNamespaceId, uint256 amount) external; + +- function transferBalanceToAddress(bytes14 fromNamespace, address toAddress, uint256 amount) external; ++ function transferBalanceToAddress(ResourceId fromNamespaceId, address toAddress, uint256 amount) external; +} + +``` diff --git a/packages/store/src/ResourceId.sol b/packages/store/src/ResourceId.sol index 9f23d76dd5..01882c250d 100644 --- a/packages/store/src/ResourceId.sol +++ b/packages/store/src/ResourceId.sol @@ -20,7 +20,7 @@ library ResourceIdInstance { return bytes2(ResourceId.unwrap(resourceId) << (NAME_BYTES * BYTES_TO_BITS)); } - function isType(ResourceId resourceId, bytes2 resourceType) internal view returns (bool) { + function isType(ResourceId resourceId, bytes2 resourceType) internal pure returns (bool) { return ResourceId.unwrap(resourceId) & TYPE_MASK == bytes32(resourceType) >> (NAME_BYTES * BYTES_TO_BITS); } } diff --git a/packages/world/gas-report.json b/packages/world/gas-report.json index fe5fe96314..0c3a8486b9 100644 --- a/packages/world/gas-report.json +++ b/packages/world/gas-report.json @@ -39,13 +39,13 @@ "file": "test/KeysInTableModule.t.sol", "test": "testInstallComposite", "name": "install keys in table module", - "gasUsed": 1414829 + "gasUsed": 1414689 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallGas", "name": "install keys in table module", - "gasUsed": 1414829 + "gasUsed": 1414689 }, { "file": "test/KeysInTableModule.t.sol", @@ -57,13 +57,13 @@ "file": "test/KeysInTableModule.t.sol", "test": "testInstallSingleton", "name": "install keys in table module", - "gasUsed": 1414829 + "gasUsed": 1414689 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "install keys in table module", - "gasUsed": 1414829 + "gasUsed": 1414689 }, { "file": "test/KeysInTableModule.t.sol", @@ -81,7 +81,7 @@ "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "install keys in table module", - "gasUsed": 1414829 + "gasUsed": 1414689 }, { "file": "test/KeysInTableModule.t.sol", @@ -99,7 +99,7 @@ "file": "test/KeysWithValueModule.t.sol", "test": "testGetKeysWithValueGas", "name": "install keys with value module", - "gasUsed": 664865 + "gasUsed": 664413 }, { "file": "test/KeysWithValueModule.t.sol", @@ -117,7 +117,7 @@ "file": "test/KeysWithValueModule.t.sol", "test": "testInstall", "name": "install keys with value module", - "gasUsed": 664865 + "gasUsed": 664413 }, { "file": "test/KeysWithValueModule.t.sol", @@ -129,7 +129,7 @@ "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "install keys with value module", - "gasUsed": 664865 + "gasUsed": 664413 }, { "file": "test/KeysWithValueModule.t.sol", @@ -147,7 +147,7 @@ "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "install keys with value module", - "gasUsed": 664865 + "gasUsed": 664413 }, { "file": "test/KeysWithValueModule.t.sol", @@ -231,7 +231,7 @@ "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromCallboundDelegation", "name": "register a callbound delegation", - "gasUsed": 114173 + "gasUsed": 114161 }, { "file": "test/StandardDelegationsModule.t.sol", @@ -243,7 +243,7 @@ "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromTimeboundDelegation", "name": "register a timebound delegation", - "gasUsed": 108625 + "gasUsed": 108613 }, { "file": "test/StandardDelegationsModule.t.sol", @@ -255,7 +255,7 @@ "file": "test/UniqueEntityModule.t.sol", "test": "testInstall", "name": "install unique entity module", - "gasUsed": 690879 + "gasUsed": 690445 }, { "file": "test/UniqueEntityModule.t.sol", @@ -267,7 +267,7 @@ "file": "test/UniqueEntityModule.t.sol", "test": "testInstallRoot", "name": "installRoot unique entity module", - "gasUsed": 681148 + "gasUsed": 680717 }, { "file": "test/UniqueEntityModule.t.sol", @@ -309,37 +309,37 @@ "file": "test/World.t.sol", "test": "testRegisterFallbackSystem", "name": "Register a fallback system", - "gasUsed": 58802 + "gasUsed": 58798 }, { "file": "test/World.t.sol", "test": "testRegisterFallbackSystem", "name": "Register a root fallback system", - "gasUsed": 52544 + "gasUsed": 52551 }, { "file": "test/World.t.sol", "test": "testRegisterFunctionSelector", "name": "Register a function selector", - "gasUsed": 79396 + "gasUsed": 79392 }, { "file": "test/World.t.sol", "test": "testRegisterNamespace", "name": "Register a new namespace", - "gasUsed": 123284 + "gasUsed": 122878 }, { "file": "test/World.t.sol", "test": "testRegisterRootFunctionSelector", "name": "Register a root function selector", - "gasUsed": 74457 + "gasUsed": 74464 }, { "file": "test/World.t.sol", "test": "testRegisterTable", "name": "Register a new table in the namespace", - "gasUsed": 652534 + "gasUsed": 652093 }, { "file": "test/World.t.sol", diff --git a/packages/world/mud.config.ts b/packages/world/mud.config.ts index 3e28c68b2c..51412869d3 100644 --- a/packages/world/mud.config.ts +++ b/packages/world/mud.config.ts @@ -13,7 +13,7 @@ export default mudConfig({ ************************************************************************/ NamespaceOwner: { keySchema: { - namespace: "bytes16", + namespaceId: "bytes32", }, valueSchema: { owner: "address", @@ -54,7 +54,7 @@ export default mudConfig({ Balances: { directory: "modules/core/tables", keySchema: { - namespace: "bytes16", + namespaceId: "bytes32", }, valueSchema: { balance: "uint256", diff --git a/packages/world/src/AccessControl.sol b/packages/world/src/AccessControl.sol index 88df5e7aa4..6cb5cc12ce 100644 --- a/packages/world/src/AccessControl.sol +++ b/packages/world/src/AccessControl.sol @@ -36,7 +36,7 @@ library AccessControl { * Reverts with AccessDenied if the check fails. */ function requireOwner(ResourceId resourceId, address caller) internal view { - if (NamespaceOwner._get(resourceId.getNamespace()) != caller) { + if (NamespaceOwner._get(ResourceId.unwrap(resourceId.getNamespaceId())) != caller) { revert IWorldErrors.AccessDenied(resourceId.toString(), caller); } } diff --git a/packages/world/src/SystemCall.sol b/packages/world/src/SystemCall.sol index 62aa1194b5..568f47e4ee 100644 --- a/packages/world/src/SystemCall.sol +++ b/packages/world/src/SystemCall.sol @@ -43,9 +43,9 @@ library SystemCall { // If the msg.value is non-zero, update the namespace's balance if (value > 0) { - bytes14 namespace = systemId.getNamespace(); - uint256 currentBalance = Balances._get(namespace); - Balances._set(namespace, currentBalance + value); + ResourceId namespaceId = systemId.getNamespaceId(); + uint256 currentBalance = Balances._get(ResourceId.unwrap(namespaceId)); + Balances._set(ResourceId.unwrap(namespaceId), currentBalance + value); } // Call the system and forward any return data diff --git a/packages/world/src/World.sol b/packages/world/src/World.sol index 97b00beba0..f24bf892e1 100644 --- a/packages/world/src/World.sol +++ b/packages/world/src/World.sol @@ -287,8 +287,8 @@ contract World is StoreRead, IStoreData, IWorldKernel { * ETH sent to the World without calldata is added to the root namespace's balance */ receive() external payable { - uint256 rootBalance = Balances._get(ROOT_NAMESPACE); - Balances._set(ROOT_NAMESPACE, rootBalance + msg.value); + uint256 rootBalance = Balances._get(ResourceId.unwrap(ROOT_NAMESPACE_ID)); + Balances._set(ResourceId.unwrap(ROOT_NAMESPACE_ID), rootBalance + msg.value); } /** diff --git a/packages/world/src/WorldResourceId.sol b/packages/world/src/WorldResourceId.sol index e9d8a3fdd3..57a78fdb85 100644 --- a/packages/world/src/WorldResourceId.sol +++ b/packages/world/src/WorldResourceId.sol @@ -92,9 +92,9 @@ library WorldResourceIdInstance { string( abi.encodePacked( resourceNamespace == ROOT_NAMESPACE ? ROOT_NAMESPACE_STRING : resourceNamespace, - "_", + ":", resourceName == ROOT_NAME ? ROOT_NAME_STRING : resourceName, - ".", + ":", resourceType ) ); diff --git a/packages/world/src/factories/WorldFactory.sol b/packages/world/src/factories/WorldFactory.sol index 752ade4ddb..87af0543ed 100644 --- a/packages/world/src/factories/WorldFactory.sol +++ b/packages/world/src/factories/WorldFactory.sol @@ -6,7 +6,7 @@ import { World } from "../World.sol"; import { IWorldFactory } from "./IWorldFactory.sol"; import { IBaseWorld } from "../interfaces/IBaseWorld.sol"; import { IModule } from "../interfaces/IModule.sol"; -import { ROOT_NAMESPACE } from "../constants.sol"; +import { ROOT_NAMESPACE_ID } from "../constants.sol"; contract WorldFactory is IWorldFactory { IModule public coreModule; @@ -27,7 +27,7 @@ contract WorldFactory is IWorldFactory { // Initialize the World and transfer ownership to the caller world.initialize(coreModule); - world.transferOwnership(ROOT_NAMESPACE, msg.sender); + world.transferOwnership(ROOT_NAMESPACE_ID, msg.sender); emit WorldDeployed(worldAddress); } diff --git a/packages/world/src/interfaces/IAccessManagementSystem.sol b/packages/world/src/interfaces/IAccessManagementSystem.sol index eeb3a50741..2e2c56e5a2 100644 --- a/packages/world/src/interfaces/IAccessManagementSystem.sol +++ b/packages/world/src/interfaces/IAccessManagementSystem.sol @@ -10,5 +10,5 @@ interface IAccessManagementSystem { function revokeAccess(ResourceId resourceId, address grantee) external; - function transferOwnership(bytes14 namespace, address newOwner) external; + function transferOwnership(ResourceId namespaceId, address newOwner) external; } diff --git a/packages/world/src/interfaces/IBalanceTransferSystem.sol b/packages/world/src/interfaces/IBalanceTransferSystem.sol index 92c3e104dd..3660f06395 100644 --- a/packages/world/src/interfaces/IBalanceTransferSystem.sol +++ b/packages/world/src/interfaces/IBalanceTransferSystem.sol @@ -3,8 +3,10 @@ pragma solidity >=0.8.0; /* Autogenerated file. Do not edit manually. */ +import { ResourceId } from "./../WorldResourceId.sol"; + interface IBalanceTransferSystem { - function transferBalanceToNamespace(bytes14 fromNamespace, bytes14 toNamespace, uint256 amount) external; + function transferBalanceToNamespace(ResourceId fromNamespaceId, ResourceId toNamespaceId, uint256 amount) external; - function transferBalanceToAddress(bytes14 fromNamespace, address toAddress, uint256 amount) external; + function transferBalanceToAddress(ResourceId fromNamespaceId, address toAddress, uint256 amount) external; } diff --git a/packages/world/src/interfaces/IWorldRegistrationSystem.sol b/packages/world/src/interfaces/IWorldRegistrationSystem.sol index cc74a1fee9..f7a6d4c61c 100644 --- a/packages/world/src/interfaces/IWorldRegistrationSystem.sol +++ b/packages/world/src/interfaces/IWorldRegistrationSystem.sol @@ -8,7 +8,7 @@ import { ISystemHook } from "./ISystemHook.sol"; import { WorldContextConsumer } from "./../WorldContext.sol"; interface IWorldRegistrationSystem { - function registerNamespace(bytes14 namespace) external; + function registerNamespace(ResourceId namespaceId) external; function registerSystemHook(ResourceId systemId, ISystemHook hookAddress, uint8 enabledHooksBitmap) external; diff --git a/packages/world/src/modules/core/CoreModule.sol b/packages/world/src/modules/core/CoreModule.sol index f8b4020491..63a4b019c4 100644 --- a/packages/world/src/modules/core/CoreModule.sol +++ b/packages/world/src/modules/core/CoreModule.sol @@ -2,7 +2,7 @@ pragma solidity >=0.8.0; import { WorldContextProvider } from "../../WorldContext.sol"; -import { ROOT_NAMESPACE } from "../../constants.sol"; +import { ROOT_NAMESPACE, ROOT_NAMESPACE_ID } from "../../constants.sol"; import { Resource } from "../../common.sol"; import { Module } from "../../Module.sol"; @@ -77,9 +77,9 @@ contract CoreModule is Module { SystemRegistry.register(); ResourceType.register(); - NamespaceOwner._set(ROOT_NAMESPACE, _msgSender()); - ResourceAccess._set(ROOT_NAMESPACE, _msgSender(), true); - ResourceType._set(ROOT_NAMESPACE, Resource.NAMESPACE); + NamespaceOwner._set(ResourceId.unwrap(ROOT_NAMESPACE_ID), _msgSender()); + ResourceAccess._set(ResourceId.unwrap(ROOT_NAMESPACE_ID), _msgSender(), true); + ResourceType._set(ResourceId.unwrap(ROOT_NAMESPACE_ID), Resource.NAMESPACE); } /** diff --git a/packages/world/src/modules/core/implementations/AccessManagementSystem.sol b/packages/world/src/modules/core/implementations/AccessManagementSystem.sol index 697f69eb3d..feb058a0d9 100644 --- a/packages/world/src/modules/core/implementations/AccessManagementSystem.sol +++ b/packages/world/src/modules/core/implementations/AccessManagementSystem.sol @@ -42,14 +42,12 @@ contract AccessManagementSystem is System { * Revoke ResourceAccess for previous owner and grant to newOwner. * Requires the caller to own the namespace. */ - function transferOwnership(bytes14 namespace, address newOwner) public virtual { - ResourceId namespaceId = WorldResourceIdLib.encodeNamespace(namespace); - + function transferOwnership(ResourceId namespaceId, address newOwner) public virtual { // Require the caller to own the namespace AccessControl.requireOwner(namespaceId, _msgSender()); // Set namespace new owner - NamespaceOwner._set(namespace, newOwner); + NamespaceOwner._set(ResourceId.unwrap(namespaceId), newOwner); // Revoke access from old owner ResourceAccess._deleteRecord(ResourceId.unwrap(namespaceId), _msgSender()); diff --git a/packages/world/src/modules/core/implementations/BalanceTransferSystem.sol b/packages/world/src/modules/core/implementations/BalanceTransferSystem.sol index e1bca1e26b..3012389d0d 100644 --- a/packages/world/src/modules/core/implementations/BalanceTransferSystem.sol +++ b/packages/world/src/modules/core/implementations/BalanceTransferSystem.sol @@ -15,36 +15,40 @@ contract BalanceTransferSystem is System, IWorldErrors { /** * Transfer balance to another namespace in the World */ - function transferBalanceToNamespace(bytes14 fromNamespace, bytes14 toNamespace, uint256 amount) public virtual { + function transferBalanceToNamespace( + ResourceId fromNamespaceId, + ResourceId toNamespaceId, + uint256 amount + ) public virtual { // Require caller to have access to the namespace - AccessControl.requireAccess(WorldResourceIdLib.encodeNamespace(fromNamespace), _msgSender()); + AccessControl.requireAccess(fromNamespaceId, _msgSender()); // Get current namespace balance - uint256 balance = Balances._get(fromNamespace); + uint256 balance = Balances._get(ResourceId.unwrap(fromNamespaceId)); // Require the balance balance to be greater or equal to the amount to transfer if (amount > balance) revert InsufficientBalance(balance, amount); // Update the balances - Balances._set(fromNamespace, balance - amount); - Balances._set(toNamespace, Balances._get(toNamespace) + amount); + Balances._set(ResourceId.unwrap(fromNamespaceId), balance - amount); + Balances._set(ResourceId.unwrap(toNamespaceId), Balances._get(ResourceId.unwrap(toNamespaceId)) + amount); } /** * Transfer balance out of the World */ - function transferBalanceToAddress(bytes14 fromNamespace, address toAddress, uint256 amount) public virtual { + function transferBalanceToAddress(ResourceId fromNamespaceId, address toAddress, uint256 amount) public virtual { // Require caller to have access to the namespace - AccessControl.requireAccess(WorldResourceIdLib.encodeNamespace(fromNamespace), _msgSender()); + AccessControl.requireAccess(fromNamespaceId, _msgSender()); // Get current namespace balance - uint256 balance = Balances._get(fromNamespace); + uint256 balance = Balances._get(ResourceId.unwrap(fromNamespaceId)); // Require the balance balance to be greater or equal to the amount to transfer if (amount > balance) revert InsufficientBalance(balance, amount); // Update the balances - Balances._set(fromNamespace, balance - amount); + Balances._set(ResourceId.unwrap(fromNamespaceId), balance - amount); // Transfer the balance to the given address, revert on failure (bool success, bytes memory data) = payable(toAddress).call{ value: amount }(""); diff --git a/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol b/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol index c307d37726..534f362d47 100644 --- a/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol +++ b/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol @@ -54,7 +54,7 @@ contract StoreRegistrationSystem is System, IWorldErrors { // Since this is a root system, we're in the context of the World contract already, // so we can use delegatecall to register the namespace (bool success, bytes memory data) = address(this).delegatecall( - abi.encodeCall(WorldRegistrationSystem.registerNamespace, (namespaceId.getNamespace())) + abi.encodeCall(WorldRegistrationSystem.registerNamespace, (namespaceId)) ); if (!success) revertWithBytes(data); } else { diff --git a/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol b/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol index 977e767c14..8b8c8a4b23 100644 --- a/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol +++ b/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol @@ -34,9 +34,7 @@ contract WorldRegistrationSystem is System, IWorldErrors { /** * Register a new namespace */ - function registerNamespace(bytes14 namespace) public virtual { - ResourceId namespaceId = WorldResourceIdLib.encodeNamespace(namespace); - + function registerNamespace(ResourceId namespaceId) public virtual { // Require namespace to not exist yet if (ResourceType._get(ResourceId.unwrap(namespaceId)) != Resource.NONE) revert ResourceExists(namespaceId, namespaceId.toString()); @@ -45,7 +43,7 @@ contract WorldRegistrationSystem is System, IWorldErrors { ResourceType._set(ResourceId.unwrap(namespaceId), Resource.NAMESPACE); // Register caller as the namespace owner - NamespaceOwner._set(namespace, _msgSender()); + NamespaceOwner._set(ResourceId.unwrap(namespaceId), _msgSender()); // Give caller access to the new namespace ResourceAccess._set(ResourceId.unwrap(namespaceId), _msgSender(), true); @@ -105,7 +103,7 @@ contract WorldRegistrationSystem is System, IWorldErrors { // otherwise require caller to own the namespace ResourceId namespaceId = systemId.getNamespaceId(); if (ResourceType._get(ResourceId.unwrap(namespaceId)) == Resource.NONE) { - registerNamespace(systemId.getNamespace()); + registerNamespace(namespaceId); } else { AccessControl.requireOwner(namespaceId, _msgSender()); } diff --git a/packages/world/src/modules/core/tables/Balances.sol b/packages/world/src/modules/core/tables/Balances.sol index 71445a9ff9..c8bdf1a910 100644 --- a/packages/world/src/modules/core/tables/Balances.sol +++ b/packages/world/src/modules/core/tables/Balances.sol @@ -38,7 +38,7 @@ library Balances { /** Get the table's key schema */ function getKeySchema() internal pure returns (Schema) { SchemaType[] memory _keySchema = new SchemaType[](1); - _keySchema[0] = SchemaType.BYTES16; + _keySchema[0] = SchemaType.BYTES32; return SchemaLib.encode(_keySchema); } @@ -54,7 +54,7 @@ library Balances { /** Get the table's key names */ function getKeyNames() internal pure returns (string[] memory keyNames) { keyNames = new string[](1); - keyNames[0] = "namespace"; + keyNames[0] = "namespaceId"; } /** Get the table's field names */ @@ -79,103 +79,103 @@ library Balances { } /** Get balance */ - function getBalance(bytes16 namespace) internal view returns (uint256 balance) { + function getBalance(bytes32 namespaceId) internal view returns (uint256 balance) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (uint256(bytes32(_blob))); } /** Get balance */ - function _getBalance(bytes16 namespace) internal view returns (uint256 balance) { + function _getBalance(bytes32 namespaceId) internal view returns (uint256 balance) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (uint256(bytes32(_blob))); } /** Get balance (using the specified store) */ - function getBalance(IStore _store, bytes16 namespace) internal view returns (uint256 balance) { + function getBalance(IStore _store, bytes32 namespaceId) internal view returns (uint256 balance) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (uint256(bytes32(_blob))); } /** Get balance */ - function get(bytes16 namespace) internal view returns (uint256 balance) { + function get(bytes32 namespaceId) internal view returns (uint256 balance) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (uint256(bytes32(_blob))); } /** Get balance */ - function _get(bytes16 namespace) internal view returns (uint256 balance) { + function _get(bytes32 namespaceId) internal view returns (uint256 balance) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (uint256(bytes32(_blob))); } /** Get balance (using the specified store) */ - function get(IStore _store, bytes16 namespace) internal view returns (uint256 balance) { + function get(IStore _store, bytes32 namespaceId) internal view returns (uint256 balance) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (uint256(bytes32(_blob))); } /** Set balance */ - function setBalance(bytes16 namespace, uint256 balance) internal { + function setBalance(bytes32 namespaceId, uint256 balance) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); } /** Set balance */ - function _setBalance(bytes16 namespace, uint256 balance) internal { + function _setBalance(bytes32 namespaceId, uint256 balance) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); } /** Set balance (using the specified store) */ - function setBalance(IStore _store, bytes16 namespace, uint256 balance) internal { + function setBalance(IStore _store, bytes32 namespaceId, uint256 balance) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); } /** Set balance */ - function set(bytes16 namespace, uint256 balance) internal { + function set(bytes32 namespaceId, uint256 balance) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); } /** Set balance */ - function _set(bytes16 namespace, uint256 balance) internal { + function _set(bytes32 namespaceId, uint256 balance) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); } /** Set balance (using the specified store) */ - function set(IStore _store, bytes16 namespace, uint256 balance) internal { + function set(IStore _store, bytes32 namespaceId, uint256 balance) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); } @@ -196,33 +196,33 @@ library Balances { } /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple(bytes16 namespace) internal pure returns (bytes32[] memory) { + function encodeKeyTuple(bytes32 namespaceId) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; return _keyTuple; } /* Delete all data for given keys */ - function deleteRecord(bytes16 namespace) internal { + function deleteRecord(bytes32 namespaceId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys */ - function _deleteRecord(bytes16 namespace) internal { + function _deleteRecord(bytes32 namespaceId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes16 namespace) internal { + function deleteRecord(IStore _store, bytes32 namespaceId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } diff --git a/packages/world/src/tables/NamespaceOwner.sol b/packages/world/src/tables/NamespaceOwner.sol index 7cdc7a98c1..ea4a01c97c 100644 --- a/packages/world/src/tables/NamespaceOwner.sol +++ b/packages/world/src/tables/NamespaceOwner.sol @@ -38,7 +38,7 @@ library NamespaceOwner { /** Get the table's key schema */ function getKeySchema() internal pure returns (Schema) { SchemaType[] memory _keySchema = new SchemaType[](1); - _keySchema[0] = SchemaType.BYTES16; + _keySchema[0] = SchemaType.BYTES32; return SchemaLib.encode(_keySchema); } @@ -54,7 +54,7 @@ library NamespaceOwner { /** Get the table's key names */ function getKeyNames() internal pure returns (string[] memory keyNames) { keyNames = new string[](1); - keyNames[0] = "namespace"; + keyNames[0] = "namespaceId"; } /** Get the table's field names */ @@ -79,103 +79,103 @@ library NamespaceOwner { } /** Get owner */ - function getOwner(bytes16 namespace) internal view returns (address owner) { + function getOwner(bytes32 namespaceId) internal view returns (address owner) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (address(bytes20(_blob))); } /** Get owner */ - function _getOwner(bytes16 namespace) internal view returns (address owner) { + function _getOwner(bytes32 namespaceId) internal view returns (address owner) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (address(bytes20(_blob))); } /** Get owner (using the specified store) */ - function getOwner(IStore _store, bytes16 namespace) internal view returns (address owner) { + function getOwner(IStore _store, bytes32 namespaceId) internal view returns (address owner) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (address(bytes20(_blob))); } /** Get owner */ - function get(bytes16 namespace) internal view returns (address owner) { + function get(bytes32 namespaceId) internal view returns (address owner) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (address(bytes20(_blob))); } /** Get owner */ - function _get(bytes16 namespace) internal view returns (address owner) { + function _get(bytes32 namespaceId) internal view returns (address owner) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (address(bytes20(_blob))); } /** Get owner (using the specified store) */ - function get(IStore _store, bytes16 namespace) internal view returns (address owner) { + function get(IStore _store, bytes32 namespaceId) internal view returns (address owner) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (address(bytes20(_blob))); } /** Set owner */ - function setOwner(bytes16 namespace, address owner) internal { + function setOwner(bytes32 namespaceId, address owner) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((owner)), _fieldLayout); } /** Set owner */ - function _setOwner(bytes16 namespace, address owner) internal { + function _setOwner(bytes32 namespaceId, address owner) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((owner)), _fieldLayout); } /** Set owner (using the specified store) */ - function setOwner(IStore _store, bytes16 namespace, address owner) internal { + function setOwner(IStore _store, bytes32 namespaceId, address owner) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((owner)), _fieldLayout); } /** Set owner */ - function set(bytes16 namespace, address owner) internal { + function set(bytes32 namespaceId, address owner) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((owner)), _fieldLayout); } /** Set owner */ - function _set(bytes16 namespace, address owner) internal { + function _set(bytes32 namespaceId, address owner) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((owner)), _fieldLayout); } /** Set owner (using the specified store) */ - function set(IStore _store, bytes16 namespace, address owner) internal { + function set(IStore _store, bytes32 namespaceId, address owner) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((owner)), _fieldLayout); } @@ -196,33 +196,33 @@ library NamespaceOwner { } /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple(bytes16 namespace) internal pure returns (bytes32[] memory) { + function encodeKeyTuple(bytes32 namespaceId) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; return _keyTuple; } /* Delete all data for given keys */ - function deleteRecord(bytes16 namespace) internal { + function deleteRecord(bytes32 namespaceId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys */ - function _deleteRecord(bytes16 namespace) internal { + function _deleteRecord(bytes32 namespaceId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes16 namespace) internal { + function deleteRecord(IStore _store, bytes32 namespaceId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } diff --git a/packages/world/test/Factories.t.sol b/packages/world/test/Factories.t.sol index 5887d42ddb..a943d7a41f 100644 --- a/packages/world/test/Factories.t.sol +++ b/packages/world/test/Factories.t.sol @@ -6,13 +6,14 @@ import { Test, console } from "forge-std/Test.sol"; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; import { WORLD_VERSION } from "../src/version.sol"; import { World } from "../src/World.sol"; +import { ResourceId } from "../src/WorldResourceId.sol"; import { CoreModule } from "../src/modules/core/CoreModule.sol"; import { Create2Factory } from "../src/factories/Create2Factory.sol"; import { WorldFactory } from "../src/factories/WorldFactory.sol"; import { IWorldFactory } from "../src/factories/IWorldFactory.sol"; import { InstalledModules } from "../src/tables/InstalledModules.sol"; import { NamespaceOwner } from "../src/tables/NamespaceOwner.sol"; -import { ROOT_NAMESPACE } from "../src/constants.sol"; +import { ROOT_NAMESPACE_ID } from "../src/constants.sol"; contract FactoriesTest is Test { event ContractDeployed(address addr, uint256 salt); @@ -80,6 +81,6 @@ contract FactoriesTest is Test { assertEq(uint256(worldFactory.worldCount()), uint256(1)); // Confirm the msg.sender is owner of the root namespace of the new world - assertEq(NamespaceOwner.get(ROOT_NAMESPACE), address(this)); + assertEq(NamespaceOwner.get(ResourceId.unwrap(ROOT_NAMESPACE_ID)), address(this)); } } diff --git a/packages/world/test/World.t.sol b/packages/world/test/World.t.sol index 5e5e6b4721..f0f82c8860 100644 --- a/packages/world/test/World.t.sol +++ b/packages/world/test/World.t.sol @@ -276,7 +276,7 @@ contract WorldTest is Test, GasReporter { function testRootNamespace() public { // Owner of root route should be the creator of the World - address rootOwner = NamespaceOwner.get(world, ROOT_NAMESPACE); + address rootOwner = NamespaceOwner.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)); assertEq(rootOwner, address(this)); // The creator of the World should have access to the root namespace @@ -296,40 +296,39 @@ contract WorldTest is Test, GasReporter { function testRegisterNamespace() public { bytes14 namespace = "testNamespace"; + ResourceId namespaceId = WorldResourceIdLib.encodeNamespace(namespace); startGasReport("Register a new namespace"); - world.registerNamespace(namespace); + world.registerNamespace(namespaceId); endGasReport(); // Expect the caller to be the namespace owner - assertEq(NamespaceOwner.get(world, namespace), address(this), "caller should be namespace owner"); + assertEq( + NamespaceOwner.get(world, ResourceId.unwrap(namespaceId)), + address(this), + "caller should be namespace owner" + ); // Expect the caller to have access assertEq( - ResourceAccess.get(world, ResourceId.unwrap(WorldResourceIdLib.encodeNamespace(namespace)), address(this)), + ResourceAccess.get(world, ResourceId.unwrap(namespaceId), address(this)), true, "caller should have access" ); // Expect an error when registering an existing namespace - vm.expectRevert( - abi.encodeWithSelector( - IWorldErrors.ResourceExists.selector, - WorldResourceIdLib.encodeNamespace(namespace), - WorldResourceIdLib.encodeNamespace(namespace).toString() - ) - ); - world.registerNamespace(namespace); + vm.expectRevert(abi.encodeWithSelector(IWorldErrors.ResourceExists.selector, namespaceId, namespaceId.toString())); + world.registerNamespace(namespaceId); } function testTransferNamespace() public { bytes14 namespace = "testTransfer"; ResourceId namespaceId = WorldResourceIdLib.encodeNamespace(namespace); - world.registerNamespace(namespace); + world.registerNamespace(namespaceId); // Expect the new owner to not be namespace owner before transfer assertFalse( - (NamespaceOwner.get(world, namespace) == address(1)), + (NamespaceOwner.get(world, ResourceId.unwrap(namespaceId)) == address(1)), "new owner should not be namespace owner before transfer" ); // Expect the new owner to not have access before transfer @@ -339,10 +338,14 @@ contract WorldTest is Test, GasReporter { "new owner should not have access before transfer" ); - world.transferOwnership(namespace, address(1)); + world.transferOwnership(namespaceId, address(1)); // Expect the new owner to be namespace owner - assertEq(NamespaceOwner.get(world, namespace), address(1), "new owner should be namespace owner"); + assertEq( + NamespaceOwner.get(world, ResourceId.unwrap(namespaceId)), + address(1), + "new owner should be namespace owner" + ); // Expect the new owner to have access assertEq( @@ -352,7 +355,10 @@ contract WorldTest is Test, GasReporter { ); // Expect previous owner to no longer be owner - assertFalse((NamespaceOwner.get(world, namespace) == address(this)), "caller should no longer be namespace owner"); + assertFalse( + (NamespaceOwner.get(world, ResourceId.unwrap(namespaceId)) == address(this)), + "caller should no longer be namespace owner" + ); // Expect previous owner to no longer have access assertEq( @@ -363,7 +369,7 @@ contract WorldTest is Test, GasReporter { // Expect revert if caller is not the owner _expectAccessDenied(address(this), namespace, 0, RESOURCE_NAMESPACE); - world.transferOwnership(namespace, address(1)); + world.transferOwnership(namespaceId, address(1)); } function testRegisterTable() public { @@ -371,6 +377,7 @@ contract WorldTest is Test, GasReporter { Schema valueSchema = SchemaEncodeHelper.encode(SchemaType.BOOL, SchemaType.UINT256, SchemaType.STRING); bytes14 namespace = "testNamespace"; bytes16 tableName = "testTable"; + ResourceId namespaceId = WorldResourceIdLib.encodeNamespace(namespace); ResourceId tableId = WorldResourceIdLib.encode(namespace, tableName, RESOURCE_TABLE); string[] memory keyNames = new string[](1); keyNames[0] = "key1"; @@ -384,7 +391,11 @@ contract WorldTest is Test, GasReporter { endGasReport(); // Expect the namespace to be created and owned by the caller - assertEq(NamespaceOwner.get(world, namespace), address(this), "namespace should be created by caller"); + assertEq( + NamespaceOwner.get(world, ResourceId.unwrap(namespaceId)), + address(this), + "namespace should be created by caller" + ); // Expect the table to be registered assertEq(world.getFieldLayout(tableId).unwrap(), fieldLayout.unwrap(), "value schema should be registered"); @@ -424,7 +435,7 @@ contract WorldTest is Test, GasReporter { assertEq(registeredAddress, address(system)); // Expect the system namespace to be owned by the caller - address routeOwner = NamespaceOwner.get(world, namespace); + address routeOwner = NamespaceOwner.get(world, ResourceId.unwrap(namespaceId)); assertEq(routeOwner, address(this)); // Expect the system to not be publicly accessible @@ -445,10 +456,11 @@ contract WorldTest is Test, GasReporter { ResourceAccess.get({ _store: world, resourceId: ResourceId.unwrap(namespaceId), caller: address(system) }) ); + ResourceId newNamespaceId = WorldResourceIdLib.encodeNamespace("newNamespace"); // Expect the namespace to be created if it doesn't exist yet - assertEq(NamespaceOwner.get(world, "newNamespace"), address(0)); + assertEq(NamespaceOwner.get(world, ResourceId.unwrap(newNamespaceId)), address(0)); world.registerSystem(WorldResourceIdLib.encode("newNamespace", "testSystem", RESOURCE_SYSTEM), new System(), false); - assertEq(NamespaceOwner.get(world, "newNamespace"), address(this)); + assertEq(NamespaceOwner.get(world, ResourceId.unwrap(newNamespaceId)), address(this)); // Expect an error when registering an existing system at a new system ID vm.expectRevert(abi.encodeWithSelector(IWorldErrors.SystemExists.selector, address(system))); diff --git a/packages/world/test/WorldBalance.t.sol b/packages/world/test/WorldBalance.t.sol index 08ae7cf035..15e4f1d897 100644 --- a/packages/world/test/WorldBalance.t.sol +++ b/packages/world/test/WorldBalance.t.sol @@ -7,7 +7,7 @@ import { World } from "../src/World.sol"; import { System } from "../src/System.sol"; import { IBaseWorld } from "../src/interfaces/IBaseWorld.sol"; import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "../src/WorldResourceId.sol"; -import { ROOT_NAMESPACE } from "../src/constants.sol"; +import { ROOT_NAMESPACE, ROOT_NAMESPACE_ID } from "../src/constants.sol"; import { CoreModule } from "../src/modules/core/CoreModule.sol"; import { Balances } from "../src/modules/core/tables/Balances.sol"; import { IWorldErrors } from "../src/interfaces/IWorldErrors.sol"; @@ -26,6 +26,7 @@ contract WorldBalanceTest is Test, GasReporter { WorldBalanceTestSystem public rootSystem = new WorldBalanceTestSystem(); WorldBalanceTestSystem public nonRootSystem = new WorldBalanceTestSystem(); bytes14 public namespace = "namespace"; + ResourceId public namespaceId = WorldResourceIdLib.encodeNamespace(namespace); ResourceId public rootSystemId = WorldResourceIdLib.encode(ROOT_NAMESPACE, "testSystem", RESOURCE_SYSTEM); ResourceId public nonRootSystemId = WorldResourceIdLib.encode(namespace, "testSystem", RESOURCE_SYSTEM); address public caller = address(4242); @@ -44,8 +45,8 @@ contract WorldBalanceTest is Test, GasReporter { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Call a function on the root system with value via call vm.deal(caller, value); @@ -54,7 +55,7 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(abi.decode(data, (uint256)), value); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Call a function on a non-root system with value via call vm.deal(caller, value); @@ -63,18 +64,18 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(abi.decode(data, (uint256)), value); // Expect the non root namespace to have the value as balance - assertEq(Balances.get(world, namespace), value); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), value); // Expect the root namespace to still have the same balance as before - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); } function testCallFromWithValue() public { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Call a function on the root system with value via callFrom vm.deal(caller, value); @@ -83,7 +84,7 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(abi.decode(data, (uint256)), value); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Call a function on a non-root system with value via callFrom vm.deal(caller, value); @@ -92,18 +93,18 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(abi.decode(data, (uint256)), value); // Expect the non root namespace to have the value as balance - assertEq(Balances.get(world, namespace), value); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), value); // Expect the root namespace to still have the same balance as before - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); } function testFallbackWithValue() public { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Call a function on the root system with value via the registered root function selector vm.deal(caller, value); @@ -113,7 +114,7 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(abi.decode(data, (uint256)), value); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Call a function on a non-root system with value vm.deal(caller, value); @@ -123,17 +124,17 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(abi.decode(data, (uint256)), value); // Expect the non root namespace to have the value as balance - assertEq(Balances.get(world, namespace), value); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), value); // Expect the root namespace to still have the same balance as before - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); } function testReceiveWithValue() public { uint256 value = 1 ether; // Expect the root to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); // Send value to the world without calldata vm.deal(caller, value); @@ -143,15 +144,15 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(data.length, 0); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); } function testTransferBalanceToNamespace() public { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Send balance to root namespace vm.deal(caller, value); @@ -161,24 +162,24 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(data.length, 0); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Transfer the balance to another namespace - world.transferBalanceToNamespace(ROOT_NAMESPACE, namespace, value); + world.transferBalanceToNamespace(ROOT_NAMESPACE_ID, namespaceId, value); // Expect the root namespace to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); // Expect the non root namespace to have the value as balance - assertEq(Balances.get(world, namespace), value); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), value); } function testTransferBalanceToNamespaceRevertInsufficientBalance() public { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Send balance to root namespace vm.deal(caller, value); @@ -188,25 +189,25 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(data.length, 0); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect revert when attempting to transfer more than the balance vm.expectRevert(abi.encodeWithSelector(IWorldErrors.InsufficientBalance.selector, value, value + 1)); - world.transferBalanceToNamespace(ROOT_NAMESPACE, namespace, value + 1); + world.transferBalanceToNamespace(ROOT_NAMESPACE_ID, namespaceId, value + 1); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect the non root namespace to have no balance - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); } function testTransferBalanceToNamespaceRevertAccessDenied() public { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Send balance to root namespace vm.deal(caller, value); @@ -216,32 +217,26 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(data.length, 0); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect revert when attempting to transfer from a namespace without access vm.prank(caller); - vm.expectRevert( - abi.encodeWithSelector( - IWorldErrors.AccessDenied.selector, - WorldResourceIdLib.encodeNamespace(ROOT_NAMESPACE).toString(), - caller - ) - ); - world.transferBalanceToNamespace(ROOT_NAMESPACE, namespace, value); + vm.expectRevert(abi.encodeWithSelector(IWorldErrors.AccessDenied.selector, ROOT_NAMESPACE_ID.toString(), caller)); + world.transferBalanceToNamespace(ROOT_NAMESPACE_ID, namespaceId, value); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect the non root namespace to have no balance - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); } function testTransferBalanceToAddress() public { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Send balance to root namespace vm.deal(caller, value); @@ -251,17 +246,17 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(data.length, 0); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect the receiver to not have any balance address receiver = address(1234); assertEq(receiver.balance, 0); // Transfer the balance to the receiver - world.transferBalanceToAddress(ROOT_NAMESPACE, receiver, value); + world.transferBalanceToAddress(ROOT_NAMESPACE_ID, receiver, value); // Expect the root namespace to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); // Expect the receiver to have value as balance assertEq(receiver.balance, value); @@ -271,8 +266,8 @@ contract WorldBalanceTest is Test, GasReporter { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Send balance to root namespace vm.deal(caller, value); @@ -282,7 +277,7 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(data.length, 0); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect the receiver to not have any balance address receiver = address(1234); @@ -290,10 +285,10 @@ contract WorldBalanceTest is Test, GasReporter { // Expect revert when attempting to transfer more than the balance vm.expectRevert(abi.encodeWithSelector(IWorldErrors.InsufficientBalance.selector, value, value + 1)); - world.transferBalanceToAddress(ROOT_NAMESPACE, receiver, value + 1); + world.transferBalanceToAddress(ROOT_NAMESPACE_ID, receiver, value + 1); // Expect the root namespace to have value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect the receiver to have no balance assertEq(receiver.balance, 0); @@ -303,8 +298,8 @@ contract WorldBalanceTest is Test, GasReporter { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Send balance to root namespace vm.deal(caller, value); @@ -314,7 +309,7 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(data.length, 0); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect the receiver to not have any balance address receiver = address(1234); @@ -329,10 +324,10 @@ contract WorldBalanceTest is Test, GasReporter { caller ) ); - world.transferBalanceToAddress(ROOT_NAMESPACE, receiver, value); + world.transferBalanceToAddress(ROOT_NAMESPACE_ID, receiver, value); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect the receiver to have no balance assertEq(receiver.balance, 0); diff --git a/packages/world/test/WorldDynamicUpdate.t.sol b/packages/world/test/WorldDynamicUpdate.t.sol index 707049148c..09918ec2c1 100644 --- a/packages/world/test/WorldDynamicUpdate.t.sol +++ b/packages/world/test/WorldDynamicUpdate.t.sol @@ -19,8 +19,6 @@ import { World } from "../src/World.sol"; import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "../src/WorldResourceId.sol"; import { RESOURCE_TABLE } from "../src/worldResourceTypes.sol"; -import { NamespaceOwner } from "../src/tables/NamespaceOwner.sol"; -import { ResourceAccess } from "../src/tables/ResourceAccess.sol"; import { AddressArray } from "./tables/AddressArray.sol"; import { CoreModule } from "../src/modules/core/CoreModule.sol";