DeFiHardhatFoundry
250,000 USDC
View results
Submission Details
Severity: high
Invalid

Ship function of LibShipping.sol doesn't work as expected.

Summary

Ship function of LibShipping.sol doesn't work as expected.

Vulnerability Details

Ship() function uses getBeansFromPoints() function:

function ship(uint256 beansToShip) public {
AppStorage storage s = LibAppStorage.diamondStorage();
uint256 remainingBeansToShip = beansToShip;
ShipmentRoute[] memory shipmentRoutes = s.sys.shipmentRoutes;
ShipmentPlan[] memory shipmentPlans = new ShipmentPlan[](shipmentRoutes.length);
uint256[] memory shipmentAmounts = new uint256[](shipmentRoutes.length);
uint256 totalPoints;
(shipmentPlans, totalPoints) = getShipmentPlans(shipmentRoutes);
// May need to calculate individual stream rewards multiple times, since
// they are dependent on each others caps. Once a cap is reached, excess Beans are
// spread to other streams, proportional to their points.
for (uint256 i; i < shipmentRoutes.length; i++) {
bool capExceeded;
// Calculate the amount of rewards to each stream. Ignores cap and plans with 0 points.
getBeansFromPoints(
shipmentAmounts,
shipmentPlans,
totalPoints,
remainingBeansToShip
);
...
}

getBeansFromPoints() function is implemented as:

function getBeansFromPoints(
uint256[] memory shipmentAmounts,
ShipmentPlan[] memory shipmentPlans,
uint256 totalPoints,
uint256 beansToShip
) public pure {
for (uint256 i; i < shipmentPlans.length; i++) {
// Do not modify amount for streams with 0 points. They either are zero or have already been set.
if (shipmentPlans[i].points == 0) continue;
shipmentAmounts[i] = (beansToShip * shipmentPlans[i].points) / totalPoints; // round down
}
}

The problem is getBeansFromPoints() function doesn't return anything and it just updates the input memory arrays. This does nothing as in the ship() function, getBeansFromPoints(shipmentAmounts, shipmentPlans, totalPoints, remainingBeansToShip); doesn't reference anything. Thus nothing gets updated in the ship() function.

Impact

shipmentsAmounts[] doesn't get updated and will be 0. Thus, the ship() function won't work as expected and may revert which is a major problem as this is the only function to distribute beans across all active shipping routes.

Tools Used

Manual Analysis

Relevant Links

https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/4e0ad0b964f74a1b4880114f4dd5b339bc69cd3e/protocol/contracts/libraries/LibShipping.sol#L45

Recommendations

Return shipmentAmounts memory in getBeansFromPoints() function and use that return value in ship() function.

Updates

Lead Judging Commences

inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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