PoolTogether V5: Part Deux - D_Auditor's results

A protocol for no-loss prize savings.

General Information

Platform: Code4rena

Start Date: 02/08/2023

Pot Size: $42,000 USDC

Total HM: 13

Participants: 45

Period: 5 days

Judge: hickuphh3

Total Solo HM: 5

Id: 271

League: ETH

PoolTogether

Findings Distribution

Researcher Performance

Rank: 31/45

Findings: 1

Award: $89.63

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

Awards

89.6296 USDC - $89.63

Labels

bug
3 (High Risk)
satisfactory
duplicate-82

External Links

Lines of code

https://github.com/GenerationSoftware/pt-v5-draw-auction/blob/f1c6d14a1772d6609de1870f8713fb79977d51c1/src/RngRelayAuction.sol#L131

Vulnerability details

Explanation

For the DrawAuction to be successfully completed, a specific sequence of actions must be followed, and each step holds significance. This demands a carefully designed execution flow that considers both the procedure's requirements and the authorized entities who can invoke these actions.

One pivotal function within this process is rngComplete(), which serves the purpose of finalizing the draw auction on the toChain and incorporating the generated random number into the prizePool. The code comments specify that only a relayer should have the privilege to call this function. Unfortunately, this crucial protocol was not adhered to, leading to an unintended vulnerability that allows anyone to execute the function as long as the sequence remains open.

Impact

Given the ability for the caller to input their own random number instead of waiting for the one generated by the RNG, several advantages are available to the msg.sender who exploits this vulnerability. Among these advantages, the most significant is the potential for financial gain. By designating their address as the rewardRecipient, the individual can direct the rewards to themselves.

    for (uint8 i = 0; i < _rewards.length; i++) {
      uint104 _reward = uint104(_rewards[i]);
      if (_reward > 0) {
        prizePool.withdrawReserve(auctionResults[i].recipient, _reward);
        emit AuctionRewardDistributed(_sequenceId, auctionResults[i].recipient, i, _reward);
      }
    }

Recommendation

Add a require state that ensures that RngRelayAuction::rngComplete() is only callable by the auction relayer

Assessed type

Access Control

#0 - c4-pre-sort

2023-08-08T03:20:13Z

raymondfam marked the issue as duplicate of #82

#1 - c4-judge

2023-08-14T02:47:52Z

HickupHH3 marked the issue as satisfactory

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