Skip to content
This repository has been archived by the owner on Jun 2, 2024. It is now read-only.

ydlee - A token owner cannot remove one mgCvg delegation when he already delegates to maxMgDelegatees addresses. #202

Closed
sherlock-admin2 opened this issue Nov 29, 2023 · 0 comments
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue

Comments

@sherlock-admin2
Copy link
Contributor

sherlock-admin2 commented Nov 29, 2023

ydlee

medium

A token owner cannot remove one mgCvg delegation when he already delegates to maxMgDelegatees addresses.

Summary

A token owner cannot remove one mgCvg delegation when he already delegates to maxMgDelegatees addresses, which violates the functionality of delegateMgCvg function.

Vulnerability Detail

A token owner can delegate his mgCvg to up to maxMgDelegatees addresses through delegateMgCvg function. This function can also be used to remove a delegation by setting parameter _percentage to 0 (L273). The removing works fine when the number of delegatees is less than maxMgDelegatees. If the token owner already delegates his mgCvg to maxMgDelegatees addresses, he cannot remove one specific delegation with delegateMgCvg, as the number of existing delegatees is required less than maxMgDelegatees at the begining of delegateMgCvg function (L282). This is inconsistent with the functionality of delegateMgCvg function.
https://github.com/sherlock-audit/2023-11-convergence/blob/main/sherlock-cvg/contracts/Locking/LockingPositionDelegate.sol#L271-L282

271:    /**
272:     * @notice Delegates a percentage of the mgCvG for a tokenId to another address (the mgCvg can be delegated to several addresses).
273:=>   * @dev Percentage=0 can be used to remove a delegation.
274:     * @param _tokenId is the ID of the token (NFT) to delegate voting power.
275:     * @param _to is the address we want to delegate to.
276:     * @param _percentage is the percentage we want to delegate to the address.
277:     */
278:    function delegateMgCvg(uint256 _tokenId, address _to, uint96 _percentage) external onlyTokenOwner(_tokenId) {
279:        require(_percentage <= 100, "INVALID_PERCENTAGE");
280:
281:        uint256 _delegateesLength = delegatedMgCvg[_tokenId].length;
282:=>      require(_delegateesLength < maxMgDelegatees, "TOO_MUCH_DELEGATEES");

POC: Let's add a new test case to sherlock-cvg/test/ut/delegation/manage-delegation.spec.ts to show this.

// File: sherlock-cvg/test/ut/delegation/manage-delegation.spec.ts

    it ("Delegates mgCvg to maxMgDelegatees and remove a delegation", async () => {
        // delegate mgCvg to 5 users to reach `maxMgDelegatees`
        await lockingPositionDelegate.connect(user1).delegateMgCvg(1, user4, 10);
        await lockingPositionDelegate.connect(user1).delegateMgCvg(1, user5, 10);
        await lockingPositionDelegate.connect(user1).delegateMgCvg(1, user6, 10);
        await lockingPositionDelegate.connect(user1).delegateMgCvg(1, user7, 10);
        await lockingPositionDelegate.connect(user1).delegateMgCvg(1, user8, 10);

        // remove one delegation through `delegateMgCvg` with 0 percentage -> revert
        await lockingPositionDelegate.connect(user1).delegateMgCvg(1, user6, 0).should.be.revertedWith("TOO_MUCH_DELEGATEES");

        // only able to remove one delegation by clean all delegations
        await lockingPositionDelegate.connect(user1).cleanDelegatees(1, false, true);
    });

In such case, token owner has to remove all the delegations first, and then add other delegations again except the one he wants to remove.

Impact

A token owner cannot remove one mgCvg delegation when he already delegates to maxMgDelegatees addresses, which violates the functionality of delegateMgCvg function.

Code Snippet

https://github.com/sherlock-audit/2023-11-convergence/blob/main/sherlock-cvg/contracts/Locking/LockingPositionDelegate.sol#L271-L282

Tool used

Manual Review

Recommendation

Change the maxMgDelegatees checking as follows:

@@ -279,7 +279,7 @@ contract LockingPositionDelegate is Initializable {
         require(_percentage <= 100, "INVALID_PERCENTAGE");
 
         uint256 _delegateesLength = delegatedMgCvg[_tokenId].length;
-        require(_delegateesLength < maxMgDelegatees, "TOO_MUCH_DELEGATEES");
+        require((_percentage > 0 && _delegateesLength < maxMgDelegatees) || (_percentage == 0 && _delegateesLength <= maxMgDelegatees), "TOO_MUCH_DELEGATEES");

Duplicate of #142

@github-actions github-actions bot closed this as completed Dec 2, 2023
@github-actions github-actions bot added Medium A valid Medium severity issue Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label labels Dec 2, 2023
@nevillehuang nevillehuang removed the Medium A valid Medium severity issue label Dec 22, 2023
@sherlock-admin2 sherlock-admin2 changed the title Keen Mulberry Hawk - A token owner cannot remove one mgCvg delegation when he already delegates to maxMgDelegatees addresses. ydlee - A token owner cannot remove one mgCvg delegation when he already delegates to maxMgDelegatees addresses. Dec 24, 2023
@sherlock-admin2 sherlock-admin2 added Non-Reward This issue will not receive a payout and removed Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label labels Dec 24, 2023
@Czar102 Czar102 added the Medium A valid Medium severity issue label Jan 12, 2024
@sherlock-admin sherlock-admin added Reward A payout will be made for this issue and removed Non-Reward This issue will not receive a payout labels Jan 12, 2024
@sherlock-admin2 sherlock-admin2 added the Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label label Jan 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue
Projects
None yet
Development

No branches or pull requests

4 participants