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: 138/179
Findings: 2
Award: $35.17
🌟 Selected for report: 0
🚀 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 payable address transfer()
function forwards a limited amount of gas (2300) for the receiver. Since this is used in payEther()
which is used for all ETH payments, including fees for the exchange, it may lead to composability issues in the future. While the distributor fee, pre-payment and extra payment might be EOAs in most cases, the exchange address will most likely be a contract that may need more than 2300 gas.
Visual Studio Code
I'd recommend using call()
instead of transfer()
for better composability. When using call()
, make sure you consider re-entrancy attack vector. All paths to payEther()
are nonReentrant so it's currently safe to switch to call()
.
payEther()
can be modified to use call()
:
function payEther(uint256 payAmt, address payAddress) internal { if (payAmt > 0) { (bool sent,/*memory data*/) = payable(payAddress).call{value: payAmt}(""); require(sent); } }
#0 - KenzoAgada
2022-08-03T14:05:58Z
Duplicate of #343
🌟 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 code is well written with moderate test coverage. While the functionality seems polished, there's a feeling of a "work in progress" project. I'm mainly referring to missing or incomplete NatSpec, whith some copy-paste error, and missing tests for part of the functionality.
amount
to units
GolomTrader.sol L205
Consider renaming the variable to units
or something similar, as it refers to number of units of an ERC1155, current naming is somewhat confusing as you can easily misunderstand as amount of ETH or some amount in fungible tokens.
tokenAmt
to tokenUnits
GolomTrader.sol L56
Consider renaming the variable to tokenUnits
or something similar, as it refers to number of units of an ERC1155, current naming is somewhat confusing as you can easily misunderstand as amount of ETH or some amount in fungible tokens.
GolomTrader.sol L267
GolomTrader.sol L401
Consider emitting an event for extra payment in fillAsk()
and _settleBalances()
, as it seems like an important state change (ETH balance) and the receiving party may listen for the event. This extra sending of ETH is not covered in OrderFilled event, so another option is to instead include it in the OrderFilled event.
fillCriteriaBid()
GolomTrader.sol L328
Fix NatSpec for fillCriteriaBid()
: Mising parameters tokenId
and proof
GolomTrader.sol L444 Consider emitting an event on changing of distributor as it seems like an important state change which stakeholders might want to listen for.
GolomTrader
to avoid inadvertently locking up fundsGolomTrader.sol L459-L461 The contract is open to receive ETH, while I found no way of withdrawing or sending the extra ETH. Would advise to remove the receive and fallback functions so contract doesn't inadvertently lock up user funds.
RewardDistributor.sol L16 RewardDistributor.sol L26 RewardDistributor.sol L34 RewardDistributor.sol L36 Several interface functions are not used and can be removed to reduce contract size.
traderRewards()
should be updatedRewardDistributor.sol L252
Comment for traderRewards()
needs updating - only golom rewards for a single trader, param is address of trader
exchangeRewards()
should be updatedRewardDistributor.sol L267
Comment for exchangeRewards()
needs updating, rewards of an exchange, param is address of exchange
RewardDistributor
to avoid inadvertently locking up fundsRewardDistributor.sol L313-L315 The contract is open to receive ETH, while I found no way of withdrawing or sending the extra ETH. Would advise to remove the receive and fallback functions so contract doesn't inadvertently lock up user funds.
tokenId
to tokenCount
in VoteEscrowCore.sol
VoteEscrowCore.sol L323
Consider renaming state variable tokenId
in VoteEscrowCore.sol
to tokenCount
. This state variable is overshadowed in several functions in VoteEscrowDelegation.sol
, the comment and code logic also hint this would be a better name for the state variable.
VoteEscrowCore.sol L462 Duplicate code can be combined to reduce contract size. Example refactoring:
function _removeTokenFromOwnerList(address _from, uint256 _tokenId) internal { // Delete uint256 current_count = _balance(_from) - 1; uint256 current_index = tokenToOwnerIndex[_tokenId]; if (current_count != current_index) { uint256 lastTokenId = ownerToNFTokenIdList[_from][current_count]; // Add // update ownerToNFTokenIdList ownerToNFTokenIdList[_from][current_index] = lastTokenId; // update tokenToOwnerIndex tokenToOwnerIndex[lastTokenId] = current_index; } // Delete // update ownerToNFTokenIdList ownerToNFTokenIdList[_from][current_count] = 0; // update tokenToOwnerIndex tokenToOwnerIndex[_tokenId] = 0; }
IVoteEscrow
can be removedVoteEscrowDelegation.sol L12
IVoteEscrow
interface is not used and can be removed to reduce contract size.
VoteEscrowDelegation.sol L244 Consider useing the super._transferFrom() to avoid duplicating code. Example refactoring:
function _transferFrom( address _from, address _to, uint256 _tokenId, address _sender ) internal override { // remove the delegation this.removeDelegation(_tokenId); super._transferFrom(_from, _to, _tokenId, _sender); }