I am recreating a UNISWAP-like AMM and have encountered problems anytime I want to divide the balances of tokens in my pool. For example: I want to require() that tokens are deposited in the correct ratio (Total number of token 1/Total number of token 2). If I do this I can encounter 2 problems:

  • either the result is 0<x<1 and I get 0 which stops all further calculations
  • or the result is rounded down to an integer which is a significant calculation error

I hoped using larger numbers (18 decimals) would solve this problem but it hasn't, I also don't want to use external libraries, other than safeMath. What can I do to solve these problems? Thanks!

  • Please share the code used, it is not possible to suggest enhancements fixes if there's no code. Also with solc 0.8 SafeMath is no longer needed. – Ismael Mar 1 at 14:00
  • function deposit(uint256 _amountRED, uint256 _amountYELLOW) payable external returns(uint256){ require((_amountYELLOW * (10 ** 18)) * balance_RED / balance_YELLOW == _amountRED * (10 ** 18), "Ratio not correct!"); Where _amountRED &_amountYELLOW are human readable token values you want to deposit, balance_RED & balance_YELLOW are the 18 decimal values of total number of tokens in the pool already. – nora goba Mar 2 at 19:12
  • You can edit your own question to add more details. Using the cross-product would be ideal _amountYELLOW * balance_RED == _amountRED * balance_YELLOW, but it will limit the possible values of _amountYELLOW and _amountRED to certain divisors of the other side. Perhaps _amountYELLOW * K / _amountRED == balance_YELLOW * K / balance_RED for some constant K will give better results (you can start with K = 10**18 and ajust how many decimals you care about). – Ismael Mar 3 at 2:36
  • Thank you! Do you have any general guidance on dealing with fractions in Solidity. These mathematical solutions are very situation specific and eventually you will need to deal with fractions where floor rounding will become a big issue. I saw Uniswap uses a library to implement fractions but I don't understand it (I never studied CS). What is the simplest way to deal with decimals or is there just no simple solution? Thanks! – nora goba Mar 3 at 18:50
  • Unfortunately there's no simplest way. Solidity doesn't support fractions, most projects use fixed point arithmetic. Having 18 decimals for most applications is good enough, a few ones like Maker or Uniswap use more decimals 36, 54 depending on the case (don't use more decimals unless you really need it). More serious projects hire security auditors that study those issues. – Ismael Mar 4 at 1:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.