- Reviewed tokenization documentation-wise

- Moved interaces in protocol/tokenization to the general interfaces/ folder.
This commit is contained in:
eboado 2020-11-26 10:21:18 +01:00
parent 92a731ec2c
commit 7bcdce3090
21 changed files with 505 additions and 511 deletions

View File

@ -0,0 +1,88 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.12;
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
import {IScaledBalanceToken} from './IScaledBalanceToken.sol';
interface IAToken is IERC20, IScaledBalanceToken {
/**
* @dev Emitted after the mint action
* @param from The address performing the mint
* @param value The amount being
* @param index The new liquidity index of the reserve
**/
event Mint(address indexed from, uint256 value, uint256 index);
/**
* @dev Mints `amount` aTokens to `user`
* @param user The address receiving the minted tokens
* @param amount The amount of tokens getting minted
* @param index The new liquidity index of the reserve
* @return `true` if the the previous balance of the user was 0
*/
function mint(
address user,
uint256 amount,
uint256 index
) external returns (bool);
/**
* @dev Emitted after aTokens are burned
* @param from The owner of the aTokens, getting them burned
* @param target The address that will receive the underlying
* @param value The amount being burned
* @param index The new liquidity index of the reserve
**/
event Burn(address indexed from, address indexed target, uint256 value, uint256 index);
/**
* @dev Emitted during the transfer action
* @param from The user whose tokens are being transferred
* @param to The recipient
* @param value The amount being transferred
* @param index The new liquidity index of the reserve
**/
event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index);
/**
* @dev Burns aTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying`
* @param user The owner of the aTokens, getting them burned
* @param receiverOfUnderlying The address that will receive the underlying
* @param amount The amount being burned
* @param index The new liquidity index of the reserve
**/
function burn(
address user,
address receiverOfUnderlying,
uint256 amount,
uint256 index
) external;
/**
* @dev Mints aTokens to the reserve treasury
* @param amount The amount of tokens getting minted
* @param index The new liquidity index of the reserve
*/
function mintToTreasury(uint256 amount, uint256 index) external;
/**
* @dev Transfers aTokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken
* @param from The address getting liquidated, current owner of the aTokens
* @param to The recipient
* @param value The amount of tokens getting transferred
**/
function transferOnLiquidation(
address from,
address to,
uint256 value
) external;
/**
* @dev Transfers the underlying asset to `target`. Used by the LendingPool to transfer
* assets in borrow(), redeem() and flashLoan()
* @param user The recipient of the aTokens
* @param amount The amount getting transferred
* @return The amount transferred
**/
function transferUnderlyingTo(address user, uint256 amount) external returns (uint256);
}

View File

@ -0,0 +1,11 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.12;
/**
* @title IDelegationToken
* @dev Implements an interface for tokens that have a delegation function
* @author Aave
**/
interface IDelegationToken {
function delegate(address delegatee) external;
}

View File

@ -3,24 +3,24 @@ pragma solidity 0.6.12;
interface IScaledBalanceToken { interface IScaledBalanceToken {
/** /**
* @dev returns the principal balance of the user. The principal balance is the last * @dev Returns the principal balance of the user. The principal balance is the last
* updated stored balance, which does not consider the perpetually accruing interest. * updated stored balance, which does not consider the perpetually accruing interest.
* @param user the address of the user * @param user The address of the user
* @return the principal balance of the user * @return The principal balance of the user
**/ **/
function scaledBalanceOf(address user) external view returns (uint256); function scaledBalanceOf(address user) external view returns (uint256);
/** /**
* @dev returns the principal balance of the user and principal total supply. * @dev Returns the principal balance of the user and principal total supply.
* @param user the address of the user * @param user The address of the user
* @return the principal balance of the user * @return The principal balance of the user
* @return the principal total supply * @return The principal total supply
**/ **/
function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256); function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256);
/** /**
* @dev Returns the scaled total supply of the variable debt token. Represents sum(debt/index) * @dev Returns the scaled total supply of the variable debt token. Represents sum(debt/index)
* @return the scaled total supply * @return The scaled total supply
**/ **/
function scaledTotalSupply() external view returns (uint256); function scaledTotalSupply() external view returns (uint256);
} }

View File

@ -0,0 +1,123 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.12;
/**
* @title IStableDebtToken
* @notice Defines the interface for the stable debt token
* @dev It does not inherit from IERC20 to save in code size
* @author Aave
**/
interface IStableDebtToken {
/**
* @dev Emitted when new stable debt is minted
* @param user The address of the user who triggered the minting
* @param onBehalfOf The recipient of aTokens
* @param amount The amount minted
* @param currentBalance The current balance of the user
* @param balanceIncrease The increase in balance since the last action of the user
* @param newRate The rate of the debt after the minting
* @param avgStableRate The new average stable rate after the minting
* @param newTotalSupply The new total supply of the stable debt token after the action
**/
event Mint(
address indexed user,
address indexed onBehalfOf,
uint256 amount,
uint256 currentBalance,
uint256 balanceIncrease,
uint256 newRate,
uint256 avgStableRate,
uint256 newTotalSupply
);
/**
* @dev Emitted when new stable debt is burned
* @param user The address of the user
* @param amount The amount minted
* @param currentBalance The current balance of the user
* @param balanceIncrease The the increase in balance since the last action of the user
* @param avgStableRate The new average stable rate after the minting
* @param newTotalSupply The new total supply of the stable debt token after the action
**/
event Burn(
address indexed user,
uint256 amount,
uint256 currentBalance,
uint256 balanceIncrease,
uint256 avgStableRate,
uint256 newTotalSupply
);
/**
* @dev Mints debt token to the `onBehalfOf` address.
* - The resulting rate is the weighted average between the rate of the new debt
* and the rate of the previous debt
* @param user The address receiving the borrowed underlying, being the delegatee in case
* of credit delegate, or same as `onBehalfOf` otherwise
* @param onBehalfOf The address receiving the debt tokens
* @param amount The amount of debt tokens to mint
* @param rate The rate of the debt being minted
**/
function mint(
address user,
address onBehalfOf,
uint256 amount,
uint256 rate
) external returns (bool);
/**
* @dev Burns debt of `user`
* @param user The address of the user getting his debt burned
* @param amount The amount of debt tokens getting burned
**/
function burn(address user, uint256 amount) external;
/**
* @dev Returns the average rate of all the stable rate loans.
* @return The average stable rate
**/
function getAverageStableRate() external view returns (uint256);
/**
* @dev Returns the stable rate of the user debt
* @return The stable rate of the user
**/
function getUserStableRate(address user) external view returns (uint256);
/**
* @dev Returns the timestamp of the last update of the user
* @return The timestamp
**/
function getUserLastUpdated(address user) external view returns (uint40);
/**
* @dev Returns the principal, the total supply and the average stable rate
**/
function getSupplyData()
external
view
returns (
uint256,
uint256,
uint256,
uint40
);
/**
* @dev Returns the timestamp of the last update of the total supply
* @return The timestamp
**/
function getTotalSupplyLastUpdated() external view returns (uint40);
/**
* @dev Returns the total supply and the average stable rate
**/
function getTotalSupplyAndAvgRate() external view returns (uint256, uint256);
/**
* @dev Returns the principal debt balance of the user
* @return The debt balance of the user since the last burn/mint action
**/
function principalBalanceOf(address user) external view returns (uint256);
}

View File

@ -1,10 +1,10 @@
// SPDX-License-Identifier: agpl-3.0 // SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6; pragma solidity ^0.6.12;
/** /**
* @title ITokenConfiguration * @title ITokenConfiguration
* @author Aave * @author Aave
* @dev common interface between aTokens and debt tokens to fetch the * @dev Common interface between aTokens and debt tokens to fetch the
* token configuration * token configuration
**/ **/
interface ITokenConfiguration { interface ITokenConfiguration {

View File

@ -0,0 +1,55 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.12;
import {IScaledBalanceToken} from './IScaledBalanceToken.sol';
/**
* @title IVariableDebtToken
* @author Aave
* @notice Defines the basic interface for a variable debt token.
**/
interface IVariableDebtToken is IScaledBalanceToken {
/**
* @dev Emitted after the mint action
* @param from The address performing the mint
* @param onBehalfOf The address of the user on which behalf minting has been performed
* @param value The amount to be minted
* @param index The last index of the reserve
**/
event Mint(address indexed from, address indexed onBehalfOf, uint256 value, uint256 index);
/**
* @dev Mints debt token to the `onBehalfOf` address
* @param user The address receiving the borrowed underlying, being the delegatee in case
* of credit delegate, or same as `onBehalfOf` otherwise
* @param onBehalfOf The address receiving the debt tokens
* @param amount The amount of debt being minted
* @param index The variable debt index of the reserve
* @return `true` if the the previous balance of the user is 0
**/
function mint(
address user,
address onBehalfOf,
uint256 amount,
uint256 index
) external returns (bool);
/**
* @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 index The index of the user
**/
event Burn(address indexed user, uint256 amount, uint256 index);
/**
* @dev Burns user variable debt
* @param user The user which debt is burnt
* @param index The variable debt index of the reserve
**/
function burn(
address user,
uint256 amount,
uint256 index
) external;
}

View File

@ -2,13 +2,13 @@
pragma solidity 0.6.12; pragma solidity 0.6.12;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol';
import {IStableDebtToken} from '../interfaces/IStableDebtToken.sol';
import {IVariableDebtToken} from '../interfaces/IVariableDebtToken.sol';
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol'; import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
import {IStableDebtToken} from '../protocol/tokenization/interfaces/IStableDebtToken.sol';
import {IVariableDebtToken} from '../protocol/tokenization/interfaces/IVariableDebtToken.sol';
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
contract AaveProtocolDataProvider { contract AaveProtocolDataProvider {

View File

@ -2,22 +2,21 @@
pragma solidity 0.6.12; pragma solidity 0.6.12;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol'; import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
import {IUiPoolDataProvider} from './interfaces/IUiPoolDataProvider.sol'; import {IUiPoolDataProvider} from './interfaces/IUiPoolDataProvider.sol';
import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol';
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
import {IAToken} from '../protocol/tokenization/interfaces/IAToken.sol'; import {IAToken} from '../interfaces/IAToken.sol';
import {IVariableDebtToken} from '../protocol/tokenization/interfaces/IVariableDebtToken.sol'; import {IVariableDebtToken} from '../interfaces/IVariableDebtToken.sol';
import {IStableDebtToken} from '../protocol/tokenization/interfaces/IStableDebtToken.sol'; import {IStableDebtToken} from '../interfaces/IStableDebtToken.sol';
import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol'; import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol';
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol'; import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
import { import {
DefaultReserveInterestRateStrategy DefaultReserveInterestRateStrategy
} from '../protocol/lendingpool/DefaultReserveInterestRateStrategy.sol'; } from '../protocol/lendingpool/DefaultReserveInterestRateStrategy.sol';
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
contract UiPoolDataProvider is IUiPoolDataProvider { contract UiPoolDataProvider is IUiPoolDataProvider {
using WadRayMath for uint256; using WadRayMath for uint256;

View File

@ -2,15 +2,15 @@
pragma solidity 0.6.12; pragma solidity 0.6.12;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol';
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
import {IWETH} from './interfaces/IWETH.sol'; import {IWETH} from './interfaces/IWETH.sol';
import {IWETHGateway} from './interfaces/IWETHGateway.sol'; import {IWETHGateway} from './interfaces/IWETHGateway.sol';
import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol';
import {IAToken} from '../protocol/tokenization/interfaces/IAToken.sol'; import {IAToken} from '../interfaces/IAToken.sol';
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol'; import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
import {Helpers} from '../protocol/libraries/helpers/Helpers.sol'; import {Helpers} from '../protocol/libraries/helpers/Helpers.sol';
import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol';
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
contract WETHGateway is IWETHGateway, Ownable { contract WETHGateway is IWETHGateway, Ownable {

View File

@ -4,9 +4,16 @@ pragma experimental ABIEncoderV2;
import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol';
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol'; import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol';
import {Address} from '../../dependencies/openzeppelin/contracts/Address.sol';
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol'; import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
import {IAToken} from '../tokenization/interfaces/IAToken.sol'; import {IAToken} from '../../interfaces/IAToken.sol';
import {IVariableDebtToken} from '../../interfaces/IVariableDebtToken.sol';
import {IFlashLoanReceiver} from '../../flashloan/interfaces/IFlashLoanReceiver.sol';
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
import {IStableDebtToken} from '../../interfaces/IStableDebtToken.sol';
import {ILendingPool} from '../../interfaces/ILendingPool.sol';
import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol';
import {Helpers} from '../libraries/helpers/Helpers.sol'; import {Helpers} from '../libraries/helpers/Helpers.sol';
import {Errors} from '../libraries/helpers/Errors.sol'; import {Errors} from '../libraries/helpers/Errors.sol';
import {WadRayMath} from '../libraries/math/WadRayMath.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol';
@ -16,15 +23,8 @@ import {GenericLogic} from '../libraries/logic/GenericLogic.sol';
import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol'; import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol';
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol'; import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol';
import {IFlashLoanReceiver} from '../../flashloan/interfaces/IFlashLoanReceiver.sol';
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol';
import {ILendingPool} from '../../interfaces/ILendingPool.sol';
import {LendingPoolStorage} from './LendingPoolStorage.sol';
import {Address} from '../../dependencies/openzeppelin/contracts/Address.sol';
import {DataTypes} from '../libraries/types/DataTypes.sol'; import {DataTypes} from '../libraries/types/DataTypes.sol';
import {LendingPoolStorage} from './LendingPoolStorage.sol';
/** /**
* @title LendingPool contract * @title LendingPool contract
@ -76,7 +76,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
); );
} }
function getRevision() internal override pure returns (uint256) { function getRevision() internal pure override returns (uint256) {
return LENDINGPOOL_REVISION; return LENDINGPOOL_REVISION;
} }
@ -251,9 +251,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
variableDebt variableDebt
); );
uint256 paybackAmount = interestRateMode == DataTypes.InterestRateMode.STABLE uint256 paybackAmount =
? stableDebt interestRateMode == DataTypes.InterestRateMode.STABLE ? stableDebt : variableDebt;
: variableDebt;
if (amount < paybackAmount) { if (amount < paybackAmount) {
paybackAmount = amount; paybackAmount = amount;
@ -426,16 +425,17 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
address collateralManager = _addressesProvider.getLendingPoolCollateralManager(); address collateralManager = _addressesProvider.getLendingPoolCollateralManager();
//solium-disable-next-line //solium-disable-next-line
(bool success, bytes memory result) = collateralManager.delegatecall( (bool success, bytes memory result) =
abi.encodeWithSignature( collateralManager.delegatecall(
'liquidationCall(address,address,address,uint256,bool)', abi.encodeWithSignature(
collateralAsset, 'liquidationCall(address,address,address,uint256,bool)',
debtAsset, collateralAsset,
user, debtAsset,
debtToCover, user,
receiveAToken debtToCover,
) receiveAToken
); )
);
require(success, Errors.LP_LIQUIDATION_CALL_FAILED); require(success, Errors.LP_LIQUIDATION_CALL_FAILED);
(uint256 returnCode, string memory returnMessage) = abi.decode(result, (uint256, string)); (uint256 returnCode, string memory returnMessage) = abi.decode(result, (uint256, string));
@ -854,9 +854,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
uint256 currentStableRate = 0; uint256 currentStableRate = 0;
bool isFirstBorrowing = false; bool isFirstBorrowing = false;
if ( if (DataTypes.InterestRateMode(vars.interestRateMode) == DataTypes.InterestRateMode.STABLE) {
DataTypes.InterestRateMode(vars.interestRateMode) == DataTypes.InterestRateMode.STABLE
) {
currentStableRate = reserve.currentStableBorrowRate; currentStableRate = reserve.currentStableBorrowRate;
isFirstBorrowing = IStableDebtToken(reserve.stableDebtTokenAddress).mint( isFirstBorrowing = IStableDebtToken(reserve.stableDebtTokenAddress).mint(

View File

@ -3,12 +3,12 @@ pragma solidity 0.6.12;
import {SafeMath} from '../../dependencies/openzeppelin/contracts//SafeMath.sol'; import {SafeMath} from '../../dependencies/openzeppelin/contracts//SafeMath.sol';
import {IERC20} from '../../dependencies/openzeppelin/contracts//IERC20.sol'; import {IERC20} from '../../dependencies/openzeppelin/contracts//IERC20.sol';
import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol'; import {IAToken} from '../../interfaces/IAToken.sol';
import {IAToken} from '../tokenization/interfaces/IAToken.sol'; import {IStableDebtToken} from '../../interfaces/IStableDebtToken.sol';
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol'; import {IVariableDebtToken} from '../../interfaces/IVariableDebtToken.sol';
import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol';
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol'; import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
import {ILendingPoolCollateralManager} from '../../interfaces/ILendingPoolCollateralManager.sol'; import {ILendingPoolCollateralManager} from '../../interfaces/ILendingPoolCollateralManager.sol';
import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol';
import {GenericLogic} from '../libraries/logic/GenericLogic.sol'; import {GenericLogic} from '../libraries/logic/GenericLogic.sol';
import {Helpers} from '../libraries/helpers/Helpers.sol'; import {Helpers} from '../libraries/helpers/Helpers.sol';
import {WadRayMath} from '../libraries/math/WadRayMath.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol';
@ -16,8 +16,8 @@ import {PercentageMath} from '../libraries/math/PercentageMath.sol';
import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol'; import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol';
import {Errors} from '../libraries/helpers/Errors.sol'; import {Errors} from '../libraries/helpers/Errors.sol';
import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol'; import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol';
import {LendingPoolStorage} from './LendingPoolStorage.sol';
import {DataTypes} from '../libraries/types/DataTypes.sol'; import {DataTypes} from '../libraries/types/DataTypes.sol';
import {LendingPoolStorage} from './LendingPoolStorage.sol';
/** /**
* @title LendingPoolCollateralManager contract * @title LendingPoolCollateralManager contract

View File

@ -10,7 +10,7 @@ import {
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol'; import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
import {ILendingPool} from '../../interfaces/ILendingPool.sol'; import {ILendingPool} from '../../interfaces/ILendingPool.sol';
import {ITokenConfiguration} from '../tokenization/interfaces/ITokenConfiguration.sol'; import {ITokenConfiguration} from '../../interfaces/ITokenConfiguration.sol';
import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
import {Errors} from '../libraries/helpers/Errors.sol'; import {Errors} from '../libraries/helpers/Errors.sol';
import {PercentageMath} from '../libraries/math/PercentageMath.sol'; import {PercentageMath} from '../libraries/math/PercentageMath.sol';

View File

@ -3,13 +3,13 @@ pragma solidity 0.6.12;
import {SafeMath} from '../../../dependencies/openzeppelin/contracts/SafeMath.sol'; import {SafeMath} from '../../../dependencies/openzeppelin/contracts/SafeMath.sol';
import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol';
import {MathUtils} from '../math/MathUtils.sol';
import {SafeERC20} from '../../../dependencies/openzeppelin/contracts/SafeERC20.sol'; import {SafeERC20} from '../../../dependencies/openzeppelin/contracts/SafeERC20.sol';
import {IAToken} from '../../tokenization/interfaces/IAToken.sol'; import {IAToken} from '../../../interfaces/IAToken.sol';
import {IStableDebtToken} from '../../tokenization/interfaces/IStableDebtToken.sol'; import {IStableDebtToken} from '../../../interfaces/IStableDebtToken.sol';
import {IVariableDebtToken} from '../../tokenization/interfaces/IVariableDebtToken.sol'; import {IVariableDebtToken} from '../../../interfaces/IVariableDebtToken.sol';
import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol'; import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol';
import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
import {MathUtils} from '../math/MathUtils.sol';
import {WadRayMath} from '../math/WadRayMath.sol'; import {WadRayMath} from '../math/WadRayMath.sol';
import {PercentageMath} from '../math/PercentageMath.sol'; import {PercentageMath} from '../math/PercentageMath.sol';
import {Errors} from '../helpers/Errors.sol'; import {Errors} from '../helpers/Errors.sol';

View File

@ -1,19 +1,18 @@
// SPDX-License-Identifier: agpl-3.0 // SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.12; pragma solidity 0.6.12;
import {IncentivizedERC20} from './IncentivizedERC20.sol'; import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol';
import {ILendingPool} from '../../interfaces/ILendingPool.sol'; import {ILendingPool} from '../../interfaces/ILendingPool.sol';
import {IAToken} from '../../interfaces/IAToken.sol';
import {WadRayMath} from '../libraries/math/WadRayMath.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol';
import {Errors} from '../libraries/helpers/Errors.sol'; import {Errors} from '../libraries/helpers/Errors.sol';
import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol'; import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol';
import {IAToken} from './interfaces/IAToken.sol'; import {IncentivizedERC20} from './IncentivizedERC20.sol';
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol';
/** /**
* @title Aave ERC20 AToken * @title Aave ERC20 AToken
* * @dev Implementation of the interest bearing token for the Aave protocol
* @dev Implementation of the interest bearing token for the Aave protocol.
* @author Aave * @author Aave
*/ */
contract AToken is VersionedInitializable, IncentivizedERC20, IAToken { contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
@ -87,9 +86,12 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
} }
/** /**
* @dev burns the aTokens and sends the equivalent amount of underlying to the target. * @dev Burns aTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying`
* only lending pools can call this function * - Only callable by the LendingPool, as extra state updates there need to be managed
* @param amount the amount being burned * @param user The owner of the aTokens, getting them burned
* @param receiverOfUnderlying The address that will receive the underlying
* @param amount The amount being burned
* @param index The new liquidity index of the reserve
**/ **/
function burn( function burn(
address user, address user,
@ -101,21 +103,19 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
require(amountScaled != 0, Errors.CT_INVALID_BURN_AMOUNT); require(amountScaled != 0, Errors.CT_INVALID_BURN_AMOUNT);
_burn(user, amountScaled); _burn(user, amountScaled);
//transfers the underlying to the target
IERC20(UNDERLYING_ASSET_ADDRESS).safeTransfer(receiverOfUnderlying, amount); IERC20(UNDERLYING_ASSET_ADDRESS).safeTransfer(receiverOfUnderlying, amount);
//transfer event to track balances
emit Transfer(user, address(0), amount); emit Transfer(user, address(0), amount);
emit Burn(user, receiverOfUnderlying, amount, index); emit Burn(user, receiverOfUnderlying, amount, index);
} }
/** /**
* @dev mints aTokens to user * @dev Mints `amount` aTokens to `user`
* only lending pools can call this function * - Only callable by the LendingPool, as extra state updates there need to be managed
* @param user the address receiving the minted tokens * @param user The address receiving the minted tokens
* @param amount the amount of tokens to mint * @param amount The amount of tokens getting minted
* @param index the the last index of the reserve * @param index The new liquidity index of the reserve
* @return true if the the previous balance of the user is 0 * @return `true` if the the previous balance of the user was 0
*/ */
function mint( function mint(
address user, address user,
@ -128,7 +128,6 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
require(amountScaled != 0, Errors.CT_INVALID_MINT_AMOUNT); require(amountScaled != 0, Errors.CT_INVALID_MINT_AMOUNT);
_mint(user, amountScaled); _mint(user, amountScaled);
//transfer event to track balances
emit Transfer(address(0), user, amount); emit Transfer(address(0), user, amount);
emit Mint(user, amount, index); emit Mint(user, amount, index);
@ -136,52 +135,49 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
} }
/** /**
* @dev mints aTokens to reserve treasury * @dev Mints aTokens to the reserve treasury
* only lending pools can call this function * - Only callable by the LendingPool
* @param amount the amount of tokens to mint to the treasury * @param amount The amount of tokens getting minted
* @param index the the last index of the reserve * @param index The new liquidity index of the reserve
*/ */
function mintToTreasury(uint256 amount, uint256 index) external override onlyLendingPool { function mintToTreasury(uint256 amount, uint256 index) external override onlyLendingPool {
if (amount == 0) { if (amount == 0) {
return; return;
} }
//compared to the normal mint, we don't check for rounding errors. // Compared to the normal mint, we don't check for rounding errors.
//the amount to mint can easily be very small since is a fraction of the interest // The amount to mint can easily be very small since it is a fraction of the interest ccrued.
//accrued. in that case, the treasury will experience a (very small) loss, but it // In that case, the treasury will experience a (very small) loss, but it
//wont cause potentially valid transactions to fail. // wont cause potentially valid transactions to fail.
_mint(RESERVE_TREASURY_ADDRESS, amount.rayDiv(index)); _mint(RESERVE_TREASURY_ADDRESS, amount.rayDiv(index));
//transfer event to track balances
emit Transfer(address(0), RESERVE_TREASURY_ADDRESS, amount); emit Transfer(address(0), RESERVE_TREASURY_ADDRESS, amount);
emit Mint(RESERVE_TREASURY_ADDRESS, amount, index); emit Mint(RESERVE_TREASURY_ADDRESS, amount, index);
} }
/** /**
* @dev transfers tokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken * @dev Transfers aTokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken
* only lending pools can call this function * - Only callable by the LendingPool
* @param from the address from which transfer the aTokens * @param from The address getting liquidated, current owner of the aTokens
* @param to the destination address * @param to The recipient
* @param value the amount to transfer * @param value The amount of tokens getting transferred
**/ **/
function transferOnLiquidation( function transferOnLiquidation(
address from, address from,
address to, address to,
uint256 value uint256 value
) external override onlyLendingPool { ) external override onlyLendingPool {
//being a normal transfer, the Transfer() and BalanceTransfer() are emitted // Being a normal transfer, the Transfer() and BalanceTransfer() are emitted
//so no need to emit a specific event here // so no need to emit a specific event here
_transfer(from, to, value, false); _transfer(from, to, value, false);
emit Transfer(from, to, value); emit Transfer(from, to, value);
} }
/** /**
* @dev calculates the balance of the user, which is the * @dev Calculates the balance of the user: principal balance + interest generated by the principal
* principal balance + interest generated by the principal balance * @param user The user whose balance is calculated
* @param user the user for which the balance is being calculated * @return The balance of the user
* @return the total balance of the user
**/ **/
function balanceOf(address user) function balanceOf(address user)
public public
@ -193,10 +189,10 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
} }
/** /**
* @dev returns the scaled balance of the user. The scaled balance is the sum of all the * @dev Returns the scaled balance of the user. The scaled balance is the sum of all the
* updated stored balance divided the reserve index at the moment of the update * updated stored balance divided by the reserve's liquidity index at the moment of the update
* @param user the address of the user * @param user The user whose balance is calculated
* @return the scaled balance of the user * @return The scaled balance of the user
**/ **/
function scaledBalanceOf(address user) external view override returns (uint256) { function scaledBalanceOf(address user) external view override returns (uint256) {
return super.balanceOf(user); return super.balanceOf(user);
@ -242,11 +238,11 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
} }
/** /**
* @dev transfers the underlying asset to the target. Used by the lendingpool to transfer * @dev Transfers the underlying asset to `target`. Used by the LendingPool to transfer
* assets in borrow(), redeem() and flashLoan() * assets in borrow(), redeem() and flashLoan()
* @param target the target of the transfer * @param target The recipient of the aTokens
* @param amount the amount to transfer * @param amount The amount getting transferred
* @return the amount transferred * @return The amount transferred
**/ **/
function transferUnderlyingTo(address target, uint256 amount) function transferUnderlyingTo(address target, uint256 amount)
external external
@ -259,14 +255,15 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
} }
/** /**
* @dev implements the permit function as for https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md * @dev implements the permit function as for
* @param owner the owner of the funds * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md
* @param spender the spender * @param owner The owner of the funds
* @param value the amount * @param spender The spender
* @param deadline the deadline timestamp, type(uint256).max for max deadline * @param value The amount
* @param v signature param * @param deadline The deadline timestamp, type(uint256).max for max deadline
* @param s signature param * @param v Signature param
* @param r signature param * @param s Signature param
* @param r Signature param
*/ */
function permit( function permit(
address owner, address owner,
@ -295,12 +292,12 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
} }
/** /**
* @dev transfers the aTokens between two users. Validates the transfer * @dev Transfers the aTokens between two users. Validates the transfer
* (ie checks for valid HF after the transfer) if required * (ie checks for valid HF after the transfer) if required
* @param from the source address * @param from The source address
* @param to the destination address * @param to The destination address
* @param amount the amount to transfer * @param amount The amount getting transferred
* @param validate true if the transfer needs to be validated * @param validate `true` if the transfer needs to be validated
**/ **/
function _transfer( function _transfer(
address from, address from,
@ -330,10 +327,10 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
} }
/** /**
* @dev overrides the parent _transfer to force validated transfer() and transferFrom() * @dev Overrides the parent _transfer to force validated transfer() and transferFrom()
* @param from the source address * @param from The source address
* @param to the destination address * @param to The destination address
* @param amount the amount to transfer * @param amount The amount getting transferred
**/ **/
function _transfer( function _transfer(
address from, address from,
@ -342,11 +339,4 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
) internal override { ) internal override {
_transfer(from, to, amount, true); _transfer(from, to, amount, true);
} }
/**
* @dev aTokens should not receive ETH
**/
receive() external payable {
revert();
}
} }

View File

@ -1,30 +1,17 @@
// SPDX-License-Identifier: agpl-3.0 // SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.12; pragma solidity 0.6.12;
import {AToken} from './AToken.sol';
import {ILendingPool} from '../../interfaces/ILendingPool.sol'; import {ILendingPool} from '../../interfaces/ILendingPool.sol';
import {IDelegationToken} from '../../interfaces/IDelegationToken.sol';
import {Errors} from '../libraries/helpers/Errors.sol'; import {Errors} from '../libraries/helpers/Errors.sol';
import {AToken} from './AToken.sol';
/** /**
* @title IDelegationToken * @title Aave AToken enabled to delegate voting power of the underlying asset to a different address
* @dev implements an interface for tokens that have a delegation function * @dev The underlying asset needs to be compatible with the COMP delegation interface
**/
interface IDelegationToken {
function delegate(address delegatee) external;
}
/**
* @title Aave AToken with delegation capabilities
*
* @dev Implementation of the interest bearing token for the Aave protocol. This version of the aToken
* adds a function which gives the Aave protocol the ability to delegate voting power of the underlying asset.
* The underlying asset needs to be compatible with the COMP delegation interface
* @author Aave * @author Aave
*/ */
contract DelegationAwareAToken is AToken { contract DelegationAwareAToken is AToken {
/**
* @dev only the aave admin can call this function
**/
modifier onlyPoolAdmin { modifier onlyPoolAdmin {
require( require(
_msgSender() == ILendingPool(POOL).getAddressesProvider().getPoolAdmin(), _msgSender() == ILendingPool(POOL).getAddressesProvider().getPoolAdmin(),
@ -63,8 +50,8 @@ contract DelegationAwareAToken is AToken {
} }
/** /**
* @dev delegates voting power of the underlying asset to a specific address * @dev Delegates voting power of the underlying asset to a `delegatee` address
* @param delegatee the address that will receive the delegation * @param delegatee The address that will receive the delegation
**/ **/
function delegateUnderlyingTo(address delegatee) external onlyPoolAdmin { function delegateUnderlyingTo(address delegatee) external onlyPoolAdmin {
IDelegationToken(UNDERLYING_ASSET_ADDRESS).delegate(delegatee); IDelegationToken(UNDERLYING_ASSET_ADDRESS).delegate(delegatee);

View File

@ -38,45 +38,45 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
} }
/** /**
* @return the name of the token * @return The name of the token
**/ **/
function name() public view override returns (string memory) { function name() public view override returns (string memory) {
return _name; return _name;
} }
/** /**
* @return the symbol of the token * @return The symbol of the token
**/ **/
function symbol() public view override returns (string memory) { function symbol() public view override returns (string memory) {
return _symbol; return _symbol;
} }
/** /**
* @return the decimals of the token * @return The decimals of the token
**/ **/
function decimals() public view override returns (uint8) { function decimals() public view override returns (uint8) {
return _decimals; return _decimals;
} }
/** /**
* @return the total supply of the token * @return The total supply of the token
**/ **/
function totalSupply() public view virtual override returns (uint256) { function totalSupply() public view virtual override returns (uint256) {
return _totalSupply; return _totalSupply;
} }
/** /**
* @return the balance of the token * @return The balance of the token
**/ **/
function balanceOf(address account) public view virtual override returns (uint256) { function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account]; return _balances[account];
} }
/** /**
* @dev executes a transfer of tokens from _msgSender() to recipient * @dev Executes a transfer of tokens from _msgSender() to recipient
* @param recipient the recipient of the tokens * @param recipient The recipient of the tokens
* @param amount the amount of tokens being transferred * @param amount The amount of tokens being transferred
* @return true if the transfer succeeds, false otherwise * @return `true` if the transfer succeeds, `false` otherwise
**/ **/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) { function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount); _transfer(_msgSender(), recipient, amount);
@ -85,10 +85,10 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
} }
/** /**
* @dev returns the allowance of spender on the tokens owned by owner * @dev Returns the allowance of spender on the tokens owned by owner
* @param owner the owner of the tokens * @param owner The owner of the tokens
* @param spender the user allowed to spend the owner's tokens * @param spender The user allowed to spend the owner's tokens
* @return the amount of owner's tokens spender is allowed to spend * @return The amount of owner's tokens spender is allowed to spend
**/ **/
function allowance(address owner, address spender) function allowance(address owner, address spender)
public public
@ -101,9 +101,9 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
} }
/** /**
* @dev allows spender to spend the tokens owned by _msgSender() * @dev Allows `spender` to spend the tokens owned by _msgSender()
* @param spender the user allowed to spend _msgSender() tokens * @param spender The user allowed to spend _msgSender() tokens
* @return true * @return `true`
**/ **/
function approve(address spender, uint256 amount) public virtual override returns (bool) { function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount); _approve(_msgSender(), spender, amount);
@ -111,11 +111,11 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
} }
/** /**
* @dev executes a transfer of token from sender to recipient, if _msgSender() is allowed to do so * @dev Executes a transfer of token from sender to recipient, if _msgSender() is allowed to do so
* @param sender the owner of the tokens * @param sender The owner of the tokens
* @param recipient the recipient of the tokens * @param recipient The recipient of the tokens
* @param amount the amount of tokens being transferred * @param amount The amount of tokens being transferred
* @return true if the transfer succeeds, false otherwise * @return `true` if the transfer succeeds, `false` otherwise
**/ **/
function transferFrom( function transferFrom(
address sender, address sender,
@ -133,10 +133,10 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
} }
/** /**
* @dev increases the allowance of spender to spend _msgSender() tokens * @dev Increases the allowance of spender to spend _msgSender() tokens
* @param spender the user allowed to spend on behalf of _msgSender() * @param spender The user allowed to spend on behalf of _msgSender()
* @param addedValue the amount being added to the allowance * @param addedValue The amount being added to the allowance
* @return true * @return `true`
**/ **/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
@ -144,10 +144,10 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
} }
/** /**
* @dev decreases the allowance of spender to spend _msgSender() tokens * @dev Decreases the allowance of spender to spend _msgSender() tokens
* @param spender the user allowed to spend on behalf of _msgSender() * @param spender The user allowed to spend on behalf of _msgSender()
* @param subtractedValue the amount being subtracted to the allowance * @param subtractedValue The amount being subtracted to the allowance
* @return true * @return `true`
**/ **/
function decreaseAllowance(address spender, uint256 subtractedValue) function decreaseAllowance(address spender, uint256 subtractedValue)
public public

View File

@ -4,12 +4,13 @@ pragma solidity 0.6.12;
import {DebtTokenBase} from './base/DebtTokenBase.sol'; import {DebtTokenBase} from './base/DebtTokenBase.sol';
import {MathUtils} from '../libraries/math/MathUtils.sol'; import {MathUtils} from '../libraries/math/MathUtils.sol';
import {WadRayMath} from '../libraries/math/WadRayMath.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol';
import {IStableDebtToken} from './interfaces/IStableDebtToken.sol'; import {IStableDebtToken} from '../../interfaces/IStableDebtToken.sol';
import {Errors} from '../libraries/helpers/Errors.sol'; import {Errors} from '../libraries/helpers/Errors.sol';
/** /**
* @title contract StableDebtToken * @title StableDebtToken
* @notice Implements a stable debt token to track the user positions * @notice Implements a stable debt token to track the borrowing positions of users
* at stable rate mode
* @author Aave * @author Aave
**/ **/
contract StableDebtToken is IStableDebtToken, DebtTokenBase { contract StableDebtToken is IStableDebtToken, DebtTokenBase {
@ -31,15 +32,15 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
) public DebtTokenBase(pool, underlyingAsset, name, symbol, incentivesController) {} ) public DebtTokenBase(pool, underlyingAsset, name, symbol, incentivesController) {}
/** /**
* @dev gets the revision of the stable debt token implementation * @dev Gets the revision of the stable debt token implementation
* @return the debt token implementation revision * @return The debt token implementation revision
**/ **/
function getRevision() internal pure virtual override returns (uint256) { function getRevision() internal pure virtual override returns (uint256) {
return DEBT_TOKEN_REVISION; return DEBT_TOKEN_REVISION;
} }
/** /**
* @dev returns the average stable rate across all the stable rate debt * @dev Returns the average stable rate across all the stable rate debt
* @return the average stable rate * @return the average stable rate
**/ **/
function getAverageStableRate() external view virtual override returns (uint256) { function getAverageStableRate() external view virtual override returns (uint256) {
@ -47,25 +48,25 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
} }
/** /**
* @dev returns the timestamp of the last user action * @dev Returns the timestamp of the last user action
* @return the last update timestamp * @return The last update timestamp
**/ **/
function getUserLastUpdated(address user) external view virtual override returns (uint40) { function getUserLastUpdated(address user) external view virtual override returns (uint40) {
return _timestamps[user]; return _timestamps[user];
} }
/** /**
* @dev returns the stable rate of the user * @dev Returns the stable rate of the user
* @param user the address of the user * @param user The address of the user
* @return the stable rate of user * @return The stable rate of user
**/ **/
function getUserStableRate(address user) external view virtual override returns (uint256) { function getUserStableRate(address user) external view virtual override returns (uint256) {
return _usersStableRate[user]; return _usersStableRate[user];
} }
/** /**
* @dev calculates the current user debt balance * @dev Calculates the current user debt balance
* @return the accumulated debt of the user * @return The accumulated debt of the user
**/ **/
function balanceOf(address account) public view virtual override returns (uint256) { function balanceOf(address account) public view virtual override returns (uint256) {
uint256 accountBalance = super.balanceOf(account); uint256 accountBalance = super.balanceOf(account);
@ -87,11 +88,15 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
} }
/** /**
* @dev mints debt token to the target user. The resulting rate is the weighted average * @dev Mints debt token to the `onBehalfOf` address.
* between the rate of the new debt and the rate of the previous debt * - Only callable by the LendingPool
* @param user the address of the user * - The resulting rate is the weighted average between the rate of the new debt
* @param amount the amount of debt tokens to mint * and the rate of the previous debt
* @param rate the rate of the debt being minted. * @param user The address receiving the borrowed underlying, being the delegatee in case
* of credit delegate, or same as `onBehalfOf` otherwise
* @param onBehalfOf The address receiving the debt tokens
* @param amount The amount of debt tokens to mint
* @param rate The rate of the debt being minted
**/ **/
function mint( function mint(
address user, address user,
@ -105,17 +110,14 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
_decreaseBorrowAllowance(onBehalfOf, user, amount); _decreaseBorrowAllowance(onBehalfOf, user, amount);
} }
//cumulates the user debt
(, uint256 currentBalance, uint256 balanceIncrease) = _calculateBalanceIncrease(onBehalfOf); (, uint256 currentBalance, uint256 balanceIncrease) = _calculateBalanceIncrease(onBehalfOf);
//accrueing the interest accumulation to the stored total supply and caching it
vars.previousSupply = totalSupply(); vars.previousSupply = totalSupply();
vars.currentAvgStableRate = _avgStableRate; vars.currentAvgStableRate = _avgStableRate;
vars.nextSupply = _totalSupply = vars.previousSupply.add(amount); vars.nextSupply = _totalSupply = vars.previousSupply.add(amount);
vars.amountInRay = amount.wadToRay(); vars.amountInRay = amount.wadToRay();
//calculates the new stable rate for the user
vars.newStableRate = _usersStableRate[onBehalfOf] vars.newStableRate = _usersStableRate[onBehalfOf]
.rayMul(currentBalance.wadToRay()) .rayMul(currentBalance.wadToRay())
.add(vars.amountInRay.rayMul(rate)) .add(vars.amountInRay.rayMul(rate))
@ -124,11 +126,10 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
require(vars.newStableRate < type(uint128).max, Errors.SDT_STABLE_DEBT_OVERFLOW); require(vars.newStableRate < type(uint128).max, Errors.SDT_STABLE_DEBT_OVERFLOW);
_usersStableRate[onBehalfOf] = vars.newStableRate; _usersStableRate[onBehalfOf] = vars.newStableRate;
//updating the user and supply timestamp
//solium-disable-next-line //solium-disable-next-line
_totalSupplyTimestamp = _timestamps[onBehalfOf] = uint40(block.timestamp); _totalSupplyTimestamp = _timestamps[onBehalfOf] = uint40(block.timestamp);
//calculates the updated average stable rate // Calculates the updated average stable rate
vars.currentAvgStableRate = _avgStableRate = vars vars.currentAvgStableRate = _avgStableRate = vars
.currentAvgStableRate .currentAvgStableRate
.rayMul(vars.previousSupply.wadToRay()) .rayMul(vars.previousSupply.wadToRay())
@ -137,7 +138,6 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
_mint(onBehalfOf, amount.add(balanceIncrease), vars.previousSupply); _mint(onBehalfOf, amount.add(balanceIncrease), vars.previousSupply);
// transfer event to track balances
emit Transfer(address(0), onBehalfOf, amount); emit Transfer(address(0), onBehalfOf, amount);
emit Mint( emit Mint(
@ -155,9 +155,9 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
} }
/** /**
* @dev burns debt of the target user. * @dev Burns debt of `user`
* @param user the address of the user * @param user The address of the user getting his debt burned
* @param amount the amount of debt tokens to mint * @param amount The amount of debt tokens getting burned
**/ **/
function burn(address user, uint256 amount) external override onlyLendingPool { function burn(address user, uint256 amount) external override onlyLendingPool {
(, uint256 currentBalance, uint256 balanceIncrease) = _calculateBalanceIncrease(user); (, uint256 currentBalance, uint256 balanceIncrease) = _calculateBalanceIncrease(user);
@ -167,10 +167,10 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
uint256 nextSupply = 0; uint256 nextSupply = 0;
uint256 userStableRate = _usersStableRate[user]; uint256 userStableRate = _usersStableRate[user];
//since the total supply and each single user debt accrue separately, // Since the total supply and each single user debt accrue separately,
//there might be accumulation errors so that the last borrower repaying // there might be accumulation errors so that the last borrower repaying
//might actually try to repay more than the available debt supply. // mght actually try to repay more than the available debt supply.
//in this case we simply set the total supply and the avg stable rate to 0 // In this case we simply set the total supply and the avg stable rate to 0
if (previousSupply <= amount) { if (previousSupply <= amount) {
_avgStableRate = 0; _avgStableRate = 0;
_totalSupply = 0; _totalSupply = 0;
@ -179,9 +179,9 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
uint256 firstTerm = _avgStableRate.rayMul(previousSupply.wadToRay()); uint256 firstTerm = _avgStableRate.rayMul(previousSupply.wadToRay());
uint256 secondTerm = userStableRate.rayMul(amount.wadToRay()); uint256 secondTerm = userStableRate.rayMul(amount.wadToRay());
//for the same reason described above, when the last user is repaying it might // For the same reason described above, when the last user is repaying it might
//happen that user rate * user balance > avg rate * total supply. In that case, // happen that user rate * user balance > avg rate * total supply. In that case,
//we simply set the avg rate to 0 // we simply set the avg rate to 0
if (secondTerm >= firstTerm) { if (secondTerm >= firstTerm) {
newStableRate = _avgStableRate = _totalSupply = 0; newStableRate = _avgStableRate = _totalSupply = 0;
} else { } else {
@ -205,7 +205,6 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
_burn(user, amount.sub(balanceIncrease), previousSupply); _burn(user, amount.sub(balanceIncrease), previousSupply);
} }
// transfer event to track balances
emit Transfer(user, address(0), amount); emit Transfer(user, address(0), amount);
emit Burn(user, amount, currentBalance, balanceIncrease, newStableRate, nextSupply); emit Burn(user, amount, currentBalance, balanceIncrease, newStableRate, nextSupply);
@ -242,7 +241,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
} }
/** /**
* @dev returns the principal and total supply, the average borrow rate and the last supply update timestamp * @dev Returns the principal and total supply, the average borrow rate and the last supply update timestamp
**/ **/
function getSupplyData() function getSupplyData()
public public
@ -260,7 +259,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
} }
/** /**
* @dev returns the the total supply and the average stable rate * @dev Returns the the total supply and the average stable rate
**/ **/
function getTotalSupplyAndAvgRate() public view override returns (uint256, uint256) { function getTotalSupplyAndAvgRate() public view override returns (uint256, uint256) {
uint256 avgRate = _avgStableRate; uint256 avgRate = _avgStableRate;
@ -268,14 +267,14 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
} }
/** /**
* @dev returns the total supply * @dev Returns the total supply
**/ **/
function totalSupply() public view override returns (uint256) { function totalSupply() public view override returns (uint256) {
return _calcTotalSupply(_avgStableRate); return _calcTotalSupply(_avgStableRate);
} }
/** /**
* @dev returns the timestamp at which the total supply was updated * @dev Returns the timestamp at which the total supply was updated
**/ **/
function getTotalSupplyLastUpdated() public view override returns (uint40) { function getTotalSupplyLastUpdated() public view override returns (uint40) {
return _totalSupplyTimestamp; return _totalSupplyTimestamp;
@ -283,7 +282,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
/** /**
* @dev Returns the principal debt balance of the user from * @dev Returns the principal debt balance of the user from
* @param user the user * @param user Rhe user's address
* @return The debt balance of the user since the last burn/mint action * @return The debt balance of the user since the last burn/mint action
**/ **/
function principalBalanceOf(address user) external view virtual override returns (uint256) { function principalBalanceOf(address user) external view virtual override returns (uint256) {
@ -291,8 +290,8 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
} }
/** /**
* @dev calculates the total supply * @dev Calculates the total supply
* @param avgRate the average rate at which calculate the total supply * @param avgRate The average rate at which calculate the total supply
* @return The debt balance of the user since the last burn/mint action * @return The debt balance of the user since the last burn/mint action
**/ **/
function _calcTotalSupply(uint256 avgRate) internal view virtual returns (uint256) { function _calcTotalSupply(uint256 avgRate) internal view virtual returns (uint256) {
@ -309,9 +308,9 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
} }
/** /**
* @dev mints stable debt tokens to an user * @dev Mints stable debt tokens to an user
* @param account the account receiving the debt tokens * @param account The account receiving the debt tokens
* @param amount the amount being minted * @param amount The amount being minted
* @param oldTotalSupply the total supply before the minting event * @param oldTotalSupply the total supply before the minting event
**/ **/
function _mint( function _mint(
@ -328,10 +327,10 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
} }
/** /**
* @dev burns stable debt tokens of an user * @dev Burns stable debt tokens of an user
* @param account the user getting his debt burned * @param account The user getting his debt burned
* @param amount the amount being burned * @param amount The amount being burned
* @param oldTotalSupply the total supply before the burning event * @param oldTotalSupply The total supply before the burning event
**/ **/
function _burn( function _burn(
address account, address account,

View File

@ -1,14 +1,15 @@
// SPDX-License-Identifier: agpl-3.0 // SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.12; pragma solidity 0.6.12;
import {DebtTokenBase} from './base/DebtTokenBase.sol'; import {IVariableDebtToken} from '../../interfaces/IVariableDebtToken.sol';
import {WadRayMath} from '../libraries/math/WadRayMath.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol';
import {IVariableDebtToken} from './interfaces/IVariableDebtToken.sol';
import {Errors} from '../libraries/helpers/Errors.sol'; import {Errors} from '../libraries/helpers/Errors.sol';
import {DebtTokenBase} from './base/DebtTokenBase.sol';
/** /**
* @title contract VariableDebtToken * @title VariableDebtToken
* @notice Implements a variable debt token to track the user positions * @notice Implements a variable debt token to track the borrowing positions of users
* at variable rate mode
* @author Aave * @author Aave
**/ **/
contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
@ -25,16 +26,16 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
) public DebtTokenBase(pool, underlyingAsset, name, symbol, incentivesController) {} ) public DebtTokenBase(pool, underlyingAsset, name, symbol, incentivesController) {}
/** /**
* @dev gets the revision of the stable debt token implementation * @dev Gets the revision of the stable debt token implementation
* @return the debt token implementation revision * @return The debt token implementation revision
**/ **/
function getRevision() internal pure virtual override returns (uint256) { function getRevision() internal pure virtual override returns (uint256) {
return DEBT_TOKEN_REVISION; return DEBT_TOKEN_REVISION;
} }
/** /**
* @dev calculates the accumulated debt balance of the user * @dev Calculates the accumulated debt balance of the user
* @return the debt balance of the user * @return The debt balance of the user
**/ **/
function balanceOf(address user) public view virtual override returns (uint256) { function balanceOf(address user) public view virtual override returns (uint256) {
uint256 scaledBalance = super.balanceOf(user); uint256 scaledBalance = super.balanceOf(user);
@ -47,11 +48,14 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
} }
/** /**
* @dev mints new variable debt * @dev Mints debt token to the `onBehalfOf` address
* @param user the user receiving the debt * - Only callable by the LendingPool
* @param amount the amount of debt being minted * @param user The address receiving the borrowed underlying, being the delegatee in case
* @param index the variable debt index of the reserve * of credit delegate, or same as `onBehalfOf` otherwise
* @return true if the the previous balance of the user is 0 * @param onBehalfOf The address receiving the debt tokens
* @param amount The amount of debt being minted
* @param index The variable debt index of the reserve
* @return `true` if the the previous balance of the user is 0
**/ **/
function mint( function mint(
address user, address user,
@ -76,9 +80,11 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
} }
/** /**
* @dev burns user variable debt * @dev Burns user variable debt
* @param user the user which debt is burnt * - Only callable by the LendingPool
* @param index the variable debt index of the reserve * @param user The user whose debt is getting burned
* @param amount The amount getting burned
* @param index The variable debt index of the reserve
**/ **/
function burn( function burn(
address user, address user,
@ -104,7 +110,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
/** /**
* @dev Returns the total supply of the variable debt token. Represents the total debt accrued by the users * @dev Returns the total supply of the variable debt token. Represents the total debt accrued by the users
* @return the total supply * @return The total supply
**/ **/
function totalSupply() public view virtual override returns (uint256) { function totalSupply() public view virtual override returns (uint256) {
return return
@ -120,10 +126,10 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
} }
/** /**
* @dev returns the principal balance of the user and principal total supply. * @dev Teturns the principal balance of the user and principal total supply.
* @param user the address of the user * @param user The address of the user
* @return the principal balance of the user * @return The principal balance of the user
* @return the principal total supply * @return The principal total supply
**/ **/
function getScaledUserBalanceAndSupply(address user) function getScaledUserBalanceAndSupply(address user)
external external

View File

@ -1,85 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.12;
import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol';
import {IScaledBalanceToken} from './IScaledBalanceToken.sol';
interface IAToken is IERC20, IScaledBalanceToken {
/**
* @dev emitted after the mint action
* @param from the address performing the mint
* @param value the amount to be minted
* @param index the last index of the reserve
**/
event Mint(address indexed from, uint256 value, uint256 index);
/**
* @dev mints aTokens to user
* only lending pools can call this function
* @param user the address receiving the minted tokens
* @param amount the amount of tokens to mint
* @param index the liquidity index
*/
function mint(
address user,
uint256 amount,
uint256 index
) external returns (bool);
/**
* @dev emitted after aTokens are burned
* @param from the address performing the redeem
* @param value the amount to be redeemed
* @param index the last index of the reserve
**/
event Burn(address indexed from, address indexed target, uint256 value, uint256 index);
/**
* @dev emitted during the transfer action
* @param from the address from which the tokens are being transferred
* @param to the adress of the destination
* @param value the amount to be minted
* @param index the last index of the reserve
**/
event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index);
/**
* @dev burns the aTokens and sends the equivalent amount of underlying to the target.
* only lending pools can call this function
* @param amount the amount being burned
* @param index the liquidity index
**/
function burn(
address user,
address underlyingTarget,
uint256 amount,
uint256 index
) external;
/**
* @dev mints aTokens to the reserve treasury
* @param amount the amount to mint
* @param index the liquidity index of the reserve
**/
function mintToTreasury(uint256 amount, uint256 index) external;
/**
* @dev transfers tokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken
* only lending pools can call this function
* @param from the address from which transfer the aTokens
* @param to the destination address
* @param value the amount to transfer
**/
function transferOnLiquidation(
address from,
address to,
uint256 value
) external;
/**
* @dev transfer the amount of the underlying asset to the user
* @param user address of the user
* @param amount the amount to transfer
* @return the amount transferred
**/
function transferUnderlyingTo(address user, uint256 amount) external returns (uint256);
}

View File

@ -1,124 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.12;
/**
* @title interface IStableDebtToken
*
* @notice defines the interface for the stable debt token
*
* @dev it does not inherit from IERC20 to save in code size
*
* @author Aave
*
**/
interface IStableDebtToken {
/**
* @dev emitted when new stable debt is minted
* @param user the address of the user who triggered the minting
* @param onBehalfOf the address of the user
* @param amount the amount minted
* @param currentBalance the current balance of the user
* @param balanceIncrease the the increase in balance since the last action of the user
* @param newRate the rate of the debt after the minting
* @param avgStableRate the new average stable rate after the minting
* @param newTotalSupply the new total supply of the stable debt token after the action
**/
event Mint(
address indexed user,
address indexed onBehalfOf,
uint256 amount,
uint256 currentBalance,
uint256 balanceIncrease,
uint256 newRate,
uint256 avgStableRate,
uint256 newTotalSupply
);
/**
* @dev emitted when new stable debt is burned
* @param user the address of the user
* @param amount the amount minted
* @param currentBalance the current balance of the user
* @param balanceIncrease the the increase in balance since the last action of the user
* @param avgStableRate the new average stable rate after the minting
* @param newTotalSupply the new total supply of the stable debt token after the action
**/
event Burn(
address indexed user,
uint256 amount,
uint256 currentBalance,
uint256 balanceIncrease,
uint256 avgStableRate,
uint256 newTotalSupply
);
/**
* @dev mints debt token to the target user. The resulting rate is the weighted average
* between the rate of the new debt and the rate of the previous debt
* @param user the address of the user
* @param amount the amount of debt tokens to mint
* @param rate the rate of the debt being minted.
**/
function mint(
address user,
address onBehalfOf,
uint256 amount,
uint256 rate
) external returns (bool);
/**
* @dev burns debt of the target user.
* @param user the address of the user
* @param amount the amount of debt tokens to mint
**/
function burn(address user, uint256 amount) external;
/**
* @dev returns the average rate of all the stable rate loans.
* @return the average stable rate
**/
function getAverageStableRate() external view returns (uint256);
/**
* @dev returns the stable rate of the user debt
* @return the stable rate of the user
**/
function getUserStableRate(address user) external view returns (uint256);
/**
* @dev returns the timestamp of the last update of the user
* @return the timestamp
**/
function getUserLastUpdated(address user) external view returns (uint40);
/**
* @dev returns the principal, the total supply and the average stable rate
**/
function getSupplyData()
external
view
returns (
uint256,
uint256,
uint256,
uint40
);
/**
* @dev returns the timestamp of the last update of the total supply
* @return the timestamp
**/
function getTotalSupplyLastUpdated() external view returns (uint40);
/**
* @dev returns the total supply and the average stable rate
**/
function getTotalSupplyAndAvgRate() external view returns (uint256, uint256);
/**
* @dev Returns the principal debt balance of the user
* @return The debt balance of the user since the last burn/mint action
**/
function principalBalanceOf(address user) external view returns (uint256);
}

View File

@ -1,53 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.12;
import {IScaledBalanceToken} from './IScaledBalanceToken.sol';
/**
* @title interface IVariableDebtToken
* @author Aave
* @notice defines the basic interface for a variable debt token.
**/
interface IVariableDebtToken is IScaledBalanceToken {
/**
* @dev emitted after the mint action
* @param from the address performing the mint
* @param onBehalfOf the address of the user on which behalf minting has been performed
* @param value the amount to be minted
* @param index the last index of the reserve
**/
event Mint(address indexed from, address indexed onBehalfOf, uint256 value, uint256 index);
/**
* @dev mints aTokens to user
* only lending pools can call this function
* @param user the address receiving the minted tokens
* @param amount the amount of tokens to mint
* @param index the liquidity index
*/
function mint(
address user,
address onBehalfOf,
uint256 amount,
uint256 index
) external returns (bool);
/**
* @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 index the index of the user
**/
event Burn(address indexed user, uint256 amount, uint256 index);
/**
* @dev burns user variable debt
* @param user the user which debt is burnt
* @param index the variable debt index of the reserve
**/
function burn(
address user,
uint256 amount,
uint256 index
) external;
}