Skip to content

Commit

Permalink
Merge pull request #21 from axieinfinity/feature/ERC1155Common
Browse files Browse the repository at this point in the history
  • Loading branch information
huyhuynh3103 authored Nov 20, 2024
2 parents f665e9e + ee7c169 commit fa36abc
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 73 deletions.
23 changes: 10 additions & 13 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ on:
branches:
- main
- dev
- 'feature/*'
- 'features/*'
- "feature/*"
- "features/*"
pull_request:
branches:
- main
- dev
- 'feature/*'
- 'features/*'
- "feature/*"
- "features/*"

env:
FOUNDRY_PROFILE: ci
Expand All @@ -23,24 +23,21 @@ jobs:
fail-fast: true

name: Foundry project
runs-on: [self-hosted, dockerize]
runs-on: ubuntu-latest
steps:
- id: 'gh-app'
name: 'Get Token'
uses: 'tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a' #v1.7.0
with:
app_id: ${{ secrets.GH_APP_ID }}
private_key: ${{ secrets.GH_PRIVATE_KEY }}

- uses: actions/[email protected]
with:
submodules: recursive
token: ${{ steps.gh-app.outputs.token }}

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Install dependencies
run: |
forge install
id: install

- name: Run Forge build
run: |
Expand Down
3 changes: 2 additions & 1 deletion remappings.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
forge-std/=lib/forge-std/src/
ds-test/=lib/forge-std/lib/ds-test/src/
@openzeppelin/=./node_modules/@openzeppelin/
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts
135 changes: 100 additions & 35 deletions src/ERC1155Common.sol
Original file line number Diff line number Diff line change
@@ -1,80 +1,145 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.0.0
pragma solidity ^0.8.20;

import { IERC165 } from "@openzeppelin/contracts/interfaces/IERC165.sol";
import { AccessControlEnumerable } from "@openzeppelin/contracts/access/AccessControlEnumerable.sol";
import { ERC1155 } from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";

import { ERC1155Burnable } from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol";
import { ERC1155Pausable } from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Pausable.sol";
import { ERC1155Supply } from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol";
import { AccessControlEnumerable } from "@openzeppelin/contracts/access/AccessControlEnumerable.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { IERC1155Common } from "./interfaces/IERC1155Common.sol";

contract ERC1155Common is AccessControlEnumerable, ERC1155, ERC1155Supply, IERC1155Common {
contract ERC1155Common is
ERC1155,
AccessControlEnumerable,
ERC1155Pausable,
ERC1155Burnable,
ERC1155Supply,
IERC1155Common
{
using Strings for uint256;

bytes32 public constant URI_SETTER_ROLE = keccak256("URI_SETTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

string private _name;
string private _symbol;

constructor(string memory name_, string memory symbol_, string memory baseTokenURI, address[] memory minters)
payable
ERC1155(baseTokenURI)
{
constructor(address admin, string memory name_, string memory symbol_, string memory uri_) ERC1155(uri_) {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
_grantRole(PAUSER_ROLE, admin);
_grantRole(MINTER_ROLE, admin);
_grantRole(URI_SETTER_ROLE, admin);

_name = name_;
_symbol = symbol_;
_grantRole(DEFAULT_ADMIN_ROLE, _msgSender());
bytes32 minterRole = MINTER_ROLE;

uint256 length = minters.length;
for (uint256 i; i < length;) {
_grantRole(minterRole, minters[i]);
unchecked {
++i;
}
}
}

function uri(uint256 tokenId) public view override returns (string memory) {
string memory _uri = super.uri(tokenId);
return string(abi.encodePacked(_uri, tokenId.toString()));
/**
* @dev Set the URI for all token types.
* Requirements:
* - the caller must have the `URI_SETTER_ROLE`.
*/
function setURI(string memory newURI) external onlyRole(URI_SETTER_ROLE) {
_setURI(newURI);
}

/**
* @dev Pauses all token transfers.
* Requirements:
* - the caller must have the `PAUSER_ROLE`.
*/
function pause() external onlyRole(PAUSER_ROLE) {
_pause();
}

function name() external view returns (string memory) {
return _name;
/**
* @dev Unpauses all token transfers.
* Requirements:
* - the caller must have the `PAUSER_ROLE`.
*/
function unpause() external onlyRole(PAUSER_ROLE) {
_unpause();
}

function symbol() external view returns (string memory) {
return _symbol;
/// @inheritdoc IERC1155Common
function mint(address account, uint256 id, uint256 amount, bytes calldata data) public virtual onlyRole(MINTER_ROLE) {
_mint(account, id, amount, data);
}

/// @inheritdoc IERC1155Common
function mintBatch(address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data)
public
virtual
onlyRole(MINTER_ROLE)
{
_mintBatch(to, ids, amounts, data);
}

/**
* @dev Mint single token to multiple addresses.
* Requirements:
* - the caller must have the `MINTER_ROLE`.
*/
function bulkMint(uint256 id, address[] calldata tos, uint256[] calldata amounts, bytes[] calldata datas)
public
virtual
onlyRole(MINTER_ROLE)
{
uint256 length = tos.length;
require(length != 0 && length == amounts.length && length == datas.length, "ERC1155: invalid array lengths");

for (uint256 i; i < length; ++i) {
_mint(tos[i], id, amounts[i], datas[i]);
}
}

/**
* @dev Sets the base URI for metadata of ERC1155 tokens.
* @param uri_ The new base URI.
* @dev See {ERC1155-uri}.
*/
function setURI(string calldata uri_) external onlyRole(DEFAULT_ADMIN_ROLE) {
_setURI(uri_);
function uri(uint256 tokenId) public view virtual override returns (string memory) {
string memory uri_ = super.uri(tokenId);
return string.concat(uri_, tokenId.toString());
}

/// @inheritdoc IERC1155Common
function mint(address to, uint256 id, uint256 amount) external onlyRole(MINTER_ROLE) {
_mint(to, id, amount, "");
function name() public view virtual returns (string memory) {
return _name;
}

/// @inheritdoc IERC1155Common
function batchMint(address to, uint256[] calldata ids, uint256[] calldata amounts) external onlyRole(MINTER_ROLE) {
_mintBatch(to, ids, amounts, "");
function symbol() public view virtual returns (string memory) {
return _symbol;
}

function supportsInterface(bytes4 interfaceId) public view override(ERC1155, AccessControlEnumerable) returns (bool) {
/**
* @dev See {ERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(IERC165, ERC1155, AccessControlEnumerable)
returns (bool)
{
return interfaceId == type(IERC1155Common).interfaceId || super.supportsInterface(interfaceId);
}

/**
* @dev See {ERC1155-_beforeTokenTransfer}.
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override(ERC1155, ERC1155Supply) {
) internal virtual override(ERC1155, ERC1155Pausable, ERC1155Supply) {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}
}
2 changes: 1 addition & 1 deletion src/ERC721Common.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import "./interfaces/IERC721Common.sol";
import "./refs/ERC721Nonce.sol";
import "./ERC721PresetMinterPauserAutoIdCustomized.sol";

abstract contract ERC721Common is ERC721Nonce, ERC721PresetMinterPauserAutoIdCustomized, IERC721State, IERC721Common {
contract ERC721Common is ERC721Nonce, ERC721PresetMinterPauserAutoIdCustomized, IERC721State, IERC721Common {
constructor(string memory name, string memory symbol, string memory baseTokenURI)
ERC721PresetMinterPauserAutoIdCustomized(name, symbol, baseTokenURI)
{ }
Expand Down
37 changes: 34 additions & 3 deletions src/interfaces/IERC1155Common.sol
Original file line number Diff line number Diff line change
@@ -1,20 +1,51 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface IERC1155Common {
import { IAccessControlEnumerable } from "@openzeppelin/contracts/access/IAccessControlEnumerable.sol";
import { IERC1155 } from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";

interface IERC1155Common is IAccessControlEnumerable, IERC1155 {
/// @dev Return the name of the collection.
function name() external view returns (string memory);

/// @dev Return the symbol of the collection.
function symbol() external view returns (string memory);

/**
* @dev Mints a single ERC1155 token and assigns it to the specified address.
*
* Requirements:
* - the caller must have the `MINTER_ROLE`.
*
* @param to The address to which the minted token will be assigned.
* @param id The ID of the token to mint.
* @param amount The amount of tokens to mint.
* @param data Additional data with no specified format.
*/
function mint(address to, uint256 id, uint256 amount) external;
function mint(address to, uint256 id, uint256 amount, bytes calldata data) external;

/**
* @dev Mints multiple ERC1155 tokens and assigns them to the specified address.
*
* Requirements:
* - the caller must have the `MINTER_ROLE`.
*
* @param to The address to which the minted tokens will be assigned.
* @param ids The IDs of the tokens to mint.
* @param amounts The amounts of tokens to mint.
* @param data Additional data with no specified format.
*/
function mintBatch(address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;

/**
* @dev Mint single token to multiple addresses.
* Requirements:
* - the caller must have the `MINTER_ROLE`.
*
* @param id The ID of the token to mint.
* @param tos The addresses to which the minted tokens will be assigned.
* @param amounts The amounts of tokens to mint.
* @param datas Additional data with no specified format.
*/
function batchMint(address to, uint256[] calldata ids, uint256[] calldata amounts) external;
function bulkMint(uint256 id, address[] calldata tos, uint256[] calldata amounts, bytes[] calldata datas) external;
}
6 changes: 3 additions & 3 deletions src/mock/SampleERC1155.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.0;
import "../ERC1155Common.sol";

contract SampleERC1155 is ERC1155Common {
constructor(string memory name, string memory symbol, string memory baseTokenURI, address[] memory minters)
ERC1155Common(name, symbol, baseTokenURI, minters)
{}
constructor(address admin, string memory name, string memory symbol, string memory uri)
ERC1155Common(admin, name, symbol, uri)
{ }
}
18 changes: 7 additions & 11 deletions src/mock/launchpad/SampleNFT1155Launchpad.sol
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { ERC1155 } from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol";
import { NFTLaunchpadCommon } from "../../launchpad/NFTLaunchpadCommon.sol";
import { SampleERC1155, ERC1155Common } from "../SampleERC1155.sol";

contract SampleNFT1155Launchpad is ERC1155, AccessControl, NFTLaunchpadCommon {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

constructor(address admin, address minter, string memory uri_) ERC1155(uri_) {
_setupRole(DEFAULT_ADMIN_ROLE, admin);
_setupRole(MINTER_ROLE, minter);
}
contract SampleNFT1155Launchpad is SampleERC1155, NFTLaunchpadCommon {
constructor(address admin, string memory name, string memory symbol, string memory uri)
SampleERC1155(admin, name, symbol, uri)
{ }

/// @dev Mint NFTs for the launchpad.
function mintLaunchpad(address to, uint256 quantity, bytes calldata /* extraData */ )
Expand All @@ -35,9 +31,9 @@ contract SampleNFT1155Launchpad is ERC1155, AccessControl, NFTLaunchpadCommon {
public
view
virtual
override(ERC1155, AccessControl, NFTLaunchpadCommon)
override(ERC1155Common, NFTLaunchpadCommon)
returns (bool)
{
return super.supportsInterface(interfaceId);
return ERC1155Common.supportsInterface(interfaceId) || NFTLaunchpadCommon.supportsInterface(interfaceId);
}
}
2 changes: 1 addition & 1 deletion src/mock/launchpad/SampleNFT721Launchpad.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ contract SampleNFT721Launchpad is SampleERC721, NFTLaunchpadCommon {
override(ERC721Common, NFTLaunchpadCommon)
returns (bool)
{
return super.supportsInterface(interfaceId);
return ERC721Common.supportsInterface(interfaceId) || NFTLaunchpadCommon.supportsInterface(interfaceId);
}
}
Loading

0 comments on commit fa36abc

Please sign in to comment.