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: 110/179
Findings: 2
Award: $56.49
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 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
//Links to githubfile
// function removeDelegationByOwner(uint256 delegatedTokenId, uint256 ownerTokenId) external {
There are many function which are not compatible to run in version less than pragma solidity 0.8.12 ., So try to use updated version of solidity
//Links to githubfile
https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/governance/GolomToken.sol#L2 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#L2 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/rewards/RewardDistributor.sol#L2 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#L3 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#L2 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/TokenUriHelper.sol#L3
contracts/governance/GolomToken.sol:2: pragma solidity ^0.8.11; contracts/vote-escrow/VoteEscrowDelegation.sol:2: pragma solidity 0.8.11; contracts/rewards/RewardDistributor.sol:2: pragma solidity 0.8.11; contracts/core/GolomTrader.sol:3: pragma solidity 0.8.11; contracts/vote-escrow/VoteEscrowCore.sol:2: pragma solidity 0.8.11; contracts/vote-escrow/TokenUriHelper.sol:3: pragma solidity 0.8.11;
Recommend using fixed solidity version
// Links to githubfile https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/governance/GolomToken.sol#L2
// actual codes contracts/governance/GolomToken.sol:2: pragma solidity ^0.8.11;
Use safeTransfer/safeTransferFrom consistently instead of transfer/transferFrom It is good to add a require() statement that checks the return value of token transfers or to use something like OpenZeppelin’s safeTransfer/safeTransferFrom unless one is sure the given token reverts in case of a failure. Failure to do so will cause silent failures of transfers and affect token accounting in contract.
// Links to githubfile https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#L861 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#L1023 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#L154 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#L236 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#L301 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#L361 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#L382
contracts/vote-escrow/VoteEscrowCore.sol:861: assert(IERC20(token).transferFrom(from, address(this), _value)); contracts/vote-escrow/VoteEscrowCore.sol:1023: assert(IERC20(token).transfer(msg.sender, value)); contracts/core/GolomTrader.sol:154: payable(payAddress).transfer(payAmt); // royalty transfer to royaltyaddress contracts/core/GolomTrader.sol:236: ERC721(o.collection).transferFrom(o.signer, receiver, o.tokenId); contracts/core/GolomTrader.sol:301: nftcontract.transferFrom(msg.sender, o.signer, o.tokenId); contracts/core/GolomTrader.sol:361: nftcontract.transferFrom(msg.sender, o.signer, tokenId); contracts/core/GolomTrader.sol:382: WETH.transferFrom(o.signer, address(this), o.totalAmt * amount);
Consider using safeTransfer/safeTransferFrom or require() consistently.
// Links to githubfile https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#L37 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#L44 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#L52 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#L950
//actual codes used in contracts contracts/governance/GolomToken.sol:37: _mint(_account, _amount); contracts/governance/GolomToken.sol:44: _mint(_airdrop, 150_000_000 * 1e18); contracts/governance/GolomToken.sol:52: _mint(_rewardDistributor, 62_500_000 * 1e18); contracts/vote-escrow/VoteEscrowCore.sol:950: _mint(_to, _tokenId);
If the intention is for the Ether to be used, the function should call another function, otherwise it should revert.
contracts/core/GolomTrader.sol:461: contracts/rewards/RewardDistributor.sol:315:
contracts/core/GolomTrader.sol:461: receive() external payable {} contracts/rewards/RewardDistributor.sol:315: receive() external payable {}
🌟 Selected for report: JohnSmith
Also found by: 0x1f8b, 0xA5DF, 0xDjango, 0xKitsune, 0xLovesleep, 0xNazgul, 0xSmartContract, 0xmatt, 0xsam, Aymen0909, Bnke0x0, CRYP70, Chandr, Chinmay, CodingNameKiki, Deivitto, Dravee, ElKu, Fitraldys, Funen, GalloDaSballo, Green, IllIllI, JC, Jmaxmanblue, Junnon, Kaiziron, Kenshin, Krow10, Maxime, Migue, MiloTruck, Noah3o6, NoamYakov, Randyyy, RedOneN, ReyAdmirado, Rohan16, Rolezn, Ruhum, Sm4rty, StyxRave, TomJ, Tomio, _Adam, __141345__, ajtra, ak1, apostle0x01, asutorufos, async, benbaessler, brgltd, c3phas, cRat1st0s, carlitox477, delfin454000, djxploit, durianSausage, ellahi, erictee, fatherOfBlocks, gerdusx, gogo, hyh, jayfromthe13th, jayphbee, joestakey, kaden, kenzo, kyteg, ladboy233, lucacez, m_Rassska, mics, minhquanym, oyc_109, pfapostol, rbserver, reassor, rfa, robee, rokinot, sach1r0, saian, samruna, sashik_eth, simon135, supernova, tofunmi, zuhaibmohd
21.3211 USDC - $21.32
//Links to githubfile https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#L927 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#L928 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#L944 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#L982 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#L997
//actual codes which shows the use. contracts/vote-escrow/VoteEscrowCore.sol:927: require(_value > 0); // dev: need non-zero value contracts/vote-escrow/VoteEscrowCore.sol:928: require(_locked.amount > 0, 'No existing lock found'); contracts/vote-escrow/VoteEscrowCore.sol:944: require(_value > 0); // dev: need non-zero value contracts/vote-escrow/VoteEscrowCore.sol:982: require(_locked.amount > 0, 'No existing lock found'); contracts/vote-escrow/VoteEscrowCore.sol:997: require(_locked.amount > 0, 'Nothing is locked');
The overheads outlined below are PER LOOP, excluding the first loop storage arrays incur a Gwarmaccess (100 gas) memory arrays use MLOAD (3 gas) calldata arrays use CALLDATALOAD (3 gas). Caching the length changes each of these to a DUP<N> (3 gas), and gets rid of the extra DUP<N> needed to store the stack offset
//Links to githubfile
https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#L171 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#L189 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#L199 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#L415
//actual codes which shows the use. contracts/vote-escrow/VoteEscrowDelegation.sol:171: for (uint256 index = 0; index < delegated.length; index++) contracts/vote-escrow/VoteEscrowDelegation.sol:189: for (uint256 index = 0; index < delegatednft.length; index++) contracts/vote-escrow/VoteEscrowDelegation.sol:199: for (uint256 i; i < _array.length; i++) contracts/core/GolomTrader.sol:415: for (uint256 i = 0; i < proof.length; i++) contracts/rewards/RewardDistributor.sol:143: for (uint256 index = 0; index < epochs.length; index++) { contracts/rewards/RewardDistributor.sol:157: for (uint256 index = 0; index < epochs.length; index++) { contracts/rewards/RewardDistributor.sol:180: for (uint256 tindex = 0; tindex < tokenids.length; tindex++) { contracts/rewards/RewardDistributor.sol:183: for (uint256 index = 0; index < epochs.length; index++) {
// Links to githubfile https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/TokenUriHelper.sol#138
//actual code which show the use contracts/vote-escrow/TokenUriHelper.sol:138: digits++;
Custom errors are available from solidity version 0.8.4. The instances below match or exceed that version
// Links to githubfile
GolomToken https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/governance/GolomToken.sol#24 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/governance/GolomToken.sol#43 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/governance/GolomToken.sol#51 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/governance/GolomToken.sol#69
VoteEscrowDelegation https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#72 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#73 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#99 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#130 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#186 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#211 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#220 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#239
VoteEscrowCore https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#538 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#928 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#929 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#945 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#946 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#982 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#983 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#996 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#997 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#998 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#999 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#1008 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#1011 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#1082 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#1227
GolomTrader https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#177 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#217 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#222 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#226 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#227 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#235 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#299 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#359 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#455
//actual code which shows the use GolomToken contracts/governance/GolomToken.sol:24: require(msg.sender == minter, 'GolomToken: only reward distributor can enable'); contracts/governance/GolomToken.sol:43: require(!isAirdropMinted, 'already minted'); contracts/governance/GolomToken.sol:51: require(!isGenesisRewardMinted, 'already minted'); contracts/governance/GolomToken.sol:69: require(minterEnableDate <= block.timestamp, 'GolomToken: wait for timelock') VoteEscrowDelegation contracts/vote-escrow/VoteEscrowDelegation.sol:72: require(ownerOf(tokenId) == msg.sender, 'VEDelegation: Not allowed'); contracts/vote-escrow/VoteEscrowDelegation.sol:73: require(this.balanceOfNFT(tokenId) >= MIN_VOTING_POWER_REQUIRED, 'VEDelegation: Need more voting power'); contracts/vote-escrow/VoteEscrowDelegation.sol:99: require(_delegatedTokenIds.length < 500, 'VVDelegation: Cannot stake more'); contracts/vote-escrow/VoteEscrowDelegation.sol:130: require(blockNumber < block.number, 'VEDelegation: not yet determined'); contracts/vote-escrow/VoteEscrowDelegation.sol:186: require(blockNumber < block.number, 'VEDelegation: not yet determined'); contracts/vote-escrow/VoteEscrowDelegation.sol:211: require(ownerOf(tokenId) == msg.sender, 'VEDelegation: Not allowed'); contracts/vote-escrow/VoteEscrowDelegation.sol:220: // require(ownerOf(ownerTokenId) == msg.sender, 'VEDelegation: Not allowed'); contracts/vote-escrow/VoteEscrowDelegation.sol:239: require(attachments[_tokenId] == 0 && !voted[_tokenId], 'attached'); VoteEscrowCore contracts/vote-escrow/VoteEscrowCore.sol:538: require(attachments[_tokenId] == 0 && !voted[_tokenId], 'attached'); contracts/vote-escrow/VoteEscrowCore.sol:928: require(_locked.amount > 0, 'No existing lock found'); contracts/vote-escrow/VoteEscrowCore.sol:929: require(_locked.end > block.timestamp, 'Cannot add to expired lock. Withdraw'); contracts/vote-escrow/VoteEscrowCore.sol:945: require(unlock_time > block.timestamp, 'Can only lock until time in the future'); contracts/vote-escrow/VoteEscrowCore.sol:946: require(unlock_time <= block.timestamp + MAXTIME, 'Voting lock can be 4 years max'); contracts/vote-escrow/VoteEscrowCore.sol:982: require(_locked.amount > 0, 'No existing lock found'); contracts/vote-escrow/VoteEscrowCore.sol:983: require(_locked.end > block.timestamp, 'Cannot add to expired lock. Withdraw'); contracts/vote-escrow/VoteEscrowCore.sol:996: require(_locked.end > block.timestamp, 'Lock expired'); contracts/vote-escrow/VoteEscrowCore.sol:997: require(_locked.amount > 0, 'Nothing is locked'); contracts/vote-escrow/VoteEscrowCore.sol:998: require(unlock_time > _locked.end, 'Can only increase lock duration'); contracts/vote-escrow/VoteEscrowCore.sol:999: require(unlock_time <= block.timestamp + MAXTIME, 'Voting lock can be 4 years max'); contracts/vote-escrow/VoteEscrowCore.sol:1008: require(attachments[_tokenId] == 0 && !voted[_tokenId], 'attached'); contracts/vote-escrow/VoteEscrowCore.sol:1011: require(block.timestamp >= _locked.end, "The lock didn't expire"); contracts/vote-escrow/VoteEscrowCore.sol:1082: require(idToOwner[_tokenId] != address(0), 'Query for nonexistent token'); contracts/vote-escrow/VoteEscrowCore.sol:1227: require(_isApprovedOrOwner(msg.sender, _tokenId), 'caller is not owner nor approved'); GolomTrader contracts/core/GolomTrader.sol:177: require(signaturesigner == o.signer, 'invalid signature'); contracts/core/GolomTrader.sol:217: require(msg.value >= o.totalAmt * amount + p.paymentAmt, 'mgmtm'); contracts/core/GolomTrader.sol:222: require(o.orderType == 0, 'invalid orderType'); contracts/core/GolomTrader.sol:226: require(status == 3, 'order not valid'); contracts/core/GolomTrader.sol:227: require(amountRemaining >= amount, 'order already filled'); contracts/core/GolomTrader.sol:235: require(amount == 1, 'only 1 erc721 at 1 time'); contracts/core/GolomTrader.sol:299: require(amount == 1, 'only 1 erc721 at 1 time'); contracts/core/GolomTrader.sol:359: require(amount == 1, 'only 1 erc721 at 1 time'); contracts/core/GolomTrader.sol:455: require(distributorEnableDate <= block.timestamp, 'not allowed');
Shortening revert strings to fit in 32 bytes will decrease deployment time gas and will decrease runtime gas when the revert condition is met.
Revert strings that are longer than 32 bytes require at least one additional mstore, along with additional overhead for computing memory offset, etc.
// Links to githubfile
https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/core/GolomTrader.sol#24 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#73 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#929 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#945
// actual code which shows the use contracts/governance/GolomToken.sol:24: require(msg.sender == minter, 'GolomToken: only reward distributor can enable'); contracts/vote-escrow/VoteEscrowDelegation.sol:73: require(this.balanceOfNFT(tokenId) >= MIN_VOTING_POWER_REQUIRED, 'VEDelegation: Need more voting power'); contracts/vote-escrow/VoteEscrowCore.sol:929: require(_locked.end > block.timestamp, 'Cannot add to expired lock. Withdraw'); contracts/vote-escrow/VoteEscrowCore.sol:945: require(unlock_time > block.timestamp, 'Can only lock until time in the future');
Recommendations: I suggest shortening the revert strings to fit in 32 bytes, or that using custom errors as described next.**
Custom errors from Solidity 0.8.4 are cheaper than revert strings (cheaper deployment cost and runtime cost when the revert condition is met)
// Links to githubfile https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#147 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#170 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowDelegation.sol#188 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#1042 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#1113 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#1133 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#1134 https://github.com/code-423n4/2022-07-golom/blob/7bbb55fca61e6bae29e57133c1e45806cbb17aa4/contracts/vote-escrow/VoteEscrowCore.sol#1211
// actual code which shows the use contracts/vote-escrow/VoteEscrowDelegation.sol:147: uint256 lower = 0; contracts/vote-escrow/VoteEscrowDelegation.sol:170: uint256 votes = 0; contracts/vote-escrow/VoteEscrowDelegation.sol:188: uint256 votes = 0; contracts/vote-escrow/VoteEscrowCore.sol:1042: uint256 _min = 0; contracts/vote-escrow/VoteEscrowCore.sol:1113: uint256 _min = 0; contracts/vote-escrow/VoteEscrowCore.sol:1133: uint256 d_block = 0; contracts/vote-escrow/VoteEscrowCore.sol:1134: uint256 d_t = 0; contracts/vote-escrow/VoteEscrowCore.sol:1211: uint256 dt = 0;
The unchecked keyword is new in solidity version 0.8.0, so this only applies to that version or higher, which these instances are. This saves 30-40 gas per loop
contracts/core/GolomTrader.sol:415: for (uint256 i = 0; i < proof.length; i++) {
contracts/rewards/RewardDistributor.sol:143: for (uint256 index = 0; index < epochs.length; index++) { contracts/rewards/RewardDistributor.sol:157: for (uint256 index = 0; index < epochs.length; index++) { contracts/rewards/RewardDistributor.sol:180: for (uint256 tindex = 0; tindex < tokenids.length; tindex++) { contracts/rewards/RewardDistributor.sol:183: for (uint256 index = 0; index < epochs.length; index++) { contracts/rewards/RewardDistributor.sol:226: for (uint256 index = 0; index < epoch; index++) { contracts/rewards/RewardDistributor.sol:258: for (uint256 index = 0; index < epoch; index++) { contracts/rewards/RewardDistributor.sol:273: for (uint256 index = 0; index < epoch; index++) {
contracts/vote-escrow/VoteEscrowDelegation.sol:171: for (uint256 index = 0; index < delegated.length; index++) { contracts/vote-escrow/VoteEscrowDelegation.sol:189: for (uint256 index = 0; index < delegatednft.length; index++) { contracts/vote-escrow/VoteEscrowDelegation.sol:199: for (uint256 i; i < _array.length; i++) {
10 ** 18 can be changed to 1e18 to avoid unnecessary arithmetic operation and save gas.s
contracts/rewards/RewardDistributor.sol:48 contracts/rewards/RewardDistributor.sol:100
contracts/rewards/RewardDistributor.sol:48: uint256 constant dailyEmission = 600000 * 10**18; contracts/rewards/RewardDistributor.sol:100: if (rewardToken.totalSupply() > 1000000000 * 10**18) {