{"sources":{"interestModel.sol":{"content":"/**\r\n *Submitted for verification at BscScan.com on 2021-03-08\r\n*/\r\n\r\n// File: contracts/interfaces/interestModelInterface.sol\r\n\r\npragma solidity 0.6.12;\r\n\r\n/**\r\n * @title BiFi's interest model interface\r\n * @author BiFi(seinmyung25, Miller-kk, tlatkdgus1, dongchangYoo)\r\n */\r\ninterface interestModelInterface {\r\n\tfunction getInterestAmount(address handlerDataStorageAddr, address payable userAddr, bool isView) external view returns (bool, uint256, uint256, bool, uint256, uint256);\r\n\tfunction viewInterestAmount(address handlerDataStorageAddr, address payable userAddr) external view returns (bool, uint256, uint256, bool, uint256, uint256);\r\n\tfunction getSIRandBIR(uint256 depositTotalAmount, uint256 borrowTotalAmount) external view returns (uint256, uint256);\r\n}\r\n\r\n// File: contracts/interfaces/marketHandlerDataStorageInterface.sol\r\n\r\npragma solidity 0.6.12;\r\n\r\n/**\r\n * @title BiFi's market handler data storage interface\r\n * @author BiFi(seinmyung25, Miller-kk, tlatkdgus1, dongchangYoo)\r\n */\r\ninterface marketHandlerDataStorageInterface  {\r\n\tfunction setCircuitBreaker(bool _emergency) external returns (bool);\r\n\r\n\tfunction setNewCustomer(address payable userAddr) external returns (bool);\r\n\r\n\tfunction getUserAccessed(address payable userAddr) external view returns (bool);\r\n\tfunction setUserAccessed(address payable userAddr, bool _accessed) external returns (bool);\r\n\r\n\tfunction getReservedAddr() external view returns (address payable);\r\n\tfunction setReservedAddr(address payable reservedAddress) external returns (bool);\r\n\r\n\tfunction getReservedAmount() external view returns (int256);\r\n\tfunction addReservedAmount(uint256 amount) external returns (int256);\r\n\tfunction subReservedAmount(uint256 amount) external returns (int256);\r\n\tfunction updateSignedReservedAmount(int256 amount) external returns (int256);\r\n\r\n\tfunction setTokenHandler(address _marketHandlerAddr, address _interestModelAddr) external returns (bool);\r\n\tfunction setCoinHandler(address _marketHandlerAddr, address _interestModelAddr) external returns (bool);\r\n\r\n\tfunction getDepositTotalAmount() external view returns (uint256);\r\n\tfunction addDepositTotalAmount(uint256 amount) external returns (uint256);\r\n\tfunction subDepositTotalAmount(uint256 amount) external returns (uint256);\r\n\r\n\tfunction getBorrowTotalAmount() external view returns (uint256);\r\n\tfunction addBorrowTotalAmount(uint256 amount) external returns (uint256);\r\n\tfunction subBorrowTotalAmount(uint256 amount) external returns (uint256);\r\n\r\n\tfunction getUserIntraDepositAmount(address payable userAddr) external view returns (uint256);\r\n\tfunction addUserIntraDepositAmount(address payable userAddr, uint256 amount) external returns (uint256);\r\n\tfunction subUserIntraDepositAmount(address payable userAddr, uint256 amount) external returns (uint256);\r\n\r\n\tfunction getUserIntraBorrowAmount(address payable userAddr) external view returns (uint256);\r\n\tfunction addUserIntraBorrowAmount(address payable userAddr, uint256 amount) external returns (uint256);\r\n\tfunction subUserIntraBorrowAmount(address payable userAddr, uint256 amount) external returns (uint256);\r\n\r\n\tfunction addDepositAmount(address payable userAddr, uint256 amount) external returns (bool);\r\n\tfunction subDepositAmount(address payable userAddr, uint256 amount) external returns (bool);\r\n\r\n\tfunction addBorrowAmount(address payable userAddr, uint256 amount) external returns (bool);\r\n\tfunction subBorrowAmount(address payable userAddr, uint256 amount) external returns (bool);\r\n\r\n\tfunction getUserAmount(address payable userAddr) external view returns (uint256, uint256);\r\n\tfunction getHandlerAmount() external view returns (uint256, uint256);\r\n\r\n\tfunction getAmount(address payable userAddr) external view returns (uint256, uint256, uint256, uint256);\r\n\tfunction setAmount(address payable userAddr, uint256 depositTotalAmount, uint256 borrowTotalAmount, uint256 depositAmount, uint256 borrowAmount) external returns (uint256);\r\n\r\n\tfunction setBlocks(uint256 lastUpdatedBlock, uint256 inactiveActionDelta) external returns (bool);\r\n\r\n\tfunction getLastUpdatedBlock() external view returns (uint256);\r\n\tfunction setLastUpdatedBlock(uint256 _lastUpdatedBlock) external returns (bool);\r\n\r\n\tfunction getInactiveActionDelta() external view returns (uint256);\r\n\tfunction setInactiveActionDelta(uint256 inactiveActionDelta) external returns (bool);\r\n\r\n\tfunction syncActionEXR() external returns (bool);\r\n\r\n\tfunction getActionEXR() external view returns (uint256, uint256);\r\n\tfunction setActionEXR(uint256 actionDepositExRate, uint256 actionBorrowExRate) external returns (bool);\r\n\r\n\tfunction getGlobalDepositEXR() external view returns (uint256);\r\n\tfunction getGlobalBorrowEXR() external view returns (uint256);\r\n\r\n\tfunction setEXR(address payable userAddr, uint256 globalDepositEXR, uint256 globalBorrowEXR) external returns (bool);\r\n\r\n\tfunction getUserEXR(address payable userAddr) external view returns (uint256, uint256);\r\n\tfunction setUserEXR(address payable userAddr, uint256 depositEXR, uint256 borrowEXR) external returns (bool);\r\n\r\n\tfunction getGlobalEXR() external view returns (uint256, uint256);\r\n\r\n\tfunction getMarketHandlerAddr() external view returns (address);\r\n\tfunction setMarketHandlerAddr(address marketHandlerAddr) external returns (bool);\r\n\r\n\tfunction getInterestModelAddr() external view returns (address);\r\n\tfunction setInterestModelAddr(address interestModelAddr) external returns (bool);\r\n\r\n\r\n\tfunction getMinimumInterestRate() external view returns (uint256);\r\n\tfunction setMinimumInterestRate(uint256 _minimumInterestRate) external returns (bool);\r\n\r\n\tfunction getLiquiditySensitivity() external view returns (uint256);\r\n\tfunction setLiquiditySensitivity(uint256 _liquiditySensitivity) external returns (bool);\r\n\r\n\tfunction getLimit() external view returns (uint256, uint256);\r\n\r\n\tfunction getBorrowLimit() external view returns (uint256);\r\n\tfunction setBorrowLimit(uint256 _borrowLimit) external returns (bool);\r\n\r\n\tfunction getMarginCallLimit() external view returns (uint256);\r\n\tfunction setMarginCallLimit(uint256 _marginCallLimit) external returns (bool);\r\n\r\n\tfunction getLimitOfAction() external view returns (uint256);\r\n\tfunction setLimitOfAction(uint256 limitOfAction) external returns (bool);\r\n\r\n\tfunction getLiquidityLimit() external view returns (uint256);\r\n\tfunction setLiquidityLimit(uint256 liquidityLimit) external returns (bool);\r\n}\r\n\r\n// File: contracts/SafeMath.sol\r\n\r\n\r\npragma solidity ^0.6.12;\r\n\r\n// from: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol\r\n// Subject to the MIT license.\r\n\r\n/**\r\n * @title BiFi's safe-math Contract\r\n * @author BiFi(seinmyung25, Miller-kk, tlatkdgus1, dongchangYoo)\r\n */\r\nlibrary SafeMath {\r\n  uint256 internal constant unifiedPoint = 10 ** 18;\r\n\t/******************** Safe Math********************/\r\n\tfunction add(uint256 a, uint256 b) internal pure returns (uint256)\r\n\t{\r\n\t\tuint256 c = a + b;\r\n\t\trequire(c >= a, \"a\");\r\n\t\treturn c;\r\n\t}\r\n\r\n\tfunction sub(uint256 a, uint256 b) internal pure returns (uint256)\r\n\t{\r\n\t\treturn _sub(a, b, \"s\");\r\n\t}\r\n\r\n\tfunction mul(uint256 a, uint256 b) internal pure returns (uint256)\r\n\t{\r\n\t\treturn _mul(a, b);\r\n\t}\r\n\r\n\tfunction div(uint256 a, uint256 b) internal pure returns (uint256)\r\n\t{\r\n\t\treturn _div(a, b, \"d\");\r\n\t}\r\n\r\n\tfunction _sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256)\r\n\t{\r\n\t\trequire(b <= a, errorMessage);\r\n\t\treturn a - b;\r\n\t}\r\n\r\n\tfunction _mul(uint256 a, uint256 b) internal pure returns (uint256)\r\n\t{\r\n\t\tif (a == 0)\r\n\t\t{\r\n\t\t\treturn 0;\r\n\t\t}\r\n\r\n\t\tuint256 c = a* b;\r\n\t\trequire((c / a) == b, \"m\");\r\n\t\treturn c;\r\n\t}\r\n\r\n\tfunction _div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256)\r\n\t{\r\n\t\trequire(b > 0, errorMessage);\r\n\t\treturn a / b;\r\n\t}\r\n\r\n\tfunction unifiedDiv(uint256 a, uint256 b) internal pure returns (uint256)\r\n\t{\r\n\t\treturn _div(_mul(a, unifiedPoint), b, \"d\");\r\n\t}\r\n\r\n\tfunction unifiedMul(uint256 a, uint256 b) internal pure returns (uint256)\r\n\t{\r\n\t\treturn _div(_mul(a, b), unifiedPoint, \"m\");\r\n\t}\r\n}\r\n\r\n// File: contracts/Errors.sol\r\n\r\npragma solidity 0.6.12;\r\n\r\ncontract Modifier {\r\n    string internal constant ONLY_OWNER = \"O\";\r\n    string internal constant ONLY_MANAGER = \"M\";\r\n    string internal constant CIRCUIT_BREAKER = \"emergency\";\r\n}\r\n\r\ncontract ManagerModifier is Modifier {\r\n    string internal constant ONLY_HANDLER = \"H\";\r\n    string internal constant ONLY_LIQUIDATION_MANAGER = \"LM\";\r\n    string internal constant ONLY_BREAKER = \"B\";\r\n}\r\n\r\ncontract HandlerDataStorageModifier is Modifier {\r\n    string internal constant ONLY_BIFI_CONTRACT = \"BF\";\r\n}\r\n\r\ncontract SIDataStorageModifier is Modifier {\r\n    string internal constant ONLY_SI_HANDLER = \"SI\";\r\n}\r\n\r\ncontract HandlerErrors is Modifier {\r\n    string internal constant USE_VAULE = \"use value\";\r\n    string internal constant USE_ARG = \"use arg\";\r\n    string internal constant EXCEED_LIMIT = \"exceed limit\";\r\n    string internal constant NO_LIQUIDATION = \"no liquidation\";\r\n    string internal constant NO_LIQUIDATION_REWARD = \"no enough reward\";\r\n    string internal constant NO_EFFECTIVE_BALANCE = \"not enough balance\";\r\n    string internal constant TRANSFER = \"err transfer\";\r\n}\r\n\r\ncontract SIErrors is Modifier { }\r\n\r\ncontract InterestErrors is Modifier { }\r\n\r\ncontract LiquidationManagerErrors is Modifier {\r\n    string internal constant NO_DELINQUENT = \"not delinquent\";\r\n}\r\n\r\ncontract ManagerErrors is ManagerModifier {\r\n    string internal constant REWARD_TRANSFER = \"RT\";\r\n    string internal constant UNSUPPORTED_TOKEN = \"UT\";\r\n}\r\n\r\ncontract OracleProxyErrors is Modifier {\r\n    string internal constant ZERO_PRICE = \"price zero\";\r\n}\r\n\r\ncontract RequestProxyErrors is Modifier { }\r\n\r\ncontract ManagerDataStorageErrors is ManagerModifier {\r\n    string internal constant NULL_ADDRESS = \"err addr null\";\r\n}\r\n\r\n// File: contracts/interestModel/interestModel.sol\r\n\r\npragma solidity 0.6.12;\r\n\r\n/**\r\n* @title Bifi interestModel Contract\r\n* @notice Contract for interestModel\r\n* @author BiFi(seinmyung25, Miller-kk, tlatkdgus1, dongchangYoo)\r\n*/\r\ncontract interestModel is interestModelInterface, InterestErrors {\r\n\tusing SafeMath for uint256;\r\n\r\n\taddress owner;\r\n\tmapping(address => bool) public operators;\r\n\r\n\tuint256 public blocksPerYear;\r\n\tuint256 constant unifiedPoint = 10 ** 18;\r\n\r\n\tuint256 minRate;\r\n\tuint256 basicSensitivity;\r\n\r\n\t/* jump rate model prams */\r\n\tuint256 jumpPoint;\r\n\tuint256 jumpSensitivity;\r\n\r\n\tuint256 spreadRate;\r\n\r\n\tstruct InterestUpdateModel {\r\n\t\tuint256 SIR;\r\n\t\tuint256 BIR;\r\n\t\tuint256 depositTotalAmount;\r\n\t\tuint256 borrowTotalAmount;\r\n\t\tuint256 userDepositAmount;\r\n\t\tuint256 userBorrowAmount;\r\n\t\tuint256 deltaDepositAmount;\r\n\t\tuint256 deltaBorrowAmount;\r\n\t\tuint256 globalDepositEXR;\r\n\t\tuint256 globalBorrowEXR;\r\n\t\tuint256 userDepositEXR;\r\n\t\tuint256 userBorrowEXR;\r\n\t\tuint256 actionDepositEXR;\r\n\t\tuint256 actionBorrowEXR;\r\n\t\tuint256 deltaDepositEXR;\r\n\t\tuint256 deltaBorrowEXR;\r\n\t\tbool depositNegativeFlag;\r\n\t\tbool borrowNegativeFlag;\r\n\t}\r\n\r\n\tmodifier onlyOwner {\r\n\t\trequire(msg.sender == owner, ONLY_OWNER);\r\n\t\t_;\r\n\t}\r\n\r\n\tmodifier onlyOperator {\r\n\t\taddress sender = msg.sender;\r\n\t\trequire(operators[sender] || sender == owner, \"Only Operators\");\r\n\t\t_;\r\n\t}\r\n\r\n\t/**\r\n\t* @dev Construct a new interestModel contract\r\n\t* @param _minRate minimum interest rate\r\n\t* @param _jumpPoint Threshold of utilizationRate to which normal interest model\r\n\t* @param _basicSensitivity liquidity basicSensitivity\r\n\t* @param _jumpSensitivity The value used to calculate the BIR if the utilizationRate is greater than the jumpPoint.\r\n\t* @param _spreadRate spread rate\r\n\t*/\r\n\tconstructor (uint256 _minRate, uint256 _jumpPoint, uint256 _basicSensitivity, uint256 _jumpSensitivity, uint256 _spreadRate) public\r\n\t{\r\n\t\taddress sender = msg.sender;\r\n\t\towner = sender;\r\n\t\toperators[owner] = true;\r\n\r\n\t\tminRate = _minRate;\r\n\t\tbasicSensitivity = _basicSensitivity;\r\n\r\n\t\tjumpPoint = _jumpPoint;\r\n\t\tjumpSensitivity = _jumpSensitivity;\r\n\r\n\t\tspreadRate = _spreadRate;\r\n\t}\r\n\r\n\t/**\r\n\t* @dev Replace the owner of the handler\r\n\t* @param _owner the address of the new owner\r\n\t* @return true (TODO: validate results)\r\n\t*/\r\n\tfunction ownershipTransfer(address payable _owner) onlyOwner external returns (bool)\r\n\t{\r\n\t\towner = _owner;\r\n\t\treturn true;\r\n\t}\r\n\r\n\t/**\r\n\t* @dev Get the address of owner\r\n\t* @return the address of owner\r\n\t*/\r\n\tfunction getOwner() public view returns (address)\r\n\t{\r\n\t\treturn owner;\r\n\t}\r\n\r\n\t/**\r\n\t* @dev set Operator or not\r\n\t* @param _operator the address of the operator\r\n\t* @param flag operator permission\r\n\t* @return true (TODO: validate results)\r\n\t*/\r\n\tfunction setOperators(address payable _operator, bool flag) onlyOwner external returns (bool) {\r\n\t\toperators[_operator] = flag;\r\n\t\treturn true;\r\n\t}\r\n\r\n\t/**\r\n\t * @dev Calculates interest amount for a user\r\n\t * @param handlerDataStorageAddr The address of handlerDataStorage contract\r\n\t * @param userAddr The address of user\r\n\t * @param isView Select _view (before action) or _get (after action) function for calculation\r\n\t * @return (bool, uint256, uint256, bool, uint256, uint256)\r\n\t */\r\n\tfunction getInterestAmount(address handlerDataStorageAddr, address payable userAddr, bool isView) external view override returns (bool, uint256, uint256, bool, uint256, uint256)\r\n\t{\r\n\t\tif (isView)\r\n\t\t{\r\n\t\t\treturn _viewInterestAmount(handlerDataStorageAddr, userAddr);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\treturn _getInterestAmount(handlerDataStorageAddr, userAddr);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @dev Calculates interest amount for a user (before user action)\r\n\t * @param handlerDataStorageAddr The address of handlerDataStorage contract\r\n\t * @param userAddr The address of user\r\n\t * @return (bool, uint256, uint256, bool, uint256, uint256)\r\n\t */\r\n\tfunction viewInterestAmount(address handlerDataStorageAddr, address payable userAddr) external view override returns (bool, uint256, uint256, bool, uint256, uint256)\r\n\t{\r\n\t\treturn _viewInterestAmount(handlerDataStorageAddr, userAddr);\r\n\t}\r\n\r\n\t/**\r\n\t * @dev Get Supply Interest Rate (SIR) and Borrow Interest Rate (BIR) (external)\r\n\t * @param totalDepositAmount The amount of total deposit\r\n\t * @param totalBorrowAmount The amount of total borrow\r\n\t * @return (uint256, uin256)\r\n\t */\r\n\tfunction getSIRandBIR(uint256 totalDepositAmount, uint256 totalBorrowAmount) external view override returns (uint256, uint256)\r\n\t{\r\n\t\treturn _getSIRandBIR(totalDepositAmount, totalBorrowAmount);\r\n\t}\r\n\r\n\t/**\r\n\t * @dev Calculates interest amount for a user (after user action)\r\n\t * @param handlerDataStorageAddr The address of handlerDataStorage contract\r\n\t * @param userAddr The address of user\r\n\t * @return (bool, uint256, uint256, bool, uint256, uint256)\r\n\t */\r\n\tfunction _getInterestAmount(address handlerDataStorageAddr, address payable userAddr) internal view returns (bool, uint256, uint256, bool, uint256, uint256)\r\n\t{\r\n\t\tmarketHandlerDataStorageInterface handlerDataStorage = marketHandlerDataStorageInterface(handlerDataStorageAddr);\r\n\t\tuint256 delta = handlerDataStorage.getInactiveActionDelta();\r\n\t\tuint256 actionDepositEXR;\r\n\t\tuint256 actionBorrowEXR;\r\n\t\t(actionDepositEXR, actionBorrowEXR) = handlerDataStorage.getActionEXR();\r\n\t\treturn _calcInterestAmount(handlerDataStorageAddr, userAddr, delta, actionDepositEXR, actionBorrowEXR);\r\n\t}\r\n\r\n\t/**\r\n\t * @dev Calculates interest amount for a user (before user action)\r\n\t * @param handlerDataStorageAddr The address of handlerDataStorage contract\r\n\t * @param userAddr The address of user\r\n\t * @return (bool, uint256, uint256, bool, uint256, uint256)\r\n\t */\r\n\tfunction _viewInterestAmount(address handlerDataStorageAddr, address payable userAddr) internal view returns (bool, uint256, uint256, bool, uint256, uint256)\r\n\t{\r\n\t\tmarketHandlerDataStorageInterface handlerDataStorage = marketHandlerDataStorageInterface(handlerDataStorageAddr);\r\n\t\tuint256 blockDelta = block.number.sub(handlerDataStorage.getLastUpdatedBlock());\r\n\t\t/* check action in block */\r\n\t\tuint256 globalDepositEXR;\r\n\t\tuint256 globalBorrowEXR;\r\n\t\t(globalDepositEXR, globalBorrowEXR) = handlerDataStorage.getGlobalEXR();\r\n\t\treturn _calcInterestAmount(handlerDataStorageAddr, userAddr, blockDelta, globalDepositEXR, globalBorrowEXR);\r\n\t}\r\n\r\n\t/**\r\n\t * @dev Calculate interest amount for a user with BIR and SIR (interal)\r\n\t * @param handlerDataStorageAddr The address of handlerDataStorage contract\r\n\t * @param userAddr The address of user\r\n\t * @return (bool, uint256, uint256, bool, uint256, uint256)\r\n\t */\r\n\tfunction _calcInterestAmount(address handlerDataStorageAddr, address payable userAddr, uint256 delta, uint256 actionDepositEXR, uint256 actionBorrowEXR) internal view returns (bool, uint256, uint256, bool, uint256, uint256)\r\n\t{\r\n\t\tInterestUpdateModel memory interestUpdateModel;\r\n\t\tmarketHandlerDataStorageInterface handlerDataStorage = marketHandlerDataStorageInterface(handlerDataStorageAddr);\r\n\t\t(interestUpdateModel.depositTotalAmount, interestUpdateModel.borrowTotalAmount, interestUpdateModel.userDepositAmount, interestUpdateModel.userBorrowAmount) = handlerDataStorage.getAmount(userAddr);\r\n\t\t(interestUpdateModel.SIR, interestUpdateModel.BIR) = _getSIRandBIRonBlock(interestUpdateModel.depositTotalAmount, interestUpdateModel.borrowTotalAmount);\r\n\t\t(interestUpdateModel.userDepositEXR, interestUpdateModel.userBorrowEXR) = handlerDataStorage.getUserEXR(userAddr);\r\n\r\n\t\t/* deposit start */\r\n\t\tinterestUpdateModel.globalDepositEXR = _getNewGlobalEXR(actionDepositEXR, interestUpdateModel.SIR, delta);\r\n\t\t(interestUpdateModel.depositNegativeFlag, interestUpdateModel.deltaDepositAmount) = _getDeltaAmount(interestUpdateModel.userDepositAmount, interestUpdateModel.globalDepositEXR, interestUpdateModel.userDepositEXR);\r\n\t\t/* deposit done */\r\n\r\n\t\t/* borrow start */\r\n\t\tinterestUpdateModel.globalBorrowEXR = _getNewGlobalEXR(actionBorrowEXR, interestUpdateModel.BIR, delta);\r\n\t\t(interestUpdateModel.borrowNegativeFlag, interestUpdateModel.deltaBorrowAmount) = _getDeltaAmount(interestUpdateModel.userBorrowAmount, interestUpdateModel.globalBorrowEXR, interestUpdateModel.userBorrowEXR);\r\n\t\t/* borrow done */\r\n\r\n\t\treturn (interestUpdateModel.depositNegativeFlag, interestUpdateModel.deltaDepositAmount, interestUpdateModel.globalDepositEXR, interestUpdateModel.borrowNegativeFlag, interestUpdateModel.deltaBorrowAmount, interestUpdateModel.globalBorrowEXR);\r\n\t}\r\n\r\n\t/**\r\n\t * @dev Calculates the utilization rate of market\r\n\t * @param depositTotalAmount The total amount of deposit\r\n\t * @param borrowTotalAmount The total amount of borrow\r\n\t * @return The utilitization rate of market\r\n\t */\r\n\tfunction _getUtilizationRate(uint256 depositTotalAmount, uint256 borrowTotalAmount) internal pure returns (uint256)\r\n\t{\r\n\t\tif ((depositTotalAmount == 0) && (borrowTotalAmount == 0))\r\n\t\t{\r\n\t\t\treturn 0;\r\n\t\t}\r\n\r\n\t\treturn borrowTotalAmount.unifiedDiv(depositTotalAmount);\r\n\t}\r\n\r\n\t/**\r\n\t * @dev Get SIR and BIR (internal)\r\n\t * @param depositTotalAmount The amount of total deposit\r\n\t * @param borrowTotalAmount The amount of total borrow\r\n\t * @return (uint256, uin256)\r\n\t */\r\n\tfunction _getSIRandBIR(uint256 depositTotalAmount, uint256 borrowTotalAmount) internal view returns (uint256, uint256)\r\n\t// TODO: update comment(jump rate)\r\n\t{\r\n\t\t/* UtilRate = TotalBorrow / (TotalDeposit + TotalBorrow) */\r\n\t\tuint256 utilRate = _getUtilizationRate(depositTotalAmount, borrowTotalAmount);\r\n\t\tuint256 BIR;\r\n\t\tuint256 _jmpPoint = jumpPoint;\r\n\t\t/* BIR = minimumRate + (UtilRate * liquiditySensitivity) */\r\n\t\tif(utilRate < _jmpPoint) {\r\n\t\t\tBIR = utilRate.unifiedMul(basicSensitivity).add(minRate);\r\n\t\t} else {\r\n      /*\r\n      Formula : BIR = minRate + jumpPoint * basicSensitivity + (utilRate - jumpPoint) * jumpSensitivity\r\n\r\n\t\t\tuint256 _baseBIR = _jmpPoint.unifiedMul(basicSensitivity);\r\n\t\t\tuint256 _jumpBIR = utilRate.sub(_jmpPoint).unifiedMul(jumpSensitivity);\r\n\t\t\tBIR = minRate.add(_baseBIR).add(_jumpBIR);\r\n      */\r\n      BIR = minRate\r\n      .add( _jmpPoint.unifiedMul(basicSensitivity) )\r\n      .add( utilRate.sub(_jmpPoint).unifiedMul(jumpSensitivity) );\r\n\t\t}\r\n\r\n\t\t/* SIR = UtilRate * BIR */\r\n\t\tuint256 SIR = utilRate.unifiedMul(BIR).unifiedMul(spreadRate);\r\n\t\treturn (SIR, BIR);\r\n\t}\r\n\r\n\t/**\r\n\t * @dev Get SIR and BIR per block (internal)\r\n\t * @param depositTotalAmount The amount of total deposit\r\n\t * @param borrowTotalAmount The amount of total borrow\r\n\t * @return (uint256, uin256)\r\n\t */\r\n\tfunction _getSIRandBIRonBlock(uint256 depositTotalAmount, uint256 borrowTotalAmount) internal view returns (uint256, uint256)\r\n\t{\r\n\t\tuint256 SIR;\r\n\t\tuint256 BIR;\r\n\t\t(SIR, BIR) = _getSIRandBIR(depositTotalAmount, borrowTotalAmount);\r\n\t\treturn ( SIR.div(blocksPerYear), BIR.div(blocksPerYear) );\r\n\t}\r\n\r\n\t/**\r\n\t * @dev Calculates the rate of globalEXR (for borrowEXR or depositEXR)\r\n\t * @param actionEXR The rate of actionEXR\r\n\t * @param interestRate The rate of interest\r\n\t * @param delta The interval between user actions (in block)\r\n\t * @return The amount of newGlobalEXR\r\n\t */\r\n\tfunction _getNewGlobalEXR(uint256 actionEXR, uint256 interestRate, uint256 delta) internal pure returns (uint256)\r\n\t{\r\n\t\treturn interestRate.mul(delta).add(unifiedPoint).unifiedMul(actionEXR);\r\n\t}\r\n\r\n\t/**\r\n\t * @dev Calculates difference between globalEXR and userEXR\r\n\t * @param unifiedAmount The unifiedAmount (for fixed decimal number)\r\n\t * @param globalEXR The amount of globalEXR\r\n\t * @param userEXR The amount of userEXR\r\n\t * @return (bool, uint256)\r\n\t */\r\n\tfunction _getDeltaAmount(uint256 unifiedAmount, uint256 globalEXR, uint256 userEXR) internal pure returns (bool, uint256)\r\n\t{\r\n\t\tuint256 deltaEXR;\r\n\t\tbool negativeFlag;\r\n\t\tuint256 deltaAmount;\r\n\t\tif (unifiedAmount != 0)\r\n\t\t{\r\n\t\t\t(negativeFlag, deltaEXR) = _getDeltaEXR(globalEXR, userEXR);\r\n\t\t\tdeltaAmount = unifiedAmount.unifiedMul(deltaEXR);\r\n\t\t}\r\n\r\n\t\treturn (negativeFlag, deltaAmount);\r\n\t}\r\n\r\n\t/**\r\n\t * @dev Calculates the delta EXR between globalEXR and userEXR\r\n\t * @param newGlobalEXR The new globalEXR\r\n\t * @param lastUserEXR The last userEXR\r\n\t * @return (bool, uint256)\r\n\t */\r\n\tfunction _getDeltaEXR(uint256 newGlobalEXR, uint256 lastUserEXR) internal pure returns (bool, uint256)\r\n\t{\r\n\t\tuint256 EXR = newGlobalEXR.unifiedDiv(lastUserEXR);\r\n\t\tif (EXR >= unifiedPoint)\r\n\t\t{\r\n\t\t\treturn ( false, EXR.sub(unifiedPoint) );\r\n\t\t}\r\n\r\n\t\treturn ( true, unifiedPoint.sub(EXR) );\r\n\t}\r\n\r\n\tfunction getMinRate() external view returns (uint256) {\r\n\t\treturn minRate;\r\n\t}\r\n\r\n\tfunction setMinRate(uint256 _minRate) external onlyOperator returns (bool) {\r\n\t\tminRate = _minRate;\r\n\t\treturn true;\r\n\t}\r\n\r\n\tfunction getBasicSensitivity() external view returns (uint256) {\r\n\t\treturn basicSensitivity;\r\n\t}\r\n\r\n\tfunction setBasicSensitivity(uint256 _sensitivity) external onlyOperator returns (bool) {\r\n\t\tbasicSensitivity = _sensitivity;\r\n\t\treturn true;\r\n\t}\r\n\r\n\tfunction getJumpPoint() external view returns (uint256) {\r\n\t\treturn jumpPoint;\r\n\t}\r\n\r\n\tfunction setJumpPoint(uint256 _jumpPoint) external onlyOperator returns (bool) {\r\n\t\tjumpPoint = _jumpPoint;\r\n\t\treturn true;\r\n\t}\r\n\r\n\tfunction getJumpSensitivity() external view returns (uint256) {\r\n\t\treturn jumpSensitivity;\r\n\t}\r\n\r\n\tfunction setJumpSensitivity(uint256 _sensitivity) external onlyOperator returns (bool) {\r\n\t\tjumpSensitivity = _sensitivity;\r\n\t\treturn true;\r\n\t}\r\n\r\n\tfunction getSpreadRate() external view returns (uint256) {\r\n\t\treturn spreadRate;\r\n\t}\r\n\r\n\tfunction setSpreadRate(uint256 _spreadRate) external onlyOperator returns (bool) {\r\n\t\tspreadRate = _spreadRate;\r\n\t\treturn true;\r\n\t}\r\n\tfunction setBlocksPerYear(uint256 _blocksPerYear) external onlyOperator returns (bool) {\r\n\t\tblocksPerYear = _blocksPerYear;\r\n\t\treturn true;\r\n\t}\r\n}"}},"matchId":"13418453","creationMatch":"match","runtimeMatch":"match","verifiedAt":"2026-01-10T09:13:54Z","match":"match","chainId":"1","address":"0x29Ecabde2C57B6D4183f915eBca1A25804A60dB1"}