Report ID
#32092
Report type
Smart Contract
Has PoC?
Yes
Target
https://etherscan.io/address/0xC1E088fC1323b20BCBee9bd1B9fC9546db5624C5
Impacts
Permanent freezing of unclaimed yield
Description
If user has not mown since germination, they'll lose their portion of plenty
After a user deposits, they have to wait 2 seasons until their deposit germinates (until they receive their stalk and roots). Currently, if the user hasn't mown since germination, their roots will be included in the sum of all roots that should receive plenty, although that's only on paper and they won't realistically be able to claim any of these funds.
When a user deposits, LibSilo.mintGerminatingStalk is called which adds the necessary stalk to the global accounting of unclaimedGerminating.
Then, when the actual germinating season comes, the global stalk and roots accounting is increased by these values
Then, when a new raining season starts, this global accounting value is used to determine the total amount of roots to distribute the rewards to:
Hence, we've just shown that although these roots are not claimed to the user, they're included in the total allocation of sop.
Now, if we look at the code of _mow, we'll see that first handleRainAndSops is called and then LibGerminate.endAccountGermination.
Since handleRainAndSops calculates the plenty user should get based on their roots and LibGerminate.endAccountGermination is the function which actually gives the user their roots, because of the order of the functions, in case the user hasn't mown since germination, user will not get the plenty they should get.
Impact Details
If user hasn't mown since germination, they'll lose all of the sop rewards that they should be getting. It's very likely that users will not mow immediately upon germination, so losses are extremely likely for new depositors.
References
Add any relevant links to documentation or code
Proof of concept
I've used the provided Foundry test suite for the currently audited code. Although there are some differences in the code, the mentioned part is the exact same, hence the issue is present in both the live code and the undeployed one.
The two test cases demonstrate that depending on whether the user has mown since germination they receive plenty or not
Add the tests to Flood.t.sol