diff --git a/src/Utils/UnitConverter.php b/src/Utils/UnitConverter.php index 473fa82..d868006 100644 --- a/src/Utils/UnitConverter.php +++ b/src/Utils/UnitConverter.php @@ -5,6 +5,7 @@ namespace ArkEcosystem\Crypto\Utils; use Brick\Math\BigDecimal; +use Brick\Math\RoundingMode; use InvalidArgumentException; class UnitConverter @@ -23,6 +24,7 @@ class UnitConverter * * @param float|int|string $value * @param string $unit + * * @return BigDecimal */ public static function parseUnits($value, string $unit = 'ark'): BigDecimal @@ -44,17 +46,24 @@ public static function parseUnits($value, string $unit = 'ark'): BigDecimal * * @param string $value * @param string $unit - * @return float + * + * @return BigDecimal */ - public static function formatUnits(string $value, string $unit = 'ark'): float + public static function formatUnits(string $value, string $unit = 'ark'): BigDecimal { switch (strtolower($unit)) { case 'wei': - return (float) bcdiv($value, (string) self::WEI_MULTIPLIER, 18); + return BigDecimal::of($value) + ->dividedBy(self::WEI_MULTIPLIER, 0, RoundingMode::HALF_UP) + ->stripTrailingZeros(); case 'gwei': - return (float) bcdiv($value, (string) self::GWEI_MULTIPLIER, 18); + return BigDecimal::of($value) + ->dividedBy(self::GWEI_MULTIPLIER, 9, RoundingMode::HALF_UP) + ->stripTrailingZeros(); case 'ark': - return (float) bcdiv($value, (string) self::ARK_MULTIPLIER, 18); + return BigDecimal::of($value) + ->dividedBy(self::ARK_MULTIPLIER, 18, RoundingMode::HALF_UP) + ->stripTrailingZeros(); default: throw new InvalidArgumentException("Unsupported unit: {$unit}. Supported units are 'wei', 'gwei', and 'ark'."); } diff --git a/tests/Unit/Utils/UnitConverterTest.php b/tests/Unit/Utils/UnitConverterTest.php index 826eab4..85d7bf1 100644 --- a/tests/Unit/Utils/UnitConverterTest.php +++ b/tests/Unit/Utils/UnitConverterTest.php @@ -24,20 +24,45 @@ expect((string) $arkValueDecimal)->toBe('100000000000000000'); }); -test('it should format units from wei', function () { - $formattedValue = UnitConverter::formatUnits('1', 'wei'); - expect($formattedValue)->toBe(1.0); -}); +test('it should format units from wei', function ($formattedAmount, $amount) { + $formattedValue = UnitConverter::formatUnits($formattedAmount, 'wei'); -test('it should format units from gwei', function () { - $formattedValue = UnitConverter::formatUnits('1000000000', 'gwei'); - expect($formattedValue)->toBe(1.0); -}); + expect((string) $formattedValue)->toEqual($amount); +})->with([ + ['1', '1'], + ['10', '10'], + ['100', '100'], + ['1000', '1000'], + ['10000', '10000'], +]); -test('it should format units from ark', function () { - $formattedValue = UnitConverter::formatUnits('1000000000000000000', 'ark'); - expect($formattedValue)->toBe(1.0); -}); +test('it should format units from gwei', function ($formattedAmount, $amount) { + $formattedValue = UnitConverter::formatUnits($formattedAmount, 'gwei'); + + expect((string) $formattedValue)->toEqual($amount); +})->with([ + ['100000001', '0.100000001'], + ['100000000', '0.1'], + ['1000000000', '1'], + ['10000000000', '10'], + ['100000000000', '100'], + ['1000000000000', '1000'], + ['10000000000000', '10000'], +]); + +test('it should format units from ark', function ($formattedAmount, $amount) { + $formattedValue = UnitConverter::formatUnits($formattedAmount, 'ark'); + + expect((string) $formattedValue)->toEqual($amount); +})->with([ + ['100000000000000001', '0.100000000000000001'], + ['100000000000000000', '0.1'], + ['1000000000000000000', '1'], + ['10000000000000000000', '10'], + ['100000000000000000000', '100'], + ['1000000000000000000000', '1000'], + ['10000000000000000000000', '10000'], +]); test('it should throw exception for unsupported unit in parse', function () { expect(fn () => UnitConverter::parseUnits(1, 'unsupported'))