Merge branch 'fix/lp-gas-optimization' into 'master'

Small lending pool gas optimization

See merge request aave-tech/protocol-v2!34
This commit is contained in:
Ernesto Boado 2020-08-25 12:59:12 +00:00
commit cd09d04d30
3 changed files with 45 additions and 36 deletions

View File

@ -92,22 +92,21 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
ValidationLogic.validateDeposit(reserve, amount);
IAToken aToken = IAToken(reserve.aTokenAddress);
bool isFirstDeposit = aToken.balanceOf(msg.sender) == 0;
address aToken = reserve.aTokenAddress;
reserve.updateCumulativeIndexesAndTimestamp();
reserve.updateInterestRates(asset, amount, 0);
reserve.updateInterestRates(asset, aToken, amount, 0);
bool isFirstDeposit = IAToken(aToken).balanceOf(msg.sender) == 0;
if (isFirstDeposit) {
_usersConfig[msg.sender].setUsingAsCollateral(reserve.index, true);
}
//minting AToken to user 1:1 with the specific exchange rate
aToken.mint(msg.sender, amount);
IAToken(aToken).mint(msg.sender, amount);
//transfer to the aToken contract
IERC20(asset).safeTransferFrom(msg.sender, address(aToken), amount);
IERC20(asset).safeTransferFrom(msg.sender, aToken, amount);
//solium-disable-next-line
emit Deposit(asset, msg.sender, amount, referralCode);
@ -121,9 +120,9 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
function withdraw(address asset, uint256 amount) external override nonReentrant {
ReserveLogic.ReserveData storage reserve = _reserves[asset];
IAToken aToken = IAToken(reserve.aTokenAddress);
address aToken = reserve.aTokenAddress;
uint256 userBalance = aToken.balanceOf(msg.sender);
uint256 userBalance = IAToken(aToken).balanceOf(msg.sender);
uint256 amountToWithdraw = amount;
@ -134,7 +133,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
ValidationLogic.validateWithdraw(
asset,
address(aToken),
aToken,
amountToWithdraw,
userBalance,
_reserves,
@ -145,13 +144,13 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
reserve.updateCumulativeIndexesAndTimestamp();
reserve.updateInterestRates(asset, 0, amountToWithdraw);
reserve.updateInterestRates(asset, aToken, 0, amountToWithdraw);
if (amountToWithdraw == userBalance) {
_usersConfig[msg.sender].setUsingAsCollateral(reserve.index, false);
}
aToken.burn(msg.sender, msg.sender, amountToWithdraw);
IAToken(aToken).burn(msg.sender, msg.sender, amountToWithdraw);
//solium-disable-next-line
emit Withdraw(asset, msg.sender, amount);
@ -202,14 +201,16 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
IVariableDebtToken(reserve.variableDebtTokenAddress).mint(msg.sender, amount);
}
reserve.updateInterestRates(asset, 0, amount);
address aToken = reserve.aTokenAddress;
reserve.updateInterestRates(asset, aToken, 0, amount);
if (!userConfig.isBorrowing(reserve.index)) {
userConfig.setBorrowing(reserve.index, true);
uint256 reserveIndex = reserve.index;
if (!userConfig.isBorrowing(reserveIndex)) {
userConfig.setBorrowing(reserveIndex, true);
}
//if we reached this point, we can transfer
IAToken(reserve.aTokenAddress).transferUnderlyingTo(msg.sender, amount);
IAToken(aToken).transferUnderlyingTo(msg.sender, amount);
emit Borrow(
asset,
@ -270,13 +271,14 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
IVariableDebtToken(reserve.variableDebtTokenAddress).burn(onBehalfOf, paybackAmount);
}
reserve.updateInterestRates(asset, paybackAmount, 0);
address aToken = reserve.aTokenAddress;
reserve.updateInterestRates(asset, aToken, paybackAmount, 0);
if (stableDebt.add(variableDebt).sub(paybackAmount) == 0) {
_usersConfig[onBehalfOf].setBorrowing(reserve.index, false);
}
IERC20(asset).safeTransferFrom(msg.sender, reserve.aTokenAddress, paybackAmount);
IERC20(asset).safeTransferFrom(msg.sender, aToken, paybackAmount);
emit Repay(asset, onBehalfOf, msg.sender, paybackAmount);
}
@ -317,7 +319,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
);
}
reserve.updateInterestRates(asset, 0, 0);
reserve.updateInterestRates(asset, reserve.aTokenAddress, 0, 0);
emit Swap(
asset,
@ -367,7 +369,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
stableDebtToken.burn(user, stableBorrowBalance);
stableDebtToken.mint(user, stableBorrowBalance, reserve.currentStableBorrowRate);
reserve.updateInterestRates(asset, 0, 0);
reserve.updateInterestRates(asset, reserve.aTokenAddress, 0, 0);
emit RebalanceStableBorrowRate(asset, user);
@ -501,7 +503,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
reserve.cumulateToLiquidityIndex(totalLiquidityBefore, amountFee);
//refresh interest rates
reserve.updateInterestRates(asset, amountFee, 0);
reserve.updateInterestRates(asset, aTokenAddress, amountFee, 0);
//solium-disable-next-line
emit FlashLoan(receiverAddress, asset, amount, amountFee);

View File

@ -136,7 +136,9 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
);
}
vars.userCollateralBalance = IERC20(collateralReserve.aTokenAddress).balanceOf(user);
vars.collateralAtoken = IAToken(collateralReserve.aTokenAddress);
vars.userCollateralBalance = vars.collateralAtoken.balanceOf(user);
vars.isCollateralEnabled =
collateralReserve.configuration.getLiquidationThreshold() > 0 &&
@ -192,8 +194,6 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
vars.actualAmountToLiquidate = vars.principalAmountNeeded;
}
vars.collateralAtoken = IAToken(collateralReserve.aTokenAddress);
//if liquidator reclaims the underlying asset, we make sure there is enough available collateral in the reserve
if (!receiveAToken) {
uint256 currentAvailableCollateral = IERC20(collateral).balanceOf(
@ -209,7 +209,12 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
//update the principal reserve
principalReserve.updateCumulativeIndexesAndTimestamp();
principalReserve.updateInterestRates(principal, vars.actualAmountToLiquidate, 0);
principalReserve.updateInterestRates(
principal,
principalReserve.aTokenAddress,
vars.actualAmountToLiquidate,
0
);
if (vars.userVariableDebt >= vars.actualAmountToLiquidate) {
IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(
@ -235,7 +240,12 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
//updating collateral reserve
collateralReserve.updateCumulativeIndexesAndTimestamp();
collateralReserve.updateInterestRates(collateral, 0, vars.maxCollateralToLiquidate);
collateralReserve.updateInterestRates(
collateral,
address(vars.collateralAtoken),
0,
vars.maxCollateralToLiquidate
);
//burn the equivalent amount of atoken
vars.collateralAtoken.burn(user, msg.sender, vars.maxCollateralToLiquidate);

View File

@ -126,18 +126,18 @@ library ReserveLogic {
IERC20(reserve.variableDebtTokenAddress).totalSupply() > 0 ||
IERC20(reserve.stableDebtTokenAddress).totalSupply() > 0
) {
uint40 lastUpdateTimestamp = reserve.lastUpdateTimestamp;
uint256 cumulatedLiquidityInterest = MathUtils.calculateLinearInterest(
reserve.currentLiquidityRate,
reserve.lastUpdateTimestamp
lastUpdateTimestamp
);
reserve.lastLiquidityIndex = cumulatedLiquidityInterest.rayMul(
reserve.lastLiquidityIndex
);
reserve.lastLiquidityIndex = cumulatedLiquidityInterest.rayMul(reserve.lastLiquidityIndex);
uint256 cumulatedVariableBorrowInterest = MathUtils.calculateCompoundedInterest(
reserve.currentVariableBorrowRate,
reserve.lastUpdateTimestamp
lastUpdateTimestamp
);
reserve.lastVariableBorrowIndex = cumulatedVariableBorrowInterest.rayMul(
reserve.lastVariableBorrowIndex
@ -164,9 +164,7 @@ library ReserveLogic {
uint256 cumulatedLiquidity = amountToLiquidityRatio.add(WadRayMath.ray());
reserve.lastLiquidityIndex = cumulatedLiquidity.rayMul(
reserve.lastLiquidityIndex
);
reserve.lastLiquidityIndex = cumulatedLiquidity.rayMul(reserve.lastLiquidityIndex);
}
/**
@ -208,21 +206,20 @@ library ReserveLogic {
function updateInterestRates(
ReserveData storage reserve,
address reserveAddress,
address aTokenAddress,
uint256 liquidityAdded,
uint256 liquidityTaken
) internal {
uint256 currentAvgStableRate = IStableDebtToken(reserve.stableDebtTokenAddress)
.getAverageStableRate();
uint256 balance = IERC20(reserveAddress).balanceOf(reserve.aTokenAddress);
(
uint256 newLiquidityRate,
uint256 newStableRate,
uint256 newVariableRate
) = IReserveInterestRateStrategy(reserve.interestRateStrategyAddress).calculateInterestRates(
reserveAddress,
balance.add(liquidityAdded).sub(liquidityTaken),
IERC20(reserveAddress).balanceOf(aTokenAddress).add(liquidityAdded).sub(liquidityTaken),
IERC20(reserve.stableDebtTokenAddress).totalSupply(),
IERC20(reserve.variableDebtTokenAddress).totalSupply(),
currentAvgStableRate