Vault.sol
Setup
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
import "lib/chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "lib/yield-utils-v2/contracts/token/IERC20.sol";
import "lib/openzeppelin-contracts/contracts/access/Ownable.sol";
contract Vault is Ownable {
//vault records DEPOSITS & Debt
mapping (address => uint) public deposits; //deposits in WETH
mapping (address => uint) public debts; //debt in DAI
///@notice ERC20 interface specifying token contract functions
///@dev For constant variables, the value has to be fixed at compile-time, while for immutable, it can still be assigned at construction time.
IERC20 public immutable collateral;
IERC20 public immutable debt;
// DAi/WETH Pricefeed
AggregatorV3Interface public immutable priceFeed;
event Deposit(address indexed collateralAsset, address indexed user, uint collateralAmount);
event Borrow(address indexed debtAsset, address indexed user, uint debtAmount);
event Repay(address indexed debtAsset, address indexed user, uint debtAmount);
event Withdraw(address indexed collateralAsset, address indexed user, uint collateralAmount);
event Liquidation(address indexed collateralAsset, address indexed debtAsset, address indexed user, uint debtToCover, uint liquidatedCollateralAmount);
uint bufferDenominator;
uint bufferNumerator;
constructor(address dai_, address weth_, address priceFeedAddress, uint bufferNumerator_, uint bufferDenominator_) {
collateral = IERC20(weth_);
debt = IERC20(dai_);
priceFeed = AggregatorV3Interface(priceFeedAddress);
// collateralization level
bufferNumerator = bufferNumerator_;
bufferDenominator = bufferDenominator_;
}mappings to track deposits & debt for each user address
IERC20 interfaces to interact with both the DAI and WETH contracts
AggregatorV3Interface for interacting with Chainlink Oracle
use of immutable vs constant
for constant variables, the value has to be fixed at compile-time, (initial and assign in one line)
for immutable, it can still be assigned at construction time (within constructor)
Margin level
buffer Num/Denominator for setting margin level: 8/10 -> 80%
80% collateralization level.
maxDebt is calculated against 80% of deposits.
Functions
deposit()
borrow()
can borrow up till maxDebt as calculated below
getMaxDebt()
based on user's deposits, calculate the available collateral, as per specified Margin level
convert availableCollateral to the quantity of corresponding debtAsset as per mkt price
repay()
covers partial and full repayments
withdraw()
users can withdraw their deposited collateral
if user has debt, checks for spare capacity before initiating withdrawal
getCollateralRequired()
Calculates collateral required to support existing debt position at current market prices
it is important to do the multiplication before the division in the pricing calculation
because leading with a division may result in a decimal -> which solidity cannot handle
liquidation()
Triggers liquidation check on supplied user address
Can only be called by Vault owner;
if collateralRequired > deposits[user] -> liquidation
get_daiETH_price()
Get current market price of Collateral/Debt asset from Chainlink
Price is returned as integer extending over its decimal places
getDecimals()
Returns number of decimal places in price returned
Using get_daiETH_price & getDecimals() together
getPrice returns: 386372840000000
getDecimals returns: 18
Used to rebase chainlink price into market price, to account for decimal places
price = 386372840000000, decimals =18, actual_price = 0.00038637284
actual price should match the market price as quotes by websites and frontends.
Full code
Last updated