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 about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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