Platform: Code4rena
Start Date: 26/07/2022
Pot Size: $75,000 USDC
Total HM: 29
Participants: 179
Period: 6 days
Judge: LSDan
Total Solo HM: 6
Id: 148
League: ETH
Rank: 66/179
Findings: 4
Award: $174.91
π Selected for report: 1
π Solo Findings: 0
π Selected for report: cloudjunky
Also found by: 0x1f8b, 0x4non, 0x52, 0xDjango, 0xHarry, 0xNazgul, 0xNineDec, 0xf15ers, 0xsanson, 0xsolstars, 8olidity, Bnke0x0, CertoraInc, Chom, Deivitto, Dravee, GalloDaSballo, GimelSec, IllIllI, Jmaxmanblue, JohnSmith, Jujic, Kenshin, Krow10, Lambda, MEP, Noah3o6, RedOneN, Ruhum, StErMi, StyxRave, TomJ, Treasure-Seeker, TrungOre, _Adam, __141345__, arcoun, asutorufos, bardamu, bearonbike, bin2chen, brgltd, bulej93, c3phas, cRat1st0s, carlitox477, cccz, codexploder, cryptonue, cryptphi, cthulhu_cult, dharma09, dipp, djxploit, durianSausage, ellahi, giovannidisiena, hansfriese, horsefacts, hyh, immeas, indijanc, jayjonah8, jayphbee, joestakey, kenzo, kyteg, ladboy233, minhquanym, navinavu, obront, oyc_109, peritoflores, rbserver, reassor, rokinot, rotcivegaf, saian, scaraven, shenwilly, simon135, sseefried, teddav, zzzitron
0.0037 USDC - $0.00
The payEther function is using transfer function for sending ETH instead of using call. The transfer function is bounded by 2300 gas units and if transaction exceeds this limit then transaction will revert which could cause disruption in fund transfer utility
function payEther(uint256 payAmt, address payAddress) internal { if (payAmt > 0) { // if royalty has to be paid payable(payAddress).transfer(payAmt); // royalty transfer to royaltyaddress } }
It is recommended to make use of call function instead of transfer
#0 - KenzoAgada
2022-08-03T14:06:03Z
Duplicate of #343
π Selected for report: codexploder
Also found by: 0x1f8b, 0xNineDec, 0xsanson, RustyRabbit, Treasure-Seeker, berndartmueller, chatch, teddav
135.2182 USDC - $135.22
If there is ever a hardfork for Golom then EIP712_DOMAIN_TYPEHASH value will become invalid. This is because the chainId parameter is computed in constructor. This means even after hard fork chainId would remain same which is incorrect and could cause possible replay attacks
constructor(address _governance) { // sets governance as owner _transferOwnership(_governance); uint256 chainId; assembly { chainId := chainid() } EIP712_DOMAIN_TYPEHASH = keccak256( abi.encode( keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'), keccak256(bytes('GOLOM.IO')), keccak256(bytes('1')), chainId, address(this) ) ); }
As we can see the chainId is derived and then hardcoded in EIP712_DOMAIN_TYPEHASH
This means even after hard fork, EIP712_DOMAIN_TYPEHASH value will remain same and point to incorrect chainId
The EIP712_DOMAIN_TYPEHASH variable should be recomputed everytime by placing current value of chainId
#0 - 0xsaruman
2022-09-03T15:03:22Z
#1 - dmvt
2022-10-12T14:32:47Z
I'm going to leave this as a medium risk. It would be a very high-impact scenario, but it relies on the external factor of a hard fork. That said, hard forks can and do happen.
π Selected for report: AuditsAreUS
Also found by: 0xSky, CertoraInc, GimelSec, GiveMeTestEther, Green, Lambda, Ruhum, RustyRabbit, Treasure-Seeker, Twpony, arcoun, bin2chen, cccz, codexploder, cryptonue, dipp, horsefacts, jayphbee, joestakey, minhquanym, obront, peritoflores, rbserver, reassor, rotcivegaf, scaraven, ych18
4.5163 USDC - $4.52
It was observed that if User has passed excess ETH while calling fillAsk function, then the excess ETH will not be refunded back to the user. This could cause loss of funds
require(msg.value >= o.totalAmt * amount + p.paymentAmt, 'mgmtm');
The function will only need to use o.totalAmt * amount + p.paymentAmt but even if more msg.value amount is passed then also it is accepted
Now in full function, there is no refund which is being made for the excess ETH
Refund excess ETH back to the User. Add below statement at function end which will refund the excess amount
payEther(msg.value - (o.totalAmt * amount + p.paymentAmt), msg.sender);
#0 - KenzoAgada
2022-08-04T02:56:06Z
Duplicate of #75
π Selected for report: IllIllI
Also found by: 0x1f8b, 0x4non, 0x52, 0xA5DF, 0xDjango, 0xLovesleep, 0xNazgul, 0xNineDec, 0xSmartContract, 0xackermann, 0xc0ffEE, 0xf15ers, 0xmatt, 0xsanson, 0xsolstars, 8olidity, AuditsAreUS, Bahurum, Bnke0x0, CRYP70, CertoraInc, Ch_301, Chom, CryptoMartian, Deivitto, DevABDee, Dravee, ElKu, Franfran, Funen, GalloDaSballo, GimelSec, GiveMeTestEther, Green, JC, Jmaxmanblue, JohnSmith, Jujic, Junnon, Kenshin, Krow10, Kumpa, Lambda, MEP, Maxime, MiloTruck, Mohandes, NoamYakov, Picodes, RedOneN, Rohan16, Rolezn, Ruhum, RustyRabbit, Sm4rty, Soosh, StErMi, StyxRave, Tadashi, TomJ, Treasure-Seeker, TrungOre, Waze, _Adam, __141345__, ajtra, ak1, apostle0x01, arcoun, asutorufos, async, benbaessler, berndartmueller, bin2chen, brgltd, c3phas, cRat1st0s, carlitox477, chatch, codetilda, codexploder, cryptonue, cryptphi, csanuragjain, cthulhu_cult, delfin454000, dipp, dirk_y, djxploit, ellahi, exd0tpy, fatherOfBlocks, giovannidisiena, hansfriese, horsefacts, hyh, idkwhatimdoing, indijanc, jayfromthe13th, jayphbee, joestakey, kenzo, kyteg, lucacez, luckypanda, mics, minhquanym, obront, oyc_109, pedr02b2, rajatbeladiya, rbserver, reassor, robee, rokinot, rotcivegaf, sach1r0, saian, saneryee, sashik_eth, scaraven, shenwilly, simon135, sseefried, supernova, teddav, ych18, zuhaibmohd, zzzitron
35.1687 USDC - $35.17
The contract is using a unrestricted receive function which means any fund sent to this contract will be stuck and cannot be refunded back to user
receive() external payable {}
Check if receive is actually required by this contract -
a. Is this contract actually expecting fund from outside sources b. If yes Is there a whitelisted source from where it should expect funds which could be hardcoded
#0 - 0xsaruman
2022-08-22T11:37:23Z
#1 - dmvt
2022-10-14T15:31:25Z
Lack of a recovery function is low risk. Downgrading to QA.