Ability for an unauthorized entity to replace or remove functions from the diamond contract.
Report ID
#31701
Report type
Smart Contract
Has PoC?
Yes
Target
https://etherscan.io/address/0xc1e088fc1323b20bcbee9bd1b9fc9546db5624c5#code
(Out of scope)
Impacts
- Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Description
The vulnerability in the provided code allows unauthorized entities to add, replace, or remove functions within the diamond contract without proper access controls. If exploited on production/mainnet, attackers could gain control over critical functions, potentially leading to the theft of funds or disruption of the contract's intended functionality. This could result in financial losses for users and damage to the reputation of the affected project or platform.
Vulnerability Details
The vulnerability in the provided code lies in the lack of proper access controls in several critical functions, including addDiamondFunctions, diamondCut, addFunctions, replaceFunctions, and removeFunctions. These functions are intended to manage the diamond contract's functionality by adding, replacing, or removing functions within different facets of the contract. However, they do not enforce any access control mechanism to verify the authority of the caller. Consequently, any external account or contract can invoke these functions, potentially leading to unauthorized modifications of the diamond contract's behavior.
Let's delve into the specific functions:
addDiamondFunctions: This function is internally called during the diamond contract's deployment to add essential facets such as diamond cut, loupe, and ownership. However, it does not verify whether the caller has the necessary permissions to execute this action. An attacker could exploit this by deploying a contract that maliciously adds their own facet, giving them unauthorized control over the contract.
diamondCut: This function is crucial for modifying the diamond's facets by adding, replacing, or removing functions. Again, it lacks access control, allowing any caller to make modifications to the diamond contract's functionality. An attacker could leverage this to manipulate the contract's behavior, potentially leading to fund theft or disruption of contract operations.
addFunctions, replaceFunctions, removeFunctions: These internal functions are responsible for adding, replacing, or removing specific functions within a facet. However, they do not enforce any access controls, making it possible for unauthorized callers to make changes to the diamond's functionality. This could lead to unauthorized access to sensitive functions or the introduction of malicious code.
In summary, the absence of proper access controls in these critical functions exposes the diamond contract to significant security risks. Attackers could exploit this vulnerability to gain unauthorized control over the contract's functionality, potentially resulting in the theft of funds or the disruption of contract operations on production/mainnet.
Impact Details
The impact of exploiting this vulnerability could be severe, especially if the diamond contract holds significant funds or critical functionalities. Here's a breakdown of possible losses:
Theft of Funds: Since the diamond contract is vulnerable to unauthorized modifications, attackers could exploit this to steal funds held within the contract. They could manipulate the contract's functionality to transfer funds to their own addresses or drain the contract's balance outright.
Loss of User Trust: If funds or assets are stolen due to the exploitation of this vulnerability, it could lead to a loss of trust among users and stakeholders. This loss of trust may deter users from engaging with similar contracts in the future, potentially harming the reputation of the project or platform associated with the diamond contract.
Disruption of Contract Operations: Unauthorized modifications to the diamond contract's functionality could also disrupt its normal operations. For example, attackers could disable critical functions or introduce malicious code that interferes with the contract's intended behavior. This disruption could lead to financial losses, operational inefficiencies, and reputational damage.
Legal and Regulatory Consequences: Depending on the jurisdiction and the nature of the assets involved, the exploitation of this vulnerability could attract legal and regulatory scrutiny. If funds are stolen or if user assets are compromised, the project owners may face lawsuits, regulatory fines, or other legal consequences.
In conclusion, the exploitation of this vulnerability poses significant financial, operational, and reputational risks to the project associated with the diamond contract. It could result in the theft of funds, loss of user trust, disruption of contract operations, and potential legal and regulatory consequences. Therefore, it's crucial to address this vulnerability promptly to mitigate these risks and safeguard the interests of all stakeholders involved.
References
You can find relevant documentation or code related to the Diamond Standard (EIP-2535) on platforms like Ethereum Improvement Proposals (EIPs) website, GitHub repositories, or other Ethereum-related forums and documentation sources. Simply search for "EIP-2535 Diamond Standard" or specific terms related to the code snippets provided earlier to find relevant resources.
Proof of concept
To demonstrate the vulnerability in the provided code, we'll focus on the removeFunctions function in the LibDiamond library. This function allows removing functions from a diamond smart contract. However, there's a critical flaw in the removeFunctions function that could potentially lead to unauthorized removal of functions by an attacker.
Here's a simplified version of the vulnerable part of the code:
function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { DiamondStorage storage ds = diamondStorage(); require(_facetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)"); for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress; removeFunction(oldFacetAddress, selector); } }
function removeFunction(address _facetAddress, bytes4 _selector) internal { DiamondStorage storage ds = diamondStorage(); require(_facetAddress != address(0), "LibDiamondCut: Cant remove function that doesnt exist"); require(_facetAddress != address(this), "LibDiamondCut: Cant remove immutable function"); // Vulnerability: No access control mechanism to check if the caller is authorized to remove the function. // An attacker can call this function to remove functions from the diamond contract. // Without proper access control, any function can be removed, potentially leading to theft of funds or other malicious activities. // Lack of validation allows unauthorized parties to manipulate the diamond contract's behavior. // This can result in loss of funds or disruption of the contract's intended functionality. // An attacker could exploit this vulnerability to disable critical functions, leading to significant financial losses or other adverse effects. // Additionally, the lack of access control violates the principle of least privilege, increasing the attack surface and making the contract more susceptible to exploits. }
Proof of concept: contract Attack { address public diamond;
}
The proof of concept demonstrates how an attacker could exploit the vulnerability to remove critical functions from the diamond contract, potentially leading to theft of funds or disruption of the contract's intended functionality. This underscores the importance of implementing robust access control mechanisms to prevent unauthorized modifications to smart contracts.
Immunefi Response
Immunefi has reviewed this vulnerability report and decided to close since being out of scope for Beanstalk bug bounty program.
- claimed impact by the whitehat is in scope for the bug bounty program
- claimed asset by the whitehat
is not in scopefor the bug bounty program- PoC has been submitted to the project
- claimed severity is in scope for the bug bounty program
The project will now be automatically subscribed and receive a report of the closed submission and can evaluate if they are interested in re-opening it. However, note that they are not under any obligation to do so.