Summary
The _update function overrides the default ERC20 transfer logic to apply swap and burn taxes. However, there is a flaw in how the burn mechanism is implemented:
Vulnerability Details
Attack Vector: Improper Burn Mechanism
-
Incorrect Burn Destination
super._update(from, address(0), burnAmount);
This tries to send tokens to address(0), but ERC20 does not handle this as a valid burn.
This could result in tokens being permanently stuck, or worse, tokens not actually burning, which would break the tokenomics.
-
Whitelisted Addresses Can Bypass Taxes
If an attacker can get themselves whitelisted, they can send tokens tax-free and exploit the system.
There is no restriction preventing the owner from adding arbitrary addresses to the whitelist.
function _update(
address from,
address to,
uint256 amount
) internal virtual override {
uint256 baseTax = swapTaxRate + burnTaxRate;
if (baseTax == 0 || from == address(0) || to == address(0) || whitelistAddress[from] || whitelistAddress[to] || feeCollector == address(0)) {
super._update(from, to, amount);
return;
}
uint256 totalTax = amount.percentMul(baseTax);
uint256 burnAmount = totalTax * burnTaxRate / baseTax;
super._update(from, feeCollector, totalTax - burnAmount);
super._update(from, address(0), burnAmount);
super._update(from, to, amount - totalTax);
}
}
Impact
Tools Used
Recommendations
function _update(
address from,
address to,
uint256 amount
) internal virtual override {
uint256 baseTax = swapTaxRate + burnTaxRate;
if (baseTax == 0 || from == address(0) || to == address(0) || whitelistAddress[from] || whitelistAddress[to] || feeCollector == address(0)) {
super._update(from, to, amount);
return;
}
uint256 totalTax = amount.percentMul(baseTax);
uint256 burnAmount = totalTax * burnTaxRate / baseTax;
uint256 feeAmount = totalTax - burnAmount;
if (feeAmount > 0) {
super._update(from, feeCollector, feeAmount);
}
if (burnAmount > 0) {
_burn(from, burnAmount);
}
super._update(from, to, amount - totalTax);
}