The RAACToken contract collects fees on all token burns, including those made by the FeeCollector during reward distribution. This causes less tokens than allocated to be burnt as a portion is taken as fees and sent back to the FeeCollector.
The issue occurs because RAACToken's `burn` function applies fees to all burns without exempting the FeeCollector.
pragma solidity ^0.8.19;
import {FeeCollector} from "../../../../contracts/core/collectors/FeeCollector.sol";
import {RAACToken} from "../../../../contracts/core/tokens/RAACToken.sol";
import {veRAACToken} from "../../../../contracts/core/tokens/veRAACToken.sol";
import {Test, console} from "forge-std/Test.sol";
contract TestSuite is Test {
FeeCollector feeCollector;
RAACToken raacToken;
veRAACToken veRAACTok;
address treasury;
address repairFund;
address admin;
uint256 initialSwapTaxRate = 100;
uint256 initialBurnTaxRate = 50;
function setUp() public {
treasury = makeAddr("treasury");
repairFund = makeAddr("repairFund");
admin = makeAddr("admin");
raacToken = new RAACToken(admin, initialSwapTaxRate, initialBurnTaxRate);
veRAACTok = new veRAACToken(address(raacToken));
feeCollector = new FeeCollector(address(raacToken), address(veRAACTok), treasury, repairFund, admin);
vm.startPrank(admin);
raacToken.setFeeCollector(address(feeCollector));
raacToken.setMinter(admin);
vm.stopPrank();
}
function testFeeCollectorBurnTokensNeverCompletelyBurnt() public {
uint256 amount = 1e18;
vm.startPrank(admin);
raacToken.mint(address(feeCollector), amount);
vm.stopPrank();
vm.startPrank(address(feeCollector));
raacToken.burn(amount);
vm.stopPrank();
uint256 balanceAfterBurn = raacToken.balanceOf(address(feeCollector));
console.log("Balance of feeCollector after burn: ", balanceAfterBurn);
assertGt(balanceAfterBurn, 0);
}
}
Burn allocation never fully burnt as fee collection causes tokens to always remain in the FeeCollector.