Holograph contest - cloudjunky's results

Omnichain protocol for deploying, minting, & bridging NFTs between blockchains.

General Information

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

Holograph

Findings Distribution

Researcher Performance

Rank: 108/144

Findings: 1

Award: $0.00

QA:
grade-c

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

https://github.com/code-423n4/2022-10-holograph/blob/main/contracts/HolographOperator.sol#L596

Vulnerability details

Impact

The transfer() function only provides a stipend for the recipient to use of 2300 gas. If the recipient uses more than that, transfers will fail. For longevity, and especially for a project of Holograph’s nature it is better to use call() rather than transfer() to ensure that future gas increases won’t affect ETH transfers.

The transfer() function can fail for a number of reasons;

  1. The claimer smart contract does not implement a payable function.
  2. The claimer smart contract does implement a payable fallback which uses more than 2300 gas unit.
  3. The claimer smart contract implements a payable fallback function that needs less than 2300 gas units but is called through proxy, raising the call’s gas usage above 2300.

Additionally, using higher than 2300 gas might be mandatory for some multi-sig wallets.

The following git diff demonstrates how call() can be used instead of transfer();

--- a/contracts/HolographOperator.sol
+++ b/contracts/HolographOperator.sol
@@ -593,7 +593,8 @@ contract HolographOperator is Admin, Initializable, HolographOperatorInterface {
     uint256 hlgFee = messagingModule.getHlgFee(toChain, gasLimit, gasPrice);
     address hToken = _registry().getHToken(_holograph().getHolographChainId());
     require(hlgFee < msg.value, "HOLOGRAPH: not enough value");
-    payable(hToken).transfer(hlgFee);
+    (bool success, ) = payable(hToken).call{value: hlgFee}("");
+    require(success, "ETH Transfer failed.");

Note call() introduces the potential for re-entrancy but future proofs ETH transfers into the future in the even that gas usage changes. Functions including call should follow the Check, Effects, Interactions pattern and or Openzeppelin’s ReentrancyGuard.

#0 - gzeoneth

2022-10-28T09:24:42Z

Duplicate of #33

#1 - gzeoneth

2022-11-21T07:20:30Z

As QA report

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter