Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

Possibly wrong implementation of "format_units" #168

Closed
PaulRBerg opened this issue Jan 16, 2021 · 8 comments · Fixed by #170
Closed

Possibly wrong implementation of "format_units" #168

PaulRBerg opened this issue Jan 16, 2021 · 8 comments · Fixed by #170
Labels
bug Something isn't working

Comments

@PaulRBerg
Copy link
Contributor

PaulRBerg commented Jan 16, 2021

Description

I was looking to use the format-units function, part of ethers-core::utils. I was expecting the same behaviour as in the canonical ethers.js, but the format_units function behaves differently in ethers-rs.

Actual Behaviour

Take the following Rust code:

use ethers::{prelude::*, utils::format_units};
let eth_in_wei = U256::from_dec_str("1000000000000000000").unwrap();
let eth_in_gwei = format_units(eth_in_wei, 9);
println!("eth_in_gwei: {:?}", eth_in_gwei);

This logs the following:

eth_in_gwei: 111111111111111111

Expected Behaviour

Take the following JavaScript code:

const { ethers } = require("ethers");
let eth_in_wei = "1000000000000000000";
const eth_in_gwei = ethers.utils.formatUnits(eth_in_wei, 9);
console.log({ eth_in_gwei });

This logs the following:

{ eth_in_gwei: '1000000000.0' }

Which is correct, as per the identity 1 eth = 1e9 gwei = 1e18 wei.

Possible Solution

Rewrite the format_units function to divide by 10^(decimals) instead of just decimals.

Environment

Using [email protected]

@PaulRBerg PaulRBerg added the bug Something isn't working label Jan 16, 2021
@gakonst
Copy link
Owner

gakonst commented Jan 17, 2021

This should be fixed in #170 @PaulRBerg!

@sakulstra
Copy link
Contributor

hey just doing my first steps with rust and I think there might still be an issue:

// js
ethers.utils.formatUnits("409030851937682650000",18) ->  "409.03085193768265"

// ethers-rs
format_units(&U256::from_dec_str("409030851937682650000"), 18).to_string(); -> "409"

@x3ccd4828
Copy link
Contributor

@gakonst can you reopen this issue since it's still not correct?

@gakonst
Copy link
Owner

gakonst commented Nov 9, 2021

i think this was addressed in #463?

@x3ccd4828
Copy link
Contributor

I have modified the parse_unit test to show that if you have 18 decimal places some are lost since f64 doesn't have enough bits to hold such a high precision number.

x3ccd4828@617997a

@x3ccd4828
Copy link
Contributor

I can submit a pull request with a fix but it will have to use the rug crate (https://crates.io/crates/rug) to create a float larger than 64bit.

@x3ccd4828
Copy link
Contributor

@gakonst have you had a chance to look at the modified test?

@gakonst
Copy link
Owner

gakonst commented Nov 18, 2021

+1 on the test and fixing it by using rug with default-features = false

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants