From 06fc515c75686a2569eb5f5a385a09795590a660 Mon Sep 17 00:00:00 2001 From: dk1a Date: Tue, 20 Dec 2022 19:21:35 +0300 Subject: [PATCH] feat: use Subsystem for ERC721Base and ERC1155Base --- README.md | 12 +-- contracts/mud/OwnableAndWriteAccess.sol | 44 --------- .../mud/OwnableAndWriteAccessStorage.sol | 20 ---- contracts/mud/SystemFacet.sol | 24 ----- contracts/mud/SystemStorage.sol | 23 ----- contracts/mud/_SystemFacet.sol | 32 ------- contracts/mud/_SystemStorage.sol | 24 ----- contracts/test/token/ERC1155/BaseTest.sol | 17 ++-- ...ystem.t.sol => ERC1155BaseSubsystem.t.sol} | 94 +++++++++---------- ...mMock.sol => ERC1155BaseSubsystemMock.sol} | 6 +- .../ERC1155/OperatorApprovalSystem.t.sol | 13 ++- .../ERC1155/SafeBatchTransferFromSystem.t.sol | 11 +-- .../SafeBatchTransferFromSystemMock.sol | 4 +- contracts/test/token/ERC721/BaseTest.sol | 17 ++-- ...System.t.sol => ERC721BaseSubsystem.t.sol} | 68 +++++++------- ...emMock.sol => ERC721BaseSubsystemMock.sol} | 8 +- .../token/ERC721/OperatorApprovalSystem.t.sol | 12 +-- .../token/ERC721/SafeTransferSystem.t.sol | 10 +- .../token/ERC721/SafeTransferSystemMock.sol | 4 +- .../token/ERC721/TokenApprovalSystem.t.sol | 13 ++- ...aseSystem.sol => ERC1155BaseSubsystem.sol} | 34 ++++--- .../systems/OperatorApprovalSystem.sol | 12 +-- .../systems/SafeBatchTransferFromSystem.sol | 12 +-- ...BaseSystem.sol => ERC721BaseSubsystem.sol} | 37 ++++---- .../ERC721/systems/OperatorApprovalSystem.sol | 12 +-- .../ERC721/systems/SafeTransferSystem.sol | 12 +-- .../ERC721/systems/TokenApprovalSystem.sol | 12 +-- package.json | 6 +- ...5BaseSystem.js => ERC1155BaseSubsystem.js} | 4 +- ...21BaseSystem.js => ERC721BaseSubsystem.js} | 8 +- yarn.lock | 9 +- 31 files changed, 228 insertions(+), 386 deletions(-) delete mode 100644 contracts/mud/OwnableAndWriteAccess.sol delete mode 100644 contracts/mud/OwnableAndWriteAccessStorage.sol delete mode 100644 contracts/mud/SystemFacet.sol delete mode 100644 contracts/mud/SystemStorage.sol delete mode 100644 contracts/mud/_SystemFacet.sol delete mode 100644 contracts/mud/_SystemStorage.sol rename contracts/test/token/ERC1155/{ERC1155BaseSystem.t.sol => ERC1155BaseSubsystem.t.sol} (54%) rename contracts/test/token/ERC1155/{ERC1155BaseSystemMock.sol => ERC1155BaseSubsystemMock.sol} (76%) rename contracts/test/token/ERC721/{ERC721BaseSystem.t.sol => ERC721BaseSubsystem.t.sol} (59%) rename contracts/test/token/ERC721/{ERC721BaseSystemMock.sol => ERC721BaseSubsystemMock.sol} (73%) rename contracts/token/ERC1155/{ERC1155BaseSystem.sol => ERC1155BaseSubsystem.sol} (87%) rename contracts/token/ERC721/{ERC721BaseSystem.sol => ERC721BaseSubsystem.sol} (87%) rename test/{ERC1155BaseSystem.js => ERC1155BaseSubsystem.js} (92%) rename test/{ERC721BaseSystem.js => ERC721BaseSubsystem.js} (89%) diff --git a/README.md b/README.md index 3c8b6a6..0a1cb4a 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # solecslib -ERC1155 and ERC721 Systems that use components to store data +ERC1155 and ERC721 Subsystems that use components to store data Experimental additions to [@latticexyz/solecs](https://github.com/latticexyz/mud/tree/main/packages/solecs) -See [mud.dev](https://mud.dev/) first for context on solecs and what a System is. +See [mud.dev](https://mud.dev/) first for context on solecs and what a System/Subsystem is. ### Development @@ -32,16 +32,16 @@ They have similar contracts with shared suffixes: - Internal - ERC internals, inherits VData - Logic - ERC public+internal methods, inherits Internal. This is a full ERC implementation, lacking only a data provider. - DataComponents - data provider (only simple setters/getters), inherits VData. -- ERC__System - Logic + DataComponents + System + constructor + default execute implementation. +- ERC__Subsystem - Logic + DataComponents + Subsystem + constructor + default execute implementation. -#### ERC1155BaseSystem, ERC721BaseSystem -Full ERC1155/721 and System implementation, with a default execute and sub-executes (mint,burn,transfer all share 1 contract). Its components may be read by anyone without even awareness of ERC1155/721, but writes must always go through ERC__BaseSystem (this is mostly because of events, only 1 contract should emit them). +#### ERC1155BaseSubsystem, ERC721BaseSubsystem +Full ERC1155/721 and Subsystem implementation, with a default execute and sub-executes (mint,burn,transfer all share 1 contract). Its components may be read by anyone without even awareness of ERC1155/721, but writes must always go through ERC__BaseSubsystem (this is mostly because of events, only 1 contract should emit them). #### Notes on VData and Logic Data and Logic separation isn't really necessary, but this was an interesting use case for it. For example by having *Logic + DataStorage + constructor* you could get an ordinary ERC1155/721 implementation (where DataStorage implements VData but just uses normal contract storage). And imo keeping components away from Logic makes it easier to compare to @solidstate/contracts (I tried to keep it very similar, and even reuse tests via @solidstate/spec). #### Forwarder systems, like OperatorApprovalSystem -These exist as an optional addition to ERC__BaseSystem. They are pure-ECS wrappers for transfers and approvals. I'm not sure they're useful. +These exist as an optional addition to ERC__BaseSubsystem. They are pure-ECS wrappers for transfers and approvals. I'm not sure they're useful. ---------- diff --git a/contracts/mud/OwnableAndWriteAccess.sol b/contracts/mud/OwnableAndWriteAccess.sol deleted file mode 100644 index 01ecab5..0000000 --- a/contracts/mud/OwnableAndWriteAccess.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.17; - -import { Ownable } from "@solidstate/contracts/access/ownable/Ownable.sol"; -import { OwnableAndWriteAccessStorage } from "./OwnableAndWriteAccessStorage.sol"; - -/** - * @title Simplified access control, with owner and authorized writers rather than full roles - */ -abstract contract OwnableAndWriteAccess is Ownable { - error OwnableAndWriteAccess__NotWriter(); - - function writeAccess(address operator) public view returns (bool) { - return OwnableAndWriteAccessStorage.layout().writeAccess[operator] - || operator == owner(); - } - - /** Revert if caller does not have write access to this component */ - modifier onlyWriter() { - if (!writeAccess(msg.sender)) { - revert OwnableAndWriteAccess__NotWriter(); - } - _; - } - - /** - * Grant write access to the given address. - * Can only be called by the owner. - * @param writer Address to grant write access to. - */ - function authorizeWriter(address writer) public onlyOwner { - OwnableAndWriteAccessStorage.layout().writeAccess[writer] = true; - } - - /** - * Revoke write access from the given address. - * Can only be called by the owner. - * @param writer Address to revoke write access. - */ - function unauthorizeWriter(address writer) public onlyOwner { - delete OwnableAndWriteAccessStorage.layout().writeAccess[writer]; - } -} diff --git a/contracts/mud/OwnableAndWriteAccessStorage.sol b/contracts/mud/OwnableAndWriteAccessStorage.sol deleted file mode 100644 index 3ecff3a..0000000 --- a/contracts/mud/OwnableAndWriteAccessStorage.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.17; - -library OwnableAndWriteAccessStorage { - bytes32 internal constant STORAGE_SLOT = - keccak256('solecslib.contracts.storage.OwnableAndWriteAccess'); - - struct Layout { - /** Addresses with write access */ - mapping(address => bool) writeAccess; - } - - function layout() internal pure returns (Layout storage l) { - bytes32 slot = STORAGE_SLOT; - assembly { - l.slot := slot - } - } -} \ No newline at end of file diff --git a/contracts/mud/SystemFacet.sol b/contracts/mud/SystemFacet.sol deleted file mode 100644 index bc77be8..0000000 --- a/contracts/mud/SystemFacet.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.17; - -import { OwnableStorage } from "@solidstate/contracts/access/ownable/OwnableStorage.sol"; -import { OwnableAndWriteAccess } from "./OwnableAndWriteAccess.sol"; - -import { ISystem } from "@latticexyz/solecs/src/interfaces/ISystem.sol"; -import { IUint256Component } from "@latticexyz/solecs/src/interfaces/IUint256Component.sol"; -import { IWorld } from "@latticexyz/solecs/src/interfaces/IWorld.sol"; - -import { SystemStorage } from "./SystemStorage.sol"; - -/** - * @title Diamond-compatible and upgradeable base System with access control - */ -abstract contract SystemFacet is OwnableAndWriteAccess { - function __SystemFacet_init(IWorld world, address components) internal virtual { - OwnableStorage.layout().owner = msg.sender; - - SystemStorage.layout().components = components == address(0) ? world.components() : IUint256Component(components); - SystemStorage.layout().world = world; - } -} diff --git a/contracts/mud/SystemStorage.sol b/contracts/mud/SystemStorage.sol deleted file mode 100644 index f64ade6..0000000 --- a/contracts/mud/SystemStorage.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.17; - -import { IUint256Component } from "@latticexyz/solecs/src/interfaces/IUint256Component.sol"; -import { IWorld } from "@latticexyz/solecs/src/interfaces/IWorld.sol"; - -library SystemStorage { - bytes32 internal constant STORAGE_SLOT = - keccak256('solecslib.contracts.storage.SystemStorage'); - - struct Layout { - IUint256Component components; - IWorld world; - } - - function layout() internal pure returns (Layout storage l) { - bytes32 slot = STORAGE_SLOT; - assembly { - l.slot := slot - } - } -} \ No newline at end of file diff --git a/contracts/mud/_SystemFacet.sol b/contracts/mud/_SystemFacet.sol deleted file mode 100644 index 8301458..0000000 --- a/contracts/mud/_SystemFacet.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.17; - -import { ISystem } from "@latticexyz/solecs/src/interfaces/ISystem.sol"; -import { IUint256Component } from "@latticexyz/solecs/src/interfaces/IUint256Component.sol"; -import { IWorld } from "@latticexyz/solecs/src/interfaces/IWorld.sol"; -import { SystemStorage } from "./_SystemStorage.sol"; - -/** - * @title Diamond-compatible and upgradeable base System - */ -abstract contract SystemFacet is ISystem { - error System__OnlyOwner(); - - function __System_init(IWorld world, address components) internal virtual { - SystemStorage.layout().owner = msg.sender; - SystemStorage.layout().components = components == address(0) ? world.components() : IUint256Component(components); - SystemStorage.layout().world = world; - } - - modifier onlyOwner() { - if (msg.sender != SystemStorage.layout().owner) { - revert System__OnlyOwner(); - } - _; - } - - function owner() public view override returns (address) { - return SystemStorage.layout().owner; - } -} diff --git a/contracts/mud/_SystemStorage.sol b/contracts/mud/_SystemStorage.sol deleted file mode 100644 index 915423e..0000000 --- a/contracts/mud/_SystemStorage.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.17; - -import { IUint256Component } from "@latticexyz/solecs/src/interfaces/IUint256Component.sol"; -import { IWorld } from "@latticexyz/solecs/src/interfaces/IWorld.sol"; - -library SystemStorage { - bytes32 internal constant STORAGE_SLOT = - keccak256('solecslib.contracts.storage.SystemStorage'); - - struct Layout { - IUint256Component components; - IWorld world; - address owner; - } - - function layout() internal pure returns (Layout storage l) { - bytes32 slot = STORAGE_SLOT; - assembly { - l.slot := slot - } - } -} \ No newline at end of file diff --git a/contracts/test/token/ERC1155/BaseTest.sol b/contracts/test/token/ERC1155/BaseTest.sol index e565eae..760e630 100644 --- a/contracts/test/token/ERC1155/BaseTest.sol +++ b/contracts/test/token/ERC1155/BaseTest.sol @@ -7,7 +7,7 @@ import { PRBTest } from "@prb/test/src/PRBTest.sol"; // ECS import { World } from "@latticexyz/solecs/src/World.sol"; // systems -import { ERC1155BaseSystemMock, ID as ERC1155BaseSystemMockID } from "./ERC1155BaseSystemMock.sol"; +import { ERC1155BaseSubsystemMock, ID as ERC1155BaseSubsystemMockID } from "./ERC1155BaseSubsystemMock.sol"; // ERC1155 events import { IERC1155Internal } from "@solidstate/contracts/interfaces/IERC1155Internal.sol"; @@ -26,8 +26,8 @@ contract BaseTest is address notWriter = address(bytes20(keccak256("notWriter"))); World world; - // ERC1155 System - ERC1155BaseSystemMock ercSystem; + // ERC1155 Subsystem + ERC1155BaseSubsystemMock ercSubsystem; uint256 tokenId = 1337; @@ -40,11 +40,10 @@ contract BaseTest is address components = address(world.components()); // deploy systems - ercSystem = new ERC1155BaseSystemMock(world, components); - // register systems - world.registerSystem(address(ercSystem), ERC1155BaseSystemMockID); - // allows calling ercSystem's execute - ercSystem.authorizeWriter(writer); + ercSubsystem = new ERC1155BaseSubsystemMock(world, components); + world.registerSystem(address(ercSubsystem), ERC1155BaseSubsystemMockID); + // authorize + ercSubsystem.authorizeWriter(writer); vm.stopPrank(); } @@ -53,7 +52,7 @@ contract BaseTest is function _defaultMintToAlice() internal { vm.prank(writer); - ercSystem.executeSafeMintBatch(alice, _asArray(tokenId), _asArray(100), ''); + ercSubsystem.executeSafeMintBatch(alice, _asArray(tokenId), _asArray(100), ''); } function _asArray(uint256 number) internal pure returns (uint256[] memory result) { diff --git a/contracts/test/token/ERC1155/ERC1155BaseSystem.t.sol b/contracts/test/token/ERC1155/ERC1155BaseSubsystem.t.sol similarity index 54% rename from contracts/test/token/ERC1155/ERC1155BaseSystem.t.sol rename to contracts/test/token/ERC1155/ERC1155BaseSubsystem.t.sol index 4be19c6..b80f9ad 100644 --- a/contracts/test/token/ERC1155/ERC1155BaseSystem.t.sol +++ b/contracts/test/token/ERC1155/ERC1155BaseSubsystem.t.sol @@ -6,16 +6,16 @@ import { BaseTest } from "./BaseTest.sol"; // errors import { IOwnableInternal } from "@solidstate/contracts/access/ownable/IOwnableInternal.sol"; -import { OwnableAndWriteAccess } from "../../../mud/OwnableAndWriteAccess.sol"; -import { ERC1155BaseSystem } from "../../../token/ERC1155/ERC1155BaseSystem.sol"; +import { OwnableWritable } from "@latticexyz/solecs/src/OwnableWritable.sol"; +import { ERC1155BaseSubsystem } from "../../../token/ERC1155/ERC1155BaseSubsystem.sol"; -contract ERC1155BaseSystemTest is BaseTest { +contract ERC1155BaseSubsystemTest is BaseTest { // EXECUTE function testInvalidExecute() public { vm.prank(deployer); - vm.expectRevert(ERC1155BaseSystem.ERC1155BaseSystem__InvalidExecuteSelector.selector); - ercSystem.execute(abi.encode( + vm.expectRevert(ERC1155BaseSubsystem.ERC1155BaseSubsystem__InvalidExecuteSelector.selector); + ercSubsystem.execute(abi.encode( bytes4(keccak256("invalid selector")), bytes('data') )); @@ -25,33 +25,33 @@ contract ERC1155BaseSystemTest is BaseTest { function testOwnerAuthorizeWriter() public { vm.prank(deployer); - ercSystem.authorizeWriter(alice); - assertTrue(ercSystem.writeAccess(alice)); + ercSubsystem.authorizeWriter(alice); + assertTrue(ercSubsystem.writeAccess(alice)); } function testNotOwnerAuthorizeWriter() public { vm.prank(alice); vm.expectRevert(IOwnableInternal.Ownable__NotOwner.selector); - ercSystem.authorizeWriter(alice); + ercSubsystem.authorizeWriter(alice); } // MINT function testMintDirectWriter() public { vm.prank(writer); - ercSystem.executeSafeMintBatch(alice, _asArray(tokenId), _asArray(100), ''); - assertEq(ercSystem.balanceOf(alice, tokenId), 100); + ercSubsystem.executeSafeMintBatch(alice, _asArray(tokenId), _asArray(100), ''); + assertEq(ercSubsystem.balanceOf(alice, tokenId), 100); } function testMintDirectNotWriter() public { vm.prank(notWriter); - vm.expectRevert(OwnableAndWriteAccess.OwnableAndWriteAccess__NotWriter.selector); - ercSystem.executeSafeMintBatch(alice, _asArray(tokenId), _asArray(100), ''); + vm.expectRevert(OwnableWritable.OwnableWritable__NotWriter.selector); + ercSubsystem.executeSafeMintBatch(alice, _asArray(tokenId), _asArray(100), ''); } function _mintExec(address receiver, uint256 _tokenId) internal { - ercSystem.execute(abi.encode( - ercSystem.executeSafeMintBatch.selector, + ercSubsystem.execute(abi.encode( + ercSubsystem.executeSafeMintBatch.selector, abi.encode(receiver, _asArray(_tokenId), _asArray(100), '') )); } @@ -59,19 +59,19 @@ contract ERC1155BaseSystemTest is BaseTest { function testMintWriter() public { vm.prank(writer); _mintExec(alice, tokenId); - assertEq(ercSystem.balanceOf(alice, tokenId), 100); + assertEq(ercSubsystem.balanceOf(alice, tokenId), 100); } function testMintNotWriter() public { vm.prank(notWriter); - vm.expectRevert(OwnableAndWriteAccess.OwnableAndWriteAccess__NotWriter.selector); + vm.expectRevert(OwnableWritable.OwnableWritable__NotWriter.selector); _mintExec(alice, tokenId); } function testMintOwner() public { vm.prank(deployer); _mintExec(alice, tokenId); - assertEq(ercSystem.balanceOf(alice, tokenId), 100); + assertEq(ercSubsystem.balanceOf(alice, tokenId), 100); } // BURN @@ -80,21 +80,21 @@ contract ERC1155BaseSystemTest is BaseTest { _defaultMintToAlice(); vm.prank(writer); - ercSystem.executeBurnBatch(alice, _asArray(tokenId), _asArray(80)); - assertEq(ercSystem.balanceOf(alice, tokenId), 20); + ercSubsystem.executeBurnBatch(alice, _asArray(tokenId), _asArray(80)); + assertEq(ercSubsystem.balanceOf(alice, tokenId), 20); } function testBurnDirectNotWriter() public { _defaultMintToAlice(); vm.prank(notWriter); - vm.expectRevert(OwnableAndWriteAccess.OwnableAndWriteAccess__NotWriter.selector); - ercSystem.executeBurnBatch(alice, _asArray(tokenId), _asArray(80)); + vm.expectRevert(OwnableWritable.OwnableWritable__NotWriter.selector); + ercSubsystem.executeBurnBatch(alice, _asArray(tokenId), _asArray(80)); } function _burnExec(address account, uint256 _tokenId) internal { - ercSystem.execute(abi.encode( - ercSystem.executeBurnBatch.selector, + ercSubsystem.execute(abi.encode( + ercSubsystem.executeBurnBatch.selector, abi.encode(account, _asArray(_tokenId), _asArray(80)) )); } @@ -104,14 +104,14 @@ contract ERC1155BaseSystemTest is BaseTest { vm.prank(writer); _burnExec(alice, tokenId); - assertEq(ercSystem.balanceOf(alice, tokenId), 20); + assertEq(ercSubsystem.balanceOf(alice, tokenId), 20); } function testBurnNotWriter() public { _defaultMintToAlice(); vm.prank(notWriter); - vm.expectRevert(OwnableAndWriteAccess.OwnableAndWriteAccess__NotWriter.selector); + vm.expectRevert(OwnableWritable.OwnableWritable__NotWriter.selector); _burnExec(alice, tokenId); } @@ -120,7 +120,7 @@ contract ERC1155BaseSystemTest is BaseTest { vm.prank(deployer); _burnExec(alice, tokenId); - assertEq(ercSystem.balanceOf(alice, tokenId), 20); + assertEq(ercSubsystem.balanceOf(alice, tokenId), 20); } // TRANSFER @@ -129,17 +129,17 @@ contract ERC1155BaseSystemTest is BaseTest { _defaultMintToAlice(); vm.prank(writer); - ercSystem.executeSafeTransferBatch(alice, alice, bob, _asArray(tokenId), _asArray(80), ''); - assertEq(ercSystem.balanceOf(alice, tokenId), 20); - assertEq(ercSystem.balanceOf(bob, tokenId), 80); + ercSubsystem.executeSafeTransferBatch(alice, alice, bob, _asArray(tokenId), _asArray(80), ''); + assertEq(ercSubsystem.balanceOf(alice, tokenId), 20); + assertEq(ercSubsystem.balanceOf(bob, tokenId), 80); } function testTransferDirectNotWriter() public { _defaultMintToAlice(); vm.prank(notWriter); - vm.expectRevert(OwnableAndWriteAccess.OwnableAndWriteAccess__NotWriter.selector); - ercSystem.executeSafeTransferBatch(alice, alice, bob, _asArray(tokenId), _asArray(80), ''); + vm.expectRevert(OwnableWritable.OwnableWritable__NotWriter.selector); + ercSubsystem.executeSafeTransferBatch(alice, alice, bob, _asArray(tokenId), _asArray(80), ''); } function _transferExec( @@ -150,8 +150,8 @@ contract ERC1155BaseSystemTest is BaseTest { uint256 amount, bytes memory data ) internal { - ercSystem.execute(abi.encode( - ercSystem.executeSafeTransferBatch.selector, + ercSubsystem.execute(abi.encode( + ercSubsystem.executeSafeTransferBatch.selector, abi.encode(operator, from, to, _asArray(_tokenId), _asArray(amount), data) )); } @@ -161,15 +161,15 @@ contract ERC1155BaseSystemTest is BaseTest { vm.prank(writer); _transferExec(alice, alice, bob, tokenId, 80, ''); - assertEq(ercSystem.balanceOf(alice, tokenId), 20); - assertEq(ercSystem.balanceOf(bob, tokenId), 80); + assertEq(ercSubsystem.balanceOf(alice, tokenId), 20); + assertEq(ercSubsystem.balanceOf(bob, tokenId), 80); } function testTransferNotWriter() public { _defaultMintToAlice(); vm.prank(notWriter); - vm.expectRevert(OwnableAndWriteAccess.OwnableAndWriteAccess__NotWriter.selector); + vm.expectRevert(OwnableWritable.OwnableWritable__NotWriter.selector); _transferExec(alice, alice, bob, tokenId, 80, ''); } @@ -178,27 +178,27 @@ contract ERC1155BaseSystemTest is BaseTest { vm.prank(deployer); _transferExec(alice, alice, bob, tokenId, 80, ''); - assertEq(ercSystem.balanceOf(alice, tokenId), 20); - assertEq(ercSystem.balanceOf(bob, tokenId), 80); + assertEq(ercSubsystem.balanceOf(alice, tokenId), 20); + assertEq(ercSubsystem.balanceOf(bob, tokenId), 80); } // APPROVAL FOR ALL function testApprovalDirectWriter() public { vm.prank(writer); - ercSystem.executeSetApprovalForAll(alice, bob, true); - assertTrue(ercSystem.isApprovedForAll(alice, bob)); + ercSubsystem.executeSetApprovalForAll(alice, bob, true); + assertTrue(ercSubsystem.isApprovedForAll(alice, bob)); } function testApprovalDirectNotWriter() public { vm.prank(notWriter); - vm.expectRevert(OwnableAndWriteAccess.OwnableAndWriteAccess__NotWriter.selector); - ercSystem.executeSetApprovalForAll(alice, bob, true); + vm.expectRevert(OwnableWritable.OwnableWritable__NotWriter.selector); + ercSubsystem.executeSetApprovalForAll(alice, bob, true); } function _approvalExec(address account, address operator) internal { - ercSystem.execute(abi.encode( - ercSystem.executeSetApprovalForAll.selector, + ercSubsystem.execute(abi.encode( + ercSubsystem.executeSetApprovalForAll.selector, abi.encode(account, operator, true) )); } @@ -206,18 +206,18 @@ contract ERC1155BaseSystemTest is BaseTest { function testApprovalWriter() public { vm.prank(writer); _approvalExec(alice, bob); - assertTrue(ercSystem.isApprovedForAll(alice, bob)); + assertTrue(ercSubsystem.isApprovedForAll(alice, bob)); } function testApprovalNotWriter() public { vm.prank(notWriter); - vm.expectRevert(OwnableAndWriteAccess.OwnableAndWriteAccess__NotWriter.selector); + vm.expectRevert(OwnableWritable.OwnableWritable__NotWriter.selector); _approvalExec(alice, bob); } function testApprovalOwner() public { vm.prank(deployer); _approvalExec(alice, bob); - assertTrue(ercSystem.isApprovedForAll(alice, bob)); + assertTrue(ercSubsystem.isApprovedForAll(alice, bob)); } } \ No newline at end of file diff --git a/contracts/test/token/ERC1155/ERC1155BaseSystemMock.sol b/contracts/test/token/ERC1155/ERC1155BaseSubsystemMock.sol similarity index 76% rename from contracts/test/token/ERC1155/ERC1155BaseSystemMock.sol rename to contracts/test/token/ERC1155/ERC1155BaseSubsystemMock.sol index 32132bb..dc698de 100644 --- a/contracts/test/token/ERC1155/ERC1155BaseSystemMock.sol +++ b/contracts/test/token/ERC1155/ERC1155BaseSubsystemMock.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.17; import { IWorld } from "@latticexyz/solecs/src/interfaces/IWorld.sol"; -import { ERC1155BaseSystem } from "../../../token/ERC1155/ERC1155BaseSystem.sol"; +import { ERC1155BaseSubsystem } from "../../../token/ERC1155/ERC1155BaseSubsystem.sol"; uint256 constant ID = uint256(keccak256("test.system.ERC1155Base")); @@ -14,11 +14,11 @@ uint256 constant operatorApprovalComponentId = uint256(keccak256( abi.encode(ID, "test.component.OperatorApproval") )); -contract ERC1155BaseSystemMock is ERC1155BaseSystem { +contract ERC1155BaseSubsystemMock is ERC1155BaseSubsystem { constructor( IWorld _world, address _components - ) ERC1155BaseSystem(_world, _components, balanceComponentId, operatorApprovalComponentId) {} + ) ERC1155BaseSubsystem(_world, _components, balanceComponentId, operatorApprovalComponentId) {} // this is for hardhat tests function mint( diff --git a/contracts/test/token/ERC1155/OperatorApprovalSystem.t.sol b/contracts/test/token/ERC1155/OperatorApprovalSystem.t.sol index b6b4104..e6b9cb8 100644 --- a/contracts/test/token/ERC1155/OperatorApprovalSystem.t.sol +++ b/contracts/test/token/ERC1155/OperatorApprovalSystem.t.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.17; import { BaseTest } from "./BaseTest.sol"; // systems -import { ID as ERC1155BaseSystemID } from "./ERC1155BaseSystemMock.sol"; +import { ID as ERC1155BaseSubsystemID } from "./ERC1155BaseSubsystemMock.sol"; import { OperatorApprovalSystem } from "../../../token/ERC1155/systems/OperatorApprovalSystem.sol"; contract OperatorApprovalSystemTest is BaseTest { @@ -18,11 +18,10 @@ contract OperatorApprovalSystemTest is BaseTest { address components = address(world.components()); // deploy systems - oaSystem = new OperatorApprovalSystem(world, components, ERC1155BaseSystemID); - // register systems + oaSystem = new OperatorApprovalSystem(world, components, ERC1155BaseSubsystemID); world.registerSystem(address(oaSystem), uint256(keccak256("oaSystem"))); - // allows calling ercSystem's execute - ercSystem.authorizeWriter(address(oaSystem)); + // authorize + ercSubsystem.authorizeWriter(address(oaSystem)); vm.stopPrank(); } @@ -38,7 +37,7 @@ contract OperatorApprovalSystemTest is BaseTest { _expectEmitApprovalForAll(alice); oaSystem.executeTyped(bob, true); - assertTrue(ercSystem.isApprovedForAll(alice, bob)); + assertTrue(ercSubsystem.isApprovedForAll(alice, bob)); } function testExecuteOnSystem() public { @@ -46,6 +45,6 @@ contract OperatorApprovalSystemTest is BaseTest { _expectEmitApprovalForAll(alice); oaSystem.executeTyped(address(oaSystem), true); - assertTrue(ercSystem.isApprovedForAll(alice, address(oaSystem))); + assertTrue(ercSubsystem.isApprovedForAll(alice, address(oaSystem))); } } \ No newline at end of file diff --git a/contracts/test/token/ERC1155/SafeBatchTransferFromSystem.t.sol b/contracts/test/token/ERC1155/SafeBatchTransferFromSystem.t.sol index d7596c8..fa6d996 100644 --- a/contracts/test/token/ERC1155/SafeBatchTransferFromSystem.t.sol +++ b/contracts/test/token/ERC1155/SafeBatchTransferFromSystem.t.sol @@ -21,10 +21,9 @@ contract SafeBatchTransferFromSystemTest is BaseTest { address components = address(world.components()); // deploy systems transferSystem = new SafeBatchTransferFromSystemMock(world, components); - // register systems world.registerSystem(address(transferSystem), SafeBatchTransferFromSystemMockID); - // allows calling ercSystem's execute - ercSystem.authorizeWriter(address(transferSystem)); + // authorize + ercSubsystem.authorizeWriter(address(transferSystem)); vm.stopPrank(); } @@ -42,8 +41,8 @@ contract SafeBatchTransferFromSystemTest is BaseTest { _expectEmitTransferBatch(alice); transferSystem.executeTyped(alice, bob, _asArray(tokenId), _asArray(80), ''); - assertEq(ercSystem.balanceOf(alice, tokenId), 20); - assertEq(ercSystem.balanceOf(bob, tokenId), 80); + assertEq(ercSubsystem.balanceOf(alice, tokenId), 20); + assertEq(ercSubsystem.balanceOf(bob, tokenId), 80); } function testExecuteNotOwner() public { @@ -56,7 +55,7 @@ contract SafeBatchTransferFromSystemTest is BaseTest { function testExecuteNotOwnerFromForwarder() public { vm.prank(writer); - ercSystem.executeSafeMintBatch(address(transferSystem), _asArray(tokenId), _asArray(100), ''); + ercSubsystem.executeSafeMintBatch(address(transferSystem), _asArray(tokenId), _asArray(100), ''); vm.prank(bob); vm.expectRevert(ERC1155BaseInternal.ERC1155Base__NotOwnerOrApproved.selector); diff --git a/contracts/test/token/ERC1155/SafeBatchTransferFromSystemMock.sol b/contracts/test/token/ERC1155/SafeBatchTransferFromSystemMock.sol index 671aefe..1a4acee 100644 --- a/contracts/test/token/ERC1155/SafeBatchTransferFromSystemMock.sol +++ b/contracts/test/token/ERC1155/SafeBatchTransferFromSystemMock.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.17; import { IWorld } from "@latticexyz/solecs/src/interfaces/IWorld.sol"; import { SafeBatchTransferFromSystem } from "../../../token/ERC1155/systems/SafeBatchTransferFromSystem.sol"; -import { ID as ERC1155BaseSystemID } from "./ERC1155BaseSystemMock.sol"; +import { ID as ERC1155BaseSubsystemID } from "./ERC1155BaseSubsystemMock.sol"; uint256 constant ID = uint256(keccak256("test.system.SafeBatchTransferFrom")); @@ -13,7 +13,7 @@ contract SafeBatchTransferFromSystemMock is SafeBatchTransferFromSystem { constructor( IWorld _world, address _components - ) SafeBatchTransferFromSystem(_world, _components, ERC1155BaseSystemID) {} + ) SafeBatchTransferFromSystem(_world, _components, ERC1155BaseSubsystemID) {} // to test transfer from self function onERC1155Received( diff --git a/contracts/test/token/ERC721/BaseTest.sol b/contracts/test/token/ERC721/BaseTest.sol index 960e25e..1b792aa 100644 --- a/contracts/test/token/ERC721/BaseTest.sol +++ b/contracts/test/token/ERC721/BaseTest.sol @@ -7,7 +7,7 @@ import { PRBTest } from "@prb/test/src/PRBTest.sol"; // ECS import { World } from "@latticexyz/solecs/src/World.sol"; // systems -import { ERC721BaseSystemMock, ID as ERC721BaseSystemMockID } from "./ERC721BaseSystemMock.sol"; +import { ERC721BaseSubsystemMock, ID as ERC721BaseSubsystemMockID } from "./ERC721BaseSubsystemMock.sol"; // ERC721 events import { IERC721Internal } from "@solidstate/contracts/interfaces/IERC721Internal.sol"; @@ -26,8 +26,8 @@ contract BaseTest is address notWriter = address(bytes20(keccak256("notWriter"))); World world; - // ERC721 System - ERC721BaseSystemMock ercSystem; + // ERC721 Subsystem + ERC721BaseSubsystemMock ercSubsystem; uint256 tokenId = 1337; @@ -40,11 +40,10 @@ contract BaseTest is address components = address(world.components()); // deploy systems - ercSystem = new ERC721BaseSystemMock(world, components); - // register systems - world.registerSystem(address(ercSystem), ERC721BaseSystemMockID); - // allows calling ercSystem's execute - ercSystem.authorizeWriter(writer); + ercSubsystem = new ERC721BaseSubsystemMock(world, components); + world.registerSystem(address(ercSubsystem), ERC721BaseSubsystemMockID); + // authorize + ercSubsystem.authorizeWriter(writer); vm.stopPrank(); } @@ -53,6 +52,6 @@ contract BaseTest is function _defaultMintToAlice() internal { vm.prank(writer); - ercSystem.executeSafeMint(alice, tokenId, ''); + ercSubsystem.executeSafeMint(alice, tokenId, ''); } } \ No newline at end of file diff --git a/contracts/test/token/ERC721/ERC721BaseSystem.t.sol b/contracts/test/token/ERC721/ERC721BaseSubsystem.t.sol similarity index 59% rename from contracts/test/token/ERC721/ERC721BaseSystem.t.sol rename to contracts/test/token/ERC721/ERC721BaseSubsystem.t.sol index 96a0f9f..3a24982 100644 --- a/contracts/test/token/ERC721/ERC721BaseSystem.t.sol +++ b/contracts/test/token/ERC721/ERC721BaseSubsystem.t.sol @@ -6,16 +6,16 @@ import { BaseTest } from "./BaseTest.sol"; // errors import { IOwnableInternal } from "@solidstate/contracts/access/ownable/IOwnableInternal.sol"; -import { OwnableAndWriteAccess } from "../../../mud/OwnableAndWriteAccess.sol"; -import { ERC721BaseSystem } from "../../../token/ERC721/ERC721BaseSystem.sol"; +import { OwnableWritable } from "@latticexyz/solecs/src/OwnableWritable.sol"; +import { ERC721BaseSubsystem } from "../../../token/ERC721/ERC721BaseSubsystem.sol"; contract ERC721BaseSystemTest is BaseTest { // EXECUTE function testInvalidExecute() public { vm.prank(deployer); - vm.expectRevert(ERC721BaseSystem.ERC721BaseSystem__InvalidExecuteSelector.selector); - ercSystem.execute(abi.encode( + vm.expectRevert(ERC721BaseSubsystem.ERC721BaseSubsystem__InvalidExecuteSelector.selector); + ercSubsystem.execute(abi.encode( bytes4(keccak256("invalid selector")), bytes('data') )); @@ -25,33 +25,33 @@ contract ERC721BaseSystemTest is BaseTest { function testOwnerAuthorizeWriter() public { vm.prank(deployer); - ercSystem.authorizeWriter(alice); - assertTrue(ercSystem.writeAccess(alice)); + ercSubsystem.authorizeWriter(alice); + assertTrue(ercSubsystem.writeAccess(alice)); } function testNotOwnerAuthorizeWriter() public { vm.prank(alice); vm.expectRevert(IOwnableInternal.Ownable__NotOwner.selector); - ercSystem.authorizeWriter(alice); + ercSubsystem.authorizeWriter(alice); } // MINT function testMintDirectWriter() public { vm.prank(writer); - ercSystem.executeSafeMint(alice, tokenId, ''); - assertEq(ercSystem.ownerOf(tokenId), alice); + ercSubsystem.executeSafeMint(alice, tokenId, ''); + assertEq(ercSubsystem.ownerOf(tokenId), alice); } function testMintDirectNotWriter() public { vm.prank(notWriter); - vm.expectRevert(OwnableAndWriteAccess.OwnableAndWriteAccess__NotWriter.selector); - ercSystem.executeSafeMint(alice, tokenId, ''); + vm.expectRevert(OwnableWritable.OwnableWritable__NotWriter.selector); + ercSubsystem.executeSafeMint(alice, tokenId, ''); } function _mintExec(address receiver, uint256 _tokenId) internal { - ercSystem.execute(abi.encode( - ercSystem.executeSafeMint.selector, + ercSubsystem.execute(abi.encode( + ercSubsystem.executeSafeMint.selector, abi.encode(receiver, _tokenId, '') )); } @@ -59,19 +59,19 @@ contract ERC721BaseSystemTest is BaseTest { function testMintWriter() public { vm.prank(writer); _mintExec(alice, tokenId); - assertEq(ercSystem.ownerOf(tokenId), alice); + assertEq(ercSubsystem.ownerOf(tokenId), alice); } function testMintNotWriter() public { vm.prank(notWriter); - vm.expectRevert(OwnableAndWriteAccess.OwnableAndWriteAccess__NotWriter.selector); + vm.expectRevert(OwnableWritable.OwnableWritable__NotWriter.selector); _mintExec(alice, tokenId); } function testMintOwner() public { vm.prank(deployer); _mintExec(alice, tokenId); - assertEq(ercSystem.ownerOf(tokenId), alice); + assertEq(ercSubsystem.ownerOf(tokenId), alice); } // BURN @@ -80,21 +80,21 @@ contract ERC721BaseSystemTest is BaseTest { _defaultMintToAlice(); vm.prank(writer); - ercSystem.executeBurn(tokenId); - assertEq(ercSystem.balanceOf(alice), 0); + ercSubsystem.executeBurn(tokenId); + assertEq(ercSubsystem.balanceOf(alice), 0); } function testBurnDirectNotWriter() public { _defaultMintToAlice(); vm.prank(notWriter); - vm.expectRevert(OwnableAndWriteAccess.OwnableAndWriteAccess__NotWriter.selector); - ercSystem.executeBurn(tokenId); + vm.expectRevert(OwnableWritable.OwnableWritable__NotWriter.selector); + ercSubsystem.executeBurn(tokenId); } function _burnExec(uint256 _tokenId) internal { - ercSystem.execute(abi.encode( - ercSystem.executeBurn.selector, + ercSubsystem.execute(abi.encode( + ercSubsystem.executeBurn.selector, abi.encode(_tokenId) )); } @@ -104,14 +104,14 @@ contract ERC721BaseSystemTest is BaseTest { vm.prank(writer); _burnExec(tokenId); - assertEq(ercSystem.balanceOf(alice), 0); + assertEq(ercSubsystem.balanceOf(alice), 0); } function testBurnNotWriter() public { _defaultMintToAlice(); vm.prank(notWriter); - vm.expectRevert(OwnableAndWriteAccess.OwnableAndWriteAccess__NotWriter.selector); + vm.expectRevert(OwnableWritable.OwnableWritable__NotWriter.selector); _burnExec(tokenId); } @@ -120,7 +120,7 @@ contract ERC721BaseSystemTest is BaseTest { vm.prank(deployer); _burnExec(tokenId); - assertEq(ercSystem.balanceOf(alice), 0); + assertEq(ercSubsystem.balanceOf(alice), 0); } // TRANSFER @@ -129,16 +129,16 @@ contract ERC721BaseSystemTest is BaseTest { _defaultMintToAlice(); vm.prank(writer); - ercSystem.executeSafeTransfer(alice, alice, bob, tokenId, ''); - assertEq(ercSystem.ownerOf(tokenId), bob); + ercSubsystem.executeSafeTransfer(alice, alice, bob, tokenId, ''); + assertEq(ercSubsystem.ownerOf(tokenId), bob); } function testTransferDirectNotWriter() public { _defaultMintToAlice(); vm.prank(notWriter); - vm.expectRevert(OwnableAndWriteAccess.OwnableAndWriteAccess__NotWriter.selector); - ercSystem.executeSafeTransfer(alice, alice, bob, tokenId, ''); + vm.expectRevert(OwnableWritable.OwnableWritable__NotWriter.selector); + ercSubsystem.executeSafeTransfer(alice, alice, bob, tokenId, ''); } function _transferExec( @@ -148,8 +148,8 @@ contract ERC721BaseSystemTest is BaseTest { uint256 _tokenId, bytes memory data ) internal { - ercSystem.execute(abi.encode( - ercSystem.executeSafeTransfer.selector, + ercSubsystem.execute(abi.encode( + ercSubsystem.executeSafeTransfer.selector, abi.encode(operator, from, to, _tokenId, data) )); } @@ -159,14 +159,14 @@ contract ERC721BaseSystemTest is BaseTest { vm.prank(writer); _transferExec(alice, alice, bob, tokenId, ''); - assertEq(ercSystem.ownerOf(tokenId), bob); + assertEq(ercSubsystem.ownerOf(tokenId), bob); } function testTransferNotWriter() public { _defaultMintToAlice(); vm.prank(notWriter); - vm.expectRevert(OwnableAndWriteAccess.OwnableAndWriteAccess__NotWriter.selector); + vm.expectRevert(OwnableWritable.OwnableWritable__NotWriter.selector); _transferExec(alice, alice, bob, tokenId, ''); } @@ -175,6 +175,6 @@ contract ERC721BaseSystemTest is BaseTest { vm.prank(deployer); _transferExec(alice, alice, bob, tokenId, ''); - assertEq(ercSystem.ownerOf(tokenId), bob); + assertEq(ercSubsystem.ownerOf(tokenId), bob); } } \ No newline at end of file diff --git a/contracts/test/token/ERC721/ERC721BaseSystemMock.sol b/contracts/test/token/ERC721/ERC721BaseSubsystemMock.sol similarity index 73% rename from contracts/test/token/ERC721/ERC721BaseSystemMock.sol rename to contracts/test/token/ERC721/ERC721BaseSubsystemMock.sol index 2b96e23..d7613f6 100644 --- a/contracts/test/token/ERC721/ERC721BaseSystemMock.sol +++ b/contracts/test/token/ERC721/ERC721BaseSubsystemMock.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.17; import { IWorld } from "@latticexyz/solecs/src/interfaces/IWorld.sol"; -import { ERC721BaseSystem } from '../../../token/ERC721/ERC721BaseSystem.sol'; +import { ERC721BaseSubsystem } from '../../../token/ERC721/ERC721BaseSubsystem.sol'; uint256 constant ID = uint256(keccak256("mock.system.ERC721Base")); @@ -17,13 +17,13 @@ uint256 constant tokenApprovalComponentId = uint256(keccak256( abi.encode(ID, "mock.component.TokenApproval") )); -contract ERC721BaseSystemMock is ERC721BaseSystem { - error ERC721BaseSystemMock__InvalidCaller(); +contract ERC721BaseSubsystemMock is ERC721BaseSubsystem { + error ERC721BaseSubsystemMock__InvalidCaller(); constructor( IWorld _world, address _components - ) ERC721BaseSystem(_world, _components, ownershipComponentId, operatorApprovalComponentId, tokenApprovalComponentId) {} + ) ERC721BaseSubsystem(_world, _components, ownershipComponentId, operatorApprovalComponentId, tokenApprovalComponentId) {} // this is for hardhat tests function mint( diff --git a/contracts/test/token/ERC721/OperatorApprovalSystem.t.sol b/contracts/test/token/ERC721/OperatorApprovalSystem.t.sol index 40f558b..6e365d2 100644 --- a/contracts/test/token/ERC721/OperatorApprovalSystem.t.sol +++ b/contracts/test/token/ERC721/OperatorApprovalSystem.t.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.17; import { BaseTest } from "./BaseTest.sol"; // systems -import { ID as ERC721BaseSystemID } from "./ERC721BaseSystemMock.sol"; +import { ID as ERC721BaseSubsystemID } from "./ERC721BaseSubsystemMock.sol"; import { OperatorApprovalSystem } from "../../../token/ERC721/systems/OperatorApprovalSystem.sol"; contract OperatorApprovalSystemTest is BaseTest { @@ -18,11 +18,11 @@ contract OperatorApprovalSystemTest is BaseTest { address components = address(world.components()); // deploy systems - oaSystem = new OperatorApprovalSystem(world, components, ERC721BaseSystemID); + oaSystem = new OperatorApprovalSystem(world, components, ERC721BaseSubsystemID); // register systems world.registerSystem(address(oaSystem), uint256(keccak256("oaSystem"))); - // allows calling ercSystem's execute - ercSystem.authorizeWriter(address(oaSystem)); + // allows calling ercSubsystem's execute + ercSubsystem.authorizeWriter(address(oaSystem)); vm.stopPrank(); } @@ -38,7 +38,7 @@ contract OperatorApprovalSystemTest is BaseTest { _expectEmitApprovalForAll(alice); oaSystem.executeTyped(bob, true); - assertTrue(ercSystem.isApprovedForAll(alice, bob)); + assertTrue(ercSubsystem.isApprovedForAll(alice, bob)); } function testExecuteOnSystem() public { @@ -46,6 +46,6 @@ contract OperatorApprovalSystemTest is BaseTest { _expectEmitApprovalForAll(alice); oaSystem.executeTyped(address(oaSystem), true); - assertTrue(ercSystem.isApprovedForAll(alice, address(oaSystem))); + assertTrue(ercSubsystem.isApprovedForAll(alice, address(oaSystem))); } } \ No newline at end of file diff --git a/contracts/test/token/ERC721/SafeTransferSystem.t.sol b/contracts/test/token/ERC721/SafeTransferSystem.t.sol index 89f1eee..ebf2234 100644 --- a/contracts/test/token/ERC721/SafeTransferSystem.t.sol +++ b/contracts/test/token/ERC721/SafeTransferSystem.t.sol @@ -10,7 +10,7 @@ import { SafeTransferSystemMock, ID as SafeTransferSystemMockID } from "./SafeTr // errors import { ERC721BaseInternal } from "../../../token/ERC721/logic/ERC721BaseInternal.sol"; -contract ERC721BaseSystemTest is BaseTest { +contract SafeTransferSystemTest is BaseTest { SafeTransferSystemMock transferSystem; function setUp() public virtual override { @@ -23,8 +23,8 @@ contract ERC721BaseSystemTest is BaseTest { transferSystem = new SafeTransferSystemMock(world, components); // register systems world.registerSystem(address(transferSystem), SafeTransferSystemMockID); - // allows calling ercSystem's execute - ercSystem.authorizeWriter(address(transferSystem)); + // allows calling ercSubsystem's execute + ercSubsystem.authorizeWriter(address(transferSystem)); vm.stopPrank(); } @@ -37,7 +37,7 @@ contract ERC721BaseSystemTest is BaseTest { vm.prank(alice); transferSystem.executeTyped(alice, bob, tokenId, ''); - assertEq(ercSystem.ownerOf(tokenId), bob); + assertEq(ercSubsystem.ownerOf(tokenId), bob); } function testExecuteNotOwner() public { @@ -50,7 +50,7 @@ contract ERC721BaseSystemTest is BaseTest { function testExecuteNotOwnerFromForwarder() public { vm.prank(writer); - ercSystem.executeSafeMint(address(transferSystem), tokenId, ''); + ercSubsystem.executeSafeMint(address(transferSystem), tokenId, ''); vm.prank(bob); vm.expectRevert(ERC721BaseInternal.ERC721Base__NotOwnerOrApproved.selector); diff --git a/contracts/test/token/ERC721/SafeTransferSystemMock.sol b/contracts/test/token/ERC721/SafeTransferSystemMock.sol index c3e6bd7..3882536 100644 --- a/contracts/test/token/ERC721/SafeTransferSystemMock.sol +++ b/contracts/test/token/ERC721/SafeTransferSystemMock.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.17; import { IWorld } from "@latticexyz/solecs/src/interfaces/IWorld.sol"; import { SafeTransferSystem } from "../../../token/ERC721/systems/SafeTransferSystem.sol"; -import { ID as ERC721BaseSystemID } from "./ERC721BaseSystemMock.sol"; +import { ID as ERC721BaseSubsystemID } from "./ERC721BaseSubsystemMock.sol"; uint256 constant ID = uint256(keccak256("test.system.SafeTransfer")); @@ -13,7 +13,7 @@ contract SafeTransferSystemMock is SafeTransferSystem { constructor( IWorld _world, address _components - ) SafeTransferSystem(_world, _components, ERC721BaseSystemID) {} + ) SafeTransferSystem(_world, _components, ERC721BaseSubsystemID) {} // to test transfer from self function onERC721Received( diff --git a/contracts/test/token/ERC721/TokenApprovalSystem.t.sol b/contracts/test/token/ERC721/TokenApprovalSystem.t.sol index 8b91232..ac7a188 100644 --- a/contracts/test/token/ERC721/TokenApprovalSystem.t.sol +++ b/contracts/test/token/ERC721/TokenApprovalSystem.t.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.17; import { BaseTest } from "./BaseTest.sol"; // systems -import { ID as ERC721BaseSystemID } from "./ERC721BaseSystemMock.sol"; +import { ID as ERC721BaseSubsystemID } from "./ERC721BaseSubsystemMock.sol"; import { TokenApprovalSystem } from "../../../token/ERC721/systems/TokenApprovalSystem.sol"; contract TokenApprovalSystemTest is BaseTest { @@ -18,11 +18,10 @@ contract TokenApprovalSystemTest is BaseTest { address components = address(world.components()); // deploy systems - taSystem = new TokenApprovalSystem(world, components, ERC721BaseSystemID); - // register systems + taSystem = new TokenApprovalSystem(world, components, ERC721BaseSubsystemID); world.registerSystem(address(taSystem), uint256(keccak256("taSystem"))); - // allows calling ercSystem's execute - ercSystem.authorizeWriter(address(taSystem)); + // authorize + ercSubsystem.authorizeWriter(address(taSystem)); vm.stopPrank(); } @@ -40,7 +39,7 @@ contract TokenApprovalSystemTest is BaseTest { _expectEmitApproval(alice); taSystem.executeTyped(bob, tokenId); - assertEq(ercSystem.getApproved(tokenId), bob); + assertEq(ercSubsystem.getApproved(tokenId), bob); } function testExecuteOnSystem() public { @@ -50,6 +49,6 @@ contract TokenApprovalSystemTest is BaseTest { _expectEmitApproval(alice); taSystem.executeTyped(address(taSystem), tokenId); - assertEq(ercSystem.getApproved(tokenId), address(taSystem)); + assertEq(ercSubsystem.getApproved(tokenId), address(taSystem)); } } \ No newline at end of file diff --git a/contracts/token/ERC1155/ERC1155BaseSystem.sol b/contracts/token/ERC1155/ERC1155BaseSubsystem.sol similarity index 87% rename from contracts/token/ERC1155/ERC1155BaseSystem.sol rename to contracts/token/ERC1155/ERC1155BaseSubsystem.sol index dd8dcdd..f913edd 100644 --- a/contracts/token/ERC1155/ERC1155BaseSystem.sol +++ b/contracts/token/ERC1155/ERC1155BaseSubsystem.sol @@ -10,30 +10,39 @@ import { ISystem } from "@latticexyz/solecs/src/interfaces/ISystem.sol"; // ECS import { IWorld } from "@latticexyz/solecs/src/interfaces/IWorld.sol"; -//import { System } from "@latticexyz/solecs/src/System.sol"; -import { SystemFacet } from "../../mud/SystemFacet.sol"; +import { Subsystem } from "@latticexyz/solecs/src/Subsystem.sol"; // ERC1155 logic and data provider import { ERC1155BaseLogic } from "./logic/ERC1155BaseLogic.sol"; import { ERC1155BaseDataComponents } from "./data-providers/ERC1155BaseDataComponents.sol"; /** - * @title ERC1155 and ECS System that uses components. + * @title ERC1155 and ECS Subsystem that uses components. * @dev ALL component changes MUST go through this system. - * Call `authorizeWriter` to let another system write to this. + * + * `deploy.json` example: + * ``` + * { + * "components": ["ExampleComponent"], + * "systems": [ + * { "name": "ERC1155BaseSubsystem", "writeAccess": [] } + * { "name": "ExampleSystem", "writeAccess": ["ERC1155BaseSubsystem"] }, + * ] + * } + * ``` + * (ERC1155BaseSubsystem deploys its components itself, you only need to deploy the subsystem) * * TODO metadata, enumerable? - * TODO atm not using solecs's System in favour of custom owner+writeAccess */ -contract ERC1155BaseSystem is +contract ERC1155BaseSubsystem is ERC165, ERC1155BaseDataComponents, ERC1155BaseLogic, - SystemFacet + Subsystem { using ERC165Storage for ERC165Storage.Layout; - error ERC1155BaseSystem__InvalidExecuteSelector(); + error ERC1155BaseSubsystem__InvalidExecuteSelector(); // TODO diamond-compatible version? constructor( @@ -41,10 +50,7 @@ contract ERC1155BaseSystem is address _components, uint256 balanceComponentId, uint256 operatorApprovalComponentId - ) { - // initialize base system - __SystemFacet_init(_world, _components); - + ) Subsystem(_world, _components) { // create components // (they're tightly coupled to this system, so making them separately isn't useful) __ERC1155BaseDataComponents_init(_world, balanceComponentId, operatorApprovalComponentId); @@ -62,7 +68,7 @@ contract ERC1155BaseSystem is /** * @notice Internally calls the specified execute method, if it's available */ - function execute(bytes memory args) public virtual returns (bytes memory) { + function _execute(bytes memory args) internal virtual override returns (bytes memory) { (bytes4 executeSelector, bytes memory innerArgs) = abi.decode(args, (bytes4, bytes)); @@ -118,7 +124,7 @@ contract ERC1155BaseSystem is executeSetApprovalForAll(account, operator, status); } else { - revert ERC1155BaseSystem__InvalidExecuteSelector(); + revert ERC1155BaseSubsystem__InvalidExecuteSelector(); } return ''; diff --git a/contracts/token/ERC1155/systems/OperatorApprovalSystem.sol b/contracts/token/ERC1155/systems/OperatorApprovalSystem.sol index 27e99d0..9c3cc4d 100644 --- a/contracts/token/ERC1155/systems/OperatorApprovalSystem.sol +++ b/contracts/token/ERC1155/systems/OperatorApprovalSystem.sol @@ -6,20 +6,20 @@ import { IWorld } from "@latticexyz/solecs/src/interfaces/IWorld.sol"; import { System, ISystem } from "@latticexyz/solecs/src/System.sol"; import { getAddressById } from "@latticexyz/solecs/src/utils.sol"; -import { ERC1155BaseSystem } from "../ERC1155BaseSystem.sol"; +import { ERC1155BaseSubsystem } from "../ERC1155BaseSubsystem.sol"; /** * @title Optional forwarder system that wraps executeSetApprovalForAll into its execute */ contract OperatorApprovalSystem is System { - uint256 immutable erc1155BaseSystemId; + uint256 immutable erc1155BaseSubsystemId; constructor( IWorld _world, address _components, - uint256 _erc1155BaseSystemId + uint256 _erc1155BaseSubsystemId ) System(_world, _components) { - erc1155BaseSystemId = _erc1155BaseSystemId; + erc1155BaseSubsystemId = _erc1155BaseSubsystemId; } function executeTyped( @@ -35,8 +35,8 @@ contract OperatorApprovalSystem is System { bool status ) = abi.decode(arguments, (address, bool)); - ERC1155BaseSystem( - getAddressById(world.systems(), erc1155BaseSystemId) + ERC1155BaseSubsystem( + getAddressById(world.systems(), erc1155BaseSubsystemId) ).executeSetApprovalForAll( msg.sender, operator, diff --git a/contracts/token/ERC1155/systems/SafeBatchTransferFromSystem.sol b/contracts/token/ERC1155/systems/SafeBatchTransferFromSystem.sol index 92183bf..2b6347a 100644 --- a/contracts/token/ERC1155/systems/SafeBatchTransferFromSystem.sol +++ b/contracts/token/ERC1155/systems/SafeBatchTransferFromSystem.sol @@ -6,20 +6,20 @@ import { IWorld } from "@latticexyz/solecs/src/interfaces/IWorld.sol"; import { System, ISystem } from "@latticexyz/solecs/src/System.sol"; import { getAddressById } from "@latticexyz/solecs/src/utils.sol"; -import { ERC1155BaseSystem } from "../ERC1155BaseSystem.sol"; +import { ERC1155BaseSubsystem } from "../ERC1155BaseSubsystem.sol"; /** * @title Optional forwarder system that wraps executeSafeTransferBatch into its execute */ contract SafeBatchTransferFromSystem is System { - uint256 immutable erc1155BaseSystemId; + uint256 immutable erc1155BaseSubsystemId; constructor( IWorld _world, address _components, - uint256 _erc1155BaseSystemId + uint256 _erc1155BaseSubsystemId ) System(_world, _components) { - erc1155BaseSystemId = _erc1155BaseSystemId; + erc1155BaseSubsystemId = _erc1155BaseSubsystemId; } function executeTyped( @@ -41,8 +41,8 @@ contract SafeBatchTransferFromSystem is System { bytes memory data ) = abi.decode(arguments, (address, address, uint256[], uint256[], bytes)); - ERC1155BaseSystem( - getAddressById(world.systems(), erc1155BaseSystemId) + ERC1155BaseSubsystem( + getAddressById(world.systems(), erc1155BaseSubsystemId) ).executeSafeTransferBatch( msg.sender, from, diff --git a/contracts/token/ERC721/ERC721BaseSystem.sol b/contracts/token/ERC721/ERC721BaseSubsystem.sol similarity index 87% rename from contracts/token/ERC721/ERC721BaseSystem.sol rename to contracts/token/ERC721/ERC721BaseSubsystem.sol index 5c591a5..aedbd20 100644 --- a/contracts/token/ERC721/ERC721BaseSystem.sol +++ b/contracts/token/ERC721/ERC721BaseSubsystem.sol @@ -10,42 +10,47 @@ import { ISystem } from "@latticexyz/solecs/src/interfaces/ISystem.sol"; // ECS import { IWorld } from "@latticexyz/solecs/src/interfaces/IWorld.sol"; -//import { System } from "@latticexyz/solecs/src/System.sol"; -import { SystemFacet } from "../../mud/SystemFacet.sol"; +import { Subsystem } from "@latticexyz/solecs/src/Subsystem.sol"; // ERC721 logic and data provider import { ERC721BaseLogic } from "./logic/ERC721BaseLogic.sol"; import { ERC721BaseDataComponents } from "./data-providers/ERC721BaseDataComponents.sol"; /** - * @title ERC721 and ECS System that uses components. + * @title ERC721 and ECS Subsystem that uses components. * @dev ALL component changes MUST go through this system. - * Call `authorizeWriter` to let another system write to this. - * + * + * `deploy.json` example: + * ``` + * { + * "components": ["ExampleComponent"], + * "systems": [ + * { "name": "ERC721BaseSubsystem", "writeAccess": [] } + * { "name": "ExampleSystem", "writeAccess": ["ERC721BaseSubsystem"] }, + * ] + * } + * ``` + * (ERC721BaseSubsystem deploys its components itself, you only need to deploy the subsystem) + * * TODO metadata, enumerable? - * TODO atm not using solecs's System in favour of custom owner+writeAccess */ -contract ERC721BaseSystem is +contract ERC721BaseSubsystem is ERC165, ERC721BaseDataComponents, ERC721BaseLogic, - SystemFacet + Subsystem { using ERC165Storage for ERC165Storage.Layout; - error ERC721BaseSystem__InvalidExecuteSelector(); + error ERC721BaseSubsystem__InvalidExecuteSelector(); - // TODO diamond-compatible version? constructor( IWorld _world, address _components, uint256 ownershipComponentId, uint256 operatorApprovalComponentId, uint256 tokenApprovalComponentId - ) { - // initialize base system - __SystemFacet_init(_world, _components); - + ) Subsystem(_world, _components) { // create components // (they're tightly coupled to this system, so making them separately isn't useful) __ERC721BaseDataComponents_init(_world, ownershipComponentId, operatorApprovalComponentId, tokenApprovalComponentId); @@ -63,7 +68,7 @@ contract ERC721BaseSystem is /** * @notice Internally calls the specified execute method, if it's available */ - function execute(bytes memory args) public virtual returns (bytes memory) { + function _execute(bytes memory args) internal virtual override returns (bytes memory) { (bytes4 executeSelector, bytes memory innerArgs) = abi.decode(args, (bytes4, bytes)); @@ -122,7 +127,7 @@ contract ERC721BaseSystem is executeApprove(account, operator, tokenId); } else { - revert ERC721BaseSystem__InvalidExecuteSelector(); + revert ERC721BaseSubsystem__InvalidExecuteSelector(); } return ''; diff --git a/contracts/token/ERC721/systems/OperatorApprovalSystem.sol b/contracts/token/ERC721/systems/OperatorApprovalSystem.sol index 7e46290..1fef955 100644 --- a/contracts/token/ERC721/systems/OperatorApprovalSystem.sol +++ b/contracts/token/ERC721/systems/OperatorApprovalSystem.sol @@ -6,20 +6,20 @@ import { IWorld } from "@latticexyz/solecs/src/interfaces/IWorld.sol"; import { System, ISystem } from "@latticexyz/solecs/src/System.sol"; import { getAddressById } from "@latticexyz/solecs/src/utils.sol"; -import { ERC721BaseSystem } from "../ERC721BaseSystem.sol"; +import { ERC721BaseSubsystem } from "../ERC721BaseSubsystem.sol"; /** * @title Optional forwarder system that wraps executeSetApprovalForAll into its execute */ contract OperatorApprovalSystem is System { - uint256 immutable erc721BaseSystemId; + uint256 immutable erc721BaseSubsystemId; constructor( IWorld _world, address _components, - uint256 _erc721BaseSystemId + uint256 _erc721BaseSubsystemId ) System(_world, _components) { - erc721BaseSystemId = _erc721BaseSystemId; + erc721BaseSubsystemId = _erc721BaseSubsystemId; } function executeTyped( @@ -35,8 +35,8 @@ contract OperatorApprovalSystem is System { bool status ) = abi.decode(arguments, (address, bool)); - ERC721BaseSystem( - getAddressById(world.systems(), erc721BaseSystemId) + ERC721BaseSubsystem( + getAddressById(world.systems(), erc721BaseSubsystemId) ).executeSetApprovalForAll( msg.sender, operator, diff --git a/contracts/token/ERC721/systems/SafeTransferSystem.sol b/contracts/token/ERC721/systems/SafeTransferSystem.sol index 83f3c86..c5f42d6 100644 --- a/contracts/token/ERC721/systems/SafeTransferSystem.sol +++ b/contracts/token/ERC721/systems/SafeTransferSystem.sol @@ -6,20 +6,20 @@ import { IWorld } from "@latticexyz/solecs/src/interfaces/IWorld.sol"; import { System } from "@latticexyz/solecs/src/System.sol"; import { getAddressById } from "@latticexyz/solecs/src/utils.sol"; -import { ERC721BaseSystem } from "../ERC721BaseSystem.sol"; +import { ERC721BaseSubsystem } from "../ERC721BaseSubsystem.sol"; /** * @title Optional forwarder system that wraps executeSafeTransfer into its execute */ contract SafeTransferSystem is System { - uint256 immutable erc721BaseSystemId; + uint256 immutable erc721BaseSubsystemId; constructor( IWorld _world, address _components, - uint256 _erc721BaseSystemId + uint256 _erc721BaseSubsystemId ) System(_world, _components) { - erc721BaseSystemId = _erc721BaseSystemId; + erc721BaseSubsystemId = _erc721BaseSubsystemId; } function executeTyped( @@ -39,8 +39,8 @@ contract SafeTransferSystem is System { bytes memory data ) = abi.decode(arguments, (address, address, uint256, bytes)); - ERC721BaseSystem( - getAddressById(world.systems(), erc721BaseSystemId) + ERC721BaseSubsystem( + getAddressById(world.systems(), erc721BaseSubsystemId) ).executeSafeTransfer( msg.sender, from, diff --git a/contracts/token/ERC721/systems/TokenApprovalSystem.sol b/contracts/token/ERC721/systems/TokenApprovalSystem.sol index 24b4c5d..639aba0 100644 --- a/contracts/token/ERC721/systems/TokenApprovalSystem.sol +++ b/contracts/token/ERC721/systems/TokenApprovalSystem.sol @@ -6,20 +6,20 @@ import { IWorld } from "@latticexyz/solecs/src/interfaces/IWorld.sol"; import { System, ISystem } from "@latticexyz/solecs/src/System.sol"; import { getAddressById } from "@latticexyz/solecs/src/utils.sol"; -import { ERC721BaseSystem } from "../ERC721BaseSystem.sol"; +import { ERC721BaseSubsystem } from "../ERC721BaseSubsystem.sol"; /** * @title Optional forwarder system that wraps executeApprove into its execute */ contract TokenApprovalSystem is System { - uint256 immutable erc721BaseSystemId; + uint256 immutable erc721BaseSubsystemId; constructor( IWorld _world, address _components, - uint256 _erc721BaseSystemId + uint256 _erc721BaseSubsystemId ) System(_world, _components) { - erc721BaseSystemId = _erc721BaseSystemId; + erc721BaseSubsystemId = _erc721BaseSubsystemId; } function executeTyped( @@ -35,8 +35,8 @@ contract TokenApprovalSystem is System { uint256 tokenId ) = abi.decode(arguments, (address, uint256)); - ERC721BaseSystem( - getAddressById(world.systems(), erc721BaseSystemId) + ERC721BaseSubsystem( + getAddressById(world.systems(), erc721BaseSubsystemId) ).executeApprove( msg.sender, operator, diff --git a/package.json b/package.json index bb903e6..3eb6260 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.3.2", "author": "dk1a ", "license": "MIT", - "description": "ERC1155 and ERC721 Systems that use components to store data", + "description": "ERC1155 and ERC721 Subsystems that use components to store data", "repository": { "type": "git", "url": "https://github.com/dk1a/solecslib.git" @@ -21,8 +21,8 @@ "/contracts/**/*.sol" ], "dependencies": { - "@latticexyz/solecs": "^1.28.0", - "@latticexyz/std-contracts": "^1.28.0", + "@latticexyz/solecs": "https://gitpkg.now.sh/dk1a/mud/packages/solecs?7cfb9d454b1b612daa9dc1ad49262a0cfbc6770a", + "@latticexyz/std-contracts": "https://gitpkg.now.sh/dk1a/mud/packages/std-contracts?7cfb9d454b1b612daa9dc1ad49262a0cfbc6770a", "@openzeppelin/contracts": "^4.8.0", "@solidstate/contracts": "^0.0.48", "memmove": "github:dk1a/memmove#ffd71cd77b1708574ef46a667b23ca3a5cc9fa27" diff --git a/test/ERC1155BaseSystem.js b/test/ERC1155BaseSubsystem.js similarity index 92% rename from test/ERC1155BaseSystem.js rename to test/ERC1155BaseSubsystem.js index 1cdbc2a..2e95d6d 100644 --- a/test/ERC1155BaseSystem.js +++ b/test/ERC1155BaseSubsystem.js @@ -1,7 +1,7 @@ const ethers = require('hardhat').ethers const describeBehaviorOfERC1155Base = require("@solidstate/spec").describeBehaviorOfERC1155Base -describe('ERC1155BaseSystem', function () { +describe('ERC1155BaseSubsystem', function () { let instance beforeEach(async function () { @@ -10,7 +10,7 @@ describe('ERC1155BaseSystem', function () { await worldInstance.deployed() await worldInstance.init() - const factory = await ethers.getContractFactory('ERC1155BaseSystemMock') + const factory = await ethers.getContractFactory('ERC1155BaseSubsystemMock') instance = await factory.deploy(worldInstance.address, await worldInstance.components()) await instance.deployed() }); diff --git a/test/ERC721BaseSystem.js b/test/ERC721BaseSubsystem.js similarity index 89% rename from test/ERC721BaseSystem.js rename to test/ERC721BaseSubsystem.js index b483cb7..564a3a8 100644 --- a/test/ERC721BaseSystem.js +++ b/test/ERC721BaseSubsystem.js @@ -1,8 +1,8 @@ const ethers = require('hardhat').ethers -const describeBehaviorOfERC1155Base = require("@solidstate/spec").describeBehaviorOfERC721Base +const describeBehaviorOfERC721Base = require("@solidstate/spec").describeBehaviorOfERC721Base const expect = require('chai').expect -describe('ERC721BaseSystem', function () { +describe('ERC721BaseSubsystem', function () { let instance beforeEach(async function () { @@ -11,12 +11,12 @@ describe('ERC721BaseSystem', function () { await worldInstance.deployed() await worldInstance.init() - const factory = await ethers.getContractFactory('ERC721BaseSystemMock') + const factory = await ethers.getContractFactory('ERC721BaseSubsystemMock') instance = await factory.deploy(worldInstance.address, await worldInstance.components()) await instance.deployed() }); - describeBehaviorOfERC1155Base( + describeBehaviorOfERC721Base( () => instance, { mint(address, tokenId) { diff --git a/yarn.lock b/yarn.lock index 8ba6ff7..9f9d07f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -559,16 +559,19 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@latticexyz/solecs@^1.28.0": +"@latticexyz/solecs@https://gitpkg.now.sh/dk1a/mud/packages/solecs?7cfb9d454b1b612daa9dc1ad49262a0cfbc6770a": version "1.31.3" - resolved "https://registry.yarnpkg.com/@latticexyz/solecs/-/solecs-1.31.3.tgz#7c3bcad61fd7e3b857d51a3fac73955c631fc25b" - integrity sha512-MPu+DdNfsCECIY+foBs9D4f1KRSyey2xcJXUdEnaFeAD+BuSVFeP4gOfllGvv8uFq9Zl8S5wC4YDGiSicnif/g== + resolved "https://gitpkg.now.sh/dk1a/mud/packages/solecs?7cfb9d454b1b612daa9dc1ad49262a0cfbc6770a#27ba271a938cb4e5d1630ae9376c763c13035be3" "@latticexyz/std-contracts@^1.28.0": version "1.31.3" resolved "https://registry.yarnpkg.com/@latticexyz/std-contracts/-/std-contracts-1.31.3.tgz#9feac98bf4c86ccd01cfb4401435d2c0fd9706d9" integrity sha512-bHIqFpVg6BdIcQ2bVC6MRdByVMdBTU2NpvtqWl3X9RDk7Yd1pfLzRsrRS2XTuSCuwb4enFQU+usQK1MP0WNPmQ== +"@latticexyz/std-contracts@https://gitpkg.now.sh/dk1a/mud/packages/std-contracts?7cfb9d454b1b612daa9dc1ad49262a0cfbc6770a": + version "1.31.3" + resolved "https://gitpkg.now.sh/dk1a/mud/packages/std-contracts?7cfb9d454b1b612daa9dc1ad49262a0cfbc6770a#51d7c92346eff54d04a15ba926cea27b0c7b5da0" + "@metamask/eth-sig-util@^4.0.0": version "4.0.1" resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088"