Skip to content

Commit a13c74e

Browse files
author
Yash Agrawal
committed
feat: use ERC721EnumerableUpgradeable in SBT
1 parent 5d0a420 commit a13c74e

File tree

3 files changed

+55
-155
lines changed

3 files changed

+55
-155
lines changed

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010
}
1111
],
1212
"editor.codeActionsOnSave": {
13-
"source.fixAll.eslint": true
13+
"source.fixAll.eslint": "explicit"
1414
}
1515
}

contracts/SBTToken.sol

Lines changed: 54 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -1,141 +1,37 @@
11
// SPDX-License-Identifier: MPL-2.0
22
pragma solidity =0.8.9;
33

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";
75
import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
86
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";
108

119
import {ISBTToken} from "./interfaces/ISBTToken.sol";
1210

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 {
2312
/// @dev EOA with minting rights.
2413
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;
2818

2919
modifier onlyMinter() {
30-
require(minter == _msgSender(), "illegal access");
20+
require(minter == _msgSender(), "Illegal access");
3121
_;
3222
}
3323

24+
event SetProxyAdmin(address _proxyAdmin);
25+
3426
function initialize(address _minter) external initializer {
3527
__ERC721_init("Dev Protocol SBT V1", "DEV-SBT-V1");
3628
minter = _minter;
3729
}
3830

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-
11431
function setProxyAdmin(address _proxyAdmin) external {
115-
require(proxyAdmin == address(0), "already set");
32+
require(proxyAdmin == address(0), "Already set");
11633
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);
13935
}
14036

14137
function setTokenURIImage(
@@ -145,14 +41,13 @@ contract SBTToken is
14541
tokenUriImage[_tokenId] = _data;
14642
}
14743

148-
function tokensOfOwner(
44+
function mint(
14945
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;
15651
}
15752

15853
function _beforeTokenTransfer(
@@ -161,18 +56,47 @@ contract SBTToken is
16156
uint256 tokenId,
16257
uint256 batchSize
16358
) internal virtual override {
164-
super._beforeTokenTransfer(from, to, tokenId, batchSize);
165-
16659
if (from == address(0)) {
167-
// mint
168-
tokenIdsMapOfOwner[to].add(tokenId);
60+
// allow mint
61+
super._beforeTokenTransfer(from, to, tokenId, batchSize);
16962
} else if (to == address(0)) {
170-
// burn
171-
revert("SBT is not burned");
63+
// disallow burn
64+
revert("SBT can not burn");
17265
} else if (to != from) {
173-
revert("SBT is non transferrable");
66+
// disallow transfer
67+
revert("SBT can not transfer");
17468
} else {
69+
// disallow other
17570
revert("Illegal operation");
17671
}
17772
}
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+
}
178102
}

contracts/interfaces/ISBTToken.sol

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,28 +38,4 @@ interface ISBTToken {
3838
* @return uint256 current token id
3939
*/
4040
function currentIndex() external view returns (uint256);
41-
42-
/// @notice Count NFTs tracked by this contract
43-
/// @return A count of valid NFTs tracked by this contract, where each one of
44-
/// them has an assigned and queryable owner not equal to the zero address
45-
function totalSupply() external view returns (uint256);
46-
47-
/// @notice Enumerate valid NFTs
48-
/// @dev Throws if `_index` >= `totalSupply()`.
49-
/// @param _index A counter less than `totalSupply()`
50-
/// @return The token identifier for the `_index`th NFT,
51-
/// (sort order not specified)
52-
function tokenByIndex(uint256 _index) external view returns (uint256);
53-
54-
/// @notice Enumerate NFTs assigned to an owner
55-
/// @dev Throws if `_index` >= `balanceOf(_owner)` or if
56-
/// `_owner` is the zero address, representing invalid NFTs.
57-
/// @param _owner An address where we are interested in NFTs owned by them
58-
/// @param _index A counter less than `balanceOf(_owner)`
59-
/// @return The token identifier for the `_index`th NFT assigned to `_owner`,
60-
/// (sort order not specified)
61-
function tokenOfOwnerByIndex(
62-
address _owner,
63-
uint256 _index
64-
) external view returns (uint256);
6541
}

0 commit comments

Comments
 (0)