https://github.com/Cyfrin/2024-04-beanstalk-2/blob/27ff8c87c9164c1fbff054be5f22e56f86cdf127/protocol/contracts/libraries/Well/LibWell.sol#L87C5-L96C6
If all tokens in the tokens array are BEAN tokens, the if condition within the loop will always evaluate to false. As a result, the loop completes without ever hitting the return statement.
The function includes a loop that iterates over an array of token addresses, returning the first address (along with its index) that does not match the C.BEAN
address. However, the function fails to include a return statement outside of the conditional block inside the loop. This leads to potential undefined behavior in scenarios where all tokens match C.BEAN
inconsistent state management due to unexpected reverts might leave the contract in a half-updated state prior to transaction failure, complicating transaction and error handling logic across the system. eg. getTWALiquidityForWell function which calls the function getNonBeanTokenAndIndexFromWell will revert due to the incomplete return issue described.
Manual Review
-
- function getNonBeanTokenAndIndexFromWell(
address well
) internal view returns (address, uint256) {
IERC20[] memory tokens = IWell(well).tokens();
for (uint256 i; i < tokens.length; i++) {
if (address(tokens[i]) != C.BEAN) {
return (address(tokens[i]), i);
}
}
}`
+
function getNonBeanTokenAndIndexFromWell( address well ) internal view returns (address, uint256) { IERC20[] memory tokens = IWell(well).tokens(); for (uint256 i = 0; i < tokens.length; i++) { if (address(tokens[i]) != C.BEAN) { return (address(tokens[i]), i); } } // If no non-BEAN token is found, return a default value. return (address(0), 0); }
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.