forked from neptune-mutual-blue/protocol
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathProtoUtilV1.sol
340 lines (277 loc) · 16.1 KB
/
ProtoUtilV1.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
// Neptune Mutual Protocol (https://neptunemutual.com)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "./StoreKeyUtil.sol";
import "../interfaces/IStore.sol";
import "../interfaces/IProtocol.sol";
import "../interfaces/IERC20Detailed.sol";
library ProtoUtilV1 {
using StoreKeyUtil for IStore;
// Magic numbers
uint256 public constant MAX_POLICY_DURATION = 3;
bytes32 public constant KEY_INTENTIONALLY_EMPTY = 0;
bytes32 public constant PRODUCT_KEY_INTENTIONALLY_EMPTY = 0;
uint256 public constant MULTIPLIER = 10_000;
uint256 public constant MAX_LIQUIDITY = 10_000_000;
uint256 public constant MAX_PROPOSAL_AMOUNT = 10_000_000;
uint256 public constant MAX_NPM_STAKE = 10_000_000;
uint256 public constant NPM_PRECISION = 1 ether;
uint256 public constant CXTOKEN_PRECISION = 1 ether;
uint256 public constant POD_PRECISION = 1 ether;
/// @dev Protocol contract namespace
bytes32 public constant CNS_CORE = "cns:core";
/// @dev The address of NPM token available in this blockchain
bytes32 public constant CNS_NPM = "cns:core:npm:instance";
/// @dev Key prefix for creating a new cover product on chain
bytes32 public constant CNS_COVER = "cns:cover";
bytes32 public constant CNS_UNISWAP_V2_ROUTER = "cns:core:uni:v2:router";
bytes32 public constant CNS_UNISWAP_V2_FACTORY = "cns:core:uni:v2:factory";
bytes32 public constant CNS_PRICE_DISCOVERY = "cns:core:price:discovery";
bytes32 public constant CNS_TREASURY = "cns:core:treasury";
bytes32 public constant CNS_NPM_PRICE_ORACLE = "cns:core:npm:price:oracle";
bytes32 public constant CNS_COVER_REASSURANCE = "cns:cover:reassurance";
bytes32 public constant CNS_POOL_BOND = "cns:pool:bond";
bytes32 public constant CNS_COVER_POLICY = "cns:cover:policy";
bytes32 public constant CNS_COVER_POLICY_MANAGER = "cns:cover:policy:manager";
bytes32 public constant CNS_COVER_POLICY_ADMIN = "cns:cover:policy:admin";
bytes32 public constant CNS_COVER_STAKE = "cns:cover:stake";
bytes32 public constant CNS_COVER_VAULT = "cns:cover:vault";
bytes32 public constant CNS_COVER_VAULT_DELEGATE = "cns:cover:vault:delegate";
bytes32 public constant CNS_COVER_STABLECOIN = "cns:cover:sc";
bytes32 public constant CNS_COVER_CXTOKEN_FACTORY = "cns:cover:cxtoken:factory";
bytes32 public constant CNS_COVER_VAULT_FACTORY = "cns:cover:vault:factory";
bytes32 public constant CNS_BOND_POOL = "cns:pools:bond";
bytes32 public constant CNS_STAKING_POOL = "cns:pools:staking";
bytes32 public constant CNS_LIQUIDITY_ENGINE = "cns:liquidity:engine";
bytes32 public constant CNS_STRATEGY_AAVE = "cns:strategy:aave";
bytes32 public constant CNS_STRATEGY_COMPOUND = "cns:strategy:compound";
/// @dev Governance contract address
bytes32 public constant CNS_GOVERNANCE = "cns:gov";
/// @dev Governance:Resolution contract address
bytes32 public constant CNS_GOVERNANCE_RESOLUTION = "cns:gov:resolution";
/// @dev Claims processor contract address
bytes32 public constant CNS_CLAIM_PROCESSOR = "cns:claim:processor";
/// @dev The address where `burn tokens` are sent or collected.
/// The collection behavior (collection) is required if the protocol
/// is deployed on a sidechain or a layer-2 blockchain.
/// \n
/// The collected NPM tokens are will be periodically bridged back to Ethereum
/// and then burned.
bytes32 public constant CNS_BURNER = "cns:core:burner";
/// @dev Namespace for all protocol members.
bytes32 public constant NS_MEMBERS = "ns:members";
/// @dev Namespace for protocol contract members.
bytes32 public constant NS_CONTRACTS = "ns:contracts";
/// @dev Key prefix for creating a new cover product on chain
bytes32 public constant NS_COVER = "ns:cover";
bytes32 public constant NS_COVER_PRODUCT = "ns:cover:product";
bytes32 public constant NS_COVER_PRODUCT_EFFICIENCY = "ns:cover:product:efficiency";
bytes32 public constant NS_COVER_CREATION_DATE = "ns:cover:creation:date";
bytes32 public constant NS_COVER_CREATION_FEE = "ns:cover:creation:fee";
bytes32 public constant NS_COVER_CREATION_MIN_STAKE = "ns:cover:creation:min:stake";
bytes32 public constant NS_COVER_REASSURANCE = "ns:cover:reassurance";
bytes32 public constant NS_COVER_REASSURANCE_PAYOUT = "ns:cover:reassurance:payout";
bytes32 public constant NS_COVER_REASSURANCE_WEIGHT = "ns:cover:reassurance:weight";
bytes32 public constant NS_COVER_REASSURANCE_RATE = "ns:cover:reassurance:rate";
bytes32 public constant NS_COVER_LEVERAGE_FACTOR = "ns:cover:leverage:factor";
bytes32 public constant NS_COVER_CREATION_FEE_EARNING = "ns:cover:creation:fee:earning";
bytes32 public constant NS_COVER_INFO = "ns:cover:info";
bytes32 public constant NS_COVER_OWNER = "ns:cover:owner";
bytes32 public constant NS_COVER_SUPPORTS_PRODUCTS = "ns:cover:supports:products";
bytes32 public constant NS_VAULT_STRATEGY_OUT = "ns:vault:strategy:out";
bytes32 public constant NS_VAULT_LENDING_INCOMES = "ns:vault:lending:incomes";
bytes32 public constant NS_VAULT_LENDING_LOSSES = "ns:vault:lending:losses";
bytes32 public constant NS_VAULT_DEPOSIT_HEIGHTS = "ns:vault:deposit:heights";
bytes32 public constant NS_COVER_LIQUIDITY_LENDING_PERIOD = "ns:cover:liquidity:len:p";
bytes32 public constant NS_COVER_LIQUIDITY_MAX_LENDING_RATIO = "ns:cover:liquidity:max:lr";
bytes32 public constant NS_COVER_LIQUIDITY_WITHDRAWAL_WINDOW = "ns:cover:liquidity:ww";
bytes32 public constant NS_COVER_LIQUIDITY_MIN_STAKE = "ns:cover:liquidity:min:stake";
bytes32 public constant NS_COVER_LIQUIDITY_STAKE = "ns:cover:liquidity:stake";
bytes32 public constant NS_COVER_LIQUIDITY_COMMITTED = "ns:cover:liquidity:committed";
bytes32 public constant NS_COVER_STABLECOIN_NAME = "ns:cover:stablecoin:name";
bytes32 public constant NS_COVER_REQUIRES_WHITELIST = "ns:cover:requires:whitelist";
bytes32 public constant NS_COVER_HAS_FLASH_LOAN = "ns:cover:has:fl";
bytes32 public constant NS_COVER_LIQUIDITY_FLASH_LOAN_FEE = "ns:cover:liquidity:fl:fee";
bytes32 public constant NS_COVER_LIQUIDITY_FLASH_LOAN_FEE_PROTOCOL = "ns:proto:cover:liquidity:fl:fee";
bytes32 public constant NS_COVERAGE_LAG = "ns:coverage:lag";
bytes32 public constant NS_COVER_POLICY_RATE_FLOOR = "ns:cover:policy:rate:floor";
bytes32 public constant NS_COVER_POLICY_RATE_CEILING = "ns:cover:policy:rate:ceiling";
bytes32 public constant NS_POLICY_DISABLED = "ns:policy:disabled";
bytes32 public constant NS_POLICY_LAST_PURCHASE_ID = "ns:policy:last:purchase:id";
bytes32 public constant NS_COVER_STAKE = "ns:cover:stake";
bytes32 public constant NS_COVER_STAKE_OWNED = "ns:cover:stake:owned";
bytes32 public constant NS_COVER_STATUS = "ns:cover:status";
bytes32 public constant NS_COVER_CXTOKEN = "ns:cover:cxtoken";
bytes32 public constant NS_VAULT_TOKEN_NAME = "ns:vault:token:name";
bytes32 public constant NS_VAULT_TOKEN_SYMBOL = "ns:vault:token:symbol";
bytes32 public constant NS_COVER_CREATOR_WHITELIST = "ns:cover:creator:whitelist";
bytes32 public constant NS_COVER_USER_WHITELIST = "ns:cover:user:whitelist";
bytes32 public constant NS_COVER_CLAIM_BLACKLIST = "ns:cover:claim:blacklist";
/// @dev Resolution timestamp = timestamp of first reporting + reporting period
bytes32 public constant NS_GOVERNANCE_RESOLUTION_TS = "ns:gov:resolution:ts";
/// @dev The timestamp when a tokenholder withdraws their reporting stake
bytes32 public constant NS_GOVERNANCE_UNSTAKEN = "ns:gov:unstaken";
/// @dev The timestamp when a tokenholder withdraws their reporting stake
bytes32 public constant NS_GOVERNANCE_UNSTAKE_TS = "ns:gov:unstake:ts";
/// @dev The reward received by the winning camp
bytes32 public constant NS_GOVERNANCE_UNSTAKE_REWARD = "ns:gov:unstake:reward";
/// @dev The stakes burned during incident resolution
bytes32 public constant NS_GOVERNANCE_UNSTAKE_BURNED = "ns:gov:unstake:burned";
/// @dev The stakes burned during incident resolution
bytes32 public constant NS_GOVERNANCE_UNSTAKE_REPORTER_FEE = "ns:gov:unstake:rep:fee";
bytes32 public constant NS_GOVERNANCE_REPORTING_MIN_FIRST_STAKE = "ns:gov:rep:min:first:stake";
/// @dev An approximate date and time when trigger event or cover incident occurred
bytes32 public constant NS_GOVERNANCE_REPORTING_INCIDENT_DATE = "ns:gov:rep:incident:date";
/// @dev A period (in solidity timestamp) configurable by cover creators during
/// when NPM tokenholders can vote on incident reporting proposals
bytes32 public constant NS_GOVERNANCE_REPORTING_PERIOD = "ns:gov:rep:period";
/// @dev Used as key element in a couple of places:
/// 1. For uint256 --> Sum total of NPM witnesses who saw incident to have happened
/// 2. For address --> The address of the first reporter
bytes32 public constant NS_GOVERNANCE_REPORTING_WITNESS_YES = "ns:gov:rep:witness:yes";
/// @dev Used as key to flag if a cover was disputed. Cleared when a cover is finalized.
bytes32 public constant NS_GOVERNANCE_REPORTING_HAS_A_DISPUTE = "ns:gov:rep:has:dispute";
/// @dev Used as key to flag if a incident was finalized.
bytes32 public constant NS_GOVERNANCE_REPORTING_FINALIZATION = "ns:gov:rep:has:finalized";
/// @dev Used as key element in a couple of places:
/// 1. For uint256 --> Sum total of NPM witnesses who disagreed with and disputed an incident reporting
/// 2. For address --> The address of the first disputing reporter (disputer / candidate reporter)
bytes32 public constant NS_GOVERNANCE_REPORTING_WITNESS_NO = "ns:gov:rep:witness:no";
/// @dev Stakes guaranteed by an individual witness supporting the "incident happened" camp
bytes32 public constant NS_GOVERNANCE_REPORTING_STAKE_OWNED_YES = "ns:gov:rep:stake:owned:yes";
/// @dev Stakes guaranteed by an individual witness supporting the "false reporting" camp
bytes32 public constant NS_GOVERNANCE_REPORTING_STAKE_OWNED_NO = "ns:gov:rep:stake:owned:no";
/// @dev The percentage rate (x MULTIPLIER) of amount of reporting/unstake reward to burn.
/// @custom:note that the reward comes from the losing camp after resolution is achieved.
bytes32 public constant NS_GOVERNANCE_REPORTING_BURN_RATE = "ns:gov:rep:burn:rate";
/// @dev The percentage rate (x MULTIPLIER) of amount of reporting/unstake
/// reward to provide to the final reporter.
bytes32 public constant NS_GOVERNANCE_REPORTER_COMMISSION = "ns:gov:reporter:commission";
bytes32 public constant NS_CLAIM_PERIOD = "ns:claim:period";
bytes32 public constant NS_CLAIM_PAYOUTS = "ns:claim:payouts";
/// @dev A 24-hour delay after a governance agent "resolves" an actively reported cover.
bytes32 public constant NS_CLAIM_BEGIN_TS = "ns:claim:begin:ts";
/// @dev Claim expiry date = Claim begin date + claim duration
bytes32 public constant NS_CLAIM_EXPIRY_TS = "ns:claim:expiry:ts";
bytes32 public constant NS_RESOLUTION_DEADLINE = "ns:resolution:deadline";
/// @dev Claim expiry date = Claim begin date + claim duration
bytes32 public constant NS_RESOLUTION_COOL_DOWN_PERIOD = "ns:resolution:cdp";
/// @dev The percentage rate (x MULTIPLIER) of amount deducted by the platform
/// for each successful claims payout
bytes32 public constant NS_COVER_PLATFORM_FEE = "ns:cover:platform:fee";
/// @dev The percentage rate (x MULTIPLIER) of amount provided to the first reporter
/// upon favorable incident resolution. This amount is a commission of the
/// 'ns:claim:platform:fee'
bytes32 public constant NS_CLAIM_REPORTER_COMMISSION = "ns:claim:reporter:commission";
bytes32 public constant NS_LAST_LIQUIDITY_STATE_UPDATE = "ns:last:snl:update";
bytes32 public constant NS_LIQUIDITY_STATE_UPDATE_INTERVAL = "ns:snl:update:interval";
bytes32 public constant NS_LENDING_STRATEGY_ACTIVE = "ns:lending:strategy:active";
bytes32 public constant NS_LENDING_STRATEGY_DISABLED = "ns:lending:strategy:disabled";
bytes32 public constant NS_LENDING_STRATEGY_WITHDRAWAL_START = "ns:lending:strategy:w:start";
bytes32 public constant NS_ACCRUAL_INVOCATION = "ns:accrual:invocation";
bytes32 public constant NS_LENDING_STRATEGY_WITHDRAWAL_END = "ns:lending:strategy:w:end";
bytes32 public constant CNAME_PROTOCOL = "Neptune Mutual Protocol";
bytes32 public constant CNAME_TREASURY = "Treasury";
bytes32 public constant CNAME_POLICY = "Policy";
bytes32 public constant CNAME_POLICY_ADMIN = "Policy Admin";
bytes32 public constant CNAME_BOND_POOL = "BondPool";
bytes32 public constant CNAME_STAKING_POOL = "Staking Pool";
bytes32 public constant CNAME_CLAIMS_PROCESSOR = "Claims Processor";
bytes32 public constant CNAME_COVER = "Cover";
bytes32 public constant CNAME_GOVERNANCE = "Governance";
bytes32 public constant CNAME_RESOLUTION = "Resolution";
bytes32 public constant CNAME_VAULT_FACTORY = "Vault Factory";
bytes32 public constant CNAME_CXTOKEN_FACTORY = "cxToken Factory";
bytes32 public constant CNAME_COVER_STAKE = "Cover Stake";
bytes32 public constant CNAME_COVER_REASSURANCE = "Cover Reassurance";
bytes32 public constant CNAME_LIQUIDITY_VAULT = "Vault";
bytes32 public constant CNAME_VAULT_DELEGATE = "Vault Delegate";
bytes32 public constant CNAME_LIQUIDITY_ENGINE = "Liquidity Engine";
function getProtocol(IStore s) external view returns (IProtocol) {
return IProtocol(getProtocolAddress(s));
}
function getProtocolAddress(IStore s) public view returns (address) {
return s.getAddressByKey(CNS_CORE);
}
function getContract(
IStore s,
bytes32 name,
bytes32 key
) public view returns (address) {
if (key > 0) {
return s.getAddressByKeys(NS_CONTRACTS, name, key);
}
return s.getAddressByKeys(NS_CONTRACTS, name);
}
function isProtocolMember(IStore s, address contractAddress) public view returns (bool) {
return s.getBoolByKeys(ProtoUtilV1.NS_MEMBERS, contractAddress);
}
/**
* @dev Reverts if the caller is one of the protocol members.
*/
function mustBeProtocolMember(IStore s, address contractAddress) external view {
bool isMember = isProtocolMember(s, contractAddress);
require(isMember, "Not a protocol member");
}
/**
* @dev Ensures that the sender matches with the exact contract having the specified name.
* @param name Enter the name of the contract
* @param sender Enter the `msg.sender` value
*/
function mustBeExactContract(
IStore s,
bytes32 name,
bytes32 key,
address sender
) public view {
address contractAddress = getContract(s, name, key);
require(sender == contractAddress, "Access denied");
}
/**
* @dev Ensures that the sender matches with the exact contract having the specified name.
* @param name Enter the name of the contract
*/
function senderMustBeExactContract(IStore s, bytes32 name) external view {
return callerMustBeExactContract(s, name, msg.sender);
}
/**
* @dev Ensures that the sender matches with the exact contract having the specified name.
* @param name Enter the name of the contract
*/
function callerMustBeExactContract(
IStore s,
bytes32 name,
address caller
) public view {
return mustBeExactContract(s, name, ProtoUtilV1.KEY_INTENTIONALLY_EMPTY, caller);
}
function npmToken(IStore s) external view returns (IERC20) {
return IERC20(getNpmTokenAddress(s));
}
function getNpmTokenAddress(IStore s) public view returns (address) {
address npm = s.getAddressByKey(CNS_NPM);
return npm;
}
function getUniswapV2Router(IStore s) external view returns (address) {
return s.getAddressByKey(CNS_UNISWAP_V2_ROUTER);
}
function getUniswapV2Factory(IStore s) external view returns (address) {
return s.getAddressByKey(CNS_UNISWAP_V2_FACTORY);
}
function getNpmPriceOracle(IStore s) external view returns (address) {
return s.getAddressByKey(CNS_NPM_PRICE_ORACLE);
}
function getTreasury(IStore s) external view returns (address) {
return s.getAddressByKey(CNS_TREASURY);
}
function getStablecoin(IStore s) public view returns (address) {
return s.getAddressByKey(CNS_COVER_STABLECOIN);
}
function getStablecoinPrecision(IStore s) external view returns (uint256) {
return 10**IERC20Detailed(getStablecoin(s)).decimals();
}
function getBurnAddress(IStore s) external view returns (address) {
return s.getAddressByKey(CNS_BURNER);
}
}