Summary
The use of low-level calls is error-prone. Low-level calls do not check for code existence or call success.
Vulnerability Details
File: contracts/libraries/Silo/LibWhitelist.sol
Low level call in LibWhitelist.verifyGaugePointSelector(bytes4) (contracts/libraries/Silo/LibWhitelist.sol#234-238):
- (success) = address(this).staticcall(abi.encodeWithSelector(selector,0,0,0)) (contracts/libraries/Silo/LibWhitelist.sol#236)
L#236,
234: function verifyGaugePointSelector(bytes4 selector) internal view {
235:
236: (bool success, ) = address(this).staticcall(abi.encodeWithSelector(selector, 0, 0, 0));
237: require(success, "Whitelist: Invalid GaugePoint selector");
238: }
GitHub : 234-238
File: contracts/libraries/LibGauge.sol
Low level call in LibGauge.calcGaugePoints(bytes4,uint256,uint256,uint256) (contracts/libraries/LibGauge.sol#185-207):
- (success,data) = address(this).staticcall(callData) (contracts/libraries/LibGauge.sol#197)
L#197,
185: function calcGaugePoints(
186: bytes4 gpSelector,
187: uint256 gaugePoints,
188: uint256 optimalPercentDepositedBdv,
189: uint256 percentDepositedBdv
190: ) internal view returns (uint256 newGaugePoints) {
191: bytes memory callData = abi.encodeWithSelector(
192: gpSelector,
193: gaugePoints,
194: optimalPercentDepositedBdv,
195: percentDepositedBdv
196: );
197: (bool success, bytes memory data) = address(this).staticcall(callData);
198: if (!success) {
199: if (data.length == 0) revert();
200: assembly {
201: revert(add(32, data), mload(data))
202: }
203: }
204: assembly {
205: newGaugePoints := mload(add(data, add(0x20, 0)))
206: }
207: }
GitHub : 185-207
File: contracts/libraries/LibEvaluate.sol
Low level call in LibEvaluate.getLiquidityWeight(bytes4) (contracts/libraries/LibEvaluate.sol#328-339):
- (success,data) = address(this).staticcall(callData) (contracts/libraries/LibEvaluate.sol#332)
L#332,
328: function getLiquidityWeight(
329: bytes4 lwSelector
330: ) internal view returns (uint256 liquidityWeight) {
331: bytes memory callData = abi.encodeWithSelector(lwSelector);
332: (bool success, bytes memory data) = address(this).staticcall(callData);
333: if (!success) {
334: return 0;
335: }
336: assembly {
337: liquidityWeight := mload(add(data, add(0x20, 0)))
338: }
339: }
GitHub : 328-339
File: contracts/libraries/Silo/LibTokenSilo.sol
Low level call in LibTokenSilo.beanDenominatedValue(address,uint256) (contracts/libraries/Silo/LibTokenSilo.sol#437-458):
- (success,data) = address(this).staticcall(encodeBdvFunction(token,s.ss[token].encodeType,s.ss[token].selector,amount)) (contracts/libraries/Silo/LibTokenSilo.sol#444-446)
L#444-446,
437: function beanDenominatedValue(
438: address token,
439: uint256 amount
440: ) internal view returns (uint256 bdv) {
441: AppStorage storage s = LibAppStorage.diamondStorage();
442: require(s.ss[token].selector != bytes4(0), "Silo: Token not whitelisted");
443:
444: (bool success, bytes memory data) = address(this).staticcall(
445: encodeBdvFunction(token, s.ss[token].encodeType, s.ss[token].selector, amount)
446: );
447:
448: if (!success) {
449: if (data.length == 0) revert();
450: assembly {
451: revert(add(32, data), mload(data))
452: }
453: }
454:
455: assembly {
456: bdv := mload(add(data, add(0x20, 0)))
457: }
458: }
GitHub : 437-458
File: contracts/libraries/Silo/LibWhitelist.sol
Low level call in LibWhitelist.verifyLiquidityWeightSelector(bytes4) (contracts/libraries/Silo/LibWhitelist.sol#243-247):
- (success) = address(this).staticcall(abi.encodeWithSelector(selector)) (contracts/libraries/Silo/LibWhitelist.sol#245)
L#245,
243: function verifyLiquidityWeightSelector(bytes4 selector) internal view {
244:
245: (bool success, ) = address(this).staticcall(abi.encodeWithSelector(selector));
246: require(success, "Whitelist: Invalid LiquidityWeight selector");
247: }
GitHub : 243-247
Impact
possible loss of funds or calls to unintended addresses.
Tools Used
Manual Review
Recommendations
Avoid low-level calls. Check the call success. If the call is meant for a contract, check for code existence.