Closed c4-submissions closed 9 months ago
0xleastwood marked the issue as primary issue
This makes sense to implement.
0xleastwood marked the issue as selected for report
elmutt (sponsor) confirmed
The only time cvxUnlockObligations
is increased is in VotiumStrategy.requestWithdraw()
, but in the same function the tokens are also burned. This means that when the last supply is withdrawn (making cvxUnlockObligations == totalCvx
) the last supply is also burned, which makes totalSupply() == 0
so that the check if (supply == 0 || totalCvx == 0) return 1e18;
is entered after all. Thus the described scenario cannot happen.
Agreed, totalSupply()
would return zero and return 1e18
so this is not an issue.
0xleastwood marked the issue as unsatisfactory: Invalid
Lines of code
https://github.com/code-423n4/2023-09-asymmetry/blob/main/contracts/strategies/votium/VotiumStrategyCore.sol#L144-L149
Vulnerability details
Summary
The implementation of
cvxPerVotium()
contains an edge case that causes it to return an invalid zero value price.Impact
The
cvxPerVotium()
function present in the VotingStrategy contract is used to measure the number of held CVX tokens per vAfEth.https://github.com/code-423n4/2023-09-asymmetry/blob/main/contracts/strategies/votium/VotiumStrategyCore.sol#L144-L149
The implementation basically divides the number of deposited CVX tokens over the total supply of vAfEth, while carefully subtracting any balance that is pending to be withdrawn (
cvxUnlockObligations
).However, if all CVX tokens are currently pending withdrawal, then
cvxUnlockObligations == totalCvx
, causingcvxPerVotium()
to return zero. This case should be similar tototalCvx == 0
and should return1e18
instead of zero.The
cvxPerVotium()
function is used in several places throughout the codebase:VotingStrategy::deposit()
, to calculate the number of minted tokens.VotingStrategy::requestWithdraw()
, to calculate the amount of owed CVX tokens.VotingStrategy::price()
, to calculate the price in ETH of the vAfEth token.AfEth::price()
, to calculate the price in ETH of the AfEth token.AfEth::deposit()
, to calculate the number of minted tokens of new deposits.AfEth::depositRewards()
, to calculate the Votium strategy TVL.This means that under this scenario, all these other critical functions will be affected.
Recommendation
The implementation of
cvxPerVotium()
can be fixed by subtracting the CVX obligations before doing thetotalCvx == 0
comparison. The edge case is then removed, since nowtotalCvx
should be zero if all CVX is pending to be withdrawn.Assessed type
Other