编译器
0.8.17+commit.8df45f5f
文件 1 的 33:AuthNoOwner.sol
pragma solidity 0.8.17;
import {Authority} from "./Authority.sol";
contract AuthNoOwner {
event AuthorityUpdated(address indexed user, Authority indexed newAuthority);
Authority private _authority;
bool private _authorityInitialized;
modifier requiresAuth() virtual {
require(isAuthorized(msg.sender, msg.sig), "Auth: UNAUTHORIZED");
_;
}
function authority() public view returns (Authority) {
return _authority;
}
function authorityInitialized() public view returns (bool) {
return _authorityInitialized;
}
function isAuthorized(address user, bytes4 functionSig) internal view virtual returns (bool) {
Authority auth = _authority;
return (address(auth) != address(0) && auth.canCall(user, address(this), functionSig));
}
function _initializeAuthority(address newAuthority) internal {
require(address(_authority) == address(0), "Auth: authority is non-zero");
require(!_authorityInitialized, "Auth: authority already initialized");
_authority = Authority(newAuthority);
_authorityInitialized = true;
emit AuthorityUpdated(address(this), Authority(newAuthority));
}
}
文件 2 的 33:Authority.sol
pragma solidity 0.8.17;
interface Authority {
function canCall(address user, address target, bytes4 functionSig) external view returns (bool);
}
文件 3 的 33:BaseMath.sol
pragma solidity 0.8.17;
contract BaseMath {
uint256 public constant DECIMAL_PRECISION = 1e18;
}
文件 4 的 33:BorrowerOperations.sol
pragma solidity 0.8.17;
import "./Interfaces/IBorrowerOperations.sol";
import "./Interfaces/ICdpManager.sol";
import "./Interfaces/ICdpManagerData.sol";
import "./Interfaces/IEBTCToken.sol";
import "./Interfaces/ICollSurplusPool.sol";
import "./Interfaces/ISortedCdps.sol";
import "./Dependencies/EbtcBase.sol";
import "./Dependencies/ReentrancyGuard.sol";
import "./Dependencies/Ownable.sol";
import "./Dependencies/AuthNoOwner.sol";
import "./Dependencies/ERC3156FlashLender.sol";
import "./Dependencies/PermitNonce.sol";
contract BorrowerOperations is
EbtcBase,
ReentrancyGuard,
IBorrowerOperations,
ERC3156FlashLender,
AuthNoOwner,
PermitNonce
{
string public constant NAME = "BorrowerOperations";
bytes32 private constant _PERMIT_POSITION_MANAGER_TYPEHASH =
keccak256(
"PermitPositionManagerApproval(address borrower,address positionManager,uint8 status,uint256 nonce,uint256 deadline)"
);
bytes32 private constant _TYPE_HASH =
0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;
string internal constant _VERSION = "1";
bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
uint256 private immutable _CACHED_CHAIN_ID;
bytes32 private immutable _HASHED_NAME;
bytes32 private immutable _HASHED_VERSION;
ICdpManager public immutable cdpManager;
ICollSurplusPool public immutable collSurplusPool;
address public immutable feeRecipientAddress;
IEBTCToken public immutable ebtcToken;
ISortedCdps public immutable sortedCdps;
mapping(address => mapping(address => PositionManagerApproval)) public positionManagers;
struct AdjustCdpLocals {
uint256 price;
uint256 collSharesChange;
uint256 netDebtChange;
bool isCollIncrease;
uint256 debt;
uint256 collShares;
uint256 oldICR;
uint256 newICR;
uint256 newTCR;
uint256 newDebt;
uint256 newCollShares;
uint256 stake;
}
struct OpenCdpLocals {
uint256 price;
uint256 debt;
uint256 netStEthBalance;
uint256 ICR;
uint256 NICR;
uint256 stake;
}
struct MoveTokensParams {
address user;
uint256 collSharesChange;
uint256 collAddUnderlying;
bool isCollIncrease;
uint256 netDebtChange;
bool isDebtIncrease;
}
constructor(
address _cdpManagerAddress,
address _activePoolAddress,
address _collSurplusPoolAddress,
address _priceFeedAddress,
address _sortedCdpsAddress,
address _ebtcTokenAddress,
address _feeRecipientAddress,
address _collTokenAddress
) EbtcBase(_activePoolAddress, _priceFeedAddress, _collTokenAddress) {
cdpManager = ICdpManager(_cdpManagerAddress);
collSurplusPool = ICollSurplusPool(_collSurplusPoolAddress);
sortedCdps = ISortedCdps(_sortedCdpsAddress);
ebtcToken = IEBTCToken(_ebtcTokenAddress);
feeRecipientAddress = _feeRecipientAddress;
address _authorityAddress = address(AuthNoOwner(_cdpManagerAddress).authority());
if (_authorityAddress != address(0)) {
_initializeAuthority(_authorityAddress);
}
bytes32 hashedName = keccak256(bytes(NAME));
bytes32 hashedVersion = keccak256(bytes(_VERSION));
_HASHED_NAME = hashedName;
_HASHED_VERSION = hashedVersion;
_CACHED_CHAIN_ID = _chainID();
_CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(_TYPE_HASH, hashedName, hashedVersion);
}
modifier nonReentrantSelfAndCdpM() {
require(locked == OPEN, "BorrowerOperations: Reentrancy in nonReentrant call");
require(
ReentrancyGuard(address(cdpManager)).locked() == OPEN,
"CdpManager: Reentrancy in nonReentrant call"
);
locked = LOCKED;
_;
locked = OPEN;
}
function openCdp(
uint256 _debt,
bytes32 _upperHint,
bytes32 _lowerHint,
uint256 _stEthBalance
) external override nonReentrantSelfAndCdpM returns (bytes32) {
return _openCdp(_debt, _upperHint, _lowerHint, _stEthBalance, msg.sender);
}
function openCdpFor(
uint256 _debt,
bytes32 _upperHint,
bytes32 _lowerHint,
uint256 _stEthBalance,
address _borrower
) external override nonReentrantSelfAndCdpM returns (bytes32) {
return _openCdp(_debt, _upperHint, _lowerHint, _stEthBalance, _borrower);
}
function addColl(
bytes32 _cdpId,
bytes32 _upperHint,
bytes32 _lowerHint,
uint256 _stEthBalanceIncrease
) external override nonReentrantSelfAndCdpM {
_adjustCdpInternal(_cdpId, 0, 0, false, _upperHint, _lowerHint, _stEthBalanceIncrease);
}
function withdrawColl(
bytes32 _cdpId,
uint256 _stEthBalanceDecrease,
bytes32 _upperHint,
bytes32 _lowerHint
) external override nonReentrantSelfAndCdpM {
_adjustCdpInternal(_cdpId, _stEthBalanceDecrease, 0, false, _upperHint, _lowerHint, 0);
}
function withdrawDebt(
bytes32 _cdpId,
uint256 _debt,
bytes32 _upperHint,
bytes32 _lowerHint
) external override nonReentrantSelfAndCdpM {
_adjustCdpInternal(_cdpId, 0, _debt, true, _upperHint, _lowerHint, 0);
}
function repayDebt(
bytes32 _cdpId,
uint256 _debt,
bytes32 _upperHint,
bytes32 _lowerHint
) external override nonReentrantSelfAndCdpM {
_adjustCdpInternal(_cdpId, 0, _debt, false, _upperHint, _lowerHint, 0);
}
function adjustCdp(
bytes32 _cdpId,
uint256 _stEthBalanceDecrease,
uint256 _debtChange,
bool _isDebtIncrease,
bytes32 _upperHint,
bytes32 _lowerHint
) external override nonReentrantSelfAndCdpM {
_adjustCdpInternal(
_cdpId,
_stEthBalanceDecrease,
_debtChange,
_isDebtIncrease,
_upperHint,
_lowerHint,
0
);
}
function adjustCdpWithColl(
bytes32 _cdpId,
uint256 _stEthBalanceDecrease,
uint256 _debtChange,
bool _isDebtIncrease,
bytes32 _upperHint,
bytes32 _lowerHint,
uint256 _stEthBalanceIncrease
) external override nonReentrantSelfAndCdpM {
_adjustCdpInternal(
_cdpId,
_stEthBalanceDecrease,
_debtChange,
_isDebtIncrease,
_upperHint,
_lowerHint,
_stEthBalanceIncrease
);
}
function _adjustCdpInternal(
bytes32 _cdpId,
uint256 _stEthBalanceDecrease,
uint256 _debtChange,
bool _isDebtIncrease,
bytes32 _upperHint,
bytes32 _lowerHint,
uint256 _stEthBalanceIncrease
) internal {
address _borrower = sortedCdps.getOwnerAddress(_cdpId);
_requireBorrowerOrPositionManagerAndUpdateManagerApproval(_borrower);
_requireCdpisActive(cdpManager, _cdpId);
cdpManager.syncAccounting(_cdpId);
AdjustCdpLocals memory vars;
vars.price = priceFeed.fetchPrice();
if (_isDebtIncrease) {
_requireMinDebtChange(_debtChange);
} else {
_requireZeroOrMinAdjustment(_debtChange);
}
_requireSingularCollChange(_stEthBalanceIncrease, _stEthBalanceDecrease);
_requireNonZeroAdjustment(_stEthBalanceIncrease, _stEthBalanceDecrease, _debtChange);
_requireZeroOrMinAdjustment(_stEthBalanceIncrease);
_requireZeroOrMinAdjustment(_stEthBalanceDecrease);
(vars.collSharesChange, vars.isCollIncrease) = _getCollSharesChangeFromStEthChange(
_stEthBalanceIncrease,
_stEthBalanceDecrease
);
vars.netDebtChange = _debtChange;
vars.debt = cdpManager.getCdpDebt(_cdpId);
vars.collShares = cdpManager.getCdpCollShares(_cdpId);
uint256 _cdpStEthBalance = collateral.getPooledEthByShares(vars.collShares);
require(
_stEthBalanceDecrease <= _cdpStEthBalance,
"BorrowerOperations: Cannot withdraw greater stEthBalance than the value in Cdp"
);
vars.oldICR = EbtcMath._computeCR(_cdpStEthBalance, vars.debt, vars.price);
vars.newICR = _getNewICRFromCdpChange(
vars.collShares,
vars.debt,
vars.collSharesChange,
vars.isCollIncrease,
vars.netDebtChange,
_isDebtIncrease,
vars.price
);
bool isRecoveryMode = _checkRecoveryModeForTCR(_getCachedTCR(vars.price));
_requireValidAdjustmentInCurrentMode(
isRecoveryMode,
_stEthBalanceDecrease,
_isDebtIncrease,
vars
);
if (!_isDebtIncrease && _debtChange > 0) {
_requireValidDebtRepayment(vars.debt, vars.netDebtChange);
_requireSufficientEbtcTokenBalance(msg.sender, vars.netDebtChange);
_requireMinDebt(vars.debt - vars.netDebtChange);
}
(vars.newCollShares, vars.newDebt) = _getNewCdpAmounts(
vars.collShares,
vars.debt,
vars.collSharesChange,
vars.isCollIncrease,
vars.netDebtChange,
_isDebtIncrease
);
_requireMinDebt(vars.newDebt);
_requireAtLeastMinNetStEthBalance(collateral.getPooledEthByShares(vars.newCollShares));
cdpManager.updateCdp(
_cdpId,
_borrower,
vars.collShares,
vars.debt,
vars.newCollShares,
vars.newDebt
);
{
uint256 newNICR = _getNewNominalICRFromCdpChange(vars, _isDebtIncrease);
sortedCdps.reInsert(_cdpId, newNICR, _upperHint, _lowerHint);
}
{
MoveTokensParams memory _varMvTokens = MoveTokensParams(
msg.sender,
vars.collSharesChange,
(vars.isCollIncrease ? _stEthBalanceIncrease : 0),
vars.isCollIncrease,
_debtChange,
_isDebtIncrease
);
_processTokenMovesFromAdjustment(_varMvTokens);
}
}
function _openCdp(
uint256 _debt,
bytes32 _upperHint,
bytes32 _lowerHint,
uint256 _stEthBalance,
address _borrower
) internal returns (bytes32) {
_requireMinDebt(_debt);
_requireBorrowerOrPositionManagerAndUpdateManagerApproval(_borrower);
OpenCdpLocals memory vars;
vars.netStEthBalance = _calcNetStEthBalance(_stEthBalance);
_requireAtLeastMinNetStEthBalance(vars.netStEthBalance);
cdpManager.syncGlobalAccounting();
vars.price = priceFeed.fetchPrice();
vars.debt = _debt;
require(vars.netStEthBalance > 0, "BorrowerOperations: zero collateral for openCdp()!");
uint256 _netCollAsShares = collateral.getSharesByPooledEth(vars.netStEthBalance);
uint256 _liquidatorRewardShares = collateral.getSharesByPooledEth(LIQUIDATOR_REWARD);
vars.ICR = EbtcMath._computeCR(vars.netStEthBalance, vars.debt, vars.price);
vars.NICR = EbtcMath._computeNominalCR(_netCollAsShares, vars.debt);
bool isRecoveryMode = _checkRecoveryModeForTCR(_getCachedTCR(vars.price));
uint256 newTCR = _getNewTCRFromCdpChange(
vars.netStEthBalance,
true,
vars.debt,
true,
vars.price
);
if (isRecoveryMode) {
_requireICRisNotBelowCCR(vars.ICR);
if (newTCR < CCR) {
cdpManager.notifyStartGracePeriod(newTCR);
} else {
cdpManager.notifyEndGracePeriod(newTCR);
}
} else {
_requireICRisNotBelowMCR(vars.ICR);
_requireNewTCRisNotBelowCCR(newTCR);
cdpManager.notifyEndGracePeriod(newTCR);
}
bytes32 _cdpId = sortedCdps.insert(_borrower, vars.NICR, _upperHint, _lowerHint);
_requireCdpIsNonExistent(_cdpId);
cdpManager.initializeCdp(
_cdpId,
vars.debt,
_netCollAsShares,
_liquidatorRewardShares,
_borrower
);
_withdrawDebt(msg.sender, _debt);
_activePoolAddColl(_stEthBalance, _netCollAsShares);
require(
vars.netStEthBalance + LIQUIDATOR_REWARD == _stEthBalance,
"BorrowerOperations: deposited collateral mismatch!"
);
return _cdpId;
}
function closeCdp(bytes32 _cdpId) external override {
address _borrower = sortedCdps.getOwnerAddress(_cdpId);
_requireBorrowerOrPositionManagerAndUpdateManagerApproval(_borrower);
_requireCdpisActive(cdpManager, _cdpId);
cdpManager.syncAccounting(_cdpId);
uint256 price = priceFeed.fetchPrice();
_requireNotInRecoveryMode(_getCachedTCR(price));
uint256 collShares = cdpManager.getCdpCollShares(_cdpId);
uint256 debt = cdpManager.getCdpDebt(_cdpId);
uint256 liquidatorRewardShares = cdpManager.getCdpLiquidatorRewardShares(_cdpId);
_requireSufficientEbtcTokenBalance(msg.sender, debt);
uint256 newTCR = _getNewTCRFromCdpChange(
collateral.getPooledEthByShares(collShares),
false,
debt,
false,
price
);
_requireNewTCRisNotBelowCCR(newTCR);
cdpManager.notifyEndGracePeriod(newTCR);
cdpManager.closeCdp(_cdpId, _borrower, debt, collShares);
_repayDebt(msg.sender, debt);
activePool.transferSystemCollSharesAndLiquidatorReward(
msg.sender,
collShares,
liquidatorRewardShares
);
}
function claimSurplusCollShares() external override {
collSurplusPool.claimSurplusCollShares(msg.sender);
}
function getPositionManagerApproval(
address _borrower,
address _positionManager
) external view override returns (PositionManagerApproval) {
return _getPositionManagerApproval(_borrower, _positionManager);
}
function _getPositionManagerApproval(
address _borrower,
address _positionManager
) internal view returns (PositionManagerApproval) {
return positionManagers[_borrower][_positionManager];
}
function setPositionManagerApproval(
address _positionManager,
PositionManagerApproval _approval
) external override {
_setPositionManagerApproval(msg.sender, _positionManager, _approval);
}
function _setPositionManagerApproval(
address _borrower,
address _positionManager,
PositionManagerApproval _approval
) internal {
positionManagers[_borrower][_positionManager] = _approval;
emit PositionManagerApprovalSet(_borrower, _positionManager, _approval);
}
function revokePositionManagerApproval(address _positionManager) external override {
_setPositionManagerApproval(msg.sender, _positionManager, PositionManagerApproval.None);
}
function renouncePositionManagerApproval(address _borrower) external override {
_setPositionManagerApproval(_borrower, msg.sender, PositionManagerApproval.None);
}
function DOMAIN_SEPARATOR() external view returns (bytes32) {
return domainSeparator();
}
function domainSeparator() public view override returns (bytes32) {
if (_chainID() == _CACHED_CHAIN_ID) {
return _CACHED_DOMAIN_SEPARATOR;
} else {
return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
}
}
function _chainID() private view returns (uint256) {
return block.chainid;
}
function _buildDomainSeparator(
bytes32 typeHash,
bytes32 name,
bytes32 version
) private view returns (bytes32) {
return keccak256(abi.encode(typeHash, name, version, _chainID(), address(this)));
}
function version() external pure override returns (string memory) {
return _VERSION;
}
function permitTypeHash() external pure override returns (bytes32) {
return _PERMIT_POSITION_MANAGER_TYPEHASH;
}
function permitPositionManagerApproval(
address _borrower,
address _positionManager,
PositionManagerApproval _approval,
uint256 _deadline,
uint8 v,
bytes32 r,
bytes32 s
) external override {
require(_deadline >= block.timestamp, "BorrowerOperations: Position manager permit expired");
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
domainSeparator(),
keccak256(
abi.encode(
_PERMIT_POSITION_MANAGER_TYPEHASH,
_borrower,
_positionManager,
_approval,
_nonces[_borrower]++,
_deadline
)
)
)
);
address recoveredAddress = ecrecover(digest, v, r, s);
require(
recoveredAddress != address(0) && recoveredAddress == _borrower,
"BorrowerOperations: Invalid signature"
);
_setPositionManagerApproval(_borrower, _positionManager, _approval);
}
function _getCollSharesChangeFromStEthChange(
uint256 _collReceived,
uint256 _requestedCollWithdrawal
) internal view returns (uint256 collSharesChange, bool isCollIncrease) {
if (_collReceived != 0) {
collSharesChange = collateral.getSharesByPooledEth(_collReceived);
isCollIncrease = true;
} else {
collSharesChange = collateral.getSharesByPooledEth(_requestedCollWithdrawal);
}
}
function _processTokenMovesFromAdjustment(MoveTokensParams memory _varMvTokens) internal {
if (_varMvTokens.isDebtIncrease) {
_withdrawDebt(_varMvTokens.user, _varMvTokens.netDebtChange);
} else {
_repayDebt(_varMvTokens.user, _varMvTokens.netDebtChange);
}
if (_varMvTokens.isCollIncrease) {
_activePoolAddColl(_varMvTokens.collAddUnderlying, _varMvTokens.collSharesChange);
} else {
activePool.transferSystemCollShares(_varMvTokens.user, _varMvTokens.collSharesChange);
}
}
function _activePoolAddColl(uint256 _stEthBalance, uint256 _sharesToTrack) internal {
collateral.transferFrom(msg.sender, address(activePool), _stEthBalance);
activePool.increaseSystemCollShares(_sharesToTrack);
}
function _withdrawDebt(address _account, uint256 _debt) internal {
activePool.increaseSystemDebt(_debt);
ebtcToken.mint(_account, _debt);
}
function _repayDebt(address _account, uint256 _debt) internal {
activePool.decreaseSystemDebt(_debt);
ebtcToken.burn(_account, _debt);
}
function _requireSingularCollChange(
uint256 _stEthBalanceIncrease,
uint256 _stEthBalanceDecrease
) internal pure {
require(
_stEthBalanceIncrease == 0 || _stEthBalanceDecrease == 0,
"BorrowerOperations: Cannot add and withdraw collateral in same operation"
);
}
function _requireNonZeroAdjustment(
uint256 _stEthBalanceIncrease,
uint256 _debtChange,
uint256 _stEthBalanceDecrease
) internal pure {
require(
_stEthBalanceIncrease > 0 || _stEthBalanceDecrease > 0 || _debtChange > 0,
"BorrowerOperations: There must be either a collateral or debt change"
);
}
function _requireZeroOrMinAdjustment(uint256 _change) internal pure {
require(
_change == 0 || _change >= MIN_CHANGE,
"BorrowerOperations: Collateral or debt change must be zero or above min"
);
}
function _requireCdpisActive(ICdpManager _cdpManager, bytes32 _cdpId) internal view {
uint256 status = _cdpManager.getCdpStatus(_cdpId);
require(status == 1, "BorrowerOperations: Cdp does not exist or is closed");
}
function _requireCdpIsNonExistent(bytes32 _cdpId) internal view {
uint status = cdpManager.getCdpStatus(_cdpId);
require(status == 0, "BorrowerOperations: Cdp is active or has been previously closed");
}
function _requireMinDebtChange(uint _debtChange) internal pure {
require(
_debtChange >= MIN_CHANGE,
"BorrowerOperations: Debt increase requires min debtChange"
);
}
function _requireNotInRecoveryMode(uint256 _tcr) internal view {
require(
!_checkRecoveryModeForTCR(_tcr),
"BorrowerOperations: Operation not permitted during Recovery Mode"
);
}
function _requireNoStEthBalanceDecrease(uint256 _stEthBalanceDecrease) internal pure {
require(
_stEthBalanceDecrease == 0,
"BorrowerOperations: Collateral withdrawal not permitted during Recovery Mode"
);
}
function _requireValidAdjustmentInCurrentMode(
bool _isRecoveryMode,
uint256 _stEthBalanceDecrease,
bool _isDebtIncrease,
AdjustCdpLocals memory _vars
) internal {
_vars.newTCR = _getNewTCRFromCdpChange(
collateral.getPooledEthByShares(_vars.collSharesChange),
_vars.isCollIncrease,
_vars.netDebtChange,
_isDebtIncrease,
_vars.price
);
if (_isRecoveryMode) {
_requireNoStEthBalanceDecrease(_stEthBalanceDecrease);
if (_isDebtIncrease) {
_requireICRisNotBelowCCR(_vars.newICR);
_requireNoDecreaseOfICR(_vars.newICR, _vars.oldICR);
}
if (_vars.newTCR < CCR) {
cdpManager.notifyStartGracePeriod(_vars.newTCR);
} else {
cdpManager.notifyEndGracePeriod(_vars.newTCR);
}
} else {
_requireICRisNotBelowMCR(_vars.newICR);
_requireNewTCRisNotBelowCCR(_vars.newTCR);
cdpManager.notifyEndGracePeriod(_vars.newTCR);
}
}
function _requireICRisNotBelowMCR(uint256 _newICR) internal pure {
require(
_newICR >= MCR,
"BorrowerOperations: An operation that would result in ICR < MCR is not permitted"
);
}
function _requireICRisNotBelowCCR(uint256 _newICR) internal pure {
require(_newICR >= CCR, "BorrowerOperations: Operation must leave cdp with ICR >= CCR");
}
function _requireNoDecreaseOfICR(uint256 _newICR, uint256 _oldICR) internal pure {
require(
_newICR >= _oldICR,
"BorrowerOperations: Cannot decrease your Cdp's ICR in Recovery Mode"
);
}
function _requireNewTCRisNotBelowCCR(uint256 _newTCR) internal pure {
require(
_newTCR >= CCR,
"BorrowerOperations: An operation that would result in TCR < CCR is not permitted"
);
}
function _requireMinDebt(uint256 _debt) internal pure {
require(_debt >= MIN_CHANGE, "BorrowerOperations: Debt must be above min");
}
function _requireAtLeastMinNetStEthBalance(uint256 _stEthBalance) internal pure {
require(
_stEthBalance >= MIN_NET_STETH_BALANCE,
"BorrowerOperations: Cdp's net stEth balance must not fall below minimum"
);
}
function _requireValidDebtRepayment(uint256 _currentDebt, uint256 _debtRepayment) internal pure {
require(
_debtRepayment <= _currentDebt,
"BorrowerOperations: Amount repaid must not be larger than the Cdp's debt"
);
}
function _requireSufficientEbtcTokenBalance(
address _account,
uint256 _debtRepayment
) internal view {
require(
ebtcToken.balanceOf(_account) >= _debtRepayment,
"BorrowerOperations: Caller doesnt have enough eBTC to make repayment"
);
}
function _requireBorrowerOrPositionManagerAndUpdateManagerApproval(address _borrower) internal {
if (_borrower == msg.sender) {
return;
}
PositionManagerApproval _approval = _getPositionManagerApproval(_borrower, msg.sender);
require(
_approval != PositionManagerApproval.None,
"BorrowerOperations: Only borrower account or approved position manager can OpenCdp on borrower's behalf"
);
if (_approval == PositionManagerApproval.OneTime) {
_setPositionManagerApproval(_borrower, msg.sender, PositionManagerApproval.None);
}
}
function _getNewNominalICRFromCdpChange(
AdjustCdpLocals memory vars,
bool _isDebtIncrease
) internal pure returns (uint256) {
(uint256 newCollShares, uint256 newDebt) = _getNewCdpAmounts(
vars.collShares,
vars.debt,
vars.collSharesChange,
vars.isCollIncrease,
vars.netDebtChange,
_isDebtIncrease
);
uint256 newNICR = EbtcMath._computeNominalCR(newCollShares, newDebt);
return newNICR;
}
function _getNewICRFromCdpChange(
uint256 _collShares,
uint256 _debt,
uint256 _collSharesChange,
bool _isCollIncrease,
uint256 _debtChange,
bool _isDebtIncrease,
uint256 _price
) internal view returns (uint256) {
(uint256 newCollShares, uint256 newDebt) = _getNewCdpAmounts(
_collShares,
_debt,
_collSharesChange,
_isCollIncrease,
_debtChange,
_isDebtIncrease
);
uint256 newICR = EbtcMath._computeCR(
collateral.getPooledEthByShares(newCollShares),
newDebt,
_price
);
return newICR;
}
function _getNewCdpAmounts(
uint256 _collShares,
uint256 _debt,
uint256 _collSharesChange,
bool _isCollIncrease,
uint256 _debtChange,
bool _isDebtIncrease
) internal pure returns (uint256, uint256) {
uint256 newCollShares = _collShares;
uint256 newDebt = _debt;
newCollShares = _isCollIncrease
? _collShares + _collSharesChange
: _collShares - _collSharesChange;
newDebt = _isDebtIncrease ? _debt + _debtChange : _debt - _debtChange;
return (newCollShares, newDebt);
}
function _getNewTCRFromCdpChange(
uint256 _stEthBalanceChange,
bool _isCollIncrease,
uint256 _debtChange,
bool _isDebtIncrease,
uint256 _price
) internal view returns (uint256) {
uint256 _systemCollShares = getSystemCollShares();
uint256 systemStEthBalance = collateral.getPooledEthByShares(_systemCollShares);
uint256 systemDebt = _getSystemDebt();
systemStEthBalance = _isCollIncrease
? systemStEthBalance + _stEthBalanceChange
: systemStEthBalance - _stEthBalanceChange;
systemDebt = _isDebtIncrease ? systemDebt + _debtChange : systemDebt - _debtChange;
uint256 newTCR = EbtcMath._computeCR(systemStEthBalance, systemDebt, _price);
return newTCR;
}
function flashLoan(
IERC3156FlashBorrower receiver,
address token,
uint256 amount,
bytes calldata data
) external override returns (bool) {
require(amount > 0, "BorrowerOperations: 0 Amount");
uint256 fee = flashFee(token, amount);
require(amount <= maxFlashLoan(token), "BorrowerOperations: Too much");
ebtcToken.mint(address(receiver), amount);
require(
receiver.onFlashLoan(msg.sender, token, amount, fee, data) == FLASH_SUCCESS_VALUE,
"IERC3156: Callback failed"
);
ebtcToken.transferFrom(address(receiver), feeRecipientAddress, fee + amount);
ebtcToken.burn(feeRecipientAddress, amount);
emit FlashLoanSuccess(address(receiver), token, amount, fee);
return true;
}
function flashFee(address token, uint256 amount) public view override returns (uint256) {
require(token == address(ebtcToken), "BorrowerOperations: EBTC Only");
require(!flashLoansPaused, "BorrowerOperations: Flash Loans Paused");
return (amount * feeBps) / MAX_BPS;
}
function maxFlashLoan(address token) public view override returns (uint256) {
if (token != address(ebtcToken)) {
return 0;
}
if (flashLoansPaused) {
return 0;
}
return type(uint112).max;
}
function setFeeBps(uint256 _newFee) external requiresAuth {
require(_newFee <= MAX_FEE_BPS, "ERC3156FlashLender: _newFee should <= MAX_FEE_BPS");
cdpManager.syncGlobalAccounting();
uint256 _oldFee = feeBps;
feeBps = uint16(_newFee);
emit FlashFeeSet(msg.sender, _oldFee, _newFee);
}
function setFlashLoansPaused(bool _paused) external requiresAuth {
cdpManager.syncGlobalAccounting();
flashLoansPaused = _paused;
emit FlashLoansPaused(msg.sender, _paused);
}
}
文件 5 的 33:Context.sol
pragma solidity 0.8.17;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 6 的 33:ERC3156FlashLender.sol
pragma solidity 0.8.17;
import "../Interfaces/IERC3156FlashLender.sol";
import "../Interfaces/IWETH.sol";
abstract contract ERC3156FlashLender is IERC3156FlashLender {
uint256 public constant MAX_BPS = 10_000;
uint256 public constant MAX_FEE_BPS = 1_000;
bytes32 public constant FLASH_SUCCESS_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan");
uint16 public feeBps = 3;
bool public flashLoansPaused;
}
文件 7 的 33:EbtcBase.sol
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";
contract EbtcBase is BaseMath, IEbtcBase {
uint256 public constant LICR = 1030000000000000000;
uint256 public constant MCR = 1100000000000000000;
uint256 public constant CCR = 1250000000000000000;
uint256 public constant LIQUIDATOR_REWARD = 2e17;
uint256 public constant MIN_NET_STETH_BALANCE = 2e18;
uint256 public constant PERCENT_DIVISOR = 200;
uint256 public constant BORROWING_FEE_FLOOR = 0;
uint256 public constant STAKING_REWARD_SPLIT = 5_000;
uint256 public constant MAX_REWARD_SPLIT = 10_000;
uint256 public constant MIN_CHANGE = 1000;
IActivePool public immutable activePool;
IPriceFeed public immutable override priceFeed;
ICollateralToken public immutable collateral;
constructor(address _activePoolAddress, address _priceFeedAddress, address _collateralAddress) {
activePool = IActivePool(_activePoolAddress);
priceFeed = IPriceFeed(_priceFeedAddress);
collateral = ICollateralToken(_collateralAddress);
}
function _calcNetStEthBalance(uint256 _stEthBalance) internal pure returns (uint256) {
return _stEthBalance - LIQUIDATOR_REWARD;
}
function getSystemCollShares() public view returns (uint256 entireSystemColl) {
return (activePool.getSystemCollShares());
}
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");
}
function _convertDebtDenominationToBtc(
uint256 _debt,
uint256 _price
) internal pure returns (uint256) {
return (_debt * _price) / DECIMAL_PRECISION;
}
function _checkICRAgainstLiqThreshold(uint256 _icr, uint _tcr) internal view returns (bool) {
return
_checkICRAgainstMCR(_icr) ||
(_checkICRAgainstTCR(_icr, _tcr) && _checkRecoveryModeForTCR(_tcr));
}
function _checkICRAgainstMCR(uint256 _icr) internal view returns (bool) {
return _icr < MCR;
}
function _checkICRAgainstTCR(uint256 _icr, uint _tcr) internal view returns (bool) {
return _icr <= _tcr;
}
}
文件 8 的 33:EbtcMath.sol
pragma solidity 0.8.17;
library EbtcMath {
uint256 internal constant DECIMAL_PRECISION = 1e18;
uint256 public constant MAX_TCR = type(uint256).max;
uint256 internal constant NICR_PRECISION = 1e20;
function _min(uint256 _a, uint256 _b) internal pure returns (uint256) {
return (_a < _b) ? _a : _b;
}
function _max(uint256 _a, uint256 _b) internal pure returns (uint256) {
return (_a >= _b) ? _a : _b;
}
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "EbtcMath: downcast to uint128 will overflow");
return uint128(value);
}
function decMul(uint256 x, uint256 y) internal pure returns (uint256 decProd) {
uint256 prod_xy = x * y;
decProd = (prod_xy + (DECIMAL_PRECISION / 2)) / DECIMAL_PRECISION;
}
function _decPow(uint256 _base, uint256 _minutes) internal pure returns (uint256) {
if (_minutes > 525600000) {
_minutes = 525600000;
}
if (_minutes == 0) {
return DECIMAL_PRECISION;
}
uint256 y = DECIMAL_PRECISION;
uint256 x = _base;
uint256 n = _minutes;
while (n > 1) {
if (n % 2 == 0) {
x = decMul(x, x);
n = n / 2;
} else {
y = decMul(x, y);
x = decMul(x, x);
n = (n - 1) / 2;
}
}
return decMul(x, y);
}
function _getAbsoluteDifference(uint256 _a, uint256 _b) internal pure returns (uint256) {
return (_a >= _b) ? (_a - _b) : (_b - _a);
}
function _computeNominalCR(uint256 _collShares, uint256 _debt) internal pure returns (uint256) {
if (_debt > 0) {
return (_collShares * NICR_PRECISION) / _debt;
}
else {
return MAX_TCR;
}
}
function _computeCR(
uint256 _stEthBalance,
uint256 _debt,
uint256 _price
) internal pure returns (uint256) {
if (_debt > 0) {
uint256 newCollRatio = (_stEthBalance * _price) / _debt;
return newCollRatio;
}
else {
return MAX_TCR;
}
}
}
文件 9 的 33:IActivePool.sol
pragma solidity 0.8.17;
import "./IPool.sol";
import "./ITwapWeightedObserver.sol";
interface IActivePool is IPool, ITwapWeightedObserver {
event ActivePoolEBTCDebtUpdated(uint256 _EBTCDebt);
event SystemCollSharesUpdated(uint256 _coll);
event FeeRecipientClaimableCollSharesIncreased(uint256 _coll, uint256 _fee);
event FeeRecipientClaimableCollSharesDecreased(uint256 _coll, uint256 _fee);
event FlashLoanSuccess(
address indexed _receiver,
address indexed _token,
uint256 _amount,
uint256 _fee
);
event SweepTokenSuccess(address indexed _token, uint256 _amount, address indexed _recipient);
function transferSystemCollShares(address _account, uint256 _amount) external;
function increaseSystemCollShares(uint256 _value) external;
function transferSystemCollSharesAndLiquidatorReward(
address _account,
uint256 _shares,
uint256 _liquidatorRewardShares
) external;
function allocateSystemCollSharesToFeeRecipient(uint256 _shares) external;
function claimFeeRecipientCollShares(uint256 _shares) external;
function feeRecipientAddress() external view returns (address);
function getFeeRecipientClaimableCollShares() external view returns (uint256);
}
文件 10 的 33:IBaseTwapWeightedObserver.sol
pragma solidity 0.8.17;
interface IBaseTwapWeightedObserver {
struct PackedData {
uint128 observerCumuVal;
uint128 accumulator;
uint64 lastObserved;
uint64 lastAccrued;
uint128 lastObservedAverage;
}
}
文件 11 的 33:IBorrowerOperations.sol
pragma solidity 0.8.17;
import "./IPositionManagers.sol";
interface IBorrowerOperations is IPositionManagers {
event FeeRecipientAddressChanged(address indexed _feeRecipientAddress);
event FlashLoanSuccess(
address indexed _receiver,
address indexed _token,
uint256 _amount,
uint256 _fee
);
function openCdp(
uint256 _EBTCAmount,
bytes32 _upperHint,
bytes32 _lowerHint,
uint256 _stEthBalance
) external returns (bytes32);
function openCdpFor(
uint _EBTCAmount,
bytes32 _upperHint,
bytes32 _lowerHint,
uint _collAmount,
address _borrower
) external returns (bytes32);
function addColl(
bytes32 _cdpId,
bytes32 _upperHint,
bytes32 _lowerHint,
uint256 _stEthBalanceIncrease
) external;
function withdrawColl(
bytes32 _cdpId,
uint256 _stEthBalanceDecrease,
bytes32 _upperHint,
bytes32 _lowerHint
) external;
function withdrawDebt(
bytes32 _cdpId,
uint256 _amount,
bytes32 _upperHint,
bytes32 _lowerHint
) external;
function repayDebt(
bytes32 _cdpId,
uint256 _amount,
bytes32 _upperHint,
bytes32 _lowerHint
) external;
function closeCdp(bytes32 _cdpId) external;
function adjustCdp(
bytes32 _cdpId,
uint256 _stEthBalanceDecrease,
uint256 _debtChange,
bool isDebtIncrease,
bytes32 _upperHint,
bytes32 _lowerHint
) external;
function adjustCdpWithColl(
bytes32 _cdpId,
uint256 _stEthBalanceDecrease,
uint256 _debtChange,
bool isDebtIncrease,
bytes32 _upperHint,
bytes32 _lowerHint,
uint256 _stEthBalanceIncrease
) external;
function claimSurplusCollShares() external;
function feeRecipientAddress() external view returns (address);
}
文件 12 的 33:ICdpManager.sol
pragma solidity 0.8.17;
import "./IEbtcBase.sol";
import "./ICdpManagerData.sol";
interface ICdpManager is IEbtcBase, ICdpManagerData {
function liquidate(bytes32 _cdpId) external;
function partiallyLiquidate(
bytes32 _cdpId,
uint256 _partialAmount,
bytes32 _upperPartialHint,
bytes32 _lowerPartialHint
) external;
function batchLiquidateCdps(bytes32[] calldata _cdpArray) external;
function redeemCollateral(
uint256 _EBTCAmount,
bytes32 _firstRedemptionHint,
bytes32 _upperPartialRedemptionHint,
bytes32 _lowerPartialRedemptionHint,
uint256 _partialRedemptionHintNICR,
uint256 _maxIterations,
uint256 _maxFee
) external;
function updateStakeAndTotalStakes(bytes32 _cdpId) external returns (uint256);
function syncAccounting(bytes32 _cdpId) external;
function closeCdp(bytes32 _cdpId, address _borrower, uint256 _debt, uint256 _coll) external;
function getRedemptionRate() external view returns (uint256);
function getRedemptionRateWithDecay() external view returns (uint256);
function getRedemptionFeeWithDecay(uint256 _stETHToRedeem) external view returns (uint256);
function getCdpStatus(bytes32 _cdpId) external view returns (uint256);
function getCdpStake(bytes32 _cdpId) external view returns (uint256);
function getCdpDebt(bytes32 _cdpId) external view returns (uint256);
function getCdpCollShares(bytes32 _cdpId) external view returns (uint256);
function getCdpLiquidatorRewardShares(bytes32 _cdpId) external view returns (uint);
function initializeCdp(
bytes32 _cdpId,
uint256 _debt,
uint256 _coll,
uint256 _liquidatorRewardShares,
address _borrower
) external;
function updateCdp(
bytes32 _cdpId,
address _borrower,
uint256 _coll,
uint256 _debt,
uint256 _newColl,
uint256 _newDebt
) external;
function getCachedTCR(uint256 _price) external view returns (uint256);
function checkRecoveryMode(uint256 _price) external view returns (bool);
}
文件 13 的 33:ICdpManagerData.sol
pragma solidity 0.8.17;
import "./ICollSurplusPool.sol";
import "./IEBTCToken.sol";
import "./ISortedCdps.sol";
import "./IActivePool.sol";
import "./IRecoveryModeGracePeriod.sol";
import "../Dependencies/ICollateralTokenOracle.sol";
interface ICdpManagerData is IRecoveryModeGracePeriod {
event StakingRewardSplitSet(uint256 _stakingRewardSplit);
event RedemptionFeeFloorSet(uint256 _redemptionFeeFloor);
event MinuteDecayFactorSet(uint256 _minuteDecayFactor);
event BetaSet(uint256 _beta);
event RedemptionsPaused(bool _paused);
event Liquidation(uint256 _liquidatedDebt, uint256 _liquidatedColl, uint256 _liqReward);
event Redemption(
uint256 _debtToRedeemExpected,
uint256 _debtToRedeemActual,
uint256 _collSharesSent,
uint256 _feeCollShares,
address indexed _redeemer
);
event CdpUpdated(
bytes32 indexed _cdpId,
address indexed _borrower,
address indexed _executor,
uint256 _oldDebt,
uint256 _oldCollShares,
uint256 _debt,
uint256 _collShares,
uint256 _stake,
CdpOperation _operation
);
event CdpLiquidated(
bytes32 indexed _cdpId,
address indexed _borrower,
uint _debt,
uint _collShares,
CdpOperation _operation,
address indexed _liquidator,
uint _premiumToLiquidator
);
event CdpPartiallyLiquidated(
bytes32 indexed _cdpId,
address indexed _borrower,
uint256 _debt,
uint256 _collShares,
CdpOperation operation,
address indexed _liquidator,
uint _premiumToLiquidator
);
event BaseRateUpdated(uint256 _baseRate);
event LastRedemptionTimestampUpdated(uint256 _lastFeeOpTime);
event TotalStakesUpdated(uint256 _newTotalStakes);
event SystemSnapshotsUpdated(uint256 _totalStakesSnapshot, uint256 _totalCollateralSnapshot);
event SystemDebtRedistributionIndexUpdated(uint256 _systemDebtRedistributionIndex);
event CdpDebtRedistributionIndexUpdated(bytes32 _cdpId, uint256 _cdpDebtRedistributionIndex);
event CdpArrayIndexUpdated(bytes32 _cdpId, uint256 _newIndex);
event StEthIndexUpdated(uint256 _oldIndex, uint256 _newIndex, uint256 _updTimestamp);
event CollateralFeePerUnitUpdated(uint256 _oldPerUnit, uint256 _newPerUnit, uint256 _feeTaken);
event CdpFeeSplitApplied(
bytes32 _cdpId,
uint256 _oldPerUnitCdp,
uint256 _newPerUnitCdp,
uint256 _collReduced,
uint256 _collLeft
);
enum CdpOperation {
openCdp,
closeCdp,
adjustCdp,
syncAccounting,
liquidateInNormalMode,
liquidateInRecoveryMode,
redeemCollateral,
partiallyLiquidate,
failedPartialRedemption
}
enum Status {
nonExistent,
active,
closedByOwner,
closedByLiquidation,
closedByRedemption
}
struct Cdp {
uint256 debt;
uint256 coll;
uint256 stake;
uint128 liquidatorRewardShares;
Status status;
}
struct CdpDebtAndCollShares {
uint256 debt;
uint256 collShares;
}
struct LiquidationLocals {
bytes32 cdpId;
uint256 partialAmount;
uint256 price;
uint256 ICR;
bytes32 upperPartialHint;
bytes32 lowerPartialHint;
bool recoveryModeAtStart;
uint256 TCR;
uint256 totalSurplusCollShares;
uint256 totalCollSharesToSend;
uint256 totalDebtToBurn;
uint256 totalDebtToRedistribute;
uint256 totalLiquidatorRewardCollShares;
}
struct LiquidationRecoveryModeLocals {
uint256 entireSystemDebt;
uint256 entireSystemColl;
uint256 totalDebtToBurn;
uint256 totalCollSharesToSend;
uint256 totalSurplusCollShares;
bytes32 cdpId;
uint256 price;
uint256 ICR;
uint256 totalDebtToRedistribute;
uint256 totalLiquidatorRewardCollShares;
}
struct LocalVariables_OuterLiquidationFunction {
uint256 price;
bool recoveryModeAtStart;
uint256 liquidatedDebt;
uint256 liquidatedColl;
}
struct LocalVariables_LiquidationSequence {
uint256 i;
uint256 ICR;
bytes32 cdpId;
bool backToNormalMode;
uint256 entireSystemDebt;
uint256 entireSystemColl;
uint256 price;
uint256 TCR;
}
struct SingleRedemptionInputs {
bytes32 cdpId;
uint256 maxEBTCamount;
uint256 price;
bytes32 upperPartialRedemptionHint;
bytes32 lowerPartialRedemptionHint;
uint256 partialRedemptionHintNICR;
}
struct LiquidationValues {
uint256 entireCdpDebt;
uint256 debtToBurn;
uint256 totalCollToSendToLiquidator;
uint256 debtToRedistribute;
uint256 collSurplus;
uint256 liquidatorCollSharesReward;
}
struct LiquidationTotals {
uint256 totalDebtInSequence;
uint256 totalDebtToBurn;
uint256 totalCollToSendToLiquidator;
uint256 totalDebtToRedistribute;
uint256 totalCollSurplus;
uint256 totalCollReward;
}
struct RedemptionTotals {
uint256 remainingDebtToRedeem;
uint256 debtToRedeem;
uint256 collSharesDrawn;
uint256 totalCollSharesSurplus;
uint256 feeCollShares;
uint256 collSharesToRedeemer;
uint256 decayedBaseRate;
uint256 price;
uint256 systemDebtAtStart;
uint256 twapSystemDebtAtStart;
uint256 systemCollSharesAtStart;
uint256 tcrAtStart;
}
struct SingleRedemptionValues {
uint256 debtToRedeem;
uint256 collSharesDrawn;
uint256 collSurplus;
uint256 liquidatorRewardShares;
bool cancelledPartial;
bool fullRedemption;
uint256 newPartialNICR;
}
function getActiveCdpsCount() external view returns (uint256);
function totalStakes() external view returns (uint256);
function ebtcToken() external view returns (IEBTCToken);
function systemStEthFeePerUnitIndex() external view returns (uint256);
function systemStEthFeePerUnitIndexError() external view returns (uint256);
function stEthIndex() external view returns (uint256);
function calcFeeUponStakingReward(
uint256 _newIndex,
uint256 _prevIndex
) external view returns (uint256, uint256, uint256);
function syncGlobalAccounting() external;
function syncGlobalAccountingAndGracePeriod() external;
function getAccumulatedFeeSplitApplied(
bytes32 _cdpId,
uint256 _systemStEthFeePerUnitIndex
) external view returns (uint256, uint256);
function getCachedNominalICR(bytes32 _cdpId) external view returns (uint256);
function getCachedICR(bytes32 _cdpId, uint256 _price) external view returns (uint256);
function getSyncedCdpDebt(bytes32 _cdpId) external view returns (uint256);
function getSyncedCdpCollShares(bytes32 _cdpId) external view returns (uint256);
function getSyncedICR(bytes32 _cdpId, uint256 _price) external view returns (uint256);
function getSyncedTCR(uint256 _price) external view returns (uint256);
function getSyncedSystemCollShares() external view returns (uint256);
function getSyncedNominalICR(bytes32 _cdpId) external view returns (uint256);
function getPendingRedistributedDebt(bytes32 _cdpId) external view returns (uint256);
function hasPendingRedistributedDebt(bytes32 _cdpId) external view returns (bool);
function getSyncedDebtAndCollShares(
bytes32 _cdpId
) external view returns (uint256 debt, uint256 collShares);
function canLiquidateRecoveryMode(uint256 icr, uint256 tcr) external view returns (bool);
function totalCollateralSnapshot() external view returns (uint256);
function totalStakesSnapshot() external view returns (uint256);
}
文件 14 的 33:ICollSurplusPool.sol
pragma solidity 0.8.17;
interface ICollSurplusPool {
event SurplusCollSharesAdded(
bytes32 indexed _cdpId,
address indexed _account,
uint256 _claimableSurplusCollShares,
uint256 _surplusCollSharesAddedFromCollateral,
uint256 _surplusCollSharesAddedFromLiquidatorReward
);
event CollSharesTransferred(address indexed _to, uint256 _amount);
event SweepTokenSuccess(address indexed _token, uint256 _amount, address indexed _recipient);
function getTotalSurplusCollShares() external view returns (uint256);
function getSurplusCollShares(address _account) external view returns (uint256);
function increaseSurplusCollShares(
bytes32 _cdpId,
address _account,
uint256 _collateralShares,
uint256 _liquidatorRewardShares
) external;
function claimSurplusCollShares(address _account) external;
function increaseTotalSurplusCollShares(uint256 _value) external;
}
文件 15 的 33:ICollateralToken.sol
pragma solidity 0.8.17;
import "./IERC20.sol";
interface ICollateralToken is IERC20 {
function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256);
function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256);
function transferShares(address _recipient, uint256 _sharesAmount) external returns (uint256);
function sharesOf(address _account) external view returns (uint256);
function getOracle() external view returns (address);
}
文件 16 的 33:ICollateralTokenOracle.sol
pragma solidity 0.8.17;
interface ICollateralTokenOracle {
function getBeaconSpec()
external
view
returns (
uint64 epochsPerFrame,
uint64 slotsPerEpoch,
uint64 secondsPerSlot,
uint64 genesisTime
);
}
文件 17 的 33:IEBTCToken.sol
pragma solidity 0.8.17;
import "../Dependencies/IERC20.sol";
import "../Dependencies/IERC2612.sol";
interface IEBTCToken is IERC20, IERC2612 {
function mint(address _account, uint256 _amount) external;
function burn(address _account, uint256 _amount) external;
}
文件 18 的 33:IERC20.sol
pragma solidity 0.8.17;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function increaseAllowance(address spender, uint256 addedValue) external returns (bool);
function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 19 的 33:IERC2612.sol
pragma solidity 0.8.17;
interface IERC2612 {
function permit(
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function version() external view returns (string memory);
function permitTypeHash() external view returns (bytes32);
function domainSeparator() external view returns (bytes32);
}
文件 20 的 33:IERC3156FlashBorrower.sol
pragma solidity 0.8.17;
interface IERC3156FlashBorrower {
function onFlashLoan(
address initiator,
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) external returns (bytes32);
}
文件 21 的 33:IERC3156FlashLender.sol
pragma solidity 0.8.17;
import "./IERC3156FlashBorrower.sol";
interface IERC3156FlashLender {
event FlashFeeSet(address indexed _setter, uint256 _oldFee, uint256 _newFee);
event MaxFlashFeeSet(address indexed _setter, uint256 _oldMaxFee, uint256 _newMaxFee);
event FlashLoansPaused(address indexed _setter, bool _paused);
function maxFlashLoan(address token) external view returns (uint256);
function flashFee(address token, uint256 amount) external view returns (uint256);
function flashLoan(
IERC3156FlashBorrower receiver,
address token,
uint256 amount,
bytes calldata data
) external returns (bool);
}
文件 22 的 33:IEbtcBase.sol
pragma solidity 0.8.17;
import "./IPriceFeed.sol";
interface IEbtcBase {
function priceFeed() external view returns (IPriceFeed);
}
文件 23 的 33:IPermitNonce.sol
pragma solidity 0.8.17;
interface IPermitNonce {
function increasePermitNonce() external returns (uint256);
function nonces(address owner) external view returns (uint256);
}
文件 24 的 33:IPool.sol
pragma solidity 0.8.17;
interface IPool {
event ETHBalanceUpdated(uint256 _newBalance);
event EBTCBalanceUpdated(uint256 _newBalance);
event CollSharesTransferred(address indexed _to, uint256 _amount);
function getSystemCollShares() external view returns (uint256);
function getSystemDebt() external view returns (uint256);
function increaseSystemDebt(uint256 _amount) external;
function decreaseSystemDebt(uint256 _amount) external;
}
文件 25 的 33:IPositionManagers.sol
pragma solidity 0.8.17;
interface IPositionManagers {
enum PositionManagerApproval {
None,
OneTime,
Persistent
}
event PositionManagerApprovalSet(
address indexed _borrower,
address indexed _positionManager,
PositionManagerApproval _approval
);
function getPositionManagerApproval(
address _borrower,
address _positionManager
) external view returns (PositionManagerApproval);
function setPositionManagerApproval(
address _positionManager,
PositionManagerApproval _approval
) external;
function revokePositionManagerApproval(address _positionManager) external;
function renouncePositionManagerApproval(address _borrower) external;
function permitPositionManagerApproval(
address _borrower,
address _positionManager,
PositionManagerApproval _approval,
uint _deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function version() external view returns (string memory);
function permitTypeHash() external view returns (bytes32);
function domainSeparator() external view returns (bytes32);
}
文件 26 的 33:IPriceFeed.sol
pragma solidity 0.8.17;
interface IPriceFeed {
event LastGoodPriceUpdated(uint256 _lastGoodPrice);
event PriceFeedStatusChanged(Status newStatus);
event FallbackCallerChanged(
address indexed _oldFallbackCaller,
address indexed _newFallbackCaller
);
event UnhealthyFallbackCaller(address indexed _fallbackCaller, uint256 timestamp);
event CollateralFeedSourceUpdated(address indexed stEthFeed);
struct ChainlinkResponse {
uint80 roundEthBtcId;
uint80 roundStEthEthId;
uint256 answer;
uint256 timestampEthBtc;
uint256 timestampStEthEth;
bool success;
}
struct FallbackResponse {
uint256 answer;
uint256 timestamp;
bool success;
}
enum Status {
chainlinkWorking,
usingFallbackChainlinkUntrusted,
bothOraclesUntrusted,
usingFallbackChainlinkFrozen,
usingChainlinkFallbackUntrusted
}
function fetchPrice() external returns (uint256);
}
文件 27 的 33:IRecoveryModeGracePeriod.sol
pragma solidity 0.8.17;
interface IRecoveryModeGracePeriod {
event TCRNotified(uint256 TCR);
event GracePeriodStart();
event GracePeriodEnd();
event GracePeriodDurationSet(uint256 _recoveryModeGracePeriodDuration);
function notifyStartGracePeriod(uint256 tcr) external;
function notifyEndGracePeriod(uint256 tcr) external;
}
文件 28 的 33:ISortedCdps.sol
pragma solidity 0.8.17;
interface ISortedCdps {
event NodeAdded(bytes32 _id, uint _NICR);
event NodeRemoved(bytes32 _id);
function remove(bytes32 _id) external;
function batchRemove(bytes32[] memory _ids) external;
function reInsert(bytes32 _id, uint256 _newICR, bytes32 _prevId, bytes32 _nextId) external;
function contains(bytes32 _id) external view returns (bool);
function isFull() external view returns (bool);
function isEmpty() external view returns (bool);
function getSize() external view returns (uint256);
function getMaxSize() external view returns (uint256);
function getFirst() external view returns (bytes32);
function getLast() external view returns (bytes32);
function getNext(bytes32 _id) external view returns (bytes32);
function getPrev(bytes32 _id) external view returns (bytes32);
function validInsertPosition(
uint256 _ICR,
bytes32 _prevId,
bytes32 _nextId
) external view returns (bool);
function findInsertPosition(
uint256 _ICR,
bytes32 _prevId,
bytes32 _nextId
) external view returns (bytes32, bytes32);
function insert(
address owner,
uint256 _ICR,
bytes32 _prevId,
bytes32 _nextId
) external returns (bytes32);
function getOwnerAddress(bytes32 _id) external pure returns (address);
function nonExistId() external view returns (bytes32);
function cdpCountOf(address owner) external view returns (uint256);
function getCdpCountOf(
address owner,
bytes32 startNodeId,
uint maxNodes
) external view returns (uint256, bytes32);
function getCdpsOf(address owner) external view returns (bytes32[] memory);
function getAllCdpsOf(
address owner,
bytes32 startNodeId,
uint maxNodes
) external view returns (bytes32[] memory, uint256, bytes32);
function cdpOfOwnerByIndex(address owner, uint256 index) external view returns (bytes32);
function cdpOfOwnerByIdx(
address owner,
uint256 index,
bytes32 startNodeId,
uint maxNodes
) external view returns (bytes32, bool);
function toCdpId(
address owner,
uint256 blockHeight,
uint256 nonce
) external pure returns (bytes32);
function nextCdpNonce() external view returns (uint256);
}
文件 29 的 33:ITwapWeightedObserver.sol
pragma solidity 0.8.17;
import {IBaseTwapWeightedObserver} from "./IBaseTwapWeightedObserver.sol";
interface ITwapWeightedObserver is IBaseTwapWeightedObserver {
event TwapDisabled();
function PERIOD() external view returns (uint256);
function valueToTrack() external view returns (uint128);
function timeToAccrue() external view returns (uint64);
function getLatestAccumulator() external view returns (uint128);
function observe() external returns (uint256);
function update() external;
function twapDisabled() external view returns (bool);
}
文件 30 的 33:IWETH.sol
pragma solidity 0.8.17;
interface IWETH {
function deposit() external payable;
function withdraw(uint256) external;
function transfer(address to, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
文件 31 的 33:Ownable.sol
pragma solidity 0.8.17;
import "./Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 32 的 33:PermitNonce.sol
pragma solidity 0.8.17;
import "../Interfaces/IPermitNonce.sol";
contract PermitNonce is IPermitNonce {
mapping(address => uint256) internal _nonces;
function increasePermitNonce() external returns (uint256) {
return ++_nonces[msg.sender];
}
function nonces(address owner) external view virtual returns (uint256) {
return _nonces[owner];
}
}
文件 33 的 33:ReentrancyGuard.sol
pragma solidity 0.8.17;
abstract contract ReentrancyGuard {
uint256 internal constant OPEN = 1;
uint256 internal constant LOCKED = 2;
uint256 public locked = OPEN;
modifier nonReentrant() virtual {
require(locked == OPEN, "ReentrancyGuard: Reentrancy in nonReentrant call");
locked = LOCKED;
_;
locked = OPEN;
}
}
{
"compilationTarget": {
"contracts/BorrowerOperations.sol": "BorrowerOperations"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_cdpManagerAddress","type":"address"},{"internalType":"address","name":"_activePoolAddress","type":"address"},{"internalType":"address","name":"_collSurplusPoolAddress","type":"address"},{"internalType":"address","name":"_priceFeedAddress","type":"address"},{"internalType":"address","name":"_sortedCdpsAddress","type":"address"},{"internalType":"address","name":"_ebtcTokenAddress","type":"address"},{"internalType":"address","name":"_feeRecipientAddress","type":"address"},{"internalType":"address","name":"_collTokenAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"AuthorityUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_feeRecipientAddress","type":"address"}],"name":"FeeRecipientAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_setter","type":"address"},{"indexed":false,"internalType":"uint256","name":"_oldFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newFee","type":"uint256"}],"name":"FlashFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_receiver","type":"address"},{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"FlashLoanSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_setter","type":"address"},{"indexed":false,"internalType":"bool","name":"_paused","type":"bool"}],"name":"FlashLoansPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_setter","type":"address"},{"indexed":false,"internalType":"uint256","name":"_oldMaxFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newMaxFee","type":"uint256"}],"name":"MaxFlashFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_borrower","type":"address"},{"indexed":true,"internalType":"address","name":"_positionManager","type":"address"},{"indexed":false,"internalType":"enum IPositionManagers.PositionManagerApproval","name":"_approval","type":"uint8"}],"name":"PositionManagerApprovalSet","type":"event"},{"inputs":[],"name":"BORROWING_FEE_FLOOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CCR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DECIMAL_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FLASH_SUCCESS_VALUE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LICR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIQUIDATOR_REWARD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REWARD_SPLIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MCR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_CHANGE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_NET_STETH_BALANCE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NAME","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERCENT_DIVISOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_REWARD_SPLIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"activePool","outputs":[{"internalType":"contract IActivePool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_cdpId","type":"bytes32"},{"internalType":"bytes32","name":"_upperHint","type":"bytes32"},{"internalType":"bytes32","name":"_lowerHint","type":"bytes32"},{"internalType":"uint256","name":"_stEthBalanceIncrease","type":"uint256"}],"name":"addColl","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_cdpId","type":"bytes32"},{"internalType":"uint256","name":"_stEthBalanceDecrease","type":"uint256"},{"internalType":"uint256","name":"_debtChange","type":"uint256"},{"internalType":"bool","name":"_isDebtIncrease","type":"bool"},{"internalType":"bytes32","name":"_upperHint","type":"bytes32"},{"internalType":"bytes32","name":"_lowerHint","type":"bytes32"}],"name":"adjustCdp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_cdpId","type":"bytes32"},{"internalType":"uint256","name":"_stEthBalanceDecrease","type":"uint256"},{"internalType":"uint256","name":"_debtChange","type":"uint256"},{"internalType":"bool","name":"_isDebtIncrease","type":"bool"},{"internalType":"bytes32","name":"_upperHint","type":"bytes32"},{"internalType":"bytes32","name":"_lowerHint","type":"bytes32"},{"internalType":"uint256","name":"_stEthBalanceIncrease","type":"uint256"}],"name":"adjustCdpWithColl","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"authority","outputs":[{"internalType":"contract Authority","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"authorityInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cdpManager","outputs":[{"internalType":"contract ICdpManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimSurplusCollShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_cdpId","type":"bytes32"}],"name":"closeCdp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collSurplusPool","outputs":[{"internalType":"contract ICollSurplusPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateral","outputs":[{"internalType":"contract ICollateralToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"domainSeparator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ebtcToken","outputs":[{"internalType":"contract IEBTCToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeBps","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeRecipientAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"flashFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC3156FlashBorrower","name":"receiver","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"flashLoan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flashLoansPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"address","name":"_positionManager","type":"address"}],"name":"getPositionManagerApproval","outputs":[{"internalType":"enum IPositionManagers.PositionManagerApproval","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSystemCollShares","outputs":[{"internalType":"uint256","name":"entireSystemColl","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"increasePermitNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"locked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"maxFlashLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_debt","type":"uint256"},{"internalType":"bytes32","name":"_upperHint","type":"bytes32"},{"internalType":"bytes32","name":"_lowerHint","type":"bytes32"},{"internalType":"uint256","name":"_stEthBalance","type":"uint256"}],"name":"openCdp","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_debt","type":"uint256"},{"internalType":"bytes32","name":"_upperHint","type":"bytes32"},{"internalType":"bytes32","name":"_lowerHint","type":"bytes32"},{"internalType":"uint256","name":"_stEthBalance","type":"uint256"},{"internalType":"address","name":"_borrower","type":"address"}],"name":"openCdpFor","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"address","name":"_positionManager","type":"address"},{"internalType":"enum IPositionManagers.PositionManagerApproval","name":"_approval","type":"uint8"},{"internalType":"uint256","name":"_deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permitPositionManagerApproval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"permitTypeHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"positionManagers","outputs":[{"internalType":"enum IPositionManagers.PositionManagerApproval","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceFeed","outputs":[{"internalType":"contract IPriceFeed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"}],"name":"renouncePositionManagerApproval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_cdpId","type":"bytes32"},{"internalType":"uint256","name":"_debt","type":"uint256"},{"internalType":"bytes32","name":"_upperHint","type":"bytes32"},{"internalType":"bytes32","name":"_lowerHint","type":"bytes32"}],"name":"repayDebt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_positionManager","type":"address"}],"name":"revokePositionManagerApproval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newFee","type":"uint256"}],"name":"setFeeBps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setFlashLoansPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_positionManager","type":"address"},{"internalType":"enum IPositionManagers.PositionManagerApproval","name":"_approval","type":"uint8"}],"name":"setPositionManagerApproval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sortedCdps","outputs":[{"internalType":"contract ISortedCdps","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_cdpId","type":"bytes32"},{"internalType":"uint256","name":"_stEthBalanceDecrease","type":"uint256"},{"internalType":"bytes32","name":"_upperHint","type":"bytes32"},{"internalType":"bytes32","name":"_lowerHint","type":"bytes32"}],"name":"withdrawColl","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_cdpId","type":"bytes32"},{"internalType":"uint256","name":"_debt","type":"uint256"},{"internalType":"bytes32","name":"_upperHint","type":"bytes32"},{"internalType":"bytes32","name":"_lowerHint","type":"bytes32"}],"name":"withdrawDebt","outputs":[],"stateMutability":"nonpayable","type":"function"}]