The historical voting power preservation mechanism in veRAACToken has aan issue. When users lock tokens and record votes, their historical voting power can be manipulated through specific withdrawal patterns. This breaks a core invariant of the vote-escrow system where historical voting records should remain immutable.
The issue stems from how voting power checkpoints are handled in veRAACToken.sol. When tokens are withdrawn, the contract updates the user's voting power checkpoint but doesn't properly preserve the historical record at the previous block number.
The PowerCheckpoint library's implementation in
veRAACTokendoesn't maintain separate mappings for historical and current voting power. Whenwithdraw()is called, it overwrites the checkpoint data without considering the block number context.
The protocol assumes checkpoints are immutable historical records, but the implementation allows retroactive changes. This breaks a fundamental invariant of the governance system where past votes should be set in stone.
The assumption that the PowerCheckpoint library would handle historical preservation automatically, similar to how Compound's checkpointing works. However, the interaction between withdrawal mechanics and the gauge voting system (see GaugeController.sol) creates an unexpected state mutation path.
When you see how the veRAACToken contract interacts with the broader RAAC ecosystem. The protocol connects real estate to DeFi through a system of tokens, gauges, and voting mechanisms. The voting power drives both governance decisions and economic incentives through the dual-gauge system (RAACGauge and RWAGauge).
The core mistake's in the checkpoint mechanism. When users withdraw their tokens, the contract updates their voting power without preserving the historical record. This means that past governance decisions which could affect real estate tokenization parameters, lending rates, or gauge weights - become mutable. See the withdraw() function
Looking at the technical implementation, the GaugeController relies on these historical voting records to calculate proper weight distributions between real estate assets (RWA) and protocol tokens (RAAC). By manipulating historical voting power, an attacker could retroactively alter gauge weights, affecting reward distributions across the entire protocol.
This vulnerability is particularly concerning because RAAC's dual-gauge system forms the backbone of directing protocol incentives between real estate activities and DeFi operations. The ability to change historical votes undermines the time-weighted nature of the ve-token mechanism, which is designed to encourage long-term alignment with protocol goals.
Governance Impact:
Affects proposal validation in Governance.sol
Compromises gauge weight calculations in GaugeController.sol
Could manipulate boost calculations in BoostController.sol
Economic Impact: The ability to manipulate historical voting power undermines the entire vote-escrow tokenomics model that incentivizes long-term protocol alignment.
Consider separating the historical and current state updates, because this maintains the integrity of past voting power for governance calculations while properly handling the withdrawal process, to align with IveRAACToken.sol's requirement that historical voting power must remain immutable, as specified in the getPastVotes() function interface.
Historical Data → Preserved (new step)
User Lock Data → Validated
Current State → Cleared
Current Checkpoint → Updated
Tokens → Burned and Transferred
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.