The lock extension validation in veRAACToken fails to properly enforce duration limits. Users can extend locks beyond the MAX_LOCK_DURATION, violating the protocol economics and potentially disrupting voting power calculations.
The extend() function's validation. While the contract defines MAX_LOCK_DURATION as 1460 days, the duration check in _lockState.extendLock() fails to properly validate the total lock duration after extension.
The RAAC Protocol introduces an innovative way to bring real estate on-chain through its veRAACToken mechanism. However, I've discovered a significant issue in how lock extensions are handled.
Notice how the protocol uses a vote-escrow system similar to Curve's veCRV, where users lock RAAC tokens to gain voting power. The longer the lock duration, the more voting power they receive. This mechanism is meant to align long-term incentives, with a maximum lock duration of 1460 days.
When a user calls extend(), the contract fails to properly validate the total lock duration after extension. This means a user could:
Create an initial lock within the allowed duration
Repeatedly extend their lock beyond the 1460-day limit
Gain disproportionate voting power that exceeds protocol design
Looking at the code, we can see why this happens
The function trusts _lockState.extendLock() to handle validation, but the check is insufficient. This breaks a core assumption of the ve-tokenomics, that voting power is properly bounded by the maximum lock duration.
This vulnerability directly impacts the dual-gauge system that governs both RAAC and RWA emissions. A malicious user could accumulate excessive voting power and significantly influence protocol direction.
The protocol uses vote-escrowed tokens (veRAACToken) to align long-term incentives, where users lock RAAC tokens to gain voting power over both real estate yields and protocol emissions.
The core mistake lies in how the protocol handles lock extensions. the veRAACToken contract allows users to extend their lock durations through the extend() function. This seemingly simple mechanism contains a powerful flaw in its validation logic.
When a user creates their initial lock, they must stay within the MAX_LOCK_DURATION of 1460 days. However, the extend() function fails to enforce this same limit on extensions. This means that a strategic user can first create a valid lock, then repeatedly extend it beyond the protocol's intended maximum duration. With each extension, they gain disproportionate voting power over both the RWA and RAAC gauges.
Consider adding two key validations:
Checks the new duration against MAX_LOCK_DURATION
Validates that the total lock duration (existing + extension) stays within protocol limits
This ensures the entire voting power and token minting flow remains within the protocol's intended boundaries.
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.