generated from citydaoproject/contracts-template
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from citydaoproject/issue1
Merge initial issue1 changes into main
- Loading branch information
Showing
30 changed files
with
1,222 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# CHANGEME | ||
# Parcel Contracts | ||
|
||
## Setup | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
|
||
pragma solidity ^0.8.9; | ||
|
||
import '@gnus.ai/contracts-upgradeable-diamond/access/AccessControlUpgradeable.sol'; | ||
import '@gnus.ai/contracts-upgradeable-diamond/proxy/utils/UUPSUpgradeable.sol'; | ||
import '@gnus.ai/contracts-upgradeable-diamond/security/PausableUpgradeable.sol'; | ||
import '@gnus.ai/contracts-upgradeable-diamond/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol'; | ||
import '@gnus.ai/contracts-upgradeable-diamond/token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol'; | ||
import './ParcelNFTStorage.sol'; | ||
import './common/RoyaltyEventSupport.sol'; | ||
import './Roles.sol'; | ||
|
||
contract ParcelNFT is | ||
UUPSUpgradeable, | ||
ERC721URIStorageUpgradeable, | ||
RoyaltyEventSupport, | ||
ERC721RoyaltyUpgradeable, | ||
AccessControlUpgradeable, | ||
PausableUpgradeable | ||
{ | ||
struct InitParams { | ||
string name; | ||
string symbol; | ||
address superAdmin; | ||
} | ||
|
||
function initialize(InitParams memory initParams) public initializer { | ||
__ERC721_init(initParams.name, initParams.symbol); | ||
__ERC721URIStorage_init_unchained(); | ||
__ERC2981_init_unchained(); | ||
__ERC721Royalty_init_unchained(); | ||
__AccessControl_init_unchained(); | ||
__Pausable_init_unchained(); | ||
|
||
if (initParams.superAdmin == address(0)) { | ||
initParams.superAdmin = _msgSender(); | ||
} | ||
_setupRole(Roles.SUPER_ADMIN, initParams.superAdmin); | ||
} | ||
|
||
// todo: temporary until minting is supported | ||
function mint(uint256 tokenId) external onlyRole(Roles.PARCEL_MANAGER) { | ||
_safeMint(_msgSender(), tokenId); | ||
} | ||
|
||
function supportsInterface(bytes4 interfaceId) | ||
public | ||
view | ||
virtual | ||
override(AccessControlUpgradeable, ERC721RoyaltyUpgradeable, ERC721Upgradeable, ERC2981Upgradeable) | ||
returns (bool) | ||
{ | ||
return super.supportsInterface(interfaceId); | ||
} | ||
|
||
/** | ||
* @notice Sets `baseURI` as the base URI for all tokens. Used when explicit tokenURI not set. | ||
*/ | ||
function setBaseURI(string calldata baseURI) external onlyRole(Roles.PARCEL_MANAGER) { | ||
ParcelNFTStorage.setBaseURI(baseURI); | ||
} | ||
|
||
function _baseURI() internal view virtual override returns (string memory) { | ||
return ParcelNFTStorage.baseURI(); | ||
} | ||
|
||
/** | ||
* @dev See {IERC721Metadata-tokenURI}. | ||
*/ | ||
function tokenURI(uint256 tokenId) | ||
public | ||
view | ||
virtual | ||
override(ERC721URIStorageUpgradeable, ERC721Upgradeable) | ||
returns (string memory) | ||
{ | ||
return super.tokenURI(tokenId); | ||
} | ||
|
||
/** | ||
* @notice Sets `_tokenURI` as the tokenURI of `tokenId`. | ||
* | ||
* Requirements: | ||
* | ||
* - `tokenId` must exist. | ||
*/ | ||
function setTokenURI(uint256 tokenId, string memory _tokenURI) external onlyRole(Roles.PARCEL_MANAGER) { | ||
_setTokenURI(tokenId, _tokenURI); | ||
} | ||
|
||
/** | ||
* @notice Sets the royalty information that all ids in this contract will default to. | ||
* | ||
* Requirements: | ||
* | ||
* - `receiver` cannot be the zero address. | ||
* - `feeNumerator` cannot be greater than the fee denominator. | ||
*/ | ||
function setDefaultRoyalty(address receiver, uint96 feeNumerator) external onlyRole(Roles.PARCEL_MANAGER) { | ||
_setDefaultRoyalty(receiver, feeNumerator); | ||
} | ||
|
||
/** | ||
* @inheritdoc ERC2981Upgradeable | ||
*/ | ||
function _setDefaultRoyalty(address receiver, uint96 feeNumerator) | ||
internal | ||
virtual | ||
override(RoyaltyEventSupport, ERC2981Upgradeable) | ||
{ | ||
super._setDefaultRoyalty(receiver, feeNumerator); | ||
} | ||
|
||
/** | ||
* @notice Removes default royalty information. | ||
*/ | ||
function deleteDefaultRoyalty() external onlyRole(Roles.PARCEL_MANAGER) { | ||
_deleteDefaultRoyalty(); | ||
} | ||
|
||
/** | ||
* @inheritdoc ERC2981Upgradeable | ||
*/ | ||
function _deleteDefaultRoyalty() internal virtual override(RoyaltyEventSupport, ERC2981Upgradeable) { | ||
super._deleteDefaultRoyalty(); | ||
} | ||
|
||
/** | ||
* @notice Sets the royalty information for a specific token id, overriding the global default. | ||
* | ||
* Requirements: | ||
* | ||
* - `tokenId` must be already minted. | ||
* - `receiver` cannot be the zero address. | ||
* - `feeNumerator` cannot be greater than the fee denominator. | ||
*/ | ||
function setTokenRoyalty( | ||
uint256 tokenId, | ||
address receiver, | ||
uint96 feeNumerator | ||
) external onlyRole(Roles.PARCEL_MANAGER) { | ||
_setTokenRoyalty(tokenId, receiver, feeNumerator); | ||
} | ||
|
||
/** | ||
* @inheritdoc ERC2981Upgradeable | ||
*/ | ||
function _setTokenRoyalty( | ||
uint256 tokenId, | ||
address receiver, | ||
uint96 feeNumerator | ||
) internal virtual override(RoyaltyEventSupport, ERC2981Upgradeable) { | ||
super._setTokenRoyalty(tokenId, receiver, feeNumerator); | ||
} | ||
|
||
/** | ||
* @notice Resets royalty information for the token id back to the global default. | ||
*/ | ||
function resetTokenRoyalty(uint256 tokenId) external onlyRole(Roles.PARCEL_MANAGER) { | ||
_resetTokenRoyalty(tokenId); | ||
} | ||
|
||
/** | ||
* @inheritdoc ERC2981Upgradeable | ||
*/ | ||
function _resetTokenRoyalty(uint256 tokenId) internal virtual override(RoyaltyEventSupport, ERC2981Upgradeable) { | ||
super._resetTokenRoyalty(tokenId); | ||
} | ||
|
||
/** | ||
* @notice Triggers stopped state. | ||
* | ||
* Requirements: | ||
* | ||
* - The contract must not be paused. | ||
*/ | ||
function pause() external onlyRole(Roles.PAUSER) { | ||
_pause(); | ||
} | ||
|
||
/** | ||
* @notice Returns to normal state. | ||
* | ||
* Requirements: | ||
* | ||
* - The contract must be paused. | ||
*/ | ||
function unpause() external onlyRole(Roles.PAUSER) { | ||
_unpause(); | ||
} | ||
|
||
function _burn(uint256 tokenId) internal virtual override(ERC721URIStorageUpgradeable, ERC721RoyaltyUpgradeable) { | ||
super._burn(tokenId); | ||
} | ||
|
||
// solhint-disable-next-line no-empty-blocks | ||
function _authorizeUpgrade(address newImplementation) internal virtual override onlyRole(Roles.UPGRADER) {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
|
||
pragma solidity ^0.8.9; | ||
|
||
library ParcelNFTStorage { | ||
struct Layout { | ||
// storage for base URI | ||
string baseURI; | ||
} | ||
|
||
bytes32 internal constant STORAGE_SLOT = keccak256('citydao.contracts.storage.ParcelNFT'); | ||
|
||
//noinspection NoReturn | ||
function layout() internal pure returns (Layout storage _layout) { | ||
bytes32 slot = STORAGE_SLOT; | ||
// solhint-disable-next-line no-inline-assembly | ||
assembly { | ||
_layout.slot := slot | ||
} | ||
} | ||
|
||
function baseURI() internal view returns (string memory) { | ||
return layout().baseURI; | ||
} | ||
|
||
function setBaseURI(string memory _baseURI) internal { | ||
layout().baseURI = _baseURI; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
|
||
pragma solidity ^0.8.9; | ||
|
||
library Roles { | ||
bytes32 public constant SUPER_ADMIN = 0x00; | ||
bytes32 public constant PARCEL_MANAGER = keccak256('citydao.ParcelManager'); | ||
bytes32 public constant PAUSER = keccak256('citydao.Pauser'); | ||
bytes32 public constant UPGRADER = keccak256('citydao.Upgrader'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// SPDX-License-Identifier: GPL-3.0-only | ||
|
||
pragma solidity ^0.8.9; | ||
|
||
import '@gnus.ai/contracts-upgradeable-diamond/token/common/ERC2981Upgradeable.sol'; | ||
|
||
abstract contract RoyaltyEventSupport is ERC2981Upgradeable { | ||
/** | ||
* @dev Emitted when the default royalty is updated. | ||
*/ | ||
event DefaultRoyaltyChanged(address indexed receiver, uint96 indexed feeNumerator); | ||
|
||
/** | ||
* @dev Emitted when a token royalty is updated. | ||
*/ | ||
event TokenRoyaltyChanged(uint256 indexed tokenId, address indexed receiver, uint96 indexed feeNumerator); | ||
|
||
/** | ||
* @inheritdoc ERC2981Upgradeable | ||
*/ | ||
function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual override { | ||
super._setDefaultRoyalty(receiver, feeNumerator); | ||
emit DefaultRoyaltyChanged(receiver, feeNumerator); | ||
} | ||
|
||
/** | ||
* @inheritdoc ERC2981Upgradeable | ||
*/ | ||
function _deleteDefaultRoyalty() internal virtual override { | ||
super._deleteDefaultRoyalty(); | ||
emit DefaultRoyaltyChanged(address(0), 0); | ||
} | ||
|
||
/** | ||
* @inheritdoc ERC2981Upgradeable | ||
*/ | ||
function _setTokenRoyalty( | ||
uint256 tokenId, | ||
address receiver, | ||
uint96 feeNumerator | ||
) internal virtual override { | ||
super._setTokenRoyalty(tokenId, receiver, feeNumerator); | ||
emit TokenRoyaltyChanged(tokenId, receiver, feeNumerator); | ||
} | ||
|
||
/** | ||
* @inheritdoc ERC2981Upgradeable | ||
*/ | ||
function _resetTokenRoyalty(uint256 tokenId) internal virtual override { | ||
super._resetTokenRoyalty(tokenId); | ||
emit TokenRoyaltyChanged(tokenId, address(0), 0); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// SPDX-License-Identifier: GPL-3.0-only | ||
|
||
pragma solidity ^0.8.9; | ||
|
||
import '@gnus.ai/contracts-upgradeable-diamond/access/IAccessControlUpgradeable.sol'; | ||
import '@gnus.ai/contracts-upgradeable-diamond/interfaces/IERC2981Upgradeable.sol'; | ||
import '@gnus.ai/contracts-upgradeable-diamond/token/ERC721/IERC721Upgradeable.sol'; | ||
import '@gnus.ai/contracts-upgradeable-diamond/token/ERC721/extensions/IERC721MetadataUpgradeable.sol'; | ||
|
||
library ERC165IdCalc { | ||
function calcAccessControlInterfaceId() external pure returns (bytes4) { | ||
return type(IAccessControlUpgradeable).interfaceId; | ||
} | ||
|
||
function calcERC2981InterfaceId() external pure returns (bytes4) { | ||
return type(IERC2981Upgradeable).interfaceId; | ||
} | ||
|
||
function calcERC721InterfaceId() external pure returns (bytes4) { | ||
return type(IERC721Upgradeable).interfaceId; | ||
} | ||
|
||
function calcERC721MetadataInterfaceId() external pure returns (bytes4) { | ||
return type(IERC721MetadataUpgradeable).interfaceId; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.