DeFiHardhatOracleProxyUpdates
100,000 USDC
View results
Submission Details
Severity: low
Invalid

Reentrancy Attack on SiloFacet::claimPlenty

Summary

when you call SiloFacet::claimPlenty function will call other function which is import from the Silo::_claimPlenty but if you check those function it transfer token to the account then it update the storage.

Vulnerability Details

Reentrancy Attack it you look closely the function Silo::_claimPlenty it call sopToken.safeTransfer then it delete the storage user can make other call an get more fund from it because it not check the plenty of address is > zero and also it delete after transfer.

/**
* @dev Gas optimization: An account can call `{SiloFacet:claimPlenty}` even
* if `s.a[account].sop.plenty == 0`. This would emit a ClaimPlenty event
* with an amount of 0.
*/
function _claimPlenty(address account) internal {
// Plenty is earned in the form of the sop token.
@> uint256 plenty = s.a[account].sop.plenty;
IWell well = IWell(s.sopWell);
IERC20[] memory tokens = well.tokens();
IERC20 sopToken = tokens[0] != C.bean() ? tokens[0] : tokens[1];
sopToken.safeTransfer(account, plenty);
@> delete s.a[account].sop.plenty;
emit ClaimPlenty(account, address(sopToken), plenty);
}
"description": "Reentrancy in Silo._claimPlenty(address) (contracts/beanstalk/silo/SiloFacet/Silo.sol#154-164):\n\tExternal calls:\n\t- sopToken.safeTransfer(account,plenty) (contracts/beanstalk/silo/SiloFacet/Silo.sol#160)\n\tState variables written after the call(s):\n\t- delete s.a[account].sop.plenty (contracts/beanstalk/silo/SiloFacet/Silo.sol#161)\n",
"markdown": "Reentrancy in [Silo._claimPlenty(address)](contracts/beanstalk/silo/SiloFacet/Silo.sol#L154-L164):\n\tExternal calls:\n\t- [sopToken.safeTransfer(account,plenty)](contracts/beanstalk/silo/SiloFacet/Silo.sol#L160)\n\tState variables written after the call(s):\n\t- [delete s.a[account].sop.plenty](contracts/beanstalk/silo/SiloFacet/Silo.sol#L161)\n",
"first_markdown_element": "contracts/beanstalk/silo/SiloFacet/Silo.sol#L154-L164",
"id": "4dbd56b6b33173000ad84687d65d9177a0ce83b578ae9abf20102990fe8648e1",
"check": "reentrancy-no-eth",
"impact": "Medium",
"confidence": "Medium"

Impact

Lose fund by Attacker call this function again and again.

Tools Used

Manual Review.

Recommendations

Delete storage before transfer and add check plenty > 0 to not waste gas try to transfer zero amount.

/**
* @dev Gas optimization: An account can call `{SiloFacet:claimPlenty}` even
* if `s.a[account].sop.plenty == 0`. This would emit a ClaimPlenty event
* with an amount of 0.
*/
function _claimPlenty(address account) internal {
// Plenty is earned in the form of the sop token.
uint256 plenty = s.a[account].sop.plenty;
+ required(plenty>0,"No plenty AMount");
IWell well = IWell(s.sopWell);
IERC20[] memory tokens = well.tokens();
IERC20 sopToken = tokens[0] != C.bean() ? tokens[0] : tokens[1];
+ delete s.a[account].sop.plenty;
sopToken.safeTransfer(account, plenty);
- delete s.a[account].sop.plenty;
// q: based in descritopn event will only called when plenty==0 but i didn't see any check
emit ClaimPlenty(account, address(sopToken), plenty);
}
Updates

Lead Judging Commences

giovannidisiena Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Too generic
Assigned finding tags:

Informational/Invalid

Re-entrancy

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.