31151 - [SC - Medium] Delegation Saturation Leading to Asset Freezing...

Submitted on May 13th 2024 at 17:22:16 UTC by @Limbooo for Boost | Alchemix

Report ID: #31151

Report type: Smart Contract

Report severity: Medium

Target: https://github.com/alchemix-finance/alchemix-v2-dao/blob/main/src/VotingEscrow.sol

Impacts:

  • Temporary freezing of NFTs

Description

Intro

The VotingEscrow.sol contract contains a critical design flaw involving the MAX_DELEGATES limit, which is meant to cap the number of token IDs a delegate can manage. This limitation, while intended to prevent excessive computational load, can be maliciously exploited to cause denial of service and manipulate delegation processes.

Vulnerability Details

The vulnerability exists due to the static nature of the MAX_DELEGATES limit and its enforcement in the contract's delegation logic. When a user or contract attempts to delegate tokens, the contract checks whether adding more token IDs would exceed this limit for the delegatee. Malicious actors can deliberately saturate this limit by creating numerous delegations with minimal token amounts (1 Wei), preventing further legitimate delegations and operations.

In the current implementation the limit is set to 1024 tokens [1], this limit is used to avoid excessive gas usage that prevent a case where block limit reached. However, this limit is checked whenever a user call VotingEscrow::delegate, VotingEscrow::createLockFor, or VotingEscrow::transferFrom. This happens when those functionalities process the movement of the delegated tokens either by _moveTokenDelegates [2] or _moveAllDelegates [3].

Impact Details

  • Denial of Service (DoS): By reaching the MAX_DELEGATES limit for a delegatee, an attacker can prevent all further delegations to that delegatee. This can block crucial operations such as token transfers, lock creation, and more, effectively disabling key functionalities for users.

  • Asset Freezing: Users may find themselves unable to transfer or operate their tokens if an attacker targets their delegatees, leading to a freezing of assets which could damage user trust and the platform’s usability.

  • Delegation Manipulation: Attackers can manipulate the delegation process to their advantage, either by blocking potential delegatees to harm competitors or by protecting their delegation status from being overridden, thereby maintaining control over delegated tokens.

To effectively mitigate the risks associated with the MAX_DELEGATES vulnerability, we propose the following enhanced strategies:

  1. Distinct Delegate Limits: Implement two separate delegate limits:

  • Internal Delegate Limit: A higher limit for delegations where the tokens owner and the delegatee are the same entity. This addresses the use case of managing multiple tokens more efficiently while still protecting against excessive computational load.

  • External Delegate Limit: A more restrictive limit for delegations to different entities. This reduces the potential for denial-of-service attacks by limiting the number of delegates an external actor can control, thus safeguarding against malicious saturations.

However, this will generate some drawbacks for those users reaching the internal limit when delegations to different entities.

  1. Cooling-Off Period: Introduce a cooling-off period that temporarily restricts changes to delegations after a delegate limit threshold is approached. This measure would slow down rapid manipulations and give administrators time to address any suspicious activities.

  2. Rate Limiting of Delegate Changes: Apply rate limiting to operations that can alter delegate counts, such as token transfers and lock creations. This preventative measure would hinder an attacker’s ability to quickly reach delegate limits.

References

[1]: alchemix-v2-dao/src/VotingEscrow.sol#L34 at GitHub

[2]: alchemix-v2-dao/src/VotingEscrow.sol#L1040 at GitHub

[3]: alchemix-v2-dao/src/VotingEscrow.sol#L1110 at GitHub

Proof of Concept

The Proof of Concept (PoC) involves creating the VotingEscrowBlocker contract which is designed to exploit this vulnerability. Here are key functionalities demonstrated by the PoC:

  1. Creating and Merging Locks: The attacker contract creates locks with minimal token amounts to reach the MAX_DELEGATES limit quickly and merges them as needed to maintain control over the total number of delegates.

  2. Blocking Delegations: By strategically managing the number of active delegates, the attacker can ensure that no new delegates can be added once the limit is reached. This is shown by attempts to delegate to a saturated delegatee, which fail due to the contract's enforcement of the MAX_DELEGATES limit.

  3. Front-Running and Disruptive Actions: The PoC also shows how an attacker can use knowledge of pending transactions to pre-emptively block other users' actions, such as creating locks or transferring tokens, by ensuring that the delegatee remains at the maximum limit.

This PoC validates the severity of the vulnerability and underscores the need for immediate remediation steps to be taken to prevent potential exploits.

Test Case (Foundry)

NOTE: It will takes to much time to finish the test but we can decrease the MAX_DELEGATES to a lower value to speed up the test. However, this is not mandatory to make the test success and it will success for the current MAX_DELEGATES value.

The test can be added to a new file under the current test suite src/test/VotingEscrowPoC.t.sol, then specify the file name in FILE flag under Makefile configuration. Then, run using make test_file command.

Test Output

Last updated

Was this helpful?