-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #304 from Instadapp/crv-usd
Crv usd
- Loading branch information
Showing
7 changed files
with
812 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
//SPDX-License-Identifier: MIT | ||
pragma solidity ^0.7.0; | ||
|
||
contract Events { | ||
event LogCreateLoan(address indexed collateral, uint256 amt, uint256 debt, uint256 indexed numBands, uint256 controllerVersion, uint256 getId, uint256 setId); | ||
event LogAddCollateral(address indexed collateral, uint256 indexed amt, uint256 controllerVersion, uint256 getId, uint256 setId); | ||
event LogRemoveCollateral(address indexed collateral, uint256 indexed amt, uint256 getId, uint256 setId); | ||
event LogBorrowMore(address indexed collateral, uint256 indexed amt, uint256 controllerVersion, uint256 indexed debt); | ||
event LogRepay(address indexed collateral, uint256 indexed amt, uint256 controllerVersion, uint256 getId, uint256 setId); | ||
event LogLiquidate(address indexed collateral, uint256 indexed min_x, uint256 controllerVersion, uint256 getId, uint256 setId); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
//SPDX-License-Identifier: MIT | ||
pragma solidity ^0.7.0; | ||
|
||
import { DSMath } from "../../common/math.sol"; | ||
import { Basic } from "../../common/basic.sol"; | ||
import { TokenInterface } from "../../common/interfaces.sol"; | ||
import "./interface.sol"; | ||
|
||
abstract contract Helpers is DSMath, Basic { | ||
|
||
address internal constant CRV_USD = 0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E; | ||
/** | ||
* @dev ControllerFactory Interface | ||
*/ | ||
IControllerFactory internal constant CONTROLLER_FACTORY = | ||
IControllerFactory(0xC9332fdCB1C491Dcc683bAe86Fe3cb70360738BC); | ||
|
||
/** | ||
* @dev Get controller address by given collateral asset | ||
*/ | ||
function getController(address collateral, uint256 i) internal view returns(IController controller) { | ||
controller = IController(CONTROLLER_FACTORY.get_controller(collateral, i)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
//SPDX-License-Identifier: MIT | ||
pragma solidity ^0.7.0; | ||
|
||
import { TokenInterface } from "../../common/interfaces.sol"; | ||
|
||
interface IControllerFactory { | ||
function get_controller(address collateral, uint256 index) external view returns (address); | ||
} | ||
|
||
interface IController { | ||
function create_loan(uint256 collateral, uint256 debt, uint256 N) payable external; | ||
function add_collateral(uint256 collateral, address _for) payable external; | ||
function remove_collateral(uint256 collateral, bool use_eth) external; | ||
function borrow_more(uint256 collateral, uint256 debt) payable external; | ||
function repay(uint256 _d_debt, address _for, int256 max_active_band, bool use_eth) payable external; | ||
function repay(uint256 _d_debt) payable external; | ||
function liquidate(address user, uint256 min_x, bool use_eth) external; | ||
function max_borrowable(uint256 collateral, uint256 N) external view returns(uint256); | ||
function min_collateral(uint256 debt, uint256 N) external view returns(uint256); | ||
function user_state(address user) external view returns(uint256[4] memory); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,281 @@ | ||
//SPDX-License-Identifier: MIT | ||
pragma solidity ^0.7.0; | ||
|
||
/** | ||
* @title Curve USD. | ||
* @dev Collateralized Borrowing. | ||
*/ | ||
|
||
import { TokenInterface, AccountInterface } from "../../common/interfaces.sol"; | ||
import { Helpers } from "./helpers.sol"; | ||
import { Events } from "./events.sol"; | ||
import "./interface.sol"; | ||
|
||
abstract contract CurveUSDResolver is Helpers, Events { | ||
/** | ||
* @dev Create loan | ||
* @dev If a user already has an existing loan, the function will revert. | ||
* @param collateral Collateral token address.(For ETH: `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`) | ||
* @param amt Amount of collateral (For max: `uint256(-1)`) | ||
* @param debtAmt Stablecoin debt to take (For max: `uint256(-1)`) | ||
* @param numBands Number of bands to deposit into (to do autoliquidation-deliquidation), can only be from MIN_TICKS(4) to MAX_TICKS(50) | ||
* @param controllerVersion Controller version, | ||
* @param getId ID to retrieve amt. | ||
* @param setId ID stores the amount of debt borrowed. | ||
*/ | ||
function createLoan( | ||
address collateral, | ||
uint256 amt, | ||
uint256 debtAmt, | ||
uint256 numBands, | ||
uint256 controllerVersion, | ||
uint256 getId, | ||
uint256 setId | ||
) external returns (string memory _eventName, bytes memory _eventParam) { | ||
uint256 _amt = getUint(getId, amt); | ||
|
||
bool _isEth = collateral == ethAddr; | ||
address _collateralAddress = _isEth ? wethAddr : collateral; | ||
TokenInterface collateralContract = TokenInterface(_collateralAddress); | ||
|
||
// Get controller address of collateral. | ||
IController controller = getController(_collateralAddress, controllerVersion); | ||
|
||
if (_isEth) { | ||
_amt = _amt == uint256(-1) ? address(this).balance : _amt; | ||
convertEthToWeth(_isEth, collateralContract, _amt); | ||
} else { | ||
_amt = _amt == uint256(-1) ? collateralContract.balanceOf(address(this)) : _amt; | ||
} | ||
|
||
approve(collateralContract, address(controller), _amt); | ||
|
||
uint256 _debtAmt = debtAmt == uint256(-1) ? controller.max_borrowable(_amt, numBands) : debtAmt; | ||
|
||
controller.create_loan(_amt, _debtAmt, numBands); | ||
|
||
setUint(setId, _debtAmt); | ||
_eventName = "LogCreateLoan(address,uint256,uint256,uint256,uint256,uin256,uin256)"; | ||
_eventParam = abi.encode(collateral, _amt, _debtAmt, numBands, controllerVersion, getId, setId); | ||
} | ||
|
||
/** | ||
* @dev Add collateral | ||
* @notice Add extra collateral to avoid bad liqidations | ||
* @param collateral Collateral token address.(For ETH: `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`) | ||
* @param amt Amount of collateral (For max: `uint256(-1)`) | ||
* @param controllerVersion Controller version, | ||
* @param getId ID to retrieve amt. | ||
* @param setId ID stores the collateral amount of tokens added. | ||
*/ | ||
function addCollateral( | ||
address collateral, | ||
uint256 amt, | ||
uint256 controllerVersion, | ||
uint256 getId, | ||
uint256 setId | ||
) external returns (string memory _eventName, bytes memory _eventParam) { | ||
uint _amt = getUint(getId, amt); | ||
|
||
bool _isEth = collateral == ethAddr; | ||
address _collateralAddress = _isEth ? wethAddr : collateral; | ||
|
||
// Get controller address of collateral. | ||
IController controller = getController(_collateralAddress, controllerVersion); | ||
TokenInterface collateralContract = TokenInterface(_collateralAddress); | ||
|
||
if (_isEth) { | ||
_amt = _amt == uint(-1) ? address(this).balance : _amt; | ||
convertEthToWeth(_isEth, collateralContract, _amt); | ||
} else { | ||
_amt = _amt == uint(-1) ? collateralContract.balanceOf(address(this)) : _amt; | ||
} | ||
|
||
approve(collateralContract, address(controller), _amt); | ||
controller.add_collateral(_amt, address(this)); | ||
|
||
setUint(setId, _amt); | ||
|
||
_eventName = "LogAddCollateral(address,uint256,uint256,uint256,uint256)"; | ||
_eventParam = abi.encode(collateral, amt, controllerVersion, getId, setId); | ||
} | ||
|
||
/** | ||
* @dev Remove ETH/ERC20_Token Collateral. | ||
* @notice Remove some collateral without repaying the debt | ||
* @param collateral Collateral token address.(For ETH: `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`) | ||
* @param amt Remove collateral amount (For max: `uint256(-1)`) | ||
* @param controllerVersion controller version | ||
* @param getId ID to retrieve amt. | ||
* @param setId ID stores the amount of tokens deposited. | ||
*/ | ||
function removeCollateral( | ||
address collateral, | ||
uint256 amt, | ||
uint256 controllerVersion, | ||
uint256 getId, | ||
uint256 setId | ||
) external returns (string memory _eventName, bytes memory _eventParam) { | ||
uint _amt = getUint(getId, amt); | ||
|
||
bool _isEth = collateral == ethAddr; | ||
address _collateralAddress = _isEth ? wethAddr : collateral; | ||
|
||
IController controller = getController(_collateralAddress, controllerVersion); | ||
|
||
// remove_collateral will unwrap the eth. | ||
controller.remove_collateral(_amt, _isEth); | ||
|
||
setUint(setId, _amt); | ||
_eventName = "LogRemoveCollateral(address,uint256,uint256,uint256,uint256)"; | ||
_eventParam = abi.encode(collateral, amt, controllerVersion, getId, setId); | ||
} | ||
|
||
/** | ||
* @dev Borrow more stablecoins while adding more collateral (not necessary) | ||
* @param collateral Collateral token address.(For ETH: `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`) | ||
* @param debtAmt Stablecoin debt to take for borrow more (For max: `uint256(-1)`) | ||
* @param controllerVersion controller version | ||
* @param getId ID to retrieve amt. | ||
* @param setId ID stores the amount of tokens deposited. | ||
*/ | ||
function borrowMore( | ||
address collateral, | ||
uint256 debtAmt, | ||
uint256 controllerVersion, | ||
uint256 getId, | ||
uint256 setId | ||
) external returns (string memory _eventName, bytes memory _eventParam) { | ||
uint _amt = getUint(getId, debtAmt); | ||
|
||
bool _isEth = collateral == ethAddr; | ||
|
||
address _collateralAddress = _isEth ? wethAddr : collateral; | ||
IController controller = getController(_collateralAddress, controllerVersion); | ||
|
||
uint256[4] memory res = controller.user_state(address(this)); | ||
uint256 _debtAmt = debtAmt == uint(-1) | ||
? controller.max_borrowable(res[0], res[3]) - res[2] | ||
: debtAmt; | ||
|
||
controller.borrow_more(0, _debtAmt); | ||
|
||
setUint(setId, _amt); | ||
_eventName = "LogBorrowMore(address,uint256,uint256,uin256,uin256)"; | ||
_eventParam = abi.encode(collateral, debtAmt, controllerVersion, getId, setId); | ||
} | ||
|
||
/** | ||
* @dev Borrow more stablecoins while adding more collateral (not necessary) | ||
* @param collateral Collateral token address.(For ETH: `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`) | ||
* @param colAmt Collateral amount for borrow more (For max: `uint256(-1)`) | ||
* @param debtAmt Stablecoin debt to take for borrow more (For max: `uint256(-1)`) | ||
* @param controllerVersion controller version | ||
* @param getId ID to retrieve amt. | ||
* @param setId ID stores the amount of tokens deposited. | ||
*/ | ||
function addCollateralAndBorrowMore( | ||
address collateral, | ||
uint256 colAmt, | ||
uint256 debtAmt, | ||
uint256 controllerVersion, | ||
uint256 getId, | ||
uint256 setId | ||
) external returns (string memory _eventName, bytes memory _eventParam) { | ||
uint _amt = getUint(getId, colAmt); | ||
|
||
bool _isEth = collateral == ethAddr; | ||
address _collateralAddress = _isEth ? wethAddr : collateral; | ||
TokenInterface collateralContract = TokenInterface(_collateralAddress); | ||
|
||
IController controller = getController(_collateralAddress, controllerVersion); | ||
|
||
if (_isEth) { | ||
_amt = _amt == uint(-1) ? address(this).balance : _amt; | ||
convertEthToWeth(_isEth, collateralContract, _amt); | ||
} else { | ||
_amt = _amt == uint(-1) ? collateralContract.balanceOf(address(this)) : _amt; | ||
} | ||
|
||
approve(collateralContract, address(controller), _amt); | ||
|
||
uint256[4] memory res = controller.user_state(address(this)); | ||
uint256 _debtAmt = debtAmt == uint(-1) | ||
? controller.max_borrowable(_amt + res[0], res[3]) - res[2] | ||
: debtAmt; | ||
|
||
controller.borrow_more(_amt, _debtAmt); | ||
|
||
setUint(setId, _amt); | ||
_eventName = "LogAddCollateralAndBorrowMore(address,uint256,uint256,uint256,uin256,uin256)"; | ||
_eventParam = abi.encode(collateral, colAmt, debtAmt, controllerVersion, getId, setId); | ||
} | ||
|
||
/** | ||
* @dev Repay Curve-USD. | ||
* @param collateral Collateral token address.(For ETH: `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`) | ||
* @param amt repay amount (For max: `uint256(-1)`) | ||
* @param controllerVersion Controller version. | ||
* @param getId ID to retrieve amt. | ||
* @param setId ID stores the amount of debt borrowed. | ||
*/ | ||
function repay( | ||
address collateral, | ||
uint256 amt, | ||
uint256 controllerVersion, | ||
uint256 getId, | ||
uint256 setId | ||
) external payable returns (string memory _eventName, bytes memory _eventParam) { | ||
uint _amt = getUint(getId, amt); | ||
|
||
bool _isEth = collateral == ethAddr; | ||
address _collateralAddress = _isEth ? wethAddr : collateral; | ||
IController controller = getController(_collateralAddress, controllerVersion); | ||
|
||
TokenInterface stableCoin = TokenInterface(CRV_USD); | ||
_amt = _amt == uint(-1) ? stableCoin.balanceOf(address(this)) : _amt; | ||
|
||
approve(stableCoin, address(controller), _amt); | ||
|
||
controller.repay(_amt); | ||
|
||
setUint(setId, _amt); | ||
_eventName = "LogRepay(address,uint256,uint256,uint256,uint256)"; | ||
_eventParam = abi.encode(collateral, amt, controllerVersion, getId, setId); | ||
} | ||
|
||
/** | ||
* @dev Peform a bad liquidation (or self-liquidation) of user if health is not good | ||
* @param collateral collateral token address | ||
* @param minReceiveAmt Minimal amount of stablecoin to receive (to avoid liquidators being sandwiched) | ||
* @param controllerVersion controller version. | ||
* @param getId ID to retrieve amt. | ||
* @param setId ID stores the amount of debt borrowed. | ||
*/ | ||
function selfLiquidate( | ||
address collateral, | ||
uint256 minReceiveAmt, | ||
uint256 controllerVersion, | ||
uint256 getId, | ||
uint256 setId | ||
) external payable returns (string memory _eventName, bytes memory _eventParam) { | ||
uint _minReceiveAmt = getUint(getId, minReceiveAmt); | ||
|
||
bool _isEth = collateral == ethAddr; | ||
address _collateralAddress = _isEth ? wethAddr : collateral; | ||
IController controller = getController(_collateralAddress, controllerVersion); | ||
|
||
TokenInterface stableCoin = TokenInterface(CRV_USD); | ||
approve(stableCoin, address(controller), _minReceiveAmt); | ||
|
||
controller.liquidate(address(this), _minReceiveAmt, _isEth); | ||
|
||
setUint(setId, _minReceiveAmt); | ||
_eventName = "LogLiquidate(address,uint256,uint256,uint256,uint256)"; | ||
_eventParam = abi.encode(collateral, _minReceiveAmt, controllerVersion, getId, setId); | ||
} | ||
} | ||
|
||
contract ConnectV2CurveUSD is CurveUSDResolver { | ||
string public constant name = "CurveUSD-v1.0"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.