Omniscia Myso Finance Audit

GLPStakingCompartment Manual Review Findings

GLPStakingCompartment Manual Review Findings

GLP-01M: Incorrect Reward Receiver

TypeSeverityLocation
Logical FaultGLPStakingCompartment.sol:L43

Description:

The GLPStakingCompartment::transferCollFromCompartment function will claim any pending WETH fees from the fGLP token and transfer the correct proportion to the borrowerAddr. This behaviour is contradictory to BaseCompartment::_transferCollFromCompartment as the latter will transfer the collateral to either the callbackAddr or the borrowerAddr with priority on the former if it is defined.

Impact:

Callback modules of the Myso Finance protocol will assume that they will be claiming their collateral as well as any associated rewards (i.e. in the case of AaveStakingCompartment), however, this is not the case for the GLPStakingCompartment which can cause those callback implementations to fail execution or misbehave in their strategy. We should note that this seems to be desirable behaviour based on the documentation of CurveLPStakingCompartment, however, we would urge Myso Finance to revisit this approach.

Example:

contracts/peer-to-peer/compartments/staking/GLPStakingCompartment.sol
19// transfer coll on repays
20function transferCollFromCompartment(
21 uint256 repayAmount,
22 uint256 repayAmountLeft,
23 address borrowerAddr,
24 address collTokenAddr,
25 address callbackAddr
26) external {
27 _transferCollFromCompartment(
28 repayAmount,
29 repayAmountLeft,
30 borrowerAddr,
31 collTokenAddr,
32 callbackAddr
33 );
34
35 IStakingHelper(FEE_GLP).claim(address(this));
36
37 // check weth token balance
38 uint256 currentWethBal = IERC20(WETH).balanceOf(address(this));
39
40 // transfer proportion of weth token balance
41 uint256 wethTokenAmount = (repayAmount * currentWethBal) /
42 repayAmountLeft;
43 IERC20(WETH).safeTransfer(borrowerAddr, wethTokenAmount);
44}

Recommendation:

We advise this behaviour to be mimicked by GLPStakingCompartment as the callbackAddr may want to liquidate the assets or perform other actions with the reward tokens claimed via the fGLP interface.

Alleviation (c740f7c6b5ebd365618fd2d7ea77370599e1ca11):

The Myso Finance team has specified that they considered whether reward disbursement should be performed to the callback address and that they have knowingly opted to not support this type of flow.

As a result, we consider this exhibit nullified given that it represents desirable behaviour by the Myso Finance team.

GLP-02M: Inexistent Opportunistic Claim

TypeSeverityLocation
External Call ValidationGLPStakingCompartment.sol:L35, L50

Description:

The fGLP token that is meant to be integrated with by the GLPStakingCompartment contains logic within fGLP::claim that can cause it to revert, rendering the GLPStakingCompartment completely inoperable.

Impact:

While the likelihood of the GLP governance module voting on private claim operations is low, it would still affect the Myso Finance in a significantly adverse way. As such, we consider this exhibit of "minor" severity.

Example:

contracts/peer-to-peer/compartments/staking/GLPStakingCompartment.sol
19// transfer coll on repays
20function transferCollFromCompartment(
21 uint256 repayAmount,
22 uint256 repayAmountLeft,
23 address borrowerAddr,
24 address collTokenAddr,
25 address callbackAddr
26) external {
27 _transferCollFromCompartment(
28 repayAmount,
29 repayAmountLeft,
30 borrowerAddr,
31 collTokenAddr,
32 callbackAddr
33 );
34
35 IStakingHelper(FEE_GLP).claim(address(this));
36
37 // check weth token balance
38 uint256 currentWethBal = IERC20(WETH).balanceOf(address(this));
39
40 // transfer proportion of weth token balance
41 uint256 wethTokenAmount = (repayAmount * currentWethBal) /
42 repayAmountLeft;
43 IERC20(WETH).safeTransfer(borrowerAddr, wethTokenAmount);
44}
45
46// unlockColl this would be called on defaults
47function unlockCollToVault(address collTokenAddr) external {
48 _unlockCollToVault(collTokenAddr);
49
50 IStakingHelper(FEE_GLP).claim(address(this));
51
52 // get weth token balance
53 uint256 currentWethBal = IERC20(WETH).balanceOf(address(this));
54 // transfer all weth to vault
55 IERC20(WETH).safeTransfer(vaultAddr, currentWethBal);
56}

Recommendation:

We advise the fGLP::claim function to be invoked opportunistically in a try-catch block, utilizing the existing WETH balance present in the contract to distribute its proportion and ensuring that both GLPStakingCompartment::transferCollFromCompartment and GLPStakingCompartment::unlockCollToVault can be invoked under all circumstances.

Alleviation (c740f7c6b5ebd365618fd2d7ea77370599e1ca11):

Both referenced IStakingHelper::claim operations have been wrapped in try-catch constructs, ensuring that a claim will be attempted but is not mandated to succeed and thus ensuring transfers and unlocks can occur regardless of the GLP protocol's state.