/
Stickers.sol
107 lines (95 loc) · 3.12 KB
/
Stickers.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
import { ERC721A } from "ERC721A/ERC721A.sol";
import { IERC721A } from "ERC721A/IERC721A.sol";
import { OwnableRoles } from "solady/auth/OwnableRoles.sol";
import { BaseERC721A } from "@/common/BaseERC721A.sol";
import { IBaseERC721A } from "@/common/IBaseERC721A.sol";
import { IStickers, StickerMetadata, StickerRarity, StickerMint } from "@/stickers/IStickers.sol";
import { VRFConfig } from "@/types/VRFConfig.sol";
/// @title Stickers
/// @author Mathieu Bour for Pooky Labs Ltd.
/// @dev Implemented roles:
/// - Owner: allowed to change metadata of the Stickers
/// - `MINTER`: allowed to mint new Stickers
/// - `GAME`: allowed to change the game attributes of the Stickers
contract Stickers is IStickers, BaseERC721A, OwnableRoles {
uint248 constant DEFAULT_LEVEL = 0;
// Roles
uint256 public constant MINTER = _ROLE_0;
uint256 public constant GAME = _ROLE_1;
/// @notice Tokens gameplay metadata, see `StickerMetadata`
mapping(uint256 => StickerMetadata) _metadata;
constructor(address admin, address _receiver, VRFConfig memory _vrf)
BaseERC721A(
admin,
"Pooky Stickers",
"STK",
"https://metadata.pooky.gg/stickers/",
"https://metadata.pooky.gg/contracts/Stickers.json",
_vrf,
_receiver,
500 // 5% royalties by default
)
{ }
/// @notice Get the StickerMetadata of the token `tokenId`.
/// @dev Requirements:
/// - Sticker `tokenId` should exist (minted and not burned).
function metadata(uint256 tokenId)
external
view
onlyExists(tokenId)
returns (StickerMetadata memory)
{
return _metadata[tokenId];
}
/// @notice Change the level of a Sticker token.
/// @dev Requirements:
/// - sender must have the `GAME` role or be the owner.
/// - Sticker `tokenId` should exist (minted and not burned).
function setLevel(uint256 tokenId, uint248 newLevel)
external
onlyExists(tokenId)
onlyRolesOrOwner(GAME)
{
_metadata[tokenId].level = newLevel;
emit LevelChanged(tokenId, newLevel);
}
/// @notice Mint a new Sticker token with a given rarity.
/// Level and seed are set to zero, entropy is requested to the VRF coordinator.
/// @dev Requirements:
/// - sender must have the `MINTER` role or be the owner.
function mint(address recipient, StickerRarity[] memory rarities)
external
onlyRolesOrOwner(MINTER)
{
uint256 quantity = rarities.length;
uint256 start = _nextTokenId();
_mint(recipient, quantity);
for (uint256 i = 0; i < quantity;) {
_metadata[start + i] = StickerMetadata(
DEFAULT_LEVEL, // Stickers are level 0 by default
rarities[i]
);
unchecked {
i++;
}
}
}
// ----- ERC165 -----
/// @notice IERC165 declaration.
/// @dev Supports the following `interfaceId`s:
/// - IERC165: 0x01ffc9a7
/// - IERC721: 0x80ac58cd
/// - IERC721Metadata: 0x5b5e139f
/// - IERC2981: 0x2a55205a
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(BaseERC721A, IBaseERC721A)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}