Closed c4-submissions closed 9 months ago
0xleastwood marked the issue as duplicate of #39
@0xleastwood I dont think this is a dupe of 39
its talking about different functions
@0xleastwood I dont think this is a dupe of 39
its talking about different functions
The vulnerable function is buyCvx()
, regardless of what path it is being called from, they still seem to be equivalent issues.
They are describing slightly different issues that can be solved in different ways.
In my opinion its kindof dangerous to just assume they will be solved by the same PR -- we have a PR ready on #39 but that PR is not sufficient to solve this issue.
I dont think our PR for #39 would fix this as the mitigations steps are different
They are describing slightly different issues that can be solved in different ways.
In my opinion its kindof dangerous to just assume they will be solved by the same PR -- we have a PR ready on #39 but that PR is not sufficient to solve this issue.
I dont think our PR for #39 would fix this as the mitigations steps are different
Can I get access to the repo so I can look at these PRs?
They are describing slightly different issues that can be solved in different ways. In my opinion its kindof dangerous to just assume they will be solved by the same PR -- we have a PR ready on #39 but that PR is not sufficient to solve this issue. I dont think our PR for #39 would fix this as the mitigations steps are different
Can I get access to the repo so I can look at these PRs?
let me double check really quick. now im second guessing my answer
They are describing slightly different issues that can be solved in different ways. In my opinion its kindof dangerous to just assume they will be solved by the same PR -- we have a PR ready on #39 but that PR is not sufficient to solve this issue. I dont think our PR for #39 would fix this as the mitigations steps are different
Can I get access to the repo so I can look at these PRs?
let me double check really quick. now im second guessing my answer
Ok. after reviewing PR's I still think they are different. I will see about getting you access
On second thoughts, I agree this is addressing the same issue but in a different area of the code.
0xleastwood marked the issue as not a duplicate
0xleastwood marked the issue as selected for report
0xleastwood marked the issue as primary issue
0xleastwood marked the issue as duplicate of #23
0xleastwood marked the issue as not selected for report
0xleastwood marked the issue as partial-25
Only giving 25% credit because it misses 2/3 edge cases where this should be applied.
Duplicate issue by same warden as it's primary issue. depositRewards()
was already covered in #23.
0xleastwood marked the issue as full credit
0xleastwood marked the issue as satisfactory
Lines of code
https://github.com/code-423n4/2023-09-asymmetry/blob/main/contracts/AfEth.sol#L272-L293
Vulnerability details
Bug Description
In
VotiumStrategyCore.sol
, thebuyCvx()
function callsexchange_underlying()
of Curve's ETH / CVX pool to buy CVX:VotiumStrategyCore.sol#L233-L240
As seen from above,
exchange_underlying()
is called with its_min_dy
parameter as 0, which means the minimum amount of CVX that the swap must return is effectively 0.buyCvx()
is used byVotiumStrategyCore
'sdepositRewards()
function to swap ETH gained from rewards to CVX:VotiumStrategyCore.sol#L203-L204
This is called by the
depositRewards()
function in theAfEth
contract:AfEth.sol#L291
However, the
depositRewards()
function inAfEth.sol
, unlikedeposit()
andwithdraw()
, does not have a_minOut
parameter or any other form of slippage protection. This leaves it susceptible to sandwich attacks.Impact
As the
depositRewards()
function inAfEth.sol
does not have any form of slippage protection, attackers can sandwich calls todepositRewards()
to extract value from itsbuyCvx()
call, resulting in a loss of rewards for the protocol.Note that
depositRewards()
is automatically called whenever the rewarder of theVotiumStrategy
contract callsapplyRewards()
.Proof of Concept
Consider the following scenario:
applyRewards()
to distribute rewards to users. This callsdepositRewards()
inAfEth.sol
to deposit ETH and exchange it to CVX.depositRewards()
in theVotiumStrategy
contract with a portion of the deposited ETH.buyCvx()
attempts to swap the deposited ETH for CVX.buyCvx()
only returns a small amount of CVX when called.In this scenario, Alice has sandwiched the call to
depositRewards()
to effectively steal a portion of rewards from the protocol.Recommended Mitigation
Consider adding some form of slippage protection to
depositRewards()
inAfEth.sol
. One way of achieving this would be to do the following:cxvAmount
whendepositRewards()
inVotiumStrategyCore
is called:VotiumStrategyCore.sol#L203-L208
_minOut
parameter indepositRewards()
, which is the minimum amount of CVX that should be returned by the swap:AfEth.sol#L272-L293
Assessed type
MEV