-
Notifications
You must be signed in to change notification settings - Fork 11
/
EbtcBase.sol
145 lines (115 loc) · 5.79 KB
/
EbtcBase.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import "./BaseMath.sol";
import "./EbtcMath.sol";
import "../Interfaces/IActivePool.sol";
import "../Interfaces/IPriceFeed.sol";
import "../Interfaces/IEbtcBase.sol";
import "../Dependencies/ICollateralToken.sol";
/*
* Base contract for CdpManager, BorrowerOperations. Contains global system constants and
* common functions.
*/
contract EbtcBase is BaseMath, IEbtcBase {
// Collateral Ratio applied for Liquidation Incentive
// i.e., liquidator repay $1 worth of debt to get back $1.03 worth of collateral
uint256 public constant LICR = 1030000000000000000; // 103%
// Minimum collateral ratio for individual cdps
uint256 public constant MCR = 1100000000000000000; // 110%
// Critical system collateral ratio. If the system's total collateral ratio (TCR) falls below the CCR, Recovery Mode is triggered.
uint256 public constant CCR = 1250000000000000000; // 125%
// Amount of stETH collateral to be locked in active pool on opening cdps
uint256 public constant LIQUIDATOR_REWARD = 2e17;
// Minimum amount of stETH collateral a CDP must have
uint256 public constant MIN_NET_STETH_BALANCE = 2e18;
uint256 public constant PERCENT_DIVISOR = 200; // dividing by 200 yields 0.5%
uint256 public constant BORROWING_FEE_FLOOR = 0; // 0.5%
uint256 public constant STAKING_REWARD_SPLIT = 5_000; // taking 50% cut from staking reward
uint256 public constant MAX_REWARD_SPLIT = 10_000;
IActivePool public immutable activePool;
IPriceFeed public immutable override priceFeed;
// the only collateral token allowed in CDP
ICollateralToken public immutable collateral;
/// @notice Initializes the contract with the provided addresses
/// @param _activePoolAddress The address of the ActivePool contract
/// @param _priceFeedAddress The address of the PriceFeed contract
/// @param _collateralAddress The address of the CollateralToken contract
constructor(address _activePoolAddress, address _priceFeedAddress, address _collateralAddress) {
activePool = IActivePool(_activePoolAddress);
priceFeed = IPriceFeed(_priceFeedAddress);
collateral = ICollateralToken(_collateralAddress);
}
// --- Gas compensation functions ---
function _calcNetStEthBalance(uint256 _stEthBalance) internal pure returns (uint256) {
return _stEthBalance - LIQUIDATOR_REWARD;
}
/// @notice Get the entire system collateral
/// @notice Entire system collateral = collateral allocated to system in ActivePool, using it's internal accounting
/// @dev Collateral tokens stored in ActivePool for liquidator rewards, fees, or coll in CollSurplusPool, are not included
function getSystemCollShares() public view returns (uint256 entireSystemColl) {
return (activePool.getSystemCollShares());
}
/**
@notice Get the entire system debt
@notice Entire system collateral = collateral stored in ActivePool, using their internal accounting
*/
function _getSystemDebt() internal view returns (uint256 entireSystemDebt) {
return (activePool.getSystemDebt());
}
function _getCachedTCR(uint256 _price) internal view returns (uint256 TCR) {
(TCR, , ) = _getTCRWithSystemDebtAndCollShares(_price);
}
function _getTCRWithSystemDebtAndCollShares(
uint256 _price
) internal view returns (uint256 TCR, uint256 _coll, uint256 _debt) {
uint256 systemCollShares = getSystemCollShares();
uint256 systemDebt = _getSystemDebt();
uint256 _systemStEthBalance = collateral.getPooledEthByShares(systemCollShares);
TCR = EbtcMath._computeCR(_systemStEthBalance, systemDebt, _price);
return (TCR, systemCollShares, systemDebt);
}
function _checkRecoveryMode(uint256 _price) internal view returns (bool) {
return _checkRecoveryModeForTCR(_getCachedTCR(_price));
}
function _checkRecoveryModeForTCR(uint256 _tcr) internal view returns (bool) {
return _tcr < CCR;
}
function _requireUserAcceptsFee(
uint256 _fee,
uint256 _amount,
uint256 _maxFeePercentage
) internal pure {
uint256 feePercentage = (_fee * DECIMAL_PRECISION) / _amount;
require(feePercentage <= _maxFeePercentage, "Fee exceeded provided maximum");
}
// Convert debt denominated in ETH to debt denominated in BTC given that _price is ETH/BTC
// _debt is denominated in ETH
// _price is ETH/BTC
function _convertDebtDenominationToBtc(
uint256 _debt,
uint256 _price
) internal pure returns (uint256) {
return (_debt * _price) / DECIMAL_PRECISION;
}
/// @dev return true if given ICR is qualified for liquidation compared to configured threshold
/// @dev this function ONLY checks numbers not check grace period switch for Recovery Mode
function _checkICRAgainstLiqThreshold(uint256 _icr, uint _tcr) internal view returns (bool) {
// Either undercollateralized
// OR, it's RM AND they meet the requirement
// Swapped Requirement && RM to save gas
return
_checkICRAgainstMCR(_icr) ||
(_checkICRAgainstTCR(_icr, _tcr) && _checkRecoveryModeForTCR(_tcr));
}
/// @dev return true if given ICR is qualified for liquidation compared to MCR
function _checkICRAgainstMCR(uint256 _icr) internal view returns (bool) {
return _icr < MCR;
}
/// @dev return true if given ICR is qualified for liquidation compared to TCR
/// @dev typically used in Recovery Mode
function _checkICRAgainstTCR(uint256 _icr, uint _tcr) internal view returns (bool) {
/// @audit is _icr <= _tcr more dangerous for overal system safety?
/// @audit Should we use _icr < CCR to allow any risky CDP being liquidated?
return _icr <= _tcr;
}
}