@ensuro/core 2.8.3 → 2.9.1

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.
Files changed (48) hide show
  1. package/README.md +2 -3
  2. package/build/build-info.json +1 -0
  3. package/build/contracts/AccessManager.sol/AccessManager.json +2 -15
  4. package/build/contracts/ERC4626AssetManager.sol/ERC4626AssetManager.json +2 -2
  5. package/build/contracts/ERC4626PlusVaultAssetManager.sol/ERC4626PlusVaultAssetManager.json +2 -2
  6. package/build/contracts/EToken.sol/EToken.json +7 -85
  7. package/build/contracts/FullSignedBucketRiskModule.sol/FullSignedBucketRiskModule.json +1484 -0
  8. package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +7 -85
  9. package/build/contracts/Policy.sol/Policy.json +2 -2
  10. package/build/contracts/PolicyPool.sol/PolicyPool.json +2 -15
  11. package/build/contracts/PolicyPoolComponent.sol/PolicyPoolComponent.json +5 -83
  12. package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +7 -85
  13. package/build/contracts/Reserve.sol/Reserve.json +5 -83
  14. package/build/contracts/RiskModule.sol/RiskModule.json +5 -96
  15. package/build/contracts/SignedBucketRiskModule.sol/SignedBucketRiskModule.json +7 -150
  16. package/build/contracts/SignedQuoteRiskModule.sol/SignedQuoteRiskModule.json +7 -98
  17. package/build/contracts/TimeScaled.sol/TimeScaled.json +2 -2
  18. package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +7 -98
  19. package/build/contracts/dependencies/WadRayMath.sol/WadRayMath.json +2 -2
  20. package/build/contracts/migration/LPManualWhitelistV20.sol/LPManualWhitelistV20.json +5 -83
  21. package/build/contracts/migration/LPManualWhitelistV20Upgraded.sol/LPManualWhitelistV20Upgraded.json +7 -85
  22. package/build/contracts/mocks/FixedRateVault.sol/FixedRateVault.json +2 -2
  23. package/build/contracts/mocks/ForwardProxy.sol/ForwardProxy.json +2 -2
  24. package/build/contracts/mocks/InterfaceIdCalculator.sol/InterfaceIdCalculator.json +2 -2
  25. package/build/contracts/mocks/PolicyHolderMock.sol/PolicyHolderMock.json +2 -2
  26. package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +2 -2
  27. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +2 -2
  28. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +2 -2
  29. package/build/contracts/mocks/RiskModuleMock.sol/RiskModuleMock.json +7 -98
  30. package/build/contracts/mocks/TestCurrency.sol/TestCurrency.json +2 -2
  31. package/contracts/AccessManager.sol +0 -1
  32. package/contracts/EToken.sol +2 -20
  33. package/contracts/FullSignedBucketRiskModule.sol +204 -0
  34. package/contracts/PolicyPool.sol +0 -1
  35. package/contracts/PolicyPoolComponent.sol +7 -44
  36. package/contracts/PremiumsAccount.sol +3 -3
  37. package/contracts/RiskModule.sol +10 -21
  38. package/contracts/SignedBucketRiskModule.sol +15 -9
  39. package/contracts/SignedQuoteRiskModule.sol +7 -4
  40. package/js/deploy.js +1 -1
  41. package/js/test-utils.js +2 -92
  42. package/js/utils.js +67 -208
  43. package/package.json +1 -1
  44. package/scripts/deploySmokeTest-fork.sh +1 -1
  45. package/scripts/deploySmokeTest.sh +1 -1
  46. package/build/contracts/mocks/TestNFT.sol/TestNFT.json +0 -388
  47. package/contracts/mocks/TestNFT.sol +0 -23
  48. package/js/constants.js +0 -13
package/js/utils.js CHANGED
@@ -1,182 +1,7 @@
1
- const { findAll } = require("solidity-ast/utils");
2
1
  const ethers = require("ethers");
3
2
  const helpers = require("@nomicfoundation/hardhat-network-helpers");
4
- const { DAY, IMPLEMENTATION_SLOT } = require("./constants");
5
-
6
- const _E = ethers.parseEther;
7
- const WAD = 10n ** 18n; // 1e18
8
- const RAY = 10n ** 27n; // 1e27
9
-
10
- function getAddress(addressable) {
11
- return addressable.address || addressable.target || addressable;
12
- }
13
-
14
- async function getStorageLayout(hre, contractSrc, contractName) {
15
- const buildInfo = await hre.artifacts.getBuildInfo(`${contractSrc}:${contractName}`);
16
- if (buildInfo === undefined) throw new Error(`Contract ${contractSrc}:${contractName} not in artifacts`);
17
-
18
- const solcOutput = buildInfo.output;
19
-
20
- const storageLayouts = {};
21
-
22
- for (const def of findAll("ContractDefinition", solcOutput.sources[contractSrc].ast)) {
23
- storageLayouts[def.name] = solcOutput.contracts[contractSrc][def.name].storageLayout;
24
- }
25
-
26
- return storageLayouts[contractName];
27
- }
28
-
29
- /**
30
- * Creates a fixed-point conversion function for the desired number of decimals
31
- * @param decimals The number of decimals. Must be >= 6.
32
- * @returns The amount function created. The function can receive strings (recommended),
33
- * floats/doubles (not recommended) and integers.
34
- *
35
- * Floats will be rounded to 6 decimal before scaling.
36
- */
37
- function amountFunction(decimals) {
38
- return function (value) {
39
- if (value === undefined) return undefined;
40
-
41
- if (typeof value === "string" || value instanceof String) {
42
- return ethers.parseUnits(value, decimals);
43
- }
44
-
45
- if (!Number.isInteger(value)) {
46
- return BigInt(Math.round(value * 1e6).toString()) * BigInt(Math.pow(10, decimals - 6).toString());
47
- }
48
-
49
- return BigInt(value.toString()) * BigInt("10") ** BigInt(decimals.toString());
50
- };
51
- }
52
-
53
- /** Wad function */
54
- const _W = amountFunction(18);
55
-
56
- /** Ray function */
57
- const _R = amountFunction(27);
58
-
59
- /**
60
- * Returns a role identifier by computing the keccak of the role name.
61
- */
62
- function getRole(role) {
63
- if (role.startsWith("0x")) return role;
64
- return role === "DEFAULT_ADMIN_ROLE" ? ethers.ZeroHash : ethers.keccak256(ethers.toUtf8Bytes(role));
65
- }
66
-
67
- /**
68
- * Builds the component role identifier
69
- *
70
- * Mimics the behaviour of the AccessManager.getComponentRole method
71
- *
72
- * Component roles are roles created doing XOR between the component
73
- * address and the original role.
74
- *
75
- * Example:
76
- * getComponentRole("0xc6e7DF5E7b4f2A278906862b61205850344D4e7d", "ORACLE_ADMIN_ROLE")
77
- * // "0x05e01b185238b49f750d03d945e38a7f6c3be8b54de0ee42d481eb7814f0d3a8"
78
- */
79
- function getComponentRole(componentAddress, role) {
80
- if (!role.startsWith("0x")) role = getRole(role);
81
-
82
- // 32 byte array
83
- const bytesRole = ethers.getBytes(role);
84
-
85
- // 20 byte array
86
- const bytesAddress = ethers.getBytes(componentAddress);
87
-
88
- // xor each byte, padding bytesAddress with zeros at the end
89
- // eslint-disable-next-line no-bitwise
90
- return ethers.hexlify(bytesRole.map((elem, idx) => elem ^ (bytesAddress[idx] || 0)));
91
- }
92
-
93
- async function getDefaultSigner(hre) {
94
- const signers = await hre.ethers.getSigners();
95
- return signers[0];
96
- }
97
-
98
- /**
99
- * Grant a component role to a user.
100
- */
101
- // eslint-disable-next-line no-empty-function
102
- async function grantComponentRole(hre, contract, component, role, user, txOverrides = {}, log = () => {}) {
103
- let userAddress;
104
- if (user === undefined) {
105
- user = await getDefaultSigner(hre);
106
- userAddress = user.address;
107
- } else {
108
- userAddress = user.address === undefined ? user : user.address;
109
- }
110
- const roleHex = getRole(role);
111
- const componentAddress = component.address || component;
112
- const componentRole = await contract.getComponentRole(componentAddress, roleHex);
113
- if (!(await contract.hasRole(componentRole, userAddress))) {
114
- await contract.grantComponentRole(componentAddress, roleHex, userAddress, txOverrides);
115
- log(`Role ${role} (${roleHex}) Component ${componentAddress} granted to ${userAddress}`);
116
- } else {
117
- log(`Role ${role} (${roleHex}) Component ${componentAddress} already granted to ${userAddress}`);
118
- }
119
- }
120
-
121
- /**
122
- * Grant a role to a user
123
- */
124
- // eslint-disable-next-line no-empty-function
125
- async function grantRole(hre, contract, role, user, txOverrides = {}, log = () => {}) {
126
- let userAddress;
127
- if (user === undefined) {
128
- user = await getDefaultSigner(hre);
129
- userAddress = user.address;
130
- } else {
131
- userAddress = user.address === undefined ? user : user.address;
132
- }
133
- const roleHex = getRole(role);
134
- if (!(await contract.hasRole(roleHex, userAddress))) {
135
- await contract.grantRole(roleHex, userAddress, txOverrides);
136
- log(`Role ${role} (${roleHex}) granted to ${userAddress}`);
137
- } else {
138
- log(`Role ${role} (${roleHex}) already granted to ${userAddress}`);
139
- }
140
- }
141
-
142
- /**
143
- * Finds an event in the receipt
144
- * @param {Interface} interface The interface of the contract that contains the requested event
145
- * @param {TransactionReceipt} receipt Transaction receipt containing the events in the logs
146
- * @param {String} eventName The name of the event we are interested in
147
- * @param {Boolean} firstOnly If false, returns all the events matching the name
148
- * @param {String} contractAddress If not null, if returns only those events generated by the specified contract
149
- * @returns {LogDescription}
150
- */
151
- function getTransactionEvent(interface, receipt, eventName, firstOnly = true, contractAddress = null) {
152
- const ret = [];
153
- // for each log in the transaction receipt
154
- for (const log of receipt.logs) {
155
- let parsedLog;
156
- if (contractAddress !== null && contractAddress !== log.address) continue;
157
- try {
158
- parsedLog = interface.parseLog(log);
159
- } catch (error) {
160
- continue;
161
- }
162
- if (parsedLog?.name == eventName) {
163
- if (firstOnly) return parsedLog;
164
- ret.push(parsedLog);
165
- }
166
- }
167
- return firstOnly ? null : ret;
168
- }
169
-
170
- /**
171
- * Builds AccessControl error message for comparison in tests
172
- */
173
- function accessControlMessage(user, component, role) {
174
- const userAddr = getAddress(user);
175
- const compAddr = component !== null ? getAddress(component) : component;
176
- const roleHash = component !== null ? getComponentRole(compAddr, role) : getRole(role);
177
-
178
- return `AccessControl: account ${userAddr.toLowerCase()} is missing role ${roleHash}`;
179
- }
3
+ const { DAY } = require("@ensuro/utils/js/constants");
4
+ const { amountFunction, getAddress, _W } = require("@ensuro/utils/js/utils");
180
5
 
181
6
  /**
182
7
  * Create a policy id by combining the riskmodule address and the internal id.
@@ -203,6 +28,31 @@ function makeQuoteMessage({ rmAddress, payout, premium, lossProb, expiration, po
203
28
  );
204
29
  }
205
30
 
31
+ function paramsAsUint256(params) {
32
+ /* eslint no-bitwise: "off" */
33
+ return (
34
+ (params.moc << 240n) |
35
+ (params.jrCollRatio << 224n) |
36
+ (params.collRatio << 208n) |
37
+ (params.ensuroPpFee << 192n) |
38
+ (params.ensuroCocFee << 176n) |
39
+ (params.jrRoc << 160n) |
40
+ (params.srRoc << 144n)
41
+ );
42
+ }
43
+
44
+ /**
45
+ * Create a packed quote message for later signing or hashing.
46
+ *
47
+ * Mimics the behaviour of the FullSignedBucketRiskModule._checkFullSignature method.
48
+ */
49
+ function makeFullQuoteMessage({ rmAddress, payout, premium, lossProb, expiration, policyData, params, validUntil }) {
50
+ return ethers.solidityPacked(
51
+ ["address", "uint256", "uint256", "uint256", "uint40", "bytes32", "uint256", "uint40"],
52
+ [rmAddress, payout, premium, lossProb, expiration, policyData, paramsAsUint256(params), validUntil]
53
+ );
54
+ }
55
+
206
56
  /**
207
57
  * Create a packed quote message for later signing or hashing.
208
58
  *
@@ -263,6 +113,42 @@ async function defaultPolicyParams(
263
113
  };
264
114
  }
265
115
 
116
+ async function defaultPolicyParamsWithBucket(opts, _A = amountFunction(6)) {
117
+ const ret = await defaultPolicyParams(opts, _A);
118
+ return { bucketId: opts.bucketId || 0, ...ret };
119
+ }
120
+
121
+ async function defaultPolicyParamsWithParams(opts, _A = amountFunction(6)) {
122
+ const ret = await defaultPolicyParams(opts, _A);
123
+ // struct PackedParams {
124
+ // uint16 moc; // Margin Of Conservativism - factor that multiplies lossProb - 4 decimals
125
+ // uint16 jrCollRatio; // Collateralization Ratio to compute Junior solvency as % of payout - 4 decimals
126
+ // uint16 collRatio; // Collateralization Ratio to compute solvency requirement as % of payout - 4 decimals
127
+ // uint16 ensuroPpFee; // % of pure premium that will go for Ensuro treasury - 4 decimals
128
+ // uint16 ensuroCocFee; // % of CoC that will go for Ensuro treasury - 4 decimals
129
+ // uint16 jrRoc; // Return on Capital paid to Junior LPs - Annualized Percentage - 4 decimals
130
+ // uint16 srRoc; // Return on Capital paid to Senior LPs - Annualized Percentage - 4 decimals
131
+ // uint32 maxPayoutPerPolicy; // Max Payout per Policy - 2 decimals
132
+ // uint32 exposureLimit; // Max exposure (sum of payouts) to be allocated to this module - 0 decimals
133
+ // uint16 maxDuration; // Max policy duration (in hours)
134
+ // }
135
+ const optsParams = opts.params || {};
136
+ const wadTo4Decimals = 10n ** 14n;
137
+ const params = {
138
+ moc: (optsParams.moc || _W(1)) / wadTo4Decimals,
139
+ jrCollRatio: (optsParams.jrCollRatio || 0n) / wadTo4Decimals,
140
+ collRatio: (optsParams.collRatio || _W(1)) / wadTo4Decimals,
141
+ ensuroPpFee: (optsParams.ensuroPpFee || 0n) / wadTo4Decimals,
142
+ ensuroCocFee: (optsParams.ensuroCocFee || 0n) / wadTo4Decimals,
143
+ jrRoc: (optsParams.jrRoc || 0n) / wadTo4Decimals,
144
+ srRoc: (optsParams.srRoc || _W("0.1")) / wadTo4Decimals, // 10%
145
+ maxPayoutPerPolicy: 0n, // Not used
146
+ exposureLimit: 0n, // Not used
147
+ maxDuration: 0n, // Not used
148
+ };
149
+ return { params, ...ret };
150
+ }
151
+
266
152
  function defaultBucketParams({ moc, jrCollRatio, collRatio, ensuroPpFee, ensuroCocFee, jrRoc, srRoc }) {
267
153
  return {
268
154
  moc: moc !== undefined ? moc : _W("1.1"),
@@ -278,43 +164,16 @@ function defaultBucketParams({ moc, jrCollRatio, collRatio, ensuroPpFee, ensuroC
278
164
  };
279
165
  }
280
166
 
281
- async function readImplementationAddress(hre, contractAddress) {
282
- const implStorage = await hre.ethers.provider.getStorageAt(contractAddress, IMPLEMENTATION_SLOT);
283
- return ethers.utils.getAddress(ethers.utils.hexDataSlice(implStorage, 12));
284
- }
285
-
286
- /**
287
- * Converts a string value to uint256(keccak(value))
288
- * @param {string} value
289
- * @returns {ethers.BigNumber}
290
- */
291
- function uintKeccak(value) {
292
- return BigInt(ethers.keccak256(ethers.toUtf8Bytes(value)));
293
- }
294
-
295
167
  module.exports = {
296
- _E,
297
- _R,
298
- _W,
299
- accessControlMessage,
300
- amountFunction,
301
168
  defaultPolicyParams,
169
+ defaultPolicyParamsWithBucket,
170
+ defaultPolicyParamsWithParams,
302
171
  defaultBucketParams,
303
- getAddress,
304
- getComponentRole,
305
- getDefaultSigner,
306
- getRole,
307
- getStorageLayout,
308
- getTransactionEvent,
309
- grantComponentRole,
310
- grantRole,
311
172
  makeBucketQuoteMessage,
173
+ makeFullQuoteMessage,
174
+ paramsAsUint256,
312
175
  makePolicyId,
313
176
  makeQuoteMessage,
314
177
  makeSignedQuote,
315
- RAY,
316
- readImplementationAddress,
317
178
  recoverAddress,
318
- uintKeccak,
319
- WAD,
320
179
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ensuro/core",
3
3
  "description": "Ensuro - Decentralized insurance protocol",
4
- "version": "2.8.3",
4
+ "version": "2.9.1",
5
5
  "files": [
6
6
  "**/*.sol",
7
7
  "/build",
@@ -26,7 +26,7 @@ POOL=`readAddress POOL`
26
26
  ACCESSMANAGER=`readAddress ACCESSMANAGER`
27
27
  echo "PolicyPool = $POOL / AccessManager = $ACCESSMANAGER"
28
28
 
29
- for ROLE in LEVEL1 LEVEL2 LEVEL3; do
29
+ for ROLE in LEVEL1 LEVEL2; do
30
30
  npx hardhat --network $NETWORK ens:grantRole --contract-address $ACCESSMANAGER \
31
31
  --role ${ROLE}_ROLE || die "Error granting ${ROLE}_ROLE"
32
32
  done
@@ -17,7 +17,7 @@ POOL=`readAddress POOL`
17
17
  ACCESSMANAGER=`readAddress ACCESSMANAGER`
18
18
  echo "PolicyPool = $POOL / AccessManager = $ACCESSMANAGER"
19
19
 
20
- for ROLE in LEVEL1 LEVEL2 LEVEL3; do
20
+ for ROLE in LEVEL1 LEVEL2; do
21
21
  npx hardhat --network $NETWORK ens:grantRole --contract-address $ACCESSMANAGER \
22
22
  --role ${ROLE}_ROLE || die "Error granting ${ROLE}_ROLE"
23
23
  done