From 77be1963d142a9cc7dd1cacc7f3e5b8523dff487 Mon Sep 17 00:00:00 2001 From: emilio Date: Thu, 9 Jul 2020 11:59:49 +0200 Subject: [PATCH] added comments, cleaned up variable debt token, base debt token --- contracts/tokenization/VariableDebtToken.sol | 93 ++++++----- contracts/tokenization/base/DebtTokenBase.sol | 148 +++++++----------- .../interfaces/IVariableDebtToken.sol | 27 +++- test/helpers/utils/calculations.ts | 1 - 4 files changed, 136 insertions(+), 133 deletions(-) diff --git a/contracts/tokenization/VariableDebtToken.sol b/contracts/tokenization/VariableDebtToken.sol index 7ed60615..23760821 100644 --- a/contracts/tokenization/VariableDebtToken.sol +++ b/contracts/tokenization/VariableDebtToken.sol @@ -9,6 +9,12 @@ import {WadRayMath} from '../libraries/WadRayMath.sol'; import '@nomiclabs/buidler/console.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 { using SafeMath for uint256; using WadRayMath for uint256; @@ -16,6 +22,15 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { 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( address _user, uint256 _amount, @@ -24,6 +39,16 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { uint256 _balanceIncrease, 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( address _user, uint256 _amount, @@ -33,19 +58,16 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { uint256 _index ); - /** - * @dev See {IERC20-balanceOf}. - */ - function balanceOf(address account) public virtual override view returns (uint256) { - if (balances[account] == 0) { + function balanceOf(address _user) public virtual override view returns (uint256) { + if (balances[_user] == 0) { return 0; } return - balances[account] + balances[_user] .wadToRay() .rayMul(pool.getReserveNormalizedVariableDebt(underlyingAssetAddress)) - .rayDiv(userIndexes[account]) + .rayDiv(userIndexes[_user]) .rayToWad(); } @@ -53,57 +75,48 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { return userIndexes[_user]; } - /** @dev Creates `amount` tokens and assigns them to `account`, increasing - * the total supply. - * - * Emits a {Transfer} event with `from` set to the zero address. - * - * Requirements - * - * - `to` cannot be the zero address. - */ - function mint(address account, uint256 amount) public override onlyLendingPool { + + /** + * @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) public override onlyLendingPool { ( uint256 previousBalance, uint256 currentBalance, 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 - * total supply. - * - * Emits a {Transfer} event with `to` set to the zero address. - * - * Requirements - * - * - `account` cannot be the zero address. - * - `account` must have at least `amount` tokens. - */ - function burn(address account, uint256 amount) public override onlyLendingPool { + * @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) public override onlyLendingPool { ( uint256 previousBalance, uint256 currentBalance, uint256 balanceIncrease - ) = internalCumulateBalance(account); + ) = _cumulateBalance(_user); - _burn(account, amount); + _burn(_user, _amount); //if user repaid everything - if (currentBalance == amount) { - userIndexes[account] = 0; + if (currentBalance == _amount) { + userIndexes[_user] = 0; } 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 * and the new user index **/ - function internalCumulateBalance(address _user) + function _cumulateBalance(address _user) internal returns ( uint256, @@ -129,7 +142,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { //calculate the accrued interest since the last accumulation 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); return ( diff --git a/contracts/tokenization/base/DebtTokenBase.sol b/contracts/tokenization/base/DebtTokenBase.sol index 4e0b227c..fa2b87e7 100644 --- a/contracts/tokenization/base/DebtTokenBase.sol +++ b/contracts/tokenization/base/DebtTokenBase.sol @@ -1,13 +1,17 @@ pragma solidity ^0.6.0; -import '@openzeppelin/contracts/GSN/Context.sol'; -import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import '@openzeppelin/contracts/math/SafeMath.sol'; -import '@openzeppelin/contracts/utils/Address.sol'; +import {Context} from '@openzeppelin/contracts/GSN/Context.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol'; +import {Address} from '@openzeppelin/contracts/utils/Address.sol'; import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol'; import {LendingPool} from '../../lendingpool/LendingPool.sol'; - +/** +* @title contract DebtTokenBase +* @author Aave +* @notice base contract for StableDebtToken and VariableDebtToken +*/ abstract contract DebtTokenBase is IERC20 { using SafeMath for uint256; using Address for address; @@ -16,31 +20,27 @@ abstract contract DebtTokenBase is IERC20 { string public name; string public symbol; - uint8 public decimals; + uint8 public decimals; address public underlyingAssetAddress; LendingPool internal pool; mapping(address => uint256) internal balances; - - - modifier onlyLendingPool { - require( - msg.sender == address(pool), - "The caller of this function must be a lending pool" - ); - _; - } - + /** + * @dev only lending pool can call functions marked by this modifier + **/ + modifier onlyLendingPool { + require(msg.sender == address(pool), 'INVALID_CALLER'); + _; + } /** - * @dev Sets the values for {name} and {symbol}, initializes {decimals} with - * a default value of 18. - * - * To select a different value for {decimals}, use {_setupDecimals}. - * - * All three of these values are immutable: they can only be set once during - * construction. + * @dev initializes the debt token. + * @param _name the name of the token + * @param _symbol the symbol of the token + * @param _decimals the decimals of the token + * @param _underlying the underlying asset of the debt token + * @param _addressesProvider the addresses provider of the protocol */ function init( string memory _name, @@ -56,35 +56,48 @@ abstract contract DebtTokenBase is IERC20 { 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}. - */ - function balanceOf(address account) public virtual override view returns (uint256); - - - /** - * @dev See {IERC20-balanceOf}. - */ - function principalBalanceOf(address account) public view returns (uint256) { - return balances[account]; + * @dev returns the principal debt balance of the user from + * @return the debt balance of the user since the last burn/mint action + **/ + function principalBalanceOf(address _user) public view returns (uint256) { + return balances[_user]; } /** - * @dev See {IERC20-transfer}. - * - * Requirements: - * - * - `recipient` cannot be the zero address. - * - the caller must have a balance of at least `amount`. - */ - function transfer(address recipient, uint256 amount) public virtual override returns (bool) { + * @dev basic accounting for the mint action + * @dev _user the target user of the minting action + * @dev _amount the amount to mint + **/ + function _mint(address _user, uint256 _amount) internal { + totalSupply = totalSupply.add(_amount); + balances[_user] = balances[_user].add(_amount); + } + + /** + * @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'); } - /** - * @dev See {IERC20-allowance}. - */ function allowance(address owner, address spender) public virtual @@ -95,55 +108,22 @@ abstract contract DebtTokenBase is IERC20 { revert('ALLOWANCE_NOT_SUPPORTED'); } - /** - * @dev See {IERC20-approve}. - * - * Requirements: - * - * - `spender` cannot be the zero address. - */ - function approve(address spender, uint256 amount) public virtual override returns (bool) { + function approve(address spender, uint256 _amount) public virtual override returns (bool) { revert('APPROVAL_NOT_SUPPORTED'); } function transferFrom( address sender, address recipient, - uint256 amount + uint256 _amount ) public virtual override returns (bool) { 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) { 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) public virtual @@ -151,14 +131,4 @@ abstract contract DebtTokenBase is IERC20 { { 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); - } } diff --git a/contracts/tokenization/interfaces/IVariableDebtToken.sol b/contracts/tokenization/interfaces/IVariableDebtToken.sol index 4cb7f41f..9ee80478 100644 --- a/contracts/tokenization/interfaces/IVariableDebtToken.sol +++ b/contracts/tokenization/interfaces/IVariableDebtToken.sol @@ -1,11 +1,32 @@ 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 { - 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); } diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index 1fb50fee..298ba346 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -1209,7 +1209,6 @@ const calcExpectedAverageStableBorrowRate = ( amountChanged: string | BigNumber, rate: BigNumber ) => { - console.log(avgStableRateBefore, totalBorrowsStableBefore); const weightedTotalBorrows = avgStableRateBefore.multipliedBy(totalBorrowsStableBefore); const weightedAmountBorrowed = rate.multipliedBy(amountChanged); const totalBorrowedStable = totalBorrowsStableBefore.plus(new BigNumber(amountChanged));