Revert Lend - Silvermist's results

A lending protocol specifically designed for liquidity providers on Uniswap v3.

General Information

Platform: Code4rena

Start Date: 04/03/2024

Pot Size: $88,500 USDC

Total HM: 31

Participants: 105

Period: 11 days

Judge: ronnyx2017

Total Solo HM: 7

Id: 342

League: ETH

Revert

Findings Distribution

Researcher Performance

Rank: 82/105

Findings: 2

Award: $25.11

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

Awards

18.5042 USDC - $18.50

Labels

bug
2 (Med Risk)
satisfactory
sufficient quality report
:robot:_49_group
duplicate-249

External Links

Lines of code

https://github.com/code-423n4/2024-03-revert-lend/blob/435b054f9ad2404173f36f0f74a5096c894b12b7/src/V3Vault.sol#L301-L309 https://github.com/code-423n4/2024-03-revert-lend/blob/435b054f9ad2404173f36f0f74a5096c894b12b7/src/V3Vault.sol#L312-L320 https://github.com/code-423n4/2024-03-revert-lend/blob/435b054f9ad2404173f36f0f74a5096c894b12b7/src/V3Vault.sol#L323-L326 https://github.com/code-423n4/2024-03-revert-lend/blob/435b054f9ad2404173f36f0f74a5096c894b12b7/src/V3Vault.sol#L329-L331

Vulnerability details

Impact

The V3Vault should be compliant with ERC4626 standart however maxDeposit, maxMint, maxWithdraw and maxRedeem are not fully up to EIP-4626's specification.

Proof of Concept

The EIP-4626 specifications states that maxDeposit and maxMint MUST factor in both global and user-specific limits.

Both maxDeposit and maxMint cover the case in which the value is more the globalLendLimit and return 0, but there is one case that is not covered.

Inside _deposit if the assets are more than the dailyLendIncreaseLimitLeft the transaction will revert. This should be taken into account in maxDeposit and maxMint and make them return 0 in that case.

 if (assets > dailyLendIncreaseLimitLeft) {
            revert DailyLendIncreaseLimit();
        } else {
            dailyLendIncreaseLimitLeft -= assets;
        }

Also, maxRedeem and maxWithdraw return the user's balance which is not correct. They MUST return the maximum amount of assets that could be transferred from owner through withdraw and not cause a revert

Inside _withdraw if the available is less than the assets the user wants to withdraw, the transaction will revert. In this case the user can only withdraw/redeem the available amount, not all of his amount as maxRedeem and maxRedeem return.

        (, uint256 available,) = _getAvailableBalance(newDebtExchangeRateX96, newLendExchangeRateX96);
        if (available < assets) {
            revert InsufficientLiquidity();
        }

Tools Used

Manual Review

Rewrite maxDeposit as shown below, same logic can be used for maxMint with minimal differences.

function maxDeposit(address) external view override returns (uint256) {
        (, uint256 lendExchangeRateX96) = _calculateGlobalInterest();
        uint256 value = _convertToAssets(totalSupply(), lendExchangeRateX96, Math.Rounding.Up);
        if (value >= globalLendLimit) {
            return 0;
        } else {
            if (globalLendLimit - value > dailyLendIncreaseLimitLeft) {
                return 0;
            } else {
                return globalLendLimit - value;
            }
        }
    }

Rewrite maxRedeem as shown below, same logic can be used for maxWithdraw with minimal differences.

    function maxRedeem(address owner) external view override returns (uint256) {
        (uint256 newDebtExchangeRateX96, uint256 newLendExchangeRateX96) = _updateGlobalInterest();
        (, uint256 available,) = _getAvailableBalance(newDebtExchangeRateX96, newLendExchangeRateX96);
        if (available < balanceOf(owner)) {
            return available;
        } else {
            return balanceOf(owner);
        }
    }

Assessed type

ERC4626

#0 - c4-pre-sort

2024-03-20T15:45:39Z

0xEVom marked the issue as duplicate of #347

#1 - c4-pre-sort

2024-03-20T15:45:42Z

0xEVom marked the issue as sufficient quality report

#2 - c4-pre-sort

2024-03-20T15:48:57Z

0xEVom marked the issue as duplicate of #249

#3 - c4-judge

2024-04-01T01:34:23Z

jhsagd76 marked the issue as satisfactory

Awards

6.6125 USDC - $6.61

Labels

bug
2 (Med Risk)
downgraded by judge
insufficient quality report
partial-50
:robot:_73_group
duplicate-175

External Links

Lines of code

https://github.com/code-423n4/2024-03-revert-lend/blob/435b054f9ad2404173f36f0f74a5096c894b12b7/src/transformers/AutoCompound.sol#L129 https://github.com/code-423n4/2024-03-revert-lend/blob/435b054f9ad2404173f36f0f74a5096c894b12b7/src/automators/Automator.sol#L148

Vulnerability details

Impact

In the Automator.sol the function _validateSwap uses UniswapV3.slot0 to get the value of sqrtPriceX96, however the sqrtPriceX96 gotten from Uniswap.slot0 is the most recent data point and can be manipulated easily via MEV bots & flashloans with sandwich attacks can cause lose of funds.

Proof of Concept

Automator.sol#_validateSwap

    function _validateSwap(
        bool swap0For1,
        uint256 amountIn,
        IUniswapV3Pool pool,
        uint32 twapPeriod,
        uint16 maxTickDifference,
        uint64 maxPriceDifferenceX64
    ) internal view returns (uint256 amountOutMin, int24 currentTick, uint160 sqrtPriceX96, uint256 priceX96) {
        // get current price and tick
        (sqrtPriceX96, currentTick,,,,,) = pool.slot0();


        // check if current tick not too far from TWAP
        if (!_hasMaxTWAPTickDifference(pool, twapPeriod, currentTick, maxTickDifference)) {
            revert TWAPCheckFailed();
        }


        // calculate min output price price and percentage
        priceX96 = FullMath.mulDiv(sqrtPriceX96, sqrtPriceX96, Q96);
        if (swap0For1) {
            amountOutMin = FullMath.mulDiv(amountIn * (Q64 - maxPriceDifferenceX64), priceX96, Q96 * Q64);
        } else {
            amountOutMin = FullMath.mulDiv(amountIn * (Q64 - maxPriceDifferenceX64), Q96, priceX96 * Q64);
        }
    }

Tools Used

Manual Review

Use TWAP to get the value of sqrtPriceX96

Assessed type

MEV

#0 - c4-pre-sort

2024-03-22T08:03:28Z

0xEVom marked the issue as duplicate of #191

#1 - c4-pre-sort

2024-03-22T08:03:31Z

0xEVom marked the issue as insufficient quality report

#2 - c4-judge

2024-03-31T14:28:16Z

jhsagd76 marked the issue as duplicate of #175

#3 - c4-judge

2024-03-31T14:44:48Z

jhsagd76 marked the issue as partial-50

#4 - c4-judge

2024-04-01T15:43:40Z

jhsagd76 changed the severity to 2 (Med Risk)

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter