Platform: Code4rena
Start Date: 18/10/2022
Pot Size: $75,000 USDC
Total HM: 27
Participants: 144
Period: 7 days
Judge: gzeon
Total Solo HM: 13
Id: 170
League: ETH
Rank: 20/144
Findings: 3
Award: $577.36
๐ Selected for report: 0
๐ Solo Findings: 0
๐ Selected for report: minhtrng
Also found by: Deivitto, V_B, __141345__, adriro, cdahlheimer, d3e4, ladboy233, nadin, teawaterwire
1.9681 USDC - $1.97
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L484-L539 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L1185-L1193
Use of pseudo randomness in chain is not recommended as it can be predicted by anyone, this can affect value in case of minting or withdrawing in some scenarios
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L484-L539 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L1185-L1193
Use oracles
#0 - gzeoneth
2022-10-30T16:57:52Z
Duplicate of #27
#1 - ACC01ADE
2022-11-09T13:15:06Z
This is a design decision. We believe pseudo randomness to be sufficient enough for this use case.
๐ Selected for report: Rolezn
Also found by: 0x1f8b, 0x52, 0x5rings, 0xNazgul, 0xSmartContract, 0xZaharina, 0xhunter, 0xzh, 8olidity, Amithuddar, Aymen0909, B2, Bnke0x0, Chom, Deivitto, Diana, Diraco, Dravee, Franfran, JC, Jeiwan, Josiah, JrNet, Jujic, KingNFT, KoKo, Lambda, Margaret, Migue, Ocean_Sky, PaludoX0, Picodes, Rahoz, RaoulSchaffranek, RaymondFam, RedOneN, ReyAdmirado, Shinchan, Tagir2003, Trust, Waze, Yiko, __141345__, a12jmx, adriro, ajtra, arcoun, aysha, ballx, bin2chen, bobirichman, brgltd, bulej93, catchup, catwhiskeys, caventa, cccz, cdahlheimer, ch0bu, chaduke, chrisdior4, cloudjunky, cryptostellar5, cryptphi, csanuragjain, cylzxje, d3e4, delfin454000, djxploit, durianSausage, erictee, fatherOfBlocks, francoHacker, gianganhnguyen, gogo, hansfriese, i_got_hacked, ignacio, imare, karanctf, kv, leosathya, louhk, lukris02, lyncurion, m_Rassska, malinariy, martin, mcwildy, mics, minhtrng, nicobevi, oyc_109, pashov, peanuts, pedr02b2, peiw, rbserver, ret2basic, rotcivegaf, rvierdiiev, ryshaw, sakman, sakshamguruji, saneryee, securerodd, seyni, sikorico, svskaushik, teawaterwire, tnevler, w0Lfrum
549.0408 USDC - $549.04
On a couple of places in the code precautions are not being taken not to divide by 0
, this would revert the code.
Navigate to the following contracts,
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L1177 current += (current / _operatorThresholdDivisor) * (position / _operatorThresholdStep);
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L346 uint256 timeDifference = elapsedTime / job.blockTimes;
Recommend making sure division by 0
wonโt occur by checking the variables beforehand and handling this edge case.
There are fallback
and receive
functions that does nothing. This can lead into unexpected behavior / loss funds if somebody sends ether and no withdraw / transfer flow created.
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L251-L257 receive() external payable {}
If the intention is for the Ether to be used, the function should call another function, otherwise it
should revert
(e.g. require(msg.sender == address(weth)) )
Risk of using block.timestamp
for time should be considered.
block.timestamp
is not an ideal proxy for time because of issues with synchronization, miner manipulation and changing block times.
This kind of issue may affect the code allowing or reverting the code before the expected deadline, modifying the normal functioning or reverting sometimes.
SWC ID: 116
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L899-L933 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L301-L439 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L849-L891 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L825-L840 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L1122-L1155 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L460-L490
block.timestamp
as time proxy and evaluate if block numbers can be used as an approximation for the application logic. Both have risks that need to be factored in.The initialize function that initializes important contract state can be called by anyone.
The attacker can initialize the contract before the legitimate deployer, hoping that the victim continues to use the same contract.
In the best case for the victim, they notice it and have to redeploy their contract costing gas.
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographBridge.sol#L162 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographFactory.sol#L143 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L240 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC20H.sol#L140 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC721H.sol#L140 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/Holographer.sol#L147 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L218 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L238 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/PA1D.sol#L173 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/module/LayerZeroModule.sol#L158
Use the constructor to initialize non-proxied contracts.
For initializing proxy contracts deploy contracts using a factory contract that immediately calls initialize after deployment or make sure to call it immediately after deployment and verify the transaction succeeded.
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L138-L757 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L138-L757 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L138-L757 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L138-L757 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L138-L757 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L138-L757 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L138-L757 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L138-L757
Events without indexed event parameters make it harder and inefficient for off-chain tools to analyze them.
Indexed parameters (โtopicsโ) are searchable event parameters. They are stored separately from unindexed event parameters in an efficient manner to allow for faster access. This is useful for efficient off-chain-analysis, but it is also more costly gas-wise.
Consider which event parameters could be particularly useful to off-chain tools and should be indexed.
Constant naming convention is all upper case.
Some constants are not using proper style.
Constant should be in UPPER_CASE_WITH_UNDERSCORES
as per Solidity Style Guide.
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/Holographer.sol#L119-L135 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographBridge.sol#L126-L142 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographFactory.sol#L127-L131 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L129-L153 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC20H.sol#L110-L114 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC721H.sol#L110-L114 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L142-L146 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L136-L140 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/PA1D.sol#L124-L144 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/module/LayerZeroModule.sol#L126-L146
Rename the constant to uppercase style: CONSTANTS_WITH_UNDERSCORES
.
Missing Natspec and regular comments affect readability and maintainability of a codebase.
Contracts has partial or full lack of comments
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/module/LayerZeroModule.sol#L1-L485 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/Holographer.sol#L1-L244 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L1-L757 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC721H.sol#L1-L230 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographFactory.sol#L1-L351 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC20H.sol#L1-L229
There is some code that is commented out. It could point to items that are not done or need redesigning, be a mistake, or just be testing overhead.
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L524-L570 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L438
Review and remove or resolve/document the commented out lines if needed.
OpenZeppelin recommends that the initializer modifier be applied to constructors in order to avoid potential griefs, social engineering, or exploits.
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC20H.sol#L133 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographBridge.sol#L155 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographFactory.sol#L136 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L233 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC721H.sol#L133 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/Holographer.sol#L140 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L211 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L231 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/PA1D.sol#L166 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/module/LayerZeroModule.sol#L151
Ensure that the modifier is applied to the implementation contract. If the default constructor is currently being used, it should be changed to be an explicit one with the modifier applied.
Code architecture, incentives, and error handling/reporting questions/issues should be resolved before deployment
The code includes a TODO
that affects readability and focus on the readers/auditors of the contracts
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L701 // TODO: move the bit-shifting around to have it be sequential
Remove already done TODO
Require/revert statements should include error messages in order to help at monitoring the system.
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L373 require(SourceERC721().beforeApprove(tokenOwner, to, tokenId));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L378 require(SourceERC721().afterApprove(tokenOwner, to, tokenId));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L391 require(SourceERC721().beforeBurn(wallet, tokenId));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L395 require(SourceERC721().afterBurn(wallet, tokenId));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L460 require(SourceERC721().beforeSafeTransfer(from, to, tokenId, data));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L473 require(SourceERC721().afterSafeTransfer(from, to, tokenId, data));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L486 require(SourceERC721().beforeApprovalAll(to, approved));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L491 require(SourceERC721().afterApprovalAll(to, approved));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L624 require(SourceERC721().beforeTransfer(from, to, tokenId, data));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L628 require(SourceERC721().afterTransfer(from, to, tokenId, data)); https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L759 require(SourceERC721().beforeOnERC721Received(_operator, _from, address(this), _tokenId, _data));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L767 require(SourceERC721().afterOnERC721Received(_operator, _from, address(this), _tokenId, _data));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L328 require(SourceERC20().beforeApprove(msg.sender, spender, amount));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L332 require(SourceERC20().afterApprove(msg.sender, spender, amount));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L339 require(SourceERC20().beforeBurn(msg.sender, amount));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L343 require(SourceERC20().afterBurn(msg.sender, amount));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L541 require(SourceERC20().afterSafeTransfer(account, recipient, amount, data));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L582 require(SourceERC20().beforeTransfer(msg.sender, recipient, amount));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L586 require(SourceERC20().afterTransfer(msg.sender, recipient, amount));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L606 require(SourceERC20().beforeTransfer(account, recipient, amount));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L610 require(SourceERC20().afterTransfer(account, recipient, amount));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographBridge.sol#L366 revert(revertReason);
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L430 require(SourceERC20().beforeApprove(msg.sender, spender, newAllowance));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L434 require(SourceERC20().afterApprove(msg.sender, spender, newAllowance)); https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L354 require(SourceERC20().beforeBurn(account, amount));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L358 require(SourceERC20().afterBurn(account, amount)); https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L371 require(SourceERC20().beforeApprove(msg.sender, spender, newAllowance));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L375 require(SourceERC20().afterApprove(msg.sender, spender, newAllowance));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L447 require(SourceERC20().beforeOnERC20Received(account, sender, address(this), amount, data));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L455 require(SourceERC20().afterOnERC20Received(account, sender, address(this), amount, data)); https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L484 require(SourceERC20().beforeApprove(account, spender, amount));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L488 require(SourceERC20().afterApprove(account, spender, amount));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L502 require(SourceERC20().beforeSafeTransfer(msg.sender, recipient, amount, data)); https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L507 require(SourceERC20().afterSafeTransfer(msg.sender, recipient, amount, data));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L536 require(SourceERC20().beforeSafeTransfer(account, recipient, amount, data)); https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L529
Add error messages
#0 - gzeoneth
2022-11-01T12:46:39Z
Front run initializer - Duplicate of #201
#1 - alexanderattar
2022-11-09T21:03:24Z
Some of these are valid and we will consider following the suggestions where it doesn't break functionality. Prevent div by 0
is invalid because those values are hardcoded to non-zero numbers
๐ Selected for report: oyc_109
Also found by: 0x040, 0x1f8b, 0x5rings, 0xNazgul, 0xSmartContract, 0xZaharina, 0xsam, 0xzh, 2997ms, Amithuddar, Aymen0909, B2, Bnke0x0, Deivitto, Diana, Dinesh11G, Franfran, JC, JrNet, Jujic, KingNFT, KoKo, Mathieu, Metatron, Mukund, Olivierdem, PaludoX0, Pheonix, Picodes, RaymondFam, RedOneN, ReyAdmirado, Rolezn, Saintcode_, Satyam_Sharma, Shinchan, Tagir2003, Tomio, Waze, Yiko, __141345__, adriro, ajtra, aysha, ballx, beardofginger, bobirichman, brgltd, bulej93, catchup, catwhiskeys, cdahlheimer, ch0bu, chaduke, chrisdior4, cryptostellar5, cylzxje, d3e4, delfin454000, dharma09, djxploit, durianSausage, emrekocak, erictee, exolorkistis, fatherOfBlocks, gianganhnguyen, gogo, halden, hxzy, i_got_hacked, iepathos, karanctf, leosathya, lucacez, lukris02, lyncurion, m_Rassska, martin, mcwildy, mics, nicobevi, peanuts, peiw, rbserver, ret2basic, rotcivegaf, ryshaw, sakman, sakshamguruji, saneryee, sikorico, skyle, svskaushik, tnevler, vv7, w0Lfrum, zishansami
26.3525 USDC - $26.35
Custom errors reduce 38 gas if the condition is met and 22 gas otherwise. Also reduces contract size and deployment costs.
Since version 0.8.4 the use of custom errors rather than revert() / require() saves gas as noticed in https://blog.soliditylang.org/2021/04/21/custom-errors/ https://github.com/code-423n4/2022-04-pooltogether-findings/issues/13
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographBridge.sol#L148 require(msg.sender == address(_operator()), "HOLOGRAPH: operator only call");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographBridge.sol#L163 require(!_isInitialized(), "HOLOGRAPH: already initialized");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographBridge.sol#L214 require(selector == Holographable.bridgeIn.selector, "HOLOGRAPH: bridge in failed");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographBridge.sol#L233 require(doNotRevert, "HOLOGRAPH: reverted");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographBridge.sol#L270 require(selector == Holographable.bridgeOut.selector, "HOLOGRAPH: bridge out failed");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L241 require(!_isInitialized(), "HOLOGRAPH: already initialized");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L309 require(_operatorJobs[hash] > 0, "HOLOGRAPH: invalid job");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L350 require(timeDifference > 0, "HOLOGRAPH: operator has time");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L354 require(gasPrice >= tx.gasprice, "HOLOGRAPH: gas spike detected");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L368 require(fallbackOperator == msg.sender, "HOLOGRAPH: invalid fallback");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L415 require(gasleft() > gasLimit, "HOLOGRAPH: not enough gas left");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L446 require(msg.sender == address(this), "HOLOGRAPH: operator only call");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L485 require(msg.sender == address(_messagingModule()), "HOLOGRAPH: messaging only call");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L591 require(msg.sender == _bridge(), "HOLOGRAPH: bridge only call");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L595 require(hlgFee < msg.value, "HOLOGRAPH: not enough value");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L728 require(_operatorPods.length >= pod, "HOLOGRAPH: pod does not exist");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L739 require(_operatorPods.length >= pod, "HOLOGRAPH: pod does not exist");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L756 require(_operatorPods.length >= pod, "HOLOGRAPH: pod does not exist");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L829 require(_bondedOperators[operator] != 0, "HOLOGRAPH: operator not bonded");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L839 require(_utilityToken().transferFrom(msg.sender, address(this), amount), "HOLOGRAPH: token transfer failed");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L857 require(_bondedOperators[operator] == 0 && _bondedAmounts[operator] == 0, "HOLOGRAPH: operator is bonded");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L863 require(current <= amount, "HOLOGRAPH: bond amount too small");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L881 require(_operatorPods[pod - 1].length < type(uint16).max, "HOLOGRAPH: too many operators");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L889 require(_utilityToken().transferFrom(msg.sender, address(this), amount), "HOLOGRAPH: token transfer failed");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L903 require(_bondedOperators[operator] != 0, "HOLOGRAPH: operator not bonded");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L911 require(_isContract(operator), "HOLOGRAPH: operator not contract");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L915 require(Ownable(operator).isOwner(msg.sender), "HOLOGRAPH: sender not owner");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L932 require(_utilityToken().transfer(recipient, amount), "HOLOGRAPH: token transfer failed");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographFactory.sol#L144 require(!_isInitialized(), "HOLOGRAPH: already initialized");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographFactory.sol#L220 require(_verifySigner(signature.r, signature.s, signature.v, hash, signer), "HOLOGRAPH: invalid signature");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographFactory.sol#L228 require(!_isContract(holographerAddress), "HOLOGRAPH: already deployed");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/module/LayerZeroModule.sol#L159 require(!_isInitialized(), "HOLOGRAPH: already initialized");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/module/LayerZeroModule.sol#L235 require(msg.sender == address(_operator()), "HOLOGRAPH: operator only call");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/Holographer.sol#L148 require(!_isInitialized(), "HOLOGRAPHER: already initialized");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/Holographer.sol#L166 require(success && selector == InitializableInterface.init.selector, "initialization failed");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/PA1D.sol#L159 require(isOwner(), "PA1D: caller not an owner");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/PA1D.sol#L174 require(!_isInitialized(), "PA1D: already initialized");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/PA1D.sol#L190 require(initialized == 0, "PA1D: already initialized");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/PA1D.sol#L390 require(balance - gasCost > 10000, "PA1D: Not enough ETH to transfer");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/PA1D.sol#L411 require(balance > 10000, "PA1D: Not enough tokens to transfer");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/PA1D.sol#L416 require(erc20.transfer(addresses[i], sending), "PA1D: Couldn't transfer token");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/PA1D.sol#L435 require(balance > 10000, "PA1D: Not enough tokens to transfer");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/PA1D.sol#L439 require(erc20.transfer(addresses[i], sending), "PA1D: Couldn't transfer token");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/PA1D.sol#L460 require(matched, "PA1D: sender not authorized");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/PA1D.sol#L472 require(addresses.length == bps.length, "PA1D: missmatched array lenghts");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/PA1D.sol#L477 require(totalBp == 10000, "PA1D: bps down't equal 10000");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L212 require(msg.sender == _holograph().getBridge(), "ERC721 bridge only call");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L224 require(msg.sender == sourceContract, "ERC721 source only call");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L239 require(!_isInitialized(), "ERC721 already initialized");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L258 require(sourceContract.init(initCode) == InitializableInterface.init.selector, "ERC721 could not init source");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L263 require(success && selector == InitializableInterface.init.selector, "ERC721 coud not init PA1D");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L323 require(_exists(tokenId), "ERC721 token does not exist");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L370 require(to != tokenOwner, "ERC721 cannot approve self");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L371 require(_isApproved(msg.sender, tokenId), "ERC721 not approved sender");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L388 require(_isApproved(msg.sender, tokenId), "ERC721 not approved sender");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L404 require(!_exists(tokenId), "ERC721 token already exists");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L408 require(SourceERC721().bridgeIn(fromChain, from, to, tokenId, data), "HOLOGRAPH: bridge in failed");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L419 require(to != address(0), "ERC721 zero address");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L420 require(_isApproved(sender, tokenId), "ERC721 sender not approved");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L421 require(from == _tokenOwner[tokenId], "ERC721 from is not owner");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L458 require(_isApproved(msg.sender, tokenId), "ERC721 not approved sender");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L484 require(to != msg.sender, "ERC721 cannot approve self");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L513 require(!_burnedTokens[token], "ERC721 can't mint burned token");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L622 require(_isApproved(msg.sender, tokenId), "ERC721 not approved sender");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L639 require(wallet != address(0), "ERC721 zero address");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L689 require(tokenOwner != address(0), "ERC721 token does not exist");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L700 require(index < _allTokens.length, "ERC721 index out of bounds");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L729 require(index < balanceOf(wallet), "ERC721 index out of bounds");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L757 require(_isContract(_operator), "ERC721 operator not contract");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L762 require(tokenOwner == address(this), "ERC721 contract not token owner");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L815 require(tokenId > 0, "ERC721 token id cannot be zero");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L816 require(to != address(0), "ERC721 minting to burn address");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L817 require(!_exists(tokenId), "ERC721 token already exists");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L818 require(!_burnedTokens[tokenId], "ERC721 token has been burned");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L869 require(_tokenOwner[tokenId] == from, "ERC721 token not owned");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L870 require(to != address(0), "ERC721 use burn instead");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L906 require(_exists(tokenId), "ERC721 token does not exist");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L192 require(msg.sender == _holograph().getBridge(), "ERC20 bridge only call");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L204 require(msg.sender == sourceContract, "ERC20 source only call");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L219 require(!_isInitialized(), "ERC20 already initialized");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L241 require(sourceContract.init(initCode) == InitializableInterface.init.selector, "ERC20 could not init source");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L349 require(currentAllowance >= amount, "ERC20 amount exceeds allowance");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L365 require(currentAllowance >= subtractedValue, "ERC20 decreased below zero");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L387 require(SourceERC20().bridgeIn(fromChain, from, to, amount, data), "HOLOGRAPH: bridge in failed");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L400 require(currentAllowance >= amount, "ERC20 amount exceeds allowance");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L427 require(newAllowance >= currentAllowance, "ERC20 increased above max value");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L445 require(_isContract(account), "ERC20 operator not contract"); https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L450 require(balance >= amount, "ERC20 balance check failed");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L469 require(block.timestamp <= deadline, "ERC20 expired deadline");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L482 require(signer == account, "ERC20 invalid signature");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L505 require(_checkOnERC20Received(msg.sender, recipient, amount, data), "ERC20 non ERC20Receiver");
require(currentAllowance >= amount, "ERC20
amount exceeds allowance");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L539 require(_checkOnERC20Received(account, recipient, amount, data), "ERC20 non ERC20Receiver");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L599 require(currentAllowance >= amount, "ERC20 amount exceeds allowance");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L620 require(account != address(0), "ERC20 account is zero address");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L621 require(spender != address(0), "ERC20 spender is zero address");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L627 require(account != address(0), "ERC20 account is zero address");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L629 require(accountBalance >= amount, "ERC20 amount exceeds balance");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L645 require(erc165support, "ERC20 no ERC165 support");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L684 require(to != address(0), "ERC20 minting to burn address");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L695 require(account != address(0), "ERC20 account is zero address");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L696 require(recipient != address(0), "ERC20 recipient is zero address");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L698 require(accountBalance >= amount, "ERC20 amount exceeds balance");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC721H.sol#L117 require(msg.sender == holographer(), "ERC721 holographer only");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC721H.sol#L123 require(msgSender() == _getOwner(), "ERC721 owner only function");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC721H.sol#L125 require(msg.sender == _getOwner(), "ERC721 owner only function");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC721H.sol#L147 require(!_isInitialized(), "ERC721 already initialized");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC20H.sol#L117 require(msg.sender == holographer(), "ERC20 holographer only");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC20H.sol#L123 require(msgSender() == _getOwner(), "ERC20 owner only function");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC20H.sol#L125 require(msg.sender == _getOwner(), "ERC20 owner only function");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/abstract/ERC20H.sol#L147 require(!_isInitialized(), "ERC20 already initialized");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L764 revert("ERC721 token does not exist");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L452 revert("ERC20 failed getting balance");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L653 revert("ERC20 non ERC20Receiver");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L661 revert("ERC20 eip-4524 not supported");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L665 revert("ERC20 no ERC165 support");
replace each error message in a require by a custom error
require()
statements that use &&
saves gasInstead of using the && operator in a single require statement to check multiple conditions, consider using multiple require statements with 1 condition per require statement (saving 3 gas per & ):
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L857 require(_bondedOperators[operator] == 0 && _bondedAmounts[operator] == 0, "HOLOGRAPH: operator is bonded");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/Holographer.sol#L166 require(success && selector == InitializableInterface.init.selector, "initialization failed");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L263 require(success && selector == InitializableInterface.init.selector, "ERC721 coud not init PA1D");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L465 (ERC165(to).supportsInterface(ERC165.supportsInterface.selector) &&
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L466 ERC165(to).supportsInterface(ERC721TokenReceiver.onERC721Received.selector) &&
Split require statements
When using elements that are smaller than 32 bytes, your contractโs gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.
https://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html Use a larger size than downcast where needed
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L181 uint8 private _decimals;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L181 uint8 private _decimals;
Consider using some data type that uses 32 bytes, for example uint256
All these variables could be combine in a Struct in order to reduce the gas cost.
As noticed in: https://gist.github.com/alexon1234/b101e3ac51bea3cbd9cf06f80eaa5bc2 When multiple mappings that access the same addresses, uints, etc, all of them can be mixed into an struct and then that data accessed like: mapping(datatype => newStructCreated) newStructMap; Also, you have this post where it explains the benefits of using Structs over mappings https://medium.com/@novablitz/storing-structs-is-costing-you-gas-774da988895e
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L193 mapping(bytes32 => uint256) private _operatorJobs;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L198 mapping(bytes32 => bool) private _failedJobs;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L218 mapping(address => uint256) private _bondedOperators;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L223 mapping(address => uint256) private _operatorPodIndex;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L228 mapping(address => uint256) private _bondedAmounts;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L170 mapping(uint256 => uint256) private _ownedTokensIndex;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L175 mapping(uint256 => address) private _tokenOwner;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L180 mapping(uint256 => address) private _tokenApprovals;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L201 mapping(uint256 => uint256) private _allTokensIndex;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L206 mapping(uint256 => bool) private _burnedTokens;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L185 mapping(address => uint256) private _ownedTokensCount;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L190 mapping(address => uint256[]) private _ownedTokens;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L196 mapping(address => mapping(address => bool)) private _operatorApprovals;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L156 mapping(address => uint256) private _balances;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L161 mapping(address => mapping(address => uint256)) private _allowances;
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L186 mapping(address => uint256) private _nonces;
Consider mixing different mappings into an struct when able in order to save gas.
--i costs less gas compared to i-- or i -= 1 for unsigned integer, as pre-increment is cheaper (about 5 gas per iteration). This statement is true even with the optimizer enabled.
i-- decrements i and returns the initial value of i . Which means:
uint i = 1; i--; // == 1 but i == 2
But --i returns the actual decremented value:
uint i = 1; --i; // == 2 and i == 2 too, so no need for a temporary variable
In the first case, the compiler has to create a temporary variable (when used) for returning 1 instead of 2
Replace to --i
as needed.
payable
If a function modifier such as onlyAdmin is used, the function will revert if a normal user tries to pay the function.
Marking the function as payable
will lower the gas cost for legitimate callers because the compiler will not include checks for whether a payment was provided.
The extra opcodes avoided are: CALLVALUE (2), DUP1 (3), ISZERO (3), PUSH2 (3), JUMPI (10), PUSH1 (3), DUP1 (3), REVERT(0), JUMPDEST (1), POP (2), which costs an average of about 21 gas per call to the function, in addition to the extra deployment cost
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographBridge.sol#L452 function setFactory(address factory) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographBridge.sol#L472 function setHolograph(address holograph) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographBridge.sol#L502 function setOperator(address operator) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographBridge.sol#L522 function setRegistry(address registry) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L285 ) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L949 function setBridge(address bridge) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L969 function setHolograph(address holograph) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L989 function setInterfaces(address interfaces) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L1009 function setMessagingModule(address messagingModule) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L1029 function setRegistry(address registry) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L1049 function setUtilityToken(address utilityToken) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographFactory.sol#L280 function setHolograph(address holograph) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographFactory.sol#L300 function setRegistry(address registry) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/module/LayerZeroModule.sol#L320 function setBridge(address bridge) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/module/LayerZeroModule.sol#L340 function setInterfaces(address interfaces) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/module/LayerZeroModule.sol#L360 function setLZEndpoint(address lZEndpoint) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/module/LayerZeroModule.sol#L380 function setOperator(address operator) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/module/LayerZeroModule.sol#L441 function setBaseGas(uint256 baseGas) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/module/LayerZeroModule.sol#L470 function setGasPerByte(uint256 gasPerByte) external onlyAdmin {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/PA1D.sol#L209 msg.sender == Admin(address(this)).getAdmin());
Consider adding payable to save gas
>=
cheaper than >
Strict inequalities ( >
) are more expensive than non-strict ones ( >=
). This is due to some supplementary checks (ISZERO
, 3 gas)
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographBridge.sol#L218 if (hTokenValue > 0) {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L309 require(_operatorJobs[hash] > 0, "HOLOGRAPH: invalid job");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L350 require(timeDifference > 0, "HOLOGRAPH: operator has time");
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L363 if (podIndex > 0 && podIndex < _operatorPods[pod].length) {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L398 if (leftovers > 0) {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L1126 if (operatorIndex > 0) {
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L815 require(tokenId > 0, "ERC721 token id cannot be zero");
Consider using >= 1
instead of > 0
to avoid some opcodes
<X> += <Y>
costs more gas than <X> = <X> + <Y>
for state variablesx+=y
costs more gas than x=x+y for state variables
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L382 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/HolographOperator.sol#L834 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L685-L686 https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L702
Don't use +=
for state variables as it cost more gas.
Using both named returns and a return statement isnโt necessary. Removing one of those can improve code clarity
Also as returns variable is ignored, it wastes extra gas
Remove return or returns when both used
abi.encode()
is less gas efficient than abi.encodePacked()
In general, abi.encodePacked
is more gas-efficient.
Changing the abi.encode function to abi.encodePacked
can save gas since the abi.encode function pads extra null bytes at the end of the call data, which is unnecessary. Also, in general, abi.encodePacked
is more gas-efficient.
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L260 abi.encodeWithSignature("initPA1D(bytes)", abi.encode(address(this), uint256(contractBps)))
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC721.sol#L426 return (Holographable.bridgeOut.selector, abi.encode(from, to, tokenId, data));
https://github.com/code-423n4/2022-10-holograph/blob/24bc4d8dfeb6e4328d2c6291d20553b1d3eff00b/contracts/enforcer/HolographERC20.sol#L409 return (Holographable.bridgeOut.selector, abi.encode(from, to, amount, data));
Consider changing abi.encode to abi.encodePacked
#0 - alexanderattar
2022-11-09T21:11:50Z
We will consider implementing suggestions where functionality is not affected