@venusprotocol/venus-protocol 9.8.0-dev.6 → 9.8.0-dev.7

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 (88) hide show
  1. package/deploy/002-interest-rate-model.ts +59 -83
  2. package/deploy/007-deploy-mock-tokens.ts +4 -3
  3. package/deploy/011-deploy-markets.ts +21 -37
  4. package/deploy/999-checks/001-check-rate-models.ts +183 -0
  5. package/deployments/bscmainnet.json +429 -429
  6. package/deployments/bscmainnet_addresses.json +29 -29
  7. package/deployments/bsctestnet.json +413 -413
  8. package/deployments/bsctestnet_addresses.json +14 -14
  9. package/dist/deploy/002-interest-rate-model.js +61 -78
  10. package/dist/deploy/007-deploy-mock-tokens.js +4 -2
  11. package/dist/deploy/011-deploy-markets.js +18 -35
  12. package/dist/deploy/999-checks/001-check-rate-models.d.ts +3 -0
  13. package/dist/deploy/999-checks/001-check-rate-models.js +107 -0
  14. package/dist/deployments/bscmainnet.json +429 -429
  15. package/dist/deployments/bsctestnet.json +413 -413
  16. package/dist/hardhat.config.js +2 -0
  17. package/dist/helpers/chains.d.ts +38 -0
  18. package/dist/helpers/chains.js +76 -0
  19. package/dist/helpers/deploymentConfig.d.ts +3 -29
  20. package/dist/helpers/deploymentConfig.js +1 -530
  21. package/dist/helpers/markets/bscmainnet.d.ts +653 -0
  22. package/dist/helpers/markets/bscmainnet.js +691 -0
  23. package/dist/helpers/markets/bsctestnet.d.ts +529 -0
  24. package/dist/helpers/markets/bsctestnet.js +561 -0
  25. package/dist/helpers/markets/hardhat.d.ts +65 -0
  26. package/dist/helpers/markets/hardhat.js +70 -0
  27. package/dist/helpers/markets/index.d.ts +122 -0
  28. package/dist/helpers/markets/index.js +94 -0
  29. package/dist/helpers/markets/types.d.ts +60 -0
  30. package/dist/helpers/markets/types.js +2 -0
  31. package/dist/helpers/rateModelHelpers.d.ts +4 -0
  32. package/dist/helpers/rateModelHelpers.js +35 -0
  33. package/dist/helpers/tokens/bscmainnet.d.ts +253 -0
  34. package/dist/helpers/tokens/bscmainnet.js +258 -0
  35. package/dist/helpers/tokens/bsctestnet.d.ts +204 -0
  36. package/dist/helpers/tokens/bsctestnet.js +209 -0
  37. package/dist/helpers/tokens/common/indexBySymbol.d.ts +6 -0
  38. package/dist/helpers/tokens/common/indexBySymbol.js +8 -0
  39. package/dist/helpers/tokens/hardhat.d.ts +27 -0
  40. package/dist/helpers/tokens/hardhat.js +30 -0
  41. package/dist/helpers/tokens/index.d.ts +1498 -0
  42. package/dist/helpers/tokens/index.js +38 -0
  43. package/dist/helpers/tokens/types.d.ts +12 -0
  44. package/dist/helpers/tokens/types.js +2 -0
  45. package/package.json +1 -1
  46. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope10000bps_jump25000bps_kink8000bps.json → JumpRateModel_base0bps_slope10000bps_jump25000bps_kink8000bps_bpy10512000.json} +0 -0
  47. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope10000bps_jump50000bps_kink8000bps.json → JumpRateModel_base0bps_slope10000bps_jump50000bps_kink8000bps_bpy10512000.json} +0 -0
  48. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope1000bps_jump20000bps_kink7500bps.json → JumpRateModel_base0bps_slope1000bps_jump20000bps_kink7500bps_bpy10512000.json} +0 -0
  49. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope1000bps_jump25000bps_kink8000bps.json → JumpRateModel_base0bps_slope1000bps_jump25000bps_kink8000bps_bpy10512000.json} +0 -0
  50. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope1000bps_jump50000bps_kink8000bps.json → JumpRateModel_base0bps_slope1000bps_jump50000bps_kink8000bps_bpy10512000.json} +0 -0
  51. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope1250bps_jump25000bps_kink8000bps.json → JumpRateModel_base0bps_slope1250bps_jump25000bps_kink8000bps_bpy10512000.json} +0 -0
  52. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope1250bps_jump50000bps_kink8000bps.json → JumpRateModel_base0bps_slope1250bps_jump50000bps_kink8000bps_bpy10512000.json} +0 -0
  53. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope1500bps_jump30000bps_kink6000bps.json → JumpRateModel_base0bps_slope1500bps_jump30000bps_kink6000bps_bpy10512000.json} +0 -0
  54. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope1750bps_jump25000bps_kink8000bps.json → JumpRateModel_base0bps_slope1750bps_jump25000bps_kink8000bps_bpy10512000.json} +0 -0
  55. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope2000bps_jump30000bps_kink5000bps.json → JumpRateModel_base0bps_slope2000bps_jump30000bps_kink5000bps_bpy10512000.json} +0 -0
  56. /package/deployments/bscmainnet/{InterestRateModelVETH.json → JumpRateModel_base0bps_slope300bps_jump45000bps_kink9000bps_bpy10512000.json} +0 -0
  57. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope687bps_jump25000bps_kink8000bps.json → JumpRateModel_base0bps_slope687bps_jump25000bps_kink8000bps_bpy10512000.json} +0 -0
  58. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope750bps_jump50000bps_kink8000bps.json → JumpRateModel_base0bps_slope750bps_jump50000bps_kink8000bps_bpy10512000.json} +0 -0
  59. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope750bps_jump5000bps_kink8000bps.json → JumpRateModel_base0bps_slope750bps_jump5000bps_kink8000bps_bpy10512000.json} +0 -0
  60. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope875bps_jump25000bps_kink8000bps.json → JumpRateModel_base0bps_slope875bps_jump25000bps_kink8000bps_bpy10512000.json} +0 -0
  61. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope875bps_jump50000bps_kink8000bps.json → JumpRateModel_base0bps_slope875bps_jump50000bps_kink8000bps_bpy10512000.json} +0 -0
  62. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope900bps_jump20000bps_kink5000bps.json → JumpRateModel_base0bps_slope900bps_jump20000bps_kink5000bps_bpy10512000.json} +0 -0
  63. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope900bps_jump20000bps_kink7500bps.json → JumpRateModel_base0bps_slope900bps_jump20000bps_kink7500bps_bpy10512000.json} +0 -0
  64. /package/deployments/bscmainnet/{JumpRateModel_base0bps_slope900bps_jump35000bps_kink4500bps.json → JumpRateModel_base0bps_slope900bps_jump35000bps_kink4500bps_bpy10512000.json} +0 -0
  65. /package/deployments/bscmainnet/{JumpRateModel_base200bps_slope10000bps_jump30000bps_kink100bps.json → JumpRateModel_base200bps_slope10000bps_jump30000bps_kink100bps_bpy10512000.json} +0 -0
  66. /package/deployments/bscmainnet/{JumpRateModel_base200bps_slope1200bps_jump30000bps_kink6000bps.json → JumpRateModel_base200bps_slope1200bps_jump30000bps_kink6000bps_bpy10512000.json} +0 -0
  67. /package/deployments/bscmainnet/{JumpRateModel_base200bps_slope1500bps_jump30000bps_kink6000bps.json → JumpRateModel_base200bps_slope1500bps_jump30000bps_kink6000bps_bpy10512000.json} +0 -0
  68. /package/deployments/bscmainnet/{JumpRateModel_base200bps_slope2000bps_jump30000bps_kink5000bps.json → JumpRateModel_base200bps_slope2000bps_jump30000bps_kink5000bps_bpy10512000.json} +0 -0
  69. /package/deployments/bscmainnet/{JumpRateModel_base5000bps_slope3000bps_jump30000bps_kink6000bps.json → JumpRateModel_base5000bps_slope3000bps_jump30000bps_kink6000bps_bpy10512000.json} +0 -0
  70. /package/deployments/bscmainnet/{TwoKinks_base0bps_slope1500bps_kink8000bps_slope29000bps_base20bps_kink29000bps_jump30000bps.json → TwoKinks_base0bps_slope1500bps_kink8000bps_slope29000bps_base20bps_kink29000bps_jump30000bps_bpy10512000.json} +0 -0
  71. /package/deployments/bscmainnet/{InterestRateModelVBNB.json → TwoKinks_base0bps_slope350bps_kink8000bps_slope217500bps_base20bps_kink29000bps_jump30000bps_bpy10512000.json} +0 -0
  72. /package/deployments/bscmainnet/{WhitePaperInterestRateModel_base0bps_slope0bps.json → WhitePaperInterestRateModel_base0bps_slope0bps_bpy10512000.json} +0 -0
  73. /package/deployments/bscmainnet/{WhitePaperInterestRateModel_base0bps_slope24000bps.json → WhitePaperInterestRateModel_base0bps_slope24000bps_bpy10512000.json} +0 -0
  74. /package/deployments/bscmainnet/{WhitePaperInterestRateModel_base2629bps_slope30000bps.json → WhitePaperInterestRateModel_base2629bps_slope30000bps_bpy10512000.json} +0 -0
  75. /package/deployments/bsctestnet/{JumpRateModel_base0bps_slope1000bps_jump20000bps_kink7500bps.json → JumpRateModel_base0bps_slope1000bps_jump20000bps_kink7500bps_bpy10512000.json} +0 -0
  76. /package/deployments/bsctestnet/{JumpRateModel_base0bps_slope1000bps_jump25000bps_kink8000bps.json → JumpRateModel_base0bps_slope1000bps_jump25000bps_kink8000bps_bpy10512000.json} +0 -0
  77. /package/deployments/bsctestnet/{JumpRateModel_base0bps_slope2000bps_jump30000bps_kink5000bps.json → JumpRateModel_base0bps_slope2000bps_jump30000bps_kink5000bps_bpy10512000.json} +0 -0
  78. /package/deployments/bsctestnet/{JumpRateModel_base0bps_slope500bps_jump10900bps_kink8000bps.json → JumpRateModel_base0bps_slope500bps_jump10900bps_kink8000bps_bpy10512000.json} +0 -0
  79. /package/deployments/bsctestnet/{JumpRateModel_base0bps_slope500bps_jump5000bps_kink8000bps.json → JumpRateModel_base0bps_slope500bps_jump5000bps_kink8000bps_bpy10512000.json} +0 -0
  80. /package/deployments/bsctestnet/{JumpRateModel_base0bps_slope687bps_jump25000bps_kink8000bps.json → JumpRateModel_base0bps_slope687bps_jump25000bps_kink8000bps_bpy10512000.json} +0 -0
  81. /package/deployments/bsctestnet/{JumpRateModel_base0bps_slope750bps_jump5000bps_kink8000bps.json → JumpRateModel_base0bps_slope750bps_jump5000bps_kink8000bps_bpy10512000.json} +0 -0
  82. /package/deployments/bsctestnet/{JumpRateModel_base0bps_slope900bps_jump20000bps_kink5000bps.json → JumpRateModel_base0bps_slope900bps_jump20000bps_kink5000bps_bpy10512000.json} +0 -0
  83. /package/deployments/bsctestnet/{JumpRateModel_base0bps_slope900bps_jump35000bps_kink4500bps.json → JumpRateModel_base0bps_slope900bps_jump35000bps_kink4500bps_bpy10512000.json} +0 -0
  84. /package/deployments/bsctestnet/{JumpRateModel_base200bps_slope1500bps_jump30000bps_kink6000bps.json → JumpRateModel_base200bps_slope1500bps_jump30000bps_kink6000bps_bpy10512000.json} +0 -0
  85. /package/deployments/bsctestnet/{JumpRateModel_base200bps_slope2000bps_jump30000bps_kink5000bps.json → JumpRateModel_base200bps_slope2000bps_jump30000bps_kink5000bps_bpy10512000.json} +0 -0
  86. /package/deployments/bsctestnet/{InterestRateModelVBNB.json → TwoKinks_base0bps_slope350bps_kink8000bps_slope217500bps_base20bps_kink29000bps_jump30000bps_bpy10512000.json} +0 -0
  87. /package/deployments/bsctestnet/{WhitePaperInterestRateModel_base0bps_slope10000bps.json → WhitePaperInterestRateModel_base0bps_slope10000bps_bpy10512000.json} +0 -0
  88. /package/deployments/bsctestnet/{WhitepaperInterestRateModel.json → WhitePaperInterestRateModel_base200bps_slope1000bps_bpy10512000.json} +0 -0
@@ -1,18 +1,19 @@
1
- import { BigNumber, BigNumberish } from "ethers";
2
- import { parseUnits } from "ethers/lib/utils";
3
1
  import { DeployFunction } from "hardhat-deploy/types";
4
2
  import { HardhatRuntimeEnvironment } from "hardhat/types";
5
3
 
6
- const mantissaToBps = (num: BigNumberish) => {
7
- return BigNumber.from(num).div(parseUnits("1", 14)).toString();
8
- };
4
+ import { assertBlockBasedChain, blocksPerYear as chainBlocksPerYear } from "../helpers/chains";
5
+ import { skipRemoteNetworks } from "../helpers/deploymentConfig";
6
+ import { markets } from "../helpers/markets";
7
+ import { getRateModelName } from "../helpers/rateModelHelpers";
9
8
 
10
9
  const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
11
10
  const { deployments, getNamedAccounts, network } = hre;
12
11
  const { deploy } = deployments;
12
+ const chain = assertBlockBasedChain(hre.network.name);
13
13
 
14
14
  const { deployer } = await getNamedAccounts();
15
15
 
16
+ // Keeping this hardcoded since 003-deploy-VBep20 (used in subgraph tests) depends on it
16
17
  if (!network.live) {
17
18
  await deploy("InterestRateModelVUSDC", {
18
19
  contract: "JumpRateModel",
@@ -31,89 +32,64 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
31
32
  });
32
33
  }
33
34
 
34
- if (network.name === "bscmainnet") {
35
- await deploy("InterestRateModelVETH", {
36
- contract: "JumpRateModel",
37
- from: deployer,
38
- log: true,
39
- autoMine: true,
40
- args: [0, parseUnits("0.03", 18), parseUnits("4.5", 18), parseUnits("0.9", 18)],
41
- });
35
+ const marketsConfig = markets[chain];
36
+ const blocksPerYear = chainBlocksPerYear[chain];
42
37
 
43
- let baseRatePerYear = parseUnits("0", 18);
44
- let multiplierPerYear = parseUnits("0.175", 18);
45
- let jumpMultiplierPerYear = parseUnits("2.5", 18);
46
- let kink = parseUnits("0.8", 18);
47
- const [b, m, j, k] = [baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink].map(mantissaToBps);
48
- let rateModelName = `JumpRateModel_base${b}bps_slope${m}bps_jump${j}bps_kink${k}bps`;
49
-
50
- await deploy(rateModelName, {
51
- contract: "JumpRateModel",
52
- from: deployer,
53
- log: true,
54
- autoMine: true,
55
- args: [baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink],
56
- skipIfAlreadyDeployed: true,
57
- });
38
+ for (const market of marketsConfig) {
39
+ const { interestRateModel, symbol } = market;
40
+ const rateModelName = getRateModelName(interestRateModel, blocksPerYear);
41
+ console.log(`Deploying interest rate model ${rateModelName} for ${symbol}`);
58
42
 
59
- baseRatePerYear = parseUnits("0", 18);
60
- multiplierPerYear = parseUnits("0.15", 18);
61
- jumpMultiplierPerYear = parseUnits("3", 18);
62
- kink = parseUnits("0.8", 18);
63
- const baseRatePerYear2 = parseUnits("0", 18);
64
- const multiplierPerYear2 = parseUnits("0.9", 18);
65
- const kink2_ = parseUnits("0.9", 18);
66
-
67
- const [b1, m1, k1, m2, b2, k2, j2] = [
68
- baseRatePerYear,
69
- multiplierPerYear,
70
- kink,
71
- multiplierPerYear2,
72
- baseRatePerYear2,
73
- kink2_,
74
- jumpMultiplierPerYear,
75
- ].map(mantissaToBps);
76
- rateModelName = `TwoKinks_base${b1}bps_slope${m1}bps_kink${k1}bps_slope2${m2}bps_base2${b2}bps_kink2${k2}bps_jump${j2}bps`;
77
-
78
- await deploy(rateModelName, {
79
- contract: "TwoKinksInterestRateModel",
80
- from: deployer,
81
- log: true,
82
- autoMine: true,
83
- args: [
84
- baseRatePerYear,
85
- multiplierPerYear,
86
- kink,
87
- multiplierPerYear2,
88
- baseRatePerYear2,
89
- kink2_,
90
- jumpMultiplierPerYear,
91
- ],
92
- skipIfAlreadyDeployed: true,
93
- });
94
- }
95
-
96
- if (network.name === "bscmainnet" || network.name === "bsctestnet") {
97
- await deploy("InterestRateModelVBNB", {
98
- contract: "TwoKinksInterestRateModel",
99
- from: deployer,
100
- log: true,
101
- autoMine: true,
102
- args: [
103
- parseUnits("0", 18), // base rate 1
104
- parseUnits("0.035", 18), // multiplier 1
105
- parseUnits("0.8", 18), // kink 1
106
- parseUnits("1.75", 18), // multiplier 2
107
- parseUnits("0", 18), // base rate 2
108
- parseUnits("0.9", 18), // kink 2
109
- parseUnits("3", 18), // jump multiplier
110
- ],
111
- });
43
+ if (interestRateModel.model === "whitepaper") {
44
+ await deploy(rateModelName, {
45
+ from: deployer,
46
+ contract: "WhitePaperInterestRateModel",
47
+ args: [
48
+ interestRateModel.baseRatePerYear,
49
+ interestRateModel.multiplierPerYear,
50
+ //blocksPerYear
51
+ ],
52
+ log: true,
53
+ autoMine: true,
54
+ skipIfAlreadyDeployed: true,
55
+ });
56
+ } else if (interestRateModel.model === "jump") {
57
+ await deploy(rateModelName, {
58
+ from: deployer,
59
+ contract: "JumpRateModel",
60
+ args: [
61
+ interestRateModel.baseRatePerYear,
62
+ interestRateModel.multiplierPerYear,
63
+ interestRateModel.jumpMultiplierPerYear,
64
+ interestRateModel.kink,
65
+ //blocksPerYear
66
+ ],
67
+ log: true,
68
+ autoMine: true,
69
+ skipIfAlreadyDeployed: true,
70
+ });
71
+ } else if (interestRateModel.model === "two-kinks") {
72
+ await deploy(rateModelName, {
73
+ contract: "TwoKinksInterestRateModel",
74
+ from: deployer,
75
+ args: [
76
+ interestRateModel.baseRatePerYear,
77
+ interestRateModel.multiplierPerYear,
78
+ interestRateModel.kink,
79
+ interestRateModel.multiplierPerYear2,
80
+ interestRateModel.baseRatePerYear2,
81
+ interestRateModel.kink2,
82
+ interestRateModel.jumpMultiplierPerYear,
83
+ ],
84
+ log: true,
85
+ autoMine: true,
86
+ skipIfAlreadyDeployed: true,
87
+ });
88
+ }
112
89
  }
113
90
  };
114
91
 
115
92
  func.tags = ["InterestRateModel"];
116
- func.skip = async hre =>
117
- hre.network.name !== "hardhat" && hre.network.name !== "bscmainnet" && hre.network.name !== "bsctestnet";
93
+ func.skip = skipRemoteNetworks();
118
94
 
119
95
  export default func;
@@ -1,14 +1,15 @@
1
1
  import { DeployFunction } from "hardhat-deploy/types";
2
2
  import { HardhatRuntimeEnvironment } from "hardhat/types";
3
3
 
4
- import { getConfig } from "../helpers/deploymentConfig";
4
+ import { assertKnownChain } from "../helpers/chains";
5
+ import { tokens } from "../helpers/tokens";
5
6
 
6
7
  const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
7
8
  const { deployments, getNamedAccounts }: any = hre;
8
9
  const { deploy } = deployments;
9
10
  const { deployer } = await getNamedAccounts();
10
-
11
- const { tokensConfig } = await getConfig(hre.network.name);
11
+ const chain = assertKnownChain(hre.network.name);
12
+ const tokensConfig = Object.values(tokens[chain]);
12
13
 
13
14
  for (const token of tokensConfig) {
14
15
  if (token.isMock) {
@@ -1,15 +1,13 @@
1
- import { BigNumber, BigNumberish } from "ethers";
2
1
  import { parseUnits } from "ethers/lib/utils";
3
2
  import { ethers } from "hardhat";
4
3
  import { network } from "hardhat";
5
- import { DeployFunction, DeployResult } from "hardhat-deploy/types";
4
+ import { DeployFunction } from "hardhat-deploy/types";
6
5
  import { HardhatRuntimeEnvironment } from "hardhat/types";
7
6
 
8
- import { InterestRateModels, getConfig, getTokenConfig, skipRemoteNetworks } from "../helpers/deploymentConfig";
9
-
10
- const mantissaToBps = (num: BigNumberish) => {
11
- return BigNumber.from(num).div(parseUnits("1", 14)).toString();
12
- };
7
+ import { assertBlockBasedChain, blocksPerYear as chainBlocksPerYear } from "../helpers/chains";
8
+ import { skipRemoteNetworks } from "../helpers/deploymentConfig";
9
+ import { markets } from "../helpers/markets";
10
+ import { getRateModelName } from "../helpers/rateModelHelpers";
13
11
 
14
12
  const VTOKEN_DECIMALS = 8;
15
13
  const EMPTY_BYTES_ARRAY = "0x";
@@ -19,50 +17,36 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
19
17
  const { deploy } = deployments;
20
18
 
21
19
  const { deployer } = await getNamedAccounts();
22
- const { tokensConfig, marketsConfig } = await getConfig(hre.network.name);
20
+ const chain = assertBlockBasedChain(hre.network.name);
21
+ const marketsConfig = markets[chain];
22
+ const blocksPerYear = chainBlocksPerYear[chain];
23
23
 
24
24
  const comptrollerDeployment = await deployments.get("Unitroller");
25
25
 
26
26
  console.log(`Got deployment of Unitroller with address: ${comptrollerDeployment.address}`);
27
27
 
28
28
  for (const market of marketsConfig) {
29
- const { name, asset, symbol, rateModel, baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink_ } = market;
29
+ const { name, asset, symbol, interestRateModel } = market;
30
+
31
+ // Short-circuit to avoid extra requests to the node if vToken already exists
32
+ const deployment = await deployments.getOrNull(symbol);
33
+ if (deployment !== null && deployment !== undefined) {
34
+ console.log(`Skipping ${symbol} deployment: found at ${deployment.address}`);
35
+ continue;
36
+ }
30
37
 
31
- const token = getTokenConfig(asset, tokensConfig);
32
38
  let tokenContract;
33
- if (token.isMock) {
34
- tokenContract = await ethers.getContract(`Mock${token.symbol}`);
39
+ if (asset.isMock) {
40
+ tokenContract = await ethers.getContract(`Mock${asset.symbol}`);
35
41
  } else {
36
42
  tokenContract = await ethers.getContractAt(
37
43
  "@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20",
38
- token.tokenAddress,
44
+ asset.tokenAddress,
39
45
  );
40
46
  }
41
47
 
42
- let rateModelAddress: string;
43
- if (rateModel === InterestRateModels.JumpRate.toString()) {
44
- const [b, m, j, k] = [baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink_].map(mantissaToBps);
45
- const rateModelName = `JumpRateModel_base${b}bps_slope${m}bps_jump${j}bps_kink${k}bps`;
46
- console.log(`Deploying interest rate model ${rateModelName}`);
47
- const result: DeployResult = await deploy(rateModelName, {
48
- from: deployer,
49
- contract: "JumpRateModel",
50
- args: [baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink_],
51
- log: true,
52
- });
53
- rateModelAddress = result.address;
54
- } else {
55
- const [b, m] = [baseRatePerYear, multiplierPerYear].map(mantissaToBps);
56
- const rateModelName = `WhitePaperInterestRateModel_base${b}bps_slope${m}bps`;
57
- console.log(`Deploying interest rate model ${rateModelName}`);
58
- const result: DeployResult = await deploy(rateModelName, {
59
- from: deployer,
60
- contract: "WhitePaperInterestRateModel",
61
- args: [baseRatePerYear, multiplierPerYear],
62
- log: true,
63
- });
64
- rateModelAddress = result.address;
65
- }
48
+ const rateModelName = getRateModelName(interestRateModel, blocksPerYear);
49
+ const rateModelAddress = (await deployments.get(rateModelName)).address;
66
50
 
67
51
  const underlyingDecimals = Number(await tokenContract.decimals());
68
52
  const normalTimelock = await ethers.getContract("NormalTimelock");
@@ -0,0 +1,183 @@
1
+ import { BigNumber, Contract } from "ethers";
2
+ import { ethers } from "hardhat";
3
+ import { DeployFunction } from "hardhat-deploy/types";
4
+ import { HardhatRuntimeEnvironment } from "hardhat/types";
5
+
6
+ import { assertBlockBasedChain, blocksPerYear as chainBlocksPerYear } from "../../helpers/chains";
7
+ import { markets } from "../../helpers/markets";
8
+ import {
9
+ JumpRateModelParams,
10
+ Parsed,
11
+ RateModelParams,
12
+ TwoKinksRateModelParams,
13
+ WpRateModelParams,
14
+ } from "../../helpers/markets/types";
15
+ import { getRateModelName } from "../../helpers/rateModelHelpers";
16
+
17
+ const expectEqual = (msg: string, a: BigNumber, b: BigNumber) => {
18
+ if (!a.eq(b)) {
19
+ throw new Error(`Expected ${a.toString()} == ${b.toString()}\n${msg}`);
20
+ }
21
+ };
22
+
23
+ const checkBlocksPerYear = async (rateModel: Contract, name: string, expected: number) => {
24
+ try {
25
+ expectEqual(
26
+ `Checking blocksPerYear for ${name} at ${rateModel.address}`,
27
+ await rateModel.blocksPerYear(),
28
+ BigNumber.from(expected),
29
+ );
30
+ } catch (err) {
31
+ console.warn(`Could not get blocks per year for rate model at ${rateModel.address}, assuming ${expected}`);
32
+ }
33
+ };
34
+
35
+ const checkWpRateModel = async (rateModelAddress: string, params: Parsed<WpRateModelParams>, blocksPerYear: number) => {
36
+ const name = getRateModelName(params, blocksPerYear);
37
+ const rateModel = await ethers.getContractAt("WhitePaperInterestRateModel", rateModelAddress);
38
+ await checkBlocksPerYear(rateModel, name, blocksPerYear);
39
+ expectEqual(
40
+ `Checking baseRatePerBlock for ${name} at ${rateModelAddress}`,
41
+ await rateModel.baseRatePerBlock(),
42
+ params.baseRatePerYear.div(blocksPerYear),
43
+ );
44
+ expectEqual(
45
+ `Checking multiplierPerBlock for ${name} at ${rateModelAddress}`,
46
+ await rateModel.multiplierPerBlock(),
47
+ params.multiplierPerYear.div(blocksPerYear),
48
+ );
49
+ };
50
+
51
+ const checkJumpRateModel = async (
52
+ rateModelAddress: string,
53
+ params: Parsed<JumpRateModelParams>,
54
+ blocksPerYear: number,
55
+ ) => {
56
+ const name = getRateModelName(params, blocksPerYear);
57
+ const rateModel = await ethers.getContractAt("JumpRateModel", rateModelAddress);
58
+ await checkBlocksPerYear(rateModel, name, blocksPerYear);
59
+ expectEqual(
60
+ `Checking baseRatePerBlock for ${name} at ${rateModelAddress}`,
61
+ await rateModel.baseRatePerBlock(),
62
+ params.baseRatePerYear.div(blocksPerYear),
63
+ );
64
+ expectEqual(
65
+ `Checking multiplierPerBlock for ${name} at ${rateModelAddress}`,
66
+ await rateModel.multiplierPerBlock(),
67
+ params.multiplierPerYear.div(blocksPerYear),
68
+ );
69
+ expectEqual(
70
+ `Checking jumpMultiplierPerBlock for ${name} at ${rateModelAddress}`,
71
+ await rateModel.jumpMultiplierPerBlock(),
72
+ params.jumpMultiplierPerYear.div(blocksPerYear),
73
+ );
74
+ expectEqual(`Checking kink for ${name} at ${rateModelAddress}`, await rateModel.kink(), params.kink);
75
+ };
76
+
77
+ const checkTwoKinksRateModel = async (
78
+ rateModelAddress: string,
79
+ params: Parsed<TwoKinksRateModelParams>,
80
+ blocksPerYear: number,
81
+ ) => {
82
+ const name = getRateModelName(params, blocksPerYear);
83
+ const rateModel = await ethers.getContractAt("TwoKinksInterestRateModel", rateModelAddress);
84
+ try {
85
+ expectEqual(
86
+ `Checking blocksPerYear for ${name} at ${rateModel.address}`,
87
+ await rateModel.BLOCKS_PER_YEAR(),
88
+ BigNumber.from(blocksPerYear),
89
+ );
90
+ } catch (err) {
91
+ console.warn(`Could not get blocks per year for rate model at ${rateModel.address}, assuming ${blocksPerYear}`);
92
+ }
93
+ expectEqual(
94
+ `Checking BASE_RATE_PER_BLOCK for ${name} at ${rateModelAddress}`,
95
+ await rateModel.BASE_RATE_PER_BLOCK(),
96
+ params.baseRatePerYear.div(blocksPerYear),
97
+ );
98
+ expectEqual(
99
+ `Checking MULTIPLIER_PER_BLOCK for ${name} at ${rateModelAddress}`,
100
+ await rateModel.MULTIPLIER_PER_BLOCK(),
101
+ params.multiplierPerYear.div(blocksPerYear),
102
+ );
103
+ expectEqual(`${name}.KINK_1`, await rateModel.KINK_1(), params.kink);
104
+ expectEqual(
105
+ `Checking BASE_RATE_2_PER_BLOCK for ${name} at ${rateModelAddress}`,
106
+ await rateModel.BASE_RATE_2_PER_BLOCK(),
107
+ params.baseRatePerYear2.div(blocksPerYear),
108
+ );
109
+ expectEqual(
110
+ `Checking MULTIPLIER_2_PER_BLOCK for ${name} at ${rateModelAddress}`,
111
+ await rateModel.MULTIPLIER_2_PER_BLOCK(),
112
+ params.multiplierPerYear2.div(blocksPerYear),
113
+ );
114
+ expectEqual(`${name}.KINK_2`, await rateModel.KINK_2(), params.kink2);
115
+ expectEqual(
116
+ `Checking JUMP_MULTIPLIER_PER_BLOCK for ${name} at ${rateModelAddress}`,
117
+ await rateModel.JUMP_MULTIPLIER_PER_BLOCK(),
118
+ params.jumpMultiplierPerYear.div(blocksPerYear),
119
+ );
120
+ };
121
+
122
+ const checkRateModel = (
123
+ rateModelAddress: string,
124
+ params: Parsed<RateModelParams>,
125
+ blocksPerYear: number,
126
+ ): Promise<void> => {
127
+ switch (params.model) {
128
+ case "whitepaper":
129
+ return checkWpRateModel(rateModelAddress, params, blocksPerYear);
130
+ case "jump":
131
+ return checkJumpRateModel(rateModelAddress, params, blocksPerYear);
132
+ case "two-kinks":
133
+ return checkTwoKinksRateModel(rateModelAddress, params, blocksPerYear);
134
+ }
135
+ };
136
+
137
+ const test = async <T>(message: string, check: () => T | Promise<T>) => {
138
+ try {
139
+ await check();
140
+ console.log(`✅ ${message}`);
141
+ } catch (err) {
142
+ console.log(`❌ Failure: ${message}`);
143
+ console.error(err);
144
+ }
145
+ };
146
+
147
+ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
148
+ const { deployments } = hre;
149
+ const chain = assertBlockBasedChain(hre.network.name);
150
+ const marketsConfig = markets[chain];
151
+ const blocksPerYear = chainBlocksPerYear[chain];
152
+
153
+ for (const vTokenConfig of marketsConfig) {
154
+ const { symbol, interestRateModel } = vTokenConfig;
155
+ console.log(`Checking interest rate model of ${symbol}`);
156
+ const vTokenAddress = (await deployments.get(`${symbol}`)).address;
157
+ const vToken = await ethers.getContractAt("VToken", vTokenAddress);
158
+ const rateModelAddress = await vToken.interestRateModel();
159
+ const name = getRateModelName(interestRateModel, blocksPerYear);
160
+ await test(`Rate model at ${rateModelAddress} should be ${name}`, () =>
161
+ checkRateModel(rateModelAddress, interestRateModel, blocksPerYear));
162
+ const deployment = await deployments.getOrNull(name);
163
+ await test(`Deployment for ${name} exists`, () => {
164
+ if (!deployment) throw new Error(`Deployment for ${name} not found`);
165
+ });
166
+ if (!deployment) {
167
+ continue;
168
+ }
169
+ if (deployment.address === rateModelAddress) {
170
+ console.log(`✅ Deployment address matches the rate model address`);
171
+ } else {
172
+ console.warn(`⚠️ Deployment at ${deployment.address} does not match ${rateModelAddress}`);
173
+ await test(`Rate model at ${deployment.address} should still be ${name}`, () =>
174
+ checkRateModel(deployment.address, interestRateModel, blocksPerYear));
175
+ }
176
+ console.log(`-----------------------------------------`);
177
+ }
178
+ };
179
+
180
+ func.tags = ["CheckIRMs"];
181
+ func.skip = async (hre: HardhatRuntimeEnvironment) => !hre.network.live;
182
+
183
+ export default func;