@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
package/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# KUB Contracts
|
|
2
|
+
|
|
3
|
+
A library of Solidity smart contracts implementing the **KAP token standards** and supporting access-control, KYC, and utility primitives for the [KUB](https://kubchain.com/) ecosystem.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This repository provides reusable, abstract base contracts for building KAP-compliant tokens and applications on KUB:
|
|
8
|
+
|
|
9
|
+
- **KAP token standards** - fungible (KAP-20, KAP-22), non-fungible (KAP-721), and multi-token (KAP-1155) implementations.
|
|
10
|
+
- **Access control** — owner, committee, and project-router-based authorization models.
|
|
11
|
+
- **KYC integration** — hooks into KUB's on-chain KYC registry to enforce KYC-level requirements.
|
|
12
|
+
- **Utilities & libraries** — pausing, introspection (KAP-165), and gas-efficient enumerable data structures.
|
|
13
|
+
|
|
14
|
+
All contracts target Solidity `^0.8.0` and are released under the MIT license.
|
|
15
|
+
|
|
16
|
+
## Repository structure
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
contracts/
|
|
20
|
+
├── token/
|
|
21
|
+
│ ├── KAP-20/ Fungible token standard (ERC-20-like) with KYC + admin routing
|
|
22
|
+
│ ├── KAP-22/ Period/stamp-based fungible token with transfer routing & whitelist
|
|
23
|
+
│ ├── KAP-721/ Non-fungible token standard (ERC-721-like), enumerable + metadata
|
|
24
|
+
│ └── KAP-1155/ Multi-token standard (ERC-1155-like), enumerable + metadata
|
|
25
|
+
├── access/ Ownable, Committee, Authorization(KAP), AccessController(KAP)
|
|
26
|
+
├── kyc/ KYCHandler — KYC level enforcement against the KUB KYC registry
|
|
27
|
+
├── utils/ Pausable, Context, KAP-165 introspection
|
|
28
|
+
├── libs/ Address, String, EnumerableSet (uint/address), EnumerableMap
|
|
29
|
+
└── interfaces/ IAdminProjectRouter, IKYCBitkubChain
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Token standards
|
|
33
|
+
|
|
34
|
+
| Standard | Type | Description |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| **KAP-20** | Fungible | ERC-20-style token integrated with KYC, the admin project router, committee control, and a transfer router. |
|
|
37
|
+
| **KAP-22** | Fungible | Period-based ("stamp") token tracking balances per period, with a transfer router and address whitelist. |
|
|
38
|
+
| **KAP-721** | Non-fungible | ERC-721-style NFT with enumerable and metadata extensions. |
|
|
39
|
+
| **KAP-1155** | Multi-token | ERC-1155-style token with enumerable and metadata extensions. |
|
|
40
|
+
|
|
41
|
+
### Access & KYC
|
|
42
|
+
|
|
43
|
+
- **Ownable / Committee** — single-owner and committee-governed roles.
|
|
44
|
+
- **Authorization / AuthorizationKAP** — permissioning via an `AdminProjectRouter`.
|
|
45
|
+
- **AccessController / AccessControllerKAP** — compose Ownable, Committee, Authorization, and KYCHandler, adding helpers such as `onlyOwnerOrCommittee` and transfer-router management.
|
|
46
|
+
- **KYCHandler** — stores the accepted KYC level and toggles whether only KYC-verified addresses may interact, validating against `IKYCBitkubChain`.
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
These are abstract base contracts intended to be inherited and configured by your concrete token. For example, a KAP-20 token is constructed with its name, symbol, project name, decimals, and the addresses of the KYC registry, admin project router, committee, and transfer router, along with the accepted KYC level:
|
|
51
|
+
|
|
52
|
+
```solidity
|
|
53
|
+
// SPDX-License-Identifier: MIT
|
|
54
|
+
pragma solidity ^0.8.0;
|
|
55
|
+
|
|
56
|
+
import {KAP20} from "./contracts/token/KAP-20/KAP20.sol";
|
|
57
|
+
|
|
58
|
+
contract MyToken is KAP20 {
|
|
59
|
+
constructor(
|
|
60
|
+
address kyc,
|
|
61
|
+
address adminProjectRouter,
|
|
62
|
+
address committee,
|
|
63
|
+
address transferRouter
|
|
64
|
+
)
|
|
65
|
+
KAP20(
|
|
66
|
+
"My Token", // name
|
|
67
|
+
"MTK", // symbol
|
|
68
|
+
"my-project", // project name
|
|
69
|
+
18, // decimals
|
|
70
|
+
kyc,
|
|
71
|
+
adminProjectRouter,
|
|
72
|
+
committee,
|
|
73
|
+
transferRouter,
|
|
74
|
+
4 // accepted KYC level
|
|
75
|
+
)
|
|
76
|
+
{}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Use the contracts as provided rather than copying and modifying them, so deployments stay consistent with the KAP standards and KUB's KYC and admin-routing requirements. For more information, visit [KUB Docs](https://docs.kubchain.com).
|
|
81
|
+
|
|
82
|
+
## Security
|
|
83
|
+
|
|
84
|
+
These contracts integrate with privileged roles (owner, committee, admin project router) and an external KYC registry. Configure those addresses carefully, and review the access-control wiring before deploying to mainnet. Using this code is not a substitute for an independent security audit.
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
Released under the [MIT License](https://opensource.org/licenses/MIT).
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
//SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.0;
|
|
4
|
+
|
|
5
|
+
import {Authorization, IAdminProjectRouter} from "./Authorization.sol";
|
|
6
|
+
import {IKYCBitkubChain} from "../interfaces/IKYCBitkubChain.sol";
|
|
7
|
+
import {KYCHandler} from "../kyc/KYCHandler.sol";
|
|
8
|
+
import {Ownable} from "./Ownable.sol";
|
|
9
|
+
import {Committee} from "./Committee.sol";
|
|
10
|
+
|
|
11
|
+
abstract contract AccessController is
|
|
12
|
+
Authorization,
|
|
13
|
+
KYCHandler,
|
|
14
|
+
Ownable,
|
|
15
|
+
Committee
|
|
16
|
+
{
|
|
17
|
+
event TransferRouterSet(
|
|
18
|
+
address indexed oldTransferRouter,
|
|
19
|
+
address indexed newTransferRouter,
|
|
20
|
+
address indexed caller
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
address public transferRouter;
|
|
24
|
+
|
|
25
|
+
modifier onlyOwnerOrCommittee() {
|
|
26
|
+
require(
|
|
27
|
+
msg.sender == owner() || msg.sender == committee,
|
|
28
|
+
"AccessController: restricted only owner or committee"
|
|
29
|
+
);
|
|
30
|
+
_;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
modifier onlySuperAdminOrTransferRouter() {
|
|
34
|
+
require(
|
|
35
|
+
adminProjectRouter.isSuperAdmin(msg.sender, PROJECT) ||
|
|
36
|
+
msg.sender == transferRouter,
|
|
37
|
+
"AccessController: restricted only super admin or transfer router"
|
|
38
|
+
);
|
|
39
|
+
_;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
modifier onlySuperAdminOrCommittee() {
|
|
43
|
+
require(
|
|
44
|
+
adminProjectRouter.isSuperAdmin(msg.sender, PROJECT) ||
|
|
45
|
+
msg.sender == committee,
|
|
46
|
+
"AccessController: restricted only super admin or committee"
|
|
47
|
+
);
|
|
48
|
+
_;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
modifier onlySuperAdminOrOwner() {
|
|
52
|
+
require(
|
|
53
|
+
adminProjectRouter.isSuperAdmin(msg.sender, PROJECT) ||
|
|
54
|
+
msg.sender == owner(),
|
|
55
|
+
"AccessController: restricted only super admin or owner"
|
|
56
|
+
);
|
|
57
|
+
_;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function activateOnlyKYCAddress() external onlyCommittee {
|
|
61
|
+
_activateOnlyKYCAddress();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function setKYC(address _kyc) external onlyCommittee {
|
|
65
|
+
_setKYC(IKYCBitkubChain(_kyc));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function setAcceptedKYCLevel(uint256 _kycLevel) external onlyCommittee {
|
|
69
|
+
_setAcceptedKYCLevel(_kycLevel);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function setTransferRouter(address _transferRouter)
|
|
73
|
+
external
|
|
74
|
+
onlyOwnerOrCommittee
|
|
75
|
+
{
|
|
76
|
+
emit TransferRouterSet(transferRouter, _transferRouter, msg.sender);
|
|
77
|
+
transferRouter = _transferRouter;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function setAdminProjectRouter(address _adminProjectRouter)
|
|
81
|
+
public
|
|
82
|
+
override
|
|
83
|
+
onlyOwnerOrCommittee
|
|
84
|
+
{
|
|
85
|
+
require(
|
|
86
|
+
_adminProjectRouter != address(0),
|
|
87
|
+
"Authorization: new admin project router is the zero address"
|
|
88
|
+
);
|
|
89
|
+
emit AdminProjectRouterSet(
|
|
90
|
+
address(adminProjectRouter),
|
|
91
|
+
_adminProjectRouter,
|
|
92
|
+
msg.sender
|
|
93
|
+
);
|
|
94
|
+
adminProjectRouter = IAdminProjectRouter(_adminProjectRouter);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity >=0.8.0;
|
|
3
|
+
|
|
4
|
+
import {WhitelistAddress} from "../token/KAP-22/utils/WhitelistAddress.sol";
|
|
5
|
+
import {TransferRouter} from "../token/KAP-22/utils/TransferRouter.sol";
|
|
6
|
+
// import {KYCHandler} from "../kyc/KYCHandler.sol";
|
|
7
|
+
// import {IKYCBitkubChain} from "../interfaces/IKYCBitkubChain.sol";
|
|
8
|
+
|
|
9
|
+
interface IKYCBitkubChain {
|
|
10
|
+
function kycsLevel(address _addr) external view returns (uint256);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
abstract contract KYCHandler {
|
|
14
|
+
event OnlyKYCAddressActivated(address indexed caller);
|
|
15
|
+
event KYCSet(
|
|
16
|
+
address indexed oldKYC,
|
|
17
|
+
address indexed newKYC,
|
|
18
|
+
address indexed caller
|
|
19
|
+
);
|
|
20
|
+
event AcceptedKYCLevelSet(
|
|
21
|
+
uint256 indexed oldAcceptedKYCLevelSet,
|
|
22
|
+
uint256 indexed newAcceptedKYCLevelSet,
|
|
23
|
+
address indexed caller
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
IKYCBitkubChain public kyc;
|
|
27
|
+
|
|
28
|
+
uint256 public acceptedKycLevel;
|
|
29
|
+
bool public isActivatedOnlyKycAddress;
|
|
30
|
+
|
|
31
|
+
modifier onlyBitkubNext(address bitkubNext_) {
|
|
32
|
+
_onlyBitkubNext(bitkubNext_);
|
|
33
|
+
_;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
constructor(address kyc_, uint256 acceptedKycLevel_) {
|
|
37
|
+
_setKyc(IKYCBitkubChain(kyc_));
|
|
38
|
+
_setAcceptedKycLevel(acceptedKycLevel_);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function _activateOnlyKycAddress() internal virtual {
|
|
42
|
+
isActivatedOnlyKycAddress = true;
|
|
43
|
+
emit OnlyKYCAddressActivated(msg.sender);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function _setKyc(IKYCBitkubChain _kyc) internal virtual {
|
|
47
|
+
emit KYCSet(address(kyc), address(_kyc), msg.sender);
|
|
48
|
+
kyc = _kyc;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function _setAcceptedKycLevel(uint256 _kycLevel) internal virtual {
|
|
52
|
+
emit AcceptedKYCLevelSet(acceptedKycLevel, _kycLevel, msg.sender);
|
|
53
|
+
acceptedKycLevel = _kycLevel;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function _onlyBitkubNext(address bitkubNext_) internal view {
|
|
57
|
+
require(
|
|
58
|
+
_isBitkubNext(bitkubNext_),
|
|
59
|
+
"KYCHandler: only Bitkub NEXT user"
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function _isBitkubNext(address bitkubNext_) internal view returns (bool) {
|
|
64
|
+
return kyc.kycsLevel(bitkubNext_) >= acceptedKycLevel;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
abstract contract AccessControllerKAP is WhitelistAddress, TransferRouter, KYCHandler {
|
|
70
|
+
address public owner;
|
|
71
|
+
|
|
72
|
+
event OwnerSet(address indexed oldOwner, address indexed newOwner, address indexed caller);
|
|
73
|
+
|
|
74
|
+
modifier onlyOwner() {
|
|
75
|
+
require(msg.sender == owner, "AccessControllerKAP: restricted only owner");
|
|
76
|
+
_;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
constructor(
|
|
80
|
+
address owner_,
|
|
81
|
+
address transferRouter_,
|
|
82
|
+
address kyc_,
|
|
83
|
+
uint256 acceptedKycLevel_
|
|
84
|
+
) TransferRouter(transferRouter_) KYCHandler(kyc_, acceptedKycLevel_) {
|
|
85
|
+
owner = owner_;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function setTransferRouter(address _transferRouter) public virtual {
|
|
89
|
+
_setTransferRouter(_transferRouter);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function setKyc(IKYCBitkubChain _kyc) public virtual {
|
|
93
|
+
_setKyc(_kyc);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function setAcceptedKycLevel(uint256 _kycLevel) public virtual {
|
|
97
|
+
_setAcceptedKycLevel(_kycLevel);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function activateOnlyKycAddress() public virtual {
|
|
101
|
+
_activateOnlyKycAddress();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function setOwner(address _owner) public virtual onlyOwner {
|
|
105
|
+
emit OwnerSet(owner, _owner, msg.sender);
|
|
106
|
+
owner = _owner;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function addWhitelistAddress(address _addr) public virtual override onlyOwner {
|
|
110
|
+
WhitelistAddress.addWhitelistAddress(_addr);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function revokeWhitelistAddress(address _addr) public virtual override onlyOwner {
|
|
114
|
+
WhitelistAddress.revokeWhitelistAddress(_addr);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.0;
|
|
4
|
+
|
|
5
|
+
import "../interfaces/IAdminProjectRouter.sol";
|
|
6
|
+
|
|
7
|
+
abstract contract Authorization {
|
|
8
|
+
IAdminProjectRouter public adminProjectRouter;
|
|
9
|
+
string public PROJECT;
|
|
10
|
+
|
|
11
|
+
event AdminProjectRouterSet(address indexed oldAdmin, address indexed newAdmin, address indexed caller);
|
|
12
|
+
|
|
13
|
+
modifier onlySuperAdmin() {
|
|
14
|
+
require(adminProjectRouter.isSuperAdmin(msg.sender, PROJECT), "Authorization: restricted only super admin");
|
|
15
|
+
_;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
modifier onlyAdmin() {
|
|
19
|
+
require(adminProjectRouter.isAdmin(msg.sender, PROJECT), "Authorization: restricted only admin");
|
|
20
|
+
_;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
modifier onlySuperAdminOrAdmin() {
|
|
24
|
+
require(
|
|
25
|
+
adminProjectRouter.isSuperAdmin(msg.sender, PROJECT) || adminProjectRouter.isAdmin(msg.sender, PROJECT),
|
|
26
|
+
"Authorization: restricted only super admin or admin"
|
|
27
|
+
);
|
|
28
|
+
_;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function setAdminProjectRouter(address _adminProjectRouter) public virtual onlySuperAdmin {
|
|
32
|
+
require(_adminProjectRouter != address(0), "Authorization: new admin project router is the zero address");
|
|
33
|
+
emit AdminProjectRouterSet(address(adminProjectRouter), _adminProjectRouter, msg.sender);
|
|
34
|
+
adminProjectRouter = IAdminProjectRouter(_adminProjectRouter);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.0;
|
|
3
|
+
|
|
4
|
+
import {IAdminProjectRouter} from "../interfaces/IAdminProjectRouter.sol";
|
|
5
|
+
|
|
6
|
+
abstract contract AuthorizationKAP {
|
|
7
|
+
IAdminProjectRouter public adminRouter;
|
|
8
|
+
string public constant PROJECT = "kap-token";
|
|
9
|
+
address public transferRouter;
|
|
10
|
+
|
|
11
|
+
address public committee;
|
|
12
|
+
|
|
13
|
+
event SetAdmin(address indexed oldAdmin, address indexed newAdmin, address indexed caller);
|
|
14
|
+
event SetCommittee(address indexed oldCommittee, address indexed newCommittee, address indexed caller);
|
|
15
|
+
|
|
16
|
+
modifier onlySuperAdmin() {
|
|
17
|
+
require(adminRouter.isSuperAdmin(msg.sender, PROJECT), "Restricted only super admin");
|
|
18
|
+
_;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
modifier onlyAdmin() {
|
|
22
|
+
require(adminRouter.isAdmin(msg.sender, PROJECT), "Restricted only admin");
|
|
23
|
+
_;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
modifier onlySuperAdminOrAdmin() {
|
|
27
|
+
require(
|
|
28
|
+
adminRouter.isSuperAdmin(msg.sender, PROJECT) || adminRouter.isAdmin(msg.sender, PROJECT),
|
|
29
|
+
"Restricted only super admin or admin"
|
|
30
|
+
);
|
|
31
|
+
_;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
modifier onlySuperAdminOrTransferRouter() {
|
|
35
|
+
require(
|
|
36
|
+
adminRouter.isSuperAdmin(msg.sender, PROJECT) || msg.sender == transferRouter,
|
|
37
|
+
"Restricted only super admin ot transfer router"
|
|
38
|
+
);
|
|
39
|
+
_;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
modifier onlyCommittee() {
|
|
43
|
+
require(msg.sender == committee, "Restricted only committee");
|
|
44
|
+
_;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function setAdmin(address _adminRouter) external onlySuperAdmin {
|
|
48
|
+
emit SetAdmin(address(adminRouter), _adminRouter, msg.sender);
|
|
49
|
+
adminRouter = IAdminProjectRouter(_adminRouter);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function setCommittee(address _committee) external onlyCommittee {
|
|
53
|
+
emit SetCommittee(committee, _committee, msg.sender);
|
|
54
|
+
committee = _committee;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function setTransferRouter(address _transferRouter) external onlySuperAdmin {
|
|
58
|
+
transferRouter = _transferRouter;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.0;
|
|
4
|
+
|
|
5
|
+
abstract contract Committee {
|
|
6
|
+
address public committee;
|
|
7
|
+
|
|
8
|
+
event CommitteeSet(
|
|
9
|
+
address indexed oldCommittee,
|
|
10
|
+
address indexed newCommittee,
|
|
11
|
+
address indexed caller
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
modifier onlyCommittee() {
|
|
15
|
+
require(
|
|
16
|
+
msg.sender == committee,
|
|
17
|
+
"Committee: restricted only committee"
|
|
18
|
+
);
|
|
19
|
+
_;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function setCommittee(address _committee) public virtual onlyCommittee {
|
|
23
|
+
emit CommitteeSet(committee, _committee, msg.sender);
|
|
24
|
+
committee = _committee;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.0;
|
|
4
|
+
|
|
5
|
+
import "../utils/Context.sol";
|
|
6
|
+
|
|
7
|
+
abstract contract Ownable is Context {
|
|
8
|
+
address private _owner;
|
|
9
|
+
|
|
10
|
+
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
|
|
11
|
+
|
|
12
|
+
constructor() {
|
|
13
|
+
_transferOwnership(_msgSender());
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function owner() public view virtual returns (address) {
|
|
17
|
+
return _owner;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
modifier onlyOwner() {
|
|
21
|
+
require(owner() == _msgSender(), "Ownable: caller is not the owner");
|
|
22
|
+
_;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function renounceOwnership() public virtual onlyOwner {
|
|
26
|
+
_transferOwnership(address(0));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function transferOwnership(address newOwner) public virtual onlyOwner {
|
|
30
|
+
require(newOwner != address(0), "Ownable: new owner is the zero address");
|
|
31
|
+
_transferOwnership(newOwner);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function _transferOwnership(address newOwner) internal virtual {
|
|
35
|
+
address oldOwner = _owner;
|
|
36
|
+
_owner = newOwner;
|
|
37
|
+
emit OwnershipTransferred(oldOwner, newOwner);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity >=0.6.0 <0.9.0;
|
|
4
|
+
|
|
5
|
+
interface IAdminProjectRouter {
|
|
6
|
+
function isSuperAdmin(address _addr, string calldata _project) external view returns (bool);
|
|
7
|
+
|
|
8
|
+
function isAdmin(address _addr, string calldata _project) external view returns (bool);
|
|
9
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.0;
|
|
4
|
+
|
|
5
|
+
import {IKYCBitkubChain} from "../interfaces/IKYCBitkubChain.sol";
|
|
6
|
+
|
|
7
|
+
abstract contract KYCHandler {
|
|
8
|
+
IKYCBitkubChain public kyc;
|
|
9
|
+
|
|
10
|
+
uint256 public acceptedKYCLevel;
|
|
11
|
+
bool public isActivatedOnlyKYCAddress;
|
|
12
|
+
|
|
13
|
+
function _activateOnlyKYCAddress() internal virtual {
|
|
14
|
+
isActivatedOnlyKYCAddress = true;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function _setKYC(IKYCBitkubChain _kyc) internal virtual {
|
|
18
|
+
kyc = _kyc;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function _setAcceptedKYCLevel(uint256 _kycLevel) internal virtual {
|
|
22
|
+
acceptedKYCLevel = _kycLevel;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.0;
|
|
3
|
+
|
|
4
|
+
library Address {
|
|
5
|
+
function isContract(address account) internal view returns (bool) {
|
|
6
|
+
// This method relies on extcodesize, which returns 0 for contracts in
|
|
7
|
+
// construction, since the code is only stored at the end of the
|
|
8
|
+
// constructor execution.
|
|
9
|
+
|
|
10
|
+
uint256 size;
|
|
11
|
+
assembly {
|
|
12
|
+
size := extcodesize(account)
|
|
13
|
+
}
|
|
14
|
+
return size > 0;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.0;
|
|
3
|
+
|
|
4
|
+
library EnumerableSetAddress {
|
|
5
|
+
struct AddressSet {
|
|
6
|
+
address[] _values;
|
|
7
|
+
mapping(address => uint256) _indexes;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function add(AddressSet storage set, address value) internal returns (bool) {
|
|
11
|
+
if (!contains(set, value)) {
|
|
12
|
+
set._values.push(value);
|
|
13
|
+
set._indexes[value] = set._values.length;
|
|
14
|
+
return true;
|
|
15
|
+
} else {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function remove(AddressSet storage set, address value) internal returns (bool) {
|
|
21
|
+
uint256 valueIndex = set._indexes[value];
|
|
22
|
+
if (valueIndex != 0) {
|
|
23
|
+
uint256 toDeleteIndex = valueIndex - 1;
|
|
24
|
+
uint256 lastIndex = set._values.length - 1;
|
|
25
|
+
address lastvalue = set._values[lastIndex];
|
|
26
|
+
set._values[toDeleteIndex] = lastvalue;
|
|
27
|
+
set._indexes[lastvalue] = toDeleteIndex + 1;
|
|
28
|
+
set._values.pop();
|
|
29
|
+
delete set._indexes[value];
|
|
30
|
+
return true;
|
|
31
|
+
} else {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function contains(AddressSet storage set, address value) internal view returns (bool) {
|
|
37
|
+
return set._indexes[value] != 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function length(AddressSet storage set) internal view returns (uint256) {
|
|
41
|
+
return set._values.length;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function at(AddressSet storage set, uint256 index) internal view returns (address) {
|
|
45
|
+
require(set._values.length > index, "EnumerableSet: index out of bounds");
|
|
46
|
+
return set._values[index];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getAll(AddressSet storage set) internal view returns (address[] memory) {
|
|
50
|
+
return set._values;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function get(AddressSet storage set, uint256 _page, uint256 _limit) internal view returns (address[] memory) {
|
|
54
|
+
require(_page > 0 && _limit > 0);
|
|
55
|
+
uint256 tempLength = _limit;
|
|
56
|
+
uint256 cursor = (_page - 1) * _limit;
|
|
57
|
+
uint256 _addressLength = length(set);
|
|
58
|
+
if (cursor >= _addressLength) {
|
|
59
|
+
return new address[](0);
|
|
60
|
+
}
|
|
61
|
+
if (tempLength > _addressLength - cursor) {
|
|
62
|
+
tempLength = _addressLength - cursor;
|
|
63
|
+
}
|
|
64
|
+
address[] memory addresses = new address[](tempLength);
|
|
65
|
+
for (uint256 i = 0; i < tempLength; i++) {
|
|
66
|
+
addresses[i] = at(set, cursor + i);
|
|
67
|
+
}
|
|
68
|
+
return addresses;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity >=0.6.0;
|
|
3
|
+
|
|
4
|
+
library EnumerableSetUint {
|
|
5
|
+
struct UintSet {
|
|
6
|
+
uint256[] _values;
|
|
7
|
+
mapping(uint256 => uint256) _indexes;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function add(UintSet storage set, uint256 value) internal returns (bool) {
|
|
11
|
+
if (!contains(set, value)) {
|
|
12
|
+
set._values.push(value);
|
|
13
|
+
set._indexes[value] = set._values.length;
|
|
14
|
+
return true;
|
|
15
|
+
} else {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function remove(UintSet storage set, uint256 value) internal returns (bool) {
|
|
21
|
+
uint256 valueIndex = set._indexes[value];
|
|
22
|
+
if (valueIndex != 0) {
|
|
23
|
+
uint256 toDeleteIndex = valueIndex - 1;
|
|
24
|
+
uint256 lastIndex = set._values.length - 1;
|
|
25
|
+
uint256 lastvalue = set._values[lastIndex];
|
|
26
|
+
set._values[toDeleteIndex] = lastvalue;
|
|
27
|
+
set._indexes[lastvalue] = toDeleteIndex + 1;
|
|
28
|
+
set._values.pop();
|
|
29
|
+
delete set._indexes[value];
|
|
30
|
+
return true;
|
|
31
|
+
} else {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
|
|
37
|
+
return set._indexes[value] != 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function length(UintSet storage set) internal view returns (uint256) {
|
|
41
|
+
return set._values.length;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
|
|
45
|
+
require(set._values.length > index, "EnumerableSet: index out of bounds");
|
|
46
|
+
return set._values[index];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getAll(UintSet storage set) internal view returns (uint256[] memory) {
|
|
50
|
+
return set._values;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function get(
|
|
54
|
+
UintSet storage set,
|
|
55
|
+
uint256 _page,
|
|
56
|
+
uint256 _limit
|
|
57
|
+
) internal view returns (uint256[] memory) {
|
|
58
|
+
require(_page > 0 && _limit > 0);
|
|
59
|
+
uint256 tempLength = _limit;
|
|
60
|
+
uint256 cursor = (_page - 1) * _limit;
|
|
61
|
+
uint256 _uintLength = length(set);
|
|
62
|
+
if (cursor >= _uintLength) {
|
|
63
|
+
return new uint256[](0);
|
|
64
|
+
}
|
|
65
|
+
if (tempLength > _uintLength - cursor) {
|
|
66
|
+
tempLength = _uintLength - cursor;
|
|
67
|
+
}
|
|
68
|
+
uint256[] memory uintList = new uint256[](tempLength);
|
|
69
|
+
for (uint256 i = 0; i < tempLength; i++) {
|
|
70
|
+
uintList[i] = at(set, cursor + i);
|
|
71
|
+
}
|
|
72
|
+
return uintList;
|
|
73
|
+
}
|
|
74
|
+
}
|