Repository: dievardump/EIP2981-implementation
Branch: main
Commit: efb71d618472
Files: 19
Total size: 22.8 KB
Directory structure:
gitextract_6dcip9tb/
├── .gitignore
├── .prettierrc
├── .solhint.json
├── README.md
├── contracts/
│ ├── ERC2981Base.sol
│ ├── ERC2981ContractWideRoyalties.sol
│ ├── ERC2981PerTokenRoyalties.sol
│ ├── IERC2981Royalties.sol
│ └── mocks/
│ ├── ERC1155WithRoyalties.sol
│ ├── ERC721WithContractWideRoyalties.sol
│ └── ERC721WithRoyalties.sol
├── deploy/
│ ├── 00_deploy_erc721.js
│ ├── 01_deploy_erc1155.js
│ └── 02_deploy_erc721_contract_wide.js
├── hardhat.config.js
├── package.json
└── test/
├── 00_royalties_721.js
├── 01_royalties_1155.js
└── 02_royalties_721_contract_wide.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
node_modules
#Hardhat files
cache
artifacts
.env*
!.env.SAMPLE
================================================
FILE: .prettierrc
================================================
{
"trailingComma": "all",
"tabWidth": 4,
"useTabs": false,
"semi": true,
"singleQuote": true
}
================================================
FILE: .solhint.json
================================================
{
"extends": "solhint:default"
}
================================================
FILE: README.md
================================================
# EIP-2981 Example
## Resume
Simple example of implementation of EIP-2981.
In all implementations, royalties are expected to be from 0 to 10000 which allows to define royalties with 2 decimals.
### Contract wide royalties
The contract `ERC2981ContractWideRoyalties.sol` implements ERC2981 with every token having the same royalties recipient and amount.
`./contracts/mocks/ERC721WithContractWideRoyalties.sol` is an example of ERC721 that would work on a contract-wide royalty base.
### Per Token royalties
The contract `ERC2981PerTokenRoyalties.sol` implements ERC2981 with every token having different royalties
The contracts
- `./contracts/mocks/ERC721WithRoyalties.sol`
- `./contracts/mocks/ERC1155WithRoyalties.sol`
show how to extend ERC2981 to set royalties at minting time.
## Installation
Clone this repository using your favorite tool (i.e: `git clone git@github.com:dievardump/EIP2981-implementation.git`)
In the directory of installation:
`npm install`
## Compilation
`npm run compile`
## Tests
`npm run test`
================================================
FILE: contracts/ERC2981Base.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/utils/introspection/ERC165.sol';
import './IERC2981Royalties.sol';
/// @dev This is a contract used to add ERC2981 support to ERC721 and 1155
abstract contract ERC2981Base is ERC165, IERC2981Royalties {
struct RoyaltyInfo {
address recipient;
uint24 amount;
}
/// @inheritdoc ERC165
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override
returns (bool)
{
return
interfaceId == type(IERC2981Royalties).interfaceId ||
super.supportsInterface(interfaceId);
}
}
================================================
FILE: contracts/ERC2981ContractWideRoyalties.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/utils/introspection/ERC165.sol';
import './ERC2981Base.sol';
/// @dev This is a contract used to add ERC2981 support to ERC721 and 1155
/// @dev This implementation has the same royalties for each and every tokens
abstract contract ERC2981ContractWideRoyalties is ERC2981Base {
RoyaltyInfo private _royalties;
/// @dev Sets token royalties
/// @param recipient recipient of the royalties
/// @param value percentage (using 2 decimals - 10000 = 100, 0 = 0)
function _setRoyalties(address recipient, uint256 value) internal {
require(value <= 10000, 'ERC2981Royalties: Too high');
_royalties = RoyaltyInfo(recipient, uint24(value));
}
/// @inheritdoc IERC2981Royalties
function royaltyInfo(uint256, uint256 value)
external
view
override
returns (address receiver, uint256 royaltyAmount)
{
RoyaltyInfo memory royalties = _royalties;
receiver = royalties.recipient;
royaltyAmount = (value * royalties.amount) / 10000;
}
}
================================================
FILE: contracts/ERC2981PerTokenRoyalties.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/utils/introspection/ERC165.sol';
import './ERC2981Base.sol';
/// @dev This is a contract used to add ERC2981 support to ERC721 and 1155
abstract contract ERC2981PerTokenRoyalties is ERC2981Base {
mapping(uint256 => RoyaltyInfo) internal _royalties;
/// @dev Sets token royalties
/// @param tokenId the token id fir which we register the royalties
/// @param recipient recipient of the royalties
/// @param value percentage (using 2 decimals - 10000 = 100, 0 = 0)
function _setTokenRoyalty(
uint256 tokenId,
address recipient,
uint256 value
) internal {
require(value <= 10000, 'ERC2981Royalties: Too high');
_royalties[tokenId] = RoyaltyInfo(recipient, uint24(value));
}
/// @inheritdoc IERC2981Royalties
function royaltyInfo(uint256 tokenId, uint256 value)
external
view
override
returns (address receiver, uint256 royaltyAmount)
{
RoyaltyInfo memory royalties = _royalties[tokenId];
receiver = royalties.recipient;
royaltyAmount = (value * royalties.amount) / 10000;
}
}
================================================
FILE: contracts/IERC2981Royalties.sol
================================================
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title IERC2981Royalties
/// @dev Interface for the ERC2981 - Token Royalty standard
interface IERC2981Royalties {
/// @notice Called with the sale price to determine how much royalty
// is owed and to whom.
/// @param _tokenId - the NFT asset queried for royalty information
/// @param _value - the sale price of the NFT asset specified by _tokenId
/// @return _receiver - address of who should be sent the royalty payment
/// @return _royaltyAmount - the royalty payment amount for value sale price
function royaltyInfo(uint256 _tokenId, uint256 _value)
external
view
returns (address _receiver, uint256 _royaltyAmount);
}
================================================
FILE: contracts/mocks/ERC1155WithRoyalties.sol
================================================
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/token/ERC1155/ERC1155.sol';
import '../ERC2981PerTokenRoyalties.sol';
/// @title Example of ERC1155 contract with ERC2981
/// @author Simon Fremaux (@dievardump)
/// @notice This is a mock, mint and mintBatch are not protected. Please do not use as-is in production
contract ERC1155WithRoyalties is ERC1155, ERC2981PerTokenRoyalties {
constructor(string memory uri_) ERC1155(uri_) {}
/// @inheritdoc ERC165
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC1155, ERC2981Base)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
/// @notice Mint amount token of type `id` to `to`
/// @param to the recipient of the token
/// @param id id of the token type to mint
/// @param amount amount of the token type to mint
/// @param royaltyRecipient the recipient for royalties (if royaltyValue > 0)
/// @param royaltyValue the royalties asked for (EIP2981)
function mint(
address to,
uint256 id,
uint256 amount,
address royaltyRecipient,
uint256 royaltyValue
) external {
_mint(to, id, amount, '');
if (royaltyValue > 0) {
_setTokenRoyalty(id, royaltyRecipient, royaltyValue);
}
}
/// @notice Mint several tokens at once
/// @param to the recipient of the token
/// @param ids array of ids of the token types to mint
/// @param amounts array of amount to mint for each token type
/// @param royaltyRecipients an array of recipients for royalties (if royaltyValues[i] > 0)
/// @param royaltyValues an array of royalties asked for (EIP2981)
function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
address[] memory royaltyRecipients,
uint256[] memory royaltyValues
) external {
require(
ids.length == royaltyRecipients.length &&
ids.length == royaltyValues.length,
'ERC1155: Arrays length mismatch'
);
_mintBatch(to, ids, amounts, '');
for (uint256 i; i < ids.length; i++) {
if (royaltyValues[i] > 0) {
_setTokenRoyalty(
ids[i],
royaltyRecipients[i],
royaltyValues[i]
);
}
}
}
}
================================================
FILE: contracts/mocks/ERC721WithContractWideRoyalties.sol
================================================
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import '../ERC2981ContractWideRoyalties.sol';
/// @title Example of ERC721 contract with ERC2981
/// @author Simon Fremaux (@dievardump)
/// @notice This is a mock, mint and mintBatch are not protected. Please do not use as-is in production
contract ERC721WithContractWideRoyalties is
ERC721,
ERC2981ContractWideRoyalties
{
uint256 nextTokenId;
constructor(string memory name_, string memory symbol_)
ERC721(name_, symbol_)
{}
/// @inheritdoc ERC165
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC721, ERC2981Base)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
/// @notice Allows to set the royalties on the contract
/// @dev This function in a real contract should be protected with a onlyOwner (or equivalent) modifier
/// @param recipient the royalties recipient
/// @param value royalties value (between 0 and 10000)
function setRoyalties(address recipient, uint256 value) public {
_setRoyalties(recipient, value);
}
/// @notice Mint one token to `to`
/// @param to the recipient of the token
function mint(address to) external {
uint256 tokenId = nextTokenId;
_safeMint(to, tokenId, '');
nextTokenId = tokenId + 1;
}
/// @notice Mint several tokens at once
/// @param recipients an array of recipients for each token
function mintBatch(address[] memory recipients) external {
uint256 tokenId = nextTokenId;
for (uint256 i; i < recipients.length; i++) {
_safeMint(recipients[i], tokenId, '');
tokenId++;
}
nextTokenId = tokenId;
}
}
================================================
FILE: contracts/mocks/ERC721WithRoyalties.sol
================================================
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import '../ERC2981PerTokenRoyalties.sol';
/// @title Example of ERC721 contract with ERC2981
/// @author Simon Fremaux (@dievardump)
/// @notice This is a mock, mint and mintBatch are not protected. Please do not use as-is in production
contract ERC721WithRoyalties is ERC721, ERC2981PerTokenRoyalties {
uint256 nextTokenId;
constructor(string memory name_, string memory symbol_)
ERC721(name_, symbol_)
{}
/// @inheritdoc ERC165
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC721, ERC2981Base)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
/// @notice Mint one token to `to`
/// @param to the recipient of the token
/// @param royaltyRecipient the recipient for royalties (if royaltyValue > 0)
/// @param royaltyValue the royalties asked for (EIP2981)
function mint(
address to,
address royaltyRecipient,
uint256 royaltyValue
) external {
uint256 tokenId = nextTokenId;
_safeMint(to, tokenId, '');
if (royaltyValue > 0) {
_setTokenRoyalty(tokenId, royaltyRecipient, royaltyValue);
}
nextTokenId = tokenId + 1;
}
/// @notice Mint several tokens at once
/// @param recipients an array of recipients for each token
/// @param royaltyRecipients an array of recipients for royalties (if royaltyValues[i] > 0)
/// @param royaltyValues an array of royalties asked for (EIP2981)
function mintBatch(
address[] memory recipients,
address[] memory royaltyRecipients,
uint256[] memory royaltyValues
) external {
uint256 tokenId = nextTokenId;
require(
recipients.length == royaltyRecipients.length &&
recipients.length == royaltyValues.length,
'ERC721: Arrays length mismatch'
);
for (uint256 i; i < recipients.length; i++) {
_safeMint(recipients[i], tokenId, '');
if (royaltyValues[i] > 0) {
_setTokenRoyalty(
tokenId,
royaltyRecipients[i],
royaltyValues[i]
);
}
tokenId++;
}
nextTokenId = tokenId;
}
}
================================================
FILE: deploy/00_deploy_erc721.js
================================================
// deploy/00_deploy_my_contract.js
module.exports = async ({ getNamedAccounts, deployments }) => {
const { deploy } = deployments;
const { deployer } = await getNamedAccounts();
await deploy('ERC721WithRoyalties', {
from: deployer,
args: ['ERC721WithRoyalties', '2981'],
log: true,
});
};
module.exports.tags = ['ERC721WithRoyalties'];
================================================
FILE: deploy/01_deploy_erc1155.js
================================================
// deploy/00_deploy_my_contract.js
module.exports = async ({ getNamedAccounts, deployments }) => {
const { deploy } = deployments;
const { deployer } = await getNamedAccounts();
await deploy('ERC1155WithRoyalties', {
from: deployer,
args: ['ipfs://baseURI'],
log: true,
});
};
module.exports.tags = ['ERC1155WithRoyalties'];
================================================
FILE: deploy/02_deploy_erc721_contract_wide.js
================================================
// deploy/00_deploy_my_contract.js
module.exports = async ({ getNamedAccounts, deployments }) => {
const { deploy } = deployments;
const { deployer } = await getNamedAccounts();
await deploy('ERC721WithContractWideRoyalties', {
from: deployer,
args: ['ERC721WithContractWideRoyalties', '2981'],
log: true,
});
};
module.exports.tags = ['ERC721WithContractWideRoyalties'];
================================================
FILE: hardhat.config.js
================================================
require('@nomiclabs/hardhat-ethers');
require('@nomiclabs/hardhat-waffle');
require('hardhat-deploy');
require('hardhat-deploy-ethers');
require('hardhat-tracer');
require('@nomiclabs/hardhat-etherscan');
require("hardhat-gas-reporter");
/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: {
version: '0.8.0',
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
namedAccounts: {
deployer: {
default: 0, // here this will by default take the first account as deployer
},
},
};
================================================
FILE: package.json
================================================
{
"name": "eip2981-example",
"version": "0.0.1",
"description": "EIP2981 implementation example",
"main": "index.js",
"scripts": {
"compile": "npx hardhat compile",
"test": "npx hardhat test"
},
"author": "simon fremaux (dievarump)",
"license": "ISC",
"devDependencies": {
"@nomiclabs/hardhat-ethers": "^2.0.2",
"@nomiclabs/hardhat-etherscan": "^2.1.3",
"@nomiclabs/hardhat-waffle": "^2.0.1",
"@openzeppelin/contracts": "^4.1.0",
"chai": "^4.3.4",
"ethereum-waffle": "^3.4.0",
"ethers": "^5.3.1",
"hardhat": "^2.4.0",
"hardhat-deploy": "^0.8.8",
"hardhat-deploy-ethers": "*",
"hardhat-gas-reporter": "1.0.4",
"hardhat-tracer": "*"
}
}
================================================
FILE: test/00_royalties_721.js
================================================
const { expect } = require('chai');
const { deployments, ethers } = require('hardhat');
const _INTERFACE_ID_ERC165 = '0x01ffc9a7';
const _INTERFACE_ID_ROYALTIES_EIP2981 = '0x2a55205a';
const _INTERFACE_ID_ERC721 = '0x80ac58cd';
describe('ERC721WithRoyalties', () => {
let ERC721WithRoyalties;
let deployer;
let royaltiesRecipient;
const ADDRESS_ZERO = ethers.constants.AddressZero;
beforeEach(async () => {
[deployer, randomAccount, royaltiesRecipient] =
await ethers.getSigners();
await deployments.fixture();
ERC721WithRoyalties = await deployments.get('ERC721WithRoyalties');
erc721WithRoyalties = await ethers.getContractAt(
'ERC721WithRoyalties',
ERC721WithRoyalties.address,
deployer,
);
});
describe('Royalties', async () => {
it('has all the right interfaces', async function () {
expect(
await erc721WithRoyalties.supportsInterface(
_INTERFACE_ID_ERC165,
),
'Error Royalties 165',
).to.be.true;
expect(
await erc721WithRoyalties.supportsInterface(
_INTERFACE_ID_ROYALTIES_EIP2981,
),
'Error Royalties 2981',
).to.be.true;
expect(
await erc721WithRoyalties.supportsInterface(
_INTERFACE_ID_ERC721,
),
'Error Royalties 721',
).to.be.true;
});
it('throws if royalties more than 100%', async function () {
const tx = erc721WithRoyalties.mint(
deployer.address,
royaltiesRecipient.address,
10001, // 100.01%
);
await expect(tx).to.be.revertedWith('ERC2981Royalties: Too high');
});
it('has the right royalties for tokenId', async function () {
await erc721WithRoyalties.mint(
deployer.address,
royaltiesRecipient.address,
250, // 2.50%
);
const info = await erc721WithRoyalties.royaltyInfo(0, 10000);
expect(info[1].toNumber()).to.be.equal(250);
expect(info[0]).to.be.equal(royaltiesRecipient.address);
});
it('can set address(0) as royalties recipient', async function () {
// 0.01% royalties
await erc721WithRoyalties.mint(deployer.address, ADDRESS_ZERO, 1);
const info = await erc721WithRoyalties.royaltyInfo(0, 10000);
expect(info[1].toNumber()).to.be.equal(1);
expect(info[0]).to.be.equal(ADDRESS_ZERO);
});
it('has no royalties if not set', async function () {
await erc721WithRoyalties.mint(
deployer.address,
royaltiesRecipient.address,
0,
);
const info = await erc721WithRoyalties.royaltyInfo(0, 100);
expect(info[1].toNumber()).to.be.equal(0);
expect(info[0]).to.be.equal(ADDRESS_ZERO);
});
});
});
================================================
FILE: test/01_royalties_1155.js
================================================
const { expect } = require('chai');
const { deployments, ethers } = require('hardhat');
describe('ERC1155WithRoyalties', () => {
let ERC1155WithRoyalties;
let deployer;
let randomAccount;
let royaltiesRecipient;
const ADDRESS_ZERO = ethers.constants.AddressZero;
beforeEach(async () => {
[deployer, randomAccount, royaltiesRecipient] =
await ethers.getSigners();
await deployments.fixture();
ERC1155WithRoyalties = await deployments.get('ERC1155WithRoyalties');
erc1155WithRoyalties = await ethers.getContractAt(
'ERC1155WithRoyalties',
ERC1155WithRoyalties.address,
deployer,
);
});
describe('Royalties', async () => {
it('throws if royalties more than 100%', async function () {
const tx = erc1155WithRoyalties.mint(
deployer.address,
0,
10,
royaltiesRecipient.address,
10001, // 100.01%
);
await expect(tx).to.be.revertedWith('ERC2981Royalties: Too high');
});
it('has the right royalties for tokenId', async function () {
await erc1155WithRoyalties.mint(
deployer.address,
0,
10,
royaltiesRecipient.address,
1000, // 10%
);
const info = await erc1155WithRoyalties.royaltyInfo(0, 100);
expect(info[1].toNumber()).to.be.equal(10);
expect(info[0]).to.be.equal(royaltiesRecipient.address);
});
it('can set address(0) as royalties recipient', async function () {
await erc1155WithRoyalties.mint(
deployer.address,
0,
10,
ADDRESS_ZERO,
1000,
);
const info = await erc1155WithRoyalties.royaltyInfo(0, 100);
expect(info[1].toNumber()).to.be.equal(10);
expect(info[0]).to.be.equal(ADDRESS_ZERO);
});
it('has no royalties if not set', async function () {
await erc1155WithRoyalties.mint(
deployer.address,
0,
10,
royaltiesRecipient.address,
0,
);
const info = await erc1155WithRoyalties.royaltyInfo(0, 100);
expect(info[1].toNumber()).to.be.equal(0);
expect(info[0]).to.be.equal(ADDRESS_ZERO);
});
it('each token has the right royalties when minting batch', async function () {
const ids = [0, 1, 2, 3];
const amounts = [10, 10, 10, 10];
const royaltyRecipients = [
randomAccount.address,
deployer.address,
ADDRESS_ZERO,
deployer.address,
];
const royaltyValues = [1000, 800, 5000, 0];
await erc1155WithRoyalties.mintBatch(
deployer.address,
ids,
amounts,
royaltyRecipients,
royaltyValues,
);
for (const [index, id] of ids.entries()) {
const info = await erc1155WithRoyalties.royaltyInfo(id, 100);
expect(info[1].toNumber()).to.be.equal(
royaltyValues[index] / 100,
);
if (info[1].toNumber() !== 0) {
expect(info[0]).to.be.equal(royaltyRecipients[index]);
}
}
});
});
});
================================================
FILE: test/02_royalties_721_contract_wide.js
================================================
const { expect } = require('chai');
const { deployments, ethers } = require('hardhat');
describe('ERC721WithContractWideRoyalties', () => {
let ERC721WithContractWideRoyalties;
let deployer;
let royaltiesRecipient;
const ADDRESS_ZERO = ethers.constants.AddressZero;
beforeEach(async () => {
[deployer, randomAccount, royaltiesRecipient] =
await ethers.getSigners();
await deployments.fixture();
ERC721WithContractWideRoyalties = await deployments.get(
'ERC721WithContractWideRoyalties',
);
erc721WithRoyalties = await ethers.getContractAt(
'ERC721WithContractWideRoyalties',
ERC721WithContractWideRoyalties.address,
deployer,
);
});
describe('Contract wide Royalties', async () => {
it('has no royalties if not set', async function () {
await erc721WithRoyalties.mint(deployer.address);
const info = await erc721WithRoyalties.royaltyInfo(0, 100);
expect(info[1].toNumber()).to.be.equal(0);
expect(info[0]).to.be.equal(ADDRESS_ZERO);
});
it('throws if royalties more than 100%', async function () {
const tx = erc721WithRoyalties.setRoyalties(
royaltiesRecipient.address,
10001,
);
await expect(tx).to.be.revertedWith('ERC2981Royalties: Too high');
});
it('has the right royalties for tokenId', async function () {
await erc721WithRoyalties.setRoyalties(
royaltiesRecipient.address,
250,
);
await erc721WithRoyalties.mint(deployer.address);
const info = await erc721WithRoyalties.royaltyInfo(0, 10000);
expect(info[1].toNumber()).to.be.equal(250);
expect(info[0]).to.be.equal(royaltiesRecipient.address);
});
it('can set address(0) as royalties recipient', async function () {
await erc721WithRoyalties.setRoyalties(ADDRESS_ZERO, 5000);
await erc721WithRoyalties.mint(deployer.address);
const info = await erc721WithRoyalties.royaltyInfo(0, 10000);
expect(info[1].toNumber()).to.be.equal(5000);
expect(info[0]).to.be.equal(ADDRESS_ZERO);
});
});
});
gitextract_6dcip9tb/
├── .gitignore
├── .prettierrc
├── .solhint.json
├── README.md
├── contracts/
│ ├── ERC2981Base.sol
│ ├── ERC2981ContractWideRoyalties.sol
│ ├── ERC2981PerTokenRoyalties.sol
│ ├── IERC2981Royalties.sol
│ └── mocks/
│ ├── ERC1155WithRoyalties.sol
│ ├── ERC721WithContractWideRoyalties.sol
│ └── ERC721WithRoyalties.sol
├── deploy/
│ ├── 00_deploy_erc721.js
│ ├── 01_deploy_erc1155.js
│ └── 02_deploy_erc721_contract_wide.js
├── hardhat.config.js
├── package.json
└── test/
├── 00_royalties_721.js
├── 01_royalties_1155.js
└── 02_royalties_721_contract_wide.js
Condensed preview — 19 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (25K chars).
[
{
"path": ".gitignore",
"chars": 64,
"preview": "node_modules\n\n#Hardhat files\ncache\nartifacts\n\n.env*\n!.env.SAMPLE"
},
{
"path": ".prettierrc",
"chars": 99,
"preview": "{\n\t\"trailingComma\": \"all\",\n\t\"tabWidth\": 4,\n\t\"useTabs\": false,\n\t\"semi\": true,\n\t\"singleQuote\": true\n}"
},
{
"path": ".solhint.json",
"chars": 34,
"preview": "{\n \"extends\": \"solhint:default\"\n}"
},
{
"path": "README.md",
"chars": 1043,
"preview": "# EIP-2981 Example\n\n## Resume\n\nSimple example of implementation of EIP-2981.\n\nIn all implementations, royalties are expe"
},
{
"path": "contracts/ERC2981Base.sol",
"chars": 683,
"preview": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport '@openzeppelin/contracts/utils/introspection/ERC165.sol'"
},
{
"path": "contracts/ERC2981ContractWideRoyalties.sol",
"chars": 1123,
"preview": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport '@openzeppelin/contracts/utils/introspection/ERC165.sol'"
},
{
"path": "contracts/ERC2981PerTokenRoyalties.sol",
"chars": 1210,
"preview": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport '@openzeppelin/contracts/utils/introspection/ERC165.sol'"
},
{
"path": "contracts/IERC2981Royalties.sol",
"chars": 747,
"preview": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title IERC2981Royalties\n/// @dev Interface for the ERC2981"
},
{
"path": "contracts/mocks/ERC1155WithRoyalties.sol",
"chars": 2482,
"preview": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport '@openzeppelin/contracts/token/ERC1155/ERC1155.sol';\n\nimp"
},
{
"path": "contracts/mocks/ERC721WithContractWideRoyalties.sol",
"chars": 1846,
"preview": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport '@openzeppelin/contracts/token/ERC721/ERC721.sol';\n\nimpor"
},
{
"path": "contracts/mocks/ERC721WithRoyalties.sol",
"chars": 2435,
"preview": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport '@openzeppelin/contracts/token/ERC721/ERC721.sol';\n\nimpor"
},
{
"path": "deploy/00_deploy_erc721.js",
"chars": 377,
"preview": "// deploy/00_deploy_my_contract.js\nmodule.exports = async ({ getNamedAccounts, deployments }) => {\n const { deploy } "
},
{
"path": "deploy/01_deploy_erc1155.js",
"chars": 366,
"preview": "// deploy/00_deploy_my_contract.js\nmodule.exports = async ({ getNamedAccounts, deployments }) => {\n const { deploy } "
},
{
"path": "deploy/02_deploy_erc721_contract_wide.js",
"chars": 413,
"preview": "// deploy/00_deploy_my_contract.js\nmodule.exports = async ({ getNamedAccounts, deployments }) => {\n const { deploy } "
},
{
"path": "hardhat.config.js",
"chars": 645,
"preview": "require('@nomiclabs/hardhat-ethers');\nrequire('@nomiclabs/hardhat-waffle');\nrequire('hardhat-deploy');\nrequire('hardhat-"
},
{
"path": "package.json",
"chars": 711,
"preview": "{\n \"name\": \"eip2981-example\",\n \"version\": \"0.0.1\",\n \"description\": \"EIP2981 implementation example\",\n \"main\": \"index"
},
{
"path": "test/00_royalties_721.js",
"chars": 3165,
"preview": "const { expect } = require('chai');\nconst { deployments, ethers } = require('hardhat');\n\nconst _INTERFACE_ID_ERC165 = '0"
},
{
"path": "test/01_royalties_1155.js",
"chars": 3594,
"preview": "const { expect } = require('chai');\nconst { deployments, ethers } = require('hardhat');\n\ndescribe('ERC1155WithRoyalties'"
},
{
"path": "test/02_royalties_721_contract_wide.js",
"chars": 2346,
"preview": "const { expect } = require('chai');\nconst { deployments, ethers } = require('hardhat');\n\ndescribe('ERC721WithContractWid"
}
]
About this extraction
This page contains the full source code of the dievardump/EIP2981-implementation GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 19 files (22.8 KB), approximately 6.1k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.