Skip to content

Commit d7924bd

Browse files
authored
Merge pull request #25 from axieinfinity/implement-feature/adapt-oz-v5/merge-with-release-0.2.0
feat: resolve conflicts caused by merging with release/v0.2.0 branch
2 parents ed6d969 + 5939e68 commit d7924bd

18 files changed

+576
-67
lines changed

.github/workflows/test.yml

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ on:
55
branches:
66
- main
77
- dev
8-
- 'feature/*'
9-
- 'features/*'
8+
- "feature/*"
9+
- "features/*"
1010
pull_request:
1111
branches:
1212
- main
1313
- dev
14-
- 'feature/*'
15-
- 'features/*'
14+
- "feature/*"
15+
- "features/*"
1616

1717
env:
1818
FOUNDRY_PROFILE: ci
@@ -23,24 +23,21 @@ jobs:
2323
fail-fast: true
2424

2525
name: Foundry project
26-
runs-on: [self-hosted, dockerize]
26+
runs-on: ubuntu-latest
2727
steps:
28-
- id: 'gh-app'
29-
name: 'Get Token'
30-
uses: 'tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a' #v1.7.0
31-
with:
32-
app_id: ${{ secrets.GH_APP_ID }}
33-
private_key: ${{ secrets.GH_PRIVATE_KEY }}
34-
3528
- uses: actions/checkout@v4.1.1
3629
with:
3730
submodules: recursive
38-
token: ${{ steps.gh-app.outputs.token }}
3931

4032
- name: Install Foundry
4133
uses: foundry-rs/foundry-toolchain@v1
4234
with:
4335
version: nightly
36+
37+
- name: Install dependencies
38+
run: |
39+
forge soldeer update
40+
id: install
4441

4542
- name: Run Forge build
4643
run: |

src/ERC1155Common.sol

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// SPDX-License-Identifier: MIT
2+
// Compatible with OpenZeppelin Contracts ^5.0.0
3+
pragma solidity ^0.8.20;
4+
5+
import { AccessControlEnumerable } from "@openzeppelin/contracts/access/extensions/AccessControlEnumerable.sol";
6+
import { IERC165 } from "@openzeppelin/contracts/interfaces/IERC165.sol";
7+
import { ERC1155 } from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
8+
9+
import { IERC1155Common } from "./interfaces/IERC1155Common.sol";
10+
import { ERC1155Burnable } from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol";
11+
import { ERC1155Pausable } from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Pausable.sol";
12+
import { ERC1155Supply } from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol";
13+
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
14+
15+
contract ERC1155Common is
16+
ERC1155,
17+
AccessControlEnumerable,
18+
ERC1155Pausable,
19+
ERC1155Burnable,
20+
ERC1155Supply,
21+
IERC1155Common
22+
{
23+
using Strings for uint256;
24+
25+
bytes32 public constant URI_SETTER_ROLE = keccak256("URI_SETTER_ROLE");
26+
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
27+
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
28+
29+
string private _name;
30+
string private _symbol;
31+
32+
constructor(address admin, string memory name_, string memory symbol_, string memory uri_) ERC1155(uri_) {
33+
_grantRole(DEFAULT_ADMIN_ROLE, admin);
34+
_grantRole(PAUSER_ROLE, admin);
35+
_grantRole(MINTER_ROLE, admin);
36+
_grantRole(URI_SETTER_ROLE, admin);
37+
38+
_name = name_;
39+
_symbol = symbol_;
40+
}
41+
42+
/**
43+
* @dev Set the URI for all token types.
44+
* Requirements:
45+
* - the caller must have the `URI_SETTER_ROLE`.
46+
*/
47+
function setURI(
48+
string memory newURI
49+
) external onlyRole(URI_SETTER_ROLE) {
50+
_setURI(newURI);
51+
}
52+
53+
/**
54+
* @dev Pauses all token transfers.
55+
* Requirements:
56+
* - the caller must have the `PAUSER_ROLE`.
57+
*/
58+
function pause() external onlyRole(PAUSER_ROLE) {
59+
_pause();
60+
}
61+
62+
/**
63+
* @dev Unpauses all token transfers.
64+
* Requirements:
65+
* - the caller must have the `PAUSER_ROLE`.
66+
*/
67+
function unpause() external onlyRole(PAUSER_ROLE) {
68+
_unpause();
69+
}
70+
71+
/// @inheritdoc IERC1155Common
72+
function mint(address account, uint256 id, uint256 amount, bytes calldata data) public virtual onlyRole(MINTER_ROLE) {
73+
_mint(account, id, amount, data);
74+
}
75+
76+
/// @inheritdoc IERC1155Common
77+
function mintBatch(
78+
address to,
79+
uint256[] calldata ids,
80+
uint256[] calldata amounts,
81+
bytes calldata data
82+
) public virtual onlyRole(MINTER_ROLE) {
83+
_mintBatch(to, ids, amounts, data);
84+
}
85+
86+
/**
87+
* @dev Mint single token to multiple addresses.
88+
* Requirements:
89+
* - the caller must have the `MINTER_ROLE`.
90+
*/
91+
function bulkMint(
92+
uint256 id,
93+
address[] calldata tos,
94+
uint256[] calldata amounts,
95+
bytes[] calldata datas
96+
) public virtual onlyRole(MINTER_ROLE) {
97+
uint256 length = tos.length;
98+
require(length != 0 && length == amounts.length && length == datas.length, "ERC1155: invalid array lengths");
99+
100+
for (uint256 i; i < length; ++i) {
101+
_mint(tos[i], id, amounts[i], datas[i]);
102+
}
103+
}
104+
105+
/**
106+
* @dev See {ERC1155-uri}.
107+
*/
108+
function uri(
109+
uint256 tokenId
110+
) public view virtual override returns (string memory) {
111+
string memory uri_ = super.uri(tokenId);
112+
return string.concat(uri_, tokenId.toString());
113+
}
114+
115+
/// @inheritdoc IERC1155Common
116+
function name() public view virtual returns (string memory) {
117+
return _name;
118+
}
119+
120+
/// @inheritdoc IERC1155Common
121+
function symbol() public view virtual returns (string memory) {
122+
return _symbol;
123+
}
124+
125+
/**
126+
* @dev See {ERC165-supportsInterface}.
127+
*/
128+
function supportsInterface(
129+
bytes4 interfaceId
130+
) public view virtual override(IERC165, ERC1155, AccessControlEnumerable) returns (bool) {
131+
return interfaceId == type(IERC1155Common).interfaceId || super.supportsInterface(interfaceId);
132+
}
133+
134+
/**
135+
* @dev See {ERC1155-_update}.
136+
*/
137+
function _update(
138+
address from,
139+
address to,
140+
uint256[] memory ids,
141+
uint256[] memory values
142+
) internal virtual override(ERC1155, ERC1155Supply, ERC1155Pausable) {
143+
super._update(from, to, ids, values);
144+
}
145+
}

src/ERC721Common.sol

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@ import { IERC721State } from "./interfaces/IERC721State.sol";
77
import { ERC721Nonce } from "./refs/ERC721Nonce.sol";
88
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
99

10-
abstract contract ERC721Common is ERC721Nonce, ERC721PresetMinterPauserAutoIdCustomized, IERC721State, IERC721Common {
11-
constructor(
12-
string memory name_,
13-
string memory symbol_,
14-
string memory baseTokenURI
15-
) ERC721PresetMinterPauserAutoIdCustomized(name_, symbol_, baseTokenURI) { }
10+
contract ERC721Common is ERC721Nonce, ERC721PresetMinterPauserAutoIdCustomized, IERC721State, IERC721Common {
11+
constructor(string memory name, string memory symbol, string memory baseTokenURI)
12+
ERC721PresetMinterPauserAutoIdCustomized(name, symbol, baseTokenURI)
13+
{ }
1614

1715
/// @inheritdoc IERC721State
1816
function stateOf(

src/interfaces/IERC1155Common.sol

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.0;
3+
4+
import { IAccessControlEnumerable } from "@openzeppelin/contracts/access/extensions/IAccessControlEnumerable.sol";
5+
import { IERC1155 } from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
6+
7+
interface IERC1155Common is IAccessControlEnumerable, IERC1155 {
8+
/// @dev Return the name of the collection.
9+
function name() external view returns (string memory);
10+
11+
/// @dev Return the symbol of the collection.
12+
function symbol() external view returns (string memory);
13+
14+
/**
15+
* @dev Mints a single ERC1155 token and assigns it to the specified address.
16+
*
17+
* Requirements:
18+
* - the caller must have the `MINTER_ROLE`.
19+
*
20+
* @param to The address to which the minted token will be assigned.
21+
* @param id The ID of the token to mint.
22+
* @param amount The amount of tokens to mint.
23+
* @param data Additional data with no specified format.
24+
*/
25+
function mint(address to, uint256 id, uint256 amount, bytes calldata data) external;
26+
27+
/**
28+
* @dev Mints multiple ERC1155 tokens and assigns them to the specified address.
29+
*
30+
* Requirements:
31+
* - the caller must have the `MINTER_ROLE`.
32+
*
33+
* @param to The address to which the minted tokens will be assigned.
34+
* @param ids The IDs of the tokens to mint.
35+
* @param amounts The amounts of tokens to mint.
36+
* @param data Additional data with no specified format.
37+
*/
38+
function mintBatch(address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;
39+
40+
/**
41+
* @dev Mint single token to multiple addresses.
42+
* Requirements:
43+
* - the caller must have the `MINTER_ROLE`.
44+
*
45+
* @param id The ID of the token to mint.
46+
* @param tos The addresses to which the minted tokens will be assigned.
47+
* @param amounts The amounts of tokens to mint.
48+
* @param datas Additional data with no specified format.
49+
*/
50+
function bulkMint(uint256 id, address[] calldata tos, uint256[] calldata amounts, bytes[] calldata datas) external;
51+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.19;
3+
4+
/// @dev Interface for the NFT contract that compatible with the contract MavisPresale.
5+
/// MUST be included ERC165 interface to support the detection of the contract's capabilities.
6+
interface INFTPresale {
7+
/**
8+
* @dev Mint NFTs for the presale.
9+
*
10+
* Requirements:
11+
* - The mintedTokenIds and mintedAmounts should have the same length.
12+
* - The mintedTokenIds array should be unique.
13+
* - For ERC721 NFTs, each minted token's quantity should always be 1.
14+
* - For ERC1155 NFTs, each minted token's quantity should be actual minted amounts.
15+
* - The total of minted amounts can be different from the input `quantity`.
16+
*
17+
* Examples:
18+
* - ERC1155: If mintedTokenIds = [1, 2], then mintedAmounts = [10, 20]
19+
* - ERC721: If mintedTokenIds = [1, 2], then mintedAmounts = [1, 1]
20+
*
21+
* @param to The address to mint the NFTs to.
22+
* @param quantity The quantity of NFTs to mint.
23+
* @param extraData The extra data for further customization.
24+
* @return mintedTokenIds The token IDs of the minted NFTs.
25+
* @return mintedAmounts The minted amounts according to the `mintedTokenIds`.
26+
*/
27+
function mintPresale(address to, uint256 quantity, bytes calldata extraData)
28+
external
29+
returns (uint256[] memory mintedTokenIds, uint256[] memory mintedAmounts);
30+
}

src/launchpad/NFTLaunchpadCommon.sol

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ import { INFTLaunchpad } from "../interfaces/launchpad/INFTLaunchpad.sol";
77

88
abstract contract NFTLaunchpadCommon is IERC165, INFTLaunchpad {
99
/// @dev Returns whether the contract supports the NFT launchpad interface.
10-
function supportsInterface(
11-
bytes4 interfaceId
12-
) public view virtual returns (bool) {
13-
return interfaceId == type(INFTLaunchpad).interfaceId;
10+
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
11+
return interfaceId == type(INFTLaunchpad).interfaceId || interfaceId == type(IERC165).interfaceId;
1412
}
1513
}

src/launchpad/NFTPresaleCommon.sol

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.22;
3+
4+
import { IERC165 } from "@openzeppelin/contracts/interfaces/IERC165.sol";
5+
6+
import { INFTPresale } from "../interfaces/launchpad/INFTPresale.sol";
7+
8+
abstract contract NFTPresaleCommon is IERC165, INFTPresale {
9+
/// @dev Returns whether the contract supports the NFT presale interface.
10+
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
11+
return interfaceId == type(INFTPresale).interfaceId || interfaceId == type(IERC165).interfaceId;
12+
}
13+
}

src/mock/SampleERC1155.sol

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.0;
3+
4+
import "../ERC1155Common.sol";
5+
6+
contract SampleERC1155 is ERC1155Common {
7+
constructor(address admin, string memory name, string memory symbol, string memory uri)
8+
ERC1155Common(admin, name, symbol, uri)
9+
{ }
10+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.19;
3+
4+
import { NFTLaunchpadCommon } from "../../launchpad/NFTLaunchpadCommon.sol";
5+
import { SampleERC1155, ERC1155Common } from "../SampleERC1155.sol";
6+
7+
contract SampleERC1155Launchpad is SampleERC1155, NFTLaunchpadCommon {
8+
constructor(address admin, string memory name, string memory symbol, string memory uri)
9+
SampleERC1155(admin, name, symbol, uri)
10+
{ }
11+
12+
/// @dev Mint NFTs for the launchpad.
13+
function mintLaunchpad(
14+
address to,
15+
uint256 quantity,
16+
bytes calldata /* extraData */
17+
) external onlyRole(MINTER_ROLE) returns (uint256[] memory tokenIds, uint256[] memory amounts) {
18+
_mint(to, 3, quantity, "");
19+
_mint(to, 4, 1, "");
20+
21+
tokenIds = new uint256[](2);
22+
amounts = new uint256[](2);
23+
tokenIds[0] = 3;
24+
tokenIds[1] = 4;
25+
26+
amounts[0] = quantity;
27+
amounts[1] = 1;
28+
}
29+
30+
function supportsInterface(bytes4 interfaceId)
31+
public
32+
view
33+
virtual
34+
override(ERC1155Common, NFTLaunchpadCommon)
35+
returns (bool)
36+
{
37+
return ERC1155Common.supportsInterface(interfaceId) || NFTLaunchpadCommon.supportsInterface(interfaceId);
38+
}
39+
}

0 commit comments

Comments
 (0)