PartyGovernanceNFT#rageQuit()
can lead to token loss for users when dealing with zero-balance ERC20 during a rageQuit()
#237
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
edited-by-warden
insufficient quality report
This report is not of sufficient quality
M-05
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 confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Lines of code
https://github.com/code-423n4/2023-10-party/blob/b23c65d62a20921c709582b0b76b387f2bb9ebb5/contracts/party/PartyGovernanceNFT.sol#L426-L432
Vulnerability details
Impact
Calling Party's
rageQuit()
with a zero-balance ERC20 disregards theminWithdrawAmounts
array, resulting in the loss of user tokens without compensation.Proof of Concept
Consider the following scenario illustrating the issue:
USDC
tokens.USDC
balance is transferred to another account, e.g., via a proposal.USDC
holdings, attempts torageQuit()
.uint256[] minWithdrawAmounts
.minWithdrawAmounts
, all of Alice's Party tokens are burned, and she receives nothing in return.In
PartyGovernanceNFT#rageQuit()
the withdraw amount for each ERC20 is calculated as follows:where
However, if the token is an ERC20 for which the Party does not have any remaining balance,
withdrawAmounts[i]
would be equal to0
.This means the following check would not be executed at all:
Since the check for the minimum withdrawal amount is within the
if
statement, it is never executed whenamount
is equal to 0, leading to unintended NFT loss.uint96 totalVotingPowerBurned = _burnAndUpdateVotingPower(tokenIds, !isAuthority_); // Update total voting power of party. _getSharedProposalStorage().governanceValues.totalVotingPower -= totalVotingPowerBurned;
PoC:
Recommended Mitigation Steps
To ensure that the
BelowMinWithdrawAmountError
check is performed even whenamount
is equal to0
,amount > 0
must be replaced withamount >= 0
in therageQuit()
function. Here's the modified code snippet:Assessed type
Invalid Validation
The text was updated successfully, but these errors were encountered: