Jovial Teal Butterfly
Medium
Apart from initialization, the state variable lastFeeClaimTime
can be only be updated via function claimFees()
.
The poolReserves
variable in Pool.sol::simulateCreate
function is calculated as -
poolReserves = poolReserves - (poolReserves * fee * (block.timestamp - lastFeeClaimTime)) / (PRECISION * SECONDS_PER_YEAR);
the poolReserves
value can be 0, if 2 subtraction parts are equal i.e.
poolReserves = (poolReserves * fee * (block.timestamp - lastFeeClaimTime)) / (PRECISION * SECONDS_PER_YEAR)
after simplification it's -
block.timestamp = (PRECISION * SECONDS_PER_YEAR)/ fee + lastFeeClaimTime
Consider the situation feeBenficiary
haven't called the claimFee
function for a long time, which means lastFeeClaimTime
havn't been updated for a long time.
If that's the case then there will be a situation -
block.timestamp >= (PRECISION * SECONDS_PER_YEAR)/ fee + lastFeeClaimTime
.
And if this situation arises, simulateCreate
function will always revert as poolReserves
will be 0 or tends to less than 0.
The simulateCreate
further calls getCreateAmount
function, passing poolReserves
-
return getCreateAmount(
tokenType,
depositAmount,
bondSupply,
levSupply,
@-> poolReserves,
getOraclePrice(reserveToken, USD),
getOracleDecimals(reserveToken, USD)
).normalizeAmount(COMMON_DECIMALS, assetDecimals);
If poolReserves
is 0 getCreateAmount
will revert. because -
tvl
will be 0.collateralLevel
will be 0.- If
collateralLevel
is 0, then code inside(collateralLevel <= COLLATERAL_THRESHOLD)
will execute. - means
creationRate
is 0, as -creationRate = (tvl * multiplier) / assetSupply;
- If
creationRate
is 0, function will revert due to, division by 0 -
return ((depositAmount * ethPrice * PRECISION) / creationRate).toBaseUnit(oracleDecimals);
function getCreateAmount(
TokenType tokenType,
uint256 depositAmount,
uint256 bondSupply,
uint256 levSupply,
uint256 poolReserves,
uint256 ethPrice,
uint8 oracleDecimals) public pure returns(uint256) {
if (bondSupply == 0) {
revert ZeroDebtSupply();
}
uint256 assetSupply = bondSupply;
uint256 multiplier = POINT_EIGHT;
if (tokenType == TokenType.LEVERAGE) {
multiplier = POINT_TWO;
assetSupply = levSupply;
}
@-> uint256 tvl = (ethPrice * poolReserves).toBaseUnit(oracleDecimals);
@-> uint256 collateralLevel = (tvl * PRECISION) / (bondSupply * BOND_TARGET_PRICE);
uint256 creationRate = BOND_TARGET_PRICE * PRECISION; // PRECISION = 1000000;
if (collateralLevel <= COLLATERAL_THRESHOLD) {
if (tokenType == TokenType.LEVERAGE && assetSupply == 0) {
revert ZeroLeverageSupply();
}
@-> creationRate = (tvl * multiplier) / assetSupply;
} else if (tokenType == TokenType.LEVERAGE) {
if (assetSupply == 0) {
revert ZeroLeverageSupply();
}
uint256 adjustedValue = tvl - (BOND_TARGET_PRICE * bondSupply);
creationRate = (adjustedValue * PRECISION) / assetSupply;
}
@-> return ((depositAmount * ethPrice * PRECISION) / creationRate).toBaseUnit(oracleDecimals);
}
The conclusion is create
will revert due to DOS, if the above situation arises.
calling claimFee()
function after long time, or only single point of updation for lastFeeClaimTime
No response
No response
if situation arises as same in summary section.
DOS, user will not be able to create ethBOND and levETH. it means supply of wstETH to pool can be affected.
No response
Create a check to ensure that claimFee
function is updated regularly.