function claimRewards() external {
@> ITokenManager.Token[] memory _tokens = ITokenManager(tokenManager).getAcceptedTokens();
for (uint256 i = 0; i < _tokens.length; i++) {
ITokenManager.Token memory _token = _tokens[i];
uint256 _rewardAmount = rewards[abi.encodePacked(msg.sender, _token.symbol)];
if (_rewardAmount > 0) {
delete rewards[abi.encodePacked(msg.sender, _token.symbol)];
if (_token.addr == address(0)) {
(bool _sent,) = payable(msg.sender).call{value: _rewardAmount}("");
require(_sent);
} else {
IERC20(_token.addr).transfer(msg.sender, _rewardAmount);
}
}
}
}
Stakers will lose unclaimed rewards for removed tokens.
function test_rewardsCannotBeClaimedFroRemovedTokensInLiquidationPool() public {
uint amount = 1000 ether;
tokens.eurosToken.mint(alice, amount);
tokens.tstToken.mint(alice, amount);
vm.startPrank(alice);
tokens.eurosToken.approve(address(contracts.liquidationPool), amount);
tokens.tstToken.approve(address(contracts.liquidationPool), amount);
contracts.liquidationPool.increasePosition(amount, amount);
vm.stopPrank();
(LiquidationPool.Position memory alicePosition, LiquidationPool.Reward[] memory rewards) =
contracts.liquidationPool.position(alice);
assertEq(alicePosition.EUROs, amount, "Alice's euros amount are not eqaul");
assertEq(alicePosition.TST, amount, "Alice's tst amount are not equal");
skip(block.timestamp + 1 weeks);
tokens.arbToken.mint(address(contracts.liquidationPoolManager), amount);
tokens.paxgToken.mint(address(contracts.liquidationPoolManager), amount);
vm.startPrank(address(contracts.liquidationPoolManager));
tokens.arbToken.approve(address(contracts.liquidationPool), amount);
tokens.paxgToken.approve(address(contracts.liquidationPool), amount);
vm.stopPrank();
ILiquidationPoolManager.Asset[1] memory _assets;
_assets[0] = ILiquidationPoolManager.Asset(
ITokenManager.Token({
symbol: 'ARB',
addr: address(tokens.arbToken),
dec: 18,
clAddr: address(priceFeeds.arbUsdPriceFeed),
clDec: 8
}),
amount
);
assets.push(_assets[0]);
console2.log("> Alice's ARB tokens Balance before Distributing Rewards: %s\n", tokens.arbToken.balanceOf(alice));
vm.startPrank(address(contracts.liquidationPoolManager));
contracts.liquidationPool.distributeAssets(assets, uint(constants.DEFAULT_COLLATERAL_RATE), 100_000);
vm.stopPrank();
(alicePosition, rewards) = contracts.liquidationPool.position(alice);
bool hasRewards;
console2.log("> Alice's Rewards After liquidation: ");
for (uint i; i < rewards.length; i++) {
if (rewards[i].amount > 0) {
console2.log('\tToken: %s', string(abi.encode(rewards[i].symbol)));
console2.log('\tReward Earned: %s\n', rewards[i].amount);
hasRewards = true;
}
}
require(hasRewards, 'No rewards are earned by the staker');
assertEq(alicePosition.EUROs, 0, 'Alice still has EUROs left');
contracts.tokenManager.removeAcceptedToken(bytes32('ARB'));
(alicePosition, rewards) = contracts.liquidationPool.position(alice);
console2.log("> Alice's Rewards After ARB Token Removal:");
hasRewards = false;
for (uint i; i < rewards.length; i++) {
if (rewards[i].amount > 0) {
console2.log("\tToken: %s", string(abi.encode(rewards[i].symbol)));
console2.log('\tReward Earned: %s', rewards[i].amount);
hasRewards = true;
}
}
require(!hasRewards, 'No rewards are earned by the staker');
if (!hasRewards) {
console2.log('\tThere are No rewards for the staker\n');
}
vm.startPrank(alice);
contracts.liquidationPool.claimRewards();
vm.stopPrank();
console2.log("> Alice's ARB tokens Balance After Distributing Rewards And Claiming: %s", tokens.arbToken.balanceOf(alice));
assertEq(tokens.arbToken.balanceOf(alice), 0, "There are ARBs token in Alice's account");
}
$ forge test --mt test_rewardsCannotBeClaimedFroRemovedTokensInLiquidationPool -vv
[⠢] Compiling...
No files changed, compilation skipped
Running 1 test for test/unit/Unit.t.sol:Unit
[PASS] test_rewardsCannotBeClaimedFroRemovedTokensInLiquidationPool() (gas: 813307)
Logs:
> Alice's ARB tokens Balance before Distributing Rewards: 0
> Alice's Rewards After liquidation:
Token: ARB
Reward Earned: 779505882352941176471
> Alice's Rewards After ARB Token Removal:
There are No rewards for the staker
> Alice's ARB tokens Balance After Distributing Rewards And Claiming: 0
Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 4.16ms
Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests)
+ function claimAsset(address token, bytes32 symbol) external {
+ uint256 _rewardAmount = rewards[abi.encodePacked(msg.sender, _token.symbol)];
+ if (_rewardAmount > 0) {
+ delete rewards[abi.encodePacked(msg.sender, symbol)];
+ IERC20(_token.addr).transfer(msg.sender, _rewardAmount);
+ }
+ }
+ function claimNative() external {
+ uint256 _rewardAmount = rewards[abi.encodePacked(msg.sender, NATIVE)];
+ if (_rewardAmount > 0) {
+ delete rewards[abi.encodePacked(msg.sender, symbol)];
+ (bool _sent,) = payable(msg.sender).call{value: _rewardAmount}("");
+ require(_sent);
+ }
+ }