mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Initial refactor
This commit is contained in:
parent
573738cd7b
commit
576fd4ec55
|
@ -73,13 +73,13 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev emitted during a redeem action.
|
* @dev emitted during a withdraw action.
|
||||||
* @param _reserve the address of the reserve
|
* @param _reserve the address of the reserve
|
||||||
* @param _user the address of the user
|
* @param _user the address of the user
|
||||||
* @param _amount the amount to be deposited
|
* @param _amount the amount to be withdrawn
|
||||||
* @param _timestamp the timestamp of the action
|
* @param _timestamp the timestamp of the action
|
||||||
**/
|
**/
|
||||||
event RedeemUnderlying(
|
event Withdraw(
|
||||||
address indexed _reserve,
|
address indexed _reserve,
|
||||||
address indexed _user,
|
address indexed _user,
|
||||||
uint256 _amount,
|
uint256 _amount,
|
||||||
|
@ -290,33 +290,45 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
||||||
* @dev Redeems the underlying amount of assets requested by _user.
|
* @dev Redeems the underlying amount of assets requested by _user.
|
||||||
* This function is executed by the overlying aToken contract in response to a redeem action.
|
* This function is executed by the overlying aToken contract in response to a redeem action.
|
||||||
* @param _reserve the address of the reserve
|
* @param _reserve the address of the reserve
|
||||||
* @param _user the address of the user performing the action
|
|
||||||
* @param _amount the underlying amount to be redeemed
|
* @param _amount the underlying amount to be redeemed
|
||||||
**/
|
**/
|
||||||
function redeemUnderlying(
|
function withdraw(address _reserve, uint256 _amount) external nonReentrant {
|
||||||
address _reserve,
|
|
||||||
address payable _user,
|
|
||||||
uint256 _amount,
|
|
||||||
uint256 _aTokenBalanceAfterRedeem
|
|
||||||
) external nonReentrant {
|
|
||||||
ReserveLogic.ReserveData storage reserve = reserves[_reserve];
|
ReserveLogic.ReserveData storage reserve = reserves[_reserve];
|
||||||
|
|
||||||
AToken aToken = AToken(payable(reserve.aTokenAddress));
|
AToken aToken = AToken(payable(reserve.aTokenAddress));
|
||||||
|
|
||||||
ValidationLogic.validateRedeem(reserve, _reserve, _amount);
|
uint256 userBalance = aToken.balanceOf(msg.sender);
|
||||||
|
|
||||||
|
uint256 amountToWithdraw = _amount;
|
||||||
|
|
||||||
|
//if amount is equal to uint(-1), the user wants to redeem everything
|
||||||
|
if (_amount == UINT_MAX_VALUE) {
|
||||||
|
amountToWithdraw = userBalance;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValidationLogic.validateWithdraw(
|
||||||
|
_reserve,
|
||||||
|
address(aToken),
|
||||||
|
amountToWithdraw,
|
||||||
|
userBalance,
|
||||||
|
reserves,
|
||||||
|
usersConfig[msg.sender],
|
||||||
|
reservesList,
|
||||||
|
addressesProvider.getPriceOracle()
|
||||||
|
);
|
||||||
|
|
||||||
reserve.updateCumulativeIndexesAndTimestamp();
|
reserve.updateCumulativeIndexesAndTimestamp();
|
||||||
|
|
||||||
reserve.updateInterestRates(_reserve, 0, _amount);
|
reserve.updateInterestRates(_reserve, 0, amountToWithdraw);
|
||||||
|
|
||||||
if (_aTokenBalanceAfterRedeem == 0) {
|
if (amountToWithdraw == userBalance) {
|
||||||
usersConfig[_user].setUsingAsCollateral(reserve.index, false);
|
usersConfig[msg.sender].setUsingAsCollateral(reserve.index, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
AToken(reserve.aTokenAddress).transferUnderlyingTo(_user, _amount);
|
aToken.burnOnWithdraw(msg.sender, _amount);
|
||||||
|
|
||||||
//solium-disable-next-line
|
//solium-disable-next-line
|
||||||
emit RedeemUnderlying(_reserve, _user, _amount, block.timestamp);
|
emit Withdraw(_reserve, msg.sender, _amount, block.timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -368,7 +380,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
||||||
|
|
||||||
reserve.updateInterestRates(_reserve, 0, _amount);
|
reserve.updateInterestRates(_reserve, 0, _amount);
|
||||||
|
|
||||||
if(!userConfig.isBorrowing(reserve.index)){
|
if (!userConfig.isBorrowing(reserve.index)) {
|
||||||
userConfig.setBorrowing(reserve.index, true);
|
userConfig.setBorrowing(reserve.index, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,16 +464,12 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
reserve.updateInterestRates(_reserve, vars.paybackAmount, 0);
|
reserve.updateInterestRates(_reserve, vars.paybackAmount, 0);
|
||||||
|
|
||||||
if(vars.totalDebt.sub(vars.paybackAmount) == 0){
|
if (vars.totalDebt.sub(vars.paybackAmount) == 0) {
|
||||||
usersConfig[_onBehalfOf].setBorrowing(reserve.index, false);
|
usersConfig[_onBehalfOf].setBorrowing(reserve.index, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
IERC20(_reserve).safeTransferFrom(
|
IERC20(_reserve).safeTransferFrom(msg.sender, reserve.aTokenAddress, vars.paybackAmount);
|
||||||
msg.sender,
|
|
||||||
reserve.aTokenAddress,
|
|
||||||
vars.paybackAmount
|
|
||||||
);
|
|
||||||
|
|
||||||
emit Repay(
|
emit Repay(
|
||||||
_reserve,
|
_reserve,
|
||||||
|
@ -485,7 +493,13 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
||||||
|
|
||||||
ReserveLogic.InterestRateMode rateMode = ReserveLogic.InterestRateMode(_rateMode);
|
ReserveLogic.InterestRateMode rateMode = ReserveLogic.InterestRateMode(_rateMode);
|
||||||
|
|
||||||
ValidationLogic.validateSwapRateMode(reserve, usersConfig[msg.sender], stableDebt, variableDebt, rateMode);
|
ValidationLogic.validateSwapRateMode(
|
||||||
|
reserve,
|
||||||
|
usersConfig[msg.sender],
|
||||||
|
stableDebt,
|
||||||
|
variableDebt,
|
||||||
|
rateMode
|
||||||
|
);
|
||||||
|
|
||||||
reserve.updateCumulativeIndexesAndTimestamp();
|
reserve.updateCumulativeIndexesAndTimestamp();
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {ReserveLogic} from './ReserveLogic.sol';
|
||||||
import {GenericLogic} from './GenericLogic.sol';
|
import {GenericLogic} from './GenericLogic.sol';
|
||||||
import {WadRayMath} from './WadRayMath.sol';
|
import {WadRayMath} from './WadRayMath.sol';
|
||||||
import {PercentageMath} from './PercentageMath.sol';
|
import {PercentageMath} from './PercentageMath.sol';
|
||||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||||
import {ReserveConfiguration} from './ReserveConfiguration.sol';
|
import {ReserveConfiguration} from './ReserveConfiguration.sol';
|
||||||
import {UserConfiguration} from './UserConfiguration.sol';
|
import {UserConfiguration} from './UserConfiguration.sol';
|
||||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||||
|
@ -41,29 +41,46 @@ library ValidationLogic {
|
||||||
{
|
{
|
||||||
(bool isActive, bool isFreezed, , ) = _reserve.configuration.getFlags();
|
(bool isActive, bool isFreezed, , ) = _reserve.configuration.getFlags();
|
||||||
|
|
||||||
internalValidateReserveStateAndAmount(_reserve, _amount);
|
require(_amount > 0, 'Amount must be greater than 0');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev validates a redeem.
|
* @dev validates a withdraw action.
|
||||||
* @param _reserve the reserve state from which the user is redeeming
|
|
||||||
* @param _reserveAddress the address of the reserve
|
* @param _reserveAddress the address of the reserve
|
||||||
* @param _amount the amount to be redeemed
|
* @param _aTokenAddress the address of the aToken for the reserve
|
||||||
|
* @param _amount the amount to be withdrawn
|
||||||
|
* @param _userBalance the balance of the user
|
||||||
*/
|
*/
|
||||||
function validateRedeem(
|
function validateWithdraw(
|
||||||
ReserveLogic.ReserveData storage _reserve,
|
|
||||||
address _reserveAddress,
|
address _reserveAddress,
|
||||||
uint256 _amount
|
address _aTokenAddress,
|
||||||
|
uint256 _amount,
|
||||||
|
uint256 _userBalance,
|
||||||
|
mapping(address => ReserveLogic.ReserveData) storage _reservesData,
|
||||||
|
UserConfiguration.Map storage _userConfig,
|
||||||
|
address[] calldata _reserves,
|
||||||
|
address _oracle
|
||||||
) external view {
|
) external view {
|
||||||
internalValidateReserveStateAndAmount(_reserve, _amount);
|
require(_amount > 0, 'Amount must be greater than 0');
|
||||||
|
|
||||||
require(msg.sender == _reserve.aTokenAddress, '31');
|
uint256 currentAvailableLiquidity = IERC20(_reserveAddress).balanceOf(address(_aTokenAddress));
|
||||||
|
|
||||||
uint256 currentAvailableLiquidity = IERC20(_reserveAddress).balanceOf(
|
|
||||||
address(_reserve.aTokenAddress)
|
|
||||||
);
|
|
||||||
|
|
||||||
require(currentAvailableLiquidity >= _amount, '4');
|
require(currentAvailableLiquidity >= _amount, '4');
|
||||||
|
|
||||||
|
require(_amount <= _userBalance, 'User cannot withdraw more than the available balance');
|
||||||
|
|
||||||
|
require(
|
||||||
|
GenericLogic.balanceDecreaseAllowed(
|
||||||
|
_reserveAddress,
|
||||||
|
msg.sender,
|
||||||
|
_userBalance,
|
||||||
|
_reservesData,
|
||||||
|
_userConfig,
|
||||||
|
_reserves,
|
||||||
|
_oracle
|
||||||
|
),
|
||||||
|
'Transfer cannot be allowed.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ValidateBorrowLocalVars {
|
struct ValidateBorrowLocalVars {
|
||||||
|
@ -135,9 +152,7 @@ library ValidationLogic {
|
||||||
);
|
);
|
||||||
|
|
||||||
//check that the amount is available in the reserve
|
//check that the amount is available in the reserve
|
||||||
vars.availableLiquidity = IERC20(_reserveAddress).balanceOf(
|
vars.availableLiquidity = IERC20(_reserveAddress).balanceOf(address(_reserve.aTokenAddress));
|
||||||
address(_reserve.aTokenAddress)
|
|
||||||
);
|
|
||||||
|
|
||||||
require(vars.availableLiquidity >= _amount, '7');
|
require(vars.availableLiquidity >= _amount, '7');
|
||||||
|
|
||||||
|
@ -325,16 +340,4 @@ library ValidationLogic {
|
||||||
'User deposit is already being used as collateral'
|
'User deposit is already being used as collateral'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev validates that the reserve is active and the amount is greater than 0
|
|
||||||
* @param _reserve the state of the reserve being validated
|
|
||||||
* @param _amount the amount being validated
|
|
||||||
*/
|
|
||||||
function internalValidateReserveStateAndAmount(
|
|
||||||
ReserveLogic.ReserveData storage _reserve,
|
|
||||||
uint256 _amount
|
|
||||||
) internal view {
|
|
||||||
require(_amount > 0, 'Amount must be greater than 0');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ pragma solidity ^0.6.8;
|
||||||
import {ERC20} from './ERC20.sol';
|
import {ERC20} from './ERC20.sol';
|
||||||
import {LendingPool} from '../lendingpool/LendingPool.sol';
|
import {LendingPool} from '../lendingpool/LendingPool.sol';
|
||||||
import {WadRayMath} from '../libraries/WadRayMath.sol';
|
import {WadRayMath} from '../libraries/WadRayMath.sol';
|
||||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||||
import {
|
import {
|
||||||
VersionedInitializable
|
VersionedInitializable
|
||||||
} from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
} from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||||
|
@ -30,7 +30,7 @@ contract AToken is VersionedInitializable, ERC20 {
|
||||||
* @param _fromBalanceIncrease the cumulated balance since the last update of the user
|
* @param _fromBalanceIncrease the cumulated balance since the last update of the user
|
||||||
* @param _fromIndex the last index of the user
|
* @param _fromIndex the last index of the user
|
||||||
**/
|
**/
|
||||||
event Redeem(
|
event BurnOnWithdraw(
|
||||||
address indexed _from,
|
address indexed _from,
|
||||||
uint256 _value,
|
uint256 _value,
|
||||||
uint256 _fromBalanceIncrease,
|
uint256 _fromBalanceIncrease,
|
||||||
|
@ -219,61 +219,35 @@ contract AToken is VersionedInitializable, ERC20 {
|
||||||
* @dev redeems aToken for the underlying asset
|
* @dev redeems aToken for the underlying asset
|
||||||
* @param _amount the amount being redeemed
|
* @param _amount the amount being redeemed
|
||||||
**/
|
**/
|
||||||
function redeem(uint256 _amount) external {
|
function burnOnWithdraw(address _user, uint256 _amount) external onlyLendingPool {
|
||||||
require(_amount > 0, 'Amount to redeem needs to be > 0');
|
|
||||||
|
|
||||||
//cumulates the balance of the user
|
//cumulates the balance of the user
|
||||||
(, uint256 currentBalance, uint256 balanceIncrease) = calculateBalanceIncreaseInternal(
|
(, uint256 currentBalance, uint256 balanceIncrease) = calculateBalanceIncreaseInternal(_user);
|
||||||
msg.sender
|
|
||||||
);
|
|
||||||
|
|
||||||
uint256 amountToRedeem = _amount;
|
|
||||||
|
|
||||||
//if amount is equal to uint(-1), the user wants to redeem everything
|
|
||||||
if (_amount == UINT_MAX_VALUE) {
|
|
||||||
amountToRedeem = currentBalance;
|
|
||||||
}
|
|
||||||
|
|
||||||
require(amountToRedeem <= currentBalance, 'User cannot redeem more than the available balance');
|
|
||||||
|
|
||||||
//check that the user is allowed to redeem the amount
|
|
||||||
require(isTransferAllowed(msg.sender, amountToRedeem), 'Transfer cannot be allowed.');
|
|
||||||
|
|
||||||
//if the user is redirecting his interest towards someone else,
|
//if the user is redirecting his interest towards someone else,
|
||||||
//we update the redirected balance of the redirection address by adding the accrued interest,
|
//we update the redirected balance of the redirection address by adding the accrued interest,
|
||||||
//and removing the amount to redeem
|
//and removing the amount to redeem
|
||||||
updateRedirectedBalanceOfRedirectionAddressInternal(
|
updateRedirectedBalanceOfRedirectionAddressInternal(_user, balanceIncrease, _amount);
|
||||||
msg.sender,
|
|
||||||
balanceIncrease,
|
|
||||||
amountToRedeem
|
|
||||||
);
|
|
||||||
|
|
||||||
if(balanceIncrease > amountToRedeem){
|
if (balanceIncrease > _amount) {
|
||||||
_mint(msg.sender, balanceIncrease.sub(amountToRedeem));
|
_mint(_user, balanceIncrease.sub(_amount));
|
||||||
}
|
} else {
|
||||||
else{
|
_burn(_user, _amount.sub(balanceIncrease));
|
||||||
_burn(msg.sender, amountToRedeem.sub(balanceIncrease));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 userIndex = 0;
|
uint256 userIndex = 0;
|
||||||
|
|
||||||
//reset the user data if the remaining balance is 0
|
//reset the user data if the remaining balance is 0
|
||||||
if (currentBalance.sub(amountToRedeem) == 0) {
|
if (currentBalance.sub(_amount) == 0) {
|
||||||
resetDataOnZeroBalanceInternal(msg.sender);
|
resetDataOnZeroBalanceInternal(_user);
|
||||||
} else {
|
} else {
|
||||||
//updates the user index
|
//updates the user index
|
||||||
userIndex = userIndexes[msg.sender] = pool.getReserveNormalizedIncome(underlyingAssetAddress);
|
userIndex = userIndexes[_user] = pool.getReserveNormalizedIncome(underlyingAssetAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
// executes redeem of the underlying asset
|
//transfers the underlying to the user
|
||||||
pool.redeemUnderlying(
|
ERC20(underlyingAssetAddress).safeTransfer(_user, _amount);
|
||||||
underlyingAssetAddress,
|
|
||||||
msg.sender,
|
|
||||||
amountToRedeem,
|
|
||||||
currentBalance.sub(amountToRedeem)
|
|
||||||
);
|
|
||||||
|
|
||||||
emit Redeem(msg.sender, amountToRedeem, balanceIncrease, userIndex);
|
emit BurnOnWithdraw(msg.sender, _amount, balanceIncrease, userIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -283,13 +257,12 @@ contract AToken is VersionedInitializable, ERC20 {
|
||||||
* @param _amount the amount of tokens to mint
|
* @param _amount the amount of tokens to mint
|
||||||
*/
|
*/
|
||||||
function mintOnDeposit(address _user, uint256 _amount) external onlyLendingPool {
|
function mintOnDeposit(address _user, uint256 _amount) external onlyLendingPool {
|
||||||
|
|
||||||
//cumulates the balance of the user
|
//cumulates the balance of the user
|
||||||
(, , uint256 balanceIncrease) = calculateBalanceIncreaseInternal(_user);
|
(, , uint256 balanceIncrease) = calculateBalanceIncreaseInternal(_user);
|
||||||
|
|
||||||
//updates the user index
|
//updates the user index
|
||||||
uint256 index = userIndexes[_user] = pool.getReserveNormalizedIncome(underlyingAssetAddress);
|
uint256 index = userIndexes[_user] = pool.getReserveNormalizedIncome(underlyingAssetAddress);
|
||||||
|
|
||||||
//if the user is redirecting his interest towards someone else,
|
//if the user is redirecting his interest towards someone else,
|
||||||
//we update the redirected balance of the redirection address by adding the accrued interest
|
//we update the redirected balance of the redirection address by adding the accrued interest
|
||||||
//and the amount deposited
|
//and the amount deposited
|
||||||
|
@ -450,12 +423,11 @@ contract AToken is VersionedInitializable, ERC20 {
|
||||||
return redirectedBalances[_user];
|
return redirectedBalances[_user];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev calculates the increase in balance since the last user action
|
* @dev calculates the increase in balance since the last user action
|
||||||
* @param _user the address of the user
|
* @param _user the address of the user
|
||||||
* @return the last user principal balance, the current balance and the balance increase
|
* @return the last user principal balance, the current balance and the balance increase
|
||||||
**/
|
**/
|
||||||
function calculateBalanceIncreaseInternal(address _user)
|
function calculateBalanceIncreaseInternal(address _user)
|
||||||
internal
|
internal
|
||||||
returns (
|
returns (
|
||||||
|
@ -473,11 +445,11 @@ contract AToken is VersionedInitializable, ERC20 {
|
||||||
//calculate the accrued interest since the last accumulation
|
//calculate the accrued interest since the last accumulation
|
||||||
balanceIncrease = currentBalance.sub(previousBalance);
|
balanceIncrease = currentBalance.sub(previousBalance);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (previousBalance, currentBalance, balanceIncrease);
|
return (previousBalance, currentBalance, balanceIncrease);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev accumulates the accrued interest of the user to the principal balance
|
* @dev accumulates the accrued interest of the user to the principal balance
|
||||||
* @param _user the address of the user for which the interest is being accumulated
|
* @param _user the address of the user for which the interest is being accumulated
|
||||||
* @return the previous principal balance, the new principal balance, the balance increase
|
* @return the previous principal balance, the new principal balance, the balance increase
|
||||||
|
@ -492,7 +464,11 @@ contract AToken is VersionedInitializable, ERC20 {
|
||||||
uint256
|
uint256
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
(uint256 previousBalance, uint256 currentBalance, uint256 balanceIncrease) = calculateBalanceIncreaseInternal(_user);
|
(
|
||||||
|
uint256 previousBalance,
|
||||||
|
uint256 currentBalance,
|
||||||
|
uint256 balanceIncrease
|
||||||
|
) = calculateBalanceIncreaseInternal(_user);
|
||||||
|
|
||||||
_mint(_user, balanceIncrease);
|
_mint(_user, balanceIncrease);
|
||||||
|
|
||||||
|
@ -500,8 +476,7 @@ contract AToken is VersionedInitializable, ERC20 {
|
||||||
uint256 index = userIndexes[_user] = pool.getReserveNormalizedIncome(underlyingAssetAddress);
|
uint256 index = userIndexes[_user] = pool.getReserveNormalizedIncome(underlyingAssetAddress);
|
||||||
|
|
||||||
return (previousBalance, currentBalance, balanceIncrease, index);
|
return (previousBalance, currentBalance, balanceIncrease, index);
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev updates the redirected balance of the user. If the user is not redirecting his
|
* @dev updates the redirected balance of the user. If the user is not redirecting his
|
||||||
|
|
Loading…
Reference in New Issue
Block a user