31276 - [SC - High] BPT can be locked for only week resulting in u...
Submitted on May 16th 2024 at 03:32:46 UTC by @marchev for Boost | Alchemix
Report ID: #31276
Report type: Smart Contract
Report severity: High
Target: https://github.com/alchemix-finance/alchemix-v2-dao/blob/main/src/VotingEscrow.sol
Impacts:
Theft of unclaimed yield
Description
Brief/Intro
The 80/20 ALCX/WETH BPT has a minimum lock period of 1 epoch (2 weeks). However, a flaw allows malicious actors to lock their BPT for just 1 week, resulting in unfair ALCX reward distribution. This means a malicious actor can unfairly claim rewards without meeting the minimum 2-week lock requirement.
Vulnerability Details
The _createLock() function is responsible for creating a lock when depositing Balancer Pool Tokens in VotingEscrow. It should enforce a minimum lock period of 1 epoch (2 weeks):
function _createLock(
uint256 _value,
uint256 _lockDuration,
bool _maxLockEnabled,
address _to
) internal returns (uint256) {
// ...
uint256 unlockTime = /** ... */ ((block.timestamp + _lockDuration) / WEEK) * WEEK;
// ...
require(unlockTime >= (((block.timestamp + EPOCH) / WEEK) * WEEK), "Voting lock must be 1 epoch");
// ...
}However, this check is flawed. A malicious actor can lock BPTs for just 1 week instead of the required 2 weeks. This allows them to unjustly receive rewards as if they had locked their BPTs for a whole epoch, effectively stealing rewards from other participants.
Example Scenario:
Next epoch starts at
1717632000(Thu Jun 06 2024 00:00:00 UTC)
Alice locks 1 BPT for
2 weeks(1 epoch) atblock.timestamp = 1716422401(Thu May 23 2024 00:00:01 UTC)Bob locks 1 BPT for
7 days + 1 secondsatblock.timestamp = 1717027199(Wed May 29 2024 23:59:59 UTC)The epoch resets on
1717632000(Thu Jun 06 2024 00:00:00 UTC)
Expected behavior: Bob should not be able to lock his BPT for less than 1 epoch (2 weeks).
Actual behavior: Alice and Bob receive equal rewards.
Bob circumvents the minimum lock duration check. Here’s why:
The check performed:
The check passes for Bob, even though his lock time is only 7 days + 1 second.
Impact Details
The flawed minimum lock time check allows users to lock BPTs for only 1 week but still receive rewards for a full epoch. This results in unfair reward distribution, with malicious users effectively stealing rewards from others.
References
https://github.com/alchemix-finance/alchemix-v2-dao/blob/f1007439ad3a32e412468c4c42f62f676822dc1f/src/VotingEscrow.sol#L1375-L1381
Proof of Concept
The following coded PoC demonstrates the issue.
Add the following test case to VotingEscrow.t.sol:
Make sure the following entries are updated in Makefile:
Run the PoC via:
PoC output:
Last updated
Was this helpful?