Summary
When reseeding the barn fertilizing
is set to true regardless of activeFertilizer
Relevant GitHub Links:
https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/main/protocol/contracts/beanstalk/init/reseed/L2/ReseedBarn.sol#L65
Vulnerability Details
When the barn is reseed, the state variable fertilizing
is set to true regardless of the activeFertilizer
.
function init(
Fertilizers[] calldata fertilizerIds,
uint256 activeFertilizer,
uint256 fertilizedIndex,
uint256 unfertilizedIndex,
uint128 bpf
) external {
Fertilizer fertilizer = new Fertilizer();
TransparentUpgradeableProxy fertilizerProxy = new TransparentUpgradeableProxy(
address(fertilizer),
address(this),
abi.encode(IFertilizer.init.selector)
);
mintFertilizers(Fertilizer(address(fertilizerProxy)), fertilizerIds);
s.sys.season.fertilizing = true;
s.sys.fert.activeFertilizer = activeFertilizer;
s.sys.fert.fertilizedIndex = fertilizedIndex;
s.sys.fert.unfertilizedIndex = unfertilizedIndex;
s.sys.fert.bpf = bpf;
}
The state variable fertilizing
represents if there is any activeFertilizer
that has been bought by any user. So if the init
function is called with 0 amount of activeFertilizer
, the fertilizing
boolean will be set to true and it can lead to unexpected results because there will be no activeFertilizer
in the system.
Impact
Low
Tools Used
Manual review
Recommendations
Set the fertilizing
variable depending on the activeFertilizer
passed in the function:
function init(
Fertilizers[] calldata fertilizerIds,
uint256 activeFertilizer,
uint256 fertilizedIndex,
uint256 unfertilizedIndex,
uint128 bpf
) external {
// deploy fertilizer implmentation.
Fertilizer fertilizer = new Fertilizer();
// deploy fertilizer proxy. Set owner to beanstalk.
TransparentUpgradeableProxy fertilizerProxy = new TransparentUpgradeableProxy(
address(fertilizer),
address(this),
abi.encode(IFertilizer.init.selector)
);
mintFertilizers(Fertilizer(address(fertilizerProxy)), fertilizerIds);
- s.sys.season.fertilizing = true;
+ if(activeFertilizer > 0) s.sys.season.fertilizing = true;
s.sys.fert.activeFertilizer = activeFertilizer;
s.sys.fert.fertilizedIndex = fertilizedIndex;
s.sys.fert.unfertilizedIndex = unfertilizedIndex;
s.sys.fert.bpf = bpf;
}