Platform: Code4rena
Start Date: 14/06/2022
Pot Size: $50,000 USDC
Total HM: 19
Participants: 99
Period: 5 days
Judge: HardlyDifficult
Total Solo HM: 4
Id: 136
League: ETH
Rank: 37/99
Findings: 4
Award: $175.59
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: hyh
Also found by: 0x29A, 0xNineDec, 0xf15ers, 0xkowloon, GreyArt, IllIllI, KIntern, Kenshin, Lambda, WatchPug, Wayne, berndartmueller, byterocket, cccz, codexploder, horsefacts, kenzo, obront, obtarian, oyc_109, peritoflores, rajatbeladiya, rfa, saian, unforgiven, zer0dot
11.084 USDC - $11.08
https://github.com/code-423n4/2022-06-infinity/blob/main/contracts/staking/InfinityStaker.sol#L345 https://github.com/code-423n4/2022-06-infinity/blob/main/contracts/core/InfinityExchange.sol#L1229
The rescueETH function is implemented incorrectly and will always fail This is sending msg.value to the destination contract instead of address(this).balance
Same need to be fixed at InfinityExchange.sol#L1229
function rescueETH(address destination) external payable onlyOwner { (bool sent, ) = destination.call{value: msg.value}(''); require(sent, 'failed'); }
Change the rescueETH function like below:
function rescueETH(address destination) external payable onlyOwner { (bool sent, ) = destination.call{value: address(this).balance}(''); require(sent, 'Failed to send Ether'); }
#0 - nneverlander
2022-06-22T11:17:13Z
Duplicate
#1 - nneverlander
2022-07-05T11:41:31Z
#2 - HardlyDifficult
2022-07-09T16:45:48Z
🌟 Selected for report: horsefacts
Also found by: 0x29A, GimelSec, GreyArt, Lambda, Ruhum, antonttc, berndartmueller, byterocket, cccz, codexploder, dipp, oyc_109, unforgiven
84.0967 USDC - $84.10
https://github.com/code-423n4/2022-06-infinity/blob/main/contracts/core/InfinityExchange.sol#L336 https://github.com/code-423n4/2022-06-infinity/blob/main/contracts/core/InfinityExchange.sol#L300
Any extra ETH passed while calling takeOrders function will not be returned by the contract causing user to loose funds
function takeOrders(OrderTypes.MakerOrder[] calldata makerOrders, OrderTypes.OrderItem[][] calldata takerNfts) external payable nonReentrant { ....... uint256 execPrice = _getCurrentPrice(makerOrders[i]); totalPrice += execPrice; _takeOrders(makerOrders[i], takerNfts[i], execPrice); unchecked { ++i; } } // check to ensure that for ETH orders, enough ETH is sent // for non ETH orders, IERC20 safeTransferFrom will throw error if insufficient amount is sent if (isMakerSeller && currency == address(0)) { require(msg.value >= totalPrice, 'invalid total price'); } }
Notice the total cost for this order is calculated as totalPrice
So if user has passed a msg.value > = totalPrice, this is executed successfully
But what about the extra ETH msg.value - totalPrice, which is simply kept by contract and not refunded back to the user
Also need to be fixed for takeMultipleOneOrders function
Return the excess funds of msg.value - totalPrice back to user
#0 - KenzoAgada
2022-06-21T12:20:14Z
Duplicate of #244
#1 - nneverlander
2022-06-22T10:12:29Z
Duplicate
#2 - HardlyDifficult
2022-07-10T12:38:13Z
When a user sends more ETH than is required for an order, the surplus is taken as exchange fees instead of being refunded.
Dupe of https://github.com/code-423n4/2022-06-infinity-findings/issues/244
🌟 Selected for report: joestakey
Also found by: 0x1f8b, 0x29A, 0x52, 0xDjango, 0xNazgul, 0xNineDec, 0xf15ers, 0xkowloon, 0xmint, 8olidity, BowTiedWardens, Chom, Cityscape, Czar102, ElKu, FSchmoede, Funen, GimelSec, GreyArt, IllIllI, KIntern, Kaiziron, Kenshin, Lambda, MadWookie, MiloTruck, PPrieditis, Picodes, Ruhum, Sm4rty, StErMi, TerrierLover, TomJ, Treasure-Seeker, VAD37, WatchPug, Wayne, _Adam, a12jmx, abhinavmir, antonttc, apostle0x01, asutorufos, berndartmueller, cccz, cloudjunky, codexploder, cryptphi, csanuragjain, defsec, delfin454000, fatherOfBlocks, georgypetrov, hake, hansfriese, horsefacts, hyh, k, kenta, nxrblsrpr, oyc_109, peritoflores, rajatbeladiya, reassor, rfa, robee, sach1r0, saian, samruna, shenwilly, simon135, sorrynotsorry, sseefried, throttle, unforgiven, wagmi, zzzitron
48.9784 USDC - $48.98
Contract: https://github.com/code-423n4/2022-06-infinity/blob/main/contracts/staking/InfinityStaker.sol#L375
Issue: In updateInfinityTreasury function it is not verified that _infinityTreasury is not address(0) else rageQuit balance penality will be lost
Recommendation: Add a check to see _infinityTreasury is not address(0)
require(_infinityTreasury!=address(0), "Incorrect address");
Contract: https://github.com/code-423n4/2022-06-infinity/blob/main/contracts/core/InfinityExchange.sol#L1023
Issue: In _transferNFTsAndFees function, it is not checked whether recipient is a contract. If receiver is an EOA not supporting ERC777/ERC1155 , NFT can be lost forever
Recommendation: Check whether recipient is a valid contract by chekcing for extcodesize>0
Contract: https://github.com/code-423n4/2022-06-infinity/blob/main/contracts/token/TimelockConfig.sol#L88
Issue: In getConfigByIndex, it is not verified if provided index is valid. Same fix is required for getPendingByIndex function as well
Recommendation: Add a check to see that provided index is valid.
require(index>=0 && index<getConfigCount(), "Invalid index");
#0 - nneverlander
2022-06-23T11:26:01Z
Thanks
#1 - HardlyDifficult
2022-07-12T05:12:36Z
🌟 Selected for report: IllIllI
Also found by: 0v3rf10w, 0x1f8b, 0x29A, 0xAsm0d3us, 0xDjango, 0xKitsune, 0xNazgul, 0xf15ers, 0xkatana, 0xkowloon, BowTiedWardens, Chom, ElKu, FSchmoede, Funen, GimelSec, Kaiziron, Kenshin, Lambda, MadWookie, MiloTruck, PPrieditis, Picodes, PwnedNoMore, StErMi, Tadashi, TerrierLover, TomJ, Tomio, Wayne, Waze, _Adam, antonttc, apostle0x01, asutorufos, c3phas, codexploder, defsec, delfin454000, fatherOfBlocks, hake, hansfriese, hyh, joestakey, k, kenta, oyc_109, peritoflores, reassor, rfa, robee, sach1r0, simon135, slywaters, zer0dot
31.4283 USDC - $31.43
Contract: https://github.com/code-423n4/2022-06-infinity/blob/main/contracts/staking/InfinityStaker.sol#L310
Issue: In _updateUserStakedAmounts function, amount can never be greater than vestedTwelveMonths otherwise user is trying to unstake amount higher than deposit which is not possible due to require check in unstake
Recommendation: Change the implementation like below:
OLD
if (amount > vestedTwelveMonths) { userstakedAmounts[user][Duration.TWELVE_MONTHS].amount = 0; userstakedAmounts[user][Duration.TWELVE_MONTHS].timestamp = 0; } else { userstakedAmounts[user][Duration.TWELVE_MONTHS].amount -= amount; }
New
if (amount > 0) { userstakedAmounts[user][Duration.TWELVE_MONTHS].amount -= amount; }
Contract: https://github.com/code-423n4/2022-06-infinity/blob/main/contracts/staking/InfinityStaker.sol#L260
Issue: Short circuit if user staked amount =0 in getVestedAmount function
Recommendation: Add below check in getVestedAmount function
require(amount!=0, "Insufficient amount");
Contract: https://github.com/code-423n4/2022-06-infinity/blob/main/contracts/core/InfinityExchange.sol#L178
Issue: In matchOneToManyOrders function, No need to check complications.contains(makerOrder.execParams[0]) at InfinityExchange.sol#L184, isUserOrderNonceExecutedOrCancelled at InfinityExchange.sol#L216 as this is already done in isOrderValid call at InfinityExchange.sol#L190 and _matchOneMakerSellToManyMakerBuys call at InfinityExchange.sol#L203
Recommendation: Remove extra complications check and isUserOrderNonceExecutedOrCancelled assignation
Contract: https://github.com/code-423n4/2022-06-infinity/blob/main/contracts/staking/InfinityStaker.sol#L168
Issue: In getUserTotalVested function, For noVesting there is no need to call getVestedAmount as this will always be userstakedAmounts[user][Duration.NONE].amount
Recommendation: Directly assign userstakedAmounts[user][Duration.NONE].amount instead of calling getVestedAmount function for noVesting condition
#0 - nneverlander
2022-06-23T11:26:59Z
Thanks