DeFiHardhatFoundry
250,000 USDC
View results
Submission Details
Severity: medium
Invalid

Diamond Storage Manipulation via Delegatecall

Vulnerability Details

The LibDiamond library implements the core functionality of the Diamond pattern, which uses a specific storage layout to manage upgradeable contracts. The key storage structure is defined as:

https://github.com/BeanstalkFarms/Beanstalk/blob/0acd470dca4f4ba5322808772293da6efc84462b/protocol/contracts/libraries/LibDiamond.sol#L222

struct DiamondStorage {
mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;
mapping(address => FacetFunctionSelectors) facetFunctionSelectors;
address[] facetAddresses;
mapping(bytes4 => bool) supportedInterfaces;
address contractOwner;
}

This storage is accessed using a specific storage position:

bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage");

The Diamond contract uses a fallback function that employs delegatecall:

fallback() external payable {
LibDiamond.DiamondStorage storage ds;
bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;
assembly {
ds.slot := position
}
address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;
require(facet != address(0), "Diamond: Function does not exist");
assembly {
calldatacopy(0, 0, calldatasize())
let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
returndatacopy(0, 0, returndatasize())
switch result
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}

Potential Exploit

A malicious actor with the ability to add or modify facets could:

  1. Create a facet with functions that directly manipulate the DiamondStorage structure.

  2. Use the diamondCut function to add this malicious facet.

  3. Call the malicious facet's function through the Diamond's fallback function.

For example, they could modify the selectorToFacetAndPosition mapping to point existing selectors to a malicious facet, effectively hijacking contract functionality.

Impact

The impact of this vulnerability is severe:

  • Complete control over contract upgradeability

  • Ability to redirect any function call to malicious code

  • Potential to lock the contract by corrupting the storage structure

This could lead to theft of funds, permanent loss of contract functionality, or complete control of the contract by the attacker.

Tools Used

Manual

Recommendations

  1. Implement strict access controls on the diamondCut function.

  2. Add invariant checks in the LibDiamond functions to ensure critical storage (like selectorToFacetAndPosition) isn't corrupted.

  3. Consider implementing a time-lock or multi-sig requirement for upgrades.

  4. Add functions to verify the integrity of the diamond storage after upgrades.

  5. Thoroughly audit any new facets before adding them to the diamond.

Updates

Lead Judging Commences

inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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