Fixed mintToTreasury function

This commit is contained in:
The3D 2020-09-17 10:53:55 +02:00
parent bcdef6fa7e
commit 7986a4704b
4 changed files with 85 additions and 45 deletions

View File

@ -150,12 +150,28 @@ library ReserveLogic {
function updateState(ReserveData storage reserve) internal { function updateState(ReserveData storage reserve) internal {
address stableDebtToken = reserve.stableDebtTokenAddress; address stableDebtToken = reserve.stableDebtTokenAddress;
address variableDebtToken = reserve.variableDebtTokenAddress; address variableDebtToken = reserve.variableDebtTokenAddress;
uint256 variableBorrowIndex = reserve.variableBorrowIndex; uint256 previousVariableBorrowIndex = reserve.variableBorrowIndex;
uint256 liquidityIndex = reserve.liquidityIndex; uint256 previousLiquidityIndex = reserve.liquidityIndex;
uint40 timestamp = reserve.lastUpdateTimestamp; uint40 timestamp = reserve.lastUpdateTimestamp;
_mintToTreasury(reserve, stableDebtToken, variableDebtToken, liquidityIndex, variableBorrowIndex, timestamp); (uint256 newLiquidityIndex, uint256 newVariableBorrowIndex) = _updateIndexes(
_updateIndexes(reserve, variableDebtToken, liquidityIndex, variableBorrowIndex, timestamp); reserve,
variableDebtToken,
previousLiquidityIndex,
previousVariableBorrowIndex,
timestamp
);
_mintToTreasury(
reserve,
stableDebtToken,
variableDebtToken,
previousLiquidityIndex,
previousVariableBorrowIndex,
newLiquidityIndex,
newVariableBorrowIndex,
timestamp
);
} }
/** /**
@ -273,14 +289,15 @@ library ReserveLogic {
} }
struct MintToTreasuryLocalVars { struct MintToTreasuryLocalVars {
uint256 currentTotalDebt; uint256 currentStableDebt;
uint256 principalStableDebt; uint256 principalStableDebt;
uint256 avgStableRate; uint256 previousStableDebt;
uint256 currentVariableDebt;
uint256 scaledVariableDebt; uint256 scaledVariableDebt;
uint256 previousVariableDebt;
uint256 avgStableRate;
uint256 cumulatedStableInterest; uint256 cumulatedStableInterest;
uint256 variableDebtOnLastUpdate; uint256 totalDebtAccrued;
uint256 stableDebtOnLastUpdate;
uint256 totalInterestAccrued;
uint256 amountToMint; uint256 amountToMint;
uint256 reserveFactor; uint256 reserveFactor;
} }
@ -289,11 +306,12 @@ library ReserveLogic {
ReserveData storage reserve, ReserveData storage reserve,
address stableDebtToken, address stableDebtToken,
address variableDebtToken, address variableDebtToken,
uint256 liquidityIndex, uint256 previousLiquidityIndex,
uint256 variableBorrowIndex, uint256 previousVariableBorrowIndex,
uint40 lastUpdateTimestamp uint256 newLiquidityIndex,
uint256 newVariableBorrowIndex,
uint40 previousTimestamp
) internal { ) internal {
MintToTreasuryLocalVars memory vars; MintToTreasuryLocalVars memory vars;
vars.reserveFactor = reserve.configuration.getReserveFactor(); vars.reserveFactor = reserve.configuration.getReserveFactor();
@ -302,27 +320,39 @@ library ReserveLogic {
return; return;
} }
vars.currentTotalDebt = IERC20(variableDebtToken).totalSupply().add(IERC20(stableDebtToken).totalSupply()); //fetching the last scaled total variable debt
(vars.principalStableDebt, vars.avgStableRate) = IStableDebtToken(stableDebtToken)
.getPrincipalSupplyAndAvgRate();
vars.scaledVariableDebt = IVariableDebtToken(variableDebtToken).scaledTotalSupply(); vars.scaledVariableDebt = IVariableDebtToken(variableDebtToken).scaledTotalSupply();
//fetching the principal, total stable debt and the avg stable rate
(vars.principalStableDebt, vars.currentStableDebt, vars.avgStableRate) = IStableDebtToken(
stableDebtToken
)
.getSupplyData();
//calculate the last principal variable debt
vars.previousVariableDebt = vars.scaledVariableDebt.rayMul(previousVariableBorrowIndex);
//calculate the new total supply after accumulation of the index
vars.currentVariableDebt = vars.scaledVariableDebt.rayMul(newVariableBorrowIndex);
//calculate the stable debt until the last timestamp update
vars.cumulatedStableInterest = MathUtils.calculateCompoundedInterest( vars.cumulatedStableInterest = MathUtils.calculateCompoundedInterest(
vars.avgStableRate, vars.avgStableRate,
lastUpdateTimestamp previousTimestamp
); );
vars.variableDebtOnLastUpdate = vars.scaledVariableDebt.rayMul(variableBorrowIndex); vars.previousStableDebt = vars.principalStableDebt.rayMul(vars.cumulatedStableInterest);
vars.stableDebtOnLastUpdate = vars.principalStableDebt.rayMul(vars.cumulatedStableInterest);
vars.totalInterestAccrued =vars.currentTotalDebt.sub(vars.variableDebtOnLastUpdate.add(vars.stableDebtOnLastUpdate)); //debt accrued is the sum of the current debt minus the sum of the debt at the last update
vars.totalDebtAccrued = vars
.currentVariableDebt
.add(vars.currentStableDebt)
.sub(vars.previousVariableDebt)
.sub(vars.previousStableDebt);
vars.amountToMint = vars.totalInterestAccrued.percentMul(vars.reserveFactor); vars.amountToMint = vars.totalDebtAccrued.percentMul(vars.reserveFactor);
IAToken(reserve.aTokenAddress).mintToTreasury(vars.amountToMint, liquidityIndex);
IAToken(reserve.aTokenAddress).mintToTreasury(vars.amountToMint, newLiquidityIndex);
} }
function _updateIndexes( function _updateIndexes(
@ -331,19 +361,22 @@ library ReserveLogic {
uint256 liquidityIndex, uint256 liquidityIndex,
uint256 variableBorrowIndex, uint256 variableBorrowIndex,
uint40 lastUpdateTimestamp uint40 lastUpdateTimestamp
) internal { ) internal returns (uint256, uint256) {
uint256 currentLiquidityRate = reserve.currentLiquidityRate; uint256 currentLiquidityRate = reserve.currentLiquidityRate;
uint256 newLiquidityIndex = liquidityIndex;
uint256 newVariableBorrowIndex = variableBorrowIndex;
//only cumulating if there is any income being produced //only cumulating if there is any income being produced
if (currentLiquidityRate > 0) { if (currentLiquidityRate > 0) {
uint256 cumulatedLiquidityInterest = MathUtils.calculateLinearInterest( uint256 cumulatedLiquidityInterest = MathUtils.calculateLinearInterest(
currentLiquidityRate, currentLiquidityRate,
lastUpdateTimestamp lastUpdateTimestamp
); );
uint256 index = cumulatedLiquidityInterest.rayMul(liquidityIndex); newLiquidityIndex = cumulatedLiquidityInterest.rayMul(liquidityIndex);
require(index < (1 << 128), Errors.LIQUIDITY_INDEX_OVERFLOW); require(newLiquidityIndex < (1 << 128), Errors.LIQUIDITY_INDEX_OVERFLOW);
reserve.liquidityIndex = uint128(index); reserve.liquidityIndex = uint128(newLiquidityIndex);
//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
@ -352,13 +385,14 @@ library ReserveLogic {
reserve.currentVariableBorrowRate, reserve.currentVariableBorrowRate,
lastUpdateTimestamp lastUpdateTimestamp
); );
index = cumulatedVariableBorrowInterest.rayMul(variableBorrowIndex); newVariableBorrowIndex = cumulatedVariableBorrowInterest.rayMul(variableBorrowIndex);
require(index < (1 << 128), Errors.VARIABLE_BORROW_INDEX_OVERFLOW); require(newVariableBorrowIndex < (1 << 128), Errors.VARIABLE_BORROW_INDEX_OVERFLOW);
reserve.variableBorrowIndex = uint128(index); reserve.variableBorrowIndex = uint128(newVariableBorrowIndex);
} }
} }
//solium-disable-next-line //solium-disable-next-line
reserve.lastUpdateTimestamp = uint40(block.timestamp); reserve.lastUpdateTimestamp = uint40(block.timestamp);
return (newLiquidityIndex, newVariableBorrowIndex);
} }
} }

View File

@ -111,9 +111,9 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
) = _calculateBalanceIncrease(user); ) = _calculateBalanceIncrease(user);
//accrueing the interest accumulation to the stored total supply and caching it //accrueing the interest accumulation to the stored total supply and caching it
vars.currentSupply = _totalSupply = totalSupply(); vars.currentSupply = totalSupply();
vars.currentAvgStableRate = _avgStableRate; vars.currentAvgStableRate = _avgStableRate;
vars.nextSupply = vars.currentSupply.add(amount); vars.nextSupply = _totalSupply = vars.currentSupply.add(amount);
vars.amountInRay = amount.wadToRay(); vars.amountInRay = amount.wadToRay();
@ -163,25 +163,32 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
uint256 balanceIncrease uint256 balanceIncrease
) = _calculateBalanceIncrease(user); ) = _calculateBalanceIncrease(user);
uint256 supplyBeforeBurn = totalSupply().add(balanceIncrease);
uint256 supplyAfterBurn = supplyBeforeBurn.sub(amount);
if (supplyAfterBurn == 0) { uint256 currentSupply = totalSupply();
uint256 currentAvgStableRate = _avgStableRate;
if (currentSupply <= amount) {
_avgStableRate = 0; _avgStableRate = 0;
_totalSupply = 0;
} else { } else {
uint256 nextSupply = _totalSupply = currentSupply.sub(amount);
_avgStableRate = _avgStableRate _avgStableRate = _avgStableRate
.rayMul(supplyBeforeBurn.wadToRay()) .rayMul(currentSupply.wadToRay())
.sub(_usersData[user].rayMul(amount.wadToRay())) .sub(_usersData[user].rayMul(amount.wadToRay()))
.rayDiv(supplyAfterBurn.wadToRay()); .rayDiv(nextSupply.wadToRay());
} }
if (amount == currentBalance) { if (amount == currentBalance) {
_usersData[user] = 0; _usersData[user] = 0;
_timestamps[user] = 0; _timestamps[user] = 0;
} else { } else {
//solium-disable-next-line //solium-disable-next-line
_totalSupplyTimestamp = _timestamps[user] = uint40(block.timestamp); _timestamps[user] = uint40(block.timestamp);
} }
//solium-disable-next-line
_totalSupplyTimestamp = uint40(block.timestamp);
if (balanceIncrease > amount) { if (balanceIncrease > amount) {
_mint(user, balanceIncrease.sub(amount)); _mint(user, balanceIncrease.sub(amount));

View File

@ -296,8 +296,7 @@ export const calcExpectedReserveDataAfterBorrow = (
if (borrowRateMode == RateMode.Stable) { if (borrowRateMode == RateMode.Stable) {
expectedReserveData. //if the borrow rate mode
const debtAccrued = userStableDebt.minus(userDataBeforeAction.principalStableDebt);
expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued);