#37058 [SC-High] Theft of remuneration through claims processing loops.

Submitted on Nov 24th 2024 at 05:14:27 UTC by @innertia for Audit Comp | Celo

  • Report ID: #37058

  • Report Type: Smart Contract

  • Report severity: High

  • Target: https://github.com/celo-org/celo-monorepo/blob/release/core-contracts/12/packages/protocol/contracts-0.8/common/EpochManager.sol

  • Impacts:

    • Theft of unclaimed royalties

Description

Brief/Intro

In EpochManager, rewards are distributed by advancing the EpochProcess. However, if a group that has already received a reward loops through the process, it will be able to obtain as many rewards as it likes.

Vulnerability Details

In setToProcessGroups, rewards are assigned to the group corresponding to the electedAccounts.

        processedGroups[group] = epochRewards == 0 ? type(uint256).max : epochRewards;

https://github.com/celo-org/celo-monorepo/blob/4903cfa3744f4e03c5c042c3f881cc93d4807b21/packages/protocol/contracts-0.8/common/EpochManager.sol#L247

After that, rewards are distributed within the processGroup.

https://github.com/celo-org/celo-monorepo/blob/4903cfa3744f4e03c5c042c3f881cc93d4807b21/packages/protocol/contracts-0.8/common/EpochManager.sol#L288

At this point, processedGroups are deleted, but electedAccounts are not deleted.

https://github.com/celo-org/celo-monorepo/blob/4903cfa3744f4e03c5c042c3f881cc93d4807b21/packages/protocol/contracts-0.8/common/EpochManager.sol#L291

In other words, by starting setToProcessGroups again, rewards are assigned to the same groups corresponding to the electedAccounts again.

https://github.com/celo-org/celo-monorepo/blob/4903cfa3744f4e03c5c042c3f881cc93d4807b21/packages/protocol/contracts-0.8/common/EpochManager.sol#L236-L237

By repeating this, group can obtain as many rewards as they like. In the case of finishNextEpochProcess, where the same process is executed in batches, the electedAccounts are deleted each time the process is executed. This is not a problem.

https://github.com/celo-org/celo-monorepo/blob/4903cfa3744f4e03c5c042c3f881cc93d4807b21/packages/protocol/contracts-0.8/common/EpochManager.sol#L336-L337

This problem occurs because there is no such process in setToProcessGroups.

Impact Details

A selected group of people can receive unlimited rewards.

References

https://github.com/celo-org/celo-monorepo/blob/4903cfa3744f4e03c5c042c3f881cc93d4807b21/packages/protocol/contracts-0.8/common/EpochManager.sol#L247. https://github.com/celo-org/celo-monorepo/blob/4903cfa3744f4e03c5c042c3f881cc93d4807b21/packages/protocol/contracts-0.8/common/EpochManager.sol#L288. https://github.com/celo-org/celo-monorepo/blob/4903cfa3744f4e03c5c042c3f881cc93d4807b21/packages/protocol/contracts-0.8/common/EpochManager.sol#L291. https://github.com/celo-org/celo-monorepo/blob/4903cfa3744f4e03c5c042c3f881cc93d4807b21/packages/protocol/contracts-0.8/common/EpochManager.sol#L236-L237. https://github.com/celo-org/celo-monorepo/blob/4903cfa3744f4e03c5c042c3f881cc93d4807b21/packages/protocol/contracts-0.8/common/EpochManager.sol#L336-L337.

Proof of Concept

First, as a preliminary preparation, modify the distributeEpochRewards of MockElection. In this mock, the value is simply assigned, but in the original function behaviour, the correct behaviour is to add. Therefore, modify it as follows.

https://github.com/celo-org/celo-monorepo/blob/4903cfa3744f4e03c5c042c3f881cc93d4807b21/packages/protocol/contracts/governance/test/MockElection.sol#L104-L106

With this modification, the existing test will not fail.

Now, we will begin the test of reward theft. As this is a repurposed version of an existing test, I have only written comments for the important parts. Please add the following contract to EpochManager.t.sol. https://github.com/celo-org/celo-monorepo/blob/release/core-contracts/12/packages/protocol/test-sol/unit/common/EpochManager.t.sol

Last updated

Was this helpful?