DittoETH

Ditto
DeFiFoundryOracle
55,000 USDC
View results
Submission Details
Severity: medium
Invalid

High-Risk Reentrancy Vulnerability Detected in baseOracleCircuitBreaker Function

Summary

We have identified a potential reentrancy vulnerability in the LibOracle contract's baseOracleCircuitBreaker function. This vulnerability arises due to an external call made to another contract, followed by state-changing operations.

Vulnerability Details

In the baseOracleCircuitBreaker function of the LibOracle contract, there's a line that makes an external call:

uint256 twapPrice = IDiamond(payable(address(this))).estimateWETHInUSDC(
Constants.UNISWAP_WETH_BASE_AMT, 30 minutes
);

This external call to the IDiamond contract can be exploited if the IDiamond contract is malicious or compromised. The malicious contract can call back into the LibOracle contract before the original call completes, leading to unexpected behavior.

Vulnerable Code:
In the baseOracleCircuitBreaker function:

uint256 twapPrice = IDiamond(payable(address(this))).estimateWETHInUSDC(
Constants.UNISWAP_WETH_BASE_AMT, 30 minutes
);

This line makes an external call to another contract (IDiamond). If the IDiamond contract is malicious or compromised, it can call back into the LibOracle contract before the original call completes, potentially leading to unexpected behavior or theft of funds.

Malicious Contract:
Let's assume that a malicious actor has control over the IDiamond contract. Here's a potential exploit:

contract MaliciousDiamond {
bool public reentrantFlag = false;
address public targetContract;

constructor(address _targetContract) {
    targetContract = _targetContract;
}

function estimateWETHInUSDC(uint256 amount, uint256 duration) external returns (uint256) {
    if (!reentrantFlag) {
        reentrantFlag = true;
        // Call back into the target contract to exploit the reentrancy vulnerability
        LibOracle(targetContract).getOraclePrice(address(this));
    }
    return 1 ether; // Return a fake price
}

}

In this malicious contract:

The estimateWETHInUSDC function is called by the LibOracle contract.
If the reentrantFlag is false, the malicious contract calls back into the LibOracle contract's getOraclePrice function.
This can lead to unexpected behavior in the LibOracle contract, as the state may not be consistent.
Exploit Steps:
The attacker deploys the MaliciousDiamond contract, setting the targetContract to the address of the LibOracle contract.
The attacker somehow convinces or triggers the LibOracle contract to use the MaliciousDiamond contract as its IDiamond implementation.
When the LibOracle contract calls the estimateWETHInUSDC function on the MaliciousDiamond contract, the reentrancy attack is triggered.
The MaliciousDiamond contract calls back into the LibOracle contract, potentially leading to unexpected behavior or theft of funds.
Mitigation:
To prevent this vulnerability:

Use the nonReentrant modifier from the OpenZeppelin library on functions that make external calls followed by state-changing operations.
Ensure that external calls are the last operations in a function.
Be cautious about which contracts you interact with and trust. Ensure that external contracts have been audited and are not malicious.
Remember, reentrancy attacks can be subtle and can lead to significant losses. Always be cautious and use well-established patterns and libraries to prevent them.

Impact

A successful exploitation of this vulnerability can lead to:

Unexpected behavior in the LibOracle contract.
Potential theft of funds or assets managed by the contract.
Corruption of the contract's state, making it unusable or compromised.

Tools Used

Manual code review and analysis.
Solidity compiler for contract compilation.

Recommendations

Use the nonReentrant Modifier: Implement the nonReentrant modifier from the OpenZeppelin library on functions that make external calls followed by state-changing operations.
Rearrange Operations: Ensure that external calls are the last operations in a function. This reduces the surface area for reentrancy attacks.
Audit External Contracts: Be cautious about which contracts you interact with. Ensure that external contracts have been audited and are not malicious.
Testing: Before deploying any changes, thoroughly test the contract to ensure that the modifications do not introduce new vulnerabilities or break existing functionalities.

Updates

Lead Judging Commences

0xnevi Lead Judge
over 1 year ago
0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Other

Support

FAQs

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