1
1
// SPDX-License-Identifier: MPL-2.0
2
2
pragma solidity = 0.8.9 ;
3
3
4
- import {IERC721EnumerableUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol " ;
5
- import {IERC165Upgradeable } from "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol " ;
6
- import {ERC721Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol " ;
4
+ import {Counters} from "@openzeppelin/contracts/utils/Counters.sol " ;
7
5
import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol " ;
8
6
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol " ;
9
- import {Counters } from "@openzeppelin/contracts/utils/Counters .sol " ;
7
+ import {ERC721EnumerableUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable .sol " ;
10
8
11
9
import {ISBTToken} from "./interfaces/ISBTToken.sol " ;
12
10
13
- contract SBTToken is
14
- ISBTToken ,
15
- IERC721EnumerableUpgradeable ,
16
- ERC721Upgradeable
17
- {
18
- Counters.Counter private tokenIdCounter;
19
-
20
- mapping (address => EnumerableSet.UintSet) private tokenIdsMapOfOwner;
21
- mapping (uint256 => string ) private tokenUriImage;
22
- address private proxyAdmin;
11
+ contract SBTToken is ISBTToken , ERC721EnumerableUpgradeable {
23
12
/// @dev EOA with minting rights.
24
13
address private minter;
25
-
26
- using Counters for Counters.Counter;
27
- using EnumerableSet for EnumerableSet.UintSet;
14
+ /// @dev Account with proxy adming rights.
15
+ address private proxyAdmin;
16
+ /// @dev Holds the URI information of a SBT token.
17
+ mapping (uint256 => string ) private tokenUriImage;
28
18
29
19
modifier onlyMinter () {
30
- require (minter == _msgSender (), "illegal access " );
20
+ require (minter == _msgSender (), "Illegal access " );
31
21
_;
32
22
}
33
23
24
+ event SetProxyAdmin (address _proxyAdmin );
25
+
34
26
function initialize (address _minter ) external initializer {
35
27
__ERC721_init ("Dev Protocol SBT V1 " , "DEV-SBT-V1 " );
36
28
minter = _minter;
37
29
}
38
30
39
- /**
40
- * @dev See {IERC165-supportsInterface}.
41
- */
42
- function supportsInterface (
43
- bytes4 interfaceId
44
- )
45
- public
46
- view
47
- virtual
48
- override (IERC165Upgradeable , ERC721Upgradeable )
49
- returns (bool )
50
- {
51
- return
52
- interfaceId == type (IERC721EnumerableUpgradeable ).interfaceId ||
53
- super .supportsInterface (interfaceId);
54
- }
55
-
56
- /**
57
- * @dev See {IERC721Enumerable-totalSupply}.
58
- */
59
- function totalSupply ()
60
- public
61
- view
62
- virtual
63
- override (ISBTToken, IERC721EnumerableUpgradeable )
64
- returns (uint256 )
65
- {
66
- return tokenIdCounter.current ();
67
- }
68
-
69
- /**
70
- * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
71
- */
72
- function tokenOfOwnerByIndex (
73
- address _owner ,
74
- uint256 index
75
- )
76
- public
77
- view
78
- virtual
79
- override (ISBTToken, IERC721EnumerableUpgradeable )
80
- returns (uint256 )
81
- {
82
- // solhint-disable-next-line reason-string
83
- require (
84
- index < tokenIdsMapOfOwner[_owner].length (),
85
- "ERC721Enumerable: owner index out of bounds "
86
- );
87
- return tokenIdsMapOfOwner[_owner].at (index);
88
- }
89
-
90
- /**
91
- * @dev See {IERC721Enumerable-tokenByIndex}.
92
- */
93
- function tokenByIndex (
94
- uint256 index
95
- )
96
- public
97
- view
98
- virtual
99
- override (ISBTToken, IERC721EnumerableUpgradeable )
100
- returns (uint256 )
101
- {
102
- // solhint-disable-next-line reason-string
103
- require (
104
- index < tokenIdCounter.current (),
105
- "ERC721Enumerable: global index out of bounds "
106
- );
107
- return index + 1 ;
108
- }
109
-
110
- function owner () external view returns (address ) {
111
- return ProxyAdmin (proxyAdmin).owner ();
112
- }
113
-
114
31
function setProxyAdmin (address _proxyAdmin ) external {
115
- require (proxyAdmin == address (0 ), "already set " );
32
+ require (proxyAdmin == address (0 ), "Already set " );
116
33
proxyAdmin = _proxyAdmin;
117
- }
118
-
119
- function tokenURI (
120
- uint256 _tokenId
121
- ) public view override returns (string memory ) {
122
- uint256 curretnTokenId = tokenIdCounter.current ();
123
- require (_tokenId <= curretnTokenId, "not found " );
124
- return _tokenURI (_tokenId);
125
- }
126
-
127
- function currentIndex () external view override returns (uint256 ) {
128
- return tokenIdCounter.current ();
129
- }
130
-
131
- function mint (
132
- address _owner
133
- ) external override onlyMinter returns (uint256 tokenId_ ) {
134
- tokenIdCounter.increment ();
135
- uint256 currentId = tokenIdCounter.current ();
136
- _mint (_owner, currentId);
137
- emit Minted (currentId, _owner);
138
- return currentId;
34
+ emit SetProxyAdmin (_proxyAdmin);
139
35
}
140
36
141
37
function setTokenURIImage (
@@ -145,14 +41,13 @@ contract SBTToken is
145
41
tokenUriImage[_tokenId] = _data;
146
42
}
147
43
148
- function tokensOfOwner (
44
+ function mint (
149
45
address _owner
150
- ) external view override returns (uint256 [] memory ) {
151
- return tokenIdsMapOfOwner[_owner].values ();
152
- }
153
-
154
- function _tokenURI (uint256 _tokenId ) private view returns (string memory ) {
155
- return tokenUriImage[_tokenId];
46
+ ) external override onlyMinter returns (uint256 tokenId_ ) {
47
+ uint256 currentId = this .currentIndex ();
48
+ _mint (_owner, currentId);
49
+ emit Minted (currentId, _owner);
50
+ return currentId;
156
51
}
157
52
158
53
function _beforeTokenTransfer (
@@ -161,18 +56,47 @@ contract SBTToken is
161
56
uint256 tokenId ,
162
57
uint256 batchSize
163
58
) internal virtual override {
164
- super ._beforeTokenTransfer (from, to, tokenId, batchSize);
165
-
166
59
if (from == address (0 )) {
167
- // mint
168
- tokenIdsMapOfOwner[to]. add ( tokenId);
60
+ // allow mint
61
+ super . _beforeTokenTransfer (from, to, tokenId, batchSize );
169
62
} else if (to == address (0 )) {
170
- // burn
171
- revert ("SBT is not burned " );
63
+ // disallow burn
64
+ revert ("SBT can not burn " );
172
65
} else if (to != from) {
173
- revert ("SBT is non transferrable " );
66
+ // disallow transfer
67
+ revert ("SBT can not transfer " );
174
68
} else {
69
+ // disallow other
175
70
revert ("Illegal operation " );
176
71
}
177
72
}
73
+
74
+ function _tokenURI (uint256 _tokenId ) private view returns (string memory ) {
75
+ return tokenUriImage[_tokenId];
76
+ }
77
+
78
+ function owner () external view returns (address ) {
79
+ return ProxyAdmin (proxyAdmin).owner ();
80
+ }
81
+
82
+ function tokenURI (
83
+ uint256 _tokenId
84
+ ) public view override returns (string memory ) {
85
+ return _tokenURI (_tokenId);
86
+ }
87
+
88
+ function currentIndex () external view override returns (uint256 ) {
89
+ return super .totalSupply ();
90
+ }
91
+
92
+ function tokensOfOwner (
93
+ address _owner
94
+ ) external view override returns (uint256 [] memory ) {
95
+ uint256 length = super .balanceOf (_owner);
96
+ uint256 [] memory tokens = new uint256 [](length);
97
+ for (uint256 i = 0 ; i < length; i++ ) {
98
+ tokens[i] = super .tokenOfOwnerByIndex (_owner, i);
99
+ }
100
+ return tokens;
101
+ }
178
102
}
0 commit comments