diff --git a/.github/workflows/hardhat-test.yml b/.github/workflows/hardhat-test.yml new file mode 100644 index 0000000..4bc34ec --- /dev/null +++ b/.github/workflows/hardhat-test.yml @@ -0,0 +1,55 @@ +name: hardhat test(yarn) + +on: pull_request +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: true + token: ${{ secrets.KROMA_GIT_TOKEN }} + + - name: Cache Submodules + id: cache-submodule + uses: actions/cache@v3 + with: + path: | + eco-contract-info + wemix-wonder-staking + key: ${{ runner.os }}-submodules + + - name: Update git submodules + if: steps.cache-submodule.outputs.cache-hit != 'true' + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install(Cache) yarn + uses: actions/setup-node@v3 + with: + node-version: '18.x' + cache: 'yarn' + + - run: yarn --ignore-scripts + shell: bash + + - name: Caching solidity compiler + uses: actions/cache@v3 + with: + path: | + ~/.solcx + ~/.vvm + ~/.brownie/packages + key: ${{ runner.os }}-compiler-cache + + - name: Compile solidity + run: yarn hardhat compile + + - name: Launch local hardhat node + run: yarn hardhat node & + + - name: Testing + run: yarn hardhat test \ No newline at end of file diff --git a/contracts/access/EcoOwnable.sol b/contracts/access/EcoOwnable.sol index 7bb3905..e153214 100644 --- a/contracts/access/EcoOwnable.sol +++ b/contracts/access/EcoOwnable.sol @@ -6,54 +6,63 @@ import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/I import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import { Ownable2StepUpgradeable } from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; -interface IEcoOwnable { - function __EcoOwnable(address initialOwner) external ; - +interface IOwnable { function owner() external view returns (address); function renounceOwnership() external ; function transferOwnership(address newOwner) external ; +} +interface IOwnable2Step is IOwnable { function pendingOwner() external view returns (address); - function registerPendingOwner(address pendingOwner) external ; function acceptOwnership() external ; } -contract EcoOwnable is +interface IEcoOwnable is IOwnable2Step { + function initEcoOwnable(address initialOwner) external ; + + function registerPendingOwner(address pendingOwner) external ; +} + +abstract contract EcoOwnable is IEcoOwnable, Initializable, Ownable2StepUpgradeable { - constructor() { - // prevent owner setting attack - // avoid initialize for simple test - _transferOwnership(_msgSender()); - } - - function __EcoOwnable(address initialOwner) public initializer { + function initEcoOwnable(address initialOwner) public initializer { __Ownable_init(initialOwner); } - function owner() public view virtual override(IEcoOwnable, OwnableUpgradeable) returns (address) { - return OwnableUpgradeable.owner(); + function owner() public view virtual + override(IOwnable, OwnableUpgradeable) returns (address) { + return super.owner(); } - function renounceOwnership() public virtual override(IEcoOwnable, OwnableUpgradeable) { - return OwnableUpgradeable.renounceOwnership(); + function renounceOwnership() public virtual + override(IOwnable, OwnableUpgradeable) { + return super.renounceOwnership(); } - function transferOwnership(address newOwner) public virtual override(IEcoOwnable, Ownable2StepUpgradeable) { + function transferOwnership(address newOwner) public virtual + override(IOwnable, Ownable2StepUpgradeable) { return OwnableUpgradeable.transferOwnership(newOwner); } - function pendingOwner() public view virtual override(IEcoOwnable, Ownable2StepUpgradeable) returns (address) { - return Ownable2StepUpgradeable.pendingOwner(); + function pendingOwner() public view virtual + override(IOwnable2Step, Ownable2StepUpgradeable) returns (address) { + return super.pendingOwner(); } - function registerPendingOwner(address nextPendingOwner) external override { + function registerPendingOwner(address nextPendingOwner) public override { return Ownable2StepUpgradeable.transferOwnership(nextPendingOwner); } - function acceptOwnership() public virtual override(IEcoOwnable, Ownable2StepUpgradeable) { - return Ownable2StepUpgradeable.acceptOwnership(); + function acceptOwnership() public virtual + override(IOwnable2Step, Ownable2StepUpgradeable) { + return super.acceptOwnership(); + } + + function _transferOwnership(address newOwner) internal virtual + override(Ownable2StepUpgradeable) { + return super._transferOwnership(newOwner); } } \ No newline at end of file diff --git a/contracts/access/SelectorRoleControlUpgradeable.sol b/contracts/access/SelectorRoleControlUpgradeable.sol index 621a6c7..6633080 100644 --- a/contracts/access/SelectorRoleControlUpgradeable.sol +++ b/contracts/access/SelectorRoleControlUpgradeable.sol @@ -10,7 +10,7 @@ import { PausableUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/P import {IAccessControlEnumerable, IAccessControl} from "@openzeppelin/contracts/access/extensions/IAccessControlEnumerable.sol"; interface IPausable { - function paused() external view returns (bool); + // function paused() external view returns (bool); already defined & implemented function pause() external ; function unpause() external ; @@ -21,10 +21,13 @@ interface IMulticall { } interface ISelectorRoleControl is - IEcoOwnable, - IPausable, - IAccessControlEnumerable -{} + // IEcoOwnable, TODO: check redundant override, already defined & implemented + IAccessControlEnumerable, + IPausable +{ + function pause() external ; + function unpause() external ; +} contract SelectorRoleControlUpgradeable is Initializable, @@ -33,9 +36,6 @@ contract SelectorRoleControlUpgradeable is PausableUpgradeable, AccessControlEnumerableUpgradeable { - function __RoleAdmin_init() internal onlyInitializing { - } - modifier onlyAdmin { _onlyAdmin(_msgSender()); _; @@ -55,36 +55,17 @@ contract SelectorRoleControlUpgradeable is override(IAccessControl, AccessControlUpgradeable) { _revokeRole(role, account); } - function owner() public view virtual override(IEcoOwnable, EcoOwnable) returns (address) { - return super.owner(); - } - - function renounceOwnership() public virtual override(IEcoOwnable, EcoOwnable) { - return super.renounceOwnership(); - } - function pendingOwner() public view virtual override(IEcoOwnable, EcoOwnable) returns (address) { - return super.pendingOwner(); - } - - function transferOwnership(address newOwner) public virtual override(IEcoOwnable, EcoOwnable) { - return super.transferOwnership(newOwner); - } - - function acceptOwnership() public virtual override(IEcoOwnable, EcoOwnable) { - return super.acceptOwnership(); - } - - // IPausable - function paused() public view virtual override(IPausable, PausableUpgradeable) returns (bool) { + function paused() public view virtual override returns (bool) { return super.paused(); } - function pause() external override onlyAdmin { + // IPausable + function pause() public virtual override onlyAdmin { _pause(); } - function unpause() external override onlyAdmin { + function unpause() public virtual override onlyAdmin { _unpause(); } } \ No newline at end of file diff --git a/contracts/token/ERC721/ERC721.sol b/contracts/token/ERC721/ERC721.sol index 47a05f8..83f5297 100644 --- a/contracts/token/ERC721/ERC721.sol +++ b/contracts/token/ERC721/ERC721.sol @@ -24,12 +24,16 @@ interface INFT_Mintable is IERC721SequencialMintUpbradeable, IERC721Queryable { contract NFT_Mintable is INFT_Mintable, - ERC721PausableUpgradeable, ERC721SequencialMintUpbradeable, - ERC721QueryableUpgradeable + ERC721QueryableUpgradeable, + ERC721PausableUpgradeable { - function __NFT_Mintable_init(address owner, string memory name, string memory symbol) public initializer { - __Ownable_init(owner); + constructor(string memory name, string memory symbol) { + initNFT_Mintable(_msgSender(), name, symbol); + } + + function initNFT_Mintable(address initialOwner, string memory name, string memory symbol) public initializer { + __Ownable_init(initialOwner); __ERC721_init(name, symbol); } @@ -55,14 +59,20 @@ contract NFT_Mintable is } } +interface INFT_Identical is INFT_Mintable {} + contract NFT_Identical is + INFT_Identical, NFT_Mintable, ERC721IdenticalResourceUpgradeable { + constructor(string memory name, string memory symbol) + NFT_Mintable(name, symbol) {} + function supportsInterface( bytes4 interfaceId ) public view virtual - override(ERC721URIStorageUpgradeable, NFT_Mintable) returns (bool) { + override(IERC165, ERC721URIStorageUpgradeable, NFT_Mintable) returns (bool) { return super.supportsInterface(interfaceId); } @@ -88,6 +98,9 @@ contract NFT_Typed is NFT_Mintable, ERC721TypedUpgradeable { + constructor(string memory name, string memory symbol) + NFT_Mintable(name, symbol) {} + function paused() public view virtual override(SelectorRoleControlUpgradeable, NFT_Mintable) returns (bool) { return super.paused(); diff --git a/contracts/token/ERC721/ERC721SequencialMintUpbradeable.sol b/contracts/token/ERC721/ERC721SequencialMintUpbradeable.sol index c011da1..d1e0aac 100644 --- a/contracts/token/ERC721/ERC721SequencialMintUpbradeable.sol +++ b/contracts/token/ERC721/ERC721SequencialMintUpbradeable.sol @@ -9,13 +9,14 @@ import { IERC4906 } from "@openzeppelin/contracts/interfaces/IERC4906.sol"; import { IERC721Metadata } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; import { IERC721Errors } from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; -import { SelectorRoleControlUpgradeable, AccessControlEnumerableUpgradeable } from "../../access/SelectorRoleControlUpgradeable.sol"; +import { ISelectorRoleControl, SelectorRoleControlUpgradeable, AccessControlEnumerableUpgradeable } from "../../access/SelectorRoleControlUpgradeable.sol"; import { ERC721Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; import { ERC721BurnableUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol"; import { ERC721EnumerableUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; interface IERC721SequencialMintUpbradeable is // Seq == Sequencial + ISelectorRoleControl, IERC165, IERC721, IERC4906, diff --git a/hardhat.config.ts b/hardhat.config.ts index 542d96b..4fb3feb 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -3,6 +3,8 @@ import "@nomicfoundation/hardhat-toolbox"; import "./tasks/utils"; +import "hardhat-tracer"; + const config: HardhatUserConfig = { solidity: { compilers: [ diff --git a/package.json b/package.json index 727a60d..23e5d60 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "ethers": "^6.4.0", "hardhat": "^2.19.2", "hardhat-gas-reporter": "^1.0.8", + "hardhat-tracer": "^2.7.0", "solidity-coverage": "^0.8.0", "ts-node": ">=8.0.0", "typechain": "^8.3.0", diff --git a/tasks/utils.ts b/tasks/utils.ts index 2f4d3f5..a6a0574 100644 --- a/tasks/utils.ts +++ b/tasks/utils.ts @@ -8,6 +8,7 @@ task("calc-slot", "calc slot value from string(ERC7201)") .setAction(async (args, hre: HardhatRuntimeEnvironment) => { await namespaceSlot(args.string) }); + task("slots", "calc slot value from string(ERC7201)") .setAction(async (_, hre: HardhatRuntimeEnvironment) => { const namespaces = [ diff --git a/test/token/ERC721.ts b/test/token/ERC721.ts index 407c61f..7b5768f 100644 --- a/test/token/ERC721.ts +++ b/test/token/ERC721.ts @@ -13,8 +13,8 @@ describe("NFT Mintable", function () { const [owner, ...users] = await ethers.getSigners(); const NFT = await ethers.getContractFactory("NFT_Mintable"); - const nft = await NFT.deploy(); - await nft.__NFT_Mintable_init(owner.address, name, symbol); + const nft = await NFT.deploy(name, symbol); + // await nft.initNFT_Mintable(owner.address, name, symbol); only for proxy return { nft, owner, users }; } diff --git a/yarn.lock b/yarn.lock index 4b30a72..1fd2c31 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1451,7 +1451,7 @@ chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.1.0: +chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -1668,7 +1668,7 @@ death@^1.1.0: resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" integrity sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w== -debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3: +debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -1925,7 +1925,7 @@ ethereumjs-util@^7.1.4: ethereum-cryptography "^0.1.3" rlp "^2.2.4" -ethers@^5.7.1, ethers@^5.7.2: +ethers@^5.6.1, ethers@^5.7.1, ethers@^5.7.2: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== @@ -2307,6 +2307,15 @@ hardhat-gas-reporter@^1.0.8: eth-gas-reporter "^0.2.25" sha1 "^1.1.1" +hardhat-tracer@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/hardhat-tracer/-/hardhat-tracer-2.7.0.tgz#af04e5cd7ec2525c24a70634f6d1051252992d03" + integrity sha512-H+30jj6bCyX7NfhY7Umbzq535jhi9Wd5fGNli9qWcQ+5iOB477Nm8XdGtPtgOV1vQ7VQzIwKFzoEbqy+BuxTlg== + dependencies: + chalk "^4.1.2" + debug "^4.3.4" + ethers "^5.6.1" + hardhat@^2.19.2: version "2.19.2" resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.19.2.tgz#815819e4efd234941d495decb718b358d572e2c8"