From 5ea8fbb10e96f408c8da931b21c0bc4dd7efccfd Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 13:54:40 +0200 Subject: [PATCH 01/29] create sol files for erc20 --- .../world-modules/src/modules/erc20-own-store/IERC20Errors.sol | 0 .../world-modules/src/modules/erc20-own-store/IERC20Events.sol | 0 packages/world-modules/src/modules/erc20-own-store/MUDERC20.sol | 0 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/world-modules/src/modules/erc20-own-store/IERC20Errors.sol create mode 100644 packages/world-modules/src/modules/erc20-own-store/IERC20Events.sol create mode 100644 packages/world-modules/src/modules/erc20-own-store/MUDERC20.sol diff --git a/packages/world-modules/src/modules/erc20-own-store/IERC20Errors.sol b/packages/world-modules/src/modules/erc20-own-store/IERC20Errors.sol new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/world-modules/src/modules/erc20-own-store/IERC20Events.sol b/packages/world-modules/src/modules/erc20-own-store/IERC20Events.sol new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/world-modules/src/modules/erc20-own-store/MUDERC20.sol b/packages/world-modules/src/modules/erc20-own-store/MUDERC20.sol new file mode 100644 index 0000000000..e69de29bb2 From 35a50e5f3efbfb5f14f9e0e7580688cf5285cabc Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:09:07 +0200 Subject: [PATCH 02/29] add errors interface --- .../modules/erc20-own-store/IERC20Errors.sol | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/packages/world-modules/src/modules/erc20-own-store/IERC20Errors.sol b/packages/world-modules/src/modules/erc20-own-store/IERC20Errors.sol index e69de29bb2..a0b54b8c17 100644 --- a/packages/world-modules/src/modules/erc20-own-store/IERC20Errors.sol +++ b/packages/world-modules/src/modules/erc20-own-store/IERC20Errors.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.24; + +interface IERC20Errors { + /** + * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param balance Current balance for the interacting account. + * @param needed Minimum amount required to perform a transfer. + */ + error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC20InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC20InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. + * @param spender Address that may be allowed to operate on tokens without being their owner. + * @param allowance Amount of tokens a `spender` is allowed to operate with. + * @param needed Minimum amount required to perform a transfer. + */ + error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC20InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `spender` to be approved. Used in approvals. + * @param spender Address that may be allowed to operate on tokens without being their owner. + */ + error ERC20InvalidSpender(address spender); +} \ No newline at end of file From fc51ac369d01d176367148b01df204ab43cbad5a Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:09:16 +0200 Subject: [PATCH 03/29] add events interface --- .../modules/erc20-own-store/IERC20Events.sol | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/world-modules/src/modules/erc20-own-store/IERC20Events.sol b/packages/world-modules/src/modules/erc20-own-store/IERC20Events.sol index e69de29bb2..294271ba36 100644 --- a/packages/world-modules/src/modules/erc20-own-store/IERC20Events.sol +++ b/packages/world-modules/src/modules/erc20-own-store/IERC20Events.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.24; + +interface IERC20Events { + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); +} \ No newline at end of file From 65fcbc0ee5823647ea8e838a5a2fb281d2163fff Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:23:56 +0200 Subject: [PATCH 04/29] move interfaces to separate directory --- .../src/modules/erc20-own-store/{ => interfaces}/IERC20Errors.sol | 0 .../src/modules/erc20-own-store/{ => interfaces}/IERC20Events.sol | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename packages/world-modules/src/modules/erc20-own-store/{ => interfaces}/IERC20Errors.sol (100%) rename packages/world-modules/src/modules/erc20-own-store/{ => interfaces}/IERC20Events.sol (100%) diff --git a/packages/world-modules/src/modules/erc20-own-store/IERC20Errors.sol b/packages/world-modules/src/modules/erc20-own-store/interfaces/IERC20Errors.sol similarity index 100% rename from packages/world-modules/src/modules/erc20-own-store/IERC20Errors.sol rename to packages/world-modules/src/modules/erc20-own-store/interfaces/IERC20Errors.sol diff --git a/packages/world-modules/src/modules/erc20-own-store/IERC20Events.sol b/packages/world-modules/src/modules/erc20-own-store/interfaces/IERC20Events.sol similarity index 100% rename from packages/world-modules/src/modules/erc20-own-store/IERC20Events.sol rename to packages/world-modules/src/modules/erc20-own-store/interfaces/IERC20Events.sol From 54d86f18567f9602438cbb57518207b3cd000d70 Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:31:49 +0200 Subject: [PATCH 05/29] update comments --- packages/world-modules/mud.config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/world-modules/mud.config.ts b/packages/world-modules/mud.config.ts index 6bf21c83b2..aea3347784 100644 --- a/packages/world-modules/mud.config.ts +++ b/packages/world-modules/mud.config.ts @@ -147,7 +147,7 @@ export default defineWorld({ }, /************************************************************************ * - * ERC20 MODULE + * ERC20 PUPPET MODULE * ************************************************************************/ ERC20Metadata: { @@ -197,7 +197,7 @@ export default defineWorld({ }, /************************************************************************ * - * ERC721 MODULE + * ERC721 PUPPET MODULE * ************************************************************************/ ERC721Metadata: { From c4b6ba4caf816df45649f0b332018bd3bdf847e8 Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:41:02 +0200 Subject: [PATCH 06/29] create new package --- .../world-module-erc20-own-store/.gitignore | 2 + .../.solhint.json | 8 ++ .../world-module-erc20-own-store/CHANGELOG.md | 16 +++ .../world-module-erc20-own-store/foundry.toml | 15 +++ .../gas-report.json | 20 +++ .../interfaces/IERC20Errors.sol | 0 .../interfaces/IERC20Events.sol | 0 .../mud.config.ts | 30 +++++ .../world-module-erc20-own-store/package.json | 63 +++++++++ .../remappings.txt | 3 + .../src/MUDERC20.sol | 15 +++ .../test/MetadataModule.t.sol | 122 ++++++++++++++++++ .../world-module-erc20-own-store/ts/build.ts | 18 +++ .../tsconfig.json | 7 + .../tsup.config.ts | 13 ++ .../src/modules/erc20-own-store/MUDERC20.sol | 0 16 files changed, 332 insertions(+) create mode 100644 packages/world-module-erc20-own-store/.gitignore create mode 100644 packages/world-module-erc20-own-store/.solhint.json create mode 100644 packages/world-module-erc20-own-store/CHANGELOG.md create mode 100644 packages/world-module-erc20-own-store/foundry.toml create mode 100644 packages/world-module-erc20-own-store/gas-report.json rename packages/{world-modules/src/modules/erc20-own-store => world-module-erc20-own-store}/interfaces/IERC20Errors.sol (100%) rename packages/{world-modules/src/modules/erc20-own-store => world-module-erc20-own-store}/interfaces/IERC20Events.sol (100%) create mode 100644 packages/world-module-erc20-own-store/mud.config.ts create mode 100644 packages/world-module-erc20-own-store/package.json create mode 100644 packages/world-module-erc20-own-store/remappings.txt create mode 100644 packages/world-module-erc20-own-store/src/MUDERC20.sol create mode 100644 packages/world-module-erc20-own-store/test/MetadataModule.t.sol create mode 100644 packages/world-module-erc20-own-store/ts/build.ts create mode 100644 packages/world-module-erc20-own-store/tsconfig.json create mode 100644 packages/world-module-erc20-own-store/tsup.config.ts delete mode 100644 packages/world-modules/src/modules/erc20-own-store/MUDERC20.sol diff --git a/packages/world-module-erc20-own-store/.gitignore b/packages/world-module-erc20-own-store/.gitignore new file mode 100644 index 0000000000..1e4ded714a --- /dev/null +++ b/packages/world-module-erc20-own-store/.gitignore @@ -0,0 +1,2 @@ +cache +out diff --git a/packages/world-module-erc20-own-store/.solhint.json b/packages/world-module-erc20-own-store/.solhint.json new file mode 100644 index 0000000000..4e2baa8be7 --- /dev/null +++ b/packages/world-module-erc20-own-store/.solhint.json @@ -0,0 +1,8 @@ +{ + "extends": "solhint:recommended", + "rules": { + "compiler-version": ["error", ">=0.8.0"], + "avoid-low-level-calls": "off", + "func-visibility": ["warn", { "ignoreConstructors": true }] + } +} diff --git a/packages/world-module-erc20-own-store/CHANGELOG.md b/packages/world-module-erc20-own-store/CHANGELOG.md new file mode 100644 index 0000000000..bcab630758 --- /dev/null +++ b/packages/world-module-erc20-own-store/CHANGELOG.md @@ -0,0 +1,16 @@ +# @latticexyz/world-module-metadata + +## 2.1.1 + +### Patch Changes + +- 6a66f57: Refactored `AccessControl` library exported from `@latticexyz/world` to be usable outside of the world package and updated module packages to use it. +- fad4e85: Added metadata module to be automatically installed during world deploy. This module allows for tagging any resource with arbitrary metadata. Internally, we'll use this to tag resources with labels onchain so that we can use labels to create a MUD project from an existing world. +- Updated dependencies [9e21e42] +- Updated dependencies [6a66f57] +- Updated dependencies [86a8104] +- Updated dependencies [542ea54] +- Updated dependencies [57bf8c3] + - @latticexyz/schema-type@2.1.1 + - @latticexyz/store@2.1.1 + - @latticexyz/world@2.1.1 diff --git a/packages/world-module-erc20-own-store/foundry.toml b/packages/world-module-erc20-own-store/foundry.toml new file mode 100644 index 0000000000..f0e017f5a0 --- /dev/null +++ b/packages/world-module-erc20-own-store/foundry.toml @@ -0,0 +1,15 @@ +[profile.default] +solc = "0.8.24" +ffi = false +fuzz_runs = 256 +optimizer = true +optimizer_runs = 3000 +verbosity = 2 +allow_paths = ["../../node_modules", "../"] +src = "src" +out = "out" +bytecode_hash = "none" +extra_output_files = [ + "abi", + "evm.bytecode" +] diff --git a/packages/world-module-erc20-own-store/gas-report.json b/packages/world-module-erc20-own-store/gas-report.json new file mode 100644 index 0000000000..3709dce3c6 --- /dev/null +++ b/packages/world-module-erc20-own-store/gas-report.json @@ -0,0 +1,20 @@ +[ + { + "file": "test/MetadataModule.t.sol", + "test": "testDeleteResourceTag", + "name": "delete resource tag", + "gasUsed": 70301 + }, + { + "file": "test/MetadataModule.t.sol", + "test": "testInstall", + "name": "install metadata module", + "gasUsed": 1109853 + }, + { + "file": "test/MetadataModule.t.sol", + "test": "testSetResourceTag", + "name": "set resource tag", + "gasUsed": 116708 + } +] diff --git a/packages/world-modules/src/modules/erc20-own-store/interfaces/IERC20Errors.sol b/packages/world-module-erc20-own-store/interfaces/IERC20Errors.sol similarity index 100% rename from packages/world-modules/src/modules/erc20-own-store/interfaces/IERC20Errors.sol rename to packages/world-module-erc20-own-store/interfaces/IERC20Errors.sol diff --git a/packages/world-modules/src/modules/erc20-own-store/interfaces/IERC20Events.sol b/packages/world-module-erc20-own-store/interfaces/IERC20Events.sol similarity index 100% rename from packages/world-modules/src/modules/erc20-own-store/interfaces/IERC20Events.sol rename to packages/world-module-erc20-own-store/interfaces/IERC20Events.sol diff --git a/packages/world-module-erc20-own-store/mud.config.ts b/packages/world-module-erc20-own-store/mud.config.ts new file mode 100644 index 0000000000..6880b0a385 --- /dev/null +++ b/packages/world-module-erc20-own-store/mud.config.ts @@ -0,0 +1,30 @@ +import { defineWorld } from "@latticexyz/world"; + +export default defineWorld({ + namespace: "erc20", + tables: { + MUDERC20: { + schema: { + totalSupply: "uint256", + id: "bytes32", + _name: "string", + _symbol: "string", + }, + key: ["id"], + }, + BALANCES: { + schema: { + account: "address", + balance: "uint256", + }, + key: ["account"], + }, + APPROVALS: { + schema: { + account: "address", + approval: "uint256", + }, + key: ["account"], + }, + }, +}); \ No newline at end of file diff --git a/packages/world-module-erc20-own-store/package.json b/packages/world-module-erc20-own-store/package.json new file mode 100644 index 0000000000..980575a713 --- /dev/null +++ b/packages/world-module-erc20-own-store/package.json @@ -0,0 +1,63 @@ +{ + "name": "@latticexyz/world-module-metadata", + "version": "2.1.1", + "description": "Metadata world module", + "repository": { + "type": "git", + "url": "https://github.com/latticexyz/mud.git", + "directory": "packages/world-module-metadata" + }, + "license": "MIT", + "type": "module", + "exports": { + "./mud.config": "./dist/mud.config.js", + "./out/*": "./out/*" + }, + "typesVersions": { + "*": { + "mud.config": [ + "./dist/mud.config.d.ts" + ] + } + }, + "files": [ + "dist", + "out", + "src" + ], + "scripts": { + "build": "pnpm run build:mud && pnpm run build:abi && pnpm run build:abi-ts && pnpm run build:js", + "build:abi": "forge build", + "build:abi-ts": "abi-ts", + "build:js": "tsup", + "build:mud": "tsx ./ts/build.ts", + "clean": "pnpm run clean:abi && pnpm run clean:js && pnpm run clean:mud", + "clean:abi": "forge clean", + "clean:js": "rimraf dist", + "clean:mud": "rimraf src/**/codegen", + "dev": "tsup --watch", + "gas-report": "gas-report --save gas-report.json", + "lint": "solhint --config ./.solhint.json 'src/**/*.sol'", + "test": "forge test", + "test:ci": "pnpm run test" + }, + "dependencies": { + "@latticexyz/schema-type": "workspace:*", + "@latticexyz/store": "workspace:*", + "@latticexyz/world": "workspace:*" + }, + "devDependencies": { + "@latticexyz/abi-ts": "workspace:*", + "@latticexyz/gas-report": "workspace:*", + "@types/node": "^18.15.11", + "ds-test": "https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0", + "forge-std": "https://github.com/foundry-rs/forge-std.git#74cfb77e308dd188d2f58864aaf44963ae6b88b1", + "solhint": "^3.3.7", + "tsup": "^6.7.0", + "tsx": "^3.12.6", + "vitest": "0.34.6" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/world-module-erc20-own-store/remappings.txt b/packages/world-module-erc20-own-store/remappings.txt new file mode 100644 index 0000000000..66be45ecbd --- /dev/null +++ b/packages/world-module-erc20-own-store/remappings.txt @@ -0,0 +1,3 @@ +ds-test/=node_modules/ds-test/src/ +forge-std/=node_modules/forge-std/src/ +@latticexyz/=node_modules/@latticexyz/ \ No newline at end of file diff --git a/packages/world-module-erc20-own-store/src/MUDERC20.sol b/packages/world-module-erc20-own-store/src/MUDERC20.sol new file mode 100644 index 0000000000..0d16558b57 --- /dev/null +++ b/packages/world-module-erc20-own-store/src/MUDERC20.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import { IERC20Errors } from "./interfaces/IERC20Errors.sol"; +import { IERC20Events } from "./interfaces/IERC20Events.sol"; + +import { Store } from "@latticexyz/store/src/Store.sol"; + +contract MUDERC20 is Store, IERC20Errors, IERC20Events { + + constructor(string memory _name, string memory _symbol, uint8 _decimals) { + + } + +} \ No newline at end of file diff --git a/packages/world-module-erc20-own-store/test/MetadataModule.t.sol b/packages/world-module-erc20-own-store/test/MetadataModule.t.sol new file mode 100644 index 0000000000..a1c3911ff1 --- /dev/null +++ b/packages/world-module-erc20-own-store/test/MetadataModule.t.sol @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.24; + +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; + +import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; +import { createWorld } from "@latticexyz/world/test/createWorld.sol"; +import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "@latticexyz/world/src/WorldResourceId.sol"; +import { IWorldErrors } from "@latticexyz/world/src/IWorldErrors.sol"; +import { IModuleErrors } from "@latticexyz/world/src/IModuleErrors.sol"; +import { NamespaceOwner } from "@latticexyz/world/src/codegen/tables/NamespaceOwner.sol"; + +import { MetadataModule } from "../src/MetadataModule.sol"; +import { IWorld } from "../src/codegen/world/IWorld.sol"; +import { ResourceTag } from "../src/codegen/tables/ResourceTag.sol"; + +contract MetadataModuleTest is Test, GasReporter { + using WorldResourceIdInstance for ResourceId; + + IWorld world; + MetadataModule metadataModule = new MetadataModule(); + ResourceId namespace = ResourceTag._tableId.getNamespaceId(); + + function setUp() public { + world = IWorld(address(createWorld())); + StoreSwitch.setStoreAddress(address(world)); + } + + function testInstall() public { + startGasReport("install metadata module"); + world.installModule(metadataModule, new bytes(0)); + endGasReport(); + + assertEq(NamespaceOwner.get(namespace), address(this)); + + vm.expectRevert(IModuleErrors.Module_AlreadyInstalled.selector); + world.installModule(metadataModule, new bytes(0)); + } + + function testInstallExistingNamespace() public { + world.registerNamespace(namespace); + + // Installing will revert because metadata namespace isn't owned by the module, so the module is unable to write to it. + vm.expectRevert( + abi.encodeWithSelector(IWorldErrors.World_AccessDenied.selector, namespace.toString(), address(metadataModule)) + ); + world.installModule(metadataModule, new bytes(0)); + + // Transferring the namespace to the module and installing will return namespace ownership. + world.transferOwnership(namespace, address(metadataModule)); + world.installModule(metadataModule, new bytes(0)); + assertEq(NamespaceOwner.get(namespace), address(this)); + } + + function testSetResourceTag() public { + world.installModule(metadataModule, new bytes(0)); + ResourceId resource = ResourceTag._tableId; + + assertEq(world.metadata__getResourceTag(resource, "label"), ""); + assertEq(ResourceTag.get(resource, "label"), ""); + + startGasReport("set resource tag"); + world.metadata__setResourceTag(resource, "label", "ResourceTag"); + endGasReport(); + + assertEq(world.metadata__getResourceTag(resource, "label"), "ResourceTag"); + assertEq(ResourceTag.get(resource, "label"), "ResourceTag"); + + // metadata is mutable, so make sure we can mutate it + world.metadata__setResourceTag(resource, "label", "Resource"); + assertEq(world.metadata__getResourceTag(resource, "label"), "Resource"); + assertEq(ResourceTag.get(resource, "label"), "Resource"); + } + + function testDeleteResourceTag() public { + world.installModule(metadataModule, new bytes(0)); + ResourceId resource = ResourceTag._tableId; + + world.metadata__setResourceTag(resource, "label", "ResourceTag"); + assertEq(ResourceTag.get(resource, "label"), "ResourceTag"); + assertEq(world.metadata__getResourceTag(resource, "label"), "ResourceTag"); + + startGasReport("delete resource tag"); + world.metadata__deleteResourceTag(resource, "label"); + endGasReport(); + + assertEq(world.metadata__getResourceTag(resource, "label"), ""); + assertEq(ResourceTag.get(resource, "label"), ""); + } + + function testTagNonexistentResource() public { + world.installModule(metadataModule, new bytes(0)); + ResourceId resource = WorldResourceIdLib.encode("tb", "whatever", "SomeTable"); + + vm.expectRevert( + abi.encodeWithSelector(IWorldErrors.World_ResourceNotFound.selector, resource, resource.toString()) + ); + world.metadata__setResourceTag(resource, "label", "SomeTable"); + + vm.expectRevert( + abi.encodeWithSelector(IWorldErrors.World_ResourceNotFound.selector, resource, resource.toString()) + ); + world.metadata__deleteResourceTag(resource, "label"); + } + + function testTagUnownedResource(address caller) public { + vm.assume(caller != address(0)); + vm.assume(caller != address(this)); + + world.installModule(metadataModule, new bytes(0)); + ResourceId resource = NamespaceOwner._tableId; + + vm.startPrank(caller); + + vm.expectRevert(abi.encodeWithSelector(IWorldErrors.World_AccessDenied.selector, resource.toString(), caller)); + world.metadata__setResourceTag(resource, "label", "NamespaceOwner"); + + vm.expectRevert(abi.encodeWithSelector(IWorldErrors.World_AccessDenied.selector, resource.toString(), caller)); + world.metadata__deleteResourceTag(resource, "label"); + } +} diff --git a/packages/world-module-erc20-own-store/ts/build.ts b/packages/world-module-erc20-own-store/ts/build.ts new file mode 100644 index 0000000000..9f24536f54 --- /dev/null +++ b/packages/world-module-erc20-own-store/ts/build.ts @@ -0,0 +1,18 @@ +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { tablegen } from "@latticexyz/store/codegen"; +import { worldgen } from "@latticexyz/world/node"; + +/** + * To avoid circular dependencies, we run a very similar `build` step as `cli` package here. + */ + +// TODO: move tablegen/worldgen to CLI commands from store/world we can run in package.json instead of a custom script +// (https://github.com/latticexyz/mud/issues/3030) + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const configPath = "../mud.config"; + +const { default: config } = await import(configPath); +const rootDir = path.dirname(path.join(__dirname, configPath)); +await Promise.all([tablegen({ rootDir, config }), worldgen({ rootDir, config })]); diff --git a/packages/world-module-erc20-own-store/tsconfig.json b/packages/world-module-erc20-own-store/tsconfig.json new file mode 100644 index 0000000000..9b0bf57752 --- /dev/null +++ b/packages/world-module-erc20-own-store/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": ["mud.config.ts", "ts"] +} diff --git a/packages/world-module-erc20-own-store/tsup.config.ts b/packages/world-module-erc20-own-store/tsup.config.ts new file mode 100644 index 0000000000..a89281f3d6 --- /dev/null +++ b/packages/world-module-erc20-own-store/tsup.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: { + "mud.config": "mud.config.ts", + }, + target: "esnext", + format: ["esm"], + dts: !process.env.TSUP_SKIP_DTS, + sourcemap: true, + clean: true, + minify: true, +}); diff --git a/packages/world-modules/src/modules/erc20-own-store/MUDERC20.sol b/packages/world-modules/src/modules/erc20-own-store/MUDERC20.sol deleted file mode 100644 index e69de29bb2..0000000000 From a9e6fdd7ecb7776e3b9dc0237b824b095bf9b677 Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:41:09 +0200 Subject: [PATCH 07/29] update README --- packages/world-module-erc20-own-store/README.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/world-module-erc20-own-store/README.md diff --git a/packages/world-module-erc20-own-store/README.md b/packages/world-module-erc20-own-store/README.md new file mode 100644 index 0000000000..d04dc67a30 --- /dev/null +++ b/packages/world-module-erc20-own-store/README.md @@ -0,0 +1,5 @@ +# Standalone ERC20 Module with own Store + +This is an `ERC20` token template that is compatible with the MUD framework. The logic of the token contract is near native and resides within the token contract, while its storage makes use of `Store` and is reflected in corresponding tables. + +The `OpenZeppelin` implementation of ERC20 will is used as reference but tests are written in `Solidity`. From 32950eb230983af3bd012dff20e9c31709105dca Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:41:31 +0200 Subject: [PATCH 08/29] update README --- packages/world-module-erc20-own-store/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/world-module-erc20-own-store/README.md b/packages/world-module-erc20-own-store/README.md index d04dc67a30..232bc049c9 100644 --- a/packages/world-module-erc20-own-store/README.md +++ b/packages/world-module-erc20-own-store/README.md @@ -2,4 +2,4 @@ This is an `ERC20` token template that is compatible with the MUD framework. The logic of the token contract is near native and resides within the token contract, while its storage makes use of `Store` and is reflected in corresponding tables. -The `OpenZeppelin` implementation of ERC20 will is used as reference but tests are written in `Solidity`. +The `OpenZeppelin` implementation of ERC20 is used as reference but tests are written in `Solidity`. From 64ef67ace71e5033120af4f0e3f2414f82ed33f9 Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:46:11 +0200 Subject: [PATCH 09/29] rm old test file --- .../test/MetadataModule.t.sol | 122 ------------------ 1 file changed, 122 deletions(-) delete mode 100644 packages/world-module-erc20-own-store/test/MetadataModule.t.sol diff --git a/packages/world-module-erc20-own-store/test/MetadataModule.t.sol b/packages/world-module-erc20-own-store/test/MetadataModule.t.sol deleted file mode 100644 index a1c3911ff1..0000000000 --- a/packages/world-module-erc20-own-store/test/MetadataModule.t.sol +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.24; - -import { Test } from "forge-std/Test.sol"; -import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; - -import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; -import { createWorld } from "@latticexyz/world/test/createWorld.sol"; -import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "@latticexyz/world/src/WorldResourceId.sol"; -import { IWorldErrors } from "@latticexyz/world/src/IWorldErrors.sol"; -import { IModuleErrors } from "@latticexyz/world/src/IModuleErrors.sol"; -import { NamespaceOwner } from "@latticexyz/world/src/codegen/tables/NamespaceOwner.sol"; - -import { MetadataModule } from "../src/MetadataModule.sol"; -import { IWorld } from "../src/codegen/world/IWorld.sol"; -import { ResourceTag } from "../src/codegen/tables/ResourceTag.sol"; - -contract MetadataModuleTest is Test, GasReporter { - using WorldResourceIdInstance for ResourceId; - - IWorld world; - MetadataModule metadataModule = new MetadataModule(); - ResourceId namespace = ResourceTag._tableId.getNamespaceId(); - - function setUp() public { - world = IWorld(address(createWorld())); - StoreSwitch.setStoreAddress(address(world)); - } - - function testInstall() public { - startGasReport("install metadata module"); - world.installModule(metadataModule, new bytes(0)); - endGasReport(); - - assertEq(NamespaceOwner.get(namespace), address(this)); - - vm.expectRevert(IModuleErrors.Module_AlreadyInstalled.selector); - world.installModule(metadataModule, new bytes(0)); - } - - function testInstallExistingNamespace() public { - world.registerNamespace(namespace); - - // Installing will revert because metadata namespace isn't owned by the module, so the module is unable to write to it. - vm.expectRevert( - abi.encodeWithSelector(IWorldErrors.World_AccessDenied.selector, namespace.toString(), address(metadataModule)) - ); - world.installModule(metadataModule, new bytes(0)); - - // Transferring the namespace to the module and installing will return namespace ownership. - world.transferOwnership(namespace, address(metadataModule)); - world.installModule(metadataModule, new bytes(0)); - assertEq(NamespaceOwner.get(namespace), address(this)); - } - - function testSetResourceTag() public { - world.installModule(metadataModule, new bytes(0)); - ResourceId resource = ResourceTag._tableId; - - assertEq(world.metadata__getResourceTag(resource, "label"), ""); - assertEq(ResourceTag.get(resource, "label"), ""); - - startGasReport("set resource tag"); - world.metadata__setResourceTag(resource, "label", "ResourceTag"); - endGasReport(); - - assertEq(world.metadata__getResourceTag(resource, "label"), "ResourceTag"); - assertEq(ResourceTag.get(resource, "label"), "ResourceTag"); - - // metadata is mutable, so make sure we can mutate it - world.metadata__setResourceTag(resource, "label", "Resource"); - assertEq(world.metadata__getResourceTag(resource, "label"), "Resource"); - assertEq(ResourceTag.get(resource, "label"), "Resource"); - } - - function testDeleteResourceTag() public { - world.installModule(metadataModule, new bytes(0)); - ResourceId resource = ResourceTag._tableId; - - world.metadata__setResourceTag(resource, "label", "ResourceTag"); - assertEq(ResourceTag.get(resource, "label"), "ResourceTag"); - assertEq(world.metadata__getResourceTag(resource, "label"), "ResourceTag"); - - startGasReport("delete resource tag"); - world.metadata__deleteResourceTag(resource, "label"); - endGasReport(); - - assertEq(world.metadata__getResourceTag(resource, "label"), ""); - assertEq(ResourceTag.get(resource, "label"), ""); - } - - function testTagNonexistentResource() public { - world.installModule(metadataModule, new bytes(0)); - ResourceId resource = WorldResourceIdLib.encode("tb", "whatever", "SomeTable"); - - vm.expectRevert( - abi.encodeWithSelector(IWorldErrors.World_ResourceNotFound.selector, resource, resource.toString()) - ); - world.metadata__setResourceTag(resource, "label", "SomeTable"); - - vm.expectRevert( - abi.encodeWithSelector(IWorldErrors.World_ResourceNotFound.selector, resource, resource.toString()) - ); - world.metadata__deleteResourceTag(resource, "label"); - } - - function testTagUnownedResource(address caller) public { - vm.assume(caller != address(0)); - vm.assume(caller != address(this)); - - world.installModule(metadataModule, new bytes(0)); - ResourceId resource = NamespaceOwner._tableId; - - vm.startPrank(caller); - - vm.expectRevert(abi.encodeWithSelector(IWorldErrors.World_AccessDenied.selector, resource.toString(), caller)); - world.metadata__setResourceTag(resource, "label", "NamespaceOwner"); - - vm.expectRevert(abi.encodeWithSelector(IWorldErrors.World_AccessDenied.selector, resource.toString(), caller)); - world.metadata__deleteResourceTag(resource, "label"); - } -} From ecb042b9e41bf8a6cd584a24fafb0747253801df Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:48:06 +0200 Subject: [PATCH 10/29] update package.json --- packages/world-module-metadata/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/world-module-metadata/package.json b/packages/world-module-metadata/package.json index 980575a713..1e21616c84 100644 --- a/packages/world-module-metadata/package.json +++ b/packages/world-module-metadata/package.json @@ -1,11 +1,11 @@ { - "name": "@latticexyz/world-module-metadata", + "name": "@latticexyz/world-module-erc20-own-store", "version": "2.1.1", - "description": "Metadata world module", + "description": "ERC20 World Module with Own Store", "repository": { "type": "git", "url": "https://github.com/latticexyz/mud.git", - "directory": "packages/world-module-metadata" + "directory": "packages/world-module-erc20-own-store" }, "license": "MIT", "type": "module", From 66f8e76c5ef16ecc0034a5986b796e49e52dc235 Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:48:32 +0200 Subject: [PATCH 11/29] rm old changelog --- packages/world-module-metadata/CHANGELOG.md | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 packages/world-module-metadata/CHANGELOG.md diff --git a/packages/world-module-metadata/CHANGELOG.md b/packages/world-module-metadata/CHANGELOG.md deleted file mode 100644 index bcab630758..0000000000 --- a/packages/world-module-metadata/CHANGELOG.md +++ /dev/null @@ -1,16 +0,0 @@ -# @latticexyz/world-module-metadata - -## 2.1.1 - -### Patch Changes - -- 6a66f57: Refactored `AccessControl` library exported from `@latticexyz/world` to be usable outside of the world package and updated module packages to use it. -- fad4e85: Added metadata module to be automatically installed during world deploy. This module allows for tagging any resource with arbitrary metadata. Internally, we'll use this to tag resources with labels onchain so that we can use labels to create a MUD project from an existing world. -- Updated dependencies [9e21e42] -- Updated dependencies [6a66f57] -- Updated dependencies [86a8104] -- Updated dependencies [542ea54] -- Updated dependencies [57bf8c3] - - @latticexyz/schema-type@2.1.1 - - @latticexyz/store@2.1.1 - - @latticexyz/world@2.1.1 From a479aae8c0740bbd8c1a799247127482d9bf1267 Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:50:32 +0200 Subject: [PATCH 12/29] update package.json --- packages/world-module-erc20-own-store/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/world-module-erc20-own-store/package.json b/packages/world-module-erc20-own-store/package.json index 980575a713..1e21616c84 100644 --- a/packages/world-module-erc20-own-store/package.json +++ b/packages/world-module-erc20-own-store/package.json @@ -1,11 +1,11 @@ { - "name": "@latticexyz/world-module-metadata", + "name": "@latticexyz/world-module-erc20-own-store", "version": "2.1.1", - "description": "Metadata world module", + "description": "ERC20 World Module with Own Store", "repository": { "type": "git", "url": "https://github.com/latticexyz/mud.git", - "directory": "packages/world-module-metadata" + "directory": "packages/world-module-erc20-own-store" }, "license": "MIT", "type": "module", From 752c0e4830266429de8d6a28d70ae0ba9deeda7d Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:50:38 +0200 Subject: [PATCH 13/29] undo prev commit --- packages/world-module-metadata/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/world-module-metadata/package.json b/packages/world-module-metadata/package.json index 1e21616c84..980575a713 100644 --- a/packages/world-module-metadata/package.json +++ b/packages/world-module-metadata/package.json @@ -1,11 +1,11 @@ { - "name": "@latticexyz/world-module-erc20-own-store", + "name": "@latticexyz/world-module-metadata", "version": "2.1.1", - "description": "ERC20 World Module with Own Store", + "description": "Metadata world module", "repository": { "type": "git", "url": "https://github.com/latticexyz/mud.git", - "directory": "packages/world-module-erc20-own-store" + "directory": "packages/world-module-metadata" }, "license": "MIT", "type": "module", From 2d4e264daa9b5968d298ef1abbc24da80b469f9b Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:51:06 +0200 Subject: [PATCH 14/29] mv changelog to correct directory --- .../CHANGELOG.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/{world-module-erc20-own-store => world-module-metadata}/CHANGELOG.md (100%) diff --git a/packages/world-module-erc20-own-store/CHANGELOG.md b/packages/world-module-metadata/CHANGELOG.md similarity index 100% rename from packages/world-module-erc20-own-store/CHANGELOG.md rename to packages/world-module-metadata/CHANGELOG.md From b44c3ab4bc9b830f445013999f3f560339fe84d6 Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 15:04:56 +0200 Subject: [PATCH 15/29] add mud config --- .../mud.config.ts | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/world-module-erc20-own-store/mud.config.ts b/packages/world-module-erc20-own-store/mud.config.ts index 6880b0a385..f166296988 100644 --- a/packages/world-module-erc20-own-store/mud.config.ts +++ b/packages/world-module-erc20-own-store/mud.config.ts @@ -1,30 +1,41 @@ import { defineWorld } from "@latticexyz/world"; export default defineWorld({ - namespace: "erc20", + namespace: "erc20-own-store", tables: { MUDERC20: { schema: { totalSupply: "uint256", id: "bytes32", - _name: "string", - _symbol: "string", + name: "string", + symbol: "string", }, key: ["id"], + codegen: { + outputDirectory: "./tables", + tableIdArgument: true, + }, }, - BALANCES: { + Balances: { schema: { account: "address", balance: "uint256", }, key: ["account"], + codegen: { + outputDirectory: "./tables", + }, }, - APPROVALS: { + Allowances: { schema: { account: "address", + spender: "address", approval: "uint256", }, - key: ["account"], + key: ["account", "spender"], + codegen: { + outputDirectory: "./tables", + }, }, }, }); \ No newline at end of file From 81b5a5fe3e3023505f579dfd7a8b4ae78ce58029 Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 15:06:44 +0200 Subject: [PATCH 16/29] update config --- packages/world-module-erc20-own-store/mud.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/world-module-erc20-own-store/mud.config.ts b/packages/world-module-erc20-own-store/mud.config.ts index f166296988..f0ba5caa28 100644 --- a/packages/world-module-erc20-own-store/mud.config.ts +++ b/packages/world-module-erc20-own-store/mud.config.ts @@ -5,6 +5,7 @@ export default defineWorld({ tables: { MUDERC20: { schema: { + decimals: "uint8", totalSupply: "uint256", id: "bytes32", name: "string", From 5ac39db943fa7ade0746ebf217e313bd753cd56e Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 15:12:25 +0200 Subject: [PATCH 17/29] rm gas-report.json --- .../gas-report.json | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 packages/world-module-erc20-own-store/gas-report.json diff --git a/packages/world-module-erc20-own-store/gas-report.json b/packages/world-module-erc20-own-store/gas-report.json deleted file mode 100644 index 3709dce3c6..0000000000 --- a/packages/world-module-erc20-own-store/gas-report.json +++ /dev/null @@ -1,20 +0,0 @@ -[ - { - "file": "test/MetadataModule.t.sol", - "test": "testDeleteResourceTag", - "name": "delete resource tag", - "gasUsed": 70301 - }, - { - "file": "test/MetadataModule.t.sol", - "test": "testInstall", - "name": "install metadata module", - "gasUsed": 1109853 - }, - { - "file": "test/MetadataModule.t.sol", - "test": "testSetResourceTag", - "name": "set resource tag", - "gasUsed": 116708 - } -] From 3048dbe528a50e2c9e3b8ebe12551a964294557e Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 17:22:33 +0200 Subject: [PATCH 18/29] update lockfile --- pnpm-lock.yaml | 277 +++++++++++++++++++++++-------------------------- 1 file changed, 131 insertions(+), 146 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dbc39ae942..44a1b5cbf0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -113,7 +113,7 @@ importers: version: 6.7.0(postcss@8.4.31)(typescript@5.4.2) vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/block-logs-stream: dependencies: @@ -141,7 +141,7 @@ importers: version: 6.7.0(postcss@8.4.31)(typescript@5.4.2) vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/cli: dependencies: @@ -277,7 +277,7 @@ importers: version: 3.12.6 vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/common: dependencies: @@ -329,7 +329,7 @@ importers: version: 6.7.0(postcss@8.4.31)(typescript@5.4.2) vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/config: dependencies: @@ -443,7 +443,7 @@ importers: version: 6.7.0(postcss@8.4.23)(typescript@5.4.2) vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/explorer: dependencies: @@ -634,7 +634,7 @@ importers: version: 3.12.6 vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/gas-report: dependencies: @@ -680,7 +680,7 @@ importers: version: 6.7.0(postcss@8.4.31)(typescript@5.4.2) vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/protocol-parser: dependencies: @@ -705,7 +705,7 @@ importers: version: 6.7.0(postcss@8.4.31)(typescript@5.4.2) vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/query: dependencies: @@ -733,7 +733,7 @@ importers: version: 6.7.0(postcss@8.4.31)(typescript@5.4.2) vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/react: dependencies: @@ -764,7 +764,7 @@ importers: version: 18.2.22 '@vitejs/plugin-react': specifier: ^4.0.0 - version: 4.0.0(vite@4.3.6(@types/node@20.12.12)) + version: 4.0.0(vite@4.3.6(@types/node@20.12.12)(terser@5.31.6)) eslint-plugin-react: specifier: 7.31.11 version: 7.31.11(eslint@8.57.0) @@ -782,10 +782,10 @@ importers: version: 6.7.0(postcss@8.4.31)(typescript@5.4.2) vite: specifier: ^4.3.6 - version: 4.3.6(@types/node@20.12.12) + version: 4.3.6(@types/node@20.12.12)(terser@5.31.6) vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/recs: dependencies: @@ -813,7 +813,7 @@ importers: version: 29.5.0(@types/node@18.15.11) ts-jest: specifier: ^29.0.5 - version: 29.0.5(@babel/core@7.21.4)(@jest/types@29.5.0)(babel-jest@29.5.0(@babel/core@7.21.4))(jest@29.5.0(@types/node@18.15.11))(typescript@5.4.2) + version: 29.0.5(@babel/core@7.21.4)(@jest/types@29.6.3)(babel-jest@29.5.0(@babel/core@7.21.4))(jest@29.5.0(@types/node@18.15.11))(typescript@5.4.2) tsup: specifier: ^6.7.0 version: 6.7.0(postcss@8.4.31)(typescript@5.4.2) @@ -844,7 +844,7 @@ importers: version: 6.7.0(postcss@8.4.31)(typescript@5.4.2) vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/solhint-config-mud: devDependencies: @@ -924,7 +924,7 @@ importers: version: 3.12.6 vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/store-indexer: dependencies: @@ -1039,7 +1039,7 @@ importers: version: 3.12.6 vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/store-sync: dependencies: @@ -1136,7 +1136,7 @@ importers: version: 6.7.0(postcss@8.4.31)(typescript@5.4.2) vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/utils: dependencies: @@ -1158,7 +1158,7 @@ importers: version: 29.5.0(@types/node@20.12.12) ts-jest: specifier: ^29.0.5 - version: 29.0.5(@babel/core@7.21.4)(@jest/types@29.5.0)(babel-jest@29.5.0(@babel/core@7.21.4))(jest@29.5.0(@types/node@20.12.12))(typescript@5.4.2) + version: 29.0.5(@babel/core@7.21.4)(@jest/types@29.6.3)(babel-jest@29.5.0(@babel/core@7.21.4))(jest@29.5.0(@types/node@20.12.12))(typescript@5.4.2) tsup: specifier: ^6.7.0 version: 6.7.0(postcss@8.4.31)(typescript@5.4.2) @@ -1237,7 +1237,47 @@ importers: version: 3.12.6 vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) + + packages/world-module-erc20-own-store: + dependencies: + '@latticexyz/schema-type': + specifier: workspace:* + version: link:../schema-type + '@latticexyz/store': + specifier: workspace:* + version: link:../store + '@latticexyz/world': + specifier: workspace:* + version: link:../world + devDependencies: + '@latticexyz/abi-ts': + specifier: workspace:* + version: link:../abi-ts + '@latticexyz/gas-report': + specifier: workspace:* + version: link:../gas-report + '@types/node': + specifier: ^18.15.11 + version: 18.15.11 + ds-test: + specifier: https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0 + version: https://codeload.github.com/dapphub/ds-test/tar.gz/e282159d5170298eb2455a6c05280ab5a73a4ef0 + forge-std: + specifier: https://github.com/foundry-rs/forge-std.git#74cfb77e308dd188d2f58864aaf44963ae6b88b1 + version: https://codeload.github.com/foundry-rs/forge-std/tar.gz/74cfb77e308dd188d2f58864aaf44963ae6b88b1 + solhint: + specifier: ^3.3.7 + version: 3.3.7 + tsup: + specifier: ^6.7.0 + version: 6.7.0(postcss@8.4.31)(typescript@5.4.2) + tsx: + specifier: ^3.12.6 + version: 3.12.6 + vitest: + specifier: 0.34.6 + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/world-module-metadata: dependencies: @@ -1277,7 +1317,7 @@ importers: version: 3.12.6 vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) packages/world-modules: dependencies: @@ -1338,7 +1378,7 @@ importers: version: 3.12.6 vitest: specifier: 0.34.6 - version: 0.34.6(jsdom@22.1.0) + version: 0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6) test/mock-game-contracts: devDependencies: @@ -1386,7 +1426,7 @@ importers: version: 2.19.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) vite: specifier: ^4.2.1 - version: 4.3.6(@types/node@20.12.12) + version: 4.3.6(@types/node@20.12.12)(terser@5.31.6) packages: @@ -2996,10 +3036,6 @@ packages: node-notifier: optional: true - '@jest/schemas@29.4.3': - resolution: {integrity: sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jest/schemas@29.6.3': resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -4220,9 +4256,6 @@ packages: '@sideway/pinpoint@2.0.0': resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} - '@sinclair/typebox@0.25.24': - resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==} - '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} @@ -6786,9 +6819,6 @@ packages: resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} - get-tsconfig@4.5.0: - resolution: {integrity: sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==} - get-tsconfig@4.7.5: resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} @@ -7661,9 +7691,6 @@ packages: engines: {node: '>=6'} hasBin: true - jsonc-parser@3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} - jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -8138,9 +8165,6 @@ packages: engines: {node: '>=10'} hasBin: true - mlly@1.5.0: - resolution: {integrity: sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==} - mlly@1.7.1: resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} @@ -8688,9 +8712,6 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} - pkg-types@1.0.3: - resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} - pkg-types@1.1.3: resolution: {integrity: sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==} @@ -8882,10 +8903,6 @@ packages: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} - pretty-format@29.5.0: - resolution: {integrity: sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -10155,9 +10172,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - ufo@1.3.2: - resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} - ufo@1.5.4: resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} @@ -11273,7 +11287,7 @@ snapshots: '@babel/helper-plugin-utils': 7.24.8 debug: 4.3.4 lodash.debounce: 4.0.8 - resolve: 1.22.2 + resolve: 1.22.8 transitivePeerDependencies: - supports-color @@ -11482,7 +11496,7 @@ snapshots: dependencies: '@babel/core': 7.21.4 '@babel/helper-create-class-features-plugin': 7.25.0(@babel/core@7.21.4) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.24.8 transitivePeerDependencies: - supports-color @@ -11495,13 +11509,13 @@ snapshots: '@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.21.4)': dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.24.8 '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.21.4) '@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.21.4)': dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.21.4) transitivePeerDependencies: @@ -11534,7 +11548,7 @@ snapshots: '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.21.4)': dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.24.8 '@babel/plugin-syntax-export-default-from@7.24.7(@babel/core@7.21.4)': dependencies: @@ -12121,7 +12135,7 @@ snapshots: dependencies: '@babel/core': 7.21.4 '@babel/helper-plugin-utils': 7.24.8 - '@babel/types': 7.21.4 + '@babel/types': 7.25.2 esutils: 2.0.3 '@babel/preset-typescript@7.24.7(@babel/core@7.21.4)': @@ -12409,7 +12423,7 @@ snapshots: '@esbuild-kit/cjs-loader@2.4.2': dependencies: '@esbuild-kit/core-utils': 3.1.0 - get-tsconfig: 4.5.0 + get-tsconfig: 4.7.5 '@esbuild-kit/core-utils@3.1.0': dependencies: @@ -12419,7 +12433,7 @@ snapshots: '@esbuild-kit/esm-loader@2.5.5': dependencies: '@esbuild-kit/core-utils': 3.1.0 - get-tsconfig: 4.5.0 + get-tsconfig: 4.7.5 '@esbuild/aix-ppc64@0.21.5': optional: true @@ -12795,7 +12809,7 @@ snapshots: jest-validate: 29.5.0 jest-watcher: 29.5.0 micromatch: 4.0.5 - pretty-format: 29.5.0 + pretty-format: 29.7.0 slash: 3.0.0 strip-ansi: 6.0.1 transitivePeerDependencies: @@ -12887,10 +12901,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@jest/schemas@29.4.3': - dependencies: - '@sinclair/typebox': 0.25.24 - '@jest/schemas@29.6.3': dependencies: '@sinclair/typebox': 0.27.8 @@ -12945,7 +12955,7 @@ snapshots: '@jest/types@29.5.0': dependencies: - '@jest/schemas': 29.4.3 + '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 '@types/node': 18.15.11 @@ -14303,7 +14313,7 @@ snapshots: '@babel/plugin-transform-sticky-regex': 7.24.7(@babel/core@7.21.4) '@babel/plugin-transform-typescript': 7.25.2(@babel/core@7.21.4) '@babel/plugin-transform-unicode-regex': 7.24.7(@babel/core@7.21.4) - '@babel/template': 7.20.7 + '@babel/template': 7.25.0 '@react-native/babel-plugin-codegen': 0.75.2(@babel/preset-env@7.25.3(@babel/core@7.21.4)) babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.21.4) react-refresh: 0.14.0 @@ -14313,7 +14323,7 @@ snapshots: '@react-native/codegen@0.75.2(@babel/preset-env@7.25.3(@babel/core@7.21.4))': dependencies: - '@babel/parser': 7.21.4 + '@babel/parser': 7.25.3 '@babel/preset-env': 7.25.3(@babel/core@7.21.4) glob: 7.2.3 hermes-parser: 0.22.0 @@ -14336,7 +14346,7 @@ snapshots: metro: 0.80.10(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) metro-config: 0.80.10(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) metro-core: 0.80.10 - node-fetch: 2.6.9(encoding@0.1.13) + node-fetch: 2.7.0(encoding@0.1.13) querystring: 0.2.1 readline: 1.3.0 transitivePeerDependencies: @@ -14357,7 +14367,7 @@ snapshots: chromium-edge-launcher: 0.2.0 connect: 3.7.0 debug: 2.6.9 - node-fetch: 2.6.9(encoding@0.1.13) + node-fetch: 2.7.0(encoding@0.1.13) nullthrows: 1.1.1 open: 7.4.2 selfsigned: 2.4.1 @@ -14496,8 +14506,6 @@ snapshots: '@sideway/pinpoint@2.0.0': {} - '@sinclair/typebox@0.25.24': {} - '@sinclair/typebox@0.27.8': {} '@sinonjs/commons@2.0.0': @@ -15255,13 +15263,13 @@ snapshots: - debug - utf-8-validate - '@vitejs/plugin-react@4.0.0(vite@4.3.6(@types/node@20.12.12))': + '@vitejs/plugin-react@4.0.0(vite@4.3.6(@types/node@20.12.12)(terser@5.31.6))': dependencies: '@babel/core': 7.21.4 '@babel/plugin-transform-react-jsx-self': 7.21.0(@babel/core@7.21.4) '@babel/plugin-transform-react-jsx-source': 7.19.6(@babel/core@7.21.4) react-refresh: 0.14.0 - vite: 4.3.6(@types/node@20.12.12) + vite: 4.3.6(@types/node@20.12.12)(terser@5.31.6) transitivePeerDependencies: - supports-color @@ -15281,7 +15289,7 @@ snapshots: dependencies: magic-string: 0.30.5 pathe: 1.1.2 - pretty-format: 29.5.0 + pretty-format: 29.7.0 '@vitest/spy@0.34.6': dependencies: @@ -15291,7 +15299,7 @@ snapshots: dependencies: diff-sequences: 29.6.3 loupe: 2.3.6 - pretty-format: 29.5.0 + pretty-format: 29.7.0 '@wagmi/connectors@5.1.7(@types/react@18.2.22)(@wagmi/core@2.13.4(@tanstack/query-core@5.52.0)(@types/react@18.2.22)(react@18.2.0)(typescript@5.4.2)(viem@2.19.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)))(bufferutil@4.0.8)(encoding@0.1.13)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.2(@babel/core@7.21.4)(@babel/preset-env@7.25.3(@babel/core@7.21.4))(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@3.21.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.19.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8)': dependencies: @@ -17361,7 +17369,7 @@ snapshots: eslint@5.16.0: dependencies: - '@babel/code-frame': 7.21.4 + '@babel/code-frame': 7.24.7 ajv: 6.12.6 chalk: 2.4.2 cross-spawn: 6.0.5 @@ -17949,8 +17957,6 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.2.4 - get-tsconfig@4.5.0: {} - get-tsconfig@4.7.5: dependencies: resolve-pkg-maps: 1.0.0 @@ -18616,7 +18622,7 @@ snapshots: jest-snapshot: 29.5.0 jest-util: 29.5.0 p-limit: 3.1.0 - pretty-format: 29.5.0 + pretty-format: 29.7.0 pure-rand: 6.0.1 slash: 3.0.0 stack-utils: 2.0.6 @@ -18682,7 +18688,7 @@ snapshots: jest-validate: 29.5.0 micromatch: 4.0.5 parse-json: 5.2.0 - pretty-format: 29.5.0 + pretty-format: 29.7.0 slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: @@ -18711,7 +18717,7 @@ snapshots: jest-validate: 29.5.0 micromatch: 4.0.5 parse-json: 5.2.0 - pretty-format: 29.5.0 + pretty-format: 29.7.0 slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: @@ -18731,7 +18737,7 @@ snapshots: chalk: 4.1.2 diff-sequences: 29.6.3 jest-get-type: 29.4.3 - pretty-format: 29.5.0 + pretty-format: 29.7.0 jest-docblock@29.4.3: dependencies: @@ -18743,7 +18749,7 @@ snapshots: chalk: 4.1.2 jest-get-type: 29.4.3 jest-util: 29.5.0 - pretty-format: 29.5.0 + pretty-format: 29.7.0 jest-environment-node@29.5.0: dependencies: @@ -18788,7 +18794,7 @@ snapshots: jest-leak-detector@29.5.0: dependencies: jest-get-type: 29.4.3 - pretty-format: 29.5.0 + pretty-format: 29.7.0 jest-matcher-utils@27.5.1: dependencies: @@ -18802,23 +18808,23 @@ snapshots: chalk: 4.1.2 jest-diff: 29.5.0 jest-get-type: 29.4.3 - pretty-format: 29.5.0 + pretty-format: 29.7.0 jest-message-util@29.5.0: dependencies: - '@babel/code-frame': 7.21.4 + '@babel/code-frame': 7.24.7 '@jest/types': 29.5.0 '@types/stack-utils': 2.0.1 chalk: 4.1.2 graceful-fs: 4.2.11 micromatch: 4.0.5 - pretty-format: 29.5.0 + pretty-format: 29.7.0 slash: 3.0.0 stack-utils: 2.0.6 jest-message-util@29.7.0: dependencies: - '@babel/code-frame': 7.21.4 + '@babel/code-frame': 7.24.7 '@jest/types': 29.6.3 '@types/stack-utils': 2.0.1 chalk: 4.1.2 @@ -18941,7 +18947,7 @@ snapshots: jest-message-util: 29.5.0 jest-util: 29.5.0 natural-compare: 1.4.0 - pretty-format: 29.5.0 + pretty-format: 29.7.0 semver: 7.6.0 transitivePeerDependencies: - supports-color @@ -18971,7 +18977,7 @@ snapshots: chalk: 4.1.2 jest-get-type: 29.4.3 leven: 3.1.0 - pretty-format: 29.5.0 + pretty-format: 29.7.0 jest-validate@29.7.0: dependencies: @@ -19061,7 +19067,7 @@ snapshots: jscodeshift@0.14.0(@babel/preset-env@7.25.3(@babel/core@7.21.4)): dependencies: '@babel/core': 7.21.4 - '@babel/parser': 7.21.4 + '@babel/parser': 7.25.3 '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.21.4) '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.21.4) '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.21.4) @@ -19140,8 +19146,6 @@ snapshots: json5@2.2.3: {} - jsonc-parser@3.2.0: {} - jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 @@ -19593,13 +19597,13 @@ snapshots: metro-runtime@0.80.10: dependencies: - '@babel/runtime': 7.21.0 + '@babel/runtime': 7.25.0 flow-enums-runtime: 0.0.6 metro-source-map@0.80.10: dependencies: - '@babel/traverse': 7.21.4 - '@babel/types': 7.21.4 + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 flow-enums-runtime: 0.0.6 invariant: 2.2.4 metro-symbolicate: 0.80.10 @@ -19625,9 +19629,9 @@ snapshots: metro-transform-plugins@0.80.10: dependencies: '@babel/core': 7.21.4 - '@babel/generator': 7.21.4 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.4 + '@babel/generator': 7.25.0 + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.3 flow-enums-runtime: 0.0.6 nullthrows: 1.1.1 transitivePeerDependencies: @@ -19636,9 +19640,9 @@ snapshots: metro-transform-worker@0.80.10(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10): dependencies: '@babel/core': 7.21.4 - '@babel/generator': 7.21.4 - '@babel/parser': 7.21.4 - '@babel/types': 7.21.4 + '@babel/generator': 7.25.0 + '@babel/parser': 7.25.3 + '@babel/types': 7.25.2 flow-enums-runtime: 0.0.6 metro: 0.80.10(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) metro-babel-transformer: 0.80.10 @@ -19656,13 +19660,13 @@ snapshots: metro@0.80.10(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10): dependencies: - '@babel/code-frame': 7.21.4 + '@babel/code-frame': 7.24.7 '@babel/core': 7.21.4 - '@babel/generator': 7.21.4 - '@babel/parser': 7.21.4 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.4 - '@babel/types': 7.21.4 + '@babel/generator': 7.25.0 + '@babel/parser': 7.25.3 + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 accepts: 1.3.8 chalk: 4.1.2 ci-info: 2.0.0 @@ -19691,7 +19695,7 @@ snapshots: metro-transform-plugins: 0.80.10 metro-transform-worker: 0.80.10(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) mime-types: 2.1.35 - node-fetch: 2.6.9(encoding@0.1.13) + node-fetch: 2.7.0(encoding@0.1.13) nullthrows: 1.1.1 serialize-error: 2.1.0 source-map: 0.5.7 @@ -19805,13 +19809,6 @@ snapshots: mkdirp@1.0.4: {} - mlly@1.5.0: - dependencies: - acorn: 8.11.3 - pathe: 1.1.2 - pkg-types: 1.0.3 - ufo: 1.3.2 - mlly@1.7.1: dependencies: acorn: 8.11.3 @@ -20243,7 +20240,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.21.4 + '@babel/code-frame': 7.24.7 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -20364,12 +20361,6 @@ snapshots: dependencies: find-up: 4.1.0 - pkg-types@1.0.3: - dependencies: - jsonc-parser: 3.2.0 - mlly: 1.5.0 - pathe: 1.1.2 - pkg-types@1.1.3: dependencies: confbox: 0.1.7 @@ -20444,7 +20435,7 @@ snapshots: postcss@8.4.31: dependencies: nanoid: 3.3.6 - picocolors: 1.0.0 + picocolors: 1.0.1 source-map-js: 1.0.2 postgres@3.3.5: {} @@ -20512,12 +20503,6 @@ snapshots: ansi-styles: 5.2.0 react-is: 17.0.2 - pretty-format@29.5.0: - dependencies: - '@jest/schemas': 29.4.3 - ansi-styles: 5.2.0 - react-is: 18.2.0 - pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 @@ -20877,7 +20862,7 @@ snapshots: regenerator-transform@0.15.2: dependencies: - '@babel/runtime': 7.21.0 + '@babel/runtime': 7.25.0 regexp.prototype.flags@1.4.3: dependencies: @@ -21253,7 +21238,7 @@ snapshots: ignore: 4.0.6 js-yaml: 3.14.1 lodash: 4.17.21 - semver: 6.3.0 + semver: 6.3.1 optionalDependencies: prettier: 1.19.1 transitivePeerDependencies: @@ -21774,7 +21759,7 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.0.5(@babel/core@7.21.4)(@jest/types@29.5.0)(babel-jest@29.5.0(@babel/core@7.21.4))(jest@29.5.0(@types/node@18.15.11))(typescript@5.4.2): + ts-jest@29.0.5(@babel/core@7.21.4)(@jest/types@29.6.3)(babel-jest@29.5.0(@babel/core@7.21.4))(jest@29.5.0(@types/node@18.15.11))(typescript@5.4.2): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 @@ -21788,10 +21773,10 @@ snapshots: yargs-parser: 21.1.1 optionalDependencies: '@babel/core': 7.21.4 - '@jest/types': 29.5.0 + '@jest/types': 29.6.3 babel-jest: 29.5.0(@babel/core@7.21.4) - ts-jest@29.0.5(@babel/core@7.21.4)(@jest/types@29.5.0)(babel-jest@29.5.0(@babel/core@7.21.4))(jest@29.5.0(@types/node@20.12.12))(typescript@5.4.2): + ts-jest@29.0.5(@babel/core@7.21.4)(@jest/types@29.6.3)(babel-jest@29.5.0(@babel/core@7.21.4))(jest@29.5.0(@types/node@20.12.12))(typescript@5.4.2): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 @@ -21805,7 +21790,7 @@ snapshots: yargs-parser: 21.1.1 optionalDependencies: '@babel/core': 7.21.4 - '@jest/types': 29.5.0 + '@jest/types': 29.6.3 babel-jest: 29.5.0(@babel/core@7.21.4) tsconfig-paths@3.15.0: @@ -21976,8 +21961,6 @@ snapshots: typescript@5.4.2: {} - ufo@1.3.2: {} - ufo@1.5.4: {} uglify-js@3.17.4: @@ -22058,7 +22041,7 @@ snapshots: dependencies: browserslist: 4.23.0 escalade: 3.1.2 - picocolors: 1.0.0 + picocolors: 1.0.1 update-browserslist-db@1.1.0(browserslist@4.23.3): dependencies: @@ -22159,14 +22142,14 @@ snapshots: - utf-8-validate - zod - vite-node@0.34.6(@types/node@18.15.11): + vite-node@0.34.6(@types/node@18.15.11)(terser@5.31.6): dependencies: cac: 6.7.14 debug: 4.3.4 - mlly: 1.5.0 + mlly: 1.7.1 pathe: 1.1.2 - picocolors: 1.0.0 - vite: 4.3.6(@types/node@18.15.11) + picocolors: 1.0.1 + vite: 4.3.6(@types/node@18.15.11)(terser@5.31.6) transitivePeerDependencies: - '@types/node' - less @@ -22176,7 +22159,7 @@ snapshots: - supports-color - terser - vite@4.3.6(@types/node@18.15.11): + vite@4.3.6(@types/node@18.15.11)(terser@5.31.6): dependencies: esbuild: 0.17.17 postcss: 8.4.23 @@ -22184,8 +22167,9 @@ snapshots: optionalDependencies: '@types/node': 18.15.11 fsevents: 2.3.3 + terser: 5.31.6 - vite@4.3.6(@types/node@20.12.12): + vite@4.3.6(@types/node@20.12.12)(terser@5.31.6): dependencies: esbuild: 0.17.17 postcss: 8.4.23 @@ -22193,8 +22177,9 @@ snapshots: optionalDependencies: '@types/node': 20.12.12 fsevents: 2.3.3 + terser: 5.31.6 - vitest@0.34.6(jsdom@22.1.0): + vitest@0.34.6(jsdom@22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6): dependencies: '@types/chai': 4.3.5 '@types/chai-subset': 1.3.3 @@ -22212,13 +22197,13 @@ snapshots: local-pkg: 0.4.3 magic-string: 0.30.5 pathe: 1.1.2 - picocolors: 1.0.0 + picocolors: 1.0.1 std-env: 3.7.0 strip-literal: 1.3.0 tinybench: 2.6.0 tinypool: 0.7.0 - vite: 4.3.6(@types/node@18.15.11) - vite-node: 0.34.6(@types/node@18.15.11) + vite: 4.3.6(@types/node@18.15.11)(terser@5.31.6) + vite-node: 0.34.6(@types/node@18.15.11)(terser@5.31.6) why-is-node-running: 2.2.2 optionalDependencies: jsdom: 22.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) From 6ec5ccef591d8a19ed10fd087eb986ac638fa0b3 Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Tue, 27 Aug 2024 18:20:20 +0200 Subject: [PATCH 19/29] update .gitignore --- packages/world-module-erc20-own-store/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/world-module-erc20-own-store/.gitignore b/packages/world-module-erc20-own-store/.gitignore index 1e4ded714a..9f8d5d6071 100644 --- a/packages/world-module-erc20-own-store/.gitignore +++ b/packages/world-module-erc20-own-store/.gitignore @@ -1,2 +1,3 @@ cache out +src/codegen From ec9471225670752588d00c1954845f0190b7aa57 Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Wed, 28 Aug 2024 13:54:17 +0200 Subject: [PATCH 20/29] move interfaces into root of src directory --- .../{interfaces => src}/IERC20Errors.sol | 2 +- .../{interfaces => src}/IERC20Events.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename packages/world-module-erc20-own-store/{interfaces => src}/IERC20Errors.sol (99%) rename packages/world-module-erc20-own-store/{interfaces => src}/IERC20Events.sol (99%) diff --git a/packages/world-module-erc20-own-store/interfaces/IERC20Errors.sol b/packages/world-module-erc20-own-store/src/IERC20Errors.sol similarity index 99% rename from packages/world-module-erc20-own-store/interfaces/IERC20Errors.sol rename to packages/world-module-erc20-own-store/src/IERC20Errors.sol index a0b54b8c17..869ccc8250 100644 --- a/packages/world-module-erc20-own-store/interfaces/IERC20Errors.sol +++ b/packages/world-module-erc20-own-store/src/IERC20Errors.sol @@ -41,4 +41,4 @@ interface IERC20Errors { * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); -} \ No newline at end of file +} diff --git a/packages/world-module-erc20-own-store/interfaces/IERC20Events.sol b/packages/world-module-erc20-own-store/src/IERC20Events.sol similarity index 99% rename from packages/world-module-erc20-own-store/interfaces/IERC20Events.sol rename to packages/world-module-erc20-own-store/src/IERC20Events.sol index 294271ba36..f86a921f3e 100644 --- a/packages/world-module-erc20-own-store/interfaces/IERC20Events.sol +++ b/packages/world-module-erc20-own-store/src/IERC20Events.sol @@ -15,4 +15,4 @@ interface IERC20Events { * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); -} \ No newline at end of file +} From 9bce23f74bd553f66f4b85809cb2ad542c1ea19e Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Wed, 28 Aug 2024 13:58:04 +0200 Subject: [PATCH 21/29] add world/ to .gitignore --- packages/world-module-erc20-own-store/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/world-module-erc20-own-store/.gitignore b/packages/world-module-erc20-own-store/.gitignore index 9f8d5d6071..764d7db934 100644 --- a/packages/world-module-erc20-own-store/.gitignore +++ b/packages/world-module-erc20-own-store/.gitignore @@ -1,3 +1,3 @@ cache out -src/codegen +src/codegen/world/ From dea487aa1f667020f1c84a11d52e3d8e3d1007f9 Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Wed, 28 Aug 2024 14:39:46 +0200 Subject: [PATCH 22/29] remove dynamicId implementation & set vars in constructor --- .../src/MUDERC20.sol | 50 +++++++++++++++++-- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/packages/world-module-erc20-own-store/src/MUDERC20.sol b/packages/world-module-erc20-own-store/src/MUDERC20.sol index 0d16558b57..aceb6bb3ef 100644 --- a/packages/world-module-erc20-own-store/src/MUDERC20.sol +++ b/packages/world-module-erc20-own-store/src/MUDERC20.sol @@ -1,15 +1,55 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; -import { IERC20Errors } from "./interfaces/IERC20Errors.sol"; -import { IERC20Events } from "./interfaces/IERC20Events.sol"; +import { IERC20Errors } from "./IERC20Errors.sol"; +import { IERC20Events } from "./IERC20Events.sol"; +import { Token } from "./codegen/tables/Token.sol"; +import { Balances } from "./codegen/tables/Balances.sol"; +import { Allowances } from "./codegen/tables/Allowances.sol"; import { Store } from "@latticexyz/store/src/Store.sol"; +import { ResourceId, ResourceIdLib } from "@latticexyz/store/src/ResourceId.sol"; contract MUDERC20 is Store, IERC20Errors, IERC20Events { - constructor(string memory _name, string memory _symbol, uint8 _decimals) { - + StoreCore.initialize(); + StoreCore.registerInternalTables(); + + Token.register(); + Balances.register(); + Allowances.register(); + + Token.set(_name, _symbol, _decimals); + } + + /// VIEW FUNCTIONS /// + + /** + * @dev Returns the name of the token. + */ + function name() public view returns (string memory) { + return Token.getName(); } -} \ No newline at end of file + /** + * @dev Returns the symbol of the token, usually a shorter version of the + * name. + */ + function symbol() public view returns (string memory) { + return Token.getSymbol(); + } + + /** + * @dev Returns the decimals of the token. + */ + function decimals() public view returns (string memory) { + return Token.getDecimals(); + } + + /** + * @dev Returns the total supply of the token. + */ + function totalSupply() public view returns (uint256) { + return Token.getTotalSupply(); + } +} From 19c29ab20d96c392f0d09af6bd4da84c342d7cac Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Wed, 28 Aug 2024 14:39:55 +0200 Subject: [PATCH 23/29] remove dynamicId implementation & set vars in constructor --- packages/world-module-erc20-own-store/src/MUDERC20.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/world-module-erc20-own-store/src/MUDERC20.sol b/packages/world-module-erc20-own-store/src/MUDERC20.sol index aceb6bb3ef..e5b882b098 100644 --- a/packages/world-module-erc20-own-store/src/MUDERC20.sol +++ b/packages/world-module-erc20-own-store/src/MUDERC20.sol @@ -8,7 +8,6 @@ import { Balances } from "./codegen/tables/Balances.sol"; import { Allowances } from "./codegen/tables/Allowances.sol"; import { Store } from "@latticexyz/store/src/Store.sol"; -import { ResourceId, ResourceIdLib } from "@latticexyz/store/src/ResourceId.sol"; contract MUDERC20 is Store, IERC20Errors, IERC20Events { constructor(string memory _name, string memory _symbol, uint8 _decimals) { From af1c5680429da36672d92a0c1f8766432956307b Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Wed, 28 Aug 2024 14:40:08 +0200 Subject: [PATCH 24/29] tablegen --- .../src/codegen/index.sol | 8 + .../src/codegen/tables/Allowances.sol | 211 ++++++ .../src/codegen/tables/Balances.sol | 199 +++++ .../src/codegen/tables/Token.sol | 696 ++++++++++++++++++ 4 files changed, 1114 insertions(+) create mode 100644 packages/world-module-erc20-own-store/src/codegen/index.sol create mode 100644 packages/world-module-erc20-own-store/src/codegen/tables/Allowances.sol create mode 100644 packages/world-module-erc20-own-store/src/codegen/tables/Balances.sol create mode 100644 packages/world-module-erc20-own-store/src/codegen/tables/Token.sol diff --git a/packages/world-module-erc20-own-store/src/codegen/index.sol b/packages/world-module-erc20-own-store/src/codegen/index.sol new file mode 100644 index 0000000000..26ea531e76 --- /dev/null +++ b/packages/world-module-erc20-own-store/src/codegen/index.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.24; + +/* Autogenerated file. Do not edit manually. */ + +import { Token, TokenData } from "./tables/Token.sol"; +import { Balances } from "./tables/Balances.sol"; +import { Allowances } from "./tables/Allowances.sol"; diff --git a/packages/world-module-erc20-own-store/src/codegen/tables/Allowances.sol b/packages/world-module-erc20-own-store/src/codegen/tables/Allowances.sol new file mode 100644 index 0000000000..463132cd2d --- /dev/null +++ b/packages/world-module-erc20-own-store/src/codegen/tables/Allowances.sol @@ -0,0 +1,211 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.24; + +/* Autogenerated file. Do not edit manually. */ + +// Import store internals +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; +import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; +import { Bytes } from "@latticexyz/store/src/Bytes.sol"; +import { Memory } from "@latticexyz/store/src/Memory.sol"; +import { SliceLib } from "@latticexyz/store/src/Slice.sol"; +import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; +import { FieldLayout } from "@latticexyz/store/src/FieldLayout.sol"; +import { Schema } from "@latticexyz/store/src/Schema.sol"; +import { EncodedLengths, EncodedLengthsLib } from "@latticexyz/store/src/EncodedLengths.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + +library Allowances { + // Hex below is the result of `WorldResourceIdLib.encode({ namespace: "erc20-store", name: "Allowances", typeId: RESOURCE_TABLE });` + ResourceId constant _tableId = ResourceId.wrap(0x746265726332302d73746f7265000000416c6c6f77616e636573000000000000); + + FieldLayout constant _fieldLayout = + FieldLayout.wrap(0x0020010020000000000000000000000000000000000000000000000000000000); + + // Hex-encoded key schema of (address, address) + Schema constant _keySchema = Schema.wrap(0x0028020061610000000000000000000000000000000000000000000000000000); + // Hex-encoded value schema of (uint256) + Schema constant _valueSchema = Schema.wrap(0x002001001f000000000000000000000000000000000000000000000000000000); + + /** + * @notice Get the table's key field names. + * @return keyNames An array of strings with the names of key fields. + */ + function getKeyNames() internal pure returns (string[] memory keyNames) { + keyNames = new string[](2); + keyNames[0] = "account"; + keyNames[1] = "spender"; + } + + /** + * @notice Get the table's value field names. + * @return fieldNames An array of strings with the names of value fields. + */ + function getFieldNames() internal pure returns (string[] memory fieldNames) { + fieldNames = new string[](1); + fieldNames[0] = "approval"; + } + + /** + * @notice Register the table with its config. + */ + function register() internal { + StoreSwitch.registerTable(_tableId, _fieldLayout, _keySchema, _valueSchema, getKeyNames(), getFieldNames()); + } + + /** + * @notice Register the table with its config. + */ + function _register() internal { + StoreCore.registerTable(_tableId, _fieldLayout, _keySchema, _valueSchema, getKeyNames(), getFieldNames()); + } + + /** + * @notice Get approval. + */ + function getApproval(address account, address spender) internal view returns (uint256 approval) { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = bytes32(uint256(uint160(account))); + _keyTuple[1] = bytes32(uint256(uint160(spender))); + + bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (uint256(bytes32(_blob))); + } + + /** + * @notice Get approval. + */ + function _getApproval(address account, address spender) internal view returns (uint256 approval) { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = bytes32(uint256(uint160(account))); + _keyTuple[1] = bytes32(uint256(uint160(spender))); + + bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (uint256(bytes32(_blob))); + } + + /** + * @notice Get approval. + */ + function get(address account, address spender) internal view returns (uint256 approval) { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = bytes32(uint256(uint160(account))); + _keyTuple[1] = bytes32(uint256(uint160(spender))); + + bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (uint256(bytes32(_blob))); + } + + /** + * @notice Get approval. + */ + function _get(address account, address spender) internal view returns (uint256 approval) { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = bytes32(uint256(uint160(account))); + _keyTuple[1] = bytes32(uint256(uint160(spender))); + + bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (uint256(bytes32(_blob))); + } + + /** + * @notice Set approval. + */ + function setApproval(address account, address spender, uint256 approval) internal { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = bytes32(uint256(uint160(account))); + _keyTuple[1] = bytes32(uint256(uint160(spender))); + + StoreSwitch.setStaticField(_tableId, _keyTuple, 0, abi.encodePacked((approval)), _fieldLayout); + } + + /** + * @notice Set approval. + */ + function _setApproval(address account, address spender, uint256 approval) internal { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = bytes32(uint256(uint160(account))); + _keyTuple[1] = bytes32(uint256(uint160(spender))); + + StoreCore.setStaticField(_tableId, _keyTuple, 0, abi.encodePacked((approval)), _fieldLayout); + } + + /** + * @notice Set approval. + */ + function set(address account, address spender, uint256 approval) internal { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = bytes32(uint256(uint160(account))); + _keyTuple[1] = bytes32(uint256(uint160(spender))); + + StoreSwitch.setStaticField(_tableId, _keyTuple, 0, abi.encodePacked((approval)), _fieldLayout); + } + + /** + * @notice Set approval. + */ + function _set(address account, address spender, uint256 approval) internal { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = bytes32(uint256(uint160(account))); + _keyTuple[1] = bytes32(uint256(uint160(spender))); + + StoreCore.setStaticField(_tableId, _keyTuple, 0, abi.encodePacked((approval)), _fieldLayout); + } + + /** + * @notice Delete all data for given keys. + */ + function deleteRecord(address account, address spender) internal { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = bytes32(uint256(uint160(account))); + _keyTuple[1] = bytes32(uint256(uint160(spender))); + + StoreSwitch.deleteRecord(_tableId, _keyTuple); + } + + /** + * @notice Delete all data for given keys. + */ + function _deleteRecord(address account, address spender) internal { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = bytes32(uint256(uint160(account))); + _keyTuple[1] = bytes32(uint256(uint160(spender))); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** + * @notice Tightly pack static (fixed length) data using this table's schema. + * @return The static data, encoded into a sequence of bytes. + */ + function encodeStatic(uint256 approval) internal pure returns (bytes memory) { + return abi.encodePacked(approval); + } + + /** + * @notice Encode all of a record's fields. + * @return The static (fixed length) data, encoded into a sequence of bytes. + * @return The lengths of the dynamic fields (packed into a single bytes32 value). + * @return The dynamic (variable length) data, encoded into a sequence of bytes. + */ + function encode(uint256 approval) internal pure returns (bytes memory, EncodedLengths, bytes memory) { + bytes memory _staticData = encodeStatic(approval); + + EncodedLengths _encodedLengths; + bytes memory _dynamicData; + + return (_staticData, _encodedLengths, _dynamicData); + } + + /** + * @notice Encode keys as a bytes32 array using this table's field layout. + */ + function encodeKeyTuple(address account, address spender) internal pure returns (bytes32[] memory) { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = bytes32(uint256(uint160(account))); + _keyTuple[1] = bytes32(uint256(uint160(spender))); + + return _keyTuple; + } +} diff --git a/packages/world-module-erc20-own-store/src/codegen/tables/Balances.sol b/packages/world-module-erc20-own-store/src/codegen/tables/Balances.sol new file mode 100644 index 0000000000..839a3573d6 --- /dev/null +++ b/packages/world-module-erc20-own-store/src/codegen/tables/Balances.sol @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.24; + +/* Autogenerated file. Do not edit manually. */ + +// Import store internals +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; +import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; +import { Bytes } from "@latticexyz/store/src/Bytes.sol"; +import { Memory } from "@latticexyz/store/src/Memory.sol"; +import { SliceLib } from "@latticexyz/store/src/Slice.sol"; +import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; +import { FieldLayout } from "@latticexyz/store/src/FieldLayout.sol"; +import { Schema } from "@latticexyz/store/src/Schema.sol"; +import { EncodedLengths, EncodedLengthsLib } from "@latticexyz/store/src/EncodedLengths.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + +library Balances { + // Hex below is the result of `WorldResourceIdLib.encode({ namespace: "erc20-store", name: "Balances", typeId: RESOURCE_TABLE });` + ResourceId constant _tableId = ResourceId.wrap(0x746265726332302d73746f726500000042616c616e6365730000000000000000); + + FieldLayout constant _fieldLayout = + FieldLayout.wrap(0x0020010020000000000000000000000000000000000000000000000000000000); + + // Hex-encoded key schema of (address) + Schema constant _keySchema = Schema.wrap(0x0014010061000000000000000000000000000000000000000000000000000000); + // Hex-encoded value schema of (uint256) + Schema constant _valueSchema = Schema.wrap(0x002001001f000000000000000000000000000000000000000000000000000000); + + /** + * @notice Get the table's key field names. + * @return keyNames An array of strings with the names of key fields. + */ + function getKeyNames() internal pure returns (string[] memory keyNames) { + keyNames = new string[](1); + keyNames[0] = "account"; + } + + /** + * @notice Get the table's value field names. + * @return fieldNames An array of strings with the names of value fields. + */ + function getFieldNames() internal pure returns (string[] memory fieldNames) { + fieldNames = new string[](1); + fieldNames[0] = "balance"; + } + + /** + * @notice Register the table with its config. + */ + function register() internal { + StoreSwitch.registerTable(_tableId, _fieldLayout, _keySchema, _valueSchema, getKeyNames(), getFieldNames()); + } + + /** + * @notice Register the table with its config. + */ + function _register() internal { + StoreCore.registerTable(_tableId, _fieldLayout, _keySchema, _valueSchema, getKeyNames(), getFieldNames()); + } + + /** + * @notice Get balance. + */ + function getBalance(address account) internal view returns (uint256 balance) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(uint160(account))); + + bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (uint256(bytes32(_blob))); + } + + /** + * @notice Get balance. + */ + function _getBalance(address account) internal view returns (uint256 balance) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(uint160(account))); + + bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (uint256(bytes32(_blob))); + } + + /** + * @notice Get balance. + */ + function get(address account) internal view returns (uint256 balance) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(uint160(account))); + + bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (uint256(bytes32(_blob))); + } + + /** + * @notice Get balance. + */ + function _get(address account) internal view returns (uint256 balance) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(uint160(account))); + + bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (uint256(bytes32(_blob))); + } + + /** + * @notice Set balance. + */ + function setBalance(address account, uint256 balance) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(uint160(account))); + + StoreSwitch.setStaticField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); + } + + /** + * @notice Set balance. + */ + function _setBalance(address account, uint256 balance) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(uint160(account))); + + StoreCore.setStaticField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); + } + + /** + * @notice Set balance. + */ + function set(address account, uint256 balance) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(uint160(account))); + + StoreSwitch.setStaticField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); + } + + /** + * @notice Set balance. + */ + function _set(address account, uint256 balance) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(uint160(account))); + + StoreCore.setStaticField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); + } + + /** + * @notice Delete all data for given keys. + */ + function deleteRecord(address account) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(uint160(account))); + + StoreSwitch.deleteRecord(_tableId, _keyTuple); + } + + /** + * @notice Delete all data for given keys. + */ + function _deleteRecord(address account) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(uint160(account))); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** + * @notice Tightly pack static (fixed length) data using this table's schema. + * @return The static data, encoded into a sequence of bytes. + */ + function encodeStatic(uint256 balance) internal pure returns (bytes memory) { + return abi.encodePacked(balance); + } + + /** + * @notice Encode all of a record's fields. + * @return The static (fixed length) data, encoded into a sequence of bytes. + * @return The lengths of the dynamic fields (packed into a single bytes32 value). + * @return The dynamic (variable length) data, encoded into a sequence of bytes. + */ + function encode(uint256 balance) internal pure returns (bytes memory, EncodedLengths, bytes memory) { + bytes memory _staticData = encodeStatic(balance); + + EncodedLengths _encodedLengths; + bytes memory _dynamicData; + + return (_staticData, _encodedLengths, _dynamicData); + } + + /** + * @notice Encode keys as a bytes32 array using this table's field layout. + */ + function encodeKeyTuple(address account) internal pure returns (bytes32[] memory) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(uint160(account))); + + return _keyTuple; + } +} diff --git a/packages/world-module-erc20-own-store/src/codegen/tables/Token.sol b/packages/world-module-erc20-own-store/src/codegen/tables/Token.sol new file mode 100644 index 0000000000..927d5496bb --- /dev/null +++ b/packages/world-module-erc20-own-store/src/codegen/tables/Token.sol @@ -0,0 +1,696 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.24; + +/* Autogenerated file. Do not edit manually. */ + +// Import store internals +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; +import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; +import { Bytes } from "@latticexyz/store/src/Bytes.sol"; +import { Memory } from "@latticexyz/store/src/Memory.sol"; +import { SliceLib } from "@latticexyz/store/src/Slice.sol"; +import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; +import { FieldLayout } from "@latticexyz/store/src/FieldLayout.sol"; +import { Schema } from "@latticexyz/store/src/Schema.sol"; +import { EncodedLengths, EncodedLengthsLib } from "@latticexyz/store/src/EncodedLengths.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + +struct TokenData { + uint8 decimals; + uint256 totalSupply; + string name; + string symbol; +} + +library Token { + // Hex below is the result of `WorldResourceIdLib.encode({ namespace: "erc20-store", name: "Token", typeId: RESOURCE_TABLE });` + ResourceId constant _tableId = ResourceId.wrap(0x746265726332302d73746f7265000000546f6b656e0000000000000000000000); + + FieldLayout constant _fieldLayout = + FieldLayout.wrap(0x0021020201200000000000000000000000000000000000000000000000000000); + + // Hex-encoded key schema of (bytes32) + Schema constant _keySchema = Schema.wrap(0x002001005f000000000000000000000000000000000000000000000000000000); + // Hex-encoded value schema of (uint8, uint256, string, string) + Schema constant _valueSchema = Schema.wrap(0x00210202001fc5c5000000000000000000000000000000000000000000000000); + + /** + * @notice Get the table's key field names. + * @return keyNames An array of strings with the names of key fields. + */ + function getKeyNames() internal pure returns (string[] memory keyNames) { + keyNames = new string[](1); + keyNames[0] = "id"; + } + + /** + * @notice Get the table's value field names. + * @return fieldNames An array of strings with the names of value fields. + */ + function getFieldNames() internal pure returns (string[] memory fieldNames) { + fieldNames = new string[](4); + fieldNames[0] = "decimals"; + fieldNames[1] = "totalSupply"; + fieldNames[2] = "name"; + fieldNames[3] = "symbol"; + } + + /** + * @notice Register the table with its config. + */ + function register() internal { + StoreSwitch.registerTable(_tableId, _fieldLayout, _keySchema, _valueSchema, getKeyNames(), getFieldNames()); + } + + /** + * @notice Register the table with its config. + */ + function _register() internal { + StoreCore.registerTable(_tableId, _fieldLayout, _keySchema, _valueSchema, getKeyNames(), getFieldNames()); + } + + /** + * @notice Get decimals. + */ + function getDecimals(bytes32 id) internal view returns (uint8 decimals) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (uint8(bytes1(_blob))); + } + + /** + * @notice Get decimals. + */ + function _getDecimals(bytes32 id) internal view returns (uint8 decimals) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (uint8(bytes1(_blob))); + } + + /** + * @notice Set decimals. + */ + function setDecimals(bytes32 id, uint8 decimals) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreSwitch.setStaticField(_tableId, _keyTuple, 0, abi.encodePacked((decimals)), _fieldLayout); + } + + /** + * @notice Set decimals. + */ + function _setDecimals(bytes32 id, uint8 decimals) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreCore.setStaticField(_tableId, _keyTuple, 0, abi.encodePacked((decimals)), _fieldLayout); + } + + /** + * @notice Get totalSupply. + */ + function getTotalSupply(bytes32 id) internal view returns (uint256 totalSupply) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 1, _fieldLayout); + return (uint256(bytes32(_blob))); + } + + /** + * @notice Get totalSupply. + */ + function _getTotalSupply(bytes32 id) internal view returns (uint256 totalSupply) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 1, _fieldLayout); + return (uint256(bytes32(_blob))); + } + + /** + * @notice Set totalSupply. + */ + function setTotalSupply(bytes32 id, uint256 totalSupply) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreSwitch.setStaticField(_tableId, _keyTuple, 1, abi.encodePacked((totalSupply)), _fieldLayout); + } + + /** + * @notice Set totalSupply. + */ + function _setTotalSupply(bytes32 id, uint256 totalSupply) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreCore.setStaticField(_tableId, _keyTuple, 1, abi.encodePacked((totalSupply)), _fieldLayout); + } + + /** + * @notice Get name. + */ + function getName(bytes32 id) internal view returns (string memory name) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + bytes memory _blob = StoreSwitch.getDynamicField(_tableId, _keyTuple, 0); + return (string(_blob)); + } + + /** + * @notice Get name. + */ + function _getName(bytes32 id) internal view returns (string memory name) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + bytes memory _blob = StoreCore.getDynamicField(_tableId, _keyTuple, 0); + return (string(_blob)); + } + + /** + * @notice Set name. + */ + function setName(bytes32 id, string memory name) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreSwitch.setDynamicField(_tableId, _keyTuple, 0, bytes((name))); + } + + /** + * @notice Set name. + */ + function _setName(bytes32 id, string memory name) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreCore.setDynamicField(_tableId, _keyTuple, 0, bytes((name))); + } + + /** + * @notice Get the length of name. + */ + function lengthName(bytes32 id) internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + uint256 _byteLength = StoreSwitch.getDynamicFieldLength(_tableId, _keyTuple, 0); + unchecked { + return _byteLength / 1; + } + } + + /** + * @notice Get the length of name. + */ + function _lengthName(bytes32 id) internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + uint256 _byteLength = StoreCore.getDynamicFieldLength(_tableId, _keyTuple, 0); + unchecked { + return _byteLength / 1; + } + } + + /** + * @notice Get an item of name. + * @dev Reverts with Store_IndexOutOfBounds if `_index` is out of bounds for the array. + */ + function getItemName(bytes32 id, uint256 _index) internal view returns (string memory) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + unchecked { + bytes memory _blob = StoreSwitch.getDynamicFieldSlice(_tableId, _keyTuple, 0, _index * 1, (_index + 1) * 1); + return (string(_blob)); + } + } + + /** + * @notice Get an item of name. + * @dev Reverts with Store_IndexOutOfBounds if `_index` is out of bounds for the array. + */ + function _getItemName(bytes32 id, uint256 _index) internal view returns (string memory) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + unchecked { + bytes memory _blob = StoreCore.getDynamicFieldSlice(_tableId, _keyTuple, 0, _index * 1, (_index + 1) * 1); + return (string(_blob)); + } + } + + /** + * @notice Push a slice to name. + */ + function pushName(bytes32 id, string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreSwitch.pushToDynamicField(_tableId, _keyTuple, 0, bytes((_slice))); + } + + /** + * @notice Push a slice to name. + */ + function _pushName(bytes32 id, string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreCore.pushToDynamicField(_tableId, _keyTuple, 0, bytes((_slice))); + } + + /** + * @notice Pop a slice from name. + */ + function popName(bytes32 id) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreSwitch.popFromDynamicField(_tableId, _keyTuple, 0, 1); + } + + /** + * @notice Pop a slice from name. + */ + function _popName(bytes32 id) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreCore.popFromDynamicField(_tableId, _keyTuple, 0, 1); + } + + /** + * @notice Update a slice of name at `_index`. + */ + function updateName(bytes32 id, uint256 _index, string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + unchecked { + bytes memory _encoded = bytes((_slice)); + StoreSwitch.spliceDynamicData(_tableId, _keyTuple, 0, uint40(_index * 1), uint40(_encoded.length), _encoded); + } + } + + /** + * @notice Update a slice of name at `_index`. + */ + function _updateName(bytes32 id, uint256 _index, string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + unchecked { + bytes memory _encoded = bytes((_slice)); + StoreCore.spliceDynamicData(_tableId, _keyTuple, 0, uint40(_index * 1), uint40(_encoded.length), _encoded); + } + } + + /** + * @notice Get symbol. + */ + function getSymbol(bytes32 id) internal view returns (string memory symbol) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + bytes memory _blob = StoreSwitch.getDynamicField(_tableId, _keyTuple, 1); + return (string(_blob)); + } + + /** + * @notice Get symbol. + */ + function _getSymbol(bytes32 id) internal view returns (string memory symbol) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + bytes memory _blob = StoreCore.getDynamicField(_tableId, _keyTuple, 1); + return (string(_blob)); + } + + /** + * @notice Set symbol. + */ + function setSymbol(bytes32 id, string memory symbol) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreSwitch.setDynamicField(_tableId, _keyTuple, 1, bytes((symbol))); + } + + /** + * @notice Set symbol. + */ + function _setSymbol(bytes32 id, string memory symbol) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreCore.setDynamicField(_tableId, _keyTuple, 1, bytes((symbol))); + } + + /** + * @notice Get the length of symbol. + */ + function lengthSymbol(bytes32 id) internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + uint256 _byteLength = StoreSwitch.getDynamicFieldLength(_tableId, _keyTuple, 1); + unchecked { + return _byteLength / 1; + } + } + + /** + * @notice Get the length of symbol. + */ + function _lengthSymbol(bytes32 id) internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + uint256 _byteLength = StoreCore.getDynamicFieldLength(_tableId, _keyTuple, 1); + unchecked { + return _byteLength / 1; + } + } + + /** + * @notice Get an item of symbol. + * @dev Reverts with Store_IndexOutOfBounds if `_index` is out of bounds for the array. + */ + function getItemSymbol(bytes32 id, uint256 _index) internal view returns (string memory) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + unchecked { + bytes memory _blob = StoreSwitch.getDynamicFieldSlice(_tableId, _keyTuple, 1, _index * 1, (_index + 1) * 1); + return (string(_blob)); + } + } + + /** + * @notice Get an item of symbol. + * @dev Reverts with Store_IndexOutOfBounds if `_index` is out of bounds for the array. + */ + function _getItemSymbol(bytes32 id, uint256 _index) internal view returns (string memory) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + unchecked { + bytes memory _blob = StoreCore.getDynamicFieldSlice(_tableId, _keyTuple, 1, _index * 1, (_index + 1) * 1); + return (string(_blob)); + } + } + + /** + * @notice Push a slice to symbol. + */ + function pushSymbol(bytes32 id, string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreSwitch.pushToDynamicField(_tableId, _keyTuple, 1, bytes((_slice))); + } + + /** + * @notice Push a slice to symbol. + */ + function _pushSymbol(bytes32 id, string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreCore.pushToDynamicField(_tableId, _keyTuple, 1, bytes((_slice))); + } + + /** + * @notice Pop a slice from symbol. + */ + function popSymbol(bytes32 id) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreSwitch.popFromDynamicField(_tableId, _keyTuple, 1, 1); + } + + /** + * @notice Pop a slice from symbol. + */ + function _popSymbol(bytes32 id) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreCore.popFromDynamicField(_tableId, _keyTuple, 1, 1); + } + + /** + * @notice Update a slice of symbol at `_index`. + */ + function updateSymbol(bytes32 id, uint256 _index, string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + unchecked { + bytes memory _encoded = bytes((_slice)); + StoreSwitch.spliceDynamicData(_tableId, _keyTuple, 1, uint40(_index * 1), uint40(_encoded.length), _encoded); + } + } + + /** + * @notice Update a slice of symbol at `_index`. + */ + function _updateSymbol(bytes32 id, uint256 _index, string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + unchecked { + bytes memory _encoded = bytes((_slice)); + StoreCore.spliceDynamicData(_tableId, _keyTuple, 1, uint40(_index * 1), uint40(_encoded.length), _encoded); + } + } + + /** + * @notice Get the full data. + */ + function get(bytes32 id) internal view returns (TokenData memory _table) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + (bytes memory _staticData, EncodedLengths _encodedLengths, bytes memory _dynamicData) = StoreSwitch.getRecord( + _tableId, + _keyTuple, + _fieldLayout + ); + return decode(_staticData, _encodedLengths, _dynamicData); + } + + /** + * @notice Get the full data. + */ + function _get(bytes32 id) internal view returns (TokenData memory _table) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + (bytes memory _staticData, EncodedLengths _encodedLengths, bytes memory _dynamicData) = StoreCore.getRecord( + _tableId, + _keyTuple, + _fieldLayout + ); + return decode(_staticData, _encodedLengths, _dynamicData); + } + + /** + * @notice Set the full data using individual values. + */ + function set(bytes32 id, uint8 decimals, uint256 totalSupply, string memory name, string memory symbol) internal { + bytes memory _staticData = encodeStatic(decimals, totalSupply); + + EncodedLengths _encodedLengths = encodeLengths(name, symbol); + bytes memory _dynamicData = encodeDynamic(name, symbol); + + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData); + } + + /** + * @notice Set the full data using individual values. + */ + function _set(bytes32 id, uint8 decimals, uint256 totalSupply, string memory name, string memory symbol) internal { + bytes memory _staticData = encodeStatic(decimals, totalSupply); + + EncodedLengths _encodedLengths = encodeLengths(name, symbol); + bytes memory _dynamicData = encodeDynamic(name, symbol); + + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreCore.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); + } + + /** + * @notice Set the full data using the data struct. + */ + function set(bytes32 id, TokenData memory _table) internal { + bytes memory _staticData = encodeStatic(_table.decimals, _table.totalSupply); + + EncodedLengths _encodedLengths = encodeLengths(_table.name, _table.symbol); + bytes memory _dynamicData = encodeDynamic(_table.name, _table.symbol); + + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData); + } + + /** + * @notice Set the full data using the data struct. + */ + function _set(bytes32 id, TokenData memory _table) internal { + bytes memory _staticData = encodeStatic(_table.decimals, _table.totalSupply); + + EncodedLengths _encodedLengths = encodeLengths(_table.name, _table.symbol); + bytes memory _dynamicData = encodeDynamic(_table.name, _table.symbol); + + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreCore.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); + } + + /** + * @notice Decode the tightly packed blob of static data using this table's field layout. + */ + function decodeStatic(bytes memory _blob) internal pure returns (uint8 decimals, uint256 totalSupply) { + decimals = (uint8(Bytes.getBytes1(_blob, 0))); + + totalSupply = (uint256(Bytes.getBytes32(_blob, 1))); + } + + /** + * @notice Decode the tightly packed blob of dynamic data using the encoded lengths. + */ + function decodeDynamic( + EncodedLengths _encodedLengths, + bytes memory _blob + ) internal pure returns (string memory name, string memory symbol) { + uint256 _start; + uint256 _end; + unchecked { + _end = _encodedLengths.atIndex(0); + } + name = (string(SliceLib.getSubslice(_blob, _start, _end).toBytes())); + + _start = _end; + unchecked { + _end += _encodedLengths.atIndex(1); + } + symbol = (string(SliceLib.getSubslice(_blob, _start, _end).toBytes())); + } + + /** + * @notice Decode the tightly packed blobs using this table's field layout. + * @param _staticData Tightly packed static fields. + * @param _encodedLengths Encoded lengths of dynamic fields. + * @param _dynamicData Tightly packed dynamic fields. + */ + function decode( + bytes memory _staticData, + EncodedLengths _encodedLengths, + bytes memory _dynamicData + ) internal pure returns (TokenData memory _table) { + (_table.decimals, _table.totalSupply) = decodeStatic(_staticData); + + (_table.name, _table.symbol) = decodeDynamic(_encodedLengths, _dynamicData); + } + + /** + * @notice Delete all data for given keys. + */ + function deleteRecord(bytes32 id) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreSwitch.deleteRecord(_tableId, _keyTuple); + } + + /** + * @notice Delete all data for given keys. + */ + function _deleteRecord(bytes32 id) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** + * @notice Tightly pack static (fixed length) data using this table's schema. + * @return The static data, encoded into a sequence of bytes. + */ + function encodeStatic(uint8 decimals, uint256 totalSupply) internal pure returns (bytes memory) { + return abi.encodePacked(decimals, totalSupply); + } + + /** + * @notice Tightly pack dynamic data lengths using this table's schema. + * @return _encodedLengths The lengths of the dynamic fields (packed into a single bytes32 value). + */ + function encodeLengths( + string memory name, + string memory symbol + ) internal pure returns (EncodedLengths _encodedLengths) { + // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits + unchecked { + _encodedLengths = EncodedLengthsLib.pack(bytes(name).length, bytes(symbol).length); + } + } + + /** + * @notice Tightly pack dynamic (variable length) data using this table's schema. + * @return The dynamic data, encoded into a sequence of bytes. + */ + function encodeDynamic(string memory name, string memory symbol) internal pure returns (bytes memory) { + return abi.encodePacked(bytes((name)), bytes((symbol))); + } + + /** + * @notice Encode all of a record's fields. + * @return The static (fixed length) data, encoded into a sequence of bytes. + * @return The lengths of the dynamic fields (packed into a single bytes32 value). + * @return The dynamic (variable length) data, encoded into a sequence of bytes. + */ + function encode( + uint8 decimals, + uint256 totalSupply, + string memory name, + string memory symbol + ) internal pure returns (bytes memory, EncodedLengths, bytes memory) { + bytes memory _staticData = encodeStatic(decimals, totalSupply); + + EncodedLengths _encodedLengths = encodeLengths(name, symbol); + bytes memory _dynamicData = encodeDynamic(name, symbol); + + return (_staticData, _encodedLengths, _dynamicData); + } + + /** + * @notice Encode keys as a bytes32 array using this table's field layout. + */ + function encodeKeyTuple(bytes32 id) internal pure returns (bytes32[] memory) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = id; + + return _keyTuple; + } +} From 5de4e04f544630062ff076b2eb167ffaccbea8c7 Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Wed, 28 Aug 2024 16:19:47 +0200 Subject: [PATCH 25/29] add view functions --- .../src/MUDERC20.sol | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/world-module-erc20-own-store/src/MUDERC20.sol b/packages/world-module-erc20-own-store/src/MUDERC20.sol index e5b882b098..4ccd5e3b30 100644 --- a/packages/world-module-erc20-own-store/src/MUDERC20.sol +++ b/packages/world-module-erc20-own-store/src/MUDERC20.sol @@ -8,6 +8,7 @@ import { Balances } from "./codegen/tables/Balances.sol"; import { Allowances } from "./codegen/tables/Allowances.sol"; import { Store } from "@latticexyz/store/src/Store.sol"; +import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; contract MUDERC20 is Store, IERC20Errors, IERC20Events { constructor(string memory _name, string memory _symbol, uint8 _decimals) { @@ -18,7 +19,7 @@ contract MUDERC20 is Store, IERC20Errors, IERC20Events { Balances.register(); Allowances.register(); - Token.set(_name, _symbol, _decimals); + Token.set( _decimals, 0, _name, _symbol); } /// VIEW FUNCTIONS /// @@ -41,7 +42,7 @@ contract MUDERC20 is Store, IERC20Errors, IERC20Events { /** * @dev Returns the decimals of the token. */ - function decimals() public view returns (string memory) { + function decimals() public view returns (uint8) { return Token.getDecimals(); } @@ -51,4 +52,18 @@ contract MUDERC20 is Store, IERC20Errors, IERC20Events { function totalSupply() public view returns (uint256) { return Token.getTotalSupply(); } + + /** + * @dev Returns the balance of the `account`. + */ + function balanceOf(address account) public view returns (uint256) { + return Balances.get(account); + } + + /** + * @dev Returns the allowance of `spender` for `owner`. + */ + function allowance(address owner, address spender) public view returns (uint256) { + return Allowances.get(owner, spender); + } } From a4adf6fc2cca01c1df308d907c1f536058c7e1ef Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Wed, 28 Aug 2024 16:20:46 +0200 Subject: [PATCH 26/29] update natspec --- packages/world-module-erc20-own-store/src/MUDERC20.sol | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/world-module-erc20-own-store/src/MUDERC20.sol b/packages/world-module-erc20-own-store/src/MUDERC20.sol index 4ccd5e3b30..2ec69b5cd7 100644 --- a/packages/world-module-erc20-own-store/src/MUDERC20.sol +++ b/packages/world-module-erc20-own-store/src/MUDERC20.sol @@ -19,13 +19,14 @@ contract MUDERC20 is Store, IERC20Errors, IERC20Events { Balances.register(); Allowances.register(); - Token.set( _decimals, 0, _name, _symbol); + Token.set(_decimals, 0, _name, _symbol); } /// VIEW FUNCTIONS /// /** * @dev Returns the name of the token. + * @return The name of the token. */ function name() public view returns (string memory) { return Token.getName(); @@ -34,6 +35,7 @@ contract MUDERC20 is Store, IERC20Errors, IERC20Events { /** * @dev Returns the symbol of the token, usually a shorter version of the * name. + * @return The symbol of the token. */ function symbol() public view returns (string memory) { return Token.getSymbol(); @@ -41,6 +43,7 @@ contract MUDERC20 is Store, IERC20Errors, IERC20Events { /** * @dev Returns the decimals of the token. + * @return The number of decimals of the token. */ function decimals() public view returns (uint8) { return Token.getDecimals(); @@ -48,6 +51,7 @@ contract MUDERC20 is Store, IERC20Errors, IERC20Events { /** * @dev Returns the total supply of the token. + * @return The total supply of the token. */ function totalSupply() public view returns (uint256) { return Token.getTotalSupply(); @@ -55,6 +59,8 @@ contract MUDERC20 is Store, IERC20Errors, IERC20Events { /** * @dev Returns the balance of the `account`. + * @param account The address of the account to get the balance of. + * @return The balance of the `account`. */ function balanceOf(address account) public view returns (uint256) { return Balances.get(account); @@ -62,6 +68,8 @@ contract MUDERC20 is Store, IERC20Errors, IERC20Events { /** * @dev Returns the allowance of `spender` for `owner`. + * @param owner The address of the owner. + * @param spender The address of the spender. */ function allowance(address owner, address spender) public view returns (uint256) { return Allowances.get(owner, spender); From 6a6e22bd60c973e944b7fa4b892a337f13fd5bf0 Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Wed, 28 Aug 2024 16:38:50 +0200 Subject: [PATCH 27/29] make Token a singleton table --- .../mud.config.ts | 3 +- .../src/codegen/tables/Token.sol | 232 +++++++----------- 2 files changed, 94 insertions(+), 141 deletions(-) diff --git a/packages/world-module-erc20-own-store/mud.config.ts b/packages/world-module-erc20-own-store/mud.config.ts index e3f30d4c83..9ac482e59d 100644 --- a/packages/world-module-erc20-own-store/mud.config.ts +++ b/packages/world-module-erc20-own-store/mud.config.ts @@ -7,11 +7,10 @@ export default defineWorld({ schema: { decimals: "uint8", totalSupply: "uint256", - id: "bytes32", name: "string", symbol: "string", }, - key: ["id"], + key: [], // Singleton table codegen: { outputDirectory: "./tables", }, diff --git a/packages/world-module-erc20-own-store/src/codegen/tables/Token.sol b/packages/world-module-erc20-own-store/src/codegen/tables/Token.sol index 927d5496bb..aae3b9fd79 100644 --- a/packages/world-module-erc20-own-store/src/codegen/tables/Token.sol +++ b/packages/world-module-erc20-own-store/src/codegen/tables/Token.sol @@ -30,8 +30,8 @@ library Token { FieldLayout constant _fieldLayout = FieldLayout.wrap(0x0021020201200000000000000000000000000000000000000000000000000000); - // Hex-encoded key schema of (bytes32) - Schema constant _keySchema = Schema.wrap(0x002001005f000000000000000000000000000000000000000000000000000000); + // Hex-encoded key schema of () + Schema constant _keySchema = Schema.wrap(0x0000000000000000000000000000000000000000000000000000000000000000); // Hex-encoded value schema of (uint8, uint256, string, string) Schema constant _valueSchema = Schema.wrap(0x00210202001fc5c5000000000000000000000000000000000000000000000000); @@ -40,8 +40,7 @@ library Token { * @return keyNames An array of strings with the names of key fields. */ function getKeyNames() internal pure returns (string[] memory keyNames) { - keyNames = new string[](1); - keyNames[0] = "id"; + keyNames = new string[](0); } /** @@ -73,9 +72,8 @@ library Token { /** * @notice Get decimals. */ - function getDecimals(bytes32 id) internal view returns (uint8 decimals) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function getDecimals() internal view returns (uint8 decimals) { + bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (uint8(bytes1(_blob))); @@ -84,9 +82,8 @@ library Token { /** * @notice Get decimals. */ - function _getDecimals(bytes32 id) internal view returns (uint8 decimals) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _getDecimals() internal view returns (uint8 decimals) { + bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (uint8(bytes1(_blob))); @@ -95,9 +92,8 @@ library Token { /** * @notice Set decimals. */ - function setDecimals(bytes32 id, uint8 decimals) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function setDecimals(uint8 decimals) internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.setStaticField(_tableId, _keyTuple, 0, abi.encodePacked((decimals)), _fieldLayout); } @@ -105,9 +101,8 @@ library Token { /** * @notice Set decimals. */ - function _setDecimals(bytes32 id, uint8 decimals) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _setDecimals(uint8 decimals) internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.setStaticField(_tableId, _keyTuple, 0, abi.encodePacked((decimals)), _fieldLayout); } @@ -115,9 +110,8 @@ library Token { /** * @notice Get totalSupply. */ - function getTotalSupply(bytes32 id) internal view returns (uint256 totalSupply) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function getTotalSupply() internal view returns (uint256 totalSupply) { + bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 1, _fieldLayout); return (uint256(bytes32(_blob))); @@ -126,9 +120,8 @@ library Token { /** * @notice Get totalSupply. */ - function _getTotalSupply(bytes32 id) internal view returns (uint256 totalSupply) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _getTotalSupply() internal view returns (uint256 totalSupply) { + bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 1, _fieldLayout); return (uint256(bytes32(_blob))); @@ -137,9 +130,8 @@ library Token { /** * @notice Set totalSupply. */ - function setTotalSupply(bytes32 id, uint256 totalSupply) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function setTotalSupply(uint256 totalSupply) internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.setStaticField(_tableId, _keyTuple, 1, abi.encodePacked((totalSupply)), _fieldLayout); } @@ -147,9 +139,8 @@ library Token { /** * @notice Set totalSupply. */ - function _setTotalSupply(bytes32 id, uint256 totalSupply) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _setTotalSupply(uint256 totalSupply) internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.setStaticField(_tableId, _keyTuple, 1, abi.encodePacked((totalSupply)), _fieldLayout); } @@ -157,9 +148,8 @@ library Token { /** * @notice Get name. */ - function getName(bytes32 id) internal view returns (string memory name) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function getName() internal view returns (string memory name) { + bytes32[] memory _keyTuple = new bytes32[](0); bytes memory _blob = StoreSwitch.getDynamicField(_tableId, _keyTuple, 0); return (string(_blob)); @@ -168,9 +158,8 @@ library Token { /** * @notice Get name. */ - function _getName(bytes32 id) internal view returns (string memory name) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _getName() internal view returns (string memory name) { + bytes32[] memory _keyTuple = new bytes32[](0); bytes memory _blob = StoreCore.getDynamicField(_tableId, _keyTuple, 0); return (string(_blob)); @@ -179,9 +168,8 @@ library Token { /** * @notice Set name. */ - function setName(bytes32 id, string memory name) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function setName(string memory name) internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.setDynamicField(_tableId, _keyTuple, 0, bytes((name))); } @@ -189,9 +177,8 @@ library Token { /** * @notice Set name. */ - function _setName(bytes32 id, string memory name) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _setName(string memory name) internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.setDynamicField(_tableId, _keyTuple, 0, bytes((name))); } @@ -199,9 +186,8 @@ library Token { /** * @notice Get the length of name. */ - function lengthName(bytes32 id) internal view returns (uint256) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function lengthName() internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](0); uint256 _byteLength = StoreSwitch.getDynamicFieldLength(_tableId, _keyTuple, 0); unchecked { @@ -212,9 +198,8 @@ library Token { /** * @notice Get the length of name. */ - function _lengthName(bytes32 id) internal view returns (uint256) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _lengthName() internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](0); uint256 _byteLength = StoreCore.getDynamicFieldLength(_tableId, _keyTuple, 0); unchecked { @@ -226,9 +211,8 @@ library Token { * @notice Get an item of name. * @dev Reverts with Store_IndexOutOfBounds if `_index` is out of bounds for the array. */ - function getItemName(bytes32 id, uint256 _index) internal view returns (string memory) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function getItemName(uint256 _index) internal view returns (string memory) { + bytes32[] memory _keyTuple = new bytes32[](0); unchecked { bytes memory _blob = StoreSwitch.getDynamicFieldSlice(_tableId, _keyTuple, 0, _index * 1, (_index + 1) * 1); @@ -240,9 +224,8 @@ library Token { * @notice Get an item of name. * @dev Reverts with Store_IndexOutOfBounds if `_index` is out of bounds for the array. */ - function _getItemName(bytes32 id, uint256 _index) internal view returns (string memory) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _getItemName(uint256 _index) internal view returns (string memory) { + bytes32[] memory _keyTuple = new bytes32[](0); unchecked { bytes memory _blob = StoreCore.getDynamicFieldSlice(_tableId, _keyTuple, 0, _index * 1, (_index + 1) * 1); @@ -253,9 +236,8 @@ library Token { /** * @notice Push a slice to name. */ - function pushName(bytes32 id, string memory _slice) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function pushName(string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.pushToDynamicField(_tableId, _keyTuple, 0, bytes((_slice))); } @@ -263,9 +245,8 @@ library Token { /** * @notice Push a slice to name. */ - function _pushName(bytes32 id, string memory _slice) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _pushName(string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.pushToDynamicField(_tableId, _keyTuple, 0, bytes((_slice))); } @@ -273,9 +254,8 @@ library Token { /** * @notice Pop a slice from name. */ - function popName(bytes32 id) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function popName() internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.popFromDynamicField(_tableId, _keyTuple, 0, 1); } @@ -283,9 +263,8 @@ library Token { /** * @notice Pop a slice from name. */ - function _popName(bytes32 id) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _popName() internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.popFromDynamicField(_tableId, _keyTuple, 0, 1); } @@ -293,9 +272,8 @@ library Token { /** * @notice Update a slice of name at `_index`. */ - function updateName(bytes32 id, uint256 _index, string memory _slice) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function updateName(uint256 _index, string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](0); unchecked { bytes memory _encoded = bytes((_slice)); @@ -306,9 +284,8 @@ library Token { /** * @notice Update a slice of name at `_index`. */ - function _updateName(bytes32 id, uint256 _index, string memory _slice) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _updateName(uint256 _index, string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](0); unchecked { bytes memory _encoded = bytes((_slice)); @@ -319,9 +296,8 @@ library Token { /** * @notice Get symbol. */ - function getSymbol(bytes32 id) internal view returns (string memory symbol) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function getSymbol() internal view returns (string memory symbol) { + bytes32[] memory _keyTuple = new bytes32[](0); bytes memory _blob = StoreSwitch.getDynamicField(_tableId, _keyTuple, 1); return (string(_blob)); @@ -330,9 +306,8 @@ library Token { /** * @notice Get symbol. */ - function _getSymbol(bytes32 id) internal view returns (string memory symbol) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _getSymbol() internal view returns (string memory symbol) { + bytes32[] memory _keyTuple = new bytes32[](0); bytes memory _blob = StoreCore.getDynamicField(_tableId, _keyTuple, 1); return (string(_blob)); @@ -341,9 +316,8 @@ library Token { /** * @notice Set symbol. */ - function setSymbol(bytes32 id, string memory symbol) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function setSymbol(string memory symbol) internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.setDynamicField(_tableId, _keyTuple, 1, bytes((symbol))); } @@ -351,9 +325,8 @@ library Token { /** * @notice Set symbol. */ - function _setSymbol(bytes32 id, string memory symbol) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _setSymbol(string memory symbol) internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.setDynamicField(_tableId, _keyTuple, 1, bytes((symbol))); } @@ -361,9 +334,8 @@ library Token { /** * @notice Get the length of symbol. */ - function lengthSymbol(bytes32 id) internal view returns (uint256) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function lengthSymbol() internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](0); uint256 _byteLength = StoreSwitch.getDynamicFieldLength(_tableId, _keyTuple, 1); unchecked { @@ -374,9 +346,8 @@ library Token { /** * @notice Get the length of symbol. */ - function _lengthSymbol(bytes32 id) internal view returns (uint256) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _lengthSymbol() internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](0); uint256 _byteLength = StoreCore.getDynamicFieldLength(_tableId, _keyTuple, 1); unchecked { @@ -388,9 +359,8 @@ library Token { * @notice Get an item of symbol. * @dev Reverts with Store_IndexOutOfBounds if `_index` is out of bounds for the array. */ - function getItemSymbol(bytes32 id, uint256 _index) internal view returns (string memory) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function getItemSymbol(uint256 _index) internal view returns (string memory) { + bytes32[] memory _keyTuple = new bytes32[](0); unchecked { bytes memory _blob = StoreSwitch.getDynamicFieldSlice(_tableId, _keyTuple, 1, _index * 1, (_index + 1) * 1); @@ -402,9 +372,8 @@ library Token { * @notice Get an item of symbol. * @dev Reverts with Store_IndexOutOfBounds if `_index` is out of bounds for the array. */ - function _getItemSymbol(bytes32 id, uint256 _index) internal view returns (string memory) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _getItemSymbol(uint256 _index) internal view returns (string memory) { + bytes32[] memory _keyTuple = new bytes32[](0); unchecked { bytes memory _blob = StoreCore.getDynamicFieldSlice(_tableId, _keyTuple, 1, _index * 1, (_index + 1) * 1); @@ -415,9 +384,8 @@ library Token { /** * @notice Push a slice to symbol. */ - function pushSymbol(bytes32 id, string memory _slice) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function pushSymbol(string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.pushToDynamicField(_tableId, _keyTuple, 1, bytes((_slice))); } @@ -425,9 +393,8 @@ library Token { /** * @notice Push a slice to symbol. */ - function _pushSymbol(bytes32 id, string memory _slice) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _pushSymbol(string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.pushToDynamicField(_tableId, _keyTuple, 1, bytes((_slice))); } @@ -435,9 +402,8 @@ library Token { /** * @notice Pop a slice from symbol. */ - function popSymbol(bytes32 id) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function popSymbol() internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.popFromDynamicField(_tableId, _keyTuple, 1, 1); } @@ -445,9 +411,8 @@ library Token { /** * @notice Pop a slice from symbol. */ - function _popSymbol(bytes32 id) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _popSymbol() internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.popFromDynamicField(_tableId, _keyTuple, 1, 1); } @@ -455,9 +420,8 @@ library Token { /** * @notice Update a slice of symbol at `_index`. */ - function updateSymbol(bytes32 id, uint256 _index, string memory _slice) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function updateSymbol(uint256 _index, string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](0); unchecked { bytes memory _encoded = bytes((_slice)); @@ -468,9 +432,8 @@ library Token { /** * @notice Update a slice of symbol at `_index`. */ - function _updateSymbol(bytes32 id, uint256 _index, string memory _slice) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _updateSymbol(uint256 _index, string memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](0); unchecked { bytes memory _encoded = bytes((_slice)); @@ -481,9 +444,8 @@ library Token { /** * @notice Get the full data. */ - function get(bytes32 id) internal view returns (TokenData memory _table) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function get() internal view returns (TokenData memory _table) { + bytes32[] memory _keyTuple = new bytes32[](0); (bytes memory _staticData, EncodedLengths _encodedLengths, bytes memory _dynamicData) = StoreSwitch.getRecord( _tableId, @@ -496,9 +458,8 @@ library Token { /** * @notice Get the full data. */ - function _get(bytes32 id) internal view returns (TokenData memory _table) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _get() internal view returns (TokenData memory _table) { + bytes32[] memory _keyTuple = new bytes32[](0); (bytes memory _staticData, EncodedLengths _encodedLengths, bytes memory _dynamicData) = StoreCore.getRecord( _tableId, @@ -511,14 +472,13 @@ library Token { /** * @notice Set the full data using individual values. */ - function set(bytes32 id, uint8 decimals, uint256 totalSupply, string memory name, string memory symbol) internal { + function set(uint8 decimals, uint256 totalSupply, string memory name, string memory symbol) internal { bytes memory _staticData = encodeStatic(decimals, totalSupply); EncodedLengths _encodedLengths = encodeLengths(name, symbol); bytes memory _dynamicData = encodeDynamic(name, symbol); - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData); } @@ -526,14 +486,13 @@ library Token { /** * @notice Set the full data using individual values. */ - function _set(bytes32 id, uint8 decimals, uint256 totalSupply, string memory name, string memory symbol) internal { + function _set(uint8 decimals, uint256 totalSupply, string memory name, string memory symbol) internal { bytes memory _staticData = encodeStatic(decimals, totalSupply); EncodedLengths _encodedLengths = encodeLengths(name, symbol); bytes memory _dynamicData = encodeDynamic(name, symbol); - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); } @@ -541,14 +500,13 @@ library Token { /** * @notice Set the full data using the data struct. */ - function set(bytes32 id, TokenData memory _table) internal { + function set(TokenData memory _table) internal { bytes memory _staticData = encodeStatic(_table.decimals, _table.totalSupply); EncodedLengths _encodedLengths = encodeLengths(_table.name, _table.symbol); bytes memory _dynamicData = encodeDynamic(_table.name, _table.symbol); - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData); } @@ -556,14 +514,13 @@ library Token { /** * @notice Set the full data using the data struct. */ - function _set(bytes32 id, TokenData memory _table) internal { + function _set(TokenData memory _table) internal { bytes memory _staticData = encodeStatic(_table.decimals, _table.totalSupply); EncodedLengths _encodedLengths = encodeLengths(_table.name, _table.symbol); bytes memory _dynamicData = encodeDynamic(_table.name, _table.symbol); - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); } @@ -617,9 +574,8 @@ library Token { /** * @notice Delete all data for given keys. */ - function deleteRecord(bytes32 id) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.deleteRecord(_tableId, _keyTuple); } @@ -627,9 +583,8 @@ library Token { /** * @notice Delete all data for given keys. */ - function _deleteRecord(bytes32 id) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function _deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } @@ -687,9 +642,8 @@ library Token { /** * @notice Encode keys as a bytes32 array using this table's field layout. */ - function encodeKeyTuple(bytes32 id) internal pure returns (bytes32[] memory) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = id; + function encodeKeyTuple() internal pure returns (bytes32[] memory) { + bytes32[] memory _keyTuple = new bytes32[](0); return _keyTuple; } From c0441cef4e0353236af26b7ec77ef544e5fd554c Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Wed, 28 Aug 2024 16:39:12 +0200 Subject: [PATCH 28/29] update getters to use a singleton table --- packages/world-module-erc20-own-store/src/MUDERC20.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/world-module-erc20-own-store/src/MUDERC20.sol b/packages/world-module-erc20-own-store/src/MUDERC20.sol index 2ec69b5cd7..f7df9e0048 100644 --- a/packages/world-module-erc20-own-store/src/MUDERC20.sol +++ b/packages/world-module-erc20-own-store/src/MUDERC20.sol @@ -22,8 +22,6 @@ contract MUDERC20 is Store, IERC20Errors, IERC20Events { Token.set(_decimals, 0, _name, _symbol); } - /// VIEW FUNCTIONS /// - /** * @dev Returns the name of the token. * @return The name of the token. From e0a1ffff1f44f6a5419881535c220a674e4c77b2 Mon Sep 17 00:00:00 2001 From: Tamara Ringas <69479754+TamaraRingas@users.noreply.github.com> Date: Wed, 28 Aug 2024 16:39:46 +0200 Subject: [PATCH 29/29] update lockfile --- pnpm-lock.yaml | 72 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 22 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 44a1b5cbf0..2c4fb4d6fb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3036,6 +3036,10 @@ packages: node-notifier: optional: true + '@jest/schemas@29.4.3': + resolution: {integrity: sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/schemas@29.6.3': resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -4256,6 +4260,9 @@ packages: '@sideway/pinpoint@2.0.0': resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + '@sinclair/typebox@0.25.24': + resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==} + '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} @@ -6819,6 +6826,9 @@ packages: resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} + get-tsconfig@4.5.0: + resolution: {integrity: sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==} + get-tsconfig@4.7.5: resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} @@ -8903,6 +8913,10 @@ packages: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + pretty-format@29.5.0: + resolution: {integrity: sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -12423,7 +12437,7 @@ snapshots: '@esbuild-kit/cjs-loader@2.4.2': dependencies: '@esbuild-kit/core-utils': 3.1.0 - get-tsconfig: 4.7.5 + get-tsconfig: 4.5.0 '@esbuild-kit/core-utils@3.1.0': dependencies: @@ -12433,7 +12447,7 @@ snapshots: '@esbuild-kit/esm-loader@2.5.5': dependencies: '@esbuild-kit/core-utils': 3.1.0 - get-tsconfig: 4.7.5 + get-tsconfig: 4.5.0 '@esbuild/aix-ppc64@0.21.5': optional: true @@ -12809,7 +12823,7 @@ snapshots: jest-validate: 29.5.0 jest-watcher: 29.5.0 micromatch: 4.0.5 - pretty-format: 29.7.0 + pretty-format: 29.5.0 slash: 3.0.0 strip-ansi: 6.0.1 transitivePeerDependencies: @@ -12901,6 +12915,10 @@ snapshots: transitivePeerDependencies: - supports-color + '@jest/schemas@29.4.3': + dependencies: + '@sinclair/typebox': 0.25.24 + '@jest/schemas@29.6.3': dependencies: '@sinclair/typebox': 0.27.8 @@ -12955,7 +12973,7 @@ snapshots: '@jest/types@29.5.0': dependencies: - '@jest/schemas': 29.6.3 + '@jest/schemas': 29.4.3 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 '@types/node': 18.15.11 @@ -14506,6 +14524,8 @@ snapshots: '@sideway/pinpoint@2.0.0': {} + '@sinclair/typebox@0.25.24': {} + '@sinclair/typebox@0.27.8': {} '@sinonjs/commons@2.0.0': @@ -15802,7 +15822,7 @@ snapshots: are-we-there-yet@3.0.1: dependencies: delegates: 1.0.0 - readable-stream: 3.6.0 + readable-stream: 3.6.2 arg@5.0.2: {} @@ -16112,7 +16132,7 @@ snapshots: dependencies: buffer: 5.7.1 inherits: 2.0.4 - readable-stream: 3.6.0 + readable-stream: 3.6.2 bn.js@4.12.0: {} @@ -17369,7 +17389,7 @@ snapshots: eslint@5.16.0: dependencies: - '@babel/code-frame': 7.24.7 + '@babel/code-frame': 7.21.4 ajv: 6.12.6 chalk: 2.4.2 cross-spawn: 6.0.5 @@ -17957,6 +17977,8 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.2.4 + get-tsconfig@4.5.0: {} + get-tsconfig@4.7.5: dependencies: resolve-pkg-maps: 1.0.0 @@ -18622,7 +18644,7 @@ snapshots: jest-snapshot: 29.5.0 jest-util: 29.5.0 p-limit: 3.1.0 - pretty-format: 29.7.0 + pretty-format: 29.5.0 pure-rand: 6.0.1 slash: 3.0.0 stack-utils: 2.0.6 @@ -18688,7 +18710,7 @@ snapshots: jest-validate: 29.5.0 micromatch: 4.0.5 parse-json: 5.2.0 - pretty-format: 29.7.0 + pretty-format: 29.5.0 slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: @@ -18717,7 +18739,7 @@ snapshots: jest-validate: 29.5.0 micromatch: 4.0.5 parse-json: 5.2.0 - pretty-format: 29.7.0 + pretty-format: 29.5.0 slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: @@ -18737,7 +18759,7 @@ snapshots: chalk: 4.1.2 diff-sequences: 29.6.3 jest-get-type: 29.4.3 - pretty-format: 29.7.0 + pretty-format: 29.5.0 jest-docblock@29.4.3: dependencies: @@ -18794,7 +18816,7 @@ snapshots: jest-leak-detector@29.5.0: dependencies: jest-get-type: 29.4.3 - pretty-format: 29.7.0 + pretty-format: 29.5.0 jest-matcher-utils@27.5.1: dependencies: @@ -18808,17 +18830,17 @@ snapshots: chalk: 4.1.2 jest-diff: 29.5.0 jest-get-type: 29.4.3 - pretty-format: 29.7.0 + pretty-format: 29.5.0 jest-message-util@29.5.0: dependencies: - '@babel/code-frame': 7.24.7 + '@babel/code-frame': 7.21.4 '@jest/types': 29.5.0 '@types/stack-utils': 2.0.1 chalk: 4.1.2 graceful-fs: 4.2.11 micromatch: 4.0.5 - pretty-format: 29.7.0 + pretty-format: 29.5.0 slash: 3.0.0 stack-utils: 2.0.6 @@ -18947,7 +18969,7 @@ snapshots: jest-message-util: 29.5.0 jest-util: 29.5.0 natural-compare: 1.4.0 - pretty-format: 29.7.0 + pretty-format: 29.5.0 semver: 7.6.0 transitivePeerDependencies: - supports-color @@ -18977,7 +18999,7 @@ snapshots: chalk: 4.1.2 jest-get-type: 29.4.3 leven: 3.1.0 - pretty-format: 29.7.0 + pretty-format: 29.5.0 jest-validate@29.7.0: dependencies: @@ -19173,7 +19195,7 @@ snapshots: dependencies: node-addon-api: 2.0.2 node-gyp-build: 4.8.1 - readable-stream: 3.6.0 + readable-stream: 3.6.2 keygrip@1.1.0: dependencies: @@ -20240,7 +20262,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.24.7 + '@babel/code-frame': 7.21.4 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -20435,7 +20457,7 @@ snapshots: postcss@8.4.31: dependencies: nanoid: 3.3.6 - picocolors: 1.0.1 + picocolors: 1.0.0 source-map-js: 1.0.2 postgres@3.3.5: {} @@ -20503,6 +20525,12 @@ snapshots: ansi-styles: 5.2.0 react-is: 17.0.2 + pretty-format@29.5.0: + dependencies: + '@jest/schemas': 29.4.3 + ansi-styles: 5.2.0 + react-is: 18.2.0 + pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 @@ -21238,7 +21266,7 @@ snapshots: ignore: 4.0.6 js-yaml: 3.14.1 lodash: 4.17.21 - semver: 6.3.1 + semver: 6.3.0 optionalDependencies: prettier: 1.19.1 transitivePeerDependencies: @@ -22041,7 +22069,7 @@ snapshots: dependencies: browserslist: 4.23.0 escalade: 3.1.2 - picocolors: 1.0.1 + picocolors: 1.0.0 update-browserslist-db@1.1.0(browserslist@4.23.3): dependencies: