Full Report
dHEDGE is an asset management protocol. Users deposit assets, and managers/traders can generate a field for them. The codebase intentionally allowed for integrations, but with minimal trust required of the manager/trader. For instance, when using Uniswap, the code had a slippage range. These checks are called contract guards; their goal is to prevent users from being drained by the strategy's owner. Designing a protocol this way is great for users, but very hard to do securely. The vulnerability existed within the 1inch integration. Each integration is called a function with a tx guard, provider call, and invariant checks at the end. The 1-inch integration provided multiple functions: swap, unoswap, unoswap2, and unoswap3. These allow for swaps via different pools, such as Uniswap and Curve. The bug is within the unoswap function. The calldata is decoded for the Unoswap to get the token information associated with it. Notably, it would get the source token and the pool address. The source token is a uint256, where the least significant 160 bits are the address and the rest are bit flags. Given a source token and a pool, it will deduce the destination asset. The vulnerability lies in some very simple-looking code used to get the destination token. The integration with unoswap sometimes uses a different value as the source token. In particular, with UniswapV3, it will use the bitmaps from the pool value from before. So, there's a desync between the validation and usage. For example, if the manager provides WETH as the source asset for a USDC/WETH pool with the USDC flag on. Even though WETH was provided as the source asset, the swap will be done from USDC->WETH. This circumvents the slippage protection because it's using the wrong value. Trying to exploit this as described won't work because the slippage logic will revert on the source asset, increasing. By specifying multiple pools (one has a malicious token and another is legitimate), we can use the fake token for the slippage checks to return wrong values to balanceOf. Now, on the second part of the trade, we can get all of the funds out. This vulnerability was missed in a contest that the author of this post actually participated in. The bug was pretty simple, but it just required some integration knowledge of the various protocols. The exploit required a very deep knowledge of the protocol to work, which was pretty awesome. Good find!
Analysis Summary
# Vulnerability: Logic Desync in dHEDGE 1inch Integration
## CVE Details
- **CVE ID:** Not Assigned (Common in decentralized finance/smart contract vulnerabilities)
- **CVSS Score:** 8.8 (High) - Estimated based on total loss of funds logic
- **CWE:** CWE-684: Incorrect Provision of Specified Functionality / CWE-88: Argument Injection or Modification
## Affected Systems
- **Products:** dHEDGE Protocol
- **Versions:** Affected versions utilizing the 1inch integration (specifically `OneInchV5Guard` or similar logic)
- **Configurations:** Pools with 1inch integration enabled where managers have permission to initiate `unoswap` calls.
## Vulnerability Description
The vulnerability stems from a synchronization failure between how the dHEDGE "contract guard" validates transaction calldata and how the 1inch protocol actually executes the swap. dHEDGE utilizes guards to ensure managers do not drain user funds by enforcing slippage checks.
Specifically, in the `unoswap` function, dHEDGE decodes the `srcToken` from the calldata to determine which asset is being traded. In 1inch V5, the `srcToken` is a `uint256` where the address is stored in the lower bits and flags (bitmaps) are stored in the higher bits. The dHEDGE guard incorrectly deduced the destination asset or validated the source asset based on these flags while the execution layer used a different interpretation. This created a "desync" where a manager could provide WETH as the source asset for a USDC/WETH pool, but 1inch would execute the swap from USDC to WETH.
By chaining this with multiple pools—one involving a malicious/controlled token—the attacker could manipulate `balanceOf` returns to bypass the invariant checks (slippage protection) and drain the pool’s TVL.
## Exploitation
- **Status:** PoC demonstrated by researcher (reported and likely mitigated)
- **Complexity:** High (Requires deep knowledge of 1inch calldata encoding and dHEDGE guard logic)
- **Attack Vector:** Network (Smart Contract Interaction)
## Impact
- **Confidentiality:** None
- **Integrity:** High (Unauthorized manipulation of asset balances)
- **Availability:** High (Loss of total TVL within affected pools)
## Remediation
### Patches
- The protocol team has reportedly updated the contract guards to correctly handle 1inch flag decoding and ensure alignment between validated tokens and executed tokens. Users should ensure they are interacting with the latest implementation of the dHEDGE 1inch guards.
### Workarounds
- Pause 1inch integration or specifically the `unoswap` function within the manager's allowed transaction list until the guard update is verified.
## Detection
- **Indicators of Compromise:** Large swaps where the `srcToken` in the transaction calldata contains non-zero bits in the upper 96 bits of the address field.
- **Detection Methods:** Monitoring for `balanceOf` anomalies immediately following a 1inch `unoswap` call within a managed dHEDGE pool.
## References
- hxxps://x[.]com/i/article/1879854499625562112
- hxxps://github[.]com/dhedge (Official Repository)
- hxxps://dhedge[.]org (Project Site)