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
Rank: 66/105
Findings: 2
Award: $61.28
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Limbooo
Also found by: 0xDemon, 0xspryon, 14si2o_Flint, Aymen0909, Silvermist, alix40, btk, crypticdefense, erosjohn, falconhoof, jnforja, shaka, wangxx2026, y0ng0p3
18.5042 USDC - $18.50
https://github.com/code-423n4/2024-03-revert-lend/blob/main/src/V3Vault.sol#L323 https://github.com/code-423n4/2024-03-revert-lend/blob/main/src/V3Vault.sol#L329
The V3Vault deviate from the EIP-4626 specification which may break external integrations.
As specified in EIP-4626, both maxDeposit and maxMint must account for deposit limits:
MUST return the maximum amount of assets deposit would allow to be deposited for receiver and not cause a revert, which MUST NOT be higher than the actual maximum that would be accepted (it should underestimate if necessary).
MUST return the maximum amount of shares mint would allow to be deposited to receiver and not cause a revert, which MUST NOT be higher than the actual maximum that would be accepted (it should underestimate if necessary).
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 { return globalLendLimit - value; } } function maxMint(address) external view override returns (uint256) { (, uint256 lendExchangeRateX96) = _calculateGlobalInterest(); uint256 value = _convertToAssets(totalSupply(), lendExchangeRateX96, Math.Rounding.Up); if (value >= globalLendLimit) { return 0; } else { return _convertToShares(globalLendLimit - value, lendExchangeRateX96, Math.Rounding.Down); } }
According to EIP-4626 maxWithdraw and maxRedeem must not return a higher amount than the actual maximum that would be accepted:
MUST return the maximum amount of assets that could be transferred from owner through withdraw and not cause a revert, which MUST NOT be higher than the actual maximum that would be accepted (it should underestimate if necessary).
MUST return the maximum amount of shares that could be transferred from owner through redeem and not cause a revert, which MUST NOT be higher than the actual maximum that would be accepted (it should underestimate if necessary).
function maxWithdraw(address owner) external view override returns (uint256) { (, uint256 lendExchangeRateX96) = _calculateGlobalInterest(); return _convertToAssets(balanceOf(owner), lendExchangeRateX96, Math.Rounding.Down); } /// @inheritdoc IERC4626 function maxRedeem(address owner) external view override returns (uint256) { return balanceOf(owner); }
Here is a simple coded PoC, paste in V3VaultIntegrationTest :
function testLogAvailable() public { _deposit(2000000, WHALE_ACCOUNT); _deposit(1000000, TEST_NFT_ACCOUNT_2); // gift some USDC so later he may repay all vm.prank(WHALE_ACCOUNT); USDC.transfer(TEST_NFT_ACCOUNT, 1000000); _createAndBorrow(TEST_NFT, TEST_NFT_ACCOUNT, 1000000); _createAndBorrow(TEST_NFT_2, TEST_NFT_ACCOUNT_2, 2000000); (,,, uint256 available,,,) = vault.vaultInfo(); assertEq(available, 0); assertEq(vault.maxWithdraw(WHALE_ACCOUNT), 2000000); }
Manual review
ERC4626
#0 - c4-pre-sort
2024-03-20T15:45:12Z
0xEVom marked the issue as duplicate of #347
#1 - c4-pre-sort
2024-03-20T15:45:17Z
0xEVom marked the issue as sufficient quality report
#2 - c4-pre-sort
2024-03-20T15:48:58Z
0xEVom marked the issue as duplicate of #249
#3 - c4-judge
2024-04-01T01:34:16Z
jhsagd76 marked the issue as satisfactory
🌟 Selected for report: Bauchibred
Also found by: 0x11singh99, 0x175, 0xAlix2, 0xDemon, 0xGreyWolf, 0xPhantom, 0xspryon, 14si2o_Flint, Arabadzhiev, Aymen0909, Bigsam, BowTiedOriole, CRYP70, DanielArmstrong, FastChecker, JecikPo, KupiaSec, MohammedRizwan, Norah, Timenov, Topmark, VAD37, adeolu, btk, crypticdefense, cryptphi, givn, grearlake, jnforja, kennedy1030, kfx, ktg, lanrebayode77, n1punp, santiellena, stonejiajia, t4sk, thank_you, tpiliposian, wangxx2026, y0ng0p3, zaevlad
42.7786 USDC - $42.78
https://github.com/code-423n4/2024-03-revert-lend/blob/main/src/V3Vault.sol#L360 https://github.com/code-423n4/2024-03-revert-lend/blob/main/src/V3Vault.sol#L366 https://github.com/code-423n4/2024-03-revert-lend/blob/main/src/V3Vault.sol#L372 https://github.com/code-423n4/2024-03-revert-lend/blob/main/src/V3Vault.sol#L378
The V3Vualt lacks a mechanism for lenders to express their minimum acceptable output. This deficiency exposes them to potential losses of their assets due to exchange rates fluctuations.
Users will loss assets due to the absence of slippage control.
Here are the main entry points for lenders, and they all have 0 slippage protection:
function deposit(uint256 assets, address receiver) external override returns (uint256) { (, uint256 shares) = _deposit(receiver, assets, false, ""); return shares; } /// @inheritdoc IERC4626 function mint(uint256 shares, address receiver) external override returns (uint256) { (uint256 assets,) = _deposit(receiver, shares, true, ""); return assets; } /// @inheritdoc IERC4626 function withdraw(uint256 assets, address receiver, address owner) external override returns (uint256) { (, uint256 shares) = _withdraw(receiver, owner, assets, false); return shares; } /// @inheritdoc IERC4626 function redeem(uint256 shares, address receiver, address owner) external override returns (uint256) { (uint256 assets,) = _withdraw(receiver, owner, shares, true); return assets; }
Manual review
Introduce a router for lenders since adding a min minOut input would not be "standard".
Other
#0 - c4-pre-sort
2024-03-18T18:37:00Z
0xEVom marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-03-18T18:37:37Z
0xEVom marked the issue as duplicate of #281
#2 - c4-judge
2024-03-31T03:21:19Z
jhsagd76 changed the severity to QA (Quality Assurance)
#3 - c4-judge
2024-04-03T00:30:45Z
This previously downgraded issue has been upgraded by jhsagd76
#4 - c4-judge
2024-04-03T00:32:13Z
jhsagd76 changed the severity to QA (Quality Assurance)