Summary
When whitelisting a new token through LibWhitelist.whitelistToken
, the verifyBDVselector
is called to check whether the selector for the token to be whitelisted is valid.
The issue is that this check only verifies whether the encodeType and not the selector itself.
(bool success, ) = address(this).staticcall(
LibTokenSilo.encodeBdvFunction(token, encodeType, selector, 0)
);
require(success, "Whitelist: Invalid BDV selector");
}
function encodeBdvFunction(
address token,
bytes1 encodeType,
bytes4 selector,
uint256 amount
) internal pure returns (bytes memory callData) {
if (encodeType == 0x00) {
callData = abi.encodeWithSelector(selector, amount);
} else if (encodeType == 0x01) {
callData = abi.encodeWithSelector(selector, token, amount);
} else {
revert("Silo: Invalid encodeType");
}
}
Vulnerability Details
A wrong method can be set as a selector and bypass the check added as long as the method with the same number/type of parameters is set. i.e: LibTokenSilo.toInt96(uint256 value)
contains 1 parameter with uint256, therefore it would be accepted as a valid method for the verifyBDVselector
.
When in fact, currently, the selector should be the methods from the BDVFacet
i.e: beanToBDV
, unripeLPToBDV
, wellBdv
, etc.
Impact
Whitelisted tokens will have the wrong selector for the bdv function. This leads the protocol to calculate the bdv incorrectly for that token.
Tools Used
Manual Review
Recommendations
A whitelist of selectors or a specific selector should be used to check whether that selector is valid or not.
function verifyBDVselector(address token, bytes1 encodeType, bytes4 selector) internal view {
+ // Define a whitelist of valid BDV calculation selectors.
+ // This could be dynamic and added through the WhitelistFacet to avoid further deployments
+ // When changes need to be made on the list of valid BDVs selectors.
+ bytes4[2] memory validSelectors = [
+ IBDVFacet.beanToBDV.selector,
+ IBDVFacet.unripeLPToBDV.selector,
+ IBDVFacet.wellBdv.selector,
+ // etc
+ ];
+
+ // Check if the provided selector is in the whitelist
+ bool isValidSelector = false;
+ for (uint i = 0; i < validSelectors.length; i++) {
+ if (selector == validSelectors[i]) {
+ isValidSelector = true;
+ break;
+ }
+ }
+
+ require(isValidSelector, "Whitelist: Invalid BDV selector");
(bool success, ) = address(this).staticcall(
LibTokenSilo.encodeBdvFunction(token, encodeType, selector, 0)
);
- require(success, "Whitelist: Invalid BDV selector");
+ require(success, "Whitelist: Invalid encodeType");
}