@kub-chain/contracts 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -0
- package/contracts/access/AccessController.sol +96 -0
- package/contracts/access/AccessControllerKAP.sol +116 -0
- package/contracts/access/Authorization.sol +36 -0
- package/contracts/access/AuthorizationKAP.sol +60 -0
- package/contracts/access/Committee.sol +26 -0
- package/contracts/access/Ownable.sol +39 -0
- package/contracts/interfaces/IAdminProjectRouter.sol +9 -0
- package/contracts/interfaces/IKYCBitkubChain.sol +8 -0
- package/contracts/kyc/KYCHandler.sol +24 -0
- package/contracts/libs/Address.sol +16 -0
- package/contracts/libs/EnumerableSetAddress.sol +70 -0
- package/contracts/libs/EnumerableSetUint.sol +74 -0
- package/contracts/libs/EnumerateMap.sol +136 -0
- package/contracts/libs/String.sol +26 -0
- package/contracts/token/KAP-1155/KAP1155.sol +493 -0
- package/contracts/token/KAP-1155/interfaces/IKAP1155.sol +69 -0
- package/contracts/token/KAP-1155/interfaces/IKAP1155Enumerable.sol +7 -0
- package/contracts/token/KAP-1155/interfaces/IKAP1155Metadata.sol +12 -0
- package/contracts/token/KAP-1155/interfaces/IKAP1155Receiver.sol +20 -0
- package/contracts/token/KAP-20/KAP20.sol +276 -0
- package/contracts/token/KAP-20/interfaces/IKAP20.sol +43 -0
- package/contracts/token/KAP-20/interfaces/IKToken.sol +17 -0
- package/contracts/token/KAP-22/KAP22.sol +358 -0
- package/contracts/token/KAP-22/interfaces/IKAP22.sol +23 -0
- package/contracts/token/KAP-22/utils/TransferRouter.sol +29 -0
- package/contracts/token/KAP-22/utils/WhitelistAddress.sol +35 -0
- package/contracts/token/KAP-721/KAP721.sol +416 -0
- package/contracts/token/KAP-721/interfaces/IKAP721.sol +60 -0
- package/contracts/token/KAP-721/interfaces/IKAP721Enumerable.sol +10 -0
- package/contracts/token/KAP-721/interfaces/IKAP721Metadata.sol +10 -0
- package/contracts/token/KAP-721/interfaces/IKAP721Receiver.sol +11 -0
- package/contracts/token/KAP-721/interfaces/IKAP721V2.sol +20 -0
- package/contracts/utils/Context.sol +13 -0
- package/contracts/utils/Pausable.sol +34 -0
- package/contracts/utils/introspections/IKAP165.sol +6 -0
- package/contracts/utils/introspections/KAP165.sol +12 -0
- package/package.json +26 -0
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.0;
|
|
4
|
+
|
|
5
|
+
import {AccessController} from "../../access/AccessController.sol";
|
|
6
|
+
import {Pausable} from "../../utils/Pausable.sol";
|
|
7
|
+
import {IKAP721} from "./interfaces/IKAP721.sol";
|
|
8
|
+
import {IKAP721V2} from "./interfaces/IKAP721V2.sol";
|
|
9
|
+
import {IKAP721Metadata} from "./interfaces/IKAP721Metadata.sol";
|
|
10
|
+
import {IKAP721Enumerable} from "./interfaces/IKAP721Enumerable.sol";
|
|
11
|
+
import {KAP165, IKAP165} from "../../utils/introspections/KAP165.sol";
|
|
12
|
+
import {IKYCBitkubChain} from "../../interfaces/IKYCBitkubChain.sol";
|
|
13
|
+
import {IAdminProjectRouter} from "../../interfaces/IAdminProjectRouter.sol";
|
|
14
|
+
import {Address} from "../../libs/Address.sol";
|
|
15
|
+
import {Strings} from "../../libs/String.sol";
|
|
16
|
+
import {EnumerableSetUint} from "../../libs/EnumerableSetUint.sol";
|
|
17
|
+
import {EnumerableMap} from "../../libs/EnumerateMap.sol";
|
|
18
|
+
import {IKAP721Receiver} from "./interfaces/IKAP721Receiver.sol";
|
|
19
|
+
|
|
20
|
+
abstract contract KAP721 is KAP165, IKAP721, IKAP721V2, IKAP721Metadata, IKAP721Enumerable, AccessController, Pausable {
|
|
21
|
+
using Address for address;
|
|
22
|
+
using EnumerableSetUint for EnumerableSetUint.UintSet;
|
|
23
|
+
using EnumerableMap for EnumerableMap.UintToAddressMap;
|
|
24
|
+
using Strings for uint256;
|
|
25
|
+
|
|
26
|
+
// Mapping from holder address to their (enumerable) set of owned tokens
|
|
27
|
+
mapping(address => EnumerableSetUint.UintSet) _holderTokens;
|
|
28
|
+
|
|
29
|
+
// Enumerable mapping from token ids to their owners
|
|
30
|
+
EnumerableMap.UintToAddressMap private _tokenOwners;
|
|
31
|
+
|
|
32
|
+
// Mapping from token ID to approved address
|
|
33
|
+
mapping(uint256 => address) private _tokenApprovals;
|
|
34
|
+
|
|
35
|
+
// Mapping from owner to operator approvals
|
|
36
|
+
mapping(address => mapping(address => bool)) private _operatorApprovals;
|
|
37
|
+
|
|
38
|
+
// Token name
|
|
39
|
+
string public override name;
|
|
40
|
+
|
|
41
|
+
// Token symbol
|
|
42
|
+
string public override symbol;
|
|
43
|
+
|
|
44
|
+
// Optional mapping for token URIs
|
|
45
|
+
mapping(uint256 => string) private _tokenURIs;
|
|
46
|
+
|
|
47
|
+
// Base URI
|
|
48
|
+
string public baseURI;
|
|
49
|
+
|
|
50
|
+
/*
|
|
51
|
+
* bytes4(keccak256('balanceOf(address)')) == 0x70a08231
|
|
52
|
+
* bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
|
|
53
|
+
* bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
|
|
54
|
+
* bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
|
|
55
|
+
* bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
|
|
56
|
+
* bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
|
|
57
|
+
* bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
|
|
58
|
+
* bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
|
|
59
|
+
* bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
|
|
60
|
+
*
|
|
61
|
+
* => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
|
|
62
|
+
* 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
|
|
63
|
+
*/
|
|
64
|
+
bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
|
|
65
|
+
|
|
66
|
+
constructor(
|
|
67
|
+
string memory _name,
|
|
68
|
+
string memory _symbol,
|
|
69
|
+
string memory _baseURI,
|
|
70
|
+
string memory _projectName,
|
|
71
|
+
address _kyc,
|
|
72
|
+
address _adminProjectRouter,
|
|
73
|
+
address _committee,
|
|
74
|
+
address _transferRouter,
|
|
75
|
+
uint256 _acceptedKYCLevel
|
|
76
|
+
) {
|
|
77
|
+
name = _name;
|
|
78
|
+
symbol = _symbol;
|
|
79
|
+
baseURI = _baseURI;
|
|
80
|
+
PROJECT = _projectName;
|
|
81
|
+
kyc = IKYCBitkubChain(_kyc);
|
|
82
|
+
adminProjectRouter = IAdminProjectRouter(_adminProjectRouter);
|
|
83
|
+
committee = _committee;
|
|
84
|
+
transferRouter = _transferRouter;
|
|
85
|
+
acceptedKYCLevel = _acceptedKYCLevel;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function supportsInterface(bytes4 interfaceId) public view virtual override(KAP165, IKAP165) returns (bool) {
|
|
89
|
+
return
|
|
90
|
+
interfaceId == _INTERFACE_ID_ERC721 ||
|
|
91
|
+
interfaceId == type(IKAP721).interfaceId ||
|
|
92
|
+
interfaceId == type(IKAP721Metadata).interfaceId ||
|
|
93
|
+
interfaceId == type(IKAP721Enumerable).interfaceId ||
|
|
94
|
+
super.supportsInterface(interfaceId);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function balanceOf(address owner) public view virtual override returns (uint256) {
|
|
98
|
+
require(owner != address(0), "KAP721: balance query for the zero address");
|
|
99
|
+
return _holderTokens[owner].length();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
|
|
103
|
+
return _tokenOwners.get(tokenId, "KAP721: owner query for nonexistent token");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
|
|
107
|
+
require(_exists(tokenId), "KAP721Metadata: URI query for nonexistent token");
|
|
108
|
+
|
|
109
|
+
string memory _tokenURI = _tokenURIs[tokenId];
|
|
110
|
+
string memory base = baseURI;
|
|
111
|
+
|
|
112
|
+
// If there is no base URI, return the token URI.
|
|
113
|
+
if (bytes(base).length == 0) {
|
|
114
|
+
return _tokenURI;
|
|
115
|
+
}
|
|
116
|
+
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
|
|
117
|
+
if (bytes(_tokenURI).length > 0) {
|
|
118
|
+
return string(abi.encodePacked(base, _tokenURI));
|
|
119
|
+
}
|
|
120
|
+
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
|
|
121
|
+
return string(abi.encodePacked(base, tokenId.toString()));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function tokenOfOwnerByPage(
|
|
125
|
+
address _owner,
|
|
126
|
+
uint256 _page,
|
|
127
|
+
uint256 _limit
|
|
128
|
+
) public view virtual override returns (uint256[] memory) {
|
|
129
|
+
return _holderTokens[_owner].get(_page, _limit);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function tokenOfOwnerAll(address _owner) public view virtual override returns (uint256[] memory) {
|
|
133
|
+
return _holderTokens[_owner].getAll();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
|
|
137
|
+
return _holderTokens[owner].at(index);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function totalSupply() public view virtual override returns (uint256) {
|
|
141
|
+
// _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds
|
|
142
|
+
return _tokenOwners.length();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
|
|
146
|
+
(uint256 tokenId, ) = _tokenOwners.at(index);
|
|
147
|
+
return tokenId;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function approve(address to, uint256 tokenId) public virtual override whenNotPaused {
|
|
151
|
+
address owner = KAP721.ownerOf(tokenId);
|
|
152
|
+
require(to != owner, "KAP721: approval to current owner");
|
|
153
|
+
|
|
154
|
+
require(
|
|
155
|
+
msg.sender == owner || isApprovedForAll(owner, msg.sender),
|
|
156
|
+
"KAP721: approve caller is not owner nor approved for all"
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
_approve(to, tokenId);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function adminApprove(address to, uint256 tokenId) public virtual override onlySuperAdmin whenNotPaused {
|
|
163
|
+
address owner = ownerOf(tokenId);
|
|
164
|
+
require(to != owner, "KAP721: approval to current owner");
|
|
165
|
+
|
|
166
|
+
require(
|
|
167
|
+
kyc.kycsLevel(owner) >= acceptedKYCLevel && (to == address(0) || kyc.kycsLevel(to) >= acceptedKYCLevel),
|
|
168
|
+
"KAP721: owner or to address is not a KYC user"
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
_approve(to, tokenId);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function getApproved(uint256 tokenId) public view virtual override returns (address) {
|
|
175
|
+
require(_exists(tokenId), "KAP721: approved query for nonexistent token");
|
|
176
|
+
|
|
177
|
+
return _tokenApprovals[tokenId];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function setApprovalForAll(address operator, bool approved) public virtual override whenNotPaused {
|
|
181
|
+
require(operator != msg.sender, "KAP721: approve to caller");
|
|
182
|
+
|
|
183
|
+
_setApprovalForAll(msg.sender, operator, approved);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function adminSetApprovalForAll(
|
|
187
|
+
address owner,
|
|
188
|
+
address operator,
|
|
189
|
+
bool approved
|
|
190
|
+
) public virtual override onlySuperAdmin whenNotPaused {
|
|
191
|
+
require(operator != owner, "KAP721: approve to caller");
|
|
192
|
+
|
|
193
|
+
require(
|
|
194
|
+
kyc.kycsLevel(owner) >= acceptedKYCLevel && kyc.kycsLevel(operator) >= acceptedKYCLevel,
|
|
195
|
+
"KAP721: owner or operator address is not a KYC user"
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
_setApprovalForAll(owner, operator, approved);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
|
|
202
|
+
return _operatorApprovals[owner][operator];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function transferFrom(
|
|
206
|
+
address from,
|
|
207
|
+
address to,
|
|
208
|
+
uint256 tokenId
|
|
209
|
+
) public virtual override whenNotPaused {
|
|
210
|
+
require(_isApprovedOrOwner(msg.sender, tokenId), "KAP721: transfer caller is not owner nor approved");
|
|
211
|
+
|
|
212
|
+
_transfer(from, to, tokenId);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function adminTransfer(
|
|
216
|
+
address _from,
|
|
217
|
+
address _to,
|
|
218
|
+
uint256 _tokenId
|
|
219
|
+
) public virtual override onlyCommittee {
|
|
220
|
+
if (isActivatedOnlyKYCAddress) {
|
|
221
|
+
require(kyc.kycsLevel(_from) > 0 && kyc.kycsLevel(_to) > 0, "KAP721: only internal purpose");
|
|
222
|
+
}
|
|
223
|
+
require(ownerOf(_tokenId) == _from, "KAP721: transfer of token that is not own"); // internal owner
|
|
224
|
+
|
|
225
|
+
// Clear approvals from the previous owner
|
|
226
|
+
_approve(address(0), _tokenId);
|
|
227
|
+
|
|
228
|
+
_holderTokens[_from].remove(_tokenId);
|
|
229
|
+
_holderTokens[_to].add(_tokenId);
|
|
230
|
+
|
|
231
|
+
_tokenOwners.set(_tokenId, _to);
|
|
232
|
+
|
|
233
|
+
emit Transfer(_from, _to, _tokenId);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function internalTransfer(
|
|
237
|
+
address sender,
|
|
238
|
+
address recipient,
|
|
239
|
+
uint256 tokenId
|
|
240
|
+
) external override onlySuperAdminOrTransferRouter whenNotPaused returns (bool) {
|
|
241
|
+
require(
|
|
242
|
+
kyc.kycsLevel(sender) >= acceptedKYCLevel && kyc.kycsLevel(recipient) >= acceptedKYCLevel,
|
|
243
|
+
"KAP721: only internal purpose"
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
_transfer(sender, recipient, tokenId);
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function externalTransfer(
|
|
251
|
+
address sender,
|
|
252
|
+
address recipient,
|
|
253
|
+
uint256 tokenId
|
|
254
|
+
) external override onlySuperAdminOrTransferRouter whenNotPaused returns (bool) {
|
|
255
|
+
require(kyc.kycsLevel(sender) >= acceptedKYCLevel, "KAP721: only internal purpose");
|
|
256
|
+
|
|
257
|
+
_transfer(sender, recipient, tokenId);
|
|
258
|
+
return true;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function safeTransferFrom(
|
|
262
|
+
address from,
|
|
263
|
+
address to,
|
|
264
|
+
uint256 tokenId
|
|
265
|
+
) public virtual override whenNotPaused {
|
|
266
|
+
safeTransferFrom(from, to, tokenId, "");
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function safeTransferFrom(
|
|
270
|
+
address from,
|
|
271
|
+
address to,
|
|
272
|
+
uint256 tokenId,
|
|
273
|
+
bytes memory _data
|
|
274
|
+
) public virtual override whenNotPaused {
|
|
275
|
+
require(_isApprovedOrOwner(msg.sender, tokenId), "KAP721: transfer caller is not owner nor approved");
|
|
276
|
+
_safeTransfer(from, to, tokenId, _data);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function _safeTransfer(
|
|
280
|
+
address from,
|
|
281
|
+
address to,
|
|
282
|
+
uint256 tokenId,
|
|
283
|
+
bytes memory _data
|
|
284
|
+
) internal virtual {
|
|
285
|
+
_transfer(from, to, tokenId);
|
|
286
|
+
require(_checkOnKAP721Received(from, to, tokenId, _data), "KAP721: transfer to non KAP721Receiver implementer");
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function _exists(uint256 tokenId) internal view virtual returns (bool) {
|
|
290
|
+
return _tokenOwners.contains(tokenId);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
|
|
294
|
+
require(_exists(tokenId), "KAP721: operator query for nonexistent token");
|
|
295
|
+
address owner = KAP721.ownerOf(tokenId);
|
|
296
|
+
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function _safeMint(address to, uint256 tokenId) internal virtual {
|
|
300
|
+
_safeMint(to, tokenId, "");
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function _safeMint(
|
|
304
|
+
address to,
|
|
305
|
+
uint256 tokenId,
|
|
306
|
+
bytes memory _data
|
|
307
|
+
) internal virtual {
|
|
308
|
+
_mint(to, tokenId);
|
|
309
|
+
require(
|
|
310
|
+
_checkOnKAP721Received(address(0), to, tokenId, _data),
|
|
311
|
+
"KAP721: transfer to non KAP721Receiver implementer"
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function _mint(address to, uint256 tokenId) internal virtual {
|
|
316
|
+
require(to != address(0), "KAP721: mint to the zero address");
|
|
317
|
+
require(!_exists(tokenId), "KAP721: token already minted");
|
|
318
|
+
|
|
319
|
+
_beforeTokenTransfer(address(0), to, tokenId);
|
|
320
|
+
|
|
321
|
+
_holderTokens[to].add(tokenId);
|
|
322
|
+
|
|
323
|
+
_tokenOwners.set(tokenId, to);
|
|
324
|
+
|
|
325
|
+
emit Transfer(address(0), to, tokenId);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function _burn(uint256 tokenId) internal virtual {
|
|
329
|
+
address owner = ownerOf(tokenId); // internal owner
|
|
330
|
+
|
|
331
|
+
_beforeTokenTransfer(owner, address(0), tokenId);
|
|
332
|
+
|
|
333
|
+
// Clear approvals
|
|
334
|
+
_approve(address(0), tokenId);
|
|
335
|
+
|
|
336
|
+
_holderTokens[owner].remove(tokenId);
|
|
337
|
+
_holderTokens[address(0)].add(tokenId);
|
|
338
|
+
|
|
339
|
+
_tokenOwners.set(tokenId, address(0));
|
|
340
|
+
|
|
341
|
+
emit Transfer(owner, address(0), tokenId);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function _transfer(
|
|
345
|
+
address from,
|
|
346
|
+
address to,
|
|
347
|
+
uint256 tokenId
|
|
348
|
+
) internal virtual {
|
|
349
|
+
require(KAP721.ownerOf(tokenId) == from, "KAP721: transfer of token that is not own");
|
|
350
|
+
require(to != address(0), "KAP721: transfer to the zero address");
|
|
351
|
+
|
|
352
|
+
_beforeTokenTransfer(from, to, tokenId);
|
|
353
|
+
|
|
354
|
+
// Clear approvals from the previous owner
|
|
355
|
+
_approve(address(0), tokenId);
|
|
356
|
+
|
|
357
|
+
_holderTokens[from].remove(tokenId);
|
|
358
|
+
_holderTokens[to].add(tokenId);
|
|
359
|
+
|
|
360
|
+
_tokenOwners.set(tokenId, to);
|
|
361
|
+
|
|
362
|
+
emit Transfer(from, to, tokenId);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
|
|
366
|
+
require(_exists(tokenId), "KAP721Metadata: URI set of nonexistent token");
|
|
367
|
+
_tokenURIs[tokenId] = _tokenURI;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function _setBaseURI(string memory baseURI_) internal virtual {
|
|
371
|
+
baseURI = baseURI_;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function _checkOnKAP721Received(
|
|
375
|
+
address from,
|
|
376
|
+
address to,
|
|
377
|
+
uint256 tokenId,
|
|
378
|
+
bytes memory _data
|
|
379
|
+
) private returns (bool) {
|
|
380
|
+
if (to.isContract()) {
|
|
381
|
+
try IKAP721Receiver(to).onKAP721Received(msg.sender, from, tokenId, _data) returns (bytes4 retval) {
|
|
382
|
+
return retval == IKAP721Receiver.onKAP721Received.selector;
|
|
383
|
+
} catch (bytes memory reason) {
|
|
384
|
+
if (reason.length == 0) {
|
|
385
|
+
revert("KAP721: transfer to non KAP721Receiver implementer");
|
|
386
|
+
} else {
|
|
387
|
+
assembly {
|
|
388
|
+
revert(add(32, reason), mload(reason))
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
} else {
|
|
393
|
+
return true;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function _approve(address to, uint256 tokenId) internal virtual {
|
|
398
|
+
_tokenApprovals[tokenId] = to;
|
|
399
|
+
emit Approval(KAP721.ownerOf(tokenId), to, tokenId);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function _setApprovalForAll(
|
|
403
|
+
address owner,
|
|
404
|
+
address operator,
|
|
405
|
+
bool approved
|
|
406
|
+
) internal virtual {
|
|
407
|
+
_operatorApprovals[owner][operator] = approved;
|
|
408
|
+
emit ApprovalForAll(owner, operator, approved);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function _beforeTokenTransfer(
|
|
412
|
+
address from,
|
|
413
|
+
address to,
|
|
414
|
+
uint256 tokenId
|
|
415
|
+
) internal virtual {}
|
|
416
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
//SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity >=0.6.0 <0.9.0;
|
|
4
|
+
|
|
5
|
+
import {IKAP165} from "../../../utils/introspections/KAP165.sol";
|
|
6
|
+
|
|
7
|
+
interface IKAP721 is IKAP165 {
|
|
8
|
+
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
|
|
9
|
+
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
|
|
10
|
+
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
|
|
11
|
+
|
|
12
|
+
function balanceOf(address owner) external view returns (uint256 balance);
|
|
13
|
+
|
|
14
|
+
function ownerOf(uint256 tokenId) external view returns (address owner);
|
|
15
|
+
|
|
16
|
+
function safeTransferFrom(
|
|
17
|
+
address from,
|
|
18
|
+
address to,
|
|
19
|
+
uint256 tokenId
|
|
20
|
+
) external;
|
|
21
|
+
|
|
22
|
+
function transferFrom(
|
|
23
|
+
address from,
|
|
24
|
+
address to,
|
|
25
|
+
uint256 tokenId
|
|
26
|
+
) external;
|
|
27
|
+
|
|
28
|
+
function adminTransfer(
|
|
29
|
+
address from,
|
|
30
|
+
address to,
|
|
31
|
+
uint256 tokenId
|
|
32
|
+
) external;
|
|
33
|
+
|
|
34
|
+
function internalTransfer(
|
|
35
|
+
address from,
|
|
36
|
+
address to,
|
|
37
|
+
uint256 tokenId
|
|
38
|
+
) external returns (bool);
|
|
39
|
+
|
|
40
|
+
function externalTransfer(
|
|
41
|
+
address from,
|
|
42
|
+
address to,
|
|
43
|
+
uint256 tokenId
|
|
44
|
+
) external returns (bool);
|
|
45
|
+
|
|
46
|
+
function approve(address to, uint256 tokenId) external;
|
|
47
|
+
|
|
48
|
+
function getApproved(uint256 tokenId) external view returns (address operator);
|
|
49
|
+
|
|
50
|
+
function setApprovalForAll(address operator, bool approved) external;
|
|
51
|
+
|
|
52
|
+
function isApprovedForAll(address owner, address operator) external view returns (bool);
|
|
53
|
+
|
|
54
|
+
function safeTransferFrom(
|
|
55
|
+
address from,
|
|
56
|
+
address to,
|
|
57
|
+
uint256 tokenId,
|
|
58
|
+
bytes calldata data
|
|
59
|
+
) external;
|
|
60
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity >=0.6.0 <0.9.0;
|
|
3
|
+
|
|
4
|
+
interface IKAP721Enumerable {
|
|
5
|
+
function totalSupply() external view returns (uint256);
|
|
6
|
+
|
|
7
|
+
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);
|
|
8
|
+
|
|
9
|
+
function tokenByIndex(uint256 index) external view returns (uint256);
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity >=0.6.0 <0.9.0;
|
|
3
|
+
|
|
4
|
+
interface IKAP721Metadata {
|
|
5
|
+
function name() external view returns (string memory);
|
|
6
|
+
|
|
7
|
+
function symbol() external view returns (string memory);
|
|
8
|
+
|
|
9
|
+
function tokenURI(uint256 tokenId) external view returns (string memory);
|
|
10
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity >=0.6.0 <0.9.0;
|
|
3
|
+
|
|
4
|
+
interface IKAP721V2 {
|
|
5
|
+
function tokenOfOwnerByPage(
|
|
6
|
+
address owner,
|
|
7
|
+
uint256 page,
|
|
8
|
+
uint256 limit
|
|
9
|
+
) external view returns (uint256[] memory);
|
|
10
|
+
|
|
11
|
+
function tokenOfOwnerAll(address owner) external view returns (uint256[] memory);
|
|
12
|
+
|
|
13
|
+
function adminApprove(address to, uint256 tokenId) external;
|
|
14
|
+
|
|
15
|
+
function adminSetApprovalForAll(
|
|
16
|
+
address owner,
|
|
17
|
+
address operator,
|
|
18
|
+
bool approved
|
|
19
|
+
) external;
|
|
20
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.0;
|
|
4
|
+
|
|
5
|
+
abstract contract Context {
|
|
6
|
+
function _msgSender() internal view virtual returns (address) {
|
|
7
|
+
return msg.sender;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function _msgData() internal view virtual returns (bytes calldata) {
|
|
11
|
+
return msg.data;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.0;
|
|
4
|
+
|
|
5
|
+
abstract contract Pausable {
|
|
6
|
+
event Paused(address account);
|
|
7
|
+
event Unpaused(address account);
|
|
8
|
+
|
|
9
|
+
bool public paused;
|
|
10
|
+
|
|
11
|
+
constructor() {
|
|
12
|
+
paused = false;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
modifier whenNotPaused() {
|
|
16
|
+
require(!paused, "Pausable: paused");
|
|
17
|
+
_;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
modifier whenPaused() {
|
|
21
|
+
require(paused, "Pausable: not paused");
|
|
22
|
+
_;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function _pause() internal virtual whenNotPaused {
|
|
26
|
+
paused = true;
|
|
27
|
+
emit Paused(msg.sender);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function _unpause() internal virtual whenPaused {
|
|
31
|
+
paused = false;
|
|
32
|
+
emit Unpaused(msg.sender);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.0;
|
|
4
|
+
|
|
5
|
+
import {IKAP165} from "./IKAP165.sol";
|
|
6
|
+
|
|
7
|
+
// Minimal KAP165 abstract
|
|
8
|
+
abstract contract KAP165 is IKAP165 {
|
|
9
|
+
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
|
|
10
|
+
return interfaceId == type(IKAP165).interfaceId;
|
|
11
|
+
}
|
|
12
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kub-chain/contracts",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A library of Solidity smart contracts implementing the KAP token standards and supporting access-control, KYC, and utility primitives for the KUB Chain (https://kubchain.com/) ecosystem.",
|
|
5
|
+
"files": [
|
|
6
|
+
"contracts/**/*.sol"
|
|
7
|
+
],
|
|
8
|
+
"keywords": [
|
|
9
|
+
"solidity",
|
|
10
|
+
"kubchain",
|
|
11
|
+
"kap20",
|
|
12
|
+
"kap20",
|
|
13
|
+
"kap721",
|
|
14
|
+
"kap1155"
|
|
15
|
+
],
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/kub-chain/kub-contracts.git"
|
|
19
|
+
},
|
|
20
|
+
"author": "kubchain",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/kub-chain/kub-contracts/issues"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://www.kubchain.com/"
|
|
26
|
+
}
|