LenderCommitmentGroup_Smart.sol#sharesExchangeRateInverse() may divide by zero
Summary
In LenderCommitmentGroup_Smart.sol#sharesExchangeRateInverse(), it divides sharesExchangeRate() which may be zero. This will block users from calling burnSharesToWithdrawEarnings() to burn shares.
Vulnerability Detail
getPoolTotalEstimatedValue() may return zero if tokenDifferenceFromLiquidations is too small due to liquidation. This will cause sharesExchangeRate() to return 0, and cause a divide by zero in sharesExchangeRateInverse(). This will cause users to not be able to call burnSharesToWithdrawEarnings().
Note that in this case, if the function doesn't revert, the withdrawn tokens may still be zero. However, this is still an issue, because:
This is a core function that reverts unexpectedly.
Users may use this function to simply burn shares, and doesn't care about withdrawn tokens.
function sharesExchangeRate() public view virtual returns (uint256 rate_) {
uint256 poolTotalEstimatedValue = getPoolTotalEstimatedValue();
if (poolSharesToken.totalSupply() == 0) {
return EXCHANGE_RATE_EXPANSION_FACTOR; // 1 to 1 for first swap
}
> rate_ =
> (poolTotalEstimatedValue *
> EXCHANGE_RATE_EXPANSION_FACTOR) /
> poolSharesToken.totalSupply();
}
function sharesExchangeRateInverse()
public
view
virtual
returns (uint256 rate_)
{
return
(EXCHANGE_RATE_EXPANSION_FACTOR * EXCHANGE_RATE_EXPANSION_FACTOR) /
> sharesExchangeRate();
}
function getPoolTotalEstimatedValue()
public
view
returns (uint256 poolTotalEstimatedValue_)
{
int256 poolTotalEstimatedValueSigned = int256(totalPrincipalTokensCommitted)
+ int256(totalInterestCollected) + int256(tokenDifferenceFromLiquidations)
- int256(totalPrincipalTokensWithdrawn);
//if the poolTotalEstimatedValue_ is less than 0, we treat it as 0.
poolTotalEstimatedValue_ = poolTotalEstimatedValueSigned > int256(0)
? uint256(poolTotalEstimatedValueSigned)
: 0;
}
pkqs90
medium
LenderCommitmentGroup_Smart.sol#sharesExchangeRateInverse()
may divide by zeroSummary
In
LenderCommitmentGroup_Smart.sol#sharesExchangeRateInverse()
, it dividessharesExchangeRate()
which may be zero. This will block users from callingburnSharesToWithdrawEarnings()
to burn shares.Vulnerability Detail
getPoolTotalEstimatedValue()
may return zero iftokenDifferenceFromLiquidations
is too small due to liquidation. This will causesharesExchangeRate()
to return 0, and cause a divide by zero insharesExchangeRateInverse()
. This will cause users to not be able to callburnSharesToWithdrawEarnings()
.Note that in this case, if the function doesn't revert, the withdrawn tokens may still be zero. However, this is still an issue, because:
Impact
Users can't to call
burnSharesToWithdrawEarnings()
, because it will revert on dividing by zero.Code Snippet
Tool used
Manual review
Recommendation
If
sharesExchangeRate()
is zero, simply also return 0 forsharesExchangeRateInverse()
.Duplicate of #64