Full Report
Osmosis is a very popular decentralized exchange running on the Cosmos SDK. The authors of this post were looking at the math within this blockchain when they stumbled across an issue. When performing exponentiation(ab), the program was using a Taylor series approximation. There is a point within this series that we need to say "good enough" though. So, what's the stopping point? When the changes to the approximation become so small that they don't matter any more in what the developers choose. They choose a change of less than 0.00000001. There is an issue with this approach though: what if the approximation is never reached? This is bad since there was no maximum iteration on the amount of loops that could occur. For example, 1.999999999999990.1 takes over 2M iterations, taking 0.8 seconds in Go. By doing this multiple times, it leads to a denial of service via resource exhaustion. Thus far, this was done via calling the PowApprox() directly. Can we trigger this on a real transaction? Yes! With the following steps on Osmosis, it was possible: Make a pool with a token weight of 0.1 and initialize it with 10. of token A. Deposit 0.99999999999999 more of tokenA. The above call triggers the approximation functionality. Do this over and over again to take down the blockchain. What's interesting to me is that this leads to a transient denial of service. The attacker must continually do this in order to perform this attack. By including the new circuit breaker module to turn off this message, the blockchain could have continued for a bit. I enjoy that only two messages could be used to trigger this! Good find friends.
Analysis Summary
# Vulnerability: Resource Exhaustion via Taylor Series Loop in Osmosis Math Library
## CVE Details
- **CVE ID:** Not explicitly assigned (Referenced as Trail of Bits Disclosure Oct 2023)
- **CVSS Score:** N/A (Estimated High 7.5 - 8.6 range due to Network-based DoS)
- **CWE:** CWE-400 (Uncontrolled Resource Consumption), CWE-835 (Loop with Unreachable Exit Condition)
## Affected Systems
- **Products:** Osmosis Blockchain (Math Library)
- **Versions:** Versions prior to the October 23, 2023 hard fork.
- **Configurations:** Any node processing transactions involving swap pool deposits/shares calculations using the `PowApprox` function.
## Vulnerability Description
The flaw exists within the `PowApprox` function of the Osmosis math library, which implements a Taylor series to calculate exponentiation ($a^b$). The implementation used a `while` loop that continued until the approximation's "precision" (the change between iterations) was less than 0.00000001.
Critically, the loop lacked a maximum iteration bound. Specific inputs—specifically where $a$ is very close to 2 and $b$ is small—force the Taylor series to converge extremely slowly. For example, calculating $1.99999999999999^{0.1}$ requires over 2 million iterations, consuming ~800ms of CPU time per call. Because gas costs did not account for this extreme computational drift, the function became a vector for resource exhaustion.
## Exploitation
- **Status:** PoC available; identified by Trail of Bits.
- **Complexity:** Medium (Requires setting up a specific pool state).
- **Attack Vector:** Network (Authenticated via standard transaction).
- **Steps to Reproduce:**
1. Create a liquidity pool with a specific token weight (e.g., 0.1).
2. Initialize the pool with a small amount of Token A (e.g., 10.0).
3. Perform a deposit of a highly specific amount (e.g., 0.99999999999999) to force the `PowApprox` inputs into the slow-convergence range.
4. Repeatedly deposit and withdraw to stall validator nodes.
## Impact
- **Confidentiality:** None
- **Integrity:** None
- **Availability:** High. This is a transient Denial of Service (DoS) that can halt the entire blockchain by exhausting the CPU resources of validators.
## Remediation
### Patches
- **Osmosis Hard Fork (Proposal 658):** Merged on October 6, 2023, and activated on October 23, 2023. The fix introduces a maximum iteration limit for the loop and reverts the transaction if the limit is exceeded.
- **Source Code Fix:** [github[.]com/osmosis-labs/osmosis/pull/6627]
### Workarounds
- **Circuit Breaker:** The transition to a new circuit breaker module could allow governance to disable specific vulnerable messages (like pool deposits) temporarily.
## Detection
- **Indicators of Compromise:** High CPU spikes on validator nodes coinciding with a high volume of `MsgJoinPool` or `MsgExitPool` transactions containing fractional token amounts with high decimal precision.
- **Detection Methods:** Fuzzing the math library with specific timeouts (e.g., using `gofuzz` or Go’s native fuzzer with a 10-100ms timeout) would identify inputs that cause execution hangs.
## References
- **Vendor Advisory:** [mintscan[.]io/osmosis/proposals/658]
- **Technical Analysis:** [blog[.]trailofbits[.]com/2023/10/23/numbers-turned-weapons-dos-in-osmosis-math-library/]
- **Code Repository:** [github[.]com/osmosis-labs/osmosis]