Initial refactor

This commit is contained in:
The3D 2020-08-18 21:19:11 +02:00
parent 573738cd7b
commit 576fd4ec55
3 changed files with 100 additions and 108 deletions

View File

@ -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 _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
**/
event RedeemUnderlying(
event Withdraw(
address indexed _reserve,
address indexed _user,
uint256 _amount,
@ -290,33 +290,45 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
* @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.
* @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
**/
function redeemUnderlying(
address _reserve,
address payable _user,
uint256 _amount,
uint256 _aTokenBalanceAfterRedeem
) external nonReentrant {
function withdraw(address _reserve, uint256 _amount) external nonReentrant {
ReserveLogic.ReserveData storage reserve = reserves[_reserve];
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.updateInterestRates(_reserve, 0, _amount);
reserve.updateInterestRates(_reserve, 0, amountToWithdraw);
if (_aTokenBalanceAfterRedeem == 0) {
usersConfig[_user].setUsingAsCollateral(reserve.index, false);
if (amountToWithdraw == userBalance) {
usersConfig[msg.sender].setUsingAsCollateral(reserve.index, false);
}
AToken(reserve.aTokenAddress).transferUnderlyingTo(_user, _amount);
aToken.burnOnWithdraw(msg.sender, _amount);
//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);
if(!userConfig.isBorrowing(reserve.index)){
if (!userConfig.isBorrowing(reserve.index)) {
userConfig.setBorrowing(reserve.index, true);
}
@ -452,16 +464,12 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
}
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);
}
IERC20(_reserve).safeTransferFrom(
msg.sender,
reserve.aTokenAddress,
vars.paybackAmount
);
IERC20(_reserve).safeTransferFrom(msg.sender, reserve.aTokenAddress, vars.paybackAmount);
emit Repay(
_reserve,
@ -485,7 +493,13 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
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();

View File

@ -9,7 +9,7 @@ import {ReserveLogic} from './ReserveLogic.sol';
import {GenericLogic} from './GenericLogic.sol';
import {WadRayMath} from './WadRayMath.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 {UserConfiguration} from './UserConfiguration.sol';
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
@ -41,29 +41,46 @@ library ValidationLogic {
{
(bool isActive, bool isFreezed, , ) = _reserve.configuration.getFlags();
internalValidateReserveStateAndAmount(_reserve, _amount);
require(_amount > 0, 'Amount must be greater than 0');
}
/**
* @dev validates a redeem.
* @param _reserve the reserve state from which the user is redeeming
* @dev validates a withdraw action.
* @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(
ReserveLogic.ReserveData storage _reserve,
function validateWithdraw(
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 {
internalValidateReserveStateAndAmount(_reserve, _amount);
require(_amount > 0, 'Amount must be greater than 0');
require(msg.sender == _reserve.aTokenAddress, '31');
uint256 currentAvailableLiquidity = IERC20(_reserveAddress).balanceOf(
address(_reserve.aTokenAddress)
);
uint256 currentAvailableLiquidity = IERC20(_reserveAddress).balanceOf(address(_aTokenAddress));
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 {
@ -135,9 +152,7 @@ library ValidationLogic {
);
//check that the amount is available in the reserve
vars.availableLiquidity = IERC20(_reserveAddress).balanceOf(
address(_reserve.aTokenAddress)
);
vars.availableLiquidity = IERC20(_reserveAddress).balanceOf(address(_reserve.aTokenAddress));
require(vars.availableLiquidity >= _amount, '7');
@ -325,16 +340,4 @@ library ValidationLogic {
'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');
}
}

View File

@ -4,7 +4,7 @@ pragma solidity ^0.6.8;
import {ERC20} from './ERC20.sol';
import {LendingPool} from '../lendingpool/LendingPool.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 {
VersionedInitializable
} 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 _fromIndex the last index of the user
**/
event Redeem(
event BurnOnWithdraw(
address indexed _from,
uint256 _value,
uint256 _fromBalanceIncrease,
@ -219,61 +219,35 @@ contract AToken is VersionedInitializable, ERC20 {
* @dev redeems aToken for the underlying asset
* @param _amount the amount being redeemed
**/
function redeem(uint256 _amount) external {
require(_amount > 0, 'Amount to redeem needs to be > 0');
function burnOnWithdraw(address _user, uint256 _amount) external onlyLendingPool {
//cumulates the balance of the user
(, uint256 currentBalance, uint256 balanceIncrease) = calculateBalanceIncreaseInternal(
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.');
(, uint256 currentBalance, uint256 balanceIncrease) = calculateBalanceIncreaseInternal(_user);
//if the user is redirecting his interest towards someone else,
//we update the redirected balance of the redirection address by adding the accrued interest,
//and removing the amount to redeem
updateRedirectedBalanceOfRedirectionAddressInternal(
msg.sender,
balanceIncrease,
amountToRedeem
);
updateRedirectedBalanceOfRedirectionAddressInternal(_user, balanceIncrease, _amount);
if(balanceIncrease > amountToRedeem){
_mint(msg.sender, balanceIncrease.sub(amountToRedeem));
}
else{
_burn(msg.sender, amountToRedeem.sub(balanceIncrease));
if (balanceIncrease > _amount) {
_mint(_user, balanceIncrease.sub(_amount));
} else {
_burn(_user, _amount.sub(balanceIncrease));
}
uint256 userIndex = 0;
//reset the user data if the remaining balance is 0
if (currentBalance.sub(amountToRedeem) == 0) {
resetDataOnZeroBalanceInternal(msg.sender);
if (currentBalance.sub(_amount) == 0) {
resetDataOnZeroBalanceInternal(_user);
} else {
//updates the user index
userIndex = userIndexes[msg.sender] = pool.getReserveNormalizedIncome(underlyingAssetAddress);
//updates the user index
userIndex = userIndexes[_user] = pool.getReserveNormalizedIncome(underlyingAssetAddress);
}
// executes redeem of the underlying asset
pool.redeemUnderlying(
underlyingAssetAddress,
msg.sender,
amountToRedeem,
currentBalance.sub(amountToRedeem)
);
//transfers the underlying to the user
ERC20(underlyingAssetAddress).safeTransfer(_user, _amount);
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
*/
function mintOnDeposit(address _user, uint256 _amount) external onlyLendingPool {
//cumulates the balance of the user
(, , uint256 balanceIncrease) = calculateBalanceIncreaseInternal(_user);
//updates the user index
uint256 index = userIndexes[_user] = pool.getReserveNormalizedIncome(underlyingAssetAddress);
//if the user is redirecting his interest towards someone else,
//we update the redirected balance of the redirection address by adding the accrued interest
//and the amount deposited
@ -450,12 +423,11 @@ contract AToken is VersionedInitializable, ERC20 {
return redirectedBalances[_user];
}
/**
* @dev calculates the increase in balance since the last user action
* @param _user the address of the user
* @return the last user principal balance, the current balance and the balance increase
**/
* @dev calculates the increase in balance since the last user action
* @param _user the address of the user
* @return the last user principal balance, the current balance and the balance increase
**/
function calculateBalanceIncreaseInternal(address _user)
internal
returns (
@ -473,11 +445,11 @@ contract AToken is VersionedInitializable, ERC20 {
//calculate the accrued interest since the last accumulation
balanceIncrease = currentBalance.sub(previousBalance);
}
return (previousBalance, currentBalance, balanceIncrease);
}
/**
/**
* @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
* @return the previous principal balance, the new principal balance, the balance increase
@ -492,7 +464,11 @@ contract AToken is VersionedInitializable, ERC20 {
uint256
)
{
(uint256 previousBalance, uint256 currentBalance, uint256 balanceIncrease) = calculateBalanceIncreaseInternal(_user);
(
uint256 previousBalance,
uint256 currentBalance,
uint256 balanceIncrease
) = calculateBalanceIncreaseInternal(_user);
_mint(_user, balanceIncrease);
@ -500,8 +476,7 @@ contract AToken is VersionedInitializable, ERC20 {
uint256 index = userIndexes[_user] = pool.getReserveNormalizedIncome(underlyingAssetAddress);
return (previousBalance, currentBalance, balanceIncrease, index);
}
}
/**
* @dev updates the redirected balance of the user. If the user is not redirecting his