Merge branch 'fix/68' into 'master'

Resolve "Gas optimizations"

Closes #68

See merge request aave-tech/protocol-v2!77
This commit is contained in:
Ernesto Boado 2020-10-16 08:05:11 +00:00
commit 017589a8f7
6 changed files with 39 additions and 26 deletions

View File

@ -104,13 +104,12 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
reserve.updateState(); reserve.updateState();
reserve.updateInterestRates(asset, aToken, amount, 0); reserve.updateInterestRates(asset, aToken, amount, 0);
bool isFirstDeposit = IAToken(aToken).balanceOf(onBehalfOf) == 0; bool isFirstDeposit = IAToken(aToken).mint(onBehalfOf, amount, reserve.liquidityIndex);
if (isFirstDeposit) { if (isFirstDeposit) {
_usersConfig[onBehalfOf].setUsingAsCollateral(reserve.id, true); _usersConfig[onBehalfOf].setUsingAsCollateral(reserve.id, true);
} }
IAToken(aToken).mint(onBehalfOf, amount, reserve.liquidityIndex);
//transfer to the aToken contract //transfer to the aToken contract
IERC20(asset).safeTransferFrom(msg.sender, aToken, amount); IERC20(asset).safeTransferFrom(msg.sender, aToken, amount);

View File

@ -146,21 +146,22 @@ library ReserveLogic {
* a formal specification. * a formal specification.
* @param reserve the reserve object * @param reserve the reserve object
**/ **/
function updateState(ReserveData storage reserve) external { function updateState(ReserveData storage reserve) internal {
address variableDebtToken = reserve.variableDebtTokenAddress; uint256 scaledVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress)
.scaledTotalSupply();
uint256 previousVariableBorrowIndex = reserve.variableBorrowIndex; uint256 previousVariableBorrowIndex = reserve.variableBorrowIndex;
uint256 previousLiquidityIndex = reserve.liquidityIndex; uint256 previousLiquidityIndex = reserve.liquidityIndex;
(uint256 newLiquidityIndex, uint256 newVariableBorrowIndex) = _updateIndexes( (uint256 newLiquidityIndex, uint256 newVariableBorrowIndex) = _updateIndexes(
reserve, reserve,
variableDebtToken, scaledVariableDebt,
previousLiquidityIndex, previousLiquidityIndex,
previousVariableBorrowIndex previousVariableBorrowIndex
); );
_mintToTreasury( _mintToTreasury(
reserve, reserve,
variableDebtToken, scaledVariableDebt,
previousVariableBorrowIndex, previousVariableBorrowIndex,
newLiquidityIndex, newLiquidityIndex,
newVariableBorrowIndex newVariableBorrowIndex
@ -178,7 +179,7 @@ library ReserveLogic {
ReserveData storage reserve, ReserveData storage reserve,
uint256 totalLiquidity, uint256 totalLiquidity,
uint256 amount uint256 amount
) external { ) internal {
uint256 amountToLiquidityRatio = amount.wadToRay().rayDiv(totalLiquidity.wadToRay()); uint256 amountToLiquidityRatio = amount.wadToRay().rayDiv(totalLiquidity.wadToRay());
uint256 result = amountToLiquidityRatio.add(WadRayMath.ray()); uint256 result = amountToLiquidityRatio.add(WadRayMath.ray());
@ -226,6 +227,7 @@ library ReserveLogic {
uint256 newStableRate; uint256 newStableRate;
uint256 newVariableRate; uint256 newVariableRate;
uint256 avgStableRate; uint256 avgStableRate;
uint256 totalVariableDebt;
} }
/** /**
@ -241,7 +243,7 @@ library ReserveLogic {
address aTokenAddress, address aTokenAddress,
uint256 liquidityAdded, uint256 liquidityAdded,
uint256 liquidityTaken uint256 liquidityTaken
) external { ) internal {
UpdateInterestRatesLocalVars memory vars; UpdateInterestRatesLocalVars memory vars;
vars.stableDebtTokenAddress = reserve.stableDebtTokenAddress; vars.stableDebtTokenAddress = reserve.stableDebtTokenAddress;
@ -249,6 +251,13 @@ library ReserveLogic {
(vars.totalStableDebt, vars.avgStableRate) = IStableDebtToken(vars.stableDebtTokenAddress) (vars.totalStableDebt, vars.avgStableRate) = IStableDebtToken(vars.stableDebtTokenAddress)
.getTotalSupplyAndAvgRate(); .getTotalSupplyAndAvgRate();
//calculates the total variable debt locally using the scaled total supply instead
//of totalSupply(), as it's noticeably cheaper. Also, the index has been
//updated by the previous updateState() call
vars.totalVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress)
.scaledTotalSupply()
.rayMul(reserve.variableBorrowIndex);
vars.availableLiquidity = IERC20(reserveAddress).balanceOf(aTokenAddress); vars.availableLiquidity = IERC20(reserveAddress).balanceOf(aTokenAddress);
( (
@ -259,7 +268,7 @@ library ReserveLogic {
reserveAddress, reserveAddress,
vars.availableLiquidity.add(liquidityAdded).sub(liquidityTaken), vars.availableLiquidity.add(liquidityAdded).sub(liquidityTaken),
vars.totalStableDebt, vars.totalStableDebt,
IERC20(reserve.variableDebtTokenAddress).totalSupply(), vars.totalVariableDebt,
vars.avgStableRate, vars.avgStableRate,
reserve.configuration.getReserveFactor() reserve.configuration.getReserveFactor()
); );
@ -286,7 +295,6 @@ library ReserveLogic {
uint256 principalStableDebt; uint256 principalStableDebt;
uint256 previousStableDebt; uint256 previousStableDebt;
uint256 currentVariableDebt; uint256 currentVariableDebt;
uint256 scaledVariableDebt;
uint256 previousVariableDebt; uint256 previousVariableDebt;
uint256 avgStableRate; uint256 avgStableRate;
uint256 cumulatedStableInterest; uint256 cumulatedStableInterest;
@ -300,14 +308,14 @@ library ReserveLogic {
* @dev mints part of the repaid interest to the reserve treasury, depending on the reserveFactor for the * @dev mints part of the repaid interest to the reserve treasury, depending on the reserveFactor for the
* specific asset. * specific asset.
* @param reserve the reserve reserve to be updated * @param reserve the reserve reserve to be updated
* @param variableDebtToken the debt token address * @param scaledVariableDebt the current scaled total variable debt
* @param previousVariableBorrowIndex the variable borrow index before the last accumulation of the interest * @param previousVariableBorrowIndex the variable borrow index before the last accumulation of the interest
* @param newLiquidityIndex the new liquidity index * @param newLiquidityIndex the new liquidity index
* @param newVariableBorrowIndex the variable borrow index after the last accumulation of the interest * @param newVariableBorrowIndex the variable borrow index after the last accumulation of the interest
**/ **/
function _mintToTreasury( function _mintToTreasury(
ReserveData storage reserve, ReserveData storage reserve,
address variableDebtToken, uint256 scaledVariableDebt,
uint256 previousVariableBorrowIndex, uint256 previousVariableBorrowIndex,
uint256 newLiquidityIndex, uint256 newLiquidityIndex,
uint256 newVariableBorrowIndex uint256 newVariableBorrowIndex
@ -320,9 +328,6 @@ library ReserveLogic {
return; return;
} }
//fetching the last scaled total variable debt
vars.scaledVariableDebt = IVariableDebtToken(variableDebtToken).scaledTotalSupply();
//fetching the principal, total stable debt and the avg stable rate //fetching the principal, total stable debt and the avg stable rate
( (
vars.principalStableDebt, vars.principalStableDebt,
@ -332,10 +337,10 @@ library ReserveLogic {
) = IStableDebtToken(reserve.stableDebtTokenAddress).getSupplyData(); ) = IStableDebtToken(reserve.stableDebtTokenAddress).getSupplyData();
//calculate the last principal variable debt //calculate the last principal variable debt
vars.previousVariableDebt = vars.scaledVariableDebt.rayMul(previousVariableBorrowIndex); vars.previousVariableDebt = scaledVariableDebt.rayMul(previousVariableBorrowIndex);
//calculate the new total supply after accumulation of the index //calculate the new total supply after accumulation of the index
vars.currentVariableDebt = vars.scaledVariableDebt.rayMul(newVariableBorrowIndex); vars.currentVariableDebt = scaledVariableDebt.rayMul(newVariableBorrowIndex);
//calculate the stable debt until the last timestamp update //calculate the stable debt until the last timestamp update
vars.cumulatedStableInterest = MathUtils.calculateCompoundedInterest( vars.cumulatedStableInterest = MathUtils.calculateCompoundedInterest(
@ -360,13 +365,13 @@ library ReserveLogic {
/** /**
* @dev updates the reserve indexes and the timestamp of the update * @dev updates the reserve indexes and the timestamp of the update
* @param reserve the reserve reserve to be updated * @param reserve the reserve reserve to be updated
* @param variableDebtToken the debt token address * @param scaledVariableDebt the scaled variable debt
* @param liquidityIndex the last stored liquidity index * @param liquidityIndex the last stored liquidity index
* @param variableBorrowIndex the last stored variable borrow index * @param variableBorrowIndex the last stored variable borrow index
**/ **/
function _updateIndexes( function _updateIndexes(
ReserveData storage reserve, ReserveData storage reserve,
address variableDebtToken, uint256 scaledVariableDebt,
uint256 liquidityIndex, uint256 liquidityIndex,
uint256 variableBorrowIndex uint256 variableBorrowIndex
) internal returns (uint256, uint256) { ) internal returns (uint256, uint256) {
@ -390,7 +395,7 @@ library ReserveLogic {
//as the liquidity rate might come only from stable rate loans, we need to ensure //as the liquidity rate might come only from stable rate loans, we need to ensure
//that there is actual variable debt before accumulating //that there is actual variable debt before accumulating
if (IERC20(variableDebtToken).totalSupply() > 0) { if (scaledVariableDebt != 0) {
uint256 cumulatedVariableBorrowInterest = MathUtils.calculateCompoundedInterest( uint256 cumulatedVariableBorrowInterest = MathUtils.calculateCompoundedInterest(
reserve.currentVariableBorrowRate, reserve.currentVariableBorrowRate,
timestamp timestamp

View File

@ -33,7 +33,7 @@ library ValidationLogic {
* @param reserve the reserve state on which the user is depositing * @param reserve the reserve state on which the user is depositing
* @param amount the amount to be deposited * @param amount the amount to be deposited
*/ */
function validateDeposit(ReserveLogic.ReserveData storage reserve, uint256 amount) external view { function validateDeposit(ReserveLogic.ReserveData storage reserve, uint256 amount) internal view {
(bool isActive, bool isFreezed, , ) = reserve.configuration.getFlags(); (bool isActive, bool isFreezed, , ) = reserve.configuration.getFlags();
require(amount > 0, Errors.AMOUNT_NOT_GREATER_THAN_0); require(amount > 0, Errors.AMOUNT_NOT_GREATER_THAN_0);
@ -56,7 +56,7 @@ library ValidationLogic {
mapping(uint256 => address) storage reserves, mapping(uint256 => address) storage reserves,
uint256 reservesCount, uint256 reservesCount,
address oracle address oracle
) external view { ) internal view {
require(amount > 0, Errors.AMOUNT_NOT_GREATER_THAN_0); require(amount > 0, Errors.AMOUNT_NOT_GREATER_THAN_0);
require(amount <= userBalance, Errors.NOT_ENOUGH_AVAILABLE_USER_BALANCE); require(amount <= userBalance, Errors.NOT_ENOUGH_AVAILABLE_USER_BALANCE);

View File

@ -117,12 +117,15 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
* @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 to mint
* @param index the the last index of the reserve * @param index the the last index of the reserve
* @return true if the the previous balance of the user is 0
*/ */
function mint( function mint(
address user, address user,
uint256 amount, uint256 amount,
uint256 index uint256 index
) external override onlyLendingPool { ) external override onlyLendingPool returns (bool) {
uint256 previousBalance = super.balanceOf(user);
uint256 amountScaled = amount.rayDiv(index); uint256 amountScaled = amount.rayDiv(index);
require(amountScaled != 0, Errors.INVALID_MINT_AMOUNT); require(amountScaled != 0, Errors.INVALID_MINT_AMOUNT);
_mint(user, amountScaled); _mint(user, amountScaled);
@ -130,6 +133,8 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
//transfer event to track balances //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);
return previousBalance == 0;
} }
/** /**

View File

@ -51,12 +51,14 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
* @param user the user receiving the debt * @param user the user receiving the debt
* @param amount the amount of debt being minted * @param amount the amount of debt being minted
* @param index the variable debt index of the reserve * @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,
uint256 amount, uint256 amount,
uint256 index uint256 index
) external override onlyLendingPool { ) external override onlyLendingPool returns (bool) {
uint256 previousBalance = super.balanceOf(user);
uint256 amountScaled = amount.rayDiv(index); uint256 amountScaled = amount.rayDiv(index);
require(amountScaled != 0, Errors.INVALID_MINT_AMOUNT); require(amountScaled != 0, Errors.INVALID_MINT_AMOUNT);
@ -64,6 +66,8 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
emit Transfer(address(0), user, amount); emit Transfer(address(0), user, amount);
emit Mint(user, amount, index); emit Mint(user, amount, index);
return previousBalance == 0;
} }
/** /**

View File

@ -21,7 +21,7 @@ interface IScaledBalanceToken {
address user, address user,
uint256 amount, uint256 amount,
uint256 index uint256 index
) external; ) external returns (bool);
/** /**
* @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