Diamond contains a delegatecall vulnerability in its fallback function. This vulnerability allows an attacker to execute arbitrary code within the context of the contract, potentially leading to unauthorized actions such as transferring ownership or draining funds, code:
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())
}
}
}
function forwards any call it receives to a corresponding facet using delegatecall. If an attacker can register a malicious facet, they can execute arbitrary code within the context of the Diamond contract.
Impact:
Unauthorized transfer of ownership.
Draining the contract of all its funds.
Arbitrary changes to the contract state.
Proof of concept
const diamond = await Diamond.new(ownerAddress);
Deploy Malicious Facet: Deploy a new facet contract with malicious code.
function exploit() external {
// Code to call back into the diamond contract to exploit delegatecall
diamond.call(abi.encodeWithSignature("functionToExploit()"));
}
}
const maliciousFacet = await MaliciousFacet.new(diamond.address);
Add Malicious Facet to Diamond: Use the diamondCut function to add the malicious facet to the Diamond.
const cut = [{
facetAddress: maliciousFacet.address,
action: 0, // Add
functionSelectors: [web3.utils.keccak256("exploit()").slice(0, 10)]
}];
await diamond.diamondCut(cut, address(0), "0x");
Execute Reentrancy: Call a function in the Diamond that the malicious facet can exploit to perform a reentrancy attack.
Unfortunately, after reviewing your report, Immunefi has decided to close it due to the assessed impact being out of scope.
Immunefi review:
The claimed impact "Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield" by the whitehat is in scope of the bug bounty program but the assessed impact doesn't match with the claimed impact for the following reasons.
If an attacker can register a malicious facet..
No evidence has been provided to show how an attacker can introduce a malicious facet.
assessed asset by the triage team is in scope for the bug bounty program
PoC has not been submitted to the project
Please note that the project will receive a report of the closed submission and may choose to re-open it, but they are not obligated to do so.