@ensuro/core 1.2.6 → 2.0.0-beta2

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 (91) hide show
  1. package/README.md +49 -17
  2. package/build/contracts/EToken.sol/EToken.json +163 -173
  3. package/build/contracts/FlightDelayRiskModule.sol/FlightDelayRiskModule.json +112 -315
  4. package/build/contracts/LPManualWhitelist.sol/LPManualWhitelist.json +34 -2
  5. package/build/contracts/Policy.sol/Policy.json +2 -2
  6. package/build/contracts/PolicyNFT.sol/PolicyNFT.json +16 -3
  7. package/build/contracts/PolicyPool.sol/PolicyPool.json +105 -351
  8. package/build/contracts/PolicyPoolComponent.sol/PolicyPoolComponent.json +32 -0
  9. package/build/contracts/PolicyPoolConfig.sol/PolicyPoolConfig.json +77 -98
  10. package/build/contracts/PremiumsAccount.sol/PremiumsAccount.json +761 -0
  11. package/build/contracts/{BaseAssetManager.sol/BaseAssetManager.json → Reserve.sol/Reserve.json} +23 -191
  12. package/build/contracts/RiskModule.sol/RiskModule.json +94 -302
  13. package/build/contracts/TimeScaled.sol/TimeScaled.json +24 -0
  14. package/build/contracts/TrustfulRiskModule.sol/TrustfulRiskModule.json +142 -325
  15. package/build/contracts/dependencies/ChainlinkClientUpgradeable.sol/ChainlinkClientUpgradeable.json +15 -2
  16. package/build/contracts/dependencies/ERC1967Proxy.sol/ERC1967Proxy.json +64 -0
  17. package/build/{interfaces/IExchange.sol/IExchange.json → contracts/dependencies/IERC20Metadata.sol/IERC20Metadata.json} +83 -79
  18. package/build/{interfaces → contracts/interfaces}/IEToken.sol/IEToken.json +32 -97
  19. package/build/{interfaces → contracts/interfaces}/ILPWhitelist.sol/ILPWhitelist.json +1 -1
  20. package/build/{interfaces → contracts/interfaces}/IPolicyHolder.sol/IPolicyHolder.json +1 -1
  21. package/build/{interfaces → contracts/interfaces}/IPolicyNFT.sol/IPolicyNFT.json +1 -1
  22. package/build/{interfaces → contracts/interfaces}/IPolicyPool.sol/IPolicyPool.json +121 -108
  23. package/build/{interfaces → contracts/interfaces}/IPolicyPoolComponent.sol/IPolicyPoolComponent.json +1 -1
  24. package/build/{interfaces → contracts/interfaces}/IPolicyPoolConfig.sol/IPolicyPoolConfig.json +20 -49
  25. package/build/contracts/interfaces/IPremiumsAccount.sol/IPremiumsAccount.json +302 -0
  26. package/build/{interfaces → contracts/interfaces}/IRiskModule.sol/IRiskModule.json +58 -34
  27. package/build/contracts/mocks/ForwardProxy.sol/ForwardProxy.json +43 -0
  28. package/build/{interfaces/IInsolvencyHook.sol/IInsolvencyHook.json → contracts/mocks/IMintableERC20.sol/IMintableERC20.json} +13 -8
  29. package/build/contracts/mocks/LinkTokenMock.sol/LinkTokenMock.json +370 -0
  30. package/build/contracts/mocks/PolicyHolderMock.sol/PolicyHolderMock.json +202 -0
  31. package/build/contracts/mocks/PolicyPoolComponentMock.sol/PolicyPoolComponentMock.json +35 -0
  32. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMock.json +603 -0
  33. package/build/contracts/mocks/PolicyPoolMock.sol/PolicyPoolMockForward.json +92 -0
  34. package/build/contracts/mocks/TestCurrency.sol/TestCurrency.json +343 -0
  35. package/build/contracts/mocks/TestNFT.sol/TestNFT.json +388 -0
  36. package/build/contracts/upgraded/PolicyNFTv1.sol/PolicyNFTv1.json +16 -3
  37. package/build/contracts/upgraded/PolicyNFTv1.sol/PolicyNFTv1_Upgrade.json +16 -3
  38. package/contracts/EToken.sol +210 -267
  39. package/contracts/FlightDelayRiskModule.sol +30 -21
  40. package/contracts/LPManualWhitelist.sol +4 -4
  41. package/contracts/Policy.sol +48 -44
  42. package/contracts/PolicyNFT.sol +2 -2
  43. package/contracts/PolicyPool.sol +114 -467
  44. package/contracts/PolicyPoolComponent.sol +14 -3
  45. package/contracts/PolicyPoolConfig.sol +29 -91
  46. package/contracts/PremiumsAccount.sol +274 -0
  47. package/contracts/Reserve.sol +34 -0
  48. package/contracts/RiskModule.sol +216 -164
  49. package/contracts/TimeScaled.sol +134 -0
  50. package/contracts/TrustfulRiskModule.sol +23 -21
  51. package/contracts/dependencies/ERC1967Proxy.sol +19 -0
  52. package/contracts/dependencies/IERC20Metadata.sol +19 -0
  53. package/contracts/interfaces/IEToken.sol +172 -0
  54. package/{interfaces → contracts/interfaces}/ILPWhitelist.sol +0 -0
  55. package/{interfaces → contracts/interfaces}/IPolicyHolder.sol +0 -0
  56. package/{interfaces → contracts/interfaces}/IPolicyNFT.sol +0 -0
  57. package/contracts/interfaces/IPolicyPool.sol +138 -0
  58. package/{interfaces → contracts/interfaces}/IPolicyPoolComponent.sol +0 -0
  59. package/{interfaces → contracts/interfaces}/IPolicyPoolConfig.sol +31 -22
  60. package/contracts/interfaces/IPremiumsAccount.sol +71 -0
  61. package/contracts/interfaces/IRiskModule.sol +60 -0
  62. package/contracts/mocks/ForwardProxy.sol +66 -0
  63. package/contracts/mocks/IMintableERC20.sol +13 -0
  64. package/contracts/mocks/LinkTokenMock.sol +30 -0
  65. package/contracts/mocks/PolicyHolderMock.sol +68 -0
  66. package/contracts/mocks/PolicyPoolComponentMock.sol +17 -0
  67. package/contracts/mocks/PolicyPoolMock.sol +122 -0
  68. package/contracts/mocks/TestCurrency.sol +35 -0
  69. package/contracts/mocks/TestNFT.sol +23 -0
  70. package/contracts/upgraded/PolicyNFTv1.sol +1 -1
  71. package/js/test-utils.js +278 -0
  72. package/package.json +2 -2
  73. package/build/contracts/AaveAssetManager.sol/AaveAssetManager.json +0 -723
  74. package/build/contracts/DataTypes.sol/DataTypes.json +0 -10
  75. package/build/contracts/Exchange.sol/Exchange.json +0 -546
  76. package/build/contracts/extras/IPriceRiskModule.sol/IPriceRiskModule.json +0 -253
  77. package/build/contracts/extras/PriceRiskModule.sol/PriceRiskModule.json +0 -1036
  78. package/build/interfaces/IAssetManager.sol/IAssetManager.json +0 -31
  79. package/build/interfaces/IExchange.sol/IPriceOracle.json +0 -30
  80. package/contracts/AaveAssetManager.sol +0 -298
  81. package/contracts/BaseAssetManager.sol +0 -301
  82. package/contracts/DataTypes.sol +0 -287
  83. package/contracts/Exchange.sol +0 -173
  84. package/contracts/extras/IPriceRiskModule.sol +0 -41
  85. package/contracts/extras/PriceRiskModule.sol +0 -243
  86. package/interfaces/IAssetManager.sol +0 -23
  87. package/interfaces/IEToken.sol +0 -48
  88. package/interfaces/IExchange.sol +0 -59
  89. package/interfaces/IInsolvencyHook.sol +0 -27
  90. package/interfaces/IPolicyPool.sol +0 -44
  91. package/interfaces/IRiskModule.sol +0 -29
@@ -0,0 +1,66 @@
1
+ //SPDX-License-Identifier: Apache-2.0
2
+
3
+ pragma solidity ^0.8.0;
4
+
5
+ import {Proxy} from "@openzeppelin/contracts/proxy/Proxy.sol";
6
+
7
+ /**
8
+ * @dev This contract provides a fallback function that forwards all calls to another contract using the EVM
9
+ * instruction `call`.
10
+ *
11
+ * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
12
+ * different contract through the {_delegate} function.
13
+ *
14
+ * The success and return data of the delegated call will be returned back to the caller of the proxy.
15
+ */
16
+ contract ForwardProxy is Proxy {
17
+ address internal _forwardTo;
18
+
19
+ constructor(address forwardTo) {
20
+ _forwardTo = forwardTo;
21
+ }
22
+
23
+ /**
24
+ * @dev Delegates the current call to `implementation`.
25
+ *
26
+ * This function does not return to its internall call site, it will return directly to the external caller.
27
+ */
28
+ function _delegate(address implementation) internal virtual override {
29
+ // solhint-disable-next-line no-inline-assembly
30
+ assembly {
31
+ // Copy msg.data. We take full control of memory in this inline assembly
32
+ // block because it will not return to Solidity code. We overwrite the
33
+ // Solidity scratch pad at memory position 0.
34
+ calldatacopy(0, 0, calldatasize())
35
+
36
+ // Call the implementation.
37
+ // out and outsize are 0 because we don't know the size yet.
38
+ // let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
39
+ let result := call(gas(), implementation, 0, 0, calldatasize(), 0, 0)
40
+
41
+ // Copy the returned data.
42
+ returndatacopy(0, 0, returndatasize())
43
+
44
+ switch result
45
+ // delegatecall returns 0 on error.
46
+ case 0 {
47
+ revert(0, returndatasize())
48
+ }
49
+ default {
50
+ return(0, returndatasize())
51
+ }
52
+ }
53
+ }
54
+
55
+ /**
56
+ * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function
57
+ * and {_fallback} should delegate.
58
+ */
59
+ function _implementation() internal view virtual override returns (address) {
60
+ return _forwardTo;
61
+ }
62
+
63
+ function setForwardTo(address forwardTo) external {
64
+ _forwardTo = forwardTo;
65
+ }
66
+ }
@@ -0,0 +1,13 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ /**
5
+ * @title IMintableERC20 interface
6
+ * @dev Interface for mintable / burnable ERC20 - for testing
7
+ * @author Ensuro
8
+ */
9
+ interface IMintableERC20 {
10
+ function mint(address recipient, uint256 amount) external;
11
+
12
+ function burn(address recipient, uint256 amount) external;
13
+ }
@@ -0,0 +1,30 @@
1
+ //SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
5
+ import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol";
6
+
7
+ contract LinkTokenMock is ERC20 {
8
+ address public lastTransferTo;
9
+ uint256 public lastTransferValue;
10
+ bytes public lastTransferData;
11
+
12
+ constructor(
13
+ string memory name_,
14
+ string memory symbol_,
15
+ uint256 initialSupply
16
+ ) ERC20(name_, symbol_) {
17
+ _mint(msg.sender, initialSupply);
18
+ }
19
+
20
+ function transferAndCall(
21
+ address to,
22
+ uint256 value,
23
+ bytes calldata data
24
+ ) external returns (bool success) {
25
+ lastTransferTo = to;
26
+ lastTransferValue = value;
27
+ lastTransferData = data;
28
+ return true;
29
+ }
30
+ }
@@ -0,0 +1,68 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IPolicyHolder} from "../interfaces/IPolicyHolder.sol";
5
+ import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
6
+
7
+ contract PolicyHolderMock is IPolicyHolder {
8
+ uint256 public policyId;
9
+ uint256 public payout;
10
+ bool public fail;
11
+
12
+ event NotificationReceived(uint256 kind, uint256 policyId, address operator, address from);
13
+
14
+ constructor(bool fail_) {
15
+ fail = fail_;
16
+ payout = type(uint256).max;
17
+ }
18
+
19
+ function setFail(bool fail_) external {
20
+ fail = fail_;
21
+ }
22
+
23
+ function onERC721Received(
24
+ address operator,
25
+ address from,
26
+ uint256 policyId_,
27
+ bytes calldata
28
+ ) external override returns (bytes4) {
29
+ if (fail) revert("onERC721Received: They told me I have to fail");
30
+ policyId = policyId_;
31
+ emit NotificationReceived(0, policyId_, operator, from);
32
+ return IERC721Receiver.onERC721Received.selector;
33
+ }
34
+
35
+ function onPolicyExpired(
36
+ address operator,
37
+ address from,
38
+ uint256 policyId_
39
+ ) external override returns (bytes4) {
40
+ if (fail) revert("onPolicyExpired: They told me I have to fail");
41
+ policyId = policyId_;
42
+ payout = 0;
43
+ emit NotificationReceived(1, policyId_, operator, from);
44
+ return IPolicyHolder.onPolicyExpired.selector;
45
+ }
46
+
47
+ /**
48
+ * @dev Whenever an Policy is resolved with payout > 0, this function is called
49
+ *
50
+ * It must return its Solidity selector to confirm the payout.
51
+ * If interface is not implemented by the recipient, it will be ignored and the payout will be successful.
52
+ * If any other value is returned or it reverts, the policy resolution / payout will be reverted.
53
+ *
54
+ * The selector can be obtained in Solidity with `IPolicyPool.onPayoutReceived.selector`.
55
+ */
56
+ function onPayoutReceived(
57
+ address operator,
58
+ address from,
59
+ uint256 policyId_,
60
+ uint256 amount
61
+ ) external override returns (bytes4) {
62
+ if (fail) revert("onPayoutReceived: They told me I have to fail");
63
+ policyId = policyId_;
64
+ payout = amount;
65
+ emit NotificationReceived(2, policyId_, operator, from);
66
+ return IPolicyHolder.onPayoutReceived.selector;
67
+ }
68
+ }
@@ -0,0 +1,17 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IPolicyPool} from "../interfaces/IPolicyPool.sol";
5
+ import {IPolicyPoolComponent} from "../interfaces/IPolicyPoolComponent.sol";
6
+
7
+ contract PolicyPoolComponentMock is IPolicyPoolComponent {
8
+ IPolicyPool internal immutable _policyPool;
9
+
10
+ constructor(IPolicyPool policyPool_) {
11
+ _policyPool = policyPool_;
12
+ }
13
+
14
+ function policyPool() external view override returns (IPolicyPool) {
15
+ return _policyPool;
16
+ }
17
+ }
@@ -0,0 +1,122 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IPolicyPool} from "../interfaces/IPolicyPool.sol";
5
+ import {IRiskModule} from "../interfaces/IRiskModule.sol";
6
+ import {IEToken} from "../interfaces/IEToken.sol";
7
+ import {IPolicyPoolConfig} from "../interfaces/IPolicyPoolConfig.sol";
8
+ import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
9
+ import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
10
+ import {Policy} from "../Policy.sol";
11
+ import {ForwardProxy} from "./ForwardProxy.sol";
12
+
13
+ contract PolicyPoolMock is IPolicyPool {
14
+ using Policy for Policy.PolicyData;
15
+
16
+ uint256 public constant MAX_INT =
17
+ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
18
+
19
+ IERC20Metadata internal _currency;
20
+ IPolicyPoolConfig internal _config;
21
+
22
+ mapping(uint256 => Policy.PolicyData) internal policies;
23
+ mapping(uint256 => bytes32) internal policyHashes;
24
+
25
+ event NewPolicy(IRiskModule indexed riskModule, Policy.PolicyData policy);
26
+ event PolicyResolved(IRiskModule indexed riskModule, uint256 indexed policyId, uint256 payout);
27
+
28
+ constructor(IERC20Metadata currency_, IPolicyPoolConfig config_) {
29
+ _currency = currency_;
30
+ _config = config_;
31
+ _config.connect();
32
+ }
33
+
34
+ function currency() external view override returns (IERC20Metadata) {
35
+ return _currency;
36
+ }
37
+
38
+ function config() external view override returns (IPolicyPoolConfig) {
39
+ return _config;
40
+ }
41
+
42
+ function policyNFT() external pure override returns (address) {
43
+ return address(0);
44
+ }
45
+
46
+ function newPolicy(
47
+ Policy.PolicyData memory policy,
48
+ address, /* customer */
49
+ uint96 internalId
50
+ ) external override returns (uint256) {
51
+ policy.id = (uint256(uint160(address(policy.riskModule))) << 96) + internalId;
52
+ policyHashes[policy.id] = policy.hash();
53
+ emit NewPolicy(IRiskModule(msg.sender), policy);
54
+ return policy.id;
55
+ }
56
+
57
+ function _resolvePolicy(Policy.PolicyData memory policy, uint256 payout) internal {
58
+ require(policy.id != 0, "Policy not found");
59
+ require(policy.hash() == policyHashes[policy.id], "Hash doesn't match");
60
+ require(
61
+ msg.sender == address(policy.riskModule),
62
+ "Only riskModule is authorized to resolve the policy"
63
+ );
64
+ delete policies[policy.id];
65
+ delete policyHashes[policy.id];
66
+ emit PolicyResolved(IRiskModule(msg.sender), policy.id, payout);
67
+ }
68
+
69
+ function resolvePolicy(Policy.PolicyData calldata policy, uint256 payout) external override {
70
+ _resolvePolicy(policy, payout);
71
+ }
72
+
73
+ function expirePolicy(Policy.PolicyData calldata policy) external override {
74
+ _resolvePolicy(policy, 0);
75
+ }
76
+
77
+ function resolvePolicyFullPayout(Policy.PolicyData calldata policy, bool customerWon)
78
+ external
79
+ override
80
+ {
81
+ return _resolvePolicy(policy, customerWon ? policy.payout : 0);
82
+ }
83
+
84
+ function deposit(IEToken, uint256) external pure override {
85
+ revert("Not Implemented deposit");
86
+ }
87
+
88
+ function withdraw(IEToken, uint256) external pure override returns (uint256) {
89
+ revert("Not Implemented withdraw");
90
+ }
91
+ }
92
+
93
+ /**
94
+ * @title PolicyPoolMockForward
95
+ * @dev PolicyPool that forwards fallback calls to another contract. Used to simulate calls to EToken
96
+ * and other contracts that have functions that can be called only from PolicyPool
97
+ */
98
+ contract PolicyPoolMockForward is ForwardProxy {
99
+ uint256 public constant MAX_INT =
100
+ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
101
+
102
+ IERC20Metadata internal _currency;
103
+ IPolicyPoolConfig internal _config;
104
+
105
+ constructor(
106
+ address forwardTo,
107
+ IERC20Metadata currency_,
108
+ IPolicyPoolConfig config_
109
+ ) ForwardProxy(forwardTo) {
110
+ _currency = currency_;
111
+ _config = config_;
112
+ _config.connect();
113
+ }
114
+
115
+ function currency() external view returns (IERC20Metadata) {
116
+ return _currency;
117
+ }
118
+
119
+ function config() external view returns (IPolicyPoolConfig) {
120
+ return _config;
121
+ }
122
+ }
@@ -0,0 +1,35 @@
1
+ //SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
5
+ import {IMintableERC20} from "./IMintableERC20.sol";
6
+
7
+ contract TestCurrency is ERC20, IMintableERC20 {
8
+ address private _owner;
9
+ uint8 internal immutable _decimals;
10
+
11
+ constructor(
12
+ string memory name_,
13
+ string memory symbol_,
14
+ uint256 initialSupply,
15
+ uint8 decimals_
16
+ ) ERC20(name_, symbol_) {
17
+ _owner = msg.sender;
18
+ _decimals = decimals_;
19
+ _mint(msg.sender, initialSupply);
20
+ }
21
+
22
+ function decimals() public view virtual override returns (uint8) {
23
+ return _decimals;
24
+ }
25
+
26
+ function mint(address recipient, uint256 amount) external override {
27
+ // require(msg.sender == _owner, "Only owner can mint");
28
+ return _mint(recipient, amount);
29
+ }
30
+
31
+ function burn(address recipient, uint256 amount) external override {
32
+ // require(msg.sender == _owner, "Only owner can burn");
33
+ return _burn(recipient, amount);
34
+ }
35
+ }
@@ -0,0 +1,23 @@
1
+ //SPDX-License-Identifier: Unlicense
2
+ pragma solidity ^0.8.0;
3
+ pragma experimental ABIEncoderV2;
4
+
5
+ import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
6
+
7
+ contract TestNFT is ERC721 {
8
+ address private _owner;
9
+
10
+ constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {
11
+ _owner = msg.sender;
12
+ }
13
+
14
+ function mint(address recipient, uint256 tokenId) public {
15
+ // require(msg.sender == _owner, "Only owner can mint");
16
+ return _mint(recipient, tokenId);
17
+ }
18
+
19
+ function burn(uint256 tokenId) public {
20
+ require(ERC721.ownerOf(tokenId) == msg.sender, "ERC721: burn of token that is not own");
21
+ return _burn(tokenId);
22
+ }
23
+ }
@@ -5,7 +5,7 @@ import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/U
5
5
  import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
6
6
  import {CountersUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol";
7
7
  import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
8
- import {IPolicyPool} from "../../interfaces/IPolicyPool.sol";
8
+ import {IPolicyPool} from "../interfaces/IPolicyPool.sol";
9
9
  import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
10
10
  import {IPolicyNFTv1} from "./IPolicyNFTv1.sol";
11
11
 
@@ -0,0 +1,278 @@
1
+ const { expect } = require("chai");
2
+ const { BigNumber } = require("ethers");
3
+ const {LogDescription} = require("ethers/lib/utils");
4
+ exports.WEEK = 3600 * 24 * 7;
5
+ exports.DAY = 3600 * 24;
6
+
7
+ exports.initCurrency = async function(options, initial_targets, initial_balances) {
8
+ const Currency = await ethers.getContractFactory("TestCurrency");
9
+ let currency = await Currency.deploy(
10
+ options.name || "Test Currency",
11
+ options.symbol || "TEST",
12
+ options.initial_supply,
13
+ options.decimals || 18,
14
+ );
15
+ initial_targets = initial_targets || [];
16
+ await Promise.all(initial_targets.map(async function (user, index) {
17
+ await currency.transfer(user.address, initial_balances[index]);
18
+ }));
19
+ return currency;
20
+ }
21
+
22
+ exports.approve_multiple = async function(currency, spender, sources, amounts) {
23
+ return Promise.all(sources.map(async function (source, index) {
24
+ await currency.connect(source).approve(spender.address, amounts[index]);
25
+ }));
26
+ }
27
+
28
+ exports.check_balances = async function(currency, users, amounts) {
29
+ return Promise.all(users.map(async function (user, index) {
30
+ expect(await currency.balanceOf(user.address)).to.equal(amounts[index]);
31
+ }));
32
+ }
33
+
34
+ exports.now = function() {
35
+ return Math.floor(new Date().getTime() / 1000);
36
+ }
37
+
38
+ exports.addRiskModule = async function(pool, premiumsAccount, contractFactory, {
39
+ rmName, scrPercentage, scrInterestRate, ensuroFee, maxScrPerPolicy,
40
+ scrLimit, moc, wallet, extraArgs, extraConstructorArgs
41
+ }) {
42
+ extraArgs = extraArgs || [];
43
+ extraConstructorArgs = extraConstructorArgs || [];
44
+ const _A = pool._A || _W;
45
+ const rm = await hre.upgrades.deployProxy(contractFactory, [
46
+ rmName || "RiskModule",
47
+ _W(scrPercentage) || _W(1),
48
+ _W(ensuroFee) || _W(0),
49
+ _W(scrInterestRate) || _W(0.1),
50
+ _A(maxScrPerPolicy) || _A(1000),
51
+ _A(scrLimit) || _A(1000000),
52
+ wallet || "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", // Random address
53
+ ...extraArgs
54
+ ], {
55
+ kind: 'uups',
56
+ unsafeAllow: ["delegatecall"],
57
+ constructorArgs: [pool.address, premiumsAccount.address, ...extraConstructorArgs]
58
+ });
59
+
60
+ await rm.deployed();
61
+
62
+ if (moc !== undefined && moc != 1.0) {
63
+ moc = _W(moc);
64
+ await rm.setParam(0, moc);
65
+ }
66
+ const policyPoolConfig = await hre.ethers.getContractAt("PolicyPoolConfig", await pool.config());
67
+ await policyPoolConfig.addRiskModule(rm.address);
68
+ return rm;
69
+ }
70
+
71
+ exports.addEToken = async function(pool, {
72
+ etkName, etkSymbol, maxUtilizationRate,
73
+ poolLoanInterestRate, extraArgs, extraConstructorArgs
74
+ }) {
75
+ const EToken = await ethers.getContractFactory("EToken");
76
+ extraArgs = extraArgs || [];
77
+ extraConstructorArgs = extraConstructorArgs || [];
78
+ const etk = await hre.upgrades.deployProxy(EToken, [
79
+ etkName || "EToken",
80
+ etkSymbol || "eUSD1YEAR",
81
+ _W(maxUtilizationRate) || _W(1),
82
+ _W(poolLoanInterestRate) || _W("0.05"),
83
+ ...extraArgs
84
+ ], {
85
+ kind: 'uups',
86
+ unsafeAllow: ["delegatecall"],
87
+ constructorArgs: [pool.address, ...extraConstructorArgs]
88
+ });
89
+
90
+ await etk.deployed();
91
+ await pool.addEToken(etk.address);
92
+ return etk;
93
+ }
94
+
95
+ exports.expected_change = async function(protocol_attribute, initial, change) {
96
+ change = BigNumber.from(change);
97
+ let actual_value = await protocol_attribute();
98
+ expect(actual_value.sub(initial)).to.equal(change);
99
+ return actual_value;
100
+ }
101
+
102
+ exports.impersonate = async function(address, setBalanceTo) {
103
+ const ok = await hre.network.provider.request(
104
+ {method: "hardhat_impersonateAccount", params: [address]}
105
+ );
106
+ if (!ok)
107
+ throw "Error impersonatting " + address;
108
+
109
+ if (setBalanceTo !== undefined)
110
+ await hre.network.provider.request(
111
+ {method: "hardhat_setBalance", params: [address, setBalanceTo.toHexString()]}
112
+ );
113
+
114
+ return await ethers.getSigner(address);
115
+ }
116
+
117
+
118
+ /**
119
+ * Finds an event in the receipt
120
+ * @param {Interface} interface The interface of the contract that contains the requested event
121
+ * @param {TransactionReceipt} receipt Transaction receipt containing the events in the logs
122
+ * @param {String} eventName The name of the event we are interested in
123
+ * @returns {LogDescription}
124
+ */
125
+ exports.getTransactionEvent = function(interface, receipt, eventName) {
126
+ // for each log in the transaction receipt
127
+ for (const log of receipt.events) {
128
+ let parsedLog;
129
+ try {
130
+ parsedLog = interface.parseLog(log);
131
+ } catch (error) {
132
+ continue;
133
+ }
134
+ if (parsedLog.name == eventName) {
135
+ return parsedLog;
136
+ }
137
+ }
138
+ return null; // not found
139
+ }
140
+
141
+ exports.deployPool = async function(hre, options) {
142
+ const PolicyPool = await ethers.getContractFactory("PolicyPool");
143
+ const PolicyPoolConfig = await ethers.getContractFactory("PolicyPoolConfig");
144
+ const PolicyNFT = await ethers.getContractFactory("PolicyNFT");
145
+
146
+ // Deploy PolicyNFT
147
+ const policyNFT = await hre.upgrades.deployProxy(
148
+ PolicyNFT,
149
+ [
150
+ options.nftName || "Policy NFT",
151
+ options.nftSymbol || "EPOL",
152
+ options.policyPoolDetAddress || ethers.constants.AddressZero
153
+ ],
154
+ {kind: 'uups'}
155
+ );
156
+ await policyNFT.deployed();
157
+
158
+ // Deploy PolicyPoolConfig
159
+ const policyPoolConfig = await hre.upgrades.deployProxy(PolicyPoolConfig, [
160
+ options.policyPoolDetAddress || ethers.constants.AddressZero,
161
+ options.treasuryAddress || ethers.constants.AddressZero
162
+ ], {kind: 'uups'});
163
+
164
+ await policyPoolConfig.deployed();
165
+
166
+ const policyPool = await hre.upgrades.deployProxy(PolicyPool, [], {
167
+ constructorArgs: [policyPoolConfig.address, policyNFT.address, options.currency],
168
+ kind: 'uups',
169
+ unsafeAllow: ["delegatecall"],
170
+ });
171
+
172
+ await policyPool.deployed();
173
+
174
+ for (const role of (options.grantRoles || [])) {
175
+ await grantRole(hre, policyPoolConfig, role);
176
+ }
177
+
178
+ await grantRole(hre, policyPoolConfig, "LEVEL1_ROLE");
179
+ await grantRole(hre, policyPoolConfig, "LEVEL2_ROLE");
180
+ await grantRole(hre, policyPoolConfig, "LEVEL3_ROLE");
181
+ return policyPool;
182
+ }
183
+
184
+ exports.deployPremiumsAccount = async function (hre, pool, options) {
185
+ const PremiumsAccount = await ethers.getContractFactory("PremiumsAccount");
186
+ const premiumsAccount = await hre.upgrades.deployProxy(PremiumsAccount, [], {
187
+ constructorArgs: [
188
+ pool.address,
189
+ options.jrEtkAddr || ethers.constants.AddressZero,
190
+ options.srEtkAddr || ethers.constants.AddressZero,
191
+ ],
192
+ kind: 'uups',
193
+ unsafeAllow: ["delegatecall"],
194
+ });
195
+
196
+ await premiumsAccount.deployed();
197
+ await pool.addPremiumsAccount(premiumsAccount.address);
198
+ return premiumsAccount;
199
+ }
200
+
201
+ async function _getDefaultSigner(hre) {
202
+ const signers = await hre.ethers.getSigners();
203
+ return signers[0];
204
+ }
205
+
206
+ async function grantRole(hre, contract, role, user) {
207
+ let userAddress;
208
+ if (user === undefined) {
209
+ user = await _getDefaultSigner(hre);
210
+ userAddress = user.address;
211
+ } else {
212
+ userAddress = user;
213
+ }
214
+ const roleHex = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
215
+ if (!await contract.hasRole(roleHex, userAddress)) {
216
+ await contract.grantRole(roleHex, userAddress);
217
+ }
218
+ }
219
+
220
+ exports.grantRole = grantRole;
221
+
222
+ async function grantComponentRole(hre, contract, component, role, user) {
223
+ let userAddress;
224
+ if (user === undefined) {
225
+ user = await _getDefaultSigner(hre);
226
+ userAddress = user.address;
227
+ } else {
228
+ userAddress = user;
229
+ }
230
+ const roleHex = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(role));
231
+ const componentRole = await contract.getComponentRole(component.address, roleHex);
232
+ if (!await contract.hasRole(componentRole, userAddress)) {
233
+ await contract.grantComponentRole(component.address, roleHex, userAddress);
234
+ }
235
+ }
236
+
237
+ exports.grantComponentRole = grantComponentRole;
238
+
239
+ exports._E = ethers.utils.parseEther;
240
+
241
+ const _BN = ethers.BigNumber.from;
242
+ const WAD = _BN(1e10).mul(_BN(1e8)); // 1e10*1e8=1e18
243
+ const RAY = WAD.mul(_BN(1e9)); // 1e18*1e9=1e27
244
+
245
+ exports._BN = _BN;
246
+
247
+ const _W = function(value) {
248
+ if (value === undefined)
249
+ return undefined;
250
+ if (!Number.isInteger(value))
251
+ return _BN(Math.round(value * 1e9)).mul(_BN(1e9));
252
+ return _BN(value).mul(WAD);
253
+ }
254
+
255
+ exports._W = _W;
256
+
257
+ const _R = function(value) {
258
+ if (value === undefined)
259
+ return undefined;
260
+ if (!Number.isInteger(value))
261
+ return _BN(Math.round(value * 1e9)).mul(WAD);
262
+ return _BN(value).mul(RAY);
263
+ }
264
+
265
+ exports._R = _R;
266
+
267
+ exports.amountFunction = function (decimals) {
268
+ // Decimals must be at least 6
269
+ return function (value) {
270
+ if (value === undefined)
271
+ return undefined;
272
+ if (typeof value === 'string' || value instanceof String) {
273
+ return _BN(value).mul(_BN(Math.pow(10, decimals)));
274
+ } else {
275
+ return _BN(Math.round(value * 1e6)).mul(_BN(Math.pow(10, decimals - 6)));
276
+ }
277
+ }
278
+ }
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@ensuro/core",
3
3
  "description": "Ensuro - Decentralized insurance protocol",
4
- "version": "1.2.6",
4
+ "version": "2.0.0-beta2",
5
5
  "files": [
6
6
  "**/*.sol",
7
7
  "/build/contracts/*.json",
8
8
  "/build/interfaces/*.json",
9
- "!/mocks/**/*"
9
+ "/js/*.js"
10
10
  ],
11
11
  "repository": {
12
12
  "type": "git",