Report ID
#33659
Report type
Smart Contract
Has PoC?
Yes
Target
https://etherscan.io/address/0xC1E088fC1323b20BCBee9bd1B9fC9546db5624C5
Impacts
- Permanent freezing of unclaimed yield
- Temporary freezing of funds for at least 1 hour
- Unbounded gas consumption
- Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
- Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
- Theft of gas
Description
Brief/Intro
The diamondCut function in the DiamondCutFacet.sol contract uses delegatecall to execute arbitrary code on a specified contract, which poses a significant risk. If the _init contract is compromised or not properly vetted, it can lead to unauthorized modifications of the diamond’s facets, potentially resulting in the theft of funds, permanent freezing of assets, or other critical issues. The DiamondLoupeFacet.sol contract, while primarily providing read-only functions, exposes facet information which could also be leveraged maliciously in conjunction with vulnerabilities in other contracts.
Vulnerability Details
The primary vulnerability lies in the use of delegatecall within the diamondCut function. delegatecall allows the _calldata to execute within the context of the current contract, which means that any unintended or malicious code could be run with the permissions of the DiamondCutFacet contract. If the _init contract or the _calldata is not thoroughly vetted and trusted, it can lead to severe security issues, including unauthorized changes to the diamond’s facets, which can have downstream effects on the contract's operations and user funds.
Key points
Access Control: While the function is protected by LibDiamond.enforceIsContractOwner(), which restricts its execution to the contract owner, this does not mitigate risks from a compromised or malicious _init contract.
Delegatecall Risks: The delegatecall executes arbitrary code which can exploit vulnerabilities if the code is not properly validated.
Reentrancy Risks: Although not explicitly addressed in the contract, delegatecall can interact with external contracts that may be vulnerable to reentrancy attacks.
Code snippet:
function diamondCut(
FacetCut[] calldata _diamondCut,
address _init,
bytes calldata _calldata
) external override {
LibDiamond.enforceIsContractOwner();
LibDiamond.diamondCut(_diamondCut, _init, _calldata);
}
In DiamondLoupeFacet.sol, the exposure of facet addresses and function selectors could facilitate targeted attacks or facilitate other forms of information leakage but does not directly exploit the delegatecall vulnerability.
Impact Details
Direct Theft of Any User Funds: Exploitation of the diamondCut function can lead to unauthorized changes in the contract's state or even theft of funds.
Permanent Freezing of Funds: Malicious modifications through delegatecall could lock or freeze user funds permanently if they are improperly handled.
Temporary Freezing of Funds: Exploits may also cause temporary issues, such as locking funds for a period of time.
Selected Impact:
Direct Theft of Any User Funds
Permanent Freezing of Funds
References
Diamond Standard (EIP-2535)
LibDiamond Implementation
DiamondCutFacet.sol Source (replace with actual address)
DiamondLoupeFacet.sol Source (replace with actual address)
Proof of concept
A Proof of Concept (PoC) for this vulnerability involves demonstrating how delegatecall can be misused to modify contract storage or steal funds. Here is a simplified example:
Deploy a malicious contract (MaliciousContract.sol):
pragma solidity ^0.7.6;
contract MaliciousContract {
address public diamondAddress;
}
Execute the Attack:
Call the attack() function on the MaliciousContract to exploit the vulnerability. Ensure to provide the PoC in a runnable format following the guidelines. If possible, demonstrate the exploit in a controlled test environment to validate the impact.