Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rage quitter loses his claimable share of distributed tokens #22

Open
code423n4 opened this issue May 30, 2023 · 9 comments
Open

Rage quitter loses his claimable share of distributed tokens #22

code423n4 opened this issue May 30, 2023 · 9 comments
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue M-02 primary issue Highest quality submission among a set of duplicates satisfactory satisfies C4 submission criteria; eligible for awards selected for report This submission will be included/highlighted in the audit report sponsor acknowledged Technically the issue is correct, but we're not going to resolve it for XYZ reasons

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2023-05-party/blob/f6f80dde81d86e397ba4f3dedb561e23d58ec884/contracts/party/PartyGovernanceNFT.sol#L293-L353

Vulnerability details

Impact

Rage quitter loses his claimable share of distributed tokens.

Proof of Concept

PartyGovernanceNFT.rageQuit() burns a governance NFT and transfers its share of the balance of ETH and tokens:

// Burn caller's party card. This will revert if caller is not the owner
// of the card.
burn(tokenId);

// Withdraw fair share of tokens from the party.
IERC20 prevToken;
for (uint256 j; j < withdrawTokens.length; ++j) {
    IERC20 token = withdrawTokens[j];

    // Prevent null and duplicate transfers.
    if (prevToken >= token) revert InvalidTokenOrderError();

    prevToken = token;

    // Check if token is ETH.
    if (address(token) == ETH_ADDRESS) {
        // Transfer fair share of ETH to receiver.
        uint256 amount = (address(this).balance * shareOfVotingPower) / 1e18;
        if (amount != 0) {
            payable(receiver).transferEth(amount);
        }
    } else {
        // Transfer fair share of tokens to receiver.
        uint256 amount = (token.balanceOf(address(this)) * shareOfVotingPower) / 1e18;
        if (amount != 0) {
            token.compatTransfer(receiver, amount);
        }
    }
}

The problem with this is that the governance NFT might also have tokens to claim() in the TokenDistributor. These cannot be claimed after the governance NFT has been burned.
The rage quitter cannot completely protect himself from this by calling claim() first, because the tokens might not yet have been distributed to the TokenDistributor until in a frontrun call to distribute() just before his rageQuit(). This way the rage quitter might be robbed of his fair share.

Recommended Mitigation Steps

Have rageQuit() call TokenDistributor.claim() before the governance NFT is burned.

Assessed type

Context

@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels May 30, 2023
code423n4 added a commit that referenced this issue May 30, 2023
@thereksfour
Copy link

Similar issues are considered M in C4. Loss of funds requires external requirements (user misses call to claim() or frontrun occurs)
Also, since the claim() only allows NFT owner to call, consider transferring the user's NFT to the contract in rageQuit().

    function claim(
        DistributionInfo calldata info,
        uint256 partyTokenId
    ) public returns (uint128 amountClaimed) {
        // Caller must own the party token.
        {
            address ownerOfPartyToken = info.party.ownerOf(partyTokenId);
            if (msg.sender != ownerOfPartyToken) {
                revert MustOwnTokenError(msg.sender, ownerOfPartyToken, partyTokenId);
            }
        }

@c4-judge c4-judge added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value downgraded by judge Judge downgraded the risk level of this issue and removed 3 (High Risk) Assets can be stolen/lost/compromised directly labels May 31, 2023
@c4-judge
Copy link
Contributor

thereksfour changed the severity to 2 (Med Risk)

@c4-judge
Copy link
Contributor

thereksfour marked the issue as primary issue

@c4-judge c4-judge added the primary issue Highest quality submission among a set of duplicates label May 31, 2023
@c4-judge
Copy link
Contributor

thereksfour marked the issue as satisfactory

@c4-judge c4-judge added the satisfactory satisfies C4 submission criteria; eligible for awards label May 31, 2023
@c4-sponsor c4-sponsor added the sponsor acknowledged Technically the issue is correct, but we're not going to resolve it for XYZ reasons label Jun 1, 2023
@c4-sponsor
Copy link

0xble marked the issue as sponsor acknowledged

@0xble
Copy link

0xble commented Jun 1, 2023

We will warn users with unclaimed distributions on the frontend but will not make any code changes to enforce this.

@c4-judge
Copy link
Contributor

c4-judge commented Jun 2, 2023

thereksfour marked the issue as selected for report

@c4-judge c4-judge added the selected for report This submission will be included/highlighted in the audit report label Jun 2, 2023
@romeroadrian
Copy link

romeroadrian commented Jun 5, 2023

@thereksfour I think this issue should be more on the QA side as the sponsor clearly stated that rage quit may cause losses due to user inaction or mistake:

If a user intentionally or accidentally excludes a token in their ragequit, they forfeit that token and will not be able to claim it.

Similar to the described scenario, if a user forgets to call claim on the distributor before rage quit, they will lose their share of tokens.

@thereksfour
Copy link

In this issue, even if the user does not make any mistake, they may suffer a loss because there may be a potential frontrun attack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue M-02 primary issue Highest quality submission among a set of duplicates satisfactory satisfies C4 submission criteria; eligible for awards selected for report This submission will be included/highlighted in the audit report sponsor acknowledged Technically the issue is correct, but we're not going to resolve it for XYZ reasons
Projects
None yet
Development

No branches or pull requests

7 participants