reinvestReward() generates dust totalPoolClaim causing vault abnormal
If the first user deposits too small , due to the round down, it may result in 0 shares, which will result in 0 shares no matter how much is deposited later. In `National`, this situation will be prevented by setting `a minimum borrow size and a minimum leverage ratio`. However, `reinvestReward()` does not have this restriction, which may cause this problem to still exist, causing the vault to enter an abnormal state.\\nThe calculation of the shares of the vault is as follows:\\n```\\n    function _mintVaultShares(uint256 lpTokens) internal returns (uint256 vaultShares) {\\n        StrategyVaultState memory state = VaultStorage.getStrategyVaultState();\\n        if (state.totalPoolClaim == 0) {\\n            // Vault Shares are in 8 decimal precision\\n          vaultShares = (lpTokens * uint256(Constants.INTERNAL_TOKEN_PRECISION)) / POOL_PRECISION();\\n        } else {\\n            vaultShares = (lpTokens * state.totalVaultSharesGlobal) / state.totalPoolClaim;\\n        }\\n\\n        // Updates internal storage here\\n        state.totalPoolClaim += lpTokens;\\n        state.totalVaultSharesGlobal += vaultShares.toUint80();\\n        state.setStrategyVaultState();\\n```\\n\\nIf the first `deposit` is too small, due to the conversion to `INTERNAL_TOKEN_PRECISION`, the precision is lost, resulting in `vaultShares=0`. Subsequent depositors will enter the second calculation, but `totalVaultSharesGlobal=0`, so `vaultShares` will always be `0`.\\nTo avoid this situation, `Notional` has restrictions.\\nhey guys, just to clarify some rounding issues stuff on vault shares and the precision loss. Notional will enforce a minimum borrow size and a minimum leverage ratio on users which will essentially force their initial deposits to be in excess of any dust amount. so we should not really see any tiny deposits that result in rounding down to zero vault shares. If there was rounding down to zero, the account will likely fail their collateral check as the vault shares act as collateral and the would have none. there is the possibility of a dust amount entering into depositFromNotional in a valid state, that would be due to an account "rolling" a position from one debt maturity to another. in this case, a small excess amount of deposit may come into the vault but the account would still be forced to be holding a sizeable position overall due to the minium borrow size.\\nin `reinvestReward()`, not this limit\\n```\\n    function reinvestReward(\\n        SingleSidedRewardTradeParams[] calldata trades,\\n        uint256 minPoolClaim\\n    ) external whenNotLocked onlyRole(REWARD_REINVESTMENT_ROLE) returns (\\n        address rewardToken,\\n        uint256 amountSold,\\n        uint256 poolClaimAmount\\n    ) {\\n        // Will revert if spot prices are not in line with the oracle values\\n        _checkPriceAndCalculateValue();\\n\\n        // Require one trade per token, if we do not want to buy any tokens at a\\n        // given index then the amount should be set to zero. This applies to pool\\n        // tokens like in the ComposableStablePool.\\n        require(trades.length == NUM_TOKENS());\\n        uint256[] memory amounts;\\n        (rewardToken, amountSold, amounts) = _executeRewardTrades(trades);\\n\\n        poolClaimAmount = _joinPoolAndStake(amounts, minPoolClaim);\\n\\n        // Increase LP token amount without minting additional vault shares\\n        StrategyVaultState memory state = VaultStorage.getStrategyVaultState();\\n      state.totalPoolClaim += poolClaimAmount;\\n        state.setStrategyVaultState();\\n\\n        emit RewardReinvested(rewardToken, amountSold, poolClaimAmount);\\n    }\\n```\\n\\nFrom the above code, we know that `reinvestReward()` will increase `totalPoolClaim`, but will not increase `totalVaultSharesGlobal`.\\nThis will cause problems in the following scenarios:\\nThe current vault has deposits.\\n`Rewards` have been generated, but `reinvestReward()` has not been executed.\\nThe `bot` submitted the `reinvestReward()` transaction. but step 4 execute first\\nThe users took away all the deposits `totalPoolClaim = 0`, `totalVaultSharesGlobal=0`.\\nAt this time `reinvestReward()` is executed, then `totalPoolClaim > 0`, `totalVaultSharesGlobal=0`.\\nOther users' deposits will fail later\\nIt is recommended that `reinvestReward()` add a judgment of `totalVaultSharesGlobal>0`.\\nNote: If there is a malicious REWARD_REINVESTMENT_ROLE, it can provoke this issue by donating reward token and triggering reinvestReward() before the first depositor appears.
```\\n    function reinvestReward(\\n        SingleSidedRewardTradeParams[] calldata trades,\\n        uint256 minPoolClaim\\n    ) external whenNotLocked onlyRole(REWARD_REINVESTMENT_ROLE) returns (\\n        address rewardToken,\\n        uint256 amountSold,\\n        uint256 poolClaimAmount\\n    ) {\\n        // Will revert if spot prices are not in line with the oracle values\\n        _checkPriceAndCalculateValue();\\n\\n        // Require one trade per token, if we do not want to buy any tokens at a\\n        // given index then the amount should be set to zero. This applies to pool\\n        // tokens like in the ComposableStablePool.\\n        require(trades.length == NUM_TOKENS());\\n        uint256[] memory amounts;\\n        (rewardToken, amountSold, amounts) = _executeRewardTrades(trades);\\n\\n        poolClaimAmount = _joinPoolAndStake(amounts, minPoolClaim);\\n\\n        // Increase LP token amount without minting additional vault shares\\n        StrategyVaultState memory state = VaultStorage.getStrategyVaultState();\\n// Add the line below\\n       require(state.totalVaultSharesGlobal > 0 ,"invalid shares");\\n        state.totalPoolClaim // Add the line below\\n= poolClaimAmount;\\n        state.setStrategyVaultState();\\n\\n        emit RewardReinvested(rewardToken, amountSold, poolClaimAmount);\\n    }\\n```\\n
reinvestReward() generates dust totalPoolClaim causing vault abnormal
```\\n    function _mintVaultShares(uint256 lpTokens) internal returns (uint256 vaultShares) {\\n        StrategyVaultState memory state = VaultStorage.getStrategyVaultState();\\n        if (state.totalPoolClaim == 0) {\\n            // Vault Shares are in 8 decimal precision\\n          vaultShares = (lpTokens * uint256(Constants.INTERNAL_TOKEN_PRECISION)) / POOL_PRECISION();\\n        } else {\\n            vaultShares = (lpTokens * state.totalVaultSharesGlobal) / state.totalPoolClaim;\\n        }\\n\\n        // Updates internal storage here\\n        state.totalPoolClaim += lpTokens;\\n        state.totalVaultSharesGlobal += vaultShares.toUint80();\\n        state.setStrategyVaultState();\\n```\\n