Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

epic: nibiru-std::math::{ SdkDec, DecimalExt } #106

Merged
merged 8 commits into from
Dec 18, 2023
Merged

Conversation

Unique-Divine
Copy link
Member

@Unique-Divine Unique-Divine commented Dec 18, 2023


Summary by CodeRabbit

  • New Features

    • Updated checksums for enhanced security and integrity of WebAssembly files.
    • Expanded error handling capabilities with new error variants for mathematical operations and parsing.
  • Documentation

    • Improved documentation for contract initialization and execution with additional code snippets and comments.
  • Refactor

    • Enhanced mathematical operations with new types and methods for arithmetic and conversions.
    • Improved code organization through reordering of module declarations.
  • Style

    • Adjusted spacing in source code annotations for consistency.
  • Chores

    • Updated codecov configuration to include a new patch threshold for code coverage.
  • Bug Fixes

    • Adjusted type definitions and imports to ensure accurate data representation and manipulation.

Copy link
Contributor

coderabbitai bot commented Dec 18, 2023

Walkthrough

The changes reflect updates to Wasm file checksums, enhancements to error handling, and revisions to contract and standard library code. New mathematical types and methods have been introduced, along with changes to import statements and enum variants. These updates aim to improve the robustness and functionality of the smart contracts and underlying libraries.

Changes

File Path Change Summary
artifacts/checksums.txt
artifacts/checksums_intermediate.txt
Updated checksums for several .wasm files.
contracts/core-shifter/README.md Added code snippets and JSON data for contract initialization and execution.
contracts/core-shifter/src/contract.rs Added import statement, modified import statements, and changed function behavior.
contracts/core-shifter/src/error.rs Added import statement and new error variant.
contracts/core-shifter/src/msgs.rs Modified import statements and changed type in ExecuteMsg enum.
nibiru-std/src/errors.rs Added new error variants to enums.
nibiru-std/src/lib.rs Reordered module declarations.
nibiru-std/src/math.rs Added new types and methods for arithmetic operations and conversions.
nibiru-std/src/proto/buf/nibiru.oracle.v1.rs Modified attribute syntax and comments.
.github/codecov.yml Added a new patch threshold configuration under the coverage section.

Assessment against linked issues

Objective Addressed Explanation
Implement a new feature to create a signed decimal type that utilizes cosmwasm_std::Decimal. The changes include the addition of new types and methods for arithmetic operations and conversions, aligning with the objective.
Ensure that the new signed decimal type is compatible with the existing cosmwasm_std::Decimal and can be used interchangeably. The changes do not disrupt the current functionality and maintain compatibility with the existing cosmwasm_std::Decimal.
Provide appropriate tests to validate the functionality and interoperability of the new signed decimal type. No specific mention of new tests for the signed decimal type.
Document the usage and behavior of the new feature, including any potential edge cases or limitations. Documentation changes are not explicitly mentioned in the provided summaries.
Integrate the new feature into the existing codebase without disrupting the current functionality or breaking backward compatibility. The changes aim to seamlessly integrate the new features without disrupting the current functionality.

🐇
In the code where bytes align,
Checksums shift, errors entwine.
Math anew, contracts refine,
A rabbit's touch, in threads combine. 🌟
🐇

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on X ?


Tips

Chat with CodeRabbit Bot (@coderabbitai)

  • You can reply to a review comment made by CodeRabbit.
  • You can tag CodeRabbit on specific lines of code or files in the PR by tagging @coderabbitai in a comment.
  • You can tag @coderabbitai in a PR comment and ask one-off questions about the PR and the codebase. Use quoted replies to pass the context for follow-up questions.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

@Unique-Divine Unique-Divine added type: enhancement New feature or request epic Project or large task that groups multiple tickets and PRs labels Dec 18, 2023
Copy link

codecov bot commented Dec 18, 2023

Codecov Report

Merging #106 (444f243) into main (535007e) will decrease coverage by 0.21%.
Report is 4 commits behind head on main.
The diff coverage is 80.39%.

❗ Current head 444f243 differs from pull request most recent head d29eee2. Consider uploading reports for the commit d29eee2 to get more accurate results

Additional details and impacted files
Files Coverage Δ
contracts/core-shifter/src/error.rs 0.00% <ø> (ø)
contracts/core-shifter/src/msgs.rs 28.57% <ø> (ø)
nibiru-std/src/proto/type_url_nibiru.rs 95.00% <ø> (ø)
contracts/core-shifter/src/contract.rs 82.52% <0.00%> (ø)
nibiru-std/src/errors.rs 0.00% <0.00%> (ø)
nibiru-std/src/math.rs 80.84% <80.84%> (ø)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 8

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 160571a and 444f243.
Files ignored due to filter (7)
  • Cargo.lock
  • Cargo.toml
  • artifacts/nibi_stargate.wasm
  • artifacts/nibi_stargate_perp.wasm
  • artifacts/nusd_valuator.wasm
  • artifacts/shifter.wasm
  • nibiru-std/Cargo.toml
Files selected for processing (11)
  • artifacts/checksums.txt (1 hunks)
  • artifacts/checksums_intermediate.txt (1 hunks)
  • contracts/core-shifter/README.md (1 hunks)
  • contracts/core-shifter/src/contract.rs (2 hunks)
  • contracts/core-shifter/src/error.rs (2 hunks)
  • contracts/core-shifter/src/msgs.rs (2 hunks)
  • nibiru-std/src/errors.rs (1 hunks)
  • nibiru-std/src/lib.rs (1 hunks)
  • nibiru-std/src/math.rs (1 hunks)
  • nibiru-std/src/proto/buf/nibiru.oracle.v1.rs (14 hunks)
  • nibiru-std/src/proto/mod.rs (1 hunks)
Files skipped from review due to trivial changes (4)
  • artifacts/checksums_intermediate.txt
  • nibiru-std/src/lib.rs
  • nibiru-std/src/proto/buf/nibiru.oracle.v1.rs
  • nibiru-std/src/proto/mod.rs
Additional comments: 18
artifacts/checksums.txt (1)
  • 5-9: Checksum updates for Wasm files are consistent with the PR's objectives to update Wasm bytecode artifacts. Ensure that the updated checksums correspond to the newly compiled Wasm files and that they have been tested to confirm they work as expected.
contracts/core-shifter/README.md (3)
  • 24-36: The addition of shifter-0-inst.json and corresponding bash command for contract initialization is clear and provides a straightforward example for users to follow. Ensure that the address provided in the JSON snippet is a placeholder or example and not a real address, to avoid any security or privacy concerns.

  • 51-65: The sudo-add.json configuration and the corresponding nibid command for editing the sudo are clear. However, as with the initialization JSON, ensure that the addresses provided are placeholders or examples and not real addresses.

  • 71-82: The shifter-1-exec-shift-peg.json configuration and the corresponding execution command are clear and provide a good example of how to use the contract's functionality. Again, ensure that the pair and new peg multiplier values are generic examples.

contracts/core-shifter/src/contract.rs (2)
  • 73-79: The conversion of new_peg_mult to SdkDec type using SdkDec::from_str(&new_peg_mult)?.pb_repr() is a significant change. Ensure that the pb_repr method correctly converts SdkDec for protobuf representation and that the error handling for potential parsing failures is adequate.

  • 1-14: The addition of use std::str::FromStr; and the changes to the import statements in nibiru_std are in line with the PR's objectives to implement new types and extensions for decimal arithmetic.

contracts/core-shifter/src/error.rs (3)
  • 3-4: The import statement for nibiru_std::errors is correctly added to support the new MathError variant in the ContractError enum.

  • 17-18: The addition of the MathError variant to the ContractError enum is consistent with the PR objectives and the AI-generated summary. The #[from] attribute is correctly used for error conversion.

  • 13-19: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [1-19]

Ensure that all math-related errors in the core-shifter contract are updated to use the new MathError variant for consistency and accurate error handling.

contracts/core-shifter/src/msgs.rs (2)
  • 1-5: The import of Uint256 suggests that the contract is now using this type for arithmetic operations, which aligns with the PR's objective to enhance decimal arithmetic capabilities.

  • 19-25: The change of new_peg_mult from Decimal to String is consistent with the PR's goal of improving protobuf representations and using the new SdkDec type. Ensure that the corresponding deserialization and validation logic is updated to handle the String type and convert it to SdkDec as needed.

Verification successful

The from_str method for SdkDec is implemented in nibiru-std/src/math.rs and returns a Result, indicating that it includes error handling which serves as validation when converting from a String. This aligns with the changes in the core-shifter contract and supports the PR's goal of using the SdkDec type for improved protobuf representations. The verification process has not revealed any issues with the deserialization and validation logic for new_peg_mult.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for deserialization logic related to `new_peg_mult` in the `core-shifter` contract.
rg 'new_peg_mult' --type rust --glob 'contracts/core-shifter/src/*'
# Verify that validation logic for `new_peg_mult` as a string is present and correct.
rg 'validate_.*new_peg_mult' --type rust --glob 'contracts/core-shifter/src/*'

Length of output: 432



Script:

#!/bin/bash
# Search for the `from_str` method implementation for `SdkDec`.
rg 'impl SdkDec' --type rust --glob 'nibiru-std/src/*'
rg 'fn from_str' --type rust --glob 'nibiru-std/src/*'

Length of output: 304

nibiru-std/src/math.rs (7)
  • 14-21: The Sign enum is well-defined with appropriate variants for representing the sign of a number.

  • 24-30: The DecimalExt struct is introduced with fields for sign and decimal value, which seems correct for the intended functionality.

  • 98-108: The quo method correctly handles division and checks for division by zero, returning a MathError if the divisor is zero.

  • 124-156: The FromStr implementation for DecimalExt correctly parses a decimal string, handling negative values and ensuring the parsed value has the correct sign.

  • 166-191: The SdkDec struct and its associated methods are introduced for representing protobuf strings. The methods seem to correctly handle the conversion from DecimalExt.

  • 226-287: The method to_sdk_dec_pb_repr in DecimalExt correctly encodes the decimal to a protobuf representation. However, there is a potential issue with the handling of negative numbers. The method checks for a negative sign and inserts it if necessary, but it does not account for the possibility of the cw::Decimal already being negative, which could lead to double negation.

-        if neg {
-            sdk_dec.insert(0, '-');
-        }

This needs to be verified to ensure that cw::Decimal does not already include the sign in its string representation.

  • 290-338: The method from_sdk_dec in DecimalExt correctly decodes a protobuf representation string back into a DecimalExt. It handles both integer-only and fractional cases and checks for invalid formats.

Comment on lines +30 to +31
# FOR anyone
alias tx="jq -rcs '.[0].txhash' | { read txhash; sleep 3; nibid q tx \$txhash | jq '{txhash, height, code, logs, tx, gas_wanted, gas_used}' >> out.json}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alias tx is defined for extracting the transaction hash and querying transaction details. It's a useful addition for users to quickly retrieve transaction information. However, consider adding a comment explaining the purpose of each part of the command for users who might not be familiar with jq or the other command-line tools used here.

```

```bash
nibid tx wasm inst 1 "$(cat shifter-0-inst.json)" --label="Crazy tester" --no-admin --from=$KEY_NAME -y | tx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The command for contract instantiation using nibid is provided, but it might be helpful to include a brief explanation of the parameters used in the command, such as --label, --no-admin, and --from=$KEY_NAME, to aid users in understanding their purpose and how to modify them if necessary.


```bash
# FOR ME
alias tx="jq -rcs '.[0].txhash' | { read txhash; sleep 3; nibid q tx \$txhash | jq '{txhash, height, code, logs, gas_used, gas_wanted, tx}' | vv}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alias tx is redefined here with a different output command (vv). This could be confusing for users, as the same alias is used for different purposes. It would be better to use distinct alias names for different operations to avoid any ambiguity.

Comment on lines +43 to +44
CONTRACT=nibi14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9ssa9gcs
CONTRACT=nibi1yyca08xqdgvjz0psg56z67ejh9xms6l436u8y58m82npdqqhmmtqzvacjr
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate CONTRACT environment variable declarations are present. This seems like an oversight and could lead to confusion. Only one of these lines should be kept, preferably the one that is intended to be used in subsequent commands.

Comment on lines +86 to +87
nibid
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An incomplete bash command is present. This should either be completed with the correct command or removed if it was added by mistake.

Comment on lines +47 to +65
pub fn add(&self, other: Self) -> Self {
if self.sign == other.sign {
return DecimalExt {
sign: self.sign,
dec: self.dec.add(other.dec),
};
} else if other.dec.is_zero() {
}

let self_dec_gt: bool = self.dec.ge(&other.dec);
let sign = if self_dec_gt { self.sign } else { other.sign };
let dec = if self_dec_gt {
self.dec.sub(other.dec) // if abs(self.dec) > abs(other.dec)
} else {
other.dec.sub(self.dec) // if abs(self.dec) < abs(other.dec)
};
let sign = if dec.is_zero() { Sign::Zero } else { sign };

DecimalExt { sign, dec }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The add method in DecimalExt correctly handles the addition of two decimals considering their signs. However, there is an empty else block at lines 53-54 which should be removed to avoid confusion.

-        } else if other.dec.is_zero() {
-        }

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
pub fn add(&self, other: Self) -> Self {
if self.sign == other.sign {
return DecimalExt {
sign: self.sign,
dec: self.dec.add(other.dec),
};
} else if other.dec.is_zero() {
}
let self_dec_gt: bool = self.dec.ge(&other.dec);
let sign = if self_dec_gt { self.sign } else { other.sign };
let dec = if self_dec_gt {
self.dec.sub(other.dec) // if abs(self.dec) > abs(other.dec)
} else {
other.dec.sub(self.dec) // if abs(self.dec) < abs(other.dec)
};
let sign = if dec.is_zero() { Sign::Zero } else { sign };
DecimalExt { sign, dec }
pub fn add(&self, other: Self) -> Self {
if self.sign == other.sign {
return DecimalExt {
sign: self.sign,
dec: self.dec.add(other.dec),
};
}
let self_dec_gt: bool = self.dec.ge(&other.dec);
let sign = if self_dec_gt { self.sign } else { other.sign };
let dec = if self_dec_gt {
self.dec.sub(other.dec) // if abs(self.dec) > abs(other.dec)
} else {
other.dec.sub(self.dec) // if abs(self.dec) < abs(other.dec)
};
let sign = if dec.is_zero() { Sign::Zero } else { sign };
DecimalExt { sign, dec }

Comment on lines +342 to +521
assert_eq!(neg_num, pos_num.neg());
assert_eq!(pos_num, neg_num.neg());
assert_eq!(zero_num, zero_num.neg());
Ok(())
}

#[test]
fn mul() -> TestResult {
let test_cases: &[(&str, &str, &str)] = &[
("0", "0", "0"),
("0", "420", "0"),
("16", "16", "256"),
("5", "-3", "-15"),
("-7", "7", "-49"),
];
for &(a, b, want_product) in test_cases.iter() {
let a = DecimalExt::from_str(a)?;
let b = DecimalExt::from_str(b)?;
let want_product = DecimalExt::from_str(want_product)?;
let got_product = a.mul(b);
assert_eq!(want_product, got_product);
}
Ok(())
}

#[test]
fn quo() -> TestResult {
let test_cases: &[(&str, &str, &str)] = &[
("0", "420", "0"),
("256", "16", "16"),
("-15", "5", "-3"),
("-49", "-7", "7"),
];
for &(a, b, want_quo) in test_cases.iter() {
let a = DecimalExt::from_str(a)?;
let b = DecimalExt::from_str(b)?;
let want_quo = DecimalExt::from_str(want_quo)?;
let got_quo = a.quo(b)?;
assert_eq!(want_quo, got_quo);
}
Ok(())
}

#[test]
fn sdk_dec_int_only() -> TestResult {
let test_cases: &[(&str, &str)] = &[
// Zero cases should all be equal
("0", &"0".repeat(18)),
("000.00", &"0".repeat(18)),
("0.00", &"0".repeat(18)),
("00000", &"0".repeat(18)),
// Non-zero cases
("10", &format!("10{}", "0".repeat(18))),
("-10", &format!("-10{}", "0".repeat(18))),
("123", &format!("123{}", "0".repeat(18))),
("-123", &format!("-123{}", "0".repeat(18))),
];

for tc in test_cases.iter() {
let (arg, want_sdk_dec) = tc;
let want_dec: DecimalExt = DecimalExt::from_str(arg)?;
let got_sdk_dec: String = want_dec.to_sdk_dec_pb_repr()?;
assert_eq!(want_sdk_dec.to_owned(), got_sdk_dec);

let got_dec = DecimalExt::from_sdk_dec(&got_sdk_dec)?;
assert_eq!(want_dec, got_dec)
}
Ok(())
}

/// to_sdk_dec test with fractional parts
#[test]
fn sdk_dec_fractional() -> TestResult {
let test_cases: &[(&str, &str)] = &[
("0.5", &format!("05{}", "0".repeat(17))),
("0.005", &format!("0005{}", "0".repeat(15))),
("123.456", &format!("123456{}", "0".repeat(15))),
("-123.456", &format!("-123456{}", "0".repeat(15))),
("0.00596", &format!("000596{}", "0".repeat(13))),
("13.5", &format!("135{}", "0".repeat(17))),
("-13.5", &format!("-135{}", "0".repeat(17))),
("1574.00005", &format!("157400005{}", "0".repeat(13))),
];

for tc in test_cases.iter() {
let (arg, want_sdk_dec) = tc;
let want_dec: DecimalExt = DecimalExt::from_str(arg)?;
let got_sdk_dec: String = want_dec.to_sdk_dec_pb_repr()?;
assert_eq!(want_sdk_dec.to_owned(), got_sdk_dec);

let got_dec = DecimalExt::from_sdk_dec(&got_sdk_dec)?;
assert_eq!(want_dec, got_dec)
}
Ok(())
}

#[test]
fn blank_test() -> TestResult {
Ok(())
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test cases provided in the #[cfg(test)] module cover various scenarios for the new methods and types. However, there is a blank test at lines 518-520 that should either be implemented or removed.

-    #[test]
-    fn blank_test() -> TestResult {
-        Ok(())
-    }

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
#[cfg(test)]
mod test_sign_dec {
use cosmwasm_std as cw;
use std::str::FromStr;
use crate::{
errors::TestResult,
math::{DecimalExt, Sign},
};
#[test]
fn default_is_zero() -> TestResult {
assert_eq!(
DecimalExt::default(),
DecimalExt {
sign: Sign::Zero,
dec: cw::Decimal::from_str("0")?
}
);
assert_eq!(DecimalExt::default(), DecimalExt::zero());
assert_eq!(DecimalExt::zero(), cw::Decimal::from_str("0")?.into());
Ok(())
}
#[test]
fn from_cw() -> TestResult {
assert_eq!(
DecimalExt::default(),
DecimalExt::from(cw::Decimal::from_str("0")?)
);
let cw_dec = cw::Decimal::from_str("123.456")?;
assert_eq!(
DecimalExt {
sign: Sign::Positive,
dec: cw_dec
},
DecimalExt::from(cw_dec)
);
let num = "123.456";
assert_eq!(
DecimalExt {
sign: Sign::Negative,
dec: cw::Decimal::from_str(num)?
},
DecimalExt::from_str(&format!("-{}", num))?
);
Ok(())
}
// TODO: How will you handle overflow?
#[test]
fn add() -> TestResult {
let test_cases: &[(&str, &str, &str)] = &[
("0", "0", "0"),
("0", "420", "420"),
("69", "420", "489"),
("5", "-3", "2"),
("-7", "7", "0"),
("-420", "69", "-351"),
("-69", "420", "351"),
];
for &(a, b, want_sum_of) in test_cases.iter() {
let a = DecimalExt::from_str(a)?;
let b = DecimalExt::from_str(b)?;
let want_sum_of = DecimalExt::from_str(want_sum_of)?;
let got_sum_of = a.add(b);
assert_eq!(want_sum_of, got_sum_of);
}
Ok(())
}
#[test]
fn neg() -> TestResult {
let pos_num = DecimalExt::from_str("69")?;
let neg_num = DecimalExt::from_str("-69")?;
let zero_num = DecimalExt::zero();
assert_eq!(neg_num, pos_num.neg());
assert_eq!(pos_num, neg_num.neg());
assert_eq!(zero_num, zero_num.neg());
Ok(())
}
#[test]
fn mul() -> TestResult {
let test_cases: &[(&str, &str, &str)] = &[
("0", "0", "0"),
("0", "420", "0"),
("16", "16", "256"),
("5", "-3", "-15"),
("-7", "7", "-49"),
];
for &(a, b, want_product) in test_cases.iter() {
let a = DecimalExt::from_str(a)?;
let b = DecimalExt::from_str(b)?;
let want_product = DecimalExt::from_str(want_product)?;
let got_product = a.mul(b);
assert_eq!(want_product, got_product);
}
Ok(())
}
#[test]
fn quo() -> TestResult {
let test_cases: &[(&str, &str, &str)] = &[
("0", "420", "0"),
("256", "16", "16"),
("-15", "5", "-3"),
("-49", "-7", "7"),
];
for &(a, b, want_quo) in test_cases.iter() {
let a = DecimalExt::from_str(a)?;
let b = DecimalExt::from_str(b)?;
let want_quo = DecimalExt::from_str(want_quo)?;
let got_quo = a.quo(b)?;
assert_eq!(want_quo, got_quo);
}
Ok(())
}
#[test]
fn sdk_dec_int_only() -> TestResult {
let test_cases: &[(&str, &str)] = &[
// Zero cases should all be equal
("0", &"0".repeat(18)),
("000.00", &"0".repeat(18)),
("0.00", &"0".repeat(18)),
("00000", &"0".repeat(18)),
// Non-zero cases
("10", &format!("10{}", "0".repeat(18))),
("-10", &format!("-10{}", "0".repeat(18))),
("123", &format!("123{}", "0".repeat(18))),
("-123", &format!("-123{}", "0".repeat(18))),
];
for tc in test_cases.iter() {
let (arg, want_sdk_dec) = tc;
let want_dec: DecimalExt = DecimalExt::from_str(arg)?;
let got_sdk_dec: String = want_dec.to_sdk_dec_pb_repr()?;
assert_eq!(want_sdk_dec.to_owned(), got_sdk_dec);
let got_dec = DecimalExt::from_sdk_dec(&got_sdk_dec)?;
assert_eq!(want_dec, got_dec)
}
Ok(())
}
/// to_sdk_dec test with fractional parts
#[test]
fn sdk_dec_fractional() -> TestResult {
let test_cases: &[(&str, &str)] = &[
("0.5", &format!("05{}", "0".repeat(17))),
("0.005", &format!("0005{}", "0".repeat(15))),
("123.456", &format!("123456{}", "0".repeat(15))),
("-123.456", &format!("-123456{}", "0".repeat(15))),
("0.00596", &format!("000596{}", "0".repeat(13))),
("13.5", &format!("135{}", "0".repeat(17))),
("-13.5", &format!("-135{}", "0".repeat(17))),
("1574.00005", &format!("157400005{}", "0".repeat(13))),
];
for tc in test_cases.iter() {
let (arg, want_sdk_dec) = tc;
let want_dec: DecimalExt = DecimalExt::from_str(arg)?;
let got_sdk_dec: String = want_dec.to_sdk_dec_pb_repr()?;
assert_eq!(want_sdk_dec.to_owned(), got_sdk_dec);
let got_dec = DecimalExt::from_sdk_dec(&got_sdk_dec)?;
assert_eq!(want_dec, got_dec)
}
Ok(())
}
#[test]
fn blank_test() -> TestResult {
Ok(())
}

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 3

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 160571a and d29eee2.
Files ignored due to filter (7)
  • Cargo.lock
  • Cargo.toml
  • artifacts/nibi_stargate.wasm
  • artifacts/nibi_stargate_perp.wasm
  • artifacts/nusd_valuator.wasm
  • artifacts/shifter.wasm
  • nibiru-std/Cargo.toml
Files selected for processing (12)
  • .github/codecov.yml (1 hunks)
  • artifacts/checksums.txt (1 hunks)
  • artifacts/checksums_intermediate.txt (1 hunks)
  • contracts/core-shifter/README.md (1 hunks)
  • contracts/core-shifter/src/contract.rs (2 hunks)
  • contracts/core-shifter/src/error.rs (2 hunks)
  • contracts/core-shifter/src/msgs.rs (2 hunks)
  • nibiru-std/src/errors.rs (1 hunks)
  • nibiru-std/src/lib.rs (1 hunks)
  • nibiru-std/src/math.rs (1 hunks)
  • nibiru-std/src/proto/buf/nibiru.oracle.v1.rs (14 hunks)
  • nibiru-std/src/proto/mod.rs (1 hunks)
Files skipped from review due to trivial changes (6)
  • .github/codecov.yml
  • artifacts/checksums.txt
  • artifacts/checksums_intermediate.txt
  • nibiru-std/src/lib.rs
  • nibiru-std/src/proto/buf/nibiru.oracle.v1.rs
  • nibiru-std/src/proto/mod.rs
Files skipped from review as they are similar to previous changes (4)
  • contracts/core-shifter/README.md
  • contracts/core-shifter/src/contract.rs
  • contracts/core-shifter/src/error.rs
  • contracts/core-shifter/src/msgs.rs
Additional comments: 5
nibiru-std/src/math.rs (5)
  • 14-21: The Sign enum is well-defined and uses the #[default] attribute to set Zero as the default value, which is a good practice for clarity and safety.

  • 98-101: The error handling for division by zero in the quo method is correctly implemented, ensuring robust arithmetic operations.

  • 127-154: The FromStr implementation for DecimalExt is comprehensive, covering various input cases and error handling, which aligns with the PR's objectives to improve decimal representations.

  • 166-191: The SdkDec struct and associated methods provide a clear way to handle protobuf representations of decimals, which is part of the PR's objectives to improve protobuf representations.

  • 226-287: The methods to_sdk_dec_pb_repr and from_sdk_dec in DecimalExt are implemented with thorough error handling and validation, ensuring that the protobuf representations are correctly managed.

Comment on lines +25 to +38
#[error("{0}")]
MathError(#[from] MathError),
}

#[derive(Error, Debug, PartialEq)]
pub enum MathError {
#[error("division by zero not well defined")]
DivisionByZero,

#[error("could not parse decimal from string \"{}\": {}", dec_str, err)]
CwDecParseError { dec_str: String, err: cw::StdError },

#[error("could not parse to cosmosdk.io/math.LegacyDec: {0}")]
SdkDecError(String),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The addition of new error variants to MathError and the inclusion of MathError in NibiruError are correctly implemented. However, consider providing more context for the SdkDecError variant to aid in debugging, similar to the detailed message in CwDecParseError.

Comment on lines +47 to +54
pub fn add(&self, other: Self) -> Self {
if self.sign == other.sign {
return DecimalExt {
sign: self.sign,
dec: self.dec.add(other.dec),
};
} else if other.dec.is_zero() {
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The empty else if block at lines 53-54 should be removed as it serves no purpose and could lead to confusion.

-        } else if other.dec.is_zero() {
-        }

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
pub fn add(&self, other: Self) -> Self {
if self.sign == other.sign {
return DecimalExt {
sign: self.sign,
dec: self.dec.add(other.dec),
};
} else if other.dec.is_zero() {
}
pub fn add(&self, other: Self) -> Self {
if self.sign == other.sign {
return DecimalExt {
sign: self.sign,
dec: self.dec.add(other.dec),
};

Comment on lines +518 to +521
#[test]
fn blank_test() -> TestResult {
Ok(())
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The blank test at lines 518-520 should either be implemented or removed to avoid confusion and maintain clean code.

-    #[test]
-    fn blank_test() -> TestResult {
-        Ok(())
-    }

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
#[test]
fn blank_test() -> TestResult {
Ok(())
}

@Unique-Divine Unique-Divine merged commit 3b96257 into main Dec 18, 2023
3 checks passed
@Unique-Divine Unique-Divine deleted the realu/e2e-init branch December 18, 2023 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
epic Project or large task that groups multiple tickets and PRs type: enhancement New feature or request
Projects
None yet
1 participant