Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- KinkMultiplierModel
- Optimization enabled
- true
- Compiler version
- v0.8.17+commit.8df45f5f
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2024-06-02T13:25:29.651587Z
Constructor Arguments
0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000095626ee78400000000000000000000000000000000000000000000000000005b2d5430ce5100000000000000000000000000000000000000000000000000000853a0d2313c0000
Arg [0] (uint256) : 0
Arg [1] (uint256) : 42048000000000000
Arg [2] (uint256) : 6570000000000000000
Arg [3] (uint256) : 600000000000000000
contracts/KinkMultiplierModel.sol
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.8.17;
import "./interfaces/IKinkMultiplierModel.sol";
import "./interfaces/IInterestRateModel.sol";
contract KinkMultiplierModel is IKinkMultiplierModel, IInterestRateModel {
uint256 public constant blocksPerYear = 2628000; // 12 second block interval
uint256 public immutable interestRateMultiplierPerBlock;
uint256 public immutable initialRatePerBlock;
uint256 public immutable kinkCurveMultiplierPerBlock;
uint256 public immutable kinkPoint;
/// @param initialRatePerYear The approximate target initial APR, as a mantissa (scaled by 1e18)
/// @param interestRateMultiplierPerYear Interest rate to utilisation rate increase ratio (scaled by 1e18)
/// @param kinkCurveMultiplierPerYear The multiplier per year after hitting a kink point
/// @param kinkPoint_ The utilisation point at which the kink curve multiplier is applied
constructor(
uint256 initialRatePerYear,
uint256 interestRateMultiplierPerYear,
uint256 kinkCurveMultiplierPerYear,
uint256 kinkPoint_
) {
require(kinkPoint_ > 0);
initialRatePerBlock = initialRatePerYear / blocksPerYear;
interestRateMultiplierPerBlock = interestRateMultiplierPerYear / blocksPerYear;
kinkCurveMultiplierPerBlock = kinkCurveMultiplierPerYear / blocksPerYear;
kinkPoint = kinkPoint_;
}
/// @inheritdoc IInterestRateModel
function getBorrowRate(
uint256 cash,
uint256 borrows,
uint256 protocolInterest
) public view returns (uint256) {
uint256 util = utilisationRate(cash, borrows, protocolInterest);
if (util <= kinkPoint) {
return (util * interestRateMultiplierPerBlock) / 1e18 + initialRatePerBlock;
} else {
uint256 normalRate = (kinkPoint * interestRateMultiplierPerBlock) / 1e18 + initialRatePerBlock;
uint256 excessUtil = util - kinkPoint;
return (excessUtil * kinkCurveMultiplierPerBlock) / 1e18 + normalRate;
}
}
/// @inheritdoc IInterestRateModel
function getSupplyRate(
uint256 cash,
uint256 borrows,
uint256 protocolInterest,
uint256 protocolInterestFactorMantissa
) external view returns (uint256) {
uint256 oneMinusProtocolInterestFactor = 1e18 - protocolInterestFactorMantissa;
uint256 borrowRate = getBorrowRate(cash, borrows, protocolInterest);
uint256 rateToPool = (borrowRate * oneMinusProtocolInterestFactor) / 1e18;
return (utilisationRate(cash, borrows, protocolInterest) * rateToPool) / 1e18;
}
/// @inheritdoc IKinkMultiplierModel
function utilisationRate(
uint256 cash,
uint256 borrows,
uint256 protocolInterest
) public pure returns (uint256) {
// Utilisation rate is 0 when there are no borrows
if (borrows == 0) return 0;
return (borrows * 1e18) / (cash + borrows - protocolInterest);
}
}
@openzeppelin/contracts/utils/introspection/IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
contracts/interfaces/IInterestRateModel.sol
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.8.17;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @title Minterest InterestRateModel Interface
* @author Minterest
*/
interface IInterestRateModel {
/**
* @notice Calculates the current borrow interest rate per block
* @param cash The total amount of cash the market has
* @param borrows The total amount of borrows the market has outstanding
* @param protocolInterest The total amount of protocol interest the market has
* @return The borrow rate per block (as a percentage, and scaled by 1e18)
*/
function getBorrowRate(
uint256 cash,
uint256 borrows,
uint256 protocolInterest
) external view returns (uint256);
/**
* @notice Calculates the current supply interest rate per block
* @param cash The total amount of cash the market has
* @param borrows The total amount of borrows the market has outstanding
* @param protocolInterest The total amount of protocol interest the market has
* @param protocolInterestFactorMantissa The current protocol interest factor the market has
* @return The supply rate per block (as a percentage, and scaled by 1e18)
*/
function getSupplyRate(
uint256 cash,
uint256 borrows,
uint256 protocolInterest,
uint256 protocolInterestFactorMantissa
) external view returns (uint256);
}
contracts/interfaces/IKinkMultiplierModel.sol
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.8.17;
interface IKinkMultiplierModel {
/**
* @notice Gets the approximate number of blocks per year that is assumed by the interest rate model
*/
function blocksPerYear() external view returns (uint256);
/**
* @notice Gets the multiplier of utilisation rate that gives the slope of the interest rate
*/
function interestRateMultiplierPerBlock() external view returns (uint256);
/**
* @notice Gets the initial interest rate which is the y-intercept when utilisation rate is 0
*/
function initialRatePerBlock() external view returns (uint256);
/**
* @notice Gets the interestRateMultiplierPerBlock after hitting a specified utilisation point
*/
function kinkCurveMultiplierPerBlock() external view returns (uint256);
/**
* @notice Gets the utilisation point at which the kink curve multiplier is applied
*/
function kinkPoint() external view returns (uint256);
/**
* @notice Calculates the utilisation rate of the market: `borrows / (cash + borrows - protocol interest)`
* @param cash The amount of cash in the market
* @param borrows The amount of borrows in the market
* @param protocolInterest The amount of protocol interest in the market
* @return The utilisation rate as a mantissa between [0, 1e18]
*/
function utilisationRate(
uint256 cash,
uint256 borrows,
uint256 protocolInterest
) external pure returns (uint256);
}
Compiler Settings
{"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"useLiteralContent":true},"libraries":{}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"uint256","name":"initialRatePerYear","internalType":"uint256"},{"type":"uint256","name":"interestRateMultiplierPerYear","internalType":"uint256"},{"type":"uint256","name":"kinkCurveMultiplierPerYear","internalType":"uint256"},{"type":"uint256","name":"kinkPoint_","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"blocksPerYear","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getBorrowRate","inputs":[{"type":"uint256","name":"cash","internalType":"uint256"},{"type":"uint256","name":"borrows","internalType":"uint256"},{"type":"uint256","name":"protocolInterest","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getSupplyRate","inputs":[{"type":"uint256","name":"cash","internalType":"uint256"},{"type":"uint256","name":"borrows","internalType":"uint256"},{"type":"uint256","name":"protocolInterest","internalType":"uint256"},{"type":"uint256","name":"protocolInterestFactorMantissa","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"initialRatePerBlock","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"interestRateMultiplierPerBlock","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"kinkCurveMultiplierPerBlock","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"kinkPoint","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"utilisationRate","inputs":[{"type":"uint256","name":"cash","internalType":"uint256"},{"type":"uint256","name":"borrows","internalType":"uint256"},{"type":"uint256","name":"protocolInterest","internalType":"uint256"}]}]
Contract Creation Code
0x61010060405234801561001157600080fd5b5060405161064a38038061064a83398101604081905261003091610079565b6000811161003d57600080fd5b61004a622819a0856100af565b60a05261005a622819a0846100af565b60805261006a622819a0836100af565b60c05260e052506100d1915050565b6000806000806080858703121561008f57600080fd5b505082516020840151604085015160609095015191969095509092509050565b6000826100cc57634e487b7160e01b600052601260045260246000fd5b500490565b60805160a05160c05160e05161050a61014060003960008181610105015281816101900152818161027701526102b801526000818161012c01526102ee0152600081816092015281816101b7015261022901526000818160de015281816101e40152610256015261050a6000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c806372c2cfd01161005b57806372c2cfd014610127578063a385fb961461014e578063b816881614610158578063ca6c72001461016b57600080fd5b80630a9ea29f1461008d57806315f24053146100c65780634c041acc146100d9578063662db9ab14610100575b600080fd5b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200160405180910390f35b6100b46100d43660046103fb565b61017e565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100b4622819a081565b6100b4610166366004610427565b610334565b6100b46101793660046103fb565b6103b0565b60008061018c8585856103b0565b90507f00000000000000000000000000000000000000000000000000000000000000008111610225577f0000000000000000000000000000000000000000000000000000000000000000670de0b6b3a76400006102097f00000000000000000000000000000000000000000000000000000000000000008461046f565b610213919061048c565b61021d91906104ae565b91505061032d565b60007f0000000000000000000000000000000000000000000000000000000000000000670de0b6b3a764000061029b7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061046f565b6102a5919061048c565b6102af91906104ae565b905060006102dd7f0000000000000000000000000000000000000000000000000000000000000000846104c1565b905081670de0b6b3a76400006103137f00000000000000000000000000000000000000000000000000000000000000008461046f565b61031d919061048c565b61032791906104ae565b93505050505b9392505050565b60008061034983670de0b6b3a76400006104c1565b9050600061035887878761017e565b90506000670de0b6b3a764000061036f848461046f565b610379919061048c565b9050670de0b6b3a7640000816103908a8a8a6103b0565b61039a919061046f565b6103a4919061048c565b98975050505050505050565b6000826000036103c25750600061032d565b816103cd84866104ae565b6103d791906104c1565b6103e984670de0b6b3a764000061046f565b6103f3919061048c565b949350505050565b60008060006060848603121561041057600080fd5b505081359360208301359350604090920135919050565b6000806000806080858703121561043d57600080fd5b5050823594602084013594506040840135936060013592509050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761048657610486610459565b92915050565b6000826104a957634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561048657610486610459565b818103818111156104865761048661045956fea2646970667358221220cd1f02eb22df8738ed95308675433e68b4d5e8274162f4bea5ea8dcffc1f825964736f6c6343000811003300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000095626ee78400000000000000000000000000000000000000000000000000005b2d5430ce5100000000000000000000000000000000000000000000000000000853a0d2313c0000
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100885760003560e01c806372c2cfd01161005b57806372c2cfd014610127578063a385fb961461014e578063b816881614610158578063ca6c72001461016b57600080fd5b80630a9ea29f1461008d57806315f24053146100c65780634c041acc146100d9578063662db9ab14610100575b600080fd5b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200160405180910390f35b6100b46100d43660046103fb565b61017e565b6100b47f00000000000000000000000000000000000000000000000000000003b9aca00081565b6100b47f0000000000000000000000000000000000000000000000000853a0d2313c000081565b6100b47f00000000000000000000000000000000000000000000000000000246139ca80081565b6100b4622819a081565b6100b4610166366004610427565b610334565b6100b46101793660046103fb565b6103b0565b60008061018c8585856103b0565b90507f0000000000000000000000000000000000000000000000000853a0d2313c00008111610225577f0000000000000000000000000000000000000000000000000000000000000000670de0b6b3a76400006102097f00000000000000000000000000000000000000000000000000000003b9aca0008461046f565b610213919061048c565b61021d91906104ae565b91505061032d565b60007f0000000000000000000000000000000000000000000000000000000000000000670de0b6b3a764000061029b7f00000000000000000000000000000000000000000000000000000003b9aca0007f0000000000000000000000000000000000000000000000000853a0d2313c000061046f565b6102a5919061048c565b6102af91906104ae565b905060006102dd7f0000000000000000000000000000000000000000000000000853a0d2313c0000846104c1565b905081670de0b6b3a76400006103137f00000000000000000000000000000000000000000000000000000246139ca8008461046f565b61031d919061048c565b61032791906104ae565b93505050505b9392505050565b60008061034983670de0b6b3a76400006104c1565b9050600061035887878761017e565b90506000670de0b6b3a764000061036f848461046f565b610379919061048c565b9050670de0b6b3a7640000816103908a8a8a6103b0565b61039a919061046f565b6103a4919061048c565b98975050505050505050565b6000826000036103c25750600061032d565b816103cd84866104ae565b6103d791906104c1565b6103e984670de0b6b3a764000061046f565b6103f3919061048c565b949350505050565b60008060006060848603121561041057600080fd5b505081359360208301359350604090920135919050565b6000806000806080858703121561043d57600080fd5b5050823594602084013594506040840135936060013592509050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761048657610486610459565b92915050565b6000826104a957634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561048657610486610459565b818103818111156104865761048661045956fea2646970667358221220cd1f02eb22df8738ed95308675433e68b4d5e8274162f4bea5ea8dcffc1f825964736f6c63430008110033