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!

DFX Finance Rounding Error Bugfix Review- 1187

ImmunefiPosted 2 Years Ago
  • DFX Finance is a decentralized foreign exchange protocol that allows users to swap many stablecoins. DFX is an AMM that exchanges tokens according to a bonding curve, which is dynamically calculated from Chainlink prices. Each one of the currencies is paired with USDC in a pool.
  • There are two main parts to the DFX protocol: Assimilators and Curve. Assimilators allow the AMM to handle pairs of different values for fixed point arithmetic, since Solidity doesn't support floating point numbers. In particular, it's responsible for converting all amounts to numeraire, a base value for all computations. DFX Finance maintains the assimilators which integrate with Curve to provide proportional liquidity to pools.
  • When users would provide liquidity to a pool to receive yield on their stablecoins, they call the deposit() for a Curve pool and receive LP tokens. During this process, a check occurs to see if the deposit amount is greater than zero.
  • The EURS token is a token with only two decimals. When creating these sorts of protocols, the developers may not have considered these small decimal tokens. The amount to transfer from the user is calculated based upon the following values:
    amount_ = (_amount.mulu(10**tokenDecimals) * 1e6) / _rate;
    token.safeTransferFrom(msg.sender, address(this), amount_);
    
  • This code leads to zero tokens being transferred from the user. Despite this transferring zero tokens, the attacker gets some value being put into the contract. However, it is an extremely small amount of LP tokens that are sent back to the user.
  • Normally, tokens have at least six decimals. So, the amount of tokens gained from this would be tiny with these larger tokens. Because of how small the values normally are, the amount spent on gas would dwarf this. However, since the EURS token only has two decimals, this attack becomes viable! By depositing a tiny amount 10K times, an attacker can get $190 per attack by withdrawing the CURVE LP tokens.
  • To fix this vulnerability, there is a simple check to make sure the amount of funds transferred is not zero. The hacker got a 100K bounty for a 230K pool; this is a good look for the protocol. Overall, this is a fascinating vulnerability that was only possible because of a single token. Precision issues are super interesting!