Summary
ReseedSilo is used to migrate Silo deposits from EOA owners. It calculates Stalk associated with migrated deposits and sets it to account:
https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/df2dd129a878d16d4adc75049179ac0029d9a96b/protocol/contracts/beanstalk/init/reseed/L2/ReseedSilo.sol#L109-L180
function reseedSiloDeposit(SiloDeposits calldata siloDeposit) internal {
...
for (uint256 i; i < siloDeposit.siloDepositsAccount.length; i++) {
...
for (uint256 j; j < deposits.dd.length; j++) {
...
@> accountStalk += uint96(siloDeposit.stemTip - stem) * deposits.dd[j].bdv;
...
}
...
@> accountStalk += stalkIssuedPerBdv * totalBdvForAccount;
@> s.accts[deposits.accounts].stalk = accountStalk;
}
...
}
Problem is that it uses =
instaed of +=
in final statement. So value will be overriden in case account has deposits in multiple tokens:
function init(
SiloDeposits calldata beanDeposits,
SiloDeposits calldata beanEthDeposits,
SiloDeposits calldata beanWstEthDeposits,
SiloDeposits calldata bean3CrvDeposits,
SiloDeposits calldata urBeanDeposits,
SiloDeposits calldata urBeanLpDeposits
) external {
reseedSiloDeposit(beanDeposits);
reseedSiloDeposit(beanEthDeposits);
reseedSiloDeposit(beanWstEthDeposits);
reseedSiloDeposit(bean3CrvDeposits);
reseedSiloDeposit(urBeanDeposits);
reseedSiloDeposit(urBeanLpDeposits);
}
Impact
User will lose Stalk in case he has Silo deposit in multiple tokens.
Tools Used
Manual Review
Recommendations
- s.accts[deposits.accounts].stalk = accountStalk;
+ s.accts[deposits.accounts].stalk += accountStalk;