Platform: Code4rena
Start Date: 13/05/2022
Pot Size: $30,000 USDC
Total HM: 8
Participants: 65
Period: 3 days
Judge: hickuphh3
Total Solo HM: 1
Id: 125
League: ETH
Rank: 42/65
Findings: 2
Award: $59.83
π Selected for report: 0
π Solo Findings: 0
π Selected for report: pedroais
Also found by: 0x4non, 0x52, 0xf15ers, 0xliumin, CertoraInc, Dravee, GimelSec, IllIllI, MaratCerby, StErMi, TerrierLover, WatchPug, berndartmueller, cccz, dipp, fatherOfBlocks, hake, hickuphh3, hyh, isamjay, mtz, oyc_109, p4st13r4, peritoflores, rotcivegaf, saian, simon135, sorrynotsorry, sseefried, tabish, z3s
14.8433 USDC - $14.84
https://github.com/code-423n4/2022-05-sturdy/blob/main/smart-contracts/LidoVault.sol#L141-L142
It is possible that users cannot receive ETH if sending ETH to users is not successful because the require
check is unreachable.
_withdrawFromYieldPool function executes the following code if user requests ETH withdrawal.
if (_asset == address(0)) { // Case of ETH withdraw request from user, so exchange stETH -> ETH via curve uint256 receivedETHAmount = CurveswapAdapter.swapExactTokensForTokens( _addressesProvider, _addressesProvider.getAddress('STETH_ETH_POOL'), LIDO, ETH, _amount, 200 ); // send ETH to the user (bool sent, bytes memory data) = address(_to).call{value: receivedETHAmount}(''); return receivedETHAmount; require(sent, Errors.VT_COLLATERAL_WITHDRAW_INVALID); } else {
Since the require
check is an unreachable code, users cannot receive ETH if sending ETH to users is not successful.
static code analysis
Changing the order of execution like this can prevent this issue.
// send ETH to the user (bool sent, bytes memory data) = address(_to).call{value: receivedETHAmount}(''); require(sent, Errors.VT_COLLATERAL_WITHDRAW_INVALID); return receivedETHAmount;
#0 - sforman2000
2022-05-18T01:32:55Z
Duplicate of https://github.com/code-423n4/2022-05-sturdy-findings/issues/157 (high risk)
π Selected for report: IllIllI
Also found by: 0x1f8b, 0x4non, 0xNazgul, 0xf15ers, 0xkatana, 0xliumin, AlleyCat, BouSalman, Dravee, Funen, GimelSec, Hawkeye, MaratCerby, Picodes, StErMi, TerrierLover, WatchPug, Waze, berndartmueller, bobirichman, cryptphi, csanuragjain, defsec, delfin454000, dipp, fatherOfBlocks, hake, hickuphh3, hyh, joestakey, kebabsec, mics, mtz, oyc_109, p4st13r4, p_crypt0, robee, rotcivegaf, sikorico, simon135, sorrynotsorry, tintin
44.9929 USDC - $44.99
Here are QA reports per file.
addCollateralAsset function does not have any address(0) check.
https://github.com/code-423n4/2022-05-sturdy/blob/main/smart-contracts/CollateralAdapter.sol#L43-L46
function addCollateralAsset( address _externalAsset, address _internalAsset, address _acceptVault ) external onlyAdmin { _assetToVaults[_externalAsset] = _acceptVault; _collateralAssets[_externalAsset] = _internalAsset; }
addCollateralAsset function is callable only by admin, but setting proper address(0) checks would be useful.
https://github.com/code-423n4/2022-05-sturdy/blob/main/smart-contracts/LidoVault.sol#L18
LidoVault.sol does not override the withdrawOnLiquidation function. If not having this functionality on LidoVault is expected, LidoVault.sol can implement the withdrawOnLiquidation function which only has revert() or other appropriate logic to specify that LidoVault does not have this functionality.
#0 - HickupHH3
2022-06-06T07:48:31Z
both NC