For UniV3Vault, it seems that lp fees are collected through collectEarnings() callable by the strategy and reinvested (rebalanced).
However, in the current implementation, unharvested yields are not included in tvl(), making it vulnerable to front-run attacks that steal pending yields.
Handle
WatchPug
Vulnerability details
For
UniV3Vault
, it seems that lp fees are collected throughcollectEarnings()
callable by thestrategy
and reinvested (rebalanced).However, in the current implementation, unharvested yields are not included in
tvl()
, making it vulnerable to front-run attacks that steal pending yields.https://github.com/code-423n4/2021-12-mellow/blob/6679e2dd118b33481ee81ad013ece4ea723327b5/mellow-vaults/contracts/UniV3Vault.sol#L100-L122
https://github.com/code-423n4/2021-12-mellow/blob/6679e2dd118b33481ee81ad013ece4ea723327b5/mellow-vaults/contracts/UniV3Vault.sol#L80-L97
POC
Given:
tvl()
is10 ETH
and40,000 USDC
;1 ETH
and4,000 USDC
;strategy
callscollectEarnings()
to collect fees and reinvest;10 ETH
and40,000 USDC
, take 50% share of the pool;withdraw()
and retrieves10.5 ETH
and42,000 USDC
.As a result, the attacker has stolen half of the pending yields in about 1 block of time.
Recommendation
Consider including fees in
tvl()
.For the code to calculate fees earned, please reference
_computeFeesEarned()
in G-UNI project:https://github.com/gelatodigital/g-uni-v1-core/blob/master/contracts/GUniPool.sol#L762-L806