Covalent contest - hickuphh3's results

One unified API. One billion possibilities.

General Information

Platform: Code4rena

Start Date: 19/10/2021

Pot Size: $30,000 ETH

Total HM: 5

Participants: 13

Period: 3 days

Judge: GalloDaSballo

Total Solo HM: 4

Id: 43

League: ETH

Covalent

Findings Distribution

Researcher Performance

Rank: 6/13

Findings: 3

Award: $830.71

🌟 Selected for report: 2

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: gpersoon

Also found by: hickuphh3, jonah1005, xYrYuYx

Labels

bug
duplicate
2 (Med Risk)

Awards

0.1639 ETH - $586.30

External Links

Handle

hickuphh3

Vulnerability details

Impact

If the owner would like to remove rewards, the number of epochs affected could potentially be 1 less because solidity division rounds down, resulting in more rewards taken out than allowed.

Proof of Concept

Assume

  • currentEpoch is 1000
  • end epoch is 2000
  • 1 CQT per epoch reward emission: allocatedTokensPerEpoch = 1e18

There is therefore (2000 - 1000) * 1 CQT = 1000 CQT remaining to be distributed.

If the owner removes 99.99 CQT = 99.99 * 1e18 = 9999 * 1e16,

  • epochs = (9999 * 1e16) / 1e18 = 99
  • new end epoch = 2000 - 99 = 1901

However, the number of remaining rewards is 1000 - 99.99 = 900.01 is only able to cover for 900 epochs, which is 1 less than the calculated end epoch of 1901.

Use OpenZeppelin's ceilDiv() for the epoch calculation.

uint128 epochs = uint128(Math.ceilDiv(amount, allocatedTokensPerEpoch));

#0 - kitti-katy

2021-10-21T19:10:32Z

similar/related to #10

#1 - GalloDaSballo

2021-11-08T01:04:03Z

Duplicate of #10

Findings Information

🌟 Selected for report: hickuphh3

Also found by: WatchPug

Labels

bug
G (Gas Optimization)
resolved
sponsor confirmed

Awards

0.0137 ETH - $48.98

External Links

Handle

hickuphh3

Vulnerability details

Impact

The following lines in takeOutRewardTokens() are only needed in the case where endEpoch != 0.

uint128 currentEpoch = uint128(block.number);
uint128 epochs = amount / allocatedTokensPerEpoch;

Hence, they can be shifted inside the "if" block.

Furthermore, a double calculation of endEpoch - epochs can be avoided by saving the result into a new variable newEpoch.

if (endEpoch != 0) {
  uint128 newEpoch = endEpoch - (amount / allocatedTokensPerEpoch);
  require(newEpoch  > uint128(block.number), "Cannot takeout rewards from past");
  endEpoch = newEpoch;
}

#0 - GalloDaSballo

2021-11-01T16:57:02Z

Agree with the finding, the sponsor has applied the improvement

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