Updated optimization in aToken and debt tokens

This commit is contained in:
emilio 2020-08-11 12:26:15 +02:00
parent 9b0b190019
commit afc9612ac4
3 changed files with 116 additions and 77 deletions

View File

@ -223,9 +223,10 @@ contract AToken is VersionedInitializable, ERC20 {
require(_amount > 0, 'Amount to redeem needs to be > 0');
//cumulates the balance of the user
(, uint256 currentBalance, uint256 balanceIncrease, uint256 index) = cumulateBalanceInternal(
(, uint256 currentBalance, uint256 balanceIncrease) = calculateBalanceIncreaseInternal(
msg.sender
);
uint256 amountToRedeem = _amount;
//if amount is equal to uint(-1), the user wants to redeem everything
@ -247,13 +248,21 @@ contract AToken is VersionedInitializable, ERC20 {
amountToRedeem
);
// burns tokens equivalent to the amount requested
_burn(msg.sender, amountToRedeem);
if(balanceIncrease > amountToRedeem){
_mint(msg.sender, balanceIncrease.sub(amountToRedeem));
}
else{
_burn(msg.sender, amountToRedeem.sub(balanceIncrease));
}
uint256 userIndex = 0;
bool userIndexReset = false;
//reset the user data if the remaining balance is 0
if (currentBalance.sub(amountToRedeem) == 0) {
userIndexReset = resetDataOnZeroBalanceInternal(msg.sender);
resetDataOnZeroBalanceInternal(msg.sender);
} else {
//updates the user index
userIndex = userIndexes[msg.sender] = pool.getReserveNormalizedIncome(underlyingAssetAddress);
}
// executes redeem of the underlying asset
@ -264,28 +273,32 @@ contract AToken is VersionedInitializable, ERC20 {
currentBalance.sub(amountToRedeem)
);
emit Redeem(msg.sender, amountToRedeem, balanceIncrease, userIndexReset ? 0 : index);
emit Redeem(msg.sender, amountToRedeem, balanceIncrease, userIndex);
}
/**
* @dev mints token in the event of users depositing the underlying asset into the lending pool
* only lending pools can call this function
* @param _account the address receiving the minted tokens
* @param _user the address receiving the minted tokens
* @param _amount the amount of tokens to mint
*/
function mintOnDeposit(address _account, uint256 _amount) external onlyLendingPool {
function mintOnDeposit(address _user, uint256 _amount) external onlyLendingPool {
//cumulates the balance of the user
(, , uint256 balanceIncrease, uint256 index) = cumulateBalanceConditionalInternal(_account,false);
(, , uint256 balanceIncrease) = calculateBalanceIncreaseInternal(_user);
//updates the user index
uint256 index = userIndexes[_user] = pool.getReserveNormalizedIncome(underlyingAssetAddress);
//if the user is redirecting his interest towards someone else,
//we update the redirected balance of the redirection address by adding the accrued interest
//and the amount deposited
updateRedirectedBalanceOfRedirectionAddressInternal(_account, balanceIncrease.add(_amount), 0);
updateRedirectedBalanceOfRedirectionAddressInternal(_user, balanceIncrease.add(_amount), 0);
//mint an equivalent amount of tokens to cover the new deposit
_mint(_account, _amount.add(balanceIncrease));
_mint(_user, _amount.add(balanceIncrease));
emit MintOnDeposit(_account, _amount, balanceIncrease, index);
emit MintOnDeposit(_user, _amount, balanceIncrease, index);
}
/**
@ -437,13 +450,40 @@ contract AToken is VersionedInitializable, ERC20 {
return redirectedBalances[_user];
}
/**
* @dev calculates the increase in balance since the last user action
* @param _user the address of the user
* @return the last user principal balance, the current balance and the balance increase
**/
function calculateBalanceIncreaseInternal(address _user)
internal
returns (
uint256,
uint256,
uint256
)
{
uint256 currentBalance = balanceOf(_user);
uint256 balanceIncrease = 0;
uint256 previousBalance = 0;
if (currentBalance != 0) {
previousBalance = super.balanceOf(_user);
//calculate the accrued interest since the last accumulation
balanceIncrease = currentBalance.sub(previousBalance);
}
return (previousBalance, currentBalance, balanceIncrease);
}
/**
* @dev accumulates the accrued interest of the user to the principal balance
* @param _user the address of the user for which the interest is being accumulated
* @return the previous principal balance, the new principal balance, the balance increase
* and the new user index
**/
function cumulateBalanceConditionalInternal(address _user, bool _mintBalanceIncrease)
function cumulateBalanceInternal(address _user)
internal
returns (
uint256,
@ -452,36 +492,16 @@ contract AToken is VersionedInitializable, ERC20 {
uint256
)
{
uint256 currBalance = balanceOf(_user);
uint256 balanceIncrease = 0;
uint256 previousBalance = 0;
(uint256 previousBalance, uint256 currentBalance, uint256 balanceIncrease) = calculateBalanceIncreaseInternal(_user);
_mint(_user, balanceIncrease);
if (currBalance != 0) {
previousBalance = super.balanceOf(_user);
//calculate the accrued interest since the last accumulation
balanceIncrease = currBalance.sub(previousBalance);
//mints an amount of tokens equivalent to the amount accumulated
if(_mintBalanceIncrease) {
_mint(_user, balanceIncrease);
}
}
//updates the user index
uint256 index = userIndexes[_user] = pool.getReserveNormalizedIncome(underlyingAssetAddress);
return (previousBalance, currBalance, balanceIncrease, index);
}
function cumulateBalanceInternal(address _user)
internal
returns (
uint256,
uint256,
uint256,
uint256
)
{
return cumulateBalanceConditionalInternal(_user, true);
}
return (previousBalance, currentBalance, balanceIncrease, index);
}
/**
* @dev updates the redirected balance of the user. If the user is not redirecting his

View File

@ -67,9 +67,11 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
uint256 _balanceIncrease
);
constructor(address _pool, address _underlyingAsset) DebtTokenBase(_pool, _underlyingAsset) public {
constructor(address _pool, address _underlyingAsset)
public
DebtTokenBase(_pool, _underlyingAsset)
{}
}
/**
* @dev returns the average stable rate across all the stable rate debt
* @return the average stable rate
@ -114,7 +116,8 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
}
struct MintLocalVars {
uint256 newSupply;
uint256 supplyAfterMint;
uint256 supplyBeforeMint;
uint256 amountInRay;
uint256 newStableRate;
}
@ -134,11 +137,14 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
MintLocalVars memory vars;
//cumulates the user debt
(uint256 previousBalance, uint256 currentBalance, uint256 balanceIncrease) = _cumulateBalance(
_user
);
(
uint256 previousBalance,
uint256 currentBalance,
uint256 balanceIncrease
) = _calculateBalanceIncrease(_user);
vars.newSupply = totalSupply.add(_amount);
vars.supplyBeforeMint = totalSupply.add(balanceIncrease);
vars.supplyAfterMint = vars.supplyBeforeMint.add(_amount);
vars.amountInRay = _amount.wadToRay();
@ -156,11 +162,11 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
//calculates the updated average stable rate
avgStableRate = avgStableRate
.rayMul(totalSupply.wadToRay())
.rayMul(vars.supplyBeforeMint.wadToRay())
.add(_rate.rayMul(vars.amountInRay))
.rayDiv(vars.newSupply.wadToRay());
.rayDiv(vars.supplyAfterMint.wadToRay());
_mint(_user, _amount);
_mint(_user, _amount.add(balanceIncrease));
emit mintDebt(
_user,
@ -178,11 +184,16 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
* @param _amount the amount of debt tokens to mint
**/
function burn(address _user, uint256 _amount) public override onlyLendingPool {
(uint256 previousBalance, uint256 currentBalance, uint256 balanceIncrease) = _cumulateBalance(
_user
);
(
uint256 previousBalance,
uint256 currentBalance,
uint256 balanceIncrease
) = _calculateCumulatedBalance(_user);
uint256 newSupply = totalSupply.sub(_amount);
uint256 supplyBeforeBurn = totalSupply.add(balanceIncrease);
uint256 supplyAfterBurn = supplyBeforeBurn.sub(_amount);
uint256 newSupply = totalSupply.add(balanceIncrease).sub(_amount);
uint256 amountInRay = _amount.wadToRay();
@ -190,9 +201,9 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
avgStableRate = 0;
} else {
avgStableRate = avgStableRate
.rayMul(totalSupply.wadToRay())
.rayMul(supplyBeforeBurn.wadToRay())
.sub(usersData[_user].currentRate.rayMul(amountInRay))
.rayDiv(newSupply.wadToRay());
.rayDiv(supplyAfterBurn.wadToRay());
}
if (_amount == currentBalance) {
@ -200,17 +211,21 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
usersData[_user].lastUpdateTimestamp = 0;
}
_burn(_user, _amount);
if (balanceIncrease > _amount) {
_mint(_user, balanceIncrease.sub(_amount));
} else {
_burn(_user, _amount.sub(balanceIncrease));
}
emit burnDebt(_user, _amount, previousBalance, currentBalance, balanceIncrease);
}
/**
* @dev accumulates the accrued interest of the user to the principal balance
* @dev calculates the increase in balance since the last user action
* @param _user the address of the user for which the interest is being accumulated
* @return the previous principal balance, the new principal balance, the balance increase
**/
function _cumulateBalance(address _user)
function _calculateBalanceIncrease(address _user)
internal
returns (
uint256,
@ -226,8 +241,6 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
//calculate the accrued interest since the last accumulation
uint256 balanceIncrease = balanceOf(_user).sub(previousPrincipalBalance);
//mints an amount of tokens equivalent to the amount accumulated
_mint(_user, balanceIncrease);
return (
previousPrincipalBalance,

View File

@ -58,9 +58,10 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
uint256 _index
);
constructor(address _pool, address _underlyingAsset) DebtTokenBase(_pool, _underlyingAsset) public {
}
constructor(address _pool, address _underlyingAsset)
public
DebtTokenBase(_pool, _underlyingAsset)
{}
/**
* @dev calculates the accumulated debt balance of the user
@ -94,11 +95,13 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
* @param _amount the amount of debt being minted
**/
function mint(address _user, uint256 _amount) public override onlyLendingPool {
(uint256 previousBalance, uint256 currentBalance, uint256 balanceIncrease) = _cumulateBalance(
_user
);
(
uint256 previousBalance,
uint256 currentBalance,
uint256 balanceIncrease
) = _calculateCumulatedBalance(_user);
_mint(_user, _amount);
_mint(_user, _amount.add(balanceIncrease));
userIndexes[_user] = pool.getReserveNormalizedVariableDebt(underlyingAssetAddress);
@ -118,11 +121,17 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
* @param _amount the amount of debt being burned
**/
function burn(address _user, uint256 _amount) public override onlyLendingPool {
(uint256 previousBalance, uint256 currentBalance, uint256 balanceIncrease) = _cumulateBalance(
_user
);
(
uint256 previousBalance,
uint256 currentBalance,
uint256 balanceIncrease
) = _calculateBalanceIncrease(_user);
_burn(_user, _amount);
if (balanceIncrease > _amount) {
_mint(_user, balanceIncrease.sub(_amount));
} else {
_burn(_user, _amount.sub(balanceIncrease));
}
//if user repaid everything
if (currentBalance == _amount) {
@ -142,12 +151,12 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
}
/**
* @dev accumulates the accrued interest of the user to the principal balance
* @dev calculates the increase in balance since the last user interaction
* @param _user the address of the user for which the interest is being accumulated
* @return the previous principal balance, the new principal balance, the balance increase
* and the new user index
**/
function _cumulateBalance(address _user)
function _calculateBalanceIncrease(address _user)
internal
returns (
uint256,
@ -164,9 +173,6 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
//calculate the accrued interest since the last accumulation
uint256 balanceIncrease = balanceOf(_user).sub(previousPrincipalBalance);
//mints an _amount of tokens equivalent to the _amount accumulated
_mint(_user, balanceIncrease);
return (
previousPrincipalBalance,
previousPrincipalBalance.add(balanceIncrease),