Omniscia Myso Finance Audit
CurveLPStakingCompartment Code Style Findings
CurveLPStakingCompartment Code Style Findings
CLP-01C: Inefficient Withdrawal Flow
Type | Severity | Location |
---|---|---|
Gas Optimization | CurveLPStakingCompartment.sol:L102-L113 |
Description:
The code of CurveLPStakingCompartment::withdrawCollFromGauge
will attempt to claim any pending rewards before withdrawing the desired withdrawAmount
which is inefficient as the Curve Finance system is meant to claim rewards automatically on withdrawals.
Example:
86function withdrawCollFromGauge(87 uint256 repayAmount,88 uint256 repayAmountLeft89) internal returns (address _rewardTokenAddr) {90 address _liqGaugeAddr = liqGaugeAddr;91
92 uint256 currentStakedBal = IERC20(_liqGaugeAddr).balanceOf(93 address(this)94 );95
96 // withdraw proportion of gauge amount97 uint256 withdrawAmount = (repayAmount * currentStakedBal) /98 repayAmountLeft;99
100 IStakingHelper(CRV_MINTER_ADDR).mint(_liqGaugeAddr);101
102 try IStakingHelper(_liqGaugeAddr).reward_tokens(0) returns (103 address rewardTokenAddr104 ) {105 if (rewardTokenAddr != address(0)) {106 _rewardTokenAddr = rewardTokenAddr;107 IStakingHelper(_liqGaugeAddr).claim_rewards();108 }109
110 IStakingHelper(_liqGaugeAddr).withdraw(withdrawAmount);111 } catch {112 IStakingHelper(_liqGaugeAddr).withdraw(withdrawAmount);113 }114}
Recommendation:
We advise the code to be updated, invoking IStakingHelper::withdraw(uint256,bool)
with the second argument true
to automatically withdraw rewards in liquidity gauges of V3, V4, and V5. In the catch
clause, the code should simply invoke IStakingHelper::withdraw(uint256)
as there either is no reward token (V1) or rewards are automatically claimed (V2).
In the try
code block, the IStakingHelper::reward_tokens
function can be safely invoked as the gauge is guaranteed to be of version 3 and up. To ensure the reward token is safely extracted in the catch
block, another try-catch
construct should be introduced that attempts to invoke IStakingHelper::reward_tokens
and set the _rewardTokenAddr
, performing no operation in its catch
block as that would indicate a version 1 liquidity gauge.
Alleviation (c740f7c6b5ebd365618fd2d7ea77370599e1ca11):
The Myso Finance team optimized their withdrawal flow by utilizing the specification we provided them with in the exhibit and using the IStakingHelper::reward_tokens
function as an indicator of a liquidity gauge's version rather than the IStakingHelper::withdraw(uint256, bool)
approach.
Given that the withdrawal flow has been optimized to the same extent we recommended, we consider this exhibit adequately addressed.
CLP-02C: Redundant Function Argument
Type | Severity | Location |
---|---|---|
Gas Optimization | CurveLPStakingCompartment.sol:L53 |
Description:
The IStakingHelper::deposit(uint256, address)
function call can be simplified to IStakingHelper::deposit(uint256)
as all Curve Finance liquidity gauge versions automatically assume that the deposit should be credited to the caller if no address
is explicitly specified.
Example:
53IStakingHelper(_liqGaugeAddr).deposit(amount, address(this));
Recommendation:
We advise the simplified call to be performed optimizing the CurveLPStakingCompartment::stake
function's gas cost.
Alleviation (c740f7c6b5ebd365618fd2d7ea77370599e1ca11):
The redundant address(this)
argument has been safely omitted from the IStakingHelper::deposit
call as advised.