diff --git a/deploy/002-interest-rate-model.ts b/deploy/002-interest-rate-model.ts index e6b1c04b2..e6c894fe4 100644 --- a/deploy/002-interest-rate-model.ts +++ b/deploy/002-interest-rate-model.ts @@ -1,7 +1,12 @@ +import { BigNumber, BigNumberish } from "ethers"; import { parseUnits } from "ethers/lib/utils"; import { DeployFunction } from "hardhat-deploy/types"; import { HardhatRuntimeEnvironment } from "hardhat/types"; +const mantissaToBps = (num: BigNumberish) => { + return BigNumber.from(num).div(parseUnits("1", 14)).toString(); +}; + const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployments, getNamedAccounts, network } = hre; const { deploy } = deployments; @@ -34,6 +39,58 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { autoMine: true, args: [0, parseUnits("0.03", 18), parseUnits("4.5", 18), parseUnits("0.9", 18)], }); + + let baseRatePerYear = parseUnits("0", 18); + let multiplierPerYear = parseUnits("0.175", 18); + let jumpMultiplierPerYear = parseUnits("2.5", 18); + let kink = parseUnits("0.8", 18); + const [b, m, j, k] = [baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink].map(mantissaToBps); + let rateModelName = `JumpRateModel_base${b}bps_slope${m}bps_jump${j}bps_kink${k}bps`; + + await deploy(rateModelName, { + contract: "JumpRateModel", + from: deployer, + log: true, + autoMine: true, + args: [baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink], + skipIfAlreadyDeployed: true, + }); + + baseRatePerYear = parseUnits("0", 18); + multiplierPerYear = parseUnits("0.15", 18); + jumpMultiplierPerYear = parseUnits("3", 18); + kink = parseUnits("0.8", 18); + const baseRatePerYear2 = parseUnits("0", 18); + const multiplierPerYear2 = parseUnits("0.9", 18); + const kink2_ = parseUnits("0.9", 18); + + const [b1, m1, k1, m2, b2, k2, j2] = [ + baseRatePerYear, + multiplierPerYear, + kink, + multiplierPerYear2, + baseRatePerYear2, + kink2_, + jumpMultiplierPerYear, + ].map(mantissaToBps); + rateModelName = `TwoKinks_base${b1}bps_slope${m1}bps_kink${k1}bps_slope2${m2}bps_base2${b2}bps_kink2${k2}bps_jump${j2}bps`; + + await deploy(rateModelName, { + contract: "TwoKinksInterestRateModel", + from: deployer, + log: true, + autoMine: true, + args: [ + baseRatePerYear, + multiplierPerYear, + kink, + multiplierPerYear2, + baseRatePerYear2, + kink2_, + jumpMultiplierPerYear, + ], + skipIfAlreadyDeployed: true, + }); } if (network.name === "bscmainnet" || network.name === "bsctestnet") { diff --git a/deployments/bscmainnet.json b/deployments/bscmainnet.json index 22277b0ff..10282ec9d 100644 --- a/deployments/bscmainnet.json +++ b/deployments/bscmainnet.json @@ -8545,6 +8545,257 @@ } ] }, + "JumpRateModel_base0bps_slope1750bps_jump25000bps_kink8000bps": { + "address": "0x0be3ca99FBBE16b86C3b00E2C4c30C3892F31647", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "baseRatePerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "multiplierPerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "jumpMultiplierPerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "kink_", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "baseRatePerBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplierPerBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "jumpMultiplierPerBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "kink", + "type": "uint256" + } + ], + "name": "NewInterestParams", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "baseRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "blocksPerYear", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + } + ], + "name": "getBorrowRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveFactorMantissa", + "type": "uint256" + } + ], + "name": "getSupplyRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isInterestRateModel", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "jumpMultiplierPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kink", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "multiplierPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + } + ], + "name": "utilizationRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + } + ] + }, "JumpRateModel_base0bps_slope687bps_jump25000bps_kink8000bps": { "address": "0xB105F9B511836cc7dF9F3dD0Ec4873766b5b6660", "abi": [ @@ -34012,6 +34263,297 @@ } ] }, + "TwoKinks_base0bps_slope1500bps_kink8000bps_slope29000bps_base20bps_kink29000bps_jump30000bps": { + "address": "0x4D712A88Ff15a7147a9966c5ED2ccb392F1760c9", + "abi": [ + { + "inputs": [ + { + "internalType": "int256", + "name": "baseRatePerYear_", + "type": "int256" + }, + { + "internalType": "int256", + "name": "multiplierPerYear_", + "type": "int256" + }, + { + "internalType": "int256", + "name": "kink1_", + "type": "int256" + }, + { + "internalType": "int256", + "name": "multiplier2PerYear_", + "type": "int256" + }, + { + "internalType": "int256", + "name": "baseRate2PerYear_", + "type": "int256" + }, + { + "internalType": "int256", + "name": "kink2_", + "type": "int256" + }, + { + "internalType": "int256", + "name": "jumpMultiplierPerYear_", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidKink", + "type": "error" + }, + { + "inputs": [], + "name": "NegativeValueNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "BASE_RATE_2_PER_BLOCK", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BASE_RATE_PER_BLOCK", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BLOCKS_PER_YEAR", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "JUMP_MULTIPLIER_PER_BLOCK", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "KINK_1", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "KINK_2", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPLIER_2_PER_BLOCK", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPLIER_PER_BLOCK", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_1", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_2", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + } + ], + "name": "getBorrowRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveFactorMantissa", + "type": "uint256" + } + ], + "name": "getSupplyRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isInterestRateModel", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + } + ], + "name": "utilizationRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ] + }, "USDC": { "address": "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", "abi": [ diff --git a/deployments/bscmainnet/JumpRateModel_base0bps_slope1750bps_jump25000bps_kink8000bps.json b/deployments/bscmainnet/JumpRateModel_base0bps_slope1750bps_jump25000bps_kink8000bps.json new file mode 100644 index 000000000..54c0c17d7 --- /dev/null +++ b/deployments/bscmainnet/JumpRateModel_base0bps_slope1750bps_jump25000bps_kink8000bps.json @@ -0,0 +1,380 @@ +{ + "address": "0x0be3ca99FBBE16b86C3b00E2C4c30C3892F31647", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "baseRatePerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "multiplierPerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "jumpMultiplierPerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "kink_", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "baseRatePerBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplierPerBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "jumpMultiplierPerBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "kink", + "type": "uint256" + } + ], + "name": "NewInterestParams", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "baseRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "blocksPerYear", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + } + ], + "name": "getBorrowRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveFactorMantissa", + "type": "uint256" + } + ], + "name": "getSupplyRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isInterestRateModel", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "jumpMultiplierPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kink", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "multiplierPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + } + ], + "name": "utilizationRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x343964f95df66451260660775396a5b1730f1bedf65338a2de607edd5fd4abab", + "receipt": { + "to": null, + "from": "0x8BDA9f9E1fEF0DFd404Fef338D9fE4c543d172e1", + "contractAddress": "0x0be3ca99FBBE16b86C3b00E2C4c30C3892F31647", + "transactionIndex": 160, + "gasUsed": "468712", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000004000000000000000000000000080000000000000000000000000000000000000040000000000000000000040000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000", + "blockHash": "0x9c41ef2f8637365accf60adcd86626b54d3cdb26ae5d54f6903a3c384ace613e", + "transactionHash": "0x343964f95df66451260660775396a5b1730f1bedf65338a2de607edd5fd4abab", + "logs": [ + { + "transactionIndex": 160, + "blockNumber": 45211118, + "transactionHash": "0x343964f95df66451260660775396a5b1730f1bedf65338a2de607edd5fd4abab", + "address": "0x0be3ca99FBBE16b86C3b00E2C4c30C3892F31647", + "topics": ["0x6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d"], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e046d6d7000000000000000000000000000000000000000000000000000000375f61b4060000000000000000000000000000000000000000000000000b1a2bc2ec500000", + "logIndex": 304, + "blockHash": "0x9c41ef2f8637365accf60adcd86626b54d3cdb26ae5d54f6903a3c384ace613e" + } + ], + "blockNumber": 45211118, + "cumulativeGasUsed": "11475402", + "status": 1, + "byzantium": true + }, + "args": ["0", "175000000000000000", "2500000000000000000", "800000000000000000"], + "numDeployments": 1, + "solcInputHash": "a2594572bdae270af6749f50c8019b6c", + "metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"baseRatePerYear\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"multiplierPerYear\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"jumpMultiplierPerYear\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"kink_\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"baseRatePerBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"multiplierPerBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"jumpMultiplierPerBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"kink\",\"type\":\"uint256\"}],\"name\":\"NewInterestParams\",\"type\":\"event\"},{\"constant\":true,\"inputs\":[],\"name\":\"baseRatePerBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"blocksPerYear\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"cash\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrows\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reserves\",\"type\":\"uint256\"}],\"name\":\"getBorrowRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"cash\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrows\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reserves\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reserveFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"getSupplyRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isInterestRateModel\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"jumpMultiplierPerBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"kink\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"multiplierPerBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"cash\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrows\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reserves\",\"type\":\"uint256\"}],\"name\":\"utilizationRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"methods\":{\"constructor\":{\"params\":{\"baseRatePerYear\":\"The approximate target base APR, as a mantissa (scaled by 1e18)\",\"jumpMultiplierPerYear\":\"The multiplierPerBlock after hitting a specified utilization point\",\"kink_\":\"The utilization point at which the jump multiplier is applied\",\"multiplierPerYear\":\"The rate of increase in interest rate wrt utilization (scaled by 1e18)\"}},\"getBorrowRate(uint256,uint256,uint256)\":{\"params\":{\"borrows\":\"The amount of borrows in the market\",\"cash\":\"The amount of cash in the market\",\"reserves\":\"The amount of reserves in the market\"},\"return\":\"The borrow rate percentage per block as a mantissa (scaled by 1e18)\"},\"getSupplyRate(uint256,uint256,uint256,uint256)\":{\"params\":{\"borrows\":\"The amount of borrows in the market\",\"cash\":\"The amount of cash in the market\",\"reserveFactorMantissa\":\"The current reserve factor for the market\",\"reserves\":\"The amount of reserves in the market\"},\"return\":\"The supply rate percentage per block as a mantissa (scaled by 1e18)\"},\"utilizationRate(uint256,uint256,uint256)\":{\"params\":{\"borrows\":\"The amount of borrows in the market\",\"cash\":\"The amount of cash in the market\",\"reserves\":\"The amount of reserves in the market (currently unused)\"},\"return\":\"The utilization rate as a mantissa between [0, 1e18]\"}},\"title\":\"Venus's JumpRateModel Contract\"},\"userdoc\":{\"methods\":{\"constructor\":\"Construct an interest rate model\",\"getBorrowRate(uint256,uint256,uint256)\":{\"notice\":\"Calculates the current borrow rate per block, with the error code expected by the market\"},\"getSupplyRate(uint256,uint256,uint256,uint256)\":{\"notice\":\"Calculates the current supply rate per block\"},\"utilizationRate(uint256,uint256,uint256)\":{\"notice\":\"Calculates the utilization rate of the market: `borrows / (cash + borrows - reserves)`\"}}}},\"settings\":{\"compilationTarget\":{\"contracts/InterestRateModels/JumpRateModel.sol\":\"JumpRateModel\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/InterestRateModels/InterestRateModel.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Venus's InterestRateModel Interface\\n * @author Venus\\n */\\ncontract InterestRateModel {\\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\\n bool public constant isInterestRateModel = true;\\n\\n /**\\n * @notice Calculates the current borrow interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);\\n\\n /**\\n * @notice Calculates the current supply interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint cash,\\n uint borrows,\\n uint reserves,\\n uint reserveFactorMantissa\\n ) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x7896290ed5d98f1b744676c0cf5cb0bc656befdd8a79ae4cd2d9f90d83aaa52d\"},\"contracts/InterestRateModels/JumpRateModel.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Utils/SafeMath.sol\\\";\\nimport \\\"./InterestRateModel.sol\\\";\\n\\n/**\\n * @title Venus's JumpRateModel Contract\\n * @author Venus\\n */\\ncontract JumpRateModel is InterestRateModel {\\n using SafeMath for uint;\\n\\n event NewInterestParams(uint baseRatePerBlock, uint multiplierPerBlock, uint jumpMultiplierPerBlock, uint kink);\\n\\n /**\\n * @notice The approximate number of blocks per year that is assumed by the interest rate model\\n */\\n uint public constant blocksPerYear = (60 * 60 * 24 * 365) / 3; // (assuming 3s blocks)\\n\\n /**\\n * @notice The multiplier of utilization rate that gives the slope of the interest rate\\n */\\n uint public multiplierPerBlock;\\n\\n /**\\n * @notice The base interest rate which is the y-intercept when utilization rate is 0\\n */\\n uint public baseRatePerBlock;\\n\\n /**\\n * @notice The multiplierPerBlock after hitting a specified utilization point\\n */\\n uint public jumpMultiplierPerBlock;\\n\\n /**\\n * @notice The utilization point at which the jump multiplier is applied\\n */\\n uint public kink;\\n\\n /**\\n * @notice Construct an interest rate model\\n * @param baseRatePerYear The approximate target base APR, as a mantissa (scaled by 1e18)\\n * @param multiplierPerYear The rate of increase in interest rate wrt utilization (scaled by 1e18)\\n * @param jumpMultiplierPerYear The multiplierPerBlock after hitting a specified utilization point\\n * @param kink_ The utilization point at which the jump multiplier is applied\\n */\\n constructor(uint baseRatePerYear, uint multiplierPerYear, uint jumpMultiplierPerYear, uint kink_) public {\\n baseRatePerBlock = baseRatePerYear.div(blocksPerYear);\\n multiplierPerBlock = multiplierPerYear.div(blocksPerYear);\\n jumpMultiplierPerBlock = jumpMultiplierPerYear.div(blocksPerYear);\\n kink = kink_;\\n\\n emit NewInterestParams(baseRatePerBlock, multiplierPerBlock, jumpMultiplierPerBlock, kink);\\n }\\n\\n /**\\n * @notice Calculates the utilization rate of the market: `borrows / (cash + borrows - reserves)`\\n * @param cash The amount of cash in the market\\n * @param borrows The amount of borrows in the market\\n * @param reserves The amount of reserves in the market (currently unused)\\n * @return The utilization rate as a mantissa between [0, 1e18]\\n */\\n function utilizationRate(uint cash, uint borrows, uint reserves) public pure returns (uint) {\\n // Utilization rate is 0 when there are no borrows\\n if (borrows == 0) {\\n return 0;\\n }\\n\\n return borrows.mul(1e18).div(cash.add(borrows).sub(reserves));\\n }\\n\\n /**\\n * @notice Calculates the current borrow rate per block, with the error code expected by the market\\n * @param cash The amount of cash in the market\\n * @param borrows The amount of borrows in the market\\n * @param reserves The amount of reserves in the market\\n * @return The borrow rate percentage per block as a mantissa (scaled by 1e18)\\n */\\n function getBorrowRate(uint cash, uint borrows, uint reserves) public view returns (uint) {\\n uint util = utilizationRate(cash, borrows, reserves);\\n\\n if (util <= kink) {\\n return util.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock);\\n } else {\\n uint normalRate = kink.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock);\\n uint excessUtil = util.sub(kink);\\n return excessUtil.mul(jumpMultiplierPerBlock).div(1e18).add(normalRate);\\n }\\n }\\n\\n /**\\n * @notice Calculates the current supply rate per block\\n * @param cash The amount of cash in the market\\n * @param borrows The amount of borrows in the market\\n * @param reserves The amount of reserves in the market\\n * @param reserveFactorMantissa The current reserve factor for the market\\n * @return The supply rate percentage per block as a mantissa (scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint cash,\\n uint borrows,\\n uint reserves,\\n uint reserveFactorMantissa\\n ) public view returns (uint) {\\n uint oneMinusReserveFactor = uint(1e18).sub(reserveFactorMantissa);\\n uint borrowRate = getBorrowRate(cash, borrows, reserves);\\n uint rateToPool = borrowRate.mul(oneMinusReserveFactor).div(1e18);\\n return utilizationRate(cash, borrows, reserves).mul(rateToPool).div(1e18);\\n }\\n}\\n\",\"keccak256\":\"0x0c90d867067f823ca47664590f132385830ed66d2cfccdf242c028d0a85bd7c9\"},\"contracts/Utils/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return add(a, b, \\\"SafeMath: addition overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, errorMessage);\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9431fd772ed4abc038cdfe9ce6c0066897bd1685ad45848748d1952935d5b8ef\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506040516108113803806108118339818101604052608081101561003357600080fd5b508051602080830151604084015160609094015192939092909161006590859062a066809061039e6100fd821b17901c565b6001556100808362a066806100fd602090811b61039e17901c565b60005561009b8262a066806100fd602090811b61039e17901c565b60028190556003829055600154600054604080519283526020830191909152818101929092526060810183905290517f6960ab234c7ef4b0c9197100f5393cfcde7c453ac910a27bd2000aa1dd4c068d9181900360800190a1505050506101ee565b600061014583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061014c60201b60201c565b9392505050565b600081836101d85760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561019d578181015183820152602001610185565b50505050905090810190601f1680156101ca5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816101e457fe5b0495945050505050565b610614806101fd6000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063a385fb9611610066578063a385fb9614610120578063b816881614610128578063b9f9850a14610157578063f14039de1461015f578063fd2da3391461016757610093565b806315f24053146100985780632191f92a146100d35780636e71e2d8146100ef5780638726bb8914610118575b600080fd5b6100c1600480360360608110156100ae57600080fd5b508035906020810135906040013561016f565b60408051918252519081900360200190f35b6100db610247565b604080519115158252519081900360200190f35b6100c16004803603606081101561010557600080fd5b508035906020810135906040013561024c565b6100c161029e565b6100c16102a4565b6100c16004803603608081101561013e57600080fd5b50803590602081013590604081013590606001356102ab565b6100c161032a565b6100c1610330565b6100c1610336565b60008061017d85858561024c565b905060035481116101cf576101c76001546101bb670de0b6b3a76400006101af6000548661033c90919063ffffffff16565b9063ffffffff61039e16565b9063ffffffff6103e016565b915050610240565b60006101fa6001546101bb670de0b6b3a76400006101af60005460035461033c90919063ffffffff16565b905060006102136003548461042290919063ffffffff16565b905061023a826101bb670de0b6b3a76400006101af6002548661033c90919063ffffffff16565b93505050505b9392505050565b600181565b60008261025b57506000610240565b61029661027e83610272878763ffffffff6103e016565b9063ffffffff61042216565b6101af85670de0b6b3a764000063ffffffff61033c16565b949350505050565b60005481565b62a0668081565b6000806102c6670de0b6b3a76400008463ffffffff61042216565b905060006102d587878761016f565b905060006102f5670de0b6b3a76400006101af848663ffffffff61033c16565b905061031e670de0b6b3a76400006101af836103128c8c8c61024c565b9063ffffffff61033c16565b98975050505050505050565b60025481565b60015481565b60035481565b60008261034b57506000610398565b8282028284828161035857fe5b04146103955760405162461bcd60e51b81526004018080602001828103825260218152602001806105bf6021913960400191505060405180910390fd5b90505b92915050565b600061039583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610464565b600061039583836040518060400160405280601b81526020017f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815250610506565b600061039583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610564565b600081836104f05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156104b557818101518382015260200161049d565b50505050905090810190601f1680156104e25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816104fc57fe5b0495945050505050565b6000838301828582101561055b5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156104b557818101518382015260200161049d565b50949350505050565b600081848411156105b65760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156104b557818101518382015260200161049d565b50505090039056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a265627a7a723158208d524531d4bd676b08c415f951c89512128d7ce72185b07b426ac97c6c3b50a564736f6c63430005100032", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100935760003560e01c8063a385fb9611610066578063a385fb9614610120578063b816881614610128578063b9f9850a14610157578063f14039de1461015f578063fd2da3391461016757610093565b806315f24053146100985780632191f92a146100d35780636e71e2d8146100ef5780638726bb8914610118575b600080fd5b6100c1600480360360608110156100ae57600080fd5b508035906020810135906040013561016f565b60408051918252519081900360200190f35b6100db610247565b604080519115158252519081900360200190f35b6100c16004803603606081101561010557600080fd5b508035906020810135906040013561024c565b6100c161029e565b6100c16102a4565b6100c16004803603608081101561013e57600080fd5b50803590602081013590604081013590606001356102ab565b6100c161032a565b6100c1610330565b6100c1610336565b60008061017d85858561024c565b905060035481116101cf576101c76001546101bb670de0b6b3a76400006101af6000548661033c90919063ffffffff16565b9063ffffffff61039e16565b9063ffffffff6103e016565b915050610240565b60006101fa6001546101bb670de0b6b3a76400006101af60005460035461033c90919063ffffffff16565b905060006102136003548461042290919063ffffffff16565b905061023a826101bb670de0b6b3a76400006101af6002548661033c90919063ffffffff16565b93505050505b9392505050565b600181565b60008261025b57506000610240565b61029661027e83610272878763ffffffff6103e016565b9063ffffffff61042216565b6101af85670de0b6b3a764000063ffffffff61033c16565b949350505050565b60005481565b62a0668081565b6000806102c6670de0b6b3a76400008463ffffffff61042216565b905060006102d587878761016f565b905060006102f5670de0b6b3a76400006101af848663ffffffff61033c16565b905061031e670de0b6b3a76400006101af836103128c8c8c61024c565b9063ffffffff61033c16565b98975050505050505050565b60025481565b60015481565b60035481565b60008261034b57506000610398565b8282028284828161035857fe5b04146103955760405162461bcd60e51b81526004018080602001828103825260218152602001806105bf6021913960400191505060405180910390fd5b90505b92915050565b600061039583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610464565b600061039583836040518060400160405280601b81526020017f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815250610506565b600061039583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610564565b600081836104f05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156104b557818101518382015260200161049d565b50505050905090810190601f1680156104e25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816104fc57fe5b0495945050505050565b6000838301828582101561055b5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156104b557818101518382015260200161049d565b50949350505050565b600081848411156105b65760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156104b557818101518382015260200161049d565b50505090039056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a265627a7a723158208d524531d4bd676b08c415f951c89512128d7ce72185b07b426ac97c6c3b50a564736f6c63430005100032", + "devdoc": { + "author": "Venus", + "methods": { + "constructor": { + "params": { + "baseRatePerYear": "The approximate target base APR, as a mantissa (scaled by 1e18)", + "jumpMultiplierPerYear": "The multiplierPerBlock after hitting a specified utilization point", + "kink_": "The utilization point at which the jump multiplier is applied", + "multiplierPerYear": "The rate of increase in interest rate wrt utilization (scaled by 1e18)" + } + }, + "getBorrowRate(uint256,uint256,uint256)": { + "params": { + "borrows": "The amount of borrows in the market", + "cash": "The amount of cash in the market", + "reserves": "The amount of reserves in the market" + }, + "return": "The borrow rate percentage per block as a mantissa (scaled by 1e18)" + }, + "getSupplyRate(uint256,uint256,uint256,uint256)": { + "params": { + "borrows": "The amount of borrows in the market", + "cash": "The amount of cash in the market", + "reserveFactorMantissa": "The current reserve factor for the market", + "reserves": "The amount of reserves in the market" + }, + "return": "The supply rate percentage per block as a mantissa (scaled by 1e18)" + }, + "utilizationRate(uint256,uint256,uint256)": { + "params": { + "borrows": "The amount of borrows in the market", + "cash": "The amount of cash in the market", + "reserves": "The amount of reserves in the market (currently unused)" + }, + "return": "The utilization rate as a mantissa between [0, 1e18]" + } + }, + "title": "Venus's JumpRateModel Contract" + }, + "userdoc": { + "methods": { + "constructor": "Construct an interest rate model", + "getBorrowRate(uint256,uint256,uint256)": { + "notice": "Calculates the current borrow rate per block, with the error code expected by the market" + }, + "getSupplyRate(uint256,uint256,uint256,uint256)": { + "notice": "Calculates the current supply rate per block" + }, + "utilizationRate(uint256,uint256,uint256)": { + "notice": "Calculates the utilization rate of the market: `borrows / (cash + borrows - reserves)`" + } + } + }, + "storageLayout": { + "storage": [ + { + "astId": 9329, + "contract": "contracts/InterestRateModels/JumpRateModel.sol:JumpRateModel", + "label": "multiplierPerBlock", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 9331, + "contract": "contracts/InterestRateModels/JumpRateModel.sol:JumpRateModel", + "label": "baseRatePerBlock", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 9333, + "contract": "contracts/InterestRateModels/JumpRateModel.sol:JumpRateModel", + "label": "jumpMultiplierPerBlock", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 9335, + "contract": "contracts/InterestRateModels/JumpRateModel.sol:JumpRateModel", + "label": "kink", + "offset": 0, + "slot": "3", + "type": "t_uint256" + } + ], + "types": { + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/bscmainnet/TwoKinks_base0bps_slope1500bps_kink8000bps_slope29000bps_base20bps_kink29000bps_jump30000bps.json b/deployments/bscmainnet/TwoKinks_base0bps_slope1500bps_kink8000bps_slope29000bps_base20bps_kink29000bps_jump30000bps.json new file mode 100644 index 000000000..68632b71c --- /dev/null +++ b/deployments/bscmainnet/TwoKinks_base0bps_slope1500bps_kink8000bps_slope29000bps_base20bps_kink29000bps_jump30000bps.json @@ -0,0 +1,436 @@ +{ + "address": "0x4D712A88Ff15a7147a9966c5ED2ccb392F1760c9", + "abi": [ + { + "inputs": [ + { + "internalType": "int256", + "name": "baseRatePerYear_", + "type": "int256" + }, + { + "internalType": "int256", + "name": "multiplierPerYear_", + "type": "int256" + }, + { + "internalType": "int256", + "name": "kink1_", + "type": "int256" + }, + { + "internalType": "int256", + "name": "multiplier2PerYear_", + "type": "int256" + }, + { + "internalType": "int256", + "name": "baseRate2PerYear_", + "type": "int256" + }, + { + "internalType": "int256", + "name": "kink2_", + "type": "int256" + }, + { + "internalType": "int256", + "name": "jumpMultiplierPerYear_", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidKink", + "type": "error" + }, + { + "inputs": [], + "name": "NegativeValueNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "BASE_RATE_2_PER_BLOCK", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BASE_RATE_PER_BLOCK", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BLOCKS_PER_YEAR", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "JUMP_MULTIPLIER_PER_BLOCK", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "KINK_1", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "KINK_2", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPLIER_2_PER_BLOCK", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTIPLIER_PER_BLOCK", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_1", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_2", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + } + ], + "name": "getBorrowRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveFactorMantissa", + "type": "uint256" + } + ], + "name": "getSupplyRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isInterestRateModel", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + } + ], + "name": "utilizationRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x306da023d5e76af8f9a0b2f612ed2675e04c4776775e486edf6d66b32b461ca3", + "receipt": { + "to": null, + "from": "0x8BDA9f9E1fEF0DFd404Fef338D9fE4c543d172e1", + "contractAddress": "0x4D712A88Ff15a7147a9966c5ED2ccb392F1760c9", + "transactionIndex": 123, + "gasUsed": "485440", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xc622cb76668bb4710cd309510ceb042c01da216ef1ff312d750b74e1f0d782ab", + "transactionHash": "0x306da023d5e76af8f9a0b2f612ed2675e04c4776775e486edf6d66b32b461ca3", + "logs": [], + "blockNumber": 45212758, + "cumulativeGasUsed": "15298910", + "status": 1, + "byzantium": true + }, + "args": [ + "0", + "150000000000000000", + "800000000000000000", + "900000000000000000", + "0", + "900000000000000000", + "3000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "4d53145ac87d6351787dba7f52e12c3e", + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"baseRatePerYear_\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"multiplierPerYear_\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"kink1_\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"multiplier2PerYear_\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"baseRate2PerYear_\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"kink2_\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"jumpMultiplierPerYear_\",\"type\":\"int256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidKink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NegativeValueNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BASE_RATE_2_PER_BLOCK\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"BASE_RATE_PER_BLOCK\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"BLOCKS_PER_YEAR\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"JUMP_MULTIPLIER_PER_BLOCK\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"KINK_1\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"KINK_2\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTIPLIER_2_PER_BLOCK\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTIPLIER_PER_BLOCK\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RATE_1\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RATE_2\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"cash\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrows\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reserves\",\"type\":\"uint256\"}],\"name\":\"getBorrowRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"cash\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrows\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reserves\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reserveFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"getSupplyRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInterestRateModel\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"cash\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrows\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reserves\",\"type\":\"uint256\"}],\"name\":\"utilizationRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"baseRate2PerYear_\":\"The additional base APR after hitting KINK_1, as a mantissa (scaled by EXP_SCALE)\",\"baseRatePerYear_\":\"The approximate target base APR, as a mantissa (scaled by EXP_SCALE)\",\"jumpMultiplierPerYear_\":\"The multiplier after hitting KINK_2\",\"kink1_\":\"The utilization point at which the multiplier2 is applied\",\"kink2_\":\"The utilization point at which the jump multiplier is applied\",\"multiplier2PerYear_\":\"The rate of increase or decrease in interest rate wrt utilization after hitting KINK_1 (scaled by EXP_SCALE)\",\"multiplierPerYear_\":\"The rate of increase or decrease in interest rate wrt utilization (scaled by EXP_SCALE)\"}},\"getBorrowRate(uint256,uint256,uint256)\":{\"params\":{\"borrows\":\"The amount of borrows in the market\",\"cash\":\"The amount of cash in the market\",\"reserves\":\"The amount of reserves in the market\"},\"returns\":{\"_0\":\"The borrow rate percentage per slot (block) as a mantissa (scaled by EXP_SCALE)\"}},\"getSupplyRate(uint256,uint256,uint256,uint256)\":{\"params\":{\"borrows\":\"The amount of borrows in the market\",\"cash\":\"The amount of cash in the market\",\"reserveFactorMantissa\":\"The current reserve factor for the market\",\"reserves\":\"The amount of reserves in the market\"},\"returns\":{\"_0\":\"The supply rate percentage per slot (block) as a mantissa (scaled by EXP_SCALE)\"}},\"utilizationRate(uint256,uint256,uint256)\":{\"params\":{\"borrows\":\"The amount of borrows in the market\",\"cash\":\"The amount of cash in the market\",\"reserves\":\"The amount of reserves in the market\"},\"returns\":{\"_0\":\"The utilization rate as a mantissa between [0, EXP_SCALE]\"}}},\"title\":\"TwoKinksInterestRateModel\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidKink()\":[{\"notice\":\"Thrown when the kink points are not in the correct order\"}],\"NegativeValueNotAllowed()\":[{\"notice\":\"Thrown when a negative value is not allowed\"}]},\"kind\":\"user\",\"methods\":{\"BASE_RATE_2_PER_BLOCK()\":{\"notice\":\"The base interest rate per block which is the y-intercept when utilization rate hits KINK_1 scaled by EXP_SCALE\"},\"BASE_RATE_PER_BLOCK()\":{\"notice\":\"The base interest rate per block which is the y-intercept when utilization rate is 0 scaled by EXP_SCALE\"},\"JUMP_MULTIPLIER_PER_BLOCK()\":{\"notice\":\"The multiplier of utilization rate per block that gives the slope 3 of interest rate scaled by EXP_SCALE\"},\"KINK_1()\":{\"notice\":\"The utilization point at which the multiplier2 is applied\"},\"KINK_2()\":{\"notice\":\"The utilization point at which the jump multiplier is applied\"},\"MULTIPLIER_2_PER_BLOCK()\":{\"notice\":\"The multiplier of utilization rate per block that gives the slope 2 of the interest rate scaled by EXP_SCALE\"},\"MULTIPLIER_PER_BLOCK()\":{\"notice\":\"The multiplier of utilization rate per block that gives the slope 1 of the interest rate scaled by EXP_SCALE\"},\"RATE_1()\":{\"notice\":\"The maximum kink interest rate scaled by EXP_SCALE\"},\"RATE_2()\":{\"notice\":\"The maximum kink interest rate scaled by EXP_SCALE\"},\"constructor\":{\"notice\":\"Construct an interest rate model\"},\"getBorrowRate(uint256,uint256,uint256)\":{\"notice\":\"Calculates the current borrow rate per slot (block)\"},\"getSupplyRate(uint256,uint256,uint256,uint256)\":{\"notice\":\"Calculates the current supply rate per slot (block)\"},\"isInterestRateModel()\":{\"notice\":\"Indicator that this is an InterestRateModel contract (for inspection)\"},\"utilizationRate(uint256,uint256,uint256)\":{\"notice\":\"Calculates the utilization rate of the market: `borrows / (cash + borrows - reserves)`\"}},\"notice\":\"An interest rate model with two different slope increase or decrease each after a certain utilization threshold called **kink** is reached.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/InterestRateModels/TwoKinksInterestRateModel.sol\":\"TwoKinksInterestRateModel\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/InterestRateModels/InterestRateModelV8.sol\":{\"content\":\"pragma solidity 0.8.25;\\n\\n/**\\n * @title Venus's InterestRateModelV8 Interface\\n * @author Venus\\n */\\nabstract contract InterestRateModelV8 {\\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\\n bool public constant isInterestRateModel = true;\\n\\n /**\\n * @notice Calculates the current borrow interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(uint256 cash, uint256 borrows, uint256 reserves) external view virtual returns (uint256);\\n\\n /**\\n * @notice Calculates the current supply interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 reserveFactorMantissa\\n ) external view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0x9b71896f66909fb3fe829c413594121f0e165d8508e8a6fa29a6938ddcfbb61f\"},\"contracts/InterestRateModels/TwoKinksInterestRateModel.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { InterestRateModelV8 } from \\\"./InterestRateModelV8.sol\\\";\\n\\n/**\\n * @title TwoKinksInterestRateModel\\n * @author Venus\\n * @notice An interest rate model with two different slope increase or decrease each after a certain utilization threshold called **kink** is reached.\\n */\\ncontract TwoKinksInterestRateModel is InterestRateModelV8 {\\n int256 public constant BLOCKS_PER_YEAR = (60 * 60 * 24 * 365) / 3; // (assuming 3s blocks)\\n\\n ////////////////////// SLOPE 1 //////////////////////\\n\\n /**\\n * @notice The multiplier of utilization rate per block that gives the slope 1 of the interest rate scaled by EXP_SCALE\\n */\\n int256 public immutable MULTIPLIER_PER_BLOCK;\\n\\n /**\\n * @notice The base interest rate per block which is the y-intercept when utilization rate is 0 scaled by EXP_SCALE\\n */\\n int256 public immutable BASE_RATE_PER_BLOCK;\\n\\n ////////////////////// SLOPE 2 //////////////////////\\n\\n /**\\n * @notice The utilization point at which the multiplier2 is applied\\n */\\n int256 public immutable KINK_1;\\n\\n /**\\n * @notice The multiplier of utilization rate per block that gives the slope 2 of the interest rate scaled by EXP_SCALE\\n */\\n int256 public immutable MULTIPLIER_2_PER_BLOCK;\\n\\n /**\\n * @notice The base interest rate per block which is the y-intercept when utilization rate hits KINK_1 scaled by EXP_SCALE\\n */\\n int256 public immutable BASE_RATE_2_PER_BLOCK;\\n\\n /**\\n * @notice The maximum kink interest rate scaled by EXP_SCALE\\n */\\n int256 public immutable RATE_1;\\n\\n ////////////////////// SLOPE 3 //////////////////////\\n\\n /**\\n * @notice The utilization point at which the jump multiplier is applied\\n */\\n int256 public immutable KINK_2;\\n\\n /**\\n * @notice The multiplier of utilization rate per block that gives the slope 3 of interest rate scaled by EXP_SCALE\\n */\\n int256 public immutable JUMP_MULTIPLIER_PER_BLOCK;\\n\\n /**\\n * @notice The maximum kink interest rate scaled by EXP_SCALE\\n */\\n int256 public immutable RATE_2;\\n\\n /// @notice Base unit for computations, usually used in scaling (multiplications, divisions)\\n uint256 internal constant EXP_SCALE = 1e18;\\n\\n /**\\n * @notice Thrown when a negative value is not allowed\\n */\\n error NegativeValueNotAllowed();\\n\\n /**\\n * @notice Thrown when the kink points are not in the correct order\\n */\\n error InvalidKink();\\n\\n /**\\n * @notice Construct an interest rate model\\n * @param baseRatePerYear_ The approximate target base APR, as a mantissa (scaled by EXP_SCALE)\\n * @param multiplierPerYear_ The rate of increase or decrease in interest rate wrt utilization (scaled by EXP_SCALE)\\n * @param kink1_ The utilization point at which the multiplier2 is applied\\n * @param multiplier2PerYear_ The rate of increase or decrease in interest rate wrt utilization after hitting KINK_1 (scaled by EXP_SCALE)\\n * @param baseRate2PerYear_ The additional base APR after hitting KINK_1, as a mantissa (scaled by EXP_SCALE)\\n * @param kink2_ The utilization point at which the jump multiplier is applied\\n * @param jumpMultiplierPerYear_ The multiplier after hitting KINK_2\\n */\\n constructor(\\n int256 baseRatePerYear_,\\n int256 multiplierPerYear_,\\n int256 kink1_,\\n int256 multiplier2PerYear_,\\n int256 baseRate2PerYear_,\\n int256 kink2_,\\n int256 jumpMultiplierPerYear_\\n ) {\\n if (baseRatePerYear_ < 0 || baseRate2PerYear_ < 0) {\\n revert NegativeValueNotAllowed();\\n }\\n\\n if (kink2_ <= kink1_ || kink1_ <= 0) {\\n revert InvalidKink();\\n }\\n\\n BASE_RATE_PER_BLOCK = baseRatePerYear_ / BLOCKS_PER_YEAR;\\n MULTIPLIER_PER_BLOCK = multiplierPerYear_ / BLOCKS_PER_YEAR;\\n KINK_1 = kink1_;\\n MULTIPLIER_2_PER_BLOCK = multiplier2PerYear_ / BLOCKS_PER_YEAR;\\n BASE_RATE_2_PER_BLOCK = baseRate2PerYear_ / BLOCKS_PER_YEAR;\\n KINK_2 = kink2_;\\n JUMP_MULTIPLIER_PER_BLOCK = jumpMultiplierPerYear_ / BLOCKS_PER_YEAR;\\n\\n int256 expScale = int256(EXP_SCALE);\\n RATE_1 = (((KINK_1 * MULTIPLIER_PER_BLOCK) / expScale) + BASE_RATE_PER_BLOCK);\\n\\n int256 slope2Util;\\n unchecked {\\n slope2Util = KINK_2 - KINK_1;\\n }\\n RATE_2 = ((slope2Util * MULTIPLIER_2_PER_BLOCK) / expScale) + BASE_RATE_2_PER_BLOCK;\\n }\\n\\n /**\\n * @notice Calculates the current borrow rate per slot (block)\\n * @param cash The amount of cash in the market\\n * @param borrows The amount of borrows in the market\\n * @param reserves The amount of reserves in the market\\n * @return The borrow rate percentage per slot (block) as a mantissa (scaled by EXP_SCALE)\\n */\\n function getBorrowRate(uint256 cash, uint256 borrows, uint256 reserves) external view override returns (uint256) {\\n return _getBorrowRate(cash, borrows, reserves);\\n }\\n\\n /**\\n * @notice Calculates the current supply rate per slot (block)\\n * @param cash The amount of cash in the market\\n * @param borrows The amount of borrows in the market\\n * @param reserves The amount of reserves in the market\\n * @param reserveFactorMantissa The current reserve factor for the market\\n * @return The supply rate percentage per slot (block) as a mantissa (scaled by EXP_SCALE)\\n */\\n function getSupplyRate(\\n uint256 cash,\\n uint256 borrows,\\n uint256 reserves,\\n uint256 reserveFactorMantissa\\n ) public view virtual override returns (uint256) {\\n uint256 oneMinusReserveFactor = EXP_SCALE - reserveFactorMantissa;\\n uint256 borrowRate = _getBorrowRate(cash, borrows, reserves);\\n uint256 rateToPool = (borrowRate * oneMinusReserveFactor) / EXP_SCALE;\\n return (utilizationRate(cash, borrows, reserves) * rateToPool) / EXP_SCALE;\\n }\\n\\n /**\\n * @notice Calculates the utilization rate of the market: `borrows / (cash + borrows - reserves)`\\n * @param cash The amount of cash in the market\\n * @param borrows The amount of borrows in the market\\n * @param reserves The amount of reserves in the market\\n * @return The utilization rate as a mantissa between [0, EXP_SCALE]\\n */\\n function utilizationRate(uint256 cash, uint256 borrows, uint256 reserves) public pure returns (uint256) {\\n // Utilization rate is 0 when there are no borrows\\n if (borrows == 0) {\\n return 0;\\n }\\n\\n uint256 rate = (borrows * EXP_SCALE) / (cash + borrows - reserves);\\n\\n if (rate > EXP_SCALE) {\\n rate = EXP_SCALE;\\n }\\n\\n return rate;\\n }\\n\\n /**\\n * @notice Calculates the current borrow rate per slot (block), with the error code expected by the market\\n * @param cash The amount of cash in the market\\n * @param borrows The amount of borrows in the market\\n * @param reserves The amount of reserves in the market\\n * @return The borrow rate percentage per slot (block) as a mantissa (scaled by EXP_SCALE)\\n */\\n function _getBorrowRate(uint256 cash, uint256 borrows, uint256 reserves) internal view returns (uint256) {\\n int256 util = int256(utilizationRate(cash, borrows, reserves));\\n int256 expScale = int256(EXP_SCALE);\\n\\n if (util < KINK_1) {\\n return _minCap(((util * MULTIPLIER_PER_BLOCK) / expScale) + BASE_RATE_PER_BLOCK);\\n } else if (util < KINK_2) {\\n int256 slope2Util;\\n unchecked {\\n slope2Util = util - KINK_1;\\n }\\n int256 rate2 = ((slope2Util * MULTIPLIER_2_PER_BLOCK) / expScale) + BASE_RATE_2_PER_BLOCK;\\n\\n return _minCap(RATE_1 + rate2);\\n } else {\\n int256 slope3Util;\\n unchecked {\\n slope3Util = util - KINK_2;\\n }\\n int256 rate3 = ((slope3Util * JUMP_MULTIPLIER_PER_BLOCK) / expScale);\\n\\n return _minCap(RATE_1 + RATE_2 + rate3);\\n }\\n }\\n\\n /**\\n * @notice Returns 0 if number is less than 0, otherwise returns the input\\n * @param number The first number\\n * @return The maximum of 0 and input number\\n */\\n function _minCap(int256 number) internal pure returns (uint256) {\\n int256 zero;\\n return uint256(number > zero ? number : zero);\\n }\\n}\\n\",\"keccak256\":\"0x5e1c42a7adfb2b10fddac364289e7af8285d0f387f4961c5bd76624ae11ef2d3\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", + "bytecode": "0x6101a060405234801561001157600080fd5b50604051610adb380380610adb83398101604081905261003091610166565b600087128061003f5750600083125b1561005d576040516341820e7560e11b815260040160405180910390fd5b848213158061006d575060008513155b1561008b57604051637099641d60e11b815260040160405180910390fd5b61009862a06680886101d0565b60a0526100a862a06680876101d0565b60805260c08590526100bd62a06680856101d0565b60e0526100cd62a06680846101d0565b610100526101408290526100e462a06680826101d0565b6101605260a05160805160c051670de0b6b3a764000092918391610108919061020c565b61011291906101d0565b61011c9190610242565b6101205260c051610140516101005160e0519290910391839061013f908461020c565b61014991906101d0565b6101539190610242565b610180525061026a975050505050505050565b600080600080600080600060e0888a03121561018157600080fd5b5050855160208701516040880151606089015160808a015160a08b015160c0909b0151949c939b50919990985090965094509092509050565b634e487b7160e01b600052601160045260246000fd5b6000826101ed57634e487b7160e01b600052601260045260246000fd5b600160ff1b821460001984141615610207576102076101ba565b500590565b80820260008212600160ff1b84141615610228576102286101ba565b818105831482151761023c5761023c6101ba565b92915050565b8082018281126000831280158216821582161715610262576102626101ba565b505092915050565b60805160a05160c05160e05161010051610120516101405161016051610180516107ae61032d600039600081816101a601526105b5015260008181610299015261057b0152600081816101580152818161046b015261055201526000818160f30152818161052101526105d601526000818161020701526104b801526000818161027201526104dd01526000818161017f015281816103d2015261049301526000818161024101526103fd0152600081816101e0015261042201526107ae6000f3fe608060405234801561001057600080fd5b50600436106100e95760003560e01c80638ea0930e1161008c578063c563364911610066578063c56336491461023c578063d37db1d214610263578063ebf22a081461026d578063fe8167d81461029457600080fd5b80638ea0930e146101db578063b571268114610202578063b81688161461022957600080fd5b806338afe9c4116100c857806338afe9c4146101535780633b53e8881461017a5780635d0054c4146101a15780636e71e2d8146101c857600080fd5b8062084e89146100ee57806315f24053146101285780632191f92a1461013b575b600080fd5b6101157f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b610115610136366004610611565b6102bb565b610143600181565b604051901515815260200161011f565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b6101156101d6366004610611565b6102d2565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b61011561023736600461063d565b61033b565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b61011562a0668081565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b60006102c88484846103b7565b90505b9392505050565b6000826000036102e4575060006102cb565b6000826102f18587610685565b6102fb919061069e565b61030d670de0b6b3a7640000866106b1565b61031791906106de565b9050670de0b6b3a76400008111156102c85750670de0b6b3a7640000949350505050565b60008061035083670de0b6b3a764000061069e565b9050600061035f8787876103b7565b90506000670de0b6b3a764000061037684846106b1565b61038091906106de565b9050670de0b6b3a7640000816103978a8a8a6102d2565b6103a191906106b1565b6103ab91906106de565b98975050505050505050565b6000806103c58585856102d2565b9050670de0b6b3a76400007f0000000000000000000000000000000000000000000000000000000000000000821215610469576104607f0000000000000000000000000000000000000000000000000000000000000000826104477f0000000000000000000000000000000000000000000000000000000000000000866106f2565b6104519190610722565b61045b9190610750565b6105fa565b925050506102cb565b7f0000000000000000000000000000000000000000000000000000000000000000821215610550577f0000000000000000000000000000000000000000000000000000000000000000820360007f0000000000000000000000000000000000000000000000000000000000000000836105027f0000000000000000000000000000000000000000000000000000000000000000856106f2565b61050c9190610722565b6105169190610750565b905061054561045b827f0000000000000000000000000000000000000000000000000000000000000000610750565b9450505050506102cb565b7f000000000000000000000000000000000000000000000000000000000000000082036000826105a07f0000000000000000000000000000000000000000000000000000000000000000846106f2565b6105aa9190610722565b9050610545816104517f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610750565b60008080831361060a57806102cb565b5090919050565b60008060006060848603121561062657600080fd5b505081359360208301359350604090920135919050565b6000806000806080858703121561065357600080fd5b5050823594602084013594506040840135936060013592509050565b634e487b7160e01b600052601160045260246000fd5b808201808211156106985761069861066f565b92915050565b818103818111156106985761069861066f565b80820281158282048414176106985761069861066f565b634e487b7160e01b600052601260045260246000fd5b6000826106ed576106ed6106c8565b500490565b80820260008212600160ff1b8414161561070e5761070e61066f565b81810583148215176106985761069861066f565b600082610731576107316106c8565b600160ff1b82146000198414161561074b5761074b61066f565b500590565b80820182811260008312801582168215821617156107705761077061066f565b50509291505056fea264697066735822122059285f5683ee3684ab772b05bd7629497a6d7358bac7b9afa55a9e81818dc59164736f6c63430008190033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100e95760003560e01c80638ea0930e1161008c578063c563364911610066578063c56336491461023c578063d37db1d214610263578063ebf22a081461026d578063fe8167d81461029457600080fd5b80638ea0930e146101db578063b571268114610202578063b81688161461022957600080fd5b806338afe9c4116100c857806338afe9c4146101535780633b53e8881461017a5780635d0054c4146101a15780636e71e2d8146101c857600080fd5b8062084e89146100ee57806315f24053146101285780632191f92a1461013b575b600080fd5b6101157f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b610115610136366004610611565b6102bb565b610143600181565b604051901515815260200161011f565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b6101156101d6366004610611565b6102d2565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b61011561023736600461063d565b61033b565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b61011562a0668081565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b6101157f000000000000000000000000000000000000000000000000000000000000000081565b60006102c88484846103b7565b90505b9392505050565b6000826000036102e4575060006102cb565b6000826102f18587610685565b6102fb919061069e565b61030d670de0b6b3a7640000866106b1565b61031791906106de565b9050670de0b6b3a76400008111156102c85750670de0b6b3a7640000949350505050565b60008061035083670de0b6b3a764000061069e565b9050600061035f8787876103b7565b90506000670de0b6b3a764000061037684846106b1565b61038091906106de565b9050670de0b6b3a7640000816103978a8a8a6102d2565b6103a191906106b1565b6103ab91906106de565b98975050505050505050565b6000806103c58585856102d2565b9050670de0b6b3a76400007f0000000000000000000000000000000000000000000000000000000000000000821215610469576104607f0000000000000000000000000000000000000000000000000000000000000000826104477f0000000000000000000000000000000000000000000000000000000000000000866106f2565b6104519190610722565b61045b9190610750565b6105fa565b925050506102cb565b7f0000000000000000000000000000000000000000000000000000000000000000821215610550577f0000000000000000000000000000000000000000000000000000000000000000820360007f0000000000000000000000000000000000000000000000000000000000000000836105027f0000000000000000000000000000000000000000000000000000000000000000856106f2565b61050c9190610722565b6105169190610750565b905061054561045b827f0000000000000000000000000000000000000000000000000000000000000000610750565b9450505050506102cb565b7f000000000000000000000000000000000000000000000000000000000000000082036000826105a07f0000000000000000000000000000000000000000000000000000000000000000846106f2565b6105aa9190610722565b9050610545816104517f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610750565b60008080831361060a57806102cb565b5090919050565b60008060006060848603121561062657600080fd5b505081359360208301359350604090920135919050565b6000806000806080858703121561065357600080fd5b5050823594602084013594506040840135936060013592509050565b634e487b7160e01b600052601160045260246000fd5b808201808211156106985761069861066f565b92915050565b818103818111156106985761069861066f565b80820281158282048414176106985761069861066f565b634e487b7160e01b600052601260045260246000fd5b6000826106ed576106ed6106c8565b500490565b80820260008212600160ff1b8414161561070e5761070e61066f565b81810583148215176106985761069861066f565b600082610731576107316106c8565b600160ff1b82146000198414161561074b5761074b61066f565b500590565b80820182811260008312801582168215821617156107705761077061066f565b50509291505056fea264697066735822122059285f5683ee3684ab772b05bd7629497a6d7358bac7b9afa55a9e81818dc59164736f6c63430008190033", + "devdoc": { + "author": "Venus", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "baseRate2PerYear_": "The additional base APR after hitting KINK_1, as a mantissa (scaled by EXP_SCALE)", + "baseRatePerYear_": "The approximate target base APR, as a mantissa (scaled by EXP_SCALE)", + "jumpMultiplierPerYear_": "The multiplier after hitting KINK_2", + "kink1_": "The utilization point at which the multiplier2 is applied", + "kink2_": "The utilization point at which the jump multiplier is applied", + "multiplier2PerYear_": "The rate of increase or decrease in interest rate wrt utilization after hitting KINK_1 (scaled by EXP_SCALE)", + "multiplierPerYear_": "The rate of increase or decrease in interest rate wrt utilization (scaled by EXP_SCALE)" + } + }, + "getBorrowRate(uint256,uint256,uint256)": { + "params": { + "borrows": "The amount of borrows in the market", + "cash": "The amount of cash in the market", + "reserves": "The amount of reserves in the market" + }, + "returns": { + "_0": "The borrow rate percentage per slot (block) as a mantissa (scaled by EXP_SCALE)" + } + }, + "getSupplyRate(uint256,uint256,uint256,uint256)": { + "params": { + "borrows": "The amount of borrows in the market", + "cash": "The amount of cash in the market", + "reserveFactorMantissa": "The current reserve factor for the market", + "reserves": "The amount of reserves in the market" + }, + "returns": { + "_0": "The supply rate percentage per slot (block) as a mantissa (scaled by EXP_SCALE)" + } + }, + "utilizationRate(uint256,uint256,uint256)": { + "params": { + "borrows": "The amount of borrows in the market", + "cash": "The amount of cash in the market", + "reserves": "The amount of reserves in the market" + }, + "returns": { + "_0": "The utilization rate as a mantissa between [0, EXP_SCALE]" + } + } + }, + "title": "TwoKinksInterestRateModel", + "version": 1 + }, + "userdoc": { + "errors": { + "InvalidKink()": [ + { + "notice": "Thrown when the kink points are not in the correct order" + } + ], + "NegativeValueNotAllowed()": [ + { + "notice": "Thrown when a negative value is not allowed" + } + ] + }, + "kind": "user", + "methods": { + "BASE_RATE_2_PER_BLOCK()": { + "notice": "The base interest rate per block which is the y-intercept when utilization rate hits KINK_1 scaled by EXP_SCALE" + }, + "BASE_RATE_PER_BLOCK()": { + "notice": "The base interest rate per block which is the y-intercept when utilization rate is 0 scaled by EXP_SCALE" + }, + "JUMP_MULTIPLIER_PER_BLOCK()": { + "notice": "The multiplier of utilization rate per block that gives the slope 3 of interest rate scaled by EXP_SCALE" + }, + "KINK_1()": { + "notice": "The utilization point at which the multiplier2 is applied" + }, + "KINK_2()": { + "notice": "The utilization point at which the jump multiplier is applied" + }, + "MULTIPLIER_2_PER_BLOCK()": { + "notice": "The multiplier of utilization rate per block that gives the slope 2 of the interest rate scaled by EXP_SCALE" + }, + "MULTIPLIER_PER_BLOCK()": { + "notice": "The multiplier of utilization rate per block that gives the slope 1 of the interest rate scaled by EXP_SCALE" + }, + "RATE_1()": { + "notice": "The maximum kink interest rate scaled by EXP_SCALE" + }, + "RATE_2()": { + "notice": "The maximum kink interest rate scaled by EXP_SCALE" + }, + "constructor": { + "notice": "Construct an interest rate model" + }, + "getBorrowRate(uint256,uint256,uint256)": { + "notice": "Calculates the current borrow rate per slot (block)" + }, + "getSupplyRate(uint256,uint256,uint256,uint256)": { + "notice": "Calculates the current supply rate per slot (block)" + }, + "isInterestRateModel()": { + "notice": "Indicator that this is an InterestRateModel contract (for inspection)" + }, + "utilizationRate(uint256,uint256,uint256)": { + "notice": "Calculates the utilization rate of the market: `borrows / (cash + borrows - reserves)`" + } + }, + "notice": "An interest rate model with two different slope increase or decrease each after a certain utilization threshold called **kink** is reached.", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bscmainnet_addresses.json b/deployments/bscmainnet_addresses.json index fd775bc44..ca97f159a 100644 --- a/deployments/bscmainnet_addresses.json +++ b/deployments/bscmainnet_addresses.json @@ -24,6 +24,7 @@ "JumpRateModel_base0bps_slope1000bps_jump50000bps_kink8000bps": "0x05c68eE7c9c66BE3a42476fe3838DE65ddE968f1", "JumpRateModel_base0bps_slope1250bps_jump25000bps_kink8000bps": "0x1485A27D95D3d2878a6641055dD3a643F296CCf6", "JumpRateModel_base0bps_slope1250bps_jump50000bps_kink8000bps": "0x9Fca5d66Cc0DF990080825051E825A8104a7ffA4", + "JumpRateModel_base0bps_slope1750bps_jump25000bps_kink8000bps": "0x0be3ca99FBBE16b86C3b00E2C4c30C3892F31647", "JumpRateModel_base0bps_slope687bps_jump25000bps_kink8000bps": "0xB105F9B511836cc7dF9F3dD0Ec4873766b5b6660", "JumpRateModel_base0bps_slope750bps_jump50000bps_kink8000bps": "0xdEf4b9462223c9a44E61d217a145063C7836FD7B", "JumpRateModel_base0bps_slope875bps_jump25000bps_kink8000bps": "0xBe4609d972FdEBAa9DC870F4A957F40C301bEb1D", @@ -62,6 +63,7 @@ "TUSD": "0x40af3827F39D0EAcBF4A168f8D4ee67c121D11c9", "TUSDOLD": "0x14016E85a25aeb13065688cAFB43044C2ef86784", "TokenRedeemer": "0xC53ffda840B51068C64b2E052a5715043f634bcd", + "TwoKinks_base0bps_slope1500bps_kink8000bps_slope29000bps_base20bps_kink29000bps_jump30000bps": "0x4D712A88Ff15a7147a9966c5ED2ccb392F1760c9", "USDC": "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", "USDT": "0x55d398326f99059fF775485246999027B3197955", "UST": "0x3d4350cD54aeF9f9b2C29435e0fa809957B3F30a", diff --git a/yarn.lock b/yarn.lock index 89a5206d8..00f8623fa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3551,17 +3551,6 @@ __metadata: languageName: node linkType: hard -"@venusprotocol/governance-contracts@npm:^2.4.0": - version: 2.4.0 - resolution: "@venusprotocol/governance-contracts@npm:2.4.0" - dependencies: - "@venusprotocol/solidity-utilities": 2.0.0 - hardhat-deploy-ethers: ^0.3.0-beta.13 - module-alias: ^2.2.2 - checksum: 2a754a05a655bc7b24c33685f86c9bd616a6e7cba4b048315b11eca67a8c1e37c033f04e1b4394e7326251b6af49ab257275cef72727c8976ae16c7f2c2ff0e7 - languageName: node - linkType: hard - "@venusprotocol/governance-contracts@npm:^2.6.0": version: 2.6.0 resolution: "@venusprotocol/governance-contracts@npm:2.6.0" @@ -3594,24 +3583,6 @@ __metadata: languageName: node linkType: hard -"@venusprotocol/protocol-reserve@npm:^2.4.0": - version: 2.4.0 - resolution: "@venusprotocol/protocol-reserve@npm:2.4.0" - dependencies: - "@nomiclabs/hardhat-ethers": ^2.2.3 - "@openzeppelin/contracts": ^4.8.3 - "@openzeppelin/contracts-upgradeable": ^4.8.3 - "@openzeppelin/hardhat-upgrades": ^1.21.0 - "@solidity-parser/parser": ^0.13.2 - "@venusprotocol/solidity-utilities": ^2.0.3 - "@venusprotocol/venus-protocol": ^9.1.0 - ethers: ^5.7.0 - hardhat-deploy: ^0.11.14 - module-alias: ^2.2.2 - checksum: 6e5ffa1c458cff073f9b920ab6385d9db0c86ac11d0950fe421a853e709ee12ec0013c6d3e9cb4e50e94f749dcd33e7a515d57828c5aa6f925dee8324e896ee5 - languageName: node - linkType: hard - "@venusprotocol/protocol-reserve@npm:^3.0.0": version: 3.0.0 resolution: "@venusprotocol/protocol-reserve@npm:3.0.0" @@ -3644,21 +3615,6 @@ __metadata: languageName: node linkType: hard -"@venusprotocol/token-bridge@npm:^2.3.0": - version: 2.3.0 - resolution: "@venusprotocol/token-bridge@npm:2.3.0" - dependencies: - "@layerzerolabs/solidity-examples": ^1.0.0 - "@openzeppelin/contracts": ^4.8.3 - "@openzeppelin/contracts-upgradeable": ^4.8.3 - "@openzeppelin/hardhat-upgrades": ^1.21.0 - "@solidity-parser/parser": ^0.13.2 - ethers: ^5.7.0 - module-alias: ^2.2.2 - checksum: c9f3dcf9eb014592404de14998f817c230e51ec640074ad0811c4ab21e141478b91daefe949b51fc80d6437f3b1f1bb9f606f2c50c2720b01a2e673008208917 - languageName: node - linkType: hard - "@venusprotocol/token-bridge@npm:^2.4.0": version: 2.4.0 resolution: "@venusprotocol/token-bridge@npm:2.4.0" @@ -3674,25 +3630,7 @@ __metadata: languageName: node linkType: hard -"@venusprotocol/venus-protocol@npm:^9.1.0": - version: 9.3.0 - resolution: "@venusprotocol/venus-protocol@npm:9.3.0" - dependencies: - "@nomicfoundation/hardhat-ethers": ^3.0.0 - "@openzeppelin/contracts": 4.9.3 - "@openzeppelin/contracts-upgradeable": ^4.8.0 - "@venusprotocol/governance-contracts": ^2.4.0 - "@venusprotocol/protocol-reserve": ^2.4.0 - "@venusprotocol/solidity-utilities": ^2.0.3 - "@venusprotocol/token-bridge": ^2.3.0 - bignumber.js: ^9.1.2 - dotenv: ^16.0.1 - module-alias: ^2.2.2 - checksum: e9869d63a5c6a4f00ad091357cf76ee6b27a2c61459e69e6818fb36fedb677ae4717c047c5241c6993b86ce29d8657e69abbd88ce4f3344d636a0069ca1559d2 - languageName: node - linkType: hard - -"@venusprotocol/venus-protocol@workspace:.": +"@venusprotocol/venus-protocol@^9.1.0, @venusprotocol/venus-protocol@workspace:.": version: 0.0.0-use.local resolution: "@venusprotocol/venus-protocol@workspace:." dependencies: