Omniscia Myso Finance Audit

CurveLPStakingCompartment Manual Review Findings

CurveLPStakingCompartment Manual Review Findings

CLP-01M: Inexistent Liquidity Gauge Reward Token Sanitization

TypeSeverityLocation
Logical FaultCurveLPStakingCompartment.sol:L39-L41

Description:

The CurveLPStakingCompartment::_collAccountingHelper workflow relies on the assumption that the reward token of a gauge is not equal to the collateral token as otherwise it will misbehave greatly, distributing the full token reward rather than a portion of it to the borrower on partial repayments.

Impact:

The current withdrawal mechanism will fail to function as expected if the reward token of the gauge is equal to the collateral token, a case that should be rare yet would result in potential value leak from the CurveLPStakingCompartment.

Example:

contracts/peer-to-peer/compartments/staking/CurveLPStakingCompartment.sol
127// check staked balance in gauge if gaugeAddr has been set
128// if not staked, then liqGaugeAddr = 0 and will not withdraw or have a reward address
129address _rewardTokenAddr = _liqGaugeAddr != address(0)
130 ? withdrawCollFromGauge(repayAmount, repayAmountLeft)
131 : address(0);
132
133// now check lp token balance of compartment which will be portion unstaked (could have never been staked)
134uint256 currentCompartmentBal = IERC20(collTokenAddr).balanceOf(
135 address(this)
136);
137
138// transfer proportion of compartment lp token balance if never staked or an unlock, else all balance if staked
139{
140 uint256 lpTokenAmount = isUnlock || _liqGaugeAddr != address(0)
141 ? currentCompartmentBal
142 : (repayAmount * currentCompartmentBal) / repayAmountLeft;

Recommendation:

We advise the code of CurveLPStakingCompartment::stake to ensure that the IStakingHelper::reward_tokens (if supported) do not contain the loan.collToke entry. Alternatively, we advise the CurveLPStakingCompartment::withdrawCollFromGauge function to yield an additional argument representing the withdrawAmount and thus supporting gauges with any type of token as CurveLPStakingCompartment::_collAccountingHelper would distribute the exact amount withdrawn rather than a dynamic evaluation based on the call's context.

Alleviation (c740f7c6b5ebd365618fd2d7ea77370599e1ca11):

The code of CurveLPStakingCompartment::_collAccountingHelper function was updated to disburse token rewards of a liquidity gauge solely when the reward token is not the collTokenAddr thus alleviating this exhibit's concerns utilizing an alternative approach than the one we advised.

CLP-02M: Potential Increase of Profitability

TypeSeverityLocation
Standard ConformityCurveLPStakingCompartment.sol:L30

Description:

The CurveLPStakingCompartment::stake function will permit only a loan's borrower to invoke its staking mechanism, thereby disallowing other authorized modules such as the callbackAddr of CurveLPStakingCompartment::transferCollFromCompartment to stake the underlying collateral to a gauge.

Impact:

Automatic strategies that wish to integrate with Myso Finance will be negatively impacted by the inability to stake a loan's collateral within a liquidity gauge thereby maximizing its potential value.

Example:

contracts/peer-to-peer/compartments/staking/CurveLPStakingCompartment.sol
26function stake(uint256 gaugeIndex) external {
27 DataTypesPeerToPeer.Loan memory loan = ILenderVaultImpl(vaultAddr).loan(
28 loanIdx
29 );
30 if (msg.sender != loan.borrower) {
31 revert Errors.InvalidSender();
32 }

Recommendation:

We advise the logic of CurveLPStakingCompartment::stake to allow staking to be performed by either a loan's borrower or an authorized party of the borrower. This can be achieved via multiple approaches, including ECDSA signatures, a typical approve workflow with approval stored on CurveLPStakingCompartment, adjustment of the DataTypesPeerToPeer.Loan structure to include authorized members, and more.

Alleviation (c740f7c6b5ebd365618fd2d7ea77370599e1ca11):

The Myso Finance team opted to apply the second approach we recommended, introducing an approvedStaker mapping to the CurveLPStakingCompartment that is set by the loan's borrower and is authorized to invoke the CurveLPStakingCompartment::stake function.

CLP-03M: Unrestricted Support of Token Reward Flow

TypeSeverityLocation
Logical FaultCurveLPStakingCompartment.sol:L105-L108

Description:

The CurveLPStakingCompartment::stake function does not sanitize the gauge being staked to as having a single reward token, thereby permitting a multi-token reward gauge to be staked and the rewards accumulated to be lost.

Impact:

Any value acquired from staking into a multi-token reward gauge will be permanently lost within the CurveLPStakingCompartment contract.

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 of CurveLPStakingCompartment to either prohibit multi-token reward gauges to be staked into within CurveLPStakingCompartment::stake, or the code of both the CurveLPStakingCompartment::withdrawCollFromGauge and CurveLPStakingCompartment::_collAccountingHelper functions to be updated introducing support for multi-token reward gauges.

Alleviation (c740f7c6b5ebd365618fd2d7ea77370599e1ca11):

The code of both CurveLPStakingCompartment::_collAccountingHelper and CurveLPStakingCompartment::_withdrawCollFromGauge have been significantly revamped to support all types of liquidity gauges and all potential reward tokens they may support.

As such, we consider this exhibit fully alleviated.