Proud Punch Mouse
Medium
In Airdrop, users who do not claim immediately after payTax
will pay the excess penalty amount.
Both payTaxAmount
and _computePenalty
are calculated according to the current time, so as to avoid double payment (Tax and Penalty).
However, there is a case where the user payTaxAmount
does not execute the claim
immediately, but executes it one or more months later, so that the user with monthsPassed > 0
will double pay the tax and Penalty.
It's possible, and it's not the user's fault, the user has the right to decide when to claim the token(within the validity period).
function _computePenalty(
AirdropDistributionStorageV0 storage $,
uint256 totalAmount,
address account,
uint256 monthsPassed
) internal returns (uint256) {
uint256 penaltyAmount = 0;
uint256 oneSixthAmount = totalAmount.mulDiv(1, AIRDROP_VESTING_DURATION_IN_MONTHS, Math.Rounding.Ceil);
for (uint256 i = 1; i <= monthsPassed; i++) {
if ($.penaltyPercentageByMonth[account][i] == 0) {
continue;
} else if ($.penaltyPercentageByMonth[account][i] == BASIS_POINT_BASE) { //BASIS_POINT_BASE = 10_000;
penaltyAmount += oneSixthAmount;
} else {
uint256 monthlyPenalty = oneSixthAmount.mulDiv($.penaltyPercentageByMonth[account][i], BASIS_POINT_BASE);
penaltyAmount += monthlyPenalty;
}
$.penaltyPercentageByMonth[account][i] = 0;
}
return penaltyAmount;
}
function _payTaxAmount(address account) internal {
AirdropTaxCollectorStorage storage $ = _airdropTaxCollectorStorage();
bool isBeforeStartDate = block.timestamp < AIRDROP_INITIAL_START_TIME;
bool isAfterEndDate = block.timestamp > AIRDROP_INITIAL_START_TIME + AIRDROP_CLAIMING_PERIOD_LENGTH;
if (isBeforeStartDate || isAfterEndDate) {
revert NotInClaimingPeriod();
}
if ($.taxedClaimers[account]) {
revert ClaimerHasPaidTax();
}
// Check if the account hasn't voided it's eligibility for airdrop
IAirdropDistribution airdropContract = IAirdropDistribution($.registryContract.getContract(CONTRACT_AIRDROP_DISTRIBUTION));
if (airdropContract.getRagequitStatus(account)) {
revert AirdropVoided();
}
uint256 claimTaxAmount = _calculateClaimTaxAmount($, account);
$.taxedClaimers[account] = true;
$.usd0PP.setBondEarlyUnlockDisabled(account);
emit AirdropTaxPaid(account, claimTaxAmount);
$.usd0PP.safeTransferFrom(account, $.treasury, claimTaxAmount);
}
No response
No response
- The user pays tax on month 0.
- The user does not claim the token at month 0, but calls the claim 6 months later.
- The user has paid the excess penalty amount.
- This is not the user's fault, the user has the right to decide when to claim the token(within the validity period)
Loss of user funds
No response
Calculate the amount of the penalty based on the time of payTax instead of the current time.