Omniscia Beanstalk Audit
LibInternal Code Style Findings
LibInternal Code Style Findings
LIL-01C: Inefficient Function Signature Computation
Type | Severity | Location |
---|---|---|
Gas Optimization | LibInternal.sol:L53, L62, L71 |
Description:
The linked code computes the function selectors it requires on each function invocation redundantly.
Example:
protocol/contracts/libraries/LibInternal.sol
51function updateSilo(address account) internal {52 DiamondStorage storage ds = diamondStorage();53 bytes4 functionSelector = bytes4(keccak256("updateSilo(address)"));54 address facet = ds.selectorToFacetAndPosition[functionSelector].facetAddress;55 bytes memory myFunctionCall = abi.encodeWithSelector(functionSelector, account);56 (bool success,) = address(facet).delegatecall(myFunctionCall);57 require(success, "Silo: updateSilo failed.");58}59
60function updateBip(uint32 bip) internal {61 DiamondStorage storage ds = diamondStorage();62 bytes4 functionSelector = bytes4(keccak256("updateBip(uint32)"));63 address facet = ds.selectorToFacetAndPosition[functionSelector].facetAddress;64 bytes memory myFunctionCall = abi.encodeWithSelector(functionSelector, bip);65 (bool success,) = address(facet).delegatecall(myFunctionCall);66 require(success, "Silo: updateBip failed.");67}68
69function stalkFor(uint32 bip) internal returns (uint256 stalk) {70 DiamondStorage storage ds = diamondStorage();71 bytes4 functionSelector = bytes4(keccak256("stalkFor(uint32)"));72 address facet = ds.selectorToFacetAndPosition[functionSelector].facetAddress;73 bytes memory myFunctionCall = abi.encodeWithSelector(functionSelector, bip);74 (bool success, bytes memory data) = address(facet).delegatecall(myFunctionCall);75 require(success, "Governance: stalkFor failed.");76 assembly { stalk := mload(add(data, add(0x20, 0))) }77}
Recommendation:
We advise the pre-calculated function selectors to be utilised instead by using the standardised ContractInterface.functionName.selector
code representation and importing the relevant interfaces.
Alleviation:
The function selector is now properly accessed via the selector
member exposed by the function within the interface.