Organization
- @coinbase
Engagement Type
Cantina Reviews
Period
-
Repositories
Researchers
Findings
Informational
5 findings
0 fixed
5 acknowledged
Informational5 findings
Duplicate market installation across morpho protection variants
State
- Acknowledged
Severity
- Severity: Informational
Submitted by
slowfi
Description
The function
_onSingleExecutorInstallfrom contractMorphoWethLoanProtectionPolicyrelies on the inheritedactivePolicyByMarketmapping to enforce the single active policy constraint for a market. Because that mapping is stored per policy contract instance, the same(account, marketId)can still be installed inMorphoLoanProtectionPolicyandMorphoWethLoanProtectionPolicyat the same time for a WETH collateral market. As a result, the account can hold two independent one-shot top-up authorizations for the same Morpho position, and the effective maximum authorized top-up for that market exceeds the bound implied by a single active protection policy.Recommendation
Consider to enforce the
(account, marketId)uniqueness check in shared storage across both Morpho protection variants, or consider to make the ERC20 policy reject WETH collateral markets so only one protection contract can be active for a given Morpho market.Coinbase: Acknowledged. No code fixes. Will discuss with product teams to avoid duplicate WETH policies in offchain implementations.
Cantina Managed: Acknowledged by Coinbase team.
Deploy Function NatSpec Omits MAX_TRIGGER_LTV_RATIO environment variable
State
- Acknowledged
Severity
- Severity: Informational
Submitted by
slowfi
Description
The function
deployfrom contractDeployreads three environment variables at runtime:ADMIN,WETH, andMAX_TRIGGER_LTV_RATIO. The@devNatSpec comment on the function states that it reads onlyADMINandWETHfrom the environment, omitting any mention ofMAX_TRIGGER_LTV_RATIO. The documentation is therefore inconsistent with the implementation, which may lead operators or integrators to believe the function has fewer external dependencies than it actually does.Recommendation
Consider to update the
@devNatSpec ondeployto list all three environment variables it reads, and to note the valid range forMAX_TRIGGER_LTV_RATIO(greater than zero and strictly less than 1e18) so operators understand the accepted input bounds before running the script.Coinbase: Acknowledged. Will not fix as part of the audit.
Cantina Managed: Acknowledged by Coinbase team.
Redundant lowercase WETH view function duplicates public getter
State
- Acknowledged
Severity
- Severity: Informational
Submitted by
slowfi
Description
The function
wethfrom contractMorphoWethLoanProtectionPolicyis an external view function that returns the value of the public immutable state variableWETH. The Solidity compiler automatically generates an external getter for every public state variable using the variable's declared name. BecauseWETHis declared aspublic, the compiler already exposes an auto generated getter namedWETH(). The manually declaredweth()function is therefore a redundant alias that returns the same value through a separate selector without adding any behavior. The same pattern exists in the parent contract for themorpho()function and theMORPHOimmutable.Recommendation
Consider to remove the
wethview function and rely on the auto generatedWETH()getter, unless a lowercase alias is required for a specific interface compatibility reason, in which case the rationale should be documented in the NatSpec.Missing share slippage protection on morpho vault deposits
State
- Acknowledged
Severity
- Severity: Informational
Submitted by
slowfi
Description
The function
_onSingleExecutorExecutefrom contractMorphoLendPolicyauthorizes and executes deposits only in terms ofdepositAssets, without committing to or validating the amount of vault shares received. The execution path consumes the recurring allowance based on the asset amount and then builds a baredeposit(assets, account)call against the configured Morpho vault.Since the vault deposit operation returns minted shares but the policy does not use that return value or perform any post-execution share-balance verification, the account can deposit the full authorized asset amount while receiving materially fewer shares if the vault share price moves adversely before execution. This leaves the recurring allowance consumed even though the effective deposit terms have deteriorated.
Recommendation
Consider to extend the execution payload with a minimum acceptable shares bound and reject executions that would mint fewer shares than authorized. Consider to enforce that bound either through a pre-execution share preview or through a same-transaction post-execution share-balance delta check.
Coinbase: Acknowledged, will not address with onchain checks. Will discuss with offchain products which protect against using new vaults.
Cantina Managed: Acknowledged by Coinbase team.
A top up may not bring user's ltv below triggerLtv threshold
State
- Acknowledged
Severity
- Severity: Informational
Submitted by
Akshay Srivastav
Description
The
MorphoLoanProtectionPolicyis a one shot policy which means that it can only be executed once for an account.In
MorphoLoanProtectionPolicy._onPostExecutefunction thepostTopUpLtvis only being compared with liquidation ltv of morpho market which means that any top up which doesn't push the account's ltv abovelltvis valid and consumes the one shot top up opportunity of the account.Ideally it should be enforced that the top up is performed with optimal top up amount which puts the account's ltv in a safer range. One way to approach this is to compare the
postTopUpLtvwithLoanProtectionPolicyConfig.triggerLtv.... if (postTopUpLtv >= marketParams.lltv) revert();+ if (postTopUpLtv >= config.triggerLtv) revert();Coinbase: Acknowledged, will not address. We want to allow actions that prevent liquidation even if it doesn't make the loan particularly healthy.
Cantina Managed: Acknowledged by Coinbase team.