code-423n4 / 2023-09-asymmetry-findings

2 stars 1 forks source link

Functions in the `VotiumStrategy` contract are susceptible to sandwich attacks #23

Open c4-submissions opened 1 year ago

c4-submissions commented 1 year ago

Lines of code

https://github.com/code-423n4/2023-09-asymmetry/blob/main/contracts/strategies/votium/VotiumStrategyCore.sol#L233-L240 https://github.com/code-423n4/2023-09-asymmetry/blob/main/contracts/strategies/votium/VotiumStrategyCore.sol#L258-L263

Vulnerability details

Bug Description

In VotiumStrategyCore.sol, the buyCvx() and sellCvx() functions call exchange_underlying() of Curve's ETH / CVX pool to buy and sell CVX respectively:

VotiumStrategyCore.sol#L233-L240

        ICrvEthPool(CVX_ETH_CRV_POOL_ADDRESS).exchange_underlying{
            value: _ethAmountIn
        }(
            0,
            1,
            _ethAmountIn,
            0 // this is handled at the afEth level
        );

VotiumStrategyCore.sol#L258-L263

        ICrvEthPool(CVX_ETH_CRV_POOL_ADDRESS).exchange_underlying(
            1,
            0,
            _cvxAmountIn,
            0 // this is handled at the afEth level
        );

As seen from above, exchange_underlying() is called with its _min_dy parameter as 0, which means the minimum amount of CVX or ETH to receive from the swap is effectively 0.

This isn't an issue when users interact with the AfEth contract, as its deposit() and withdraw() functions include a _minOut parameter which protects against slippage.

However, users that interact with the VotiumStrategy contract directly will not be protected from slippage when they call any of the following functions:

Should users call any of the functions listed above directly, they will be susceptible to sandwich attacks by attackers, which would reduce the amount of CVX or ETH received from the swap with curve's pool.

Impact

Due to a lack of slippage protection in buyCvx() and sellCvx(), users that interact with the VotiumStrategy contract will be susceptible to sandwich attacks. This results in a loss of funds for them as they will receive less CVX or ETH for the same amount of funds.

Proof of Concept

Consider the following scenario:

In this scenario, Alice has sandwiched Bob's deposit() transaction for a profit, causing Bob to receive less CVX for his deposited ETH.

Recommended Mitigation

Consider adding a _minOut parameter to either buyCvx() and sellCvx(), or the following functions:

This allows the caller to specify a minimum amount they expect from the swap, which would protect them from slippage.

Assessed type

MEV

elmutt commented 1 year ago

@toshiSat i think we should just lock this down so afEth can only use votium strategy

elmutt commented 1 year ago

https://github.com/asymmetryfinance/afeth/pull/169

c4-judge commented 1 year ago

0xleastwood marked the issue as duplicate of #39

c4-judge commented 1 year ago

0xleastwood marked the issue as satisfactory

0xleastwood commented 1 year ago

Marking this as primary issue and best report because it addresses all edge cases where slippage should be checked.

c4-judge commented 1 year ago

0xleastwood marked the issue as not a duplicate

c4-judge commented 1 year ago

0xleastwood marked the issue as selected for report

c4-judge commented 1 year ago

0xleastwood marked the issue as primary issue

c4-sponsor commented 1 year ago

elmutt (sponsor) confirmed

elmutt commented 1 year ago

@toshiSat @0xleastwood I think https://github.com/asymmetryfinance/afeth/pull/169 should partially solve this issue.

In order fully solve it and issues marked as duplicates( #24 #61 #15) we also need to pass _minout to afEth.applyRewards()

will update here when we have that PR

0xleastwood commented 1 year ago

Agree with you on this ^

elmutt commented 1 year ago

@toshiSat @0xleastwood I think asymmetryfinance/afeth#169 should partially solve this issue.

In order fully solve it and issues marked as duplicates( #24 #61 #15) we also need to pass _minout to afEth.applyRewards()

will update here when we have that PR

https://github.com/asymmetryfinance/afeth/pull/176 https://github.com/asymmetryfinance/afeth/pull/178