added comments, cleaned up variable debt token, base debt token

This commit is contained in:
emilio 2020-07-09 11:59:49 +02:00
parent 7813e8cec0
commit 77be1963d1
4 changed files with 136 additions and 133 deletions

View File

@ -9,6 +9,12 @@ import {WadRayMath} from '../libraries/WadRayMath.sol';
import '@nomiclabs/buidler/console.sol'; import '@nomiclabs/buidler/console.sol';
import {IVariableDebtToken} from './interfaces/IVariableDebtToken.sol'; import {IVariableDebtToken} from './interfaces/IVariableDebtToken.sol';
/**
* @title interface IVariableDebtToken
* @author Aave
* @notice defines the basic interface for a variable debt token.
* @dev does not inherit from IERC20 to save in contract size
**/
contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
using SafeMath for uint256; using SafeMath for uint256;
using WadRayMath for uint256; using WadRayMath for uint256;
@ -16,6 +22,15 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
mapping(address => uint256) private userIndexes; mapping(address => uint256) private userIndexes;
/**
* @dev emitted when new variable debt is minted
* @param _user the user receiving the debt
* @param _amount the amount of debt being minted
* @param _previousBalance the previous balance of the user
* @param _currentBalance the current balance of the user
* @param _balanceIncrease the debt accumulated since the last action
* @param _index the index of the user
**/
event mintDebt( event mintDebt(
address _user, address _user,
uint256 _amount, uint256 _amount,
@ -24,6 +39,16 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
uint256 _balanceIncrease, uint256 _balanceIncrease,
uint256 _index uint256 _index
); );
/**
* @dev emitted when variable debt is burnt
* @param _user the user which debt has been burned
* @param _amount the amount of debt being burned
* @param _previousBalance the previous balance of the user
* @param _currentBalance the current balance of the user
* @param _balanceIncrease the debt accumulated since the last action
* @param _index the index of the user
**/
event burnDebt( event burnDebt(
address _user, address _user,
uint256 _amount, uint256 _amount,
@ -33,19 +58,16 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
uint256 _index uint256 _index
); );
/** function balanceOf(address _user) public virtual override view returns (uint256) {
* @dev See {IERC20-balanceOf}. if (balances[_user] == 0) {
*/
function balanceOf(address account) public virtual override view returns (uint256) {
if (balances[account] == 0) {
return 0; return 0;
} }
return return
balances[account] balances[_user]
.wadToRay() .wadToRay()
.rayMul(pool.getReserveNormalizedVariableDebt(underlyingAssetAddress)) .rayMul(pool.getReserveNormalizedVariableDebt(underlyingAssetAddress))
.rayDiv(userIndexes[account]) .rayDiv(userIndexes[_user])
.rayToWad(); .rayToWad();
} }
@ -53,57 +75,48 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
return userIndexes[_user]; return userIndexes[_user];
} }
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply. /**
* * @dev mints new variable debt
* Emits a {Transfer} event with `from` set to the zero address. * @param _user the user receiving the debt
* * @param _amount the amount of debt being minted
* Requirements **/
* function mint(address _user, uint256 _amount) public override onlyLendingPool {
* - `to` cannot be the zero address.
*/
function mint(address account, uint256 amount) public override onlyLendingPool {
( (
uint256 previousBalance, uint256 previousBalance,
uint256 currentBalance, uint256 currentBalance,
uint256 balanceIncrease uint256 balanceIncrease
) = internalCumulateBalance(account); ) = _cumulateBalance(_user);
_mint(account, amount); _mint(_user, _amount);
userIndexes[account] = pool.getReserveNormalizedVariableDebt(underlyingAssetAddress); userIndexes[_user] = pool.getReserveNormalizedVariableDebt(underlyingAssetAddress);
emit mintDebt(account, amount, previousBalance, currentBalance, balanceIncrease, userIndexes[account]); emit mintDebt(_user, _amount, previousBalance, currentBalance, balanceIncrease, userIndexes[_user]);
} }
/** /**
* @dev Destroys `amount` tokens from `account`, reducing the * @dev burns user variable debt
* total supply. * @param _user the user which debt is burnt
* * @param _amount the amount of debt being burned
* Emits a {Transfer} event with `to` set to the zero address. **/
* function burn(address _user, uint256 _amount) public override onlyLendingPool {
* Requirements
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function burn(address account, uint256 amount) public override onlyLendingPool {
( (
uint256 previousBalance, uint256 previousBalance,
uint256 currentBalance, uint256 currentBalance,
uint256 balanceIncrease uint256 balanceIncrease
) = internalCumulateBalance(account); ) = _cumulateBalance(_user);
_burn(account, amount); _burn(_user, _amount);
//if user repaid everything //if user repaid everything
if (currentBalance == amount) { if (currentBalance == _amount) {
userIndexes[account] = 0; userIndexes[_user] = 0;
} else { } else {
userIndexes[account] = pool.getReserveNormalizedVariableDebt(underlyingAssetAddress); userIndexes[_user] = pool.getReserveNormalizedVariableDebt(underlyingAssetAddress);
} }
emit burnDebt(account, amount, previousBalance, currentBalance, balanceIncrease, userIndexes[account]); emit burnDebt(_user, _amount, previousBalance, currentBalance, balanceIncrease, userIndexes[_user]);
} }
/** /**
@ -112,7 +125,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
* @return the previous principal balance, the new principal balance, the balance increase * @return the previous principal balance, the new principal balance, the balance increase
* and the new user index * and the new user index
**/ **/
function internalCumulateBalance(address _user) function _cumulateBalance(address _user)
internal internal
returns ( returns (
uint256, uint256,
@ -129,7 +142,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
//calculate the accrued interest since the last accumulation //calculate the accrued interest since the last accumulation
uint256 balanceIncrease = balanceOf(_user).sub(previousPrincipalBalance); uint256 balanceIncrease = balanceOf(_user).sub(previousPrincipalBalance);
//mints an amount of tokens equivalent to the amount accumulated //mints an _amount of tokens equivalent to the _amount accumulated
_mint(_user, balanceIncrease); _mint(_user, balanceIncrease);
return ( return (

View File

@ -1,13 +1,17 @@
pragma solidity ^0.6.0; pragma solidity ^0.6.0;
import '@openzeppelin/contracts/GSN/Context.sol'; import {Context} from '@openzeppelin/contracts/GSN/Context.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@openzeppelin/contracts/math/SafeMath.sol'; import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
import '@openzeppelin/contracts/utils/Address.sol'; import {Address} from '@openzeppelin/contracts/utils/Address.sol';
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol'; import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
import {LendingPool} from '../../lendingpool/LendingPool.sol'; import {LendingPool} from '../../lendingpool/LendingPool.sol';
/**
* @title contract DebtTokenBase
* @author Aave
* @notice base contract for StableDebtToken and VariableDebtToken
*/
abstract contract DebtTokenBase is IERC20 { abstract contract DebtTokenBase is IERC20 {
using SafeMath for uint256; using SafeMath for uint256;
using Address for address; using Address for address;
@ -22,25 +26,21 @@ abstract contract DebtTokenBase is IERC20 {
LendingPool internal pool; LendingPool internal pool;
mapping(address => uint256) internal balances; mapping(address => uint256) internal balances;
/**
* @dev only lending pool can call functions marked by this modifier
**/
modifier onlyLendingPool { modifier onlyLendingPool {
require( require(msg.sender == address(pool), 'INVALID_CALLER');
msg.sender == address(pool),
"The caller of this function must be a lending pool"
);
_; _;
} }
/** /**
* @dev Sets the values for {name} and {symbol}, initializes {decimals} with * @dev initializes the debt token.
* a default value of 18. * @param _name the name of the token
* * @param _symbol the symbol of the token
* To select a different value for {decimals}, use {_setupDecimals}. * @param _decimals the decimals of the token
* * @param _underlying the underlying asset of the debt token
* All three of these values are immutable: they can only be set once during * @param _addressesProvider the addresses provider of the protocol
* construction.
*/ */
function init( function init(
string memory _name, string memory _name,
@ -56,35 +56,48 @@ abstract contract DebtTokenBase is IERC20 {
pool = LendingPool(payable(_addressesProvider.getLendingPool())); pool = LendingPool(payable(_addressesProvider.getLendingPool()));
} }
/**
* @dev calculates the accumulated debt balance of the user
* @return the debt balance of the user
**/
function balanceOf(address _user) public virtual override view returns (uint256);
/** /**
* @dev See {IERC20-balanceOf}. * @dev returns the principal debt balance of the user from
*/ * @return the debt balance of the user since the last burn/mint action
function balanceOf(address account) public virtual override view returns (uint256); **/
function principalBalanceOf(address _user) public view returns (uint256) {
return balances[_user];
/**
* @dev See {IERC20-balanceOf}.
*/
function principalBalanceOf(address account) public view returns (uint256) {
return balances[account];
} }
/** /**
* @dev See {IERC20-transfer}. * @dev basic accounting for the mint action
* * @dev _user the target user of the minting action
* Requirements: * @dev _amount the amount to mint
* **/
* - `recipient` cannot be the zero address. function _mint(address _user, uint256 _amount) internal {
* - the caller must have a balance of at least `amount`. totalSupply = totalSupply.add(_amount);
*/ balances[_user] = balances[_user].add(_amount);
function transfer(address recipient, uint256 amount) public virtual override returns (bool) { }
/**
* @dev basic accounting for the burn action
* @dev _user the target user of the burning action
* @dev _amount the amount to burn
**/
function _burn(address _user, uint256 _amount) internal {
totalSupply = totalSupply.sub(_amount);
balances[_user] = balances[_user].sub(_amount);
}
/**
* @dev being non transferrable, the debt token does not implement any of the
* standard ERC20 functions for transfer and allowance.
**/
function transfer(address recipient, uint256 _amount) public virtual override returns (bool) {
revert('TRANSFER_NOT_SUPPORTED'); revert('TRANSFER_NOT_SUPPORTED');
} }
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) function allowance(address owner, address spender)
public public
virtual virtual
@ -95,55 +108,22 @@ abstract contract DebtTokenBase is IERC20 {
revert('ALLOWANCE_NOT_SUPPORTED'); revert('ALLOWANCE_NOT_SUPPORTED');
} }
/** function approve(address spender, uint256 _amount) public virtual override returns (bool) {
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
revert('APPROVAL_NOT_SUPPORTED'); revert('APPROVAL_NOT_SUPPORTED');
} }
function transferFrom( function transferFrom(
address sender, address sender,
address recipient, address recipient,
uint256 amount uint256 _amount
) public virtual override returns (bool) { ) public virtual override returns (bool) {
revert('TRANSFER_NOT_SUPPORTED'); revert('TRANSFER_NOT_SUPPORTED');
} }
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
revert('ALLOWANCE_NOT_SUPPORTED'); revert('ALLOWANCE_NOT_SUPPORTED');
} }
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) function decreaseAllowance(address spender, uint256 subtractedValue)
public public
virtual virtual
@ -151,14 +131,4 @@ abstract contract DebtTokenBase is IERC20 {
{ {
revert('ALLOWANCE_NOT_SUPPORTED'); revert('ALLOWANCE_NOT_SUPPORTED');
} }
function _mint(address account, uint256 amount) internal {
totalSupply = totalSupply.add(amount);
balances[account] = balances[account].add(amount);
}
function _burn(address account, uint256 amount) internal {
totalSupply = totalSupply.sub(amount);
balances[account] = balances[account].sub(amount);
}
} }

View File

@ -1,11 +1,32 @@
pragma solidity ^0.6.0; pragma solidity ^0.6.0;
/**
* @title interface IVariableDebtToken
* @author Aave
* @notice defines the basic interface for a variable debt token.
* @dev does not inherit from IERC20 to save in contract size
**/
interface IVariableDebtToken { interface IVariableDebtToken {
function mint(address account, uint256 amount) external virtual; /**
* @dev mints new variable debt
* @param _user the user receiving the debt
* @param _amount the amount of debt being minted
**/
function mint(address _user, uint256 _amount) external virtual;
function burn(address _account, uint256 _amount) external virtual; /**
* @dev burns user variable debt
* @param _user the user which debt is burnt
* @param _amount the amount of debt being burned
**/
function burn(address _user, uint256 _amount) external virtual;
/**
* @dev returns the last index of the user
* @return the index of the user
**/
function getUserIndex(address _user) external virtual view returns(uint256);
function getUserIndex(address _account) external virtual view returns(uint256);
} }

View File

@ -1209,7 +1209,6 @@ const calcExpectedAverageStableBorrowRate = (
amountChanged: string | BigNumber, amountChanged: string | BigNumber,
rate: BigNumber rate: BigNumber
) => { ) => {
console.log(avgStableRateBefore, totalBorrowsStableBefore);
const weightedTotalBorrows = avgStableRateBefore.multipliedBy(totalBorrowsStableBefore); const weightedTotalBorrows = avgStableRateBefore.multipliedBy(totalBorrowsStableBefore);
const weightedAmountBorrowed = rate.multipliedBy(amountChanged); const weightedAmountBorrowed = rate.multipliedBy(amountChanged);
const totalBorrowedStable = totalBorrowsStableBefore.plus(new BigNumber(amountChanged)); const totalBorrowedStable = totalBorrowsStableBefore.plus(new BigNumber(amountChanged));