small lending pool gas optimization

This commit is contained in:
andyk 2020-08-25 13:37:38 +03:00
parent eba3b5260f
commit b0ddb815b8
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); ValidationLogic.validateDeposit(reserve, amount);
IAToken aToken = IAToken(reserve.aTokenAddress); address aToken = reserve.aTokenAddress;
bool isFirstDeposit = aToken.balanceOf(msg.sender) == 0;
reserve.updateCumulativeIndexesAndTimestamp(); reserve.updateCumulativeIndexesAndTimestamp();
reserve.updateInterestRates(asset, amount, 0); reserve.updateInterestRates(asset, aToken, amount, 0);
bool isFirstDeposit = IAToken(aToken).balanceOf(msg.sender) == 0;
if (isFirstDeposit) { if (isFirstDeposit) {
_usersConfig[msg.sender].setUsingAsCollateral(reserve.index, true); _usersConfig[msg.sender].setUsingAsCollateral(reserve.index, true);
} }
//minting AToken to user 1:1 with the specific exchange rate //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 //transfer to the aToken contract
IERC20(asset).safeTransferFrom(msg.sender, address(aToken), amount); IERC20(asset).safeTransferFrom(msg.sender, aToken, amount);
//solium-disable-next-line //solium-disable-next-line
emit Deposit(asset, msg.sender, amount, referralCode); 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 { function withdraw(address asset, uint256 amount) external override nonReentrant {
ReserveLogic.ReserveData storage reserve = _reserves[asset]; 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; uint256 amountToWithdraw = amount;
@ -134,7 +133,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
ValidationLogic.validateWithdraw( ValidationLogic.validateWithdraw(
asset, asset,
address(aToken), aToken,
amountToWithdraw, amountToWithdraw,
userBalance, userBalance,
_reserves, _reserves,
@ -145,13 +144,13 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
reserve.updateCumulativeIndexesAndTimestamp(); reserve.updateCumulativeIndexesAndTimestamp();
reserve.updateInterestRates(asset, 0, amountToWithdraw); reserve.updateInterestRates(asset, aToken, 0, amountToWithdraw);
if (amountToWithdraw == userBalance) { if (amountToWithdraw == userBalance) {
_usersConfig[msg.sender].setUsingAsCollateral(reserve.index, false); _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 //solium-disable-next-line
emit Withdraw(asset, msg.sender, amount); emit Withdraw(asset, msg.sender, amount);
@ -202,14 +201,16 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
IVariableDebtToken(reserve.variableDebtTokenAddress).mint(msg.sender, amount); 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)) { uint256 reserveIndex = reserve.index;
userConfig.setBorrowing(reserve.index, true); if (!userConfig.isBorrowing(reserveIndex)) {
userConfig.setBorrowing(reserveIndex, true);
} }
//if we reached this point, we can transfer //if we reached this point, we can transfer
IAToken(reserve.aTokenAddress).transferUnderlyingTo(msg.sender, amount); IAToken(aToken).transferUnderlyingTo(msg.sender, amount);
emit Borrow( emit Borrow(
asset, asset,
@ -270,13 +271,14 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
IVariableDebtToken(reserve.variableDebtTokenAddress).burn(onBehalfOf, paybackAmount); 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) { if (stableDebt.add(variableDebt).sub(paybackAmount) == 0) {
_usersConfig[onBehalfOf].setBorrowing(reserve.index, false); _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); 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( emit Swap(
asset, asset,
@ -367,7 +369,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
stableDebtToken.burn(user, stableBorrowBalance); stableDebtToken.burn(user, stableBorrowBalance);
stableDebtToken.mint(user, stableBorrowBalance, reserve.currentStableBorrowRate); stableDebtToken.mint(user, stableBorrowBalance, reserve.currentStableBorrowRate);
reserve.updateInterestRates(asset, 0, 0); reserve.updateInterestRates(asset, reserve.aTokenAddress, 0, 0);
emit RebalanceStableBorrowRate(asset, user); emit RebalanceStableBorrowRate(asset, user);
@ -501,7 +503,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
reserve.cumulateToLiquidityIndex(totalLiquidityBefore, amountFee); reserve.cumulateToLiquidityIndex(totalLiquidityBefore, amountFee);
//refresh interest rates //refresh interest rates
reserve.updateInterestRates(asset, amountFee, 0); reserve.updateInterestRates(asset, aTokenAddress, amountFee, 0);
//solium-disable-next-line //solium-disable-next-line
emit FlashLoan(receiverAddress, asset, amount, amountFee); 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 = vars.isCollateralEnabled =
collateralReserve.configuration.getLiquidationThreshold() > 0 && collateralReserve.configuration.getLiquidationThreshold() > 0 &&
@ -192,8 +194,6 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
vars.actualAmountToLiquidate = vars.principalAmountNeeded; 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 liquidator reclaims the underlying asset, we make sure there is enough available collateral in the reserve
if (!receiveAToken) { if (!receiveAToken) {
uint256 currentAvailableCollateral = IERC20(collateral).balanceOf( uint256 currentAvailableCollateral = IERC20(collateral).balanceOf(
@ -209,7 +209,12 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
//update the principal reserve //update the principal reserve
principalReserve.updateCumulativeIndexesAndTimestamp(); principalReserve.updateCumulativeIndexesAndTimestamp();
principalReserve.updateInterestRates(principal, vars.actualAmountToLiquidate, 0); principalReserve.updateInterestRates(
principal,
principalReserve.aTokenAddress,
vars.actualAmountToLiquidate,
0
);
if (vars.userVariableDebt >= vars.actualAmountToLiquidate) { if (vars.userVariableDebt >= vars.actualAmountToLiquidate) {
IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn( IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(
@ -235,7 +240,12 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
//updating collateral reserve //updating collateral reserve
collateralReserve.updateCumulativeIndexesAndTimestamp(); collateralReserve.updateCumulativeIndexesAndTimestamp();
collateralReserve.updateInterestRates(collateral, 0, vars.maxCollateralToLiquidate); collateralReserve.updateInterestRates(
collateral,
address(vars.collateralAtoken),
0,
vars.maxCollateralToLiquidate
);
//burn the equivalent amount of atoken //burn the equivalent amount of atoken
vars.collateralAtoken.burn(user, msg.sender, vars.maxCollateralToLiquidate); vars.collateralAtoken.burn(user, msg.sender, vars.maxCollateralToLiquidate);

View File

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