Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: high
Valid

Governance Attack Through Lock Value Manipulation in veRAACToken

Summary

veRAACToken::increase() allows users to increase their voting power through additional deposits without extending their lock time, enabling governance attacks where users can gain significant voting power and then withdraw funds shortly after, avoiding exposition to RAACToken, while still having the power to influence governance decision

Vulnerability Details

  1. Attacker locks 1 wei of RAAC for 1 year

  2. After ~364 days, attacker can increase his share as much as he wants (using borrowed amount) and calling increase()

  3. Attacker propose and vote massively a bad governance proposition

  4. Attacker can withdraw all his locked RAACToken and reimburse his debt

Note that it's only possible to have 1 lock active per address, but this limitation is useless as a user can use multiple different address with only 1 wei locked everytime to have a pool of address with already stacked amount to try to attack governance
There is no min lock amount in lock()

100_000 is needed to propose, and there is a minimal amount of time of 1 day to vote, but because castVote() use getVotingPower(address) that gets voting power at the time of call instead of getVotingPower(address, uint256) that get voting power at a certain time, an attacker could propose in 1 block by borrowing enough RAACToken, and vote with a succession of different account in 1 block as well, having no exposure to RAAC.

In 1 block :

  1. Attacker borrow/swap for RAAC

  2. Attacker use throwaway address with 1 wei increase() and castVote().

  3. Attacker withdraw(), the only check here is the timing of the lock, already expired

  4. Attacker repay or swap back to starting token.

Repeat in order to have as much vote needed to pass the proposal and execute it

Impact

Anyone can attack governance with very limited risk and pass vote that could be detrimental for the protocol.

Tools Used

Manual

Recommendations

It should not be possible to increase() amount without refreshing the timelock

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Governance.castVote uses current voting power instead of proposal creation snapshot, enabling vote manipulation through token transfers and potential double-voting

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Governance.castVote uses current voting power instead of proposal creation snapshot, enabling vote manipulation through token transfers and potential double-voting

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.