Platform: Code4rena
Start Date: 24/03/2023
Pot Size: $49,200 USDC
Total HM: 20
Participants: 246
Period: 6 days
Judge: Picodes
Total Solo HM: 1
Id: 226
League: ETH
Rank: 179/246
Findings: 1
Award: $13.13
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: brgltd
Also found by: 0x3b, 0xAgro, 0xGusMcCrae, 0xNorman, 0xRajkumar, 0xSmartContract, 0xTraub, 0xWagmi, 0xWaitress, 0xffchain, 0xhacksmithh, 0xkazim, 0xnev, 3dgeville, ArbitraryExecution, Aymen0909, BRONZEDISC, Bason, Bloqarl, BlueAlder, Brenzee, CodeFoxInc, CodingNameKiki, Cryptor, DadeKuma, DevABDee, Diana, Dug, Englave, Gde, Haipls, HollaDieWaldfee, Ignite, Infect3d, Jerry0x, Josiah, Kaysoft, Koko1912, KrisApostolov, Lavishq, LeoGold, Madalad, PNS, Rappie, RaymondFam, RedTiger, Rickard, Rolezn, Sathish9098, SunSec, T1MOH, UdarTeam, Udsen, Viktor_Cortess, Wander, adriro, ak1, alejandrocovrr, alexzoid, arialblack14, ayden, bin2chen, brevis, btk, c3phas, carlitox477, catellatech, ch0bu, chaduke, ck, climber2002, codeslide, descharre, dingo2077, ernestognw, fatherOfBlocks, favelanky, georgits, helios, hl_, inmarelibero, juancito, ks__xxxxx, lopotras, lukris02, m_Rassska, mahdirostami, maxper, nadin, navinavu, nemveer, p_crypt0, peanuts, pipoca, pixpi, qpzm, rbserver, reassor, roelio, rotcivegaf, scokaf, siddhpurakaran, slvDev, smaul, tnevler, tsvetanovv, turvy_fuzz, vagrant, wen, yac, zzzitron
13.1298 USDC - $13.13
On /contracts/SafEth/derivatives/WstEth.sol#L56 there are some refactors that can be applied to improve both code quality and security.
The current code is:
function withdraw(uint256 _amount) external onlyOwner { IWStETH(WST_ETH).unwrap(_amount); uint256 stEthBal = IERC20(STETH_TOKEN).balanceOf(address(this)); IERC20(STETH_TOKEN).approve(LIDO_CRV_POOL, stEthBal); uint256 minOut = (stEthBal * (10 ** 18 - maxSlippage)) / 10 ** 18; IStEthEthPool(LIDO_CRV_POOL).exchange(1, 0, stEthBal, minOut); // solhint-disable-next-line (bool sent, ) = address(msg.sender).call{value: address(this).balance}( "" ); require(sent, "Failed to send Ether"); }
Has some points that could be improved, the following refactored code shows it:
function withdraw(uint256 _amount) external onlyOwner { require(_amount > 0 && _amount <= address(this).balance, "Invalid amount"); IWStETH(WST_ETH).unwrap(_amount); uint256 stEthBal = IERC20(STETH_TOKEN).balanceOf(address(this)); IERC20(STETH_TOKEN).approve(LIDO_CRV_POOL, stEthBal); uint256 minOut = (stEthBal * (10 ** 18 - maxSlippage)) / 10 ** 18; IStEthEthPool(LIDO_CRV_POOL).exchange(1, 0, stEthBal, minOut); // solhint-disable-next-line payable(msg.sender).transfer(address(this).balance); }
1. Use require() for input validation: Currently, there is no validation on the _amount parameter. It would be better to use a require() statement to validate that the _amount parameter is greater than 0 and less than the balance of the contract. 2. Use transfer() instead of call(): The current code uses call() to send Ether to the owner of the contract. However, transfer() is a more secure and gas-efficient way to transfer Ether.
#0 - c4-sponsor
2023-04-10T18:31:38Z
elmutt marked the issue as sponsor confirmed
#1 - c4-judge
2023-04-24T19:05:32Z
Picodes marked the issue as grade-b