Omniscia Myso Finance Audit

CurveLPStakingCompartment Code Style Findings

CurveLPStakingCompartment Code Style Findings

CLP-01C: Inefficient Withdrawal Flow

TypeSeverityLocation
Gas OptimizationCurveLPStakingCompartment.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:

contracts/peer-to-peer/compartments/staking/CurveLPStakingCompartment.sol
86function withdrawCollFromGauge(
87 uint256 repayAmount,
88 uint256 repayAmountLeft
89) 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 amount
97 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 rewardTokenAddr
104 ) {
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

TypeSeverityLocation
Gas OptimizationCurveLPStakingCompartment.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:

contracts/peer-to-peer/compartments/staking/CurveLPStakingCompartment.sol
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.