From d287bfe9a106909c6fb62dcee1d76d5bd70076fe Mon Sep 17 00:00:00 2001 From: Tomosuke0930 Date: Tue, 26 Jul 2022 15:05:06 +0900 Subject: [PATCH 1/4] [WIP] faces-import-error --- .vscode/settings.json | 3 + contract/contracts/Diamond.sol | 75 +++ contract/contracts/MerkleTree.sol | 1 + contract/contracts/YoMinter.sol | 4 +- contract/contracts/facets/DiamondCutFacet.sol | 21 + .../contracts/facets/DiamondLoupeFacet.sol | 154 +++++++ contract/contracts/facets/MerkleTree.sol | 158 +++++++ contract/contracts/facets/OwnershipFacet.sol | 16 + contract/contracts/interface/IDiamondCut.sol | 30 ++ .../contracts/interface/IDiamondLoupe.sol | 13 + contract/contracts/interface/Sample.sol | 22 - contract/contracts/library/LibAppStorage.sol | 85 ++++ contract/contracts/library/LibDiamond.sol | 176 +++++++ .../upgradeInitializers/DiamondInit.sol | 27 ++ contract/contracts/utils/IERC173.sol | 9 + contract/hardhat.config.js | 2 + contract/package-lock.json | 429 +++++++++++++++++- contract/package.json | 6 +- 18 files changed, 1202 insertions(+), 29 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 contract/contracts/Diamond.sol create mode 100644 contract/contracts/facets/DiamondCutFacet.sol create mode 100644 contract/contracts/facets/DiamondLoupeFacet.sol create mode 100644 contract/contracts/facets/MerkleTree.sol create mode 100644 contract/contracts/facets/OwnershipFacet.sol create mode 100644 contract/contracts/interface/IDiamondCut.sol create mode 100644 contract/contracts/interface/IDiamondLoupe.sol delete mode 100644 contract/contracts/interface/Sample.sol create mode 100644 contract/contracts/library/LibAppStorage.sol create mode 100644 contract/contracts/library/LibDiamond.sol create mode 100644 contract/contracts/upgradeInitializers/DiamondInit.sol create mode 100644 contract/contracts/utils/IERC173.sol diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..2e09aa7 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "solidity.defaultCompiler": "localNodeModule" +} diff --git a/contract/contracts/Diamond.sol b/contract/contracts/Diamond.sol new file mode 100644 index 0000000..40854f7 --- /dev/null +++ b/contract/contracts/Diamond.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +* +* Implementation of a diamond. +/******************************************************************************/ + +import {LibDiamond} from "./libraries/LibDiamond.sol"; +import {IDiamondCut} from "./interfaces/IDiamondCut.sol"; + +contract Diamond { + constructor(address _contractOwner, address _diamondCutFacet) payable { + LibDiamond.setContractOwner(_contractOwner); + + // Add the diamondCut external function from the diamondCutFacet + IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1); + bytes4[] memory functionSelectors = new bytes4[](1); + functionSelectors[0] = IDiamondCut.diamondCut.selector; + cut[0] = IDiamondCut.FacetCut({facetAddress: _diamondCutFacet, action: IDiamondCut.FacetCutAction.Add, functionSelectors: functionSelectors}); + LibDiamond.diamondCut(cut, address(0), ""); + } + + /** + DS + */ + struct DiamondStorageMerkleTree { + // + } + + function diamondStorage() internal pure returns (DiamondStorage storage ds) { + bytes32 storagePosition = keccak256("diamond.storage.MerkleTree"); + assembly { + ds.slot := storagePosition + } + } + + + // Find facet for function that is called and execute the + // function if a facet is found and return any value. + fallback() external payable { + LibDiamond.DiamondStorage storage ds; + bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION; + // get diamond storage + assembly { + ds.slot := position + } + // get facet from function selector + address facet = ds.facetAddressAndSelectorPosition[msg.sig].facetAddress; + require(facet != address(0), "Diamond: Function does not exist"); + // Execute external function from facet using delegatecall and return any value. + assembly { + // copy function selector and any arguments + // the selectore stores in the stack + calldatacopy(0, 0, calldatasize()) + + // calldatasize: byte size of the calldata. + let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) + // get any return value + returndatacopy(0, 0, returndatasize()) + // return any return value or error back to the caller + switch result + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } + } + + receive() external payable {} +} diff --git a/contract/contracts/MerkleTree.sol b/contract/contracts/MerkleTree.sol index 68288d1..5091dca 100644 --- a/contract/contracts/MerkleTree.sol +++ b/contract/contracts/MerkleTree.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; + import './interface/IMerkleTree.sol'; import './utils/Checkers.sol'; diff --git a/contract/contracts/YoMinter.sol b/contract/contracts/YoMinter.sol index acab8f9..a89e254 100644 --- a/contract/contracts/YoMinter.sol +++ b/contract/contracts/YoMinter.sol @@ -11,7 +11,7 @@ import '@appliedzkp/semaphore-contracts/interfaces/IVerifier.sol'; /// @title YoNFTMinter -contract YoMinter is IYoMinter, SemaphoreCore, ERC1238, ERC1238URIStorage, Ownable { +contract YoMinter is IYoMinter, SemaphoreCore, ERC1238, ERC1238URIStorage, Ownable, Initializable { /************************************************ * Library & Variables @@ -27,7 +27,7 @@ contract YoMinter is IYoMinter, SemaphoreCore, ERC1238, ERC1238URIStorage, Ownab * Constructor ***********************************************/ - constructor(address verifierAddress, string memory baseURI_) ERC1238(baseURI_) { + constructor(address verifierAddress, string memory baseURI_) initializer ERC1238(baseURI_) { verifier = IVerifier(verifierAddress); } diff --git a/contract/contracts/facets/DiamondCutFacet.sol b/contract/contracts/facets/DiamondCutFacet.sol new file mode 100644 index 0000000..343e066 --- /dev/null +++ b/contract/contracts/facets/DiamondCutFacet.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +/******************************************************************************/ + +import {IDiamondCut} from "../interfaces/IDiamondCut.sol"; +import {LibDiamond} from "../libraries/LibDiamond.sol"; +え +contract DiamondCutFacet is IDiamondCut { + function diamondCut( + FacetCut[] calldata _diamondCut, + address _init, + bytes calldata _calldata + ) external override { + LibDiamond.enforceIsContractOwner(); + LibDiamond.diamondCut(_diamondCut, _init, _calldata); + } +} \ No newline at end of file diff --git a/contract/contracts/facets/DiamondLoupeFacet.sol b/contract/contracts/facets/DiamondLoupeFacet.sol new file mode 100644 index 0000000..bf1ca69 --- /dev/null +++ b/contract/contracts/facets/DiamondLoupeFacet.sol @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +/******************************************************************************/ + +// The functions in DiamondLoupeFacet MUST be added to a diamond. +// The EIP-2535 Diamond standard requires these functions. + +import {LibDiamond} from "../libraries/LibDiamond.sol"; +import {IDiamondLoupe} from "../interfaces/IDiamondLoupe.sol"; +import {IERC165} from "../utils/IERC165.sol"; + +contract DiamondLoupeFacet is IDiamondLoupe, IERC165 { + // Diamond Loupe Functions + //////////////////////////////////////////////////////////////////// + /// These functions are expected to be called frequently by tools. + // + // struct Facet { + // address facetAddress; + // bytes4[] functionSelectors; + // } + /// @notice Gets all facets and their selectors. + /// @return facets_ Facet + function facets() external view override returns (Facet[] memory facets_) { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + uint256 selectorCount = ds.selectors.length; + // create an array set to the maximum size possible + facets_ = new Facet[](selectorCount); + // create an array for counting the number of selectors for each facet + uint8[] memory numFacetSelectors = new uint8[](selectorCount); + // total number of facets + uint256 numFacets; + // loop through function selectors + for (uint256 selectorIndex; selectorIndex < selectorCount; selectorIndex++) { + bytes4 selector = ds.selectors[selectorIndex]; + address facetAddress_ = ds.facetAddressAndSelectorPosition[selector].facetAddress; + bool continueLoop = false; + // find the functionSelectors array for selector and add selector to it + for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { + if (facets_[facetIndex].facetAddress == facetAddress_) { + facets_[facetIndex].functionSelectors[numFacetSelectors[facetIndex]] = selector; + // probably will never have more than 256 functions from one facet contract + require(numFacetSelectors[facetIndex] < 255); + numFacetSelectors[facetIndex]++; + continueLoop = true; + break; + } + } + // if functionSelectors array exists for selector then continue loop + if (continueLoop) { + continueLoop = false; + continue; + } + // create a new functionSelectors array for selector + facets_[numFacets].facetAddress = facetAddress_; + facets_[numFacets].functionSelectors = new bytes4[](selectorCount); + facets_[numFacets].functionSelectors[0] = selector; + numFacetSelectors[numFacets] = 1; + numFacets++; + } + for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { + uint256 numSelectors = numFacetSelectors[facetIndex]; + bytes4[] memory selectors = facets_[facetIndex].functionSelectors; + // setting the number of selectors + assembly { + mstore(selectors, numSelectors) + } + } + // setting the number of facets + assembly { + mstore(facets_, numFacets) + } + } + + /// @notice Gets all the function selectors supported by a specific facet. + /// @param _facet The facet address. + /// @return _facetFunctionSelectors The selectors associated with a facet address. + function facetFunctionSelectors(address _facet) external view override returns (bytes4[] memory _facetFunctionSelectors) { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + // all selectors + uint256 selectorCount = ds.selectors.length; + // target selector number + uint256 numSelectors; + _facetFunctionSelectors = new bytes4[](selectorCount); + // loop through function selectors + for (uint256 selectorIndex; selectorIndex < selectorCount; selectorIndex++) { + bytes4 selector = ds.selectors[selectorIndex]; + address facetAddress_ = ds.facetAddressAndSelectorPosition[selector].facetAddress; + if (_facet == facetAddress_) { + // 同じでは? + // mstore(_facetFunctionSelectors, numSelectors) + _facetFunctionSelectors[numSelectors] = selector; + numSelectors++; + } + } + // Set the number of selectors in the array + // 最後にnumSelecotorsを返す lengthみたいな感じ + assembly { + mstore(_facetFunctionSelectors, numSelectors) + } + } + + /// @notice Get all the facet addresses used by a diamond. + /// @return facetAddresses_ + function facetAddresses() external view override returns (address[] memory facetAddresses_) { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + uint256 selectorCount = ds.selectors.length; + // create an array set to the maximum size possible + facetAddresses_ = new address[](selectorCount); + uint256 numFacets; + // loop through function selectors + for (uint256 selectorIndex; selectorIndex < selectorCount; selectorIndex++) { + bytes4 selector = ds.selectors[selectorIndex]; + address facetAddress_ = ds.facetAddressAndSelectorPosition[selector].facetAddress; + bool continueLoop = false; + // see if we have collected the address already and break out of loop if we have + for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { + if (facetAddress_ == facetAddresses_[facetIndex]) { + continueLoop = true; + break; + } + } + // continue loop if we already have the address + if (continueLoop) { + continueLoop = false; + continue; + } + // include address + facetAddresses_[numFacets] = facetAddress_; + numFacets++; + } + // Set the number of facet addresses in the array + assembly { + mstore(facetAddresses_, numFacets) + } + } + + /// @notice Gets the facet address that supports the given selector. + /// @dev If facet is not found return address(0). + /// @param _functionSelector The function selector. + /// @return facetAddress_ The facet address. + function facetAddress(bytes4 _functionSelector) external view override returns (address facetAddress_) { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + facetAddress_ = ds.facetAddressAndSelectorPosition[_functionSelector].facetAddress; + } + + // This implements ERC-165. + function supportsInterface(bytes4 _interfaceId) external view override returns (bool) { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + return ds.supportedInterfaces[_interfaceId]; + } +} diff --git a/contract/contracts/facets/MerkleTree.sol b/contract/contracts/facets/MerkleTree.sol new file mode 100644 index 0000000..797a6da --- /dev/null +++ b/contract/contracts/facets/MerkleTree.sol @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.4; +import {AppStorage} from "../libraries/LibAppStorage.sol"; +import '../interface/IMerkleTree.sol'; +import '../utils/Checkers.sol'; + +contract MerkleTree is IMerkleTree, Checkers { + // /************************************************ + // * Variables + // ***********************************************/ + AppStorage internal s; + + /************************************************ + * Getters count for something of Mekrle Tree + ***********************************************/ + + /// get "index" of Merkle Tree + function getMerkleTreesIndex(uint256 _groupId) external view returns (uint256 idsIndex) { + for (uint256 i = 0; i < s.merkelTrees.length; i++) { + if (_groupId == s.merkleTrees[i].groupId) return idsIndex = i; + } + } + + function getSameLevelNodesLength(uint256 _groupId, uint256 _level) external view returns (uint256 index) { + (, index) = getNodesByLevel(_groupId, _level); + } + + /// get "amounts" of Merkle Tree + function getNodeCounts(uint256 _groupId) public view groupIdCheck(_groupId) returns (uint256 nodeCounts) { + uint256 idsIndexs = getMerkleTreesIndex(_groupId); + nodeCounts = s.merkleTrees[idsIndexs].nodes.length; + } + + /************************************************ + * Getters info for info of Mekrle Tree Node + ***********************************************/ + + /// get "all nodes" of Merkle Tree + function getAllNodes(uint256 _groupId) public view groupIdCheck(_groupId) returns (MerkleTreeNode[] memory allNodes) { + uint256 idsIndexs = getMerkleTreesIndex(_groupId); + allNodes = s.merkleTrees[idsIndexs].nodes; + } + + /// get "all nodes" the same "level" + function getNodesByLevel(uint256 _groupId, uint256 _level) public view returns (MerkleTreeNode[] memory nodes, uint256 counts) { + MerkleTreeNode[] memory allNodes = getAllNodes(_groupId); + for (uint256 i = 0; i < allNodes.length; i++) { + if (_level == allNodes[i].level) { + nodes[counts] = allNodes[i]; + // nodes.push(allNodes[i]); + counts++; + } + } + } + + /// get "node" by hash + function getNodeByHash(uint256 _groupId, bytes32 _hash) public view groupIdCheck(_groupId) returns (MerkleTreeNode memory node) { + MerkleTreeNode[] memory allNodes = getAllNodes(_groupId); + for (uint256 i = 0; i < allNodes.length; i++) { + if (_hash == allNodes[i].hash) node = allNodes[i]; + } + } + + /// get "node" from groupId, level, index + function getNode( + uint256 _groupId, + uint256 _level, + uint256 _index + ) public view allCheck(_groupId, _level, _index) returns (MerkleTreeNode memory node) { + (MerkleTreeNode[] memory nodes, ) = getNodesByLevel(_groupId, _level); + for (uint256 i = 0; i < nodes.length; i++) { + if (_index == nodes[i].index) { + node = nodes[i]; + } + } + } + + /************************************************ + * Add Node + ***********************************************/ + /// add Node + function addNode( + address _signer, + bytes32 _hash, + uint256 _groupId, + bytes32 _groupName, + uint256 _level, + uint256 _index + ) public { + MerkleTreeNode memory node; + uint256 treeIndex = getMerkleTreesIndex(_groupId); + { + node.hash = _hash; + node.groupId = _groupId; + node.groupName = _groupName; + node.index = _index; + node.level = _level; + } + s.merkleTrees[treeIndex].nodes.push(node); + s.userNodes[_signer][_groupId] = node;///check + } + + /// Collectively execute addNode func + function batchAddNode(address _signer, BatchAddNode[] memory txs) external { + for (uint256 i; i < txs.length; i++) { + addNode(_signer, txs[i].hash, txs[i].groupId, txs[i].groupName, txs[i].level, txs[i].index); + } + } + + /************************************************ + * Update Node + ***********************************************/ + + /// update hash of Node + function updateNodeHash( + address _signer, + uint256 _groupId, + bytes32 _hash + ) public { + // MerkleTreeNode memory node = getNode(_groupId, _level, _index); + MerkleTreeNode storage node = s.userNodes[_signer][_groupId]; + node.hash = _hash; + } + + /// update "siblingHash" and "parent" of Node + function updateNodeProperties( + address _signer, + uint256 _groupId, + // uint256 _level, + // uint256 _index, + uint256 _parentLevel, + uint256 _parentIndex, + bytes32 _siblingHash + ) public { + // MerkleTreeNode memory node = getNode(_groupId, _level, _index); //this is target node + MerkleTreeNode storage node = s.userNodes[_signer][_groupId]; + { + node.siblingHash = _siblingHash; + node.parent.groupId = _groupId; + node.parent.level = _parentLevel; + node.parent.index = _parentIndex; + } + } + + /// Collectively execute updateNode func + function batchUpdateNode(address _signer,BatchUpdateNode[] memory txs) external { + for (uint256 i; i < txs.length; i++) { + updateNodeHash(_signer, txs[i].groupId,txs[i].hash); + } + } + + /// Collectively execute updateNodeProperties func + function batchUpdateNodePro(address _signer,BatchUpdateNodePro[] memory txs) external { + for (uint256 i; i < txs.length; i++) { + updateNodeProperties(_signer,txs[i].groupId, txs[i].parentLevel, txs[i].parentIndex, txs[i].siblingHash); + } + } +} diff --git a/contract/contracts/facets/OwnershipFacet.sol b/contract/contracts/facets/OwnershipFacet.sol new file mode 100644 index 0000000..0dd4c2c --- /dev/null +++ b/contract/contracts/facets/OwnershipFacet.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { LibDiamond } from "../libraries/LibDiamond.sol"; +import { IERC173 } from "../utils/IERC173.sol"; + +contract OwnershipFacet is IERC173 { + function transferOwnership(address _newOwner) external override { + LibDiamond.enforceIsContractOwner(); + LibDiamond.setContractOwner(_newOwner); + } + + function owner() external override view returns (address owner_) { + owner_ = LibDiamond.contractOwner(); + } +} diff --git a/contract/contracts/interface/IDiamondCut.sol b/contract/contracts/interface/IDiamondCut.sol new file mode 100644 index 0000000..009bbc7 --- /dev/null +++ b/contract/contracts/interface/IDiamondCut.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IDiamondCut { + enum FacetCutAction { + Add, + Replace, + Remove + } + // Add=0, Replace=1, Remove=2 + // DiamondCutで使われる + + struct FacetCut { + address facetAddress; + FacetCutAction action; // ここで使用 + bytes4[] functionSelectors; + } + + //ここで条件分岐とか起きそうね + + function diamondCut( + FacetCut[] calldata _diamondCut, + address _init, + bytes calldata _calldata + // including function selector and arguments + // _calldata is executed with delegatecall on _init + ) external; + + event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata); +} diff --git a/contract/contracts/interface/IDiamondLoupe.sol b/contract/contracts/interface/IDiamondLoupe.sol new file mode 100644 index 0000000..636301d --- /dev/null +++ b/contract/contracts/interface/IDiamondLoupe.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IDiamondLoupe { + struct Facet { + address facetAddress; + bytes4[] functionSelectors; + } + function facets() external view returns(Facet[] memory facets_); + function facetFunctionSelectors(address _facet) external view returns(bytes4[] memory facetFunctionSelectors_); + function facetAddresses() external view returns(address[] memory facetAddresses_); + function facetAddress(bytes4 _functionSelector) external view returns(address facetAddress_); +} \ No newline at end of file diff --git a/contract/contracts/interface/Sample.sol b/contract/contracts/interface/Sample.sol deleted file mode 100644 index 042b932..0000000 --- a/contract/contracts/interface/Sample.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity >=0.4.22 <0.9.0; - -contract Oracle { - struct Request { - bytes data; - function(uint256) external callback; - } - - Request[] private requests; - event NewRequest(uint256); - - function query(bytes memory data, function(uint256) external callback) public { - requests.push(Request(data, callback)); - emit NewRequest(requests.length - 1); - } - - function reply(uint256 requestID, uint256 response) public { - // Here goes the check that the reply comes from a trusted source - requests[requestID].callback(response); - } -} diff --git a/contract/contracts/library/LibAppStorage.sol b/contract/contracts/library/LibAppStorage.sol new file mode 100644 index 0000000..31cd3ab --- /dev/null +++ b/contract/contracts/library/LibAppStorage.sol @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import '../interface/IGroup.sol'; +import '../interface/ICommitment.sol'; +import '../interface/IMerkleTree.sol'; + +uint256 constant nums = 49; + +struct Group { + uint256 id; + uint256 nullfier; + string name; + uint256 criteria; + string attr_key; +} + +struct Commitment { + uint256 id; + string userId; + uint256 groupId; + bytes32 data; + string metadata; + address mintAddress; + uint256 createdAt; +} + + +struct MerkleTreeNode { + uint256 id; + bytes32 hash; //hash + uint256 groupId; + bytes32 groupName; + uint256 index; + uint256 level; + bytes32 siblingHash; + /// next to node's hash, for[2],siblingHash is [3]'s hash + ParentLocate parent; +} +struct ParentLocate { + uint256 groupId; + uint256 index; + uint256 level; +} + +struct BatchAddNode { + bytes32 hash; + uint256 groupId; + bytes32 groupName; + uint256 index; + uint256 level; +} + +struct BatchUpdateNode { + bytes32 hash; + uint256 groupId; + uint256 index; + uint256 level; +} + +struct BatchUpdateNodePro { + uint256 groupId; + uint256 index; + uint256 level; + uint256 parentIndex; + uint256 parentLevel; + bytes32 siblingHash; +} + +struct MerkleTree { + uint256 groupId; + MerkleTreeNode[] nodes; +} + +struct AppStorage { + // IMerkleTree + mapping(address => mapping(uint256 => MerkleTreeNode)) userNodes; + MerkleTree[nums] merkleTrees; + // Group + Group[nums] groups; + uint256[nums] groupIds; + uint256[nums] groupNullfiers; + // Commitment + mapping(address => Commitment[]) userCommitments; +} diff --git a/contract/contracts/library/LibDiamond.sol b/contract/contracts/library/LibDiamond.sol new file mode 100644 index 0000000..a704c16 --- /dev/null +++ b/contract/contracts/library/LibDiamond.sol @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IDiamondCut} from "../interfaces/IDiamondCut.sol"; + +library LibDiamond { + bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage"); + + struct FacetAddressAndSelectorPosition { + address facetAddress; + uint16 selectorPosion; //selectorPosition? + } + + // diamondStorage storong the function selector and facet + struct DiamondStorage { + mapping(bytes4 => FacetAddressAndSelectorPosition) facetAddressAndSelectorPosition; + bytes4[] selectors; + mapping(bytes4 => bool) supportedInterfaces; + // owner of the contract + address contractOwner; + } + + // returns ds + function diamondStorage() internal pure returns (DiamondStorage storage ds) { + bytes32 position = DIAMOND_STORAGE_POSITION; + // c8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c + + assembly { + ds.slot := position + } + } + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + function setContreactOwner(address _newOwner) internal { + DiamondStorage storage ds = diamondStorage(); // set the ds.slot + address previousOwner = ds.contractOwner; + ds.contractOwner = _newOwner; + emit OwnershipTransferred(previousOwner, _newOwner); + } + + function contractOwner() internal view returns (address contractOwner_) { + contractOwner_ = diamondStorage().contractOwner; + } + + function enforceIsContractOwner() internal view { + require(msg.sender == diamondStorage().contractOwner, "ERROR"); + } + + event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata); + + // どうやって実行しているんだろう?何故ならおそらく一つしか渡されないんだろうと思うから + function daimondCut( + IDiamondCut.FacetCut[] memory _diamondCut, + // below argument use to execute initializeDiamondCut + address _init, + bytes memory _calldata + ) internal { + for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) { + IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action; + if (action == IDiamondCut.FacetCutAction.Add) { + addFunction(_diamondCut[faceIndex].facetAddress, _diamondCut[facetIndex].functionSelectors); + } else if (action == IDiamondCut.FacetCutAction.Replace) { + replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors); + } else if ( + action == IDiamondCut.FacetCutAction.Remove + ) { + removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors); + } else { + revert("ERROR"); + } + } + // 絶対にこれを読んでいる + emit DiamondCut(_diamondCut, _init, _calldata); + // Actionに引っかかるやつはelseに行ってdelegatecallされる + initializeDiamondCut(_init, _calldata); + } + + // add Selector + // ds.selectors.push(selector); + // selectorCount++; + function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { + require(_functionSelectors.length > 0, "Error"); + DiamondStorage storage ds = diamondStorage(); + // selectorCount = length + // bytes4[] selectors; + uint16 selectorCount = uint16(ds.selectors.length); + require(_facetAddress != address(0), "Error"); + enforceHasContractCode(_facetAddress, "ERROR"); + for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { + bytes4 selector = _functionSelectors[selectorIndex]; + address oldFacetAddress = ds.facetAddressAndSelectorPosition[selector].facetAddress; + require(oldFacetAddress == address(0), "ERROR"); + // struct - FacetAddressAndSelectorPosition.selectorPosition == selectorCount + ds.facetAddressAndSelectorPosition[selector] = FacetAddressAndSelectorPosition(_facetAddress, selectorCount); + ds.selectors.push(selector); // bytes4[] selectors; + selectorCount++; + } + } + + // change the facet address to new facet address + // ds.facetAddressAndSelectorPosition[selector].facetAddress = _facetAddress; + // no selectorsCount + function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { + require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut"); + DiamondStorage storage ds = diamondStorage(); + require(_facetAddress != address(0), "LibDiamondCut: Replace facet can't be address(0)"); + enforceHasContractCode(_facetAddress, "LibDiamondCut: Replace facet has no code"); + for(uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { + bytes4 selector = _functionSelectors[selectorIndex]; + address oldFacetAddress = ds.facetAddressAndSelectorPosition[selector].facetAddress; + require(oldFacetAddress != address(this), "LibDiamondCut: Can't replace immutable function"); + require(oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function"); + require(oldFacetAddress != address(0), "LibDiamondCut: Can't replace function that doesn't exist"); + // replace old facet address + ds.facetAddressAndSelectorPosition[selector].facetAddress = _facetAddress; + } + } + + // この意味がわからない! + // _facetAddress + function removeFunctions(address _facetAddress, bytes4[] memory _functionSelecotrs) internal { + require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut"); + DiamondStorage storage ds = diamondStorage(); + uint256 selectorCount = ds.selectors.length; + // not remove, go to address(0) + // ここでfacetAddressを0にしてもらっている前提で指定されたやつに0を入れる + require(_facetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)"); + for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { + bytes4 selector = _functionSelectors[selectorIndex]; + FacetAddressAndSelectorPosition memory oldFacetAddressAndSelectorPosition = ds.facetAddressAndSelectorPosition[selector]; + require(oldFacetAddressAndSelectorPosition.facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist"); + // can't remove immutable functions -- functions defined directly in the diamond + // function on Diamond.sol cannot change. + require(oldFacetAddressAndSelectorPosition.facetAddress != address(this), "LibDiamondCut: Can't remove immutable function."); + selectorCount --; + if (oldFacetAddressAndSelectorPosition.selectorPosition != selectorCount) { + bytes4 lastSelector = ds.selectors[selectorCount]; + ds.selectors[oldFacetAddressAndSelectorPosition.selectorPosition] = lastSelector; + ds.facetAddressAndSelectorPosition[lastSelector].selectorPosition = oldFacetAddressAndSelectorPosition.selectorPosition; + } + /// why last selector?? + // delete last selector + ds.selectors.pop(); + delete ds.facetAddressAndSelectorPosition[selector]; + } + } + + function initializeDiamondCut(address _init, bytes memory _calldata) internal { + if(_init == address(0)) { + require(_calldata.length == 0,"ERROR"); + } else { + if(_init != address(this)) { + enforceHasContractCode(_init, "LibDiamondCut: _init address has no code"); + } + (bool success, bytes memory error) = _init.delegatecall(_caldata); + if (!success) { + if (error.length > 0) { + // bubble up the error + revert(string(error)); + } else { + revert("LibDiamondCut: _init function reverted"); + } + } + } + } + + // checking the contract or not + function enforceHasContractCode(address _contract, string memory _errorMessage) internal view { + uint256 contractSize; + assembly { + contractSize := extcodesize(_contract) + } + require(contractSize > 0, _errorMessage); + } +} diff --git a/contract/contracts/upgradeInitializers/DiamondInit.sol b/contract/contracts/upgradeInitializers/DiamondInit.sol new file mode 100644 index 0000000..56e205e --- /dev/null +++ b/contract/contracts/upgradeInitializers/DiamondInit.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/******************************************************************************\ +* Author: Nick Mudge (https://twitter.com/mudgen) +* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 +* +* Implementation of a diamond. +/******************************************************************************/ + +import {LibDiamond} from "../libraries/LibDiamond.sol"; +import {IDiamondLoupe} from "../interfaces/IDiamondLoupe.sol"; +import {IDiamondCut} from "../interfaces/IDiamondCut.sol"; +import {IERC173} from "../utils/IERC173.sol"; +import {IERC165} from "../utils/IERC165.sol"; + +contract DiamondInit { + function init() external { + LibDiamond.DiamondStorage storage ds = LibDiamond.DiamondStorage(); + ds.supportInterfaces[type(IERC165.interfaceId)] = true; + ds.supportedInterfaces[type(IDiamondCut).interfaceId] = true; + ds.supportedInterfaces[type(IDiamondLoupe).interfaceId] = true; + ds.supportedInterfaces[type(IERC173).interfaceId] = true; + } + // define the state vairables + +} \ No newline at end of file diff --git a/contract/contracts/utils/IERC173.sol b/contract/contracts/utils/IERC173.sol new file mode 100644 index 0000000..eb525c6 --- /dev/null +++ b/contract/contracts/utils/IERC173.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IERC173 { + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + function owner() external view returns(address owner_); + function tranferOwnership(address _newOwner) external; +} \ No newline at end of file diff --git a/contract/hardhat.config.js b/contract/hardhat.config.js index 771b64d..af8b9e6 100644 --- a/contract/hardhat.config.js +++ b/contract/hardhat.config.js @@ -2,6 +2,8 @@ require('@typechain/hardhat') require('@nomiclabs/hardhat-ethers') require('@nomiclabs/hardhat-waffle') require('@nomiclabs/hardhat-etherscan') +require('@openzeppelin/hardhat-upgrades') + require('dotenv').config() const privateKey = process.env.PRIVATE_KEY diff --git a/contract/package-lock.json b/contract/package-lock.json index 115d297..acd513d 100644 --- a/contract/package-lock.json +++ b/contract/package-lock.json @@ -1,14 +1,17 @@ { - "name": "hardhat-project", + "name": "diamond-yo", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "hardhat-project", + "name": "diamond-yo", + "license": "MIT", "dependencies": { "@appliedzkp/semaphore-contracts": "^0.10.0", "@nomiclabs/hardhat-etherscan": "^3.1.0", "@openzeppelin/contracts": "^4.7.0", + "@openzeppelin/contracts-upgradeable": "^4.7.0", + "@openzeppelin/hardhat-upgrades": "^1.19.0", "@typechain/hardhat": "^6.1.2", "dotenv": "^16.0.1" }, @@ -1273,7 +1276,6 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.6.tgz", "integrity": "sha512-q2Cjp20IB48rEn2NPjR1qxsIQBvFVYW9rFRCFq+bC4RUrn1Ljz3g4wM8uSlgIBZYBi2JMXxmOzFqHraczxq4Ng==", - "dev": true, "peerDependencies": { "ethers": "^5.0.0", "hardhat": "^2.0.0" @@ -1341,6 +1343,217 @@ "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.7.0.tgz", "integrity": "sha512-52Qb+A1DdOss8QvJrijYYPSf32GUg2pGaG/yCxtaA3cu4jduouTdg4XZSMLW9op54m1jH7J8hoajhHKOPsoJFw==" }, + "node_modules/@openzeppelin/contracts-upgradeable": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.7.0.tgz", + "integrity": "sha512-wO3PyoAaAV/rA77cK8H4c3SbO98QylTjfiFxyvURUZKTFLV180rnAvna1x7/Nxvt0Gqv+jt1sXKC7ygxsq8iCw==" + }, + "node_modules/@openzeppelin/hardhat-upgrades": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.19.0.tgz", + "integrity": "sha512-351QqDO3nZ96g0BO/bQnaTflix4Nw4ELWC/hZ8PwicsuVxRmxN/GZhxPrs62AOdiQdZ+xweawrVXa5knliRd4A==", + "dependencies": { + "@openzeppelin/upgrades-core": "^1.16.0", + "chalk": "^4.1.0", + "proper-lockfile": "^4.1.1" + }, + "bin": { + "migrate-oz-cli-project": "dist/scripts/migrate-oz-cli-project.js" + }, + "peerDependencies": { + "@nomiclabs/hardhat-ethers": "^2.0.0", + "@nomiclabs/hardhat-etherscan": "^3.1.0", + "hardhat": "^2.0.2" + }, + "peerDependenciesMeta": { + "@nomiclabs/harhdat-etherscan": { + "optional": true + } + } + }, + "node_modules/@openzeppelin/hardhat-upgrades/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@openzeppelin/hardhat-upgrades/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@openzeppelin/hardhat-upgrades/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@openzeppelin/hardhat-upgrades/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@openzeppelin/hardhat-upgrades/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@openzeppelin/hardhat-upgrades/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@openzeppelin/upgrades-core": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.16.1.tgz", + "integrity": "sha512-+hejbeAfsZWIQL5Ih13gkdm2KO6kbERc1ektzcyb25/OtUwaRjIIHxW++LdC/3Hg5uzThVOzJBfiLdAbgwD+OA==", + "dependencies": { + "bn.js": "^5.1.2", + "cbor": "^8.0.0", + "chalk": "^4.1.0", + "compare-versions": "^4.0.0", + "debug": "^4.1.1", + "ethereumjs-util": "^7.0.3", + "proper-lockfile": "^4.1.1", + "solidity-ast": "^0.4.15" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/cbor": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "engines": { + "node": ">=12.19" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@resolver-engine/core": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz", @@ -2392,6 +2605,11 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==" }, + "node_modules/compare-versions": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-4.1.3.tgz", + "integrity": "sha512-WQfnbDcrYnGr55UwbxKiQKASnTtNnaAWVi8jZyy8NTpVAXWACSne8lMD1iaIo9AiU6mnuLvSVshCzewVuWxHUg==" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -14118,6 +14336,16 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "dependencies": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + } + }, "node_modules/prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -14366,6 +14594,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "engines": { + "node": ">= 4" + } + }, "node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -14531,6 +14767,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -14638,6 +14879,11 @@ "semver": "bin/semver" } }, + "node_modules/solidity-ast": { + "version": "0.4.35", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.35.tgz", + "integrity": "sha512-F5bTDLh3rmDxRmLSrs3qt3nvxJprWSEkS7h2KmuXDx7XTfJ6ZKVTV1rtPIYCqJAuPsU/qa8YUeFn7jdOAZcTPA==" + }, "node_modules/solidity-comments-extractor": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", @@ -16472,7 +16718,6 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.6.tgz", "integrity": "sha512-q2Cjp20IB48rEn2NPjR1qxsIQBvFVYW9rFRCFq+bC4RUrn1Ljz3g4wM8uSlgIBZYBi2JMXxmOzFqHraczxq4Ng==", - "dev": true, "requires": {} }, "@nomiclabs/hardhat-etherscan": { @@ -16522,6 +16767,152 @@ "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.7.0.tgz", "integrity": "sha512-52Qb+A1DdOss8QvJrijYYPSf32GUg2pGaG/yCxtaA3cu4jduouTdg4XZSMLW9op54m1jH7J8hoajhHKOPsoJFw==" }, + "@openzeppelin/contracts-upgradeable": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.7.0.tgz", + "integrity": "sha512-wO3PyoAaAV/rA77cK8H4c3SbO98QylTjfiFxyvURUZKTFLV180rnAvna1x7/Nxvt0Gqv+jt1sXKC7ygxsq8iCw==" + }, + "@openzeppelin/hardhat-upgrades": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.19.0.tgz", + "integrity": "sha512-351QqDO3nZ96g0BO/bQnaTflix4Nw4ELWC/hZ8PwicsuVxRmxN/GZhxPrs62AOdiQdZ+xweawrVXa5knliRd4A==", + "requires": { + "@openzeppelin/upgrades-core": "^1.16.0", + "chalk": "^4.1.0", + "proper-lockfile": "^4.1.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@openzeppelin/upgrades-core": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.16.1.tgz", + "integrity": "sha512-+hejbeAfsZWIQL5Ih13gkdm2KO6kbERc1ektzcyb25/OtUwaRjIIHxW++LdC/3Hg5uzThVOzJBfiLdAbgwD+OA==", + "requires": { + "bn.js": "^5.1.2", + "cbor": "^8.0.0", + "chalk": "^4.1.0", + "compare-versions": "^4.0.0", + "debug": "^4.1.1", + "ethereumjs-util": "^7.0.3", + "proper-lockfile": "^4.1.1", + "solidity-ast": "^0.4.15" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "cbor": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", + "requires": { + "nofilter": "^3.1.0" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "@resolver-engine/core": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz", @@ -17382,6 +17773,11 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==" }, + "compare-versions": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-4.1.3.tgz", + "integrity": "sha512-WQfnbDcrYnGr55UwbxKiQKASnTtNnaAWVi8jZyy8NTpVAXWACSne8lMD1iaIo9AiU6mnuLvSVshCzewVuWxHUg==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -26380,6 +26776,16 @@ } } }, + "proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "requires": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + } + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -26572,6 +26978,11 @@ "path-parse": "^1.0.6" } }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==" + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -26695,6 +27106,11 @@ "object-inspect": "^1.9.0" } }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -26779,6 +27195,11 @@ } } }, + "solidity-ast": { + "version": "0.4.35", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.35.tgz", + "integrity": "sha512-F5bTDLh3rmDxRmLSrs3qt3nvxJprWSEkS7h2KmuXDx7XTfJ6ZKVTV1rtPIYCqJAuPsU/qa8YUeFn7jdOAZcTPA==" + }, "solidity-comments-extractor": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", diff --git a/contract/package.json b/contract/package.json index 60674a5..c8a2ba1 100644 --- a/contract/package.json +++ b/contract/package.json @@ -1,5 +1,5 @@ { - "name": "hardhat-project", + "name": "diamond-yo", "devDependencies": { "@nomiclabs/hardhat-ethers": "^2.0.6", "@nomiclabs/hardhat-waffle": "^2.0.3", @@ -10,10 +10,14 @@ "prettier": "^2.7.1", "prettier-plugin-solidity": "^1.0.0-dev.22" }, + "author": "Tomosuke Chiba", + "license": "MIT", "dependencies": { "@appliedzkp/semaphore-contracts": "^0.10.0", "@nomiclabs/hardhat-etherscan": "^3.1.0", "@openzeppelin/contracts": "^4.7.0", + "@openzeppelin/contracts-upgradeable": "^4.7.0", + "@openzeppelin/hardhat-upgrades": "^1.19.0", "@typechain/hardhat": "^6.1.2", "dotenv": "^16.0.1" } From c5a0babcc84d9ef4fcc242454f0ba5b24da97a4c Mon Sep 17 00:00:00 2001 From: Tomosuke0930 Date: Tue, 26 Jul 2022 17:21:53 +0900 Subject: [PATCH 2/4] add: Groups and Commitment --- contract/contracts/facets/Commitment.sol | 74 ++++++++++++++++++++++++ contract/contracts/facets/Group.sol | 47 +++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 contract/contracts/facets/Commitment.sol create mode 100644 contract/contracts/facets/Group.sol diff --git a/contract/contracts/facets/Commitment.sol b/contract/contracts/facets/Commitment.sol new file mode 100644 index 0000000..6a0f7d1 --- /dev/null +++ b/contract/contracts/facets/Commitment.sol @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.4; + +import '../interface/ICommitment.sol'; +import {AppStorage} from "../libraries/LibAppStorage.sol"; + + +contract Commitment is ICommitment { + + AppStorage internal s; + + /************************************************ + * Getters + ***********************************************/ + + // commitment is so long + // commitments => coms + + /// get user's commitment length + function getComsLength(address _address) public view returns (uint256 length) { + length = s.userCommitments[_address].length; + } + + /// get user's all commitments + function getAllComs(address _address) public view returns (Commitment[] memory commitments) { + uint256 length = getComsLength(_address); + for (uint256 i = 0; i < length; i++) { + commitments[i] = s.userCommitments[_address][i]; + } + } + + /// get target commitment + function getTargetCom(address _address, uint256 _id) private view returns (Commitment memory commitment) { + uint256 length = getComsLength(_address); + Commitment[] memory commtiments = getAllComs(_address); + uint256 targetIndex; + for (uint256 i = 0; i < length; i++) { + if (commtiments[i].id == _id) targetIndex = i; + } + commitment = s.userCommitments[_address][targetIndex]; + } + + /************************************************ + * Add + ***********************************************/ + + /// add commitment + function addCom( + address _address, + uint256 _id, + bytes32 _data, + uint256 _groupId, + string calldata _userId, + uint256 _createdAt + ) external { + s.userCommitments[_address].push(Commitment(_id, _userId, _groupId, _data, '', address(0), _createdAt)); + } + + /************************************************ + * Update + ***********************************************/ + + /// update commitment + function updateCom( + string calldata _metadta, + address _mintAddress, + address _address, + uint256 _id + ) external view { + Commitment memory commitment = getTargetCom(_address, _id); + commitment.metadata = _metadta; + commitment.mintAddress = _mintAddress; + } +} diff --git a/contract/contracts/facets/Group.sol b/contract/contracts/facets/Group.sol new file mode 100644 index 0000000..010c314 --- /dev/null +++ b/contract/contracts/facets/Group.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.4; +import '../interface/IGroup.sol'; +import {AppStorage} from "../libraries/LibAppStorage.sol"; + + +contract Group is IGroup { + /************************************************ + * Variable and Constraint + ***********************************************/ + + // uint256 public constant s.groups.length = 49; + // Group[size] public groups; + // uint256[size] public groupIds; + // uint256[size] public groupNullfiers; + AppStorage internal s; + + + /************************************************ + * Initialization + ***********************************************/ + + function initialGroups(Group[s.groups.length] calldata _groups) external { + for (uint256 i = 0; i < s.groups.length; i++) { + s.groups[i] = _groups[i]; + s.groupIds[i] = _groups[i].id; + s.groupNullfiers[i] = _groups[i].nullfier; + } + } + + /************************************************ + * Getters + ***********************************************/ + + function getGroups() external view returns (Group[49] memory _groups) { + _groups = groups; + } + + /// get "group" from _id + function getGroup(uint256 _id) external view returns (Group memory group) { + uint256 idsIndex; + for (uint256 i = 0; i < s.groups.length; i++) { + if (_id == groupIds[i]) idsIndex = i; + } + group = s.groups[idsIndex]; + } +} From 3ec36fa45c0b9a59a80a9cdd5a89bdeb6118850c Mon Sep 17 00:00:00 2001 From: Tomosuke0930 Date: Tue, 26 Jul 2022 17:22:22 +0900 Subject: [PATCH 3/4] add DiamondCut --- contract/contracts/facets/DiamondCutFacet.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contract/contracts/facets/DiamondCutFacet.sol b/contract/contracts/facets/DiamondCutFacet.sol index 343e066..bd7b0ad 100644 --- a/contract/contracts/facets/DiamondCutFacet.sol +++ b/contract/contracts/facets/DiamondCutFacet.sol @@ -8,7 +8,7 @@ pragma solidity ^0.8.0; import {IDiamondCut} from "../interfaces/IDiamondCut.sol"; import {LibDiamond} from "../libraries/LibDiamond.sol"; -え + contract DiamondCutFacet is IDiamondCut { function diamondCut( FacetCut[] calldata _diamondCut, From dd2e9aa94a076bac76c3afe88d63a7b554548ce6 Mon Sep 17 00:00:00 2001 From: Tomosuke0930 Date: Tue, 26 Jul 2022 17:24:26 +0900 Subject: [PATCH 4/4] fix: move some files to archive --- contract/contracts/{ => facets/archive}/Commitment.sol | 0 contract/contracts/{ => facets/archive}/Group.sol | 0 contract/contracts/{ => facets/archive}/MerkleTree.sol | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename contract/contracts/{ => facets/archive}/Commitment.sol (100%) rename contract/contracts/{ => facets/archive}/Group.sol (100%) rename contract/contracts/{ => facets/archive}/MerkleTree.sol (100%) diff --git a/contract/contracts/Commitment.sol b/contract/contracts/facets/archive/Commitment.sol similarity index 100% rename from contract/contracts/Commitment.sol rename to contract/contracts/facets/archive/Commitment.sol diff --git a/contract/contracts/Group.sol b/contract/contracts/facets/archive/Group.sol similarity index 100% rename from contract/contracts/Group.sol rename to contract/contracts/facets/archive/Group.sol diff --git a/contract/contracts/MerkleTree.sol b/contract/contracts/facets/archive/MerkleTree.sol similarity index 100% rename from contract/contracts/MerkleTree.sol rename to contract/contracts/facets/archive/MerkleTree.sol