forked from neptune-mutual-blue/protocol
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Cover.sol
178 lines (153 loc) · 6.17 KB
/
Cover.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
// Neptune Mutual Protocol (https://neptunemutual.com)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.4.22 <0.9.0;
import "./CoverBase.sol";
import "../../interfaces/ICoverStake.sol";
import "../../interfaces/ICoverStake.sol";
import "../../interfaces/IVault.sol";
import "../liquidity/Vault.sol";
/**
* @title Cover Contract
* @dev The cover contract facilitates you create and update covers
*/
contract Cover is CoverBase {
using ProtoUtilV1 for bytes;
using ProtoUtilV1 for IStore;
using StoreKeyUtil for IStore;
using CoverUtilV1 for IStore;
using RegistryLibV1 for IStore;
using ValidationLibV1 for IStore;
using NTransferUtilV2 for IERC20;
/**
* @dev Constructs this contract
* @param store Enter the store
*/
constructor(IStore store) CoverBase(store) {
this;
}
/**
* @dev Updates the cover contract.
* This feature is accessible only to the cover owner or protocol owner (governance).
*
* @param key Enter the cover key
* @param info Enter a new IPFS URL to update
*/
function updateCover(bytes32 key, bytes32 info) external override nonReentrant {
s.mustNotBePaused();
s.mustBeValidCover(key);
if (AccessControlLibV1.hasAccess(s, AccessControlLibV1.NS_ROLES_ADMIN, msg.sender) == false) {
s.mustBeCoverOwner(key, msg.sender);
}
require(s.getBytes32ByKeys(ProtoUtilV1.NS_COVER_INFO, key) != info, "Duplicate content");
s.setBytes32ByKeys(ProtoUtilV1.NS_COVER_INFO, key, info);
emit CoverUpdated(key, info);
}
/**
* @dev Adds a new coverage pool or cover contract.
* To add a new cover, you need to pay cover creation fee
* and stake minimum amount of NPM in the Vault. <br /> <br />
*
* Through the governance portal, projects will be able redeem
* the full cover fee at a later date. <br /> <br />
*
* **Apply for Fee Redemption** <br />
* https://docs.neptunemutual.com/covers/cover-fee-redemption <br /><br />
*
* As the cover creator, you will earn a portion of all cover fees
* generated in this pool. <br /> <br />
*
* Read the documentation to learn more about the fees: <br />
* https://docs.neptunemutual.com/covers/contract-creators
*
* @param key Enter a unique key for this cover
* @param info IPFS info of the cover contract
* @param assuranceToken **Optional.** Token added as an assurance of this cover. <br /><br />
*
* Assurance tokens can be added by a project to demonstrate coverage support
* for their own project. This helps bring the cover fee down and enhances
* liquidity provider confidence. Along with the NPM tokens, the assurance tokens are rewarded
* as a support to the liquidity providers when a cover incident occurs.
* @param reportingPeriod The period during when reporting happens.
* @param initialAssuranceAmount **Optional.** Enter the initial amount of
* assurance tokens you'd like to add to this pool.
* @param stakeWithFee Enter the total NPM amount (stake + fee) to transfer to this contract.
* @param initialLiquidity **Optional.** Enter the initial stablecoin liquidity for this cover.
*/
function addCover(
bytes32 key,
bytes32 info,
uint256 reportingPeriod,
uint256 stakeWithFee,
address assuranceToken,
uint256 initialAssuranceAmount,
uint256 initialLiquidity
) external override nonReentrant {
s.mustNotBePaused();
require(reportingPeriod >= 7 days, "Insufficent reporting period");
// First validate the information entered
uint256 fee = _validateAndGetFee(key, info, stakeWithFee);
// Set the basic cover info
_addCover(key, info, reportingPeriod, fee, assuranceToken);
// Stake the supplied NPM tokens and burn the fees
s.getStakingContract().increaseStake(key, msg.sender, stakeWithFee, fee);
// Add cover assurance
if (initialAssuranceAmount > 0) {
s.getAssuranceContract().addAssurance(key, msg.sender, initialAssuranceAmount);
}
// Add initial liquidity
if (initialLiquidity > 0) {
IVault vault = s.getVault(key);
s.getVault(key).addLiquidityInternal(key, msg.sender, initialLiquidity);
// Transfer liquidity only after minting the pods
IERC20(s.getLiquidityToken()).ensureTransferFrom(msg.sender, address(vault), initialLiquidity);
}
emit CoverCreated(key, info, stakeWithFee, initialLiquidity);
}
/**
* Adds a new cover contract
* @param key Enter a unique key for this cover
* @param info IPFS info of the cover contract
* @param reportingPeriod The period during when reporting happens.
* @param fee Fee paid to create this cover
* @param assuranceToken **Optional.** Token added as an assurance of this cover.
*/
function _addCover(
bytes32 key,
bytes32 info,
uint256 reportingPeriod,
uint256 fee,
address assuranceToken
) private {
// Add a new cover
s.setBoolByKeys(ProtoUtilV1.NS_COVER, key, true);
// Set cover owner
s.setAddressByKeys(ProtoUtilV1.NS_COVER_OWNER, key, msg.sender);
// Set cover info
s.setBytes32ByKeys(ProtoUtilV1.NS_COVER_INFO, key, info);
s.setUintByKeys(ProtoUtilV1.NS_REPORTING_PERIOD, key, reportingPeriod);
// Set assurance token
s.setAddressByKeys(ProtoUtilV1.NS_COVER_ASSURANCE_TOKEN, key, assuranceToken);
s.setUintByKeys(ProtoUtilV1.NS_COVER_ASSURANCE_WEIGHT, key, 500000000 gwei); // Default 50% weight
// Set the fee charged during cover creation
s.setUintByKeys(ProtoUtilV1.NS_COVER_FEE, key, fee);
// Deploy cover liquidity contract
address deployed = s.getVaultFactoryContract().deploy(s, key);
s.setAddressByKeys(ProtoUtilV1.NS_CONTRACTS, ProtoUtilV1.NS_COVER_VAULT, key, deployed);
s.setBoolByKeys(ProtoUtilV1.NS_MEMBERS, deployed, true);
}
/**
* @dev Validation checks before adding a new cover
* @return Returns fee required to create a new cover
*/
function _validateAndGetFee(
bytes32 key,
bytes32 info,
uint256 stakeWithFee
) private view returns (uint256) {
require(info > 0, "Invalid info");
(uint256 fee, uint256 minStake) = s.getCoverFee();
require(stakeWithFee > fee + minStake, "NPM Insufficient");
require(s.getBoolByKeys(ProtoUtilV1.NS_COVER, key) == false, "Already exists");
return fee;
}
}