@web3dotorg/evm-slc-core-contracts 0.3.2
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/governance/ExecutorsRegistry.sol +710 -0
- package/governance/Governance.sol +969 -0
- package/governance/NeutralsRegistry.sol +1130 -0
- package/governance/ParameterRegistry.sol +381 -0
- package/interfaces/IExecutorsRegistry.sol +62 -0
- package/interfaces/IGovernance.sol +57 -0
- package/interfaces/INeutralsRegistry.sol +72 -0
- package/interfaces/IQParameters.sol +37 -0
- package/interfaces/ISLCCore.sol +59 -0
- package/interfaces/ISLCCoreFactory.sol +29 -0
- package/interfaces/IWrappedToken.sol +8 -0
- package/libs/Errors.sol +22 -0
- package/libs/NeutralsSelection.sol +78 -0
- package/mocks/Helper.sol +4 -0
- package/mocks/MockGovernance.sol +75 -0
- package/mocks/MockNeutralsRegistry.sol +126 -0
- package/mocks/SimpleContract.sol +14 -0
- package/mocks/WrappedToken.sol +24 -0
- package/package.json +27 -0
- package/slc-core/SLCCore.sol +119 -0
- package/slc-core/SLCCoreFactory.sol +215 -0
- package/token/Token.sol +20 -0
- package/utils/Globals.sol +7 -0
@@ -0,0 +1,215 @@
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
2
|
+
pragma solidity ^0.8.28;
|
3
|
+
|
4
|
+
import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
|
5
|
+
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
|
6
|
+
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
7
|
+
import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
|
8
|
+
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
9
|
+
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
10
|
+
import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
|
11
|
+
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
12
|
+
|
13
|
+
import {SLCCore} from "./SLCCore.sol";
|
14
|
+
|
15
|
+
import {ISLCCoreFactory} from "../interfaces/ISLCCoreFactory.sol";
|
16
|
+
import {INeutralsRegistry} from "../interfaces/INeutralsRegistry.sol";
|
17
|
+
import {IExecutorsRegistry} from "../interfaces/IExecutorsRegistry.sol";
|
18
|
+
import {IQParameters} from "../interfaces/IQParameters.sol";
|
19
|
+
|
20
|
+
/**
|
21
|
+
* @title SLCCoreFactory
|
22
|
+
* @notice Factory contract for deploying SLC Core contracts
|
23
|
+
*/
|
24
|
+
contract SLCCoreFactory is ISLCCoreFactory, ERC165, OwnableUpgradeable, UUPSUpgradeable {
|
25
|
+
using EnumerableSet for EnumerableSet.AddressSet;
|
26
|
+
|
27
|
+
/// @custom:storage-location erc7201:slc-core-poc.storage.SLCFactory
|
28
|
+
struct SLCFactoryStorage {
|
29
|
+
INeutralsRegistry neutralsRegistry;
|
30
|
+
IExecutorsRegistry executorsRegistry;
|
31
|
+
IQParameters parametersRegistry;
|
32
|
+
address slcCoreImplementation;
|
33
|
+
EnumerableSet.AddressSet deployedSLCs;
|
34
|
+
mapping(address => uint256) nonces;
|
35
|
+
}
|
36
|
+
|
37
|
+
struct SLCFactoryStorageData {
|
38
|
+
address parametersRegistry;
|
39
|
+
address slcCoreImplementation;
|
40
|
+
}
|
41
|
+
|
42
|
+
// keccak256(abi.encode(uint256(keccak256("slc-core-poc.storage.SLCFactory")) - 1)) & ~bytes32(uint256(0xff))
|
43
|
+
bytes32 private constant SLC_FACTORY_STORAGE_LOCATION =
|
44
|
+
0x2a4c5f206148f75b3c203bb4f62027a088ca55bbc9fba0fb4e0029fabdf99000;
|
45
|
+
|
46
|
+
string private constant DEFAULT_GOVERNANCE_PARAM_NAME = "slc.governance.defaultGovernance";
|
47
|
+
|
48
|
+
function _getSLCFactoryStorage() private pure returns (SLCFactoryStorage storage $) {
|
49
|
+
/* solhint-disable-next-line no-inline-assembly */
|
50
|
+
assembly ("memory-safe") {
|
51
|
+
$.slot := SLC_FACTORY_STORAGE_LOCATION
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
event SLCDeployed(address indexed slc, address indexed governance, address indexed deployer);
|
56
|
+
|
57
|
+
error DefaultGovernanceNotSet(address parametersRegistry);
|
58
|
+
|
59
|
+
function __SLCFactory_init(
|
60
|
+
address initialOwner_,
|
61
|
+
address parametersRegistry_,
|
62
|
+
address slcImplementation_
|
63
|
+
) external initializer {
|
64
|
+
__Ownable_init(initialOwner_);
|
65
|
+
|
66
|
+
SLCFactoryStorage storage $ = _getSLCFactoryStorage();
|
67
|
+
|
68
|
+
$.parametersRegistry = IQParameters(parametersRegistry_);
|
69
|
+
$.slcCoreImplementation = slcImplementation_;
|
70
|
+
}
|
71
|
+
|
72
|
+
function deploySLC(string calldata legalDocumentLink_) external virtual returns (address) {
|
73
|
+
SLCFactoryStorage storage $ = _getSLCFactoryStorage();
|
74
|
+
|
75
|
+
address defaultGovernance_ = $.parametersRegistry.getAddr(DEFAULT_GOVERNANCE_PARAM_NAME);
|
76
|
+
require(
|
77
|
+
defaultGovernance_ != address(0),
|
78
|
+
DefaultGovernanceNotSet(address($.parametersRegistry))
|
79
|
+
);
|
80
|
+
|
81
|
+
return _deploySLC(defaultGovernance_, legalDocumentLink_);
|
82
|
+
}
|
83
|
+
|
84
|
+
function deploySLCWithGovernance(
|
85
|
+
address governance_,
|
86
|
+
string calldata legalDocumentLink_
|
87
|
+
) external virtual returns (address) {
|
88
|
+
return _deploySLC(governance_, legalDocumentLink_);
|
89
|
+
}
|
90
|
+
|
91
|
+
function _deploySLC(
|
92
|
+
address governance_,
|
93
|
+
string calldata legalDocumentLink_
|
94
|
+
) internal returns (address) {
|
95
|
+
SLCFactoryStorage storage $ = _getSLCFactoryStorage();
|
96
|
+
|
97
|
+
uint256 nonce_ = _useNonce(msg.sender);
|
98
|
+
|
99
|
+
SLCCore slcCore_ = SLCCore(_deploy2($.slcCoreImplementation, getSalt(msg.sender, nonce_)));
|
100
|
+
|
101
|
+
slcCore_.__SLCCore_init(msg.sender, governance_, legalDocumentLink_, new bytes(0));
|
102
|
+
|
103
|
+
$.deployedSLCs.add(address(slcCore_));
|
104
|
+
|
105
|
+
emit SLCDeployed(address(slcCore_), governance_, msg.sender);
|
106
|
+
|
107
|
+
return address(slcCore_);
|
108
|
+
}
|
109
|
+
|
110
|
+
function nonces(address owner_) public view virtual returns (uint256) {
|
111
|
+
return _getSLCFactoryStorage().nonces[owner_];
|
112
|
+
}
|
113
|
+
|
114
|
+
function _useNonce(address owner_) internal virtual returns (uint256) {
|
115
|
+
SLCFactoryStorage storage $ = _getSLCFactoryStorage();
|
116
|
+
uint256 current_ = $.nonces[owner_];
|
117
|
+
$.nonces[owner_] = current_ + 1;
|
118
|
+
return current_;
|
119
|
+
}
|
120
|
+
|
121
|
+
function setSLCCoreImplementation(address newImplementation_) external virtual onlyOwner {
|
122
|
+
_getSLCFactoryStorage().slcCoreImplementation = newImplementation_;
|
123
|
+
}
|
124
|
+
|
125
|
+
function predictSLCAddress(
|
126
|
+
address slcDeployer_,
|
127
|
+
uint256 nonce_
|
128
|
+
) external view virtual returns (address) {
|
129
|
+
return
|
130
|
+
_predictAddress(_getSLCFactoryStorage().slcCoreImplementation, slcDeployer_, nonce_);
|
131
|
+
}
|
132
|
+
|
133
|
+
function getSLCCoreImplementation() external view virtual returns (address) {
|
134
|
+
return _getSLCFactoryStorage().slcCoreImplementation;
|
135
|
+
}
|
136
|
+
|
137
|
+
function getSLCFactoryStorage() external view virtual returns (SLCFactoryStorageData memory) {
|
138
|
+
SLCFactoryStorage storage $ = _getSLCFactoryStorage();
|
139
|
+
|
140
|
+
return
|
141
|
+
SLCFactoryStorageData({
|
142
|
+
parametersRegistry: address($.parametersRegistry),
|
143
|
+
slcCoreImplementation: $.slcCoreImplementation
|
144
|
+
});
|
145
|
+
}
|
146
|
+
|
147
|
+
function getDeployedSLCs(
|
148
|
+
uint256 offset_,
|
149
|
+
uint256 limit_
|
150
|
+
) external view virtual returns (address[] memory) {
|
151
|
+
EnumerableSet.AddressSet storage deployedSLCs_ = _getSLCFactoryStorage().deployedSLCs;
|
152
|
+
uint256 length_ = deployedSLCs_.length();
|
153
|
+
|
154
|
+
if (offset_ >= length_) {
|
155
|
+
return new address[](0);
|
156
|
+
}
|
157
|
+
|
158
|
+
uint256 to_ = offset_ + limit_;
|
159
|
+
if (to_ > length_) {
|
160
|
+
to_ = length_;
|
161
|
+
}
|
162
|
+
|
163
|
+
address[] memory result_ = new address[](to_ - offset_);
|
164
|
+
for (uint256 i = 0; i < result_.length; ++i) {
|
165
|
+
result_[i] = deployedSLCs_.at(offset_ + i);
|
166
|
+
}
|
167
|
+
|
168
|
+
return result_;
|
169
|
+
}
|
170
|
+
|
171
|
+
function getSalt(address slcDeployer_, uint256 nonce_) public pure virtual returns (bytes32) {
|
172
|
+
return keccak256(abi.encodePacked(slcDeployer_, nonce_));
|
173
|
+
}
|
174
|
+
|
175
|
+
function isSLCCore(address toCheck_) public view virtual returns (bool) {
|
176
|
+
return _getSLCFactoryStorage().deployedSLCs.contains(toCheck_);
|
177
|
+
}
|
178
|
+
|
179
|
+
function _deploy2(address implementation_, bytes32 salt_) internal returns (address payable) {
|
180
|
+
return payable(address(new ERC1967Proxy{salt: salt_}(implementation_, new bytes(0))));
|
181
|
+
}
|
182
|
+
|
183
|
+
function _predictAddress(
|
184
|
+
address implementation_,
|
185
|
+
address slcDeployer_,
|
186
|
+
uint256 nonce_
|
187
|
+
) internal view virtual returns (address) {
|
188
|
+
bytes32 bytecodeHash = keccak256(
|
189
|
+
abi.encodePacked(
|
190
|
+
type(ERC1967Proxy).creationCode,
|
191
|
+
abi.encode(implementation_, new bytes(0))
|
192
|
+
)
|
193
|
+
);
|
194
|
+
|
195
|
+
return Create2.computeAddress(getSalt(slcDeployer_, nonce_), bytecodeHash);
|
196
|
+
}
|
197
|
+
|
198
|
+
/**
|
199
|
+
* @inheritdoc ERC165
|
200
|
+
*/
|
201
|
+
function supportsInterface(
|
202
|
+
bytes4 interfaceId_
|
203
|
+
) public view override(IERC165, ERC165) returns (bool) {
|
204
|
+
return
|
205
|
+
interfaceId_ == type(ISLCCoreFactory).interfaceId ||
|
206
|
+
super.supportsInterface(interfaceId_);
|
207
|
+
}
|
208
|
+
|
209
|
+
// solhint-disable-next-line no-empty-blocks
|
210
|
+
function _authorizeUpgrade(address) internal override onlyOwner {}
|
211
|
+
|
212
|
+
function implementation() external view returns (address) {
|
213
|
+
return ERC1967Utils.getImplementation();
|
214
|
+
}
|
215
|
+
}
|
package/token/Token.sol
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
2
|
+
pragma solidity ^0.8.21;
|
3
|
+
|
4
|
+
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
|
5
|
+
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
6
|
+
|
7
|
+
contract Token is ERC20, Ownable {
|
8
|
+
constructor(
|
9
|
+
string memory name_,
|
10
|
+
string memory symbol_
|
11
|
+
) ERC20(name_, symbol_) Ownable(msg.sender) {}
|
12
|
+
|
13
|
+
function mint(address to_, uint256 amount_) public onlyOwner {
|
14
|
+
_mint(to_, amount_);
|
15
|
+
}
|
16
|
+
|
17
|
+
function burn(address to_, uint256 amount_) public onlyOwner {
|
18
|
+
_burn(to_, amount_);
|
19
|
+
}
|
20
|
+
}
|