-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reduce liquidation penalty #157
Changes from 7 commits
9311b08
3fee998
32c3766
c315fdc
3aedd9f
b89f18e
57446c9
78d631f
74cb1b3
81577dc
bbab92a
1d848b7
bcc8344
a49a34e
2de444e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,14 +23,17 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe | |
// --- Connected contract declarations --- | ||
|
||
IERC20 public immutable ETH; | ||
ITroveManager public troveManager; | ||
ITroveManager public immutable troveManager; | ||
address stabilityPoolAddress; | ||
address gasPoolAddress; | ||
ICollSurplusPool collSurplusPool; | ||
IBoldToken public boldToken; | ||
// A doubly linked list of Troves, sorted by their collateral ratios | ||
ISortedTroves public sortedTroves; | ||
|
||
// Minimum collateral ratio for individual troves | ||
uint256 public immutable MCR; | ||
|
||
/* --- Variable container structs --- | ||
|
||
Used to hold, return and assign variables inside a function, in order to avoid the error: | ||
|
@@ -101,15 +104,21 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe | |
); | ||
event BoldBorrowingFeePaid(uint256 indexed _troveId, uint256 _boldFee); | ||
|
||
constructor(address _ETHAddress) { | ||
checkContract(_ETHAddress); | ||
ETH = IERC20(_ETHAddress); | ||
constructor(IERC20 _ETH, ITroveManager _troveManager) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is moving TM into constructor related to the reduced liq penalty, or an independent improvement? (fine if so, just curious) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the reason is to fetch MCR from TroveManager, thus avoiding to define it twice (and making sure it’s consistent). |
||
checkContract(address(_ETH)); | ||
checkContract(address(_troveManager)); | ||
|
||
ETH = _ETH; | ||
troveManager = _troveManager; | ||
|
||
MCR = _troveManager.MCR(); | ||
|
||
emit TroveManagerAddressChanged(address(_troveManager)); | ||
} | ||
|
||
// --- Dependency setters --- | ||
|
||
function setAddresses( | ||
address _troveManagerAddress, | ||
address _activePoolAddress, | ||
address _defaultPoolAddress, | ||
address _stabilityPoolAddress, | ||
|
@@ -122,7 +131,6 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe | |
// This makes impossible to open a trove with zero withdrawn Bold | ||
assert(MIN_NET_DEBT > 0); | ||
|
||
checkContract(_troveManagerAddress); | ||
checkContract(_activePoolAddress); | ||
checkContract(_defaultPoolAddress); | ||
checkContract(_stabilityPoolAddress); | ||
|
@@ -132,7 +140,6 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe | |
checkContract(_sortedTrovesAddress); | ||
checkContract(_boldTokenAddress); | ||
|
||
troveManager = ITroveManager(_troveManagerAddress); | ||
activePool = IActivePool(_activePoolAddress); | ||
defaultPool = IDefaultPool(_defaultPoolAddress); | ||
stabilityPoolAddress = _stabilityPoolAddress; | ||
|
@@ -142,7 +149,6 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe | |
sortedTroves = ISortedTroves(_sortedTrovesAddress); | ||
boldToken = IBoldToken(_boldTokenAddress); | ||
|
||
emit TroveManagerAddressChanged(_troveManagerAddress); | ||
emit ActivePoolAddressChanged(_activePoolAddress); | ||
emit DefaultPoolAddressChanged(_defaultPoolAddress); | ||
emit StabilityPoolAddressChanged(_stabilityPoolAddress); | ||
|
@@ -278,7 +284,7 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe | |
// TODO: Use oldDebt and assert in fuzzing, remove before deployment | ||
uint256 oldDebt = troveManager.getTroveEntireDebt(_troveId); | ||
_adjustTrove(msg.sender, _troveId, 0, false, _boldAmount, false, 0, contractsCache); | ||
assert(troveManager.getTroveEntireDebt(_troveId) < oldDebt); | ||
assert(troveManager.getTroveEntireDebt(_troveId) < oldDebt); | ||
} | ||
|
||
function adjustTrove( | ||
|
@@ -292,12 +298,19 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe | |
ContractsCacheTMAPBT memory contractsCache = ContractsCacheTMAPBT(troveManager, activePool, boldToken); | ||
_requireTroveIsActive(contractsCache.troveManager, _troveId); | ||
_adjustTrove( | ||
msg.sender, _troveId, _collChange, _isCollIncrease, _boldChange, _isDebtIncrease, _maxFeePercentage, contractsCache | ||
msg.sender, | ||
_troveId, | ||
_collChange, | ||
_isCollIncrease, | ||
_boldChange, | ||
_isDebtIncrease, | ||
_maxFeePercentage, | ||
contractsCache | ||
); | ||
} | ||
|
||
function adjustUnredeemableTrove( | ||
uint256 _troveId, | ||
uint256 _troveId, | ||
uint256 _maxFeePercentage, | ||
uint256 _collChange, | ||
bool _isCollIncrease, | ||
|
@@ -308,12 +321,21 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe | |
) external override { | ||
ContractsCacheTMAPBT memory contractsCache = ContractsCacheTMAPBT(troveManager, activePool, boldToken); | ||
_requireTroveIsUnredeemable(contractsCache.troveManager, _troveId); | ||
// TODO: Gas - pass the cached TM down here, since we fetch it again inside _adjustTrove? | ||
// TODO: Gas - pass the cached TM down here, since we fetch it again inside _adjustTrove? | ||
_adjustTrove( | ||
msg.sender, _troveId, _collChange, _isCollIncrease, _boldChange, _isDebtIncrease, _maxFeePercentage, contractsCache | ||
msg.sender, | ||
_troveId, | ||
_collChange, | ||
_isCollIncrease, | ||
_boldChange, | ||
_isDebtIncrease, | ||
_maxFeePercentage, | ||
contractsCache | ||
); | ||
troveManager.setTroveStatusToActive(_troveId); | ||
sortedTroves.insert(_troveId, contractsCache.troveManager.getTroveAnnualInterestRate(_troveId), _upperHint, _lowerHint); | ||
sortedTroves.insert( | ||
_troveId, contractsCache.troveManager.getTroveAnnualInterestRate(_troveId), _upperHint, _lowerHint | ||
); | ||
} | ||
|
||
function adjustTroveInterestRate( | ||
|
@@ -545,11 +567,9 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe | |
/** | ||
* Claim remaining collateral from a redemption or from a liquidation with ICR > MCR in Recovery Mode | ||
bingen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
function claimCollateral(uint256 _troveId) external override { | ||
_requireIsOwner(_troveId); | ||
|
||
function claimCollateral() external override { | ||
// send ETH from CollSurplus Pool to owner | ||
collSurplusPool.claimColl(msg.sender, _troveId); | ||
collSurplusPool.claimColl(msg.sender); | ||
} | ||
|
||
// --- Helper functions --- | ||
|
@@ -632,17 +652,19 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe | |
uint256 _boldChange, | ||
bool _isDebtIncrease | ||
) internal { | ||
if (_isDebtIncrease) { // implies _boldChange > 0 | ||
if (_isDebtIncrease) { | ||
// implies _boldChange > 0 | ||
address borrower = _troveManager.ownerOf(_troveId); | ||
_boldToken.mint(borrower, _boldChange); | ||
} else if (_boldChange > 0 ){ | ||
} else if (_boldChange > 0) { | ||
_boldToken.burn(msg.sender, _boldChange); | ||
} | ||
|
||
if (_isCollIncrease) { // implies _collChange > 0 | ||
if (_isCollIncrease) { | ||
// implies _collChange > 0 | ||
// Pull ETH tokens from sender and move them to the Active Pool | ||
_pullETHAndSendToActivePool(_activePool, _collChange); | ||
} else if (_collChange > 0 ){ | ||
} else if (_collChange > 0) { | ||
address borrower = _troveManager.ownerOf(_troveId); | ||
// Pull ETH from Active Pool and decrease its recorded ETH balance | ||
_activePool.sendETH(borrower, _collChange); | ||
|
@@ -709,11 +731,13 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe | |
} | ||
|
||
function _requireTroveIsUnredeemable(ITroveManager _troveManager, uint256 _troveId) internal view { | ||
require(_troveManager.checkTroveIsUnredeemable(_troveId), "BorrowerOps: Trove does not have unredeemable status"); | ||
require( | ||
_troveManager.checkTroveIsUnredeemable(_troveId), "BorrowerOps: Trove does not have unredeemable status" | ||
); | ||
} | ||
|
||
function _requireTroveIsNotOpen(ITroveManager _troveManager, uint256 _troveId) internal view { | ||
require(!_troveManager.checkTroveIsOpen(_troveId),"BorrowerOps: Trove is open"); | ||
function _requireTroveIsNotOpen(ITroveManager _troveManager, uint256 _troveId) internal view { | ||
require(!_troveManager.checkTroveIsOpen(_troveId), "BorrowerOps: Trove is open"); | ||
} | ||
|
||
function _requireNonZeroCollChange(uint256 _collChange) internal pure { | ||
|
@@ -770,7 +794,7 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe | |
} | ||
} | ||
|
||
function _requireICRisAboveMCR(uint256 _newICR) internal pure { | ||
function _requireICRisAboveMCR(uint256 _newICR) internal view { | ||
require(_newICR >= MCR, "BorrowerOps: An operation that would result in ICR < MCR is not permitted"); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use a constant here - it would save (a bit) of gas when we read the MCR value right?
Though I guess this approach makes deployment more robust as we can pass those Trove params.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, specially because we plan to have different MCRs for different collaterals.