From e867c35c52da828d20242e98fefefb638241ae0e Mon Sep 17 00:00:00 2001 From: seinmyung25 Date: Mon, 8 Apr 2024 18:03:52 +0900 Subject: [PATCH 1/4] feat: eco erc1155 init --- .../ERC1155/{EcoERC1155.sol => EcoERC1155Upgradeable.sol} | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) rename contracts/token/ERC1155/{EcoERC1155.sol => EcoERC1155Upgradeable.sol} (82%) diff --git a/contracts/token/ERC1155/EcoERC1155.sol b/contracts/token/ERC1155/EcoERC1155Upgradeable.sol similarity index 82% rename from contracts/token/ERC1155/EcoERC1155.sol rename to contracts/token/ERC1155/EcoERC1155Upgradeable.sol index 014cb66..8e95497 100644 --- a/contracts/token/ERC1155/EcoERC1155.sol +++ b/contracts/token/ERC1155/EcoERC1155Upgradeable.sol @@ -10,7 +10,12 @@ import { ERC1155URIStorageUpgradeable } from "@openzeppelin/contracts-upgradeabl import { ERC1155Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; -contract EcoERC1155 is ERC1155MintableUpgradeable, EcoERC1155URIControl { +contract EcoERC1155Upgradeable is ERC1155MintableUpgradeable, EcoERC1155URIControl { + function initEcoERC1155(address initialOwner, string memory baseURI) public initializer { + _initEcoOwnable(initialOwner); + __ERC1155_init(baseURI); + } + function supportsInterface( bytes4 interfaceId ) public view override(ERC1155MintableUpgradeable, EcoERC1155URIControl) returns (bool) { From 723340e9d38bb7dca75cf1f840bc4fb1096b376a Mon Sep 17 00:00:00 2001 From: seinmyung25 Date: Mon, 8 Apr 2024 18:14:25 +0900 Subject: [PATCH 2/4] test: erc1155 --- test/token/ERC1155.ts | 85 +++++++++++++++++++++++++++++++++++++++++++ test/token/ERC20.ts | 2 +- 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 test/token/ERC1155.ts diff --git a/test/token/ERC1155.ts b/test/token/ERC1155.ts new file mode 100644 index 0000000..e24dc12 --- /dev/null +++ b/test/token/ERC1155.ts @@ -0,0 +1,85 @@ +import { loadFixture } from "@nomicfoundation/hardhat-toolbox/network-helpers"; +import { expect } from "chai"; +import hre from "hardhat"; + +import { getSelector } from "../helper"; + +describe("ERC1155 Mintable", function () { + const baseURI = "https://this.is.base.uri/"; + const amount = hre.ethers.parseEther("100"); + + const default1155Id = 0; + + async function NFT_Mintable_Fixture() { + const [owner, ...users] = await hre.ethers.getSigners(); + + const ERC1155 = await hre.ethers.getContractFactory("EcoERC1155Upgradeable"); + const erc1155 = await ERC1155.deploy(); + await erc1155.initEcoERC1155(owner, baseURI); + + return { erc1155, owner, users }; + } + + describe("Deployment", function () { + it("Should set the right owner", async function () { + const { erc1155, owner } = await loadFixture(NFT_Mintable_Fixture); + + expect(await erc1155.owner()).to.equal(owner.address); + await expect(erc1155.initEcoERC1155(owner, baseURI)).reverted; + }); + + it("Should set the right metadata", async function () { + const { erc1155 } = await loadFixture(NFT_Mintable_Fixture); + + expect(await erc1155.uri(0)).to.equal(baseURI); + }); + }); + + describe("ERC1155 Feature", function () { + describe("Mint", function () { + it("Should revert with the right error if mint called from another account", async function () { + const { erc1155, users } = await loadFixture(NFT_Mintable_Fixture); + const user_connected_nft = erc1155.connect(users[0]); + await expect(user_connected_nft.mint(users[0], default1155Id, amount, "0x")).reverted; + }); + + it("Shouldn't fail mint with the right owner", async function () { + const { erc1155, users } = await loadFixture(NFT_Mintable_Fixture); + await expect(erc1155.mint(users[0], default1155Id, amount, "0x")).not.reverted; + }); + + it("Shouldn't fail mint with the right role access account", async function () { + const { erc1155, users } = await loadFixture(NFT_Mintable_Fixture); + + await expect(erc1155.grantSelectorRole(getSelector(erc1155.mint), users[0])).not.reverted; + + const user_connected_nft = erc1155.connect(users[0]); + await expect(user_connected_nft.mint(users[0], default1155Id, amount, "0x")).not.reverted; + + await expect(erc1155.revokeSelectorRole(getSelector(erc1155.mint), users[0])).not.reverted; + await expect(user_connected_nft.mint(users[0], default1155Id, amount, "0x")).reverted; + }); + }); + + describe("Transfer", function () { + it("Should revert with the right error if mint called from another account", async function () { + const { owner, erc1155, users } = await loadFixture(NFT_Mintable_Fixture); + await expect(erc1155.mint(users[0], default1155Id, amount, "0x")).not.reverted; + await expect(erc1155.connect(users[0]).burn(users[0], default1155Id, amount)).not.reverted; + expect(await erc1155.balanceOf(users[0], default1155Id)).equal(0); + + await expect(erc1155.mint(users[0], default1155Id, amount, "0x")).not.reverted; + await expect(erc1155.mint(users[0], default1155Id, amount, "0x")).not.reverted; + + await erc1155.connect(users[0]).setApprovalForAll(owner, true); + await expect(erc1155.safeTransferFrom(users[0], users[1], default1155Id, await erc1155.balanceOf(users[0], default1155Id), "0x")).not.reverted; + await expect(erc1155.safeTransferFrom(users[0], users[1], default1155Id, amount, "0x")).reverted; + console.log(await erc1155.balanceOf(users[1], default1155Id)); + await expect(erc1155.connect(users[1]).safeTransferFrom(users[1], users[0], default1155Id, await erc1155.balanceOf(users[1], default1155Id)/2n, "0x")) + .not.reverted; // this allowed, openzeppelin transfer imple differ from erc20 + await erc1155.connect(users[1]).setApprovalForAll(owner, true); + await expect(erc1155.burn(users[1], default1155Id, await erc1155.balanceOf(users[1], default1155Id))).not.reverted; + }); + }); + }); +}); diff --git a/test/token/ERC20.ts b/test/token/ERC20.ts index 7cd9b11..73af5b9 100644 --- a/test/token/ERC20.ts +++ b/test/token/ERC20.ts @@ -78,7 +78,7 @@ describe("ERC20 Mintable", function () { await expect(erc20.transferFrom(users[0], users[1], await erc20.balanceOf(users[0]))).not.reverted; await expect(erc20.transferFrom(users[0], users[1], amount)).reverted; await expect(erc20.connect(users[1]).transferFrom(users[1], users[0], await erc20.balanceOf(users[1]))) - .reverted; + .reverted; // should use transfer, owner == spender not allowed await erc20.connect(users[1]).approve(owner, hre.ethers.MaxUint256); await expect(erc20.burnFrom(users[1], await erc20.balanceOf(users[1]))).not.reverted; }); From 119c24e2bed439e720bfef192fed36f58dfd498d Mon Sep 17 00:00:00 2001 From: seinmyung25 Date: Tue, 9 Apr 2024 12:53:36 +0900 Subject: [PATCH 3/4] feat: erc1155 supply view --- .../ERC1155/ERC1155MintableUpgradeable.sol | 21 +----------------- .../token/ERC1155/EcoERC1155Upgradeable.sol | 22 ++++++++++++++----- contracts/token/ERC1155/IERC1155.sol | 10 ++++++++- test/token/ERC1155.ts | 2 +- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/contracts/token/ERC1155/ERC1155MintableUpgradeable.sol b/contracts/token/ERC1155/ERC1155MintableUpgradeable.sol index 0dca36b..255d0bb 100644 --- a/contracts/token/ERC1155/ERC1155MintableUpgradeable.sol +++ b/contracts/token/ERC1155/ERC1155MintableUpgradeable.sol @@ -4,37 +4,18 @@ pragma solidity ^0.8.0; // import { ISelectorRoleControl, IPausable, IEcoOwnable, import { AccessControlEnumerableUpgradeable, SelectorRoleControlUpgradeable } from "../../access/SelectorRoleControlUpgradeable.sol"; - import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { ERC1155Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; -import { ERC1155BurnableUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol"; -import { ERC1155PausableUpgradeable } from "./ERC1155PausableUpgradeable.sol"; - import { IERC1155Mintable } from "./IERC1155.sol"; -abstract contract ERC1155MintableUpgradeable is - SelectorRoleControlUpgradeable, - IERC1155Mintable, - ERC1155Upgradeable, - ERC1155BurnableUpgradeable, - ERC1155PausableUpgradeable -{ +abstract contract ERC1155MintableUpgradeable is SelectorRoleControlUpgradeable, IERC1155Mintable, ERC1155Upgradeable { function supportsInterface( bytes4 interfaceId ) public view virtual override(IERC165, AccessControlEnumerableUpgradeable, ERC1155Upgradeable) returns (bool) { return super.supportsInterface(interfaceId); } - function _update( - address from, - address to, - uint256[] memory ids, - uint256[] memory values - ) internal virtual override(ERC1155Upgradeable, ERC1155PausableUpgradeable) whenNotPaused { - super._update(from, to, ids, values); - } - function mint(address to, uint256 id, uint256 value, bytes calldata data) external onlyAdmin { _mint(to, id, value, data); } diff --git a/contracts/token/ERC1155/EcoERC1155Upgradeable.sol b/contracts/token/ERC1155/EcoERC1155Upgradeable.sol index 8e95497..66e12e9 100644 --- a/contracts/token/ERC1155/EcoERC1155Upgradeable.sol +++ b/contracts/token/ERC1155/EcoERC1155Upgradeable.sol @@ -3,14 +3,24 @@ pragma solidity ^0.8.0; import { IERC1155MetadataURI, IEcoERC1155 } from "./IERC1155.sol"; + +import { ERC1155Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; import { ERC1155MintableUpgradeable } from "./ERC1155MintableUpgradeable.sol"; -import { EcoERC1155URIControl } from "./EcoERC1155URIControl.sol"; import { ERC1155URIStorageUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol"; +import { EcoERC1155URIControl } from "./EcoERC1155URIControl.sol"; -import { ERC1155Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; - -contract EcoERC1155Upgradeable is ERC1155MintableUpgradeable, EcoERC1155URIControl { +import { ERC1155BurnableUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol"; +import { ERC1155SupplyUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol"; +import { ERC1155PausableUpgradeable } from "./ERC1155PausableUpgradeable.sol"; + +contract EcoERC1155Upgradeable is + ERC1155MintableUpgradeable, + EcoERC1155URIControl, + ERC1155BurnableUpgradeable, + ERC1155PausableUpgradeable, + ERC1155SupplyUpgradeable +{ function initEcoERC1155(address initialOwner, string memory baseURI) public initializer { _initEcoOwnable(initialOwner); __ERC1155_init(baseURI); @@ -18,7 +28,7 @@ contract EcoERC1155Upgradeable is ERC1155MintableUpgradeable, EcoERC1155URIContr function supportsInterface( bytes4 interfaceId - ) public view override(ERC1155MintableUpgradeable, EcoERC1155URIControl) returns (bool) { + ) public view override(ERC1155MintableUpgradeable, ERC1155Upgradeable, EcoERC1155URIControl) returns (bool) { return super.supportsInterface(interfaceId); } @@ -27,7 +37,7 @@ contract EcoERC1155Upgradeable is ERC1155MintableUpgradeable, EcoERC1155URIContr address to, uint256[] memory ids, uint256[] memory values - ) internal virtual override(ERC1155MintableUpgradeable, ERC1155Upgradeable) { + ) internal virtual override(ERC1155PausableUpgradeable, ERC1155SupplyUpgradeable, ERC1155Upgradeable) { super._update(from, to, ids, values); } diff --git a/contracts/token/ERC1155/IERC1155.sol b/contracts/token/ERC1155/IERC1155.sol index 7fcea80..b2834c8 100644 --- a/contracts/token/ERC1155/IERC1155.sol +++ b/contracts/token/ERC1155/IERC1155.sol @@ -13,10 +13,18 @@ interface IERC1155URIControl is ISelectorRoleControl, IERC1155MetadataURI { function setBaseURI(string memory baseURI) external; } +interface IERC1155Supply is IERC1155 { + function totalSupply(uint256 id) external view returns (uint256); + + function totalSupply() external view returns (uint256); + + function exists(uint256 id) external view returns (bool); +} + interface IERC1155Mintable is ISelectorRoleControl, IERC1155 { function mint(address to, uint256 id, uint256 value, bytes calldata data) external; function mintBatch(address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data) external; } -interface IEcoERC1155 is IERC1155Mintable, IERC1155URIControl {} +interface IEcoERC1155 is IERC1155Supply, IERC1155Mintable, IERC1155URIControl {} diff --git a/test/token/ERC1155.ts b/test/token/ERC1155.ts index e24dc12..af71e90 100644 --- a/test/token/ERC1155.ts +++ b/test/token/ERC1155.ts @@ -74,7 +74,7 @@ describe("ERC1155 Mintable", function () { await erc1155.connect(users[0]).setApprovalForAll(owner, true); await expect(erc1155.safeTransferFrom(users[0], users[1], default1155Id, await erc1155.balanceOf(users[0], default1155Id), "0x")).not.reverted; await expect(erc1155.safeTransferFrom(users[0], users[1], default1155Id, amount, "0x")).reverted; - console.log(await erc1155.balanceOf(users[1], default1155Id)); + await expect(erc1155.connect(users[1]).safeTransferFrom(users[1], users[0], default1155Id, await erc1155.balanceOf(users[1], default1155Id)/2n, "0x")) .not.reverted; // this allowed, openzeppelin transfer imple differ from erc20 await erc1155.connect(users[1]).setApprovalForAll(owner, true); From bffbab12f8d7b29edf6ddd6086a109ae09ada7ee Mon Sep 17 00:00:00 2001 From: seinmyung25 Date: Tue, 9 Apr 2024 13:00:31 +0900 Subject: [PATCH 4/4] feat: erc1155 supply interfacing --- .../token/ERC1155/EcoERC1155Upgradeable.sol | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/contracts/token/ERC1155/EcoERC1155Upgradeable.sol b/contracts/token/ERC1155/EcoERC1155Upgradeable.sol index 66e12e9..62f9525 100644 --- a/contracts/token/ERC1155/EcoERC1155Upgradeable.sol +++ b/contracts/token/ERC1155/EcoERC1155Upgradeable.sol @@ -2,7 +2,8 @@ pragma solidity ^0.8.0; -import { IERC1155MetadataURI, IEcoERC1155 } from "./IERC1155.sol"; +import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import { IERC1155MetadataURI, IEcoERC1155, IERC1155Supply } from "./IERC1155.sol"; import { ERC1155Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; import { ERC1155MintableUpgradeable } from "./ERC1155MintableUpgradeable.sol"; @@ -15,6 +16,7 @@ import { ERC1155SupplyUpgradeable } from "@openzeppelin/contracts-upgradeable/to import { ERC1155PausableUpgradeable } from "./ERC1155PausableUpgradeable.sol"; contract EcoERC1155Upgradeable is + IEcoERC1155, ERC1155MintableUpgradeable, EcoERC1155URIControl, ERC1155BurnableUpgradeable, @@ -28,7 +30,12 @@ contract EcoERC1155Upgradeable is function supportsInterface( bytes4 interfaceId - ) public view override(ERC1155MintableUpgradeable, ERC1155Upgradeable, EcoERC1155URIControl) returns (bool) { + ) + public + view + override(ERC1155MintableUpgradeable, ERC1155Upgradeable, EcoERC1155URIControl, IERC165) + returns (bool) + { return super.supportsInterface(interfaceId); } @@ -52,4 +59,16 @@ contract EcoERC1155Upgradeable is { return super.uri(id); } + + function totalSupply(uint256 id) public view override(ERC1155SupplyUpgradeable, IERC1155Supply) returns (uint256) { + return super.totalSupply(id); + } + + function totalSupply() public view override(ERC1155SupplyUpgradeable, IERC1155Supply) returns (uint256) { + return super.totalSupply(); + } + + function exists(uint256 id) public view override(ERC1155SupplyUpgradeable, IERC1155Supply) returns (bool) { + return super.exists(id); + } }