Skip to content

Commit

Permalink
add erc-7765 reference
Browse files Browse the repository at this point in the history
  • Loading branch information
frank authored and frankmint2024 committed Oct 28, 2024
1 parent a74c8e1 commit be529ee
Show file tree
Hide file tree
Showing 596 changed files with 88,497 additions and 1 deletion.
2 changes: 1 addition & 1 deletion ERCS/erc-7765.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ This standard is an extension of ERC-721. It is fully compatible with both of th

## Reference Implementation

The reference implementation of Privileged NFTs can be found at the repository named EIP-7765-example under the organization of Mint-Blockchain on github.
The reference implementation of Privileged NFTs can be found [Here](../assets/erc-7765/contracts/ERC7765Example.sol).

## Security Considerations

Expand Down
112 changes: 112 additions & 0 deletions assets/erc-7765/contracts/ERC7765Example.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.7.0 <0.9.0;

import "../lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol";
import "../lib/openzeppelin-contracts/contracts/utils/Strings.sol";
import "../lib/openzeppelin-contracts/contracts/utils/Base64.sol";
import "./interfaces/IERC7765.sol";
import "./interfaces/IERC7765Metadata.sol";

contract ERC7765Example is ERC721, IERC7765, IERC7765Metadata {
uint256[] private privilegeIdsArr = [1, 2];
mapping(uint256 privilegeId => bool) private privilegeIds;

mapping(uint256 tokenId => mapping(uint256 privilegeId => address to)) privilegeStates;

constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {
privilegeIds[1] = true;
privilegeIds[2] = true;
}

/// @notice This function exercised a specific privilege of a token if succeeds.
/// @dev Throws if `_privilegeId` is not a valid privilegeId.
/// @param _to the address to benifit from the privilege.
/// @param _tokenId the NFT tokenID.
/// @param _privilegeId the ID of the privileges.
/// @param _data extra data passed in for extra message or future extension.
function exercisePrivilege(address _to, uint256 _tokenId, uint256 _privilegeId, bytes calldata _data) external {
if (_to == address(0)) {
_to = msg.sender;
}

require(ownerOf(_tokenId) == msg.sender, "Token not exist");
require(privilegeIds[_privilegeId], "Privilege not exist");
require(privilegeStates[_tokenId][_privilegeId] == address(0), "Privilege already exercised");

// Optional to deal with _data
dealWithData(_data);

privilegeStates[_tokenId][_privilegeId] = _to;
emit PrivilegeExercised(msg.sender, _to, _tokenId, _privilegeId);
}

function dealWithData(bytes calldata _data) internal {
//
}

/// @notice This function is to check whether a specific privilege of a token can be exercised.
/// @dev Throws if `_privilegeId` is not a valid privilegeId.
/// @param _to the address to benifit from the privilege.
/// @param _tokenId the NFT tokenID.
/// @param _privilegeId the ID of the privileges.
function isExercisable(address _to, uint256 _tokenId, uint256 _privilegeId)
external
view
returns (bool _exercisable)
{
require(_to != address(0), "Illegal _to address");
require(ownerOf(_tokenId) != address(0), "Token not exist");
require(privilegeIds[_privilegeId], "Privilege not exist");

return privilegeStates[_tokenId][_privilegeId] == address(0);
}

/// @notice This function is to check whether a specific privilege of a token has been exercised.
/// @dev Throws if `_privilegeId` is not a valid privilegeId.
/// @param _to the address to benifit from the privilege.
/// @param _tokenId the NFT tokenID.
/// @param _privilegeId the ID of the privileges.
function isExercised(address _to, uint256 _tokenId, uint256 _privilegeId) external view returns (bool _exercised) {
require(_to != address(0), "Illegal _to address");
require(ownerOf(_tokenId) != address(0), "Token not exist");
require(privilegeIds[_privilegeId], "Privilege not exist");

return privilegeStates[_tokenId][_privilegeId] == _to;
}

/// @notice This function is to list all privilegeIds of a token.
/// @param _tokenId the NFT tokenID.
function getPrivilegeIds(uint256 _tokenId) external view returns (uint256[] memory) {
require(ownerOf(_tokenId) != address(0), "Token not exist");
return privilegeIdsArr;
}

/// @notice A distinct Uniform Resource Identifier (URI) for a given privilegeId.
/// @dev Throws if `_privilegeId` is not a valid privilegeId. URIs are defined in RFC
/// 3986. The URI may point to a JSON file that conforms to the "ERC-7765
/// Metadata JSON Schema".
function privilegeURI(uint256 _privilegeId) external view returns (string memory) {
require(privilegeIds[_privilegeId], "Privilege not exist");

return string(
abi.encodePacked("data:application/json;base64,", Base64.encode(bytes(privilegeURIJSON(_privilegeId))))
);
}

function privilegeURIJSON(uint256 _privilegeId) internal pure returns (string memory) {
return string(
abi.encodePacked(
"{",
'"name": "Privilege #',
Strings.toString(_privilegeId),
'",',
'"description": "description -',
Strings.toString(_privilegeId),
'",',
'"resource": "ipfs://abc/',
Strings.toString(_privilegeId),
'"}'
)
);
}
}
44 changes: 44 additions & 0 deletions assets/erc-7765/contracts/interfaces/IERC7765.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.7.0 <0.9.0;

/// @title ERC-7765 Privileged Non-Fungible Tokens Tied To Real World Assets
/// @dev See https://eips.ethereum.org/EIPS/eip-7765
interface IERC7765 /* is IERC721, IERC165 */ {
/// @notice This event emitted when a specific privilege of a token is successfully exercised.
/// @param _operator the address who exercised the privilege.
/// @param _to the address to benefit from the privilege.
/// @param _tokenId the NFT tokenID.
/// @param _privilegeId the ID of the privileges.
event PrivilegeExercised(
address indexed _operator, address indexed _to, uint256 indexed _tokenId, uint256 _privilegeId
);

/// @notice This function exercise a specific privilege of a token.
/// @dev Throws if `_privilegeId` is not a valid privilegeId.
/// @param _to the address to benefit from the privilege.
/// @param _tokenId the NFT tokenID.
/// @param _privilegeId the ID of the privileges.
/// @param _data extra data passed in for extra message or future extension.
function exercisePrivilege(address _to, uint256 _tokenId, uint256 _privilegeId, bytes calldata _data) external;

/// @notice This function is to check whether a specific privilege of a token can be exercised.
/// @dev Throws if `_privilegeId` is not a valid privilegeId.
/// @param _to the address to benefit from the privilege.
/// @param _tokenId the NFT tokenID.
/// @param _privilegeId the ID of the privileges.
function isExercisable(address _to, uint256 _tokenId, uint256 _privilegeId)
external
view
returns (bool _exercisable);

/// @notice This function is to check whether a specific privilege of a token has been exercised.
/// @dev Throws if `_privilegeId` is not a valid privilegeId.
/// @param _to the address to benefit from the privilege.
/// @param _tokenId the NFT tokenID.
/// @param _privilegeId the ID of the privileges.
function isExercised(address _to, uint256 _tokenId, uint256 _privilegeId) external view returns (bool _exercised);

/// @notice This function is to list all privilegeIds of a token.
/// @param _tokenId the NFT tokenID.
function getPrivilegeIds(uint256 _tokenId) external view returns (uint256[] memory privilegeIds);
}
12 changes: 12 additions & 0 deletions assets/erc-7765/contracts/interfaces/IERC7765Metadata.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.7.0 <0.9.0;

/// @title ERC-7765 Privileged Non-Fungible Tokens Tied To Real World Assets, optional metadata extension
/// @dev See https://eips.ethereum.org/EIPS/eip-7765
interface IERC7765Metadata /* is IERC7765 */ {
/// @notice A distinct Uniform Resource Identifier (URI) for a given privilegeId.
/// @dev Throws if `_privilegeId` is not a valid privilegeId. URIs are defined in RFC
/// 3986. The URI may point to a JSON file that conforms to the "ERC-7765
/// Metadata JSON Schema".
function privilegeURI(uint256 _privilegeId) external view returns (string memory);
}
12 changes: 12 additions & 0 deletions assets/erc-7765/lib/openzeppelin-contracts/.changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"$schema": "https://unpkg.com/@changesets/[email protected]/schema.json",
"changelog": [
"@changesets/changelog-github",
{
"repo": "OpenZeppelin/openzeppelin-contracts"
}
],
"commit": false,
"access": "public",
"baseBranch": "master"
}
12 changes: 12 additions & 0 deletions assets/erc-7765/lib/openzeppelin-contracts/.codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
comment: off
github_checks:
annotations: false
coverage:
status:
patch:
default:
target: 95%
only_pulls: true
project:
default:
threshold: 1%
21 changes: 21 additions & 0 deletions assets/erc-7765/lib/openzeppelin-contracts/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

[*]
charset = utf-8
end_of_line = lf
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = false
max_line_length = 120

[*.sol]
indent_size = 4

[*.js]
indent_size = 2

[*.{adoc,md}]
max_line_length = 0
20 changes: 20 additions & 0 deletions assets/erc-7765/lib/openzeppelin-contracts/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"root": true,
"extends" : [
"eslint:recommended",
"prettier",
],
"env": {
"es2022": true,
"browser": true,
"node": true,
"mocha": true,
},
"globals" : {
"artifacts": "readonly",
"contract": "readonly",
"web3": "readonly",
"extendEnvironment": "readonly",
"expect": "readonly",
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
name: Bug report
about: Report a bug in OpenZeppelin Contracts

---

<!-- Briefly describe the issue you're experiencing. Tell us what you were trying to do and what happened instead. -->

<!-- Remember, this is not a place to ask for help debugging code. For that, we welcome you in the OpenZeppelin Community Forum: https://forum.openzeppelin.com/. -->

**💻 Environment**

<!-- Tell us what version of OpenZeppelin Contracts you're using, and how you're using it: Truffle, Remix, etc. -->

**📝 Details**

<!-- Describe the problem you have been experiencing in more detail. Include as much information as you think is relevant. Keep in mind that transactions can fail for many reasons; context is key here. -->

**🔢 Code to reproduce bug**

<!-- We will be able to better help if you provide a minimal example that triggers the bug. -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
contact_links:
- name: Questions & Support Requests
url: https://forum.openzeppelin.com/c/support/contracts/18
about: Ask in the OpenZeppelin Forum
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
name: Feature request
about: Suggest an idea for OpenZeppelin Contracts

---

**🧐 Motivation**
<!-- Is your feature request related to a specific problem? Is it just a crazy idea? Tell us about it! -->

**📝 Details**
<!-- Please describe your feature request in detail. -->

<!-- Make sure that you have reviewed the OpenZeppelin Contracts Contributor Guidelines. -->
<!-- https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/CONTRIBUTING.md -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!-- Thank you for your interest in contributing to OpenZeppelin! -->

<!-- Consider opening an issue for discussion prior to submitting a PR. -->
<!-- New features will be merged faster if they were first discussed and designed with the team. -->

Fixes #???? <!-- Fill in with issue number -->

<!-- Describe the changes introduced in this pull request. -->
<!-- Include any context necessary for understanding the PR's purpose. -->


#### PR Checklist

<!-- Before merging the pull request all of the following must be complete. -->
<!-- Feel free to submit a PR or Draft PR even if some items are pending. -->
<!-- Some of the items may not apply. -->

- [ ] Tests
- [ ] Documentation
- [ ] Changeset entry (run `npx changeset add`)
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Compare gas costs
inputs:
token:
description: github token
required: true
report:
description: report to read from
required: false
default: gasReporterOutput.json
out_report:
description: report to read
required: false
default: ${{ github.ref_name }}.gasreport.json
ref_report:
description: report to read from
required: false
default: ${{ github.base_ref }}.gasreport.json

runs:
using: composite
steps:
- name: Download reference report
if: github.event_name == 'pull_request'
run: |
RUN_ID=`gh run list --repo ${{ github.repository }} --branch ${{ github.base_ref }} --workflow ${{ github.workflow }} --limit 100 --json 'conclusion,databaseId,event' --jq 'map(select(.conclusion=="success" and .event!="pull_request"))[0].databaseId'`
gh run download ${RUN_ID} --repo ${{ github.repository }} -n gasreport
env:
GITHUB_TOKEN: ${{ inputs.token }}
shell: bash
continue-on-error: true
id: reference
- name: Compare reports
if: steps.reference.outcome == 'success' && github.event_name == 'pull_request'
run: |
node scripts/checks/compareGasReports.js ${{ inputs.report }} ${{ inputs.ref_report }} >> $GITHUB_STEP_SUMMARY
env:
STYLE: markdown
shell: bash
- name: Rename report for upload
if: github.event_name != 'pull_request'
run: |
mv ${{ inputs.report }} ${{ inputs.out_report }}
shell: bash
- name: Save report
if: github.event_name != 'pull_request'
uses: actions/upload-artifact@v3
with:
name: gasreport
path: ${{ inputs.out_report }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Setup

runs:
using: composite
steps:
- uses: actions/setup-node@v3
with:
node-version: 16.x
- uses: actions/cache@v3
id: cache
with:
path: '**/node_modules'
key: npm-v3-${{ hashFiles('**/package-lock.json') }}
- name: Install dependencies
run: npm ci
shell: bash
if: steps.cache.outputs.cache-hit != 'true'
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
Loading

0 comments on commit be529ee

Please sign in to comment.