As reward for staking in Silo users receive 2 currencies: Stalk and Roots. Stalk is governance token and Roots is some form of future Beans.
L2ContractMigrationFacet.sol is used to migrate Silo deposits to L2 and not forfeit users' previous rewards. Merkle root is used to verify that deposits provided by user are valid. Worth noting is that user migrates deposits by himself, so it can't be calculated in advance which user in which time will migrate.
For this reason grown Stalk is calculated to current moment, i.e. from deposit start to current cumulated value:
https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/df2dd129a878d16d4adc75049179ac0029d9a96b/protocol/contracts/beanstalk/silo/L2ContractMigrationFacet.sol#L176
As you understood accountStalk
increases with time. Problem is that Roots have the same logic, but it is hardcoded for each user. So Roots doesn't increase before migration is executed by user.
As a result, users lose accrued Roots from yet-not-migrated deposits because Roots is hardcoded.
Here you can see that Roots value is strictly written in Merkle root and can grow with time:
Here you can read that roots reward to user increases with time:
https://docs.bean.money/developers/misc/faq#what-are-roots
And here is how it is done currently in Beanstalk:
https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/df2dd129a878d16d4adc75049179ac0029d9a96b/protocol/contracts/libraries/Silo/LibSilo.sol#L161-L200
Users lose accrued Roots from yet-not-migrated deposits.
Manual Review
Develop a way to correctly migrate Roots which is not sensitive to migration time.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.