Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

Getting Rounding Right in DeFi- 1874

Josselin FeistPosted 1 Month Ago
  • Poor rounding in DeFi has been the catalyst of many, many bugs in Web3, even on major projects. The consequences of truncations and rounding down can seem insignificant but can be horrible consequences. This post dives into how this happens and a systematic approach for discovering rounding issues.
  • The EVM doesn't have floats; everything is an integer. So, 5/2 is not 2.5 but 2. To combat this, fixed-point arithmetic is used, which most folks know as decimal arithmetic. Now, 5 is no longer 5 but 5^18. Now, when you divide by 2 it's 2.5^18 which keeps most the precision. Some libraries also provide functionality for rounding up or down depending on the situation.
  • They provide an example of the following formula: balanceOut * (1 - balanceIn / (balanceIn + tokenIn)) from Balancer. if balanceIn is 0, then this can become balanceOut * (1-0). balanceOut is the only value leftover. This can happen by combining a flash mint with a pool unbalanced. This truncation allows the attacker to steal all funds from the protocol. The fix is rounding up instead of down.
  • It's commonly said to round in the favor of the protocol. In particular, if going to the users' round down and if going to the protocol round up. In reality, this doesn't work. First, there's a complexity problem. With HUGE formulas, the rounding depends on the runtime values, making this not a simple task.
  • Second, code is commonly reused. Sometimes, it'll require rounding down and others up. Third, errors can be bad as well. For instance, making a liquidation unliquidatable would be a major problem.
  • The author includes several tips for fixing this. First, every rounding issue is a bug. Instead of spending hours writing an exploit path, it just needs to be fixed on the spot. Some bugs are vulnerabilities, some are exploitable, but they are ALL bugs. The second consideration is around design. One thought is to redesign or simplify formulas, or to add protocol invariants. Next, precision loss can cancel each other out. By rewriting formulas with multiple steps, math errors can cancel each other out. All of these decisions must be explicitly documented.
  • Overall, a good post on rounding vulnerabilities and how to think about them going forward.