0

In the else statement, where the Boolean is false, the amount has more than 18 decimals. In this example I used a 24 decimal amount, 123456789123456789123456. Now, it will return 123456789123456789. How do I prevent the precision loss?

Source: https://calnix.gitbook.io/eth-dev/yield-mentorship-2022/projects/5-collateralized-vault/pricing-+-decimal-scaling

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract precision {
    
    function standardize(uint256 amount, bool true_less_false_more) external pure returns (uint256 standardizedAmount) {
        standardizedAmount = amount;
        if (true_less_false_more) { 
            standardizedAmount *= 10 ** (18 - 6); //123456
        } 
        else if (!true_less_false_more) { 
            standardizedAmount /= 10 ** (24 - 18); //123456789123456789123456 
            // standardizedAmount = 123456789123456789123456 / 1e6;
            // standardizedAmount = 123456789123456789 (Last six decimals will be truncated)
        }
    }
}
3
  • Last six decimals are getting truncated because you're converting it from 24-decimal format to 18-decimal format explicitly in your else condition. What exactly you want to achieve? Commented Apr 8 at 8:19
  • I want to keep the last 6 decimals too. Is there a way to downscale without losing precision? Commented Apr 8 at 8:48
  • 1
    In such a scenario, there's no need to downscale; instead, you need to upscale the other value (having lower decimal precision) with which you're multiplying or dividing. Commented Apr 8 at 8:52

1 Answer 1

1

If you want to keep the last 6 decimals, then it's not actually downscaling from 24-decimal format to 18-decimal format, instead it's keeping it the same. And that, you can simply achieve by getting rid of your else condition completely.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract precision {
    
    function standardize(uint256 amount, bool true_less_false_more) external pure returns (uint256 standardizedAmount) {
        standardizedAmount = amount;
        if (true_less_false_more) { 
            standardizedAmount *= 10 ** (18 - 6); 
        } 
        // else { 
        //     // Do nothing
        // }
    }
}

P.S., In such a scenario, there's no need to downscale; instead, you need to upscale the other value (having lower decimal precision) with which you're multiplying or dividing.

1
  • 1
    Thanks I think there is no reason to downscale. Commented Apr 8 at 9:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.