function claimTokens() external {
if (!ended) {
revert AuctionNotYetEnded();
}
uint256 userBids = bids[msg.sender];
if (userBids == 0) {
revert NoTokensToClaim();
}
uint256 claimable = userBids.mul(multiplier).div(PRECISION_18);
bids[msg.sender] = 0;
auctionToken.transfer(msg.sender, claimable);
emit TokensClaimed(msg.sender, claimable);
}
These small amounts, although minor individually, can accumulate among different FjordAuction
s deployed over time and result in tokens being stuck in all the auction contracts.
function test_ClaimReward_DustLeft() public {
fjordStaking.stake(20 ether);
_addRewardAndEpochRollover(1 ether, 2);
vm.warp(vm.getBlockTimestamp() + fjordStaking.epochDuration() * 5);
address alice = makeAddr("alice");
deal(address(token), alice, 10000 ether);
vm.startPrank(alice);
fjordStaking.stake(30 ether);
vm.stopPrank();
vm.warp(vm.getBlockTimestamp() + fjordStaking.epochDuration() * 5);
_addRewardAndEpochRollover(1 ether, 2);
FjordPoints fpt = FjordPoints(points);
fpt.claimPoints();
vm.startPrank(alice);
fpt.claimPoints();
vm.stopPrank();
uint256 totalTokens = 1000 ether;
uint256 biddingTime = 1 weeks;
ERC20BurnableMock auctionToken = new ERC20BurnableMock("AuctionToken", "AUCT");
deal(address(auctionToken), alice, totalTokens);
vm.startPrank(alice);
AuctionFactory auctionFactory = new AuctionFactory(address(fpt));
auctionToken.approve(address(auctionFactory), totalTokens);
bytes32 salt = keccak256(abi.encodePacked(block.timestamp, msg.sender));
vm.recordLogs();
auctionFactory.createAuction(address(auctionToken), biddingTime, totalTokens, salt);
Vm.Log[] memory logs = vm.getRecordedLogs();
address auctionAddress;
for (uint256 i = 0; i < logs.length; i++) {
if (logs[i].topics[0] == keccak256("AuctionCreated(address)")) {
auctionAddress = address(uint160(uint256(logs[i].topics[1])));
}
}
FjordAuction fjordAuction = FjordAuction(auctionAddress);
fpt.approve(auctionAddress, fpt.balanceOf(alice));
fjordAuction.bid(fpt.balanceOf(alice));
vm.stopPrank();
fpt.approve(auctionAddress, fpt.balanceOf(address(this)));
fjordAuction.bid(fpt.balanceOf(address(this)));
skip(biddingTime);
fjordAuction.auctionEnd();
console.log("======================== DUST AMOUNT LEFT ========================");
fjordAuction.claimTokens();
vm.startPrank(alice);
fjordAuction.claimTokens();
vm.stopPrank();
console.log("auctionToken.balanceOf(auctionAddress) = ", auctionToken.balanceOf(auctionAddress));
}