Holograph contest - pashov'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: 100/144

Findings: 2

Award: $0.02

QA:
grade-c

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: d3e4

Also found by: 2997ms, Bnke0x0, Dinesh11G, Jeiwan, Lambda, RedOneN, Trust, V_B, __141345__, ballx, brgltd, cccz, chaduke, d3e4, joestakey, martin, pashov, vv7

Awards

0.0184 USDC - $0.02

Labels

bug
duplicate
2 (Med Risk)

External Links

Lines of code

https://github.com/code-423n4/2022-10-holograph/blob/f8c2eae866280a1acfdc8a8352401ed031be1373/contracts/enforcer/PA1D.sol#L416 https://github.com/code-423n4/2022-10-holograph/blob/f8c2eae866280a1acfdc8a8352401ed031be1373/contracts/enforcer/PA1D.sol#L439

Vulnerability details

Proof of concept

USDT’s transfer function does not return a boolean - it is not ERC20 compliant. If the contract had a balance of USDT and getTokenPayout() or getTokenPayouts() were called to get that USDT payout, the line

require(erc20**.transfer**(addresses[i], sending), "PA1D: Couldn't transfer token");

will always revert, because USDT’s transfer doesn’t return a boolean.

Impact

The impact is forever stuck payouts in PA1D.sol essentially resulting in a loss of value.

Recommendation

Use OpenZeppelin’s SafeERC20 instead with safeTransferFrom - it works with USDT as well.

#0 - gzeoneth

2022-10-28T10:01:46Z

Duplicate of #456

Lines of code

https://github.com/code-423n4/2022-10-holograph/blob/f8c2eae866280a1acfdc8a8352401ed031be1373/contracts/enforcer/PA1D.sol#L396

Vulnerability details

Impact

The use of the deprecated transfer() function for an address will inevitably make the transaction fail when:

  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 multisig wallets.

Even if the current design is for using an EOA feeController you might decide to use a multisig in a later stage, and using call() will work for both, unlike transfer().

Recommendation

Use call() with value instead of transfer()

#0 - gzeoneth

2022-10-30T15:50:09Z

#1 - gzeoneth

2022-11-21T07:26:07Z

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