Basic Pink Barracuda
Medium
Eligible "TOP80" users for airdrop redemption, can simply wait till before the very end of the claimingTimeLeft
period
to avoid paying taxes on their airdrops.
In the AirdropTaxCollector.sol#_calculateClaimTaxAmount()
function, airdrop claim taxes are calculated based on the remaining time
(claimingTimeLeft) within the airdrop claiming period. This approach calculates a proportional tax
amount, where users are supposed to pay a decreasing tax as they delay their claim. However, due to integer
rounding behavior in Solidity, users who wait until the end of the claiming period can have their tax
amount reduced to zero.
Key calculations here: uint256 taxFee = $.maxChargeableTax.mulDiv(claimingTimeLeft, AIRDROP_CLAIMING_PERIOD_LENGTH); claimTaxAmount = claimerUsd0PPBalance.mulDiv(taxFee, BASIS_POINT_BASE);
Calculation Breakdown: In the tax calculation, if claimingTimeLeft becomes very low, taxFee may round down to zero due to the multiplication and division of relatively small integers. For instance:
10e3 * 3e1 / 15724800
results in zero when claimingTimeLeft approaches the end of the claiming period, thus nullifying the tax.
If maxChargeableTax = 10,000:
Which means it will take approx. 26 minutes before actual end, to reach zero tax.
But if the maxChargeableTax
is to change to less then BASIS_POINT_BASE
let's say half i.e. 5000
then the time to reach zero tax will be way higher.
Applying the same formula as above: 3,144 seconds which is around 52 minutes.
and for maxChargeableTax
= 1000, it will be approx 4.5 hours.
No response
No response
Rounding Effect: The default mulDiv() does not account for small decimal values, which in this case makes the taxFee zero when claimingTimeLeft is near zero. Consequently, users can avoid paying any tax by claiming at the very end of the claiming period.
Loss of tax revenue for the airdrop distribution contract, as malicious users can avoid paying taxes, giving them advantage over regular ones.
No response
Add a minimum tax threshold or consider adding Math.Rounding.Ceil
to the tax calculation to ensure that
users pay a minimum tax amount regardless of the remaining time in the claiming period.
- uint256 taxFee = $.maxChargeableTax.mulDiv(claimingTimeLeft, AIRDROP_CLAIMING_PERIOD_LENGTH);
+ uint256 taxFee = $.maxChargeableTax.mulDiv(claimingTimeLeft, AIRDROP_CLAIMING_PERIOD_LENGTH, Math.Rounding.Ceil);
By that if somebody wants to pay the tax around 1 hour before the airdrop, they will be encouraged to
wait till the end of the claiming period. And will be able to redeem their airdrop without paying/calling the
external function to pay the tax as the checks in AirdropDistribution.sol
will be sufficient since the claim
period has already passed.