Smart contract unable to operate due to lack of token funds
Description
Brief/Intro
When distributing yields, the total effective supply is used to determine the share that each person gets based on their balance. This supply is calculated every time distributeYieldWithLimit is called. The total effective supply increases when more tokens are minted, and since the Arc token is mintable, there is a chance that this will occur.
Vulnerability Details
Assuming that there are 10 holders, all holding 100 tokens each.
The admin distributes 100 yield to the first 5 token holders; they will each get 10 yield tokens. The next step will be to distribute the remaining 50 tokens to the remaining 5 token holders. This will work perfectly on a normal day; however, if the token total supply increases before the second batch is distributed, then the distribution will fail due to insufficient balance in the contract, and the remaining reward per holder will be diluted.
Relevant snippet:
Note: The Arc token admin/minter can be anyone, including a smart contract that controls the minting of tokens; they are not necessarily protocol admins.
Impact Details
Rewards will be temporarily stuck as the distributeYieldWithLimit function will fail on subsequent batches.
function test_POC2() public {
for (uint160 i = 2; i <= 10; i++) {
token.transfer(address(i), 100e18); // Transfer 0.1 ARC to each address
}
// Approve and distribute yield
yieldToken.approve(address(token), YIELD_AMOUNT);
token.distributeYieldWithLimit(YIELD_AMOUNT, 0, 5);
// Mint to address 6
token.mint(address(6), 100e18);
token.distributeYieldWithLimit(YIELD_AMOUNT, 5, 10);
}
Encountered 1 failing test in test/ArcToken.t.sol:ArcTokenTest
[FAIL: ERC20InsufficientBalance(0xc7183455a4C133Ae270771860664b6B7ec320bB1, 45454545454545454549 [4.545e19], 90909090909090909090 [9.09e19])] test_POC2() (gas: 1192212)