Skip to content

Commit

Permalink
feat: add modularized contract (#223)
Browse files Browse the repository at this point in the history
* fix: fix ERC5727Example code size

* fix: remove package_lock.json

* feat: add core contract test

* feat: add ERC5727Delegate test

* feat: test Expirable & Claimable

* fix: onlyManger Expirable

* fix: fix vairable name

* fix: fix typo; format test title; fix merkle node inputs

* feat: add test ERC5727Enumerable

* feat: update ERC5727Governance test

* feat: update test

* feat: update test

* fix: fix ERC5727Recovery

* feat: add query methods; prevent duplicated sbt

* chore(release): 0.2.1-alpha.1

* fix: set organization

* feat: add support interface test

* fix: fix ERC5727Recovery and ERC721Enumerable bug

* feat: update test

* feat: update test

* fix: fix _beforeValueTransfer

* feat: remove access control

* fix: fix erc3525 spendAllowance

* feat: update test

* fix: update lockfile

* fix: fix lockfile

* fix: update lockfile

* fix: update lockfile

* feat: add diamond proxy

* feat: add modularized test

* feat: add erc721 storage

* feat: add erc3525 storage

* feat: add erc5727 storage && fix interfaces

* feat: update diamond test

* feat: add erc5727 facet test

* fix: fix erc5727 storage

* feat: add erc721 core

* feat: add erc3525 core

* feat: update erc5727 core

* feat: add claimable test

* feat: add enumerable & recovery facet

* fix: fix recovery interface

* feat: add governance facet

* chore: file directory structure

* feat: add expirable & delegate facet

* feat: change revoke

* feat: add multi init

* feat: add delegate test

* feat: add deploy script & readme

* feat: change revoke

* fix: fix solidity ci & test

* fix: fix test coverage

* fix: fix test coverage

* fix: fix test coverage

* fix: fix test coverage

* fix: fix test coverage

* feat: add base uri

* feat: add factory contract

* feat: update deploy script

---------

Co-authored-by: Austin Zhu <[email protected]>
  • Loading branch information
beyond009 and AustinZhu authored May 12, 2023
1 parent 85ed7af commit d5bc3d1
Show file tree
Hide file tree
Showing 91 changed files with 13,779 additions and 1,655 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/solidity-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ jobs:
- name: Compile
run: pnpm run compile

- name: Compile modularized
run: pnpm run compile:modularized

test:
runs-on: ubuntu-latest
needs: [compile]
Expand Down
160 changes: 160 additions & 0 deletions contracts-modularized/EIP712/EIP712Upgradeable.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/EIP712.sol)

pragma solidity ^0.8.0;

import "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol";
import "../utils/Initializable.sol";

/**
* @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
*
* The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
* thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
* they need in their contracts using a combination of `abi.encode` and `keccak256`.
*
* This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
* scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
* ({_hashTypedDataV4}).
*
* The implementation of the domain separator was designed to be as efficient as possible while still properly updating
* the chain id to protect against replay attacks on an eventual fork of the chain.
*
* NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
* https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
*
* _Available since v3.4._
*
* @custom:storage-size 52
*/

bytes32 constant EIP712_POSITION = keccak256("diamond.eip712.storage");

struct EIP712Struct {
bytes32 _HASHED_NAME;
bytes32 _HASHED_VERSION;
}

function eip712ds() pure returns (EIP712Struct storage eip712Struct) {
bytes32 position = EIP712_POSITION;
assembly {
eip712Struct.slot := position
}
}

abstract contract EIP712Upgradeable is Initializable {
/* solhint-disable var-name-mixedcase */
bytes32 private constant _TYPE_HASH =
keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
);

/* solhint-enable var-name-mixedcase */

/**
* @dev Initializes the domain separator and parameter caches.
*
* The meaning of `name` and `version` is specified in
* https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
*
* - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
* - `version`: the current major version of the signing domain.
*
* NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
* contract upgrade].
*/
function __EIP712_init(
string memory name,
string memory version
) internal onlyInitializing {
__EIP712_init_unchained(name, version);
}

function __EIP712_init_unchained(
string memory name,
string memory version
) internal onlyInitializing {
bytes32 hashedName = keccak256(bytes(name));
bytes32 hashedVersion = keccak256(bytes(version));
eip712ds()._HASHED_NAME = hashedName;
eip712ds()._HASHED_VERSION = hashedVersion;
}

/**
* @dev Returns the domain separator for the current chain.
*/
function _domainSeparatorV4() internal view returns (bytes32) {
return
_buildDomainSeparator(
_TYPE_HASH,
_EIP712NameHash(),
_EIP712VersionHash()
);
}

function _buildDomainSeparator(
bytes32 typeHash,
bytes32 nameHash,
bytes32 versionHash
) private view returns (bytes32) {
return
keccak256(
abi.encode(
typeHash,
nameHash,
versionHash,
block.chainid,
address(this)
)
);
}

/**
* @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
* function returns the hash of the fully encoded EIP712 message for this domain.
*
* This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
*
* ```solidity
* bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
* keccak256("Mail(address to,string contents)"),
* mailTo,
* keccak256(bytes(mailContents))
* )));
* address signer = ECDSA.recover(digest, signature);
* ```
*/
function _hashTypedDataV4(
bytes32 structHash
) internal view virtual returns (bytes32) {
return
ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);
}

/**
* @dev The hash of the name parameter for the EIP712 domain.
*
* NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
* are a concern.
*/
function _EIP712NameHash() internal view virtual returns (bytes32) {
return eip712ds()._HASHED_NAME;
}

/**
* @dev The hash of the version parameter for the EIP712 domain.
*
* NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
* are a concern.
*/
function _EIP712VersionHash() internal view virtual returns (bytes32) {
return eip712ds()._HASHED_VERSION;
}

/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}
39 changes: 39 additions & 0 deletions contracts-modularized/ERC165/ERC165UpgradeableDS.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol";
import "../utils/Initializable.sol";

/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(
bytes4 interfaceId
) public view virtual override returns (bool) {
return interfaceId == type(IERC165Upgradeable).interfaceId;
}

/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}
16 changes: 16 additions & 0 deletions contracts-modularized/ERC173/ERC173Upgradeable.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {LibDiamond} from "../diamond/libraries/LibDiamond.sol";
import {IERC173} from "./interfaces/IERC173.sol";

contract ERC173Upgradeable is IERC173 {
function transferOwnership(address _newOwner) public override {
LibDiamond.enforceIsContractOwner();
LibDiamond.setContractOwner(_newOwner);
}

function owner() public view override returns (address owner_) {
owner_ = LibDiamond.contractOwner();
}
}
22 changes: 22 additions & 0 deletions contracts-modularized/ERC173/interfaces/IERC173.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @title ERC-173 Contract Ownership Standard
/// Note: the ERC-165 identifier for this interface is 0x7f5828d0
/* is ERC165 */
interface IERC173 {
/// @dev This emits when ownership of a contract changes.
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);

/// @notice Get the address of the owner
/// @return owner_ The address of the owner.
function owner() external view returns (address owner_);

/// @notice Set the address of the new owner of the contract
/// @dev Set _newOwner to address(0) to renounce any ownership.
/// @param _newOwner The address of the new owner of the contract
function transferOwnership(address _newOwner) external;
}
Loading

0 comments on commit d5bc3d1

Please sign in to comment.