mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Merge pull request #132 from aave/feat/gas-optimization-3
Feat/gas optimization 3
This commit is contained in:
commit
729194d587
|
@ -167,6 +167,16 @@ interface ILendingPool {
|
||||||
uint256 variableBorrowIndex
|
uint256 variableBorrowIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Emitted when the protocol treasury receives minted aTokens from the accrued interest.
|
||||||
|
* @param reserve the address of the reserve
|
||||||
|
* @param amountMinted the amount minted to the treasury
|
||||||
|
**/
|
||||||
|
event MintedToTreasury(
|
||||||
|
address indexed reserve,
|
||||||
|
uint256 amountMinted
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
|
* @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
|
||||||
* - E.g. User deposits 100 USDC and gets in return 100 aUSDC
|
* - E.g. User deposits 100 USDC and gets in return 100 aUSDC
|
||||||
|
|
|
@ -537,6 +537,34 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Mints the assets accrued through the reserve factor to the treasury in the form of aTokens
|
||||||
|
* @param reserves The list of reserves for which the minting needs to be executed
|
||||||
|
**/
|
||||||
|
function mintToTreasury(address[] calldata reserves) public {
|
||||||
|
for (uint256 i = 0; i < reserves.length; i++) {
|
||||||
|
address reserveAddress = reserves[i];
|
||||||
|
|
||||||
|
DataTypes.ReserveData storage reserve = _reserves[reserveAddress];
|
||||||
|
|
||||||
|
// this cover both inactive reserves and invalid reserves since the flag will be 0 for both
|
||||||
|
if(!reserve.configuration.getActive()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint256 accruedToTreasury = reserve.accruedToTreasury;
|
||||||
|
|
||||||
|
if (accruedToTreasury != 0) {
|
||||||
|
uint256 normalizedIncome = reserve.getNormalizedIncome();
|
||||||
|
uint256 amountToMint = accruedToTreasury.rayMul(normalizedIncome);
|
||||||
|
IAToken(reserve.aTokenAddress).mintToTreasury(amountToMint, normalizedIncome);
|
||||||
|
|
||||||
|
reserve.accruedToTreasury = 0;
|
||||||
|
emit MintedToTreasury(reserveAddress, amountToMint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Returns the state and configuration of the reserve
|
* @dev Returns the state and configuration of the reserve
|
||||||
* @param asset The address of the underlying asset of the reserve
|
* @param asset The address of the underlying asset of the reserve
|
||||||
|
|
|
@ -123,7 +123,7 @@ library ReserveLogic {
|
||||||
lastUpdatedTimestamp
|
lastUpdatedTimestamp
|
||||||
);
|
);
|
||||||
|
|
||||||
_mintToTreasury(
|
_accrueToTreasury(
|
||||||
reserve,
|
reserve,
|
||||||
scaledVariableDebt,
|
scaledVariableDebt,
|
||||||
previousVariableBorrowIndex,
|
previousVariableBorrowIndex,
|
||||||
|
@ -271,7 +271,7 @@ library ReserveLogic {
|
||||||
* @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 _accrueToTreasury(
|
||||||
DataTypes.ReserveData storage reserve,
|
DataTypes.ReserveData storage reserve,
|
||||||
uint256 scaledVariableDebt,
|
uint256 scaledVariableDebt,
|
||||||
uint256 previousVariableBorrowIndex,
|
uint256 previousVariableBorrowIndex,
|
||||||
|
@ -320,7 +320,7 @@ library ReserveLogic {
|
||||||
vars.amountToMint = vars.totalDebtAccrued.percentMul(vars.reserveFactor);
|
vars.amountToMint = vars.totalDebtAccrued.percentMul(vars.reserveFactor);
|
||||||
|
|
||||||
if (vars.amountToMint != 0) {
|
if (vars.amountToMint != 0) {
|
||||||
IAToken(reserve.aTokenAddress).mintToTreasury(vars.amountToMint, newLiquidityIndex);
|
reserve.accruedToTreasury = reserve.accruedToTreasury.add(vars.amountToMint.rayDiv(newLiquidityIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@ library DataTypes {
|
||||||
address interestRateStrategyAddress;
|
address interestRateStrategyAddress;
|
||||||
//the id of the reserve. Represents the position in the list of the active reserves
|
//the id of the reserve. Represents the position in the list of the active reserves
|
||||||
uint8 id;
|
uint8 id;
|
||||||
|
//the current treasury balance, scaled
|
||||||
|
uint256 accruedToTreasury;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ReserveConfigurationMap {
|
struct ReserveConfigurationMap {
|
||||||
|
|
|
@ -1196,7 +1196,7 @@ const calcLinearInterest = (
|
||||||
return cumulatedInterest;
|
return cumulatedInterest;
|
||||||
};
|
};
|
||||||
|
|
||||||
const calcCompoundedInterest = (
|
export const calcCompoundedInterest = (
|
||||||
rate: BigNumber,
|
rate: BigNumber,
|
||||||
currentTimestamp: BigNumber,
|
currentTimestamp: BigNumber,
|
||||||
lastUpdateTimestamp: BigNumber
|
lastUpdateTimestamp: BigNumber
|
||||||
|
|
90
test-suites/test-aave/mint-to-treasury.spec.ts
Normal file
90
test-suites/test-aave/mint-to-treasury.spec.ts
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
import { makeSuite, TestEnv } from './helpers/make-suite';
|
||||||
|
import { RateMode } from '../../helpers/types';
|
||||||
|
import { APPROVAL_AMOUNT_LENDING_POOL, ONE_YEAR } from '../../helpers/constants';
|
||||||
|
import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
|
||||||
|
import { BigNumber } from 'bignumber.js';
|
||||||
|
import { advanceTimeAndBlock, waitForTx } from '../../helpers/misc-utils';
|
||||||
|
import './helpers/utils/math';
|
||||||
|
|
||||||
|
const { expect } = require('chai');
|
||||||
|
|
||||||
|
makeSuite('Mint to treasury', (testEnv: TestEnv) => {
|
||||||
|
it('User 0 deposits 1000 DAI. Borrower borrows 100 DAI. Clock moved forward one year. Calculates and verifies the amount accrued to the treasury', async () => {
|
||||||
|
const { users, pool, dai, helpersContract } = testEnv;
|
||||||
|
|
||||||
|
const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
|
||||||
|
const amountDAItoBorrow = await convertToCurrencyDecimals(dai.address, '100');
|
||||||
|
|
||||||
|
await waitForTx(await dai.connect(users[0].signer).mint(amountDAItoDeposit));
|
||||||
|
|
||||||
|
// user 0 deposits 1000 DAI
|
||||||
|
await waitForTx(
|
||||||
|
await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL)
|
||||||
|
);
|
||||||
|
await waitForTx(
|
||||||
|
await pool
|
||||||
|
.connect(users[0].signer)
|
||||||
|
.deposit(dai.address, amountDAItoDeposit, users[0].address, '0')
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitForTx(
|
||||||
|
await pool
|
||||||
|
.connect(users[0].signer)
|
||||||
|
.borrow(dai.address, amountDAItoBorrow, RateMode.Variable, '0', users[0].address)
|
||||||
|
);
|
||||||
|
|
||||||
|
const { reserveFactor } = await helpersContract.getReserveConfigurationData(dai.address);
|
||||||
|
|
||||||
|
await advanceTimeAndBlock(parseInt(ONE_YEAR));
|
||||||
|
|
||||||
|
await waitForTx(await dai.connect(users[0].signer).mint(amountDAItoDeposit));
|
||||||
|
|
||||||
|
await waitForTx(
|
||||||
|
await pool
|
||||||
|
.connect(users[0].signer)
|
||||||
|
.deposit(dai.address, amountDAItoDeposit, users[0].address, '0')
|
||||||
|
);
|
||||||
|
|
||||||
|
const { liquidityIndex, variableBorrowIndex } = await pool.getReserveData(dai.address);
|
||||||
|
|
||||||
|
const amountBorrowedBN = new BigNumber(amountDAItoBorrow.toString());
|
||||||
|
const liquidityIndexBN = new BigNumber(liquidityIndex.toString());
|
||||||
|
const variableBorrowIndexBN = new BigNumber(variableBorrowIndex.toString());
|
||||||
|
|
||||||
|
const expectedAccruedToTreasury = amountBorrowedBN
|
||||||
|
.rayMul(variableBorrowIndexBN)
|
||||||
|
.minus(amountBorrowedBN)
|
||||||
|
.times(reserveFactor.toString())
|
||||||
|
.div(10000)
|
||||||
|
.rayDiv(liquidityIndexBN)
|
||||||
|
.toFixed(0);
|
||||||
|
|
||||||
|
const { accruedToTreasury } = await pool.getReserveData(dai.address);
|
||||||
|
|
||||||
|
console.log("Accrued to treasury ", accruedToTreasury.toString());
|
||||||
|
|
||||||
|
expect(accruedToTreasury.toString()).to.be.bignumber.almostEqual(
|
||||||
|
expectedAccruedToTreasury,
|
||||||
|
'Invalid amount accrued to the treasury'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Mints the accrued to the treasury', async () => {
|
||||||
|
const { users, pool, dai, aDai, helpersContract } = testEnv;
|
||||||
|
|
||||||
|
const treasuryAddress = await aDai.RESERVE_TREASURY_ADDRESS();
|
||||||
|
const { accruedToTreasury } = await pool.getReserveData(dai.address);
|
||||||
|
|
||||||
|
await waitForTx(await pool.connect(users[0].signer).mintToTreasury([dai.address]));
|
||||||
|
const normalizedIncome = await pool.getReserveNormalizedIncome(dai.address);
|
||||||
|
|
||||||
|
const treasuryBalance = await aDai.balanceOf(treasuryAddress);
|
||||||
|
|
||||||
|
const expectedTreasuryBalance = new BigNumber(accruedToTreasury.toString()).rayMul(
|
||||||
|
new BigNumber(normalizedIncome.toString())
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(treasuryBalance.toString()).to.be.bignumber.almostEqual(expectedTreasuryBalance, "Invalid treasury balance after minting");
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
|
@ -1195,7 +1195,7 @@ const calcLinearInterest = (
|
||||||
return cumulatedInterest;
|
return cumulatedInterest;
|
||||||
};
|
};
|
||||||
|
|
||||||
const calcCompoundedInterest = (
|
export const calcCompoundedInterest = (
|
||||||
rate: BigNumber,
|
rate: BigNumber,
|
||||||
currentTimestamp: BigNumber,
|
currentTimestamp: BigNumber,
|
||||||
lastUpdateTimestamp: BigNumber
|
lastUpdateTimestamp: BigNumber
|
||||||
|
|
Loading…
Reference in New Issue
Block a user