Platform: Code4rena
Start Date: 23/05/2022
Pot Size: $50,000 USDC
Total HM: 44
Participants: 99
Period: 5 days
Judge: hickuphh3
Total Solo HM: 11
Id: 129
League: ETH
Rank: 86/99
Findings: 3
Award: $39.20
🌟 Selected for report: 0
🚀 Solo Findings: 0
8.2687 USDC - $8.27
Judge has assessed an item in Issue #408 as Medium risk. The relevant finding follows:
#0 - HickupHH3
2022-06-27T16:04:31Z
[L02] Instead of call(), transfer() is used to withdraw ETH: To withdraw ETH, it uses transfer(), this transaction will fail inevitably when:
The withdrawer smart contract does not implement a payable function. Withdrawer smart contract does implement a payable fallback which uses more than 2300 gas unit. The withdrawer smart contract implements a payable fallback function that needs less than 2300 gas units but is called through proxy, raising the call’s gas usage above 2300.
dup of #82
🌟 Selected for report: berndartmueller
Also found by: 0x1f8b, 0xDjango, 0xsomeone, ACai, Bahurum, BouSalman, CertoraInc, Deivitto, Dravee, GimelSec, IllIllI, JMukesh, Kaiziron, PP1004, Ruhum, SmartSek, VAD37, WatchPug, _Adam, aez121, antonttc, blockdev, broccolirob, camden, cccz, cryptphi, defsec, dipp, ellahi, fatherOfBlocks, gzeon, horsefacts, ilan, jayjonah8, joestakey, kenta, kenzo, minhquanym, oyc_109, pauliax, pedroais, peritoflores, sashik_eth, shenwilly, simon135, throttle, xiaoming90, z3s
0.1022 USDC - $0.10
https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconMarket.sol#L361
function cancel(uint256 id) public virtual can_cancel(id) synchronized returns (bool success) { OfferInfo memory _offer = offers[id]; delete offers[id]; require(_offer.pay_gem.transfer(_offer.owner, _offer.pay_amt)); // @audit non-standard compliant tokens like USDT emit LogItemUpdate(id); emit LogKill( bytes32(id), keccak256(abi.encodePacked(_offer.pay_gem, _offer.buy_gem)), _offer.owner, _offer.pay_gem, _offer.buy_gem, uint128(_offer.pay_amt), uint128(_offer.buy_amt), uint64(block.timestamp) ); success = true; }
if _offer.pay_gem === <USDT_ADDRESS>
this function will revert because transfer
of usdt does not return anything. and ERC20.transfer
want a boolean
. so the cancel
will never happen if _offer.pay_gem === <USDT_ADDRESS>
.
Use OpenZeppelin’s SafeERC20 safeTransfer/safeTransferFrom
instead of transfer/transferFrom
that handles the return value check as well as non-standard-compliant tokens.
#0 - bghughes
2022-06-04T01:17:29Z
Duplicate of #316
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0x4non, 0xDjango, 0xNazgul, 0xf15ers, 0xkatana, Chom, DavidGialdi, Dravee, ElKu, FSchmoede, Fitraldys, Funen, GimelSec, JC, Kaiziron, MaratCerby, Metatron, MiloTruck, Picodes, Randyyy, RoiEvenHaim, SmartSek, Tomio, UnusualTurtle, WatchPug, Waze, _Adam, antonttc, asutorufos, berndartmueller, blackscale, blockdev, c3phas, catchup, csanuragjain, defsec, delfin454000, ellahi, fatherOfBlocks, gzeon, hansfriese, ilan, joestakey, minhquanym, oyc_109, pauliax, pedroais, reassor, rfa, rotcivegaf, sach1r0, samruna, sashik_eth, simon135, z3s
30.8316 USDC - $30.83
uint256
default value is 0
so we can remove = 0
:RubiconMarket.sol 990,25: uint256 old_top = 0; RubiconRouter.sol 82,25: uint256 lastBid = 0; 83,25: uint256 lastAsk = 0; 85,28: for (uint256 index = 0; index < topNOrders; index++) { 168,31: uint256 currentAmount = 0; 169,24: for (uint256 i = 0; i < route.length - 1; i++) { 226,31: uint256 currentAmount = 0; 227,24: for (uint256 i = 0; i < route.length - 1; i++) { rubiconPools/BathToken.sol 635,32: for (uint256 index = 0; index < bonusTokens.length; index++) {
++i
use less gas than i++
:++i
costs less gas compared to i++
. about 5 gas per iteration.
RubiconRouter.sol 169,51: for (uint256 i = 0; i < route.length - 1; i++) { 227,51: for (uint256 i = 0; i < route.length - 1; i++) {