Platform: Code4rena
Start Date: 21/06/2022
Pot Size: $30,000 USDC
Total HM: 12
Participants: 96
Period: 3 days
Judge: HardlyDifficult
Total Solo HM: 5
Id: 140
League: ETH
Rank: 59/96
Findings: 2
Award: $45.50
π Selected for report: 0
π Solo Findings: 0
π Selected for report: IllIllI
Also found by: 0x1f8b, 0x29A, 0x52, 0xNazgul, 0xNineDec, 0xc0ffEE, 0xf15ers, 0xkatana, BowTiedWardens, Chom, ElKu, Funen, GalloDaSballo, JC, JMukesh, JohnSmith, Lambda, Limbooo, MadWookie, MiloTruck, Nethermind, Noah3o6, Nyamcil, Picodes, PwnedNoMore, Randyyy, RoiEvenHaim, SmartSek, StErMi, Tadashi, TerrierLover, TomJ, Tomio, Treasure-Seeker, UnusualTurtle, Varun_Verma, Wayne, Waze, _Adam, apostle0x01, asutorufos, berndartmueller, c3phas, catchup, cccz, cloudjunky, codexploder, cryptphi, defsec, delfin454000, dipp, ellahi, exd0tpy, fatherOfBlocks, hansfriese, hyh, joestakey, kebabsec, kenta, masterchief, minhquanym, naps62, oyc_109, pashov, peritoflores, reassor, rfa, robee, sach1r0, saian, sashik_eth, shenwilly, simon135, slywaters, sorrynotsorry, sseefried, unforgiven, xiaoming90, ych18, zuhaibmohd, zzzitron
28.2781 USDC - $28.28
https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVault.sol#L517 https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVault.sol#L526 https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/Basket.sol#L80 https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/Basket.sol#L87 https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/Basket.sol#L94
The use of the deprecated transfer function will likely cause failure in the future. The receiver has multiple ways in which to make the transfer fail.
contracts/NibblVault.sol#L517: IERC20(_asset).transfer(_to, IERC20(_asset).balanceOf(address(this))); contracts/NibblVault.sol#L526 IERC20(_assets[i]).transfer(_to, IERC20(_assets[i]).balanceOf(address(this))); contracts/Basket.sol#L80 _to.transfer(address(this).balance); contracts/Basket.sol#L87 IERC20(_token).transfer(msg.sender, IERC20(_token).balanceOf(address(this))); contracts/Basket.sol#L94 IERC20(_tokens[i]).transfer(msg.sender, IERC20(_tokens[i]).balanceOf(address(this)));
https://github.com/code-423n4/2021-04-meebits-findings/issues/2 https://github.com/code-423n4/2021-10-tally-findings/issues/20 https://github.com/code-423n4/2022-01-openleverage-findings/issues/75
Use call() instead of transfer().
#0 - mundhrakeshav
2022-06-26T07:00:43Z
Those are ERC20 contracts
#1 - HardlyDifficult
2022-07-04T00:59:42Z
Some of the examples were ERC20, which do not apply here. But an ETH transfer was included as well.
Agree that using .transfer is now discouraged. I think a difference here as compared to other contests is that the _to address is simply an input to this function call -- so if it reverts they could try again with a EOA and then transfer manually to the contract. Lowering risk and converting this into a QA report for the warden.
π Selected for report: IllIllI
Also found by: 0v3rf10w, 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, 0xf15ers, 0xkatana, 8olidity, ACai, BowTiedWardens, Chandr, Chom, ElKu, Fitraldys, Funen, IgnacioB, JC, Lambda, Limbooo, MiloTruck, Noah3o6, Nyamcil, Picodes, Randyyy, SmartSek, StErMi, TerrierLover, TomJ, Tomio, UnusualTurtle, Waze, _Adam, ajtra, c3phas, cRat1st0s, catchup, codexploder, cryptphi, defsec, delfin454000, ellahi, exd0tpy, fatherOfBlocks, hansfriese, joestakey, kebabsec, kenta, m_Rassska, minhquanym, oyc_109, pashov, reassor, rfa, robee, sach1r0, saian, sashik_eth, simon135, slywaters, ych18, ynnad, zuhaibmohd
17.224 USDC - $17.22
If a variable is not set/initialized, it is assumed to have the default value (0, false, 0x0 etc. depending on the data type). Explicitly initializing it wastes gas.
I would recommend leaving the initialized variables with the default values on the following lines:
nibbl-smartcontracts/contracts/Basket.sol:43: for (uint256 i = 0; i < _tokens.length; i++) { nibbl-smartcontracts/contracts/Basket.sol:70: for (uint256 i = 0; i < _tokens.length; i++) { nibbl-smartcontracts/contracts/Basket.sol:93: for (uint256 i = 0; i < _tokens.length; i++) { nibbl-smartcontracts/contracts/NibblVault.sol:506: for (uint256 i = 0; i < _assetAddresses.length; i++) { nibbl-smartcontracts/contracts/NibblVault.sol:525: for (uint256 i = 0; i < _assets.length; i++) { nibbl-smartcontracts/contracts/NibblVault.sol:547: for (uint256 i = 0; i < _assets.length; i++) {
Prefix Increments cost less gas than postfix increments ++i costs less gas compared to i++ or i += 1 for unsigned integers, as pre-increment is cheaper (about 5 gas per iteration). This statement is true even with the optimizer enabled.
I would changing the increment from postfix to prefix in the following lines:
nibbl-smartcontracts/contracts/Basket.sol:43: for (uint256 i = 0; i < _tokens.length; i++) { nibbl-smartcontracts/contracts/Basket.sol:70: for (uint256 i = 0; i < _tokens.length; i++) { nibbl-smartcontracts/contracts/Basket.sol:93: for (uint256 i = 0; i < _tokens.length; i++) { nibbl-smartcontracts/contracts/NibblVault.sol:506: for (uint256 i = 0; i < _assetAddresses.length; i++) { nibbl-smartcontracts/contracts/NibblVault.sol:525: for (uint256 i = 0; i < _assets.length; i++) { nibbl-smartcontracts/contracts/NibblVault.sol:547: for (uint256 i = 0; i < _assets.length; i++) {
Increments Can be Unchecked In Solidity 0.8+, thereβs a default overflow check on unsigned integers. Unchecking this saves gas each iteration but sacrifices code readability. Gas optimizing solutions can be found at https://github.com/ethereum/solidity/issues/10695
I would recommend that the following lines be unchecked to optimize gas costs
nibbl-smartcontracts/contracts/Basket.sol:43: for (uint256 i = 0; i < _tokens.length; i++) { nibbl-smartcontracts/contracts/Basket.sol:70: for (uint256 i = 0; i < _tokens.length; i++) { nibbl-smartcontracts/contracts/Basket.sol:93: for (uint256 i = 0; i < _tokens.length; i++) { nibbl-smartcontracts/contracts/NibblVault.sol:506: for (uint256 i = 0; i < _assetAddresses.length; i++) { nibbl-smartcontracts/contracts/NibblVault.sol:525: for (uint256 i = 0; i < _assets.length; i++) { nibbl-smartcontracts/contracts/NibblVault.sol:547: for (uint256 i = 0; i < _assets.length; i++) {
#0 - mundhrakeshav
2022-06-26T06:35:36Z
Duplicate #15