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

feat: Add ut to all helper functions #66

Closed
wants to merge 10 commits into from

Conversation

apollo-pablo
Copy link
Contributor

@apollo-pablo apollo-pablo commented Nov 16, 2022

Closes #54

Problem

We dont have any test on math functions.

Tasks

  • Add UT to implementations Helpers functions.
  • Add on every file instead of new files.

Notes

Format and lints failures are from develop branch, we should make a PR and fix them first.

@apollo-pablo apollo-pablo changed the title feat: Add ut to astroport helper Draft: feat: Add ut to astroport helper Nov 16, 2022
@apollo-pablo apollo-pablo self-assigned this Nov 16, 2022
@apollo-pablo apollo-pablo added the enhancement New feature or request label Nov 16, 2022
@apollo-pablo apollo-pablo changed the title Draft: feat: Add ut to astroport helper Draft: feat: Add ut to all helper functions Nov 16, 2022
@pacmanifold pacmanifold marked this pull request as draft November 17, 2022 14:33
Copy link
Contributor

@pacmanifold pacmanifold left a comment

Choose a reason for hiding this comment

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

nice work! 👍 a few comments @apollo-pablo

src/implementations/astroport/helpers.rs Outdated Show resolved Hide resolved
Comment on lines 141 to 142
// do we need clone here since the reference d_product is mut? -> d.clone()
let mut d_product = d;
Copy link
Contributor

Choose a reason for hiding this comment

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

i don't think this should affect the value of d even though d_product is mut. U256 implements the Copy trait

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed the todo

Comment on lines 105 to 107
///
/// [Paper](https://curve.fi/files/stableswap-paper.pdf)
/// [playground](https://github.com/asquare08/AMM-Models/blob/main/Curve%20AMM%20plots.ipynb)
Copy link
Contributor

Choose a reason for hiding this comment

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

this is just a copy from astroports code. Do they reference this? or do they implement it exactlyAs described there? otherwise this might be confusing

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why would be confusing if it gives more information? its describe the formula and the second link is a playground to test things. IMO i would left it as is more helpfull than the eq described in plain text.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

leave the description as original

Comment on lines 55 to 66
let amp_range = next_amp - init_amp;
let res = init_amp + (amp_range * elapsed_time).checked_div(time_range)?;
Ok(res.u128() as u64)
let amp_range = next_amp.checked_sub(init_amp)?;
let res = init_amp
.checked_add((amp_range.checked_mul(elapsed_time))?.checked_div(time_range)?)?;
// Ok(res.u128() as u64) -> downgrading from u128 to u64 implies loose conversion
Ok(u64::try_from(res.u128()).unwrap())
} else {
let amp_range = init_amp - next_amp;
let res = init_amp - (amp_range * elapsed_time).checked_div(time_range)?;
Ok(res.u128() as u64)
let amp_range = init_amp.checked_sub(next_amp)?;
let res = init_amp
.checked_sub((amp_range.checked_mul(elapsed_time))?.checked_div(time_range)?)?;
// Ok(res.u128() as u64) -> downgrading from u128 to u64 implies loose conversion
Ok(u64::try_from(res.u128()).unwrap())
Copy link
Contributor

Choose a reason for hiding this comment

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

since this is a copy of astroports code i think we should keep it as is. If it fails or has rounding errors that will happen on astro also andAll we want is to exactly emulate their behaviour

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, but keep in mind that they change the whole code in their master, so they did it for a reason. They also create a simulator to test the new code , so my guess is that the old code doesnt work (that why test fails) and refactor to a new code that can be tested. astroport stabe-swap simulator

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do we have someone from astroport to talk to about this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

leave the code as original, mark test as failure in code comments. I think if we want to use the original code should be reviewed and tested properly using their simulator. On our ut it fails.

src/implementations/astroport/helpers.rs Outdated Show resolved Hide resolved
src/implementations/astroport/helper_test.rs Outdated Show resolved Hide resolved
@apollo-pablo apollo-pablo changed the title Draft: feat: Add ut to all helper functions feat: Add ut to all helper functions Nov 18, 2022
@apollo-pablo apollo-pablo marked this pull request as ready for review November 18, 2022 11:14
Cargo.toml Outdated
Comment on lines 37 to 38
# TODO: is it safe to use a beta, unaudited code?
wasmswap = { git = "https://github.com/Wasmswap/wasmswap-contracts.git", tag = "v1.1.0-beta", features = ["library"] }
Copy link
Contributor

Choose a reason for hiding this comment

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

We're not sure which versions of wasmswap are live on mainnet actually. We have asked their developers but not yet received a response. There is an open issue. Please remove comment.

Suggested change
# TODO: is it safe to use a beta, unaudited code?
wasmswap = { git = "https://github.com/Wasmswap/wasmswap-contracts.git", tag = "v1.1.0-beta", features = ["library"] }
wasmswap = { git = "https://github.com/Wasmswap/wasmswap-contracts.git", tag = "v1.1.0-beta", features = ["library"] }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed.

Cargo.toml Outdated
# core cosmwasm
cosmwasm-schema = "1.1"
# standard libs
anyhow = "1"
Copy link
Contributor

Choose a reason for hiding this comment

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

What is this used for?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed.

@@ -193,6 +193,7 @@ pub(crate) fn juno_get_token2_amount_required(
token2_reserve: Uint128,
token1_reserve: Uint128,
) -> Result<Uint128, CwDexError> {
// TODO: on master they handle errors https://github.com/Wasmswap/wasmswap-contracts/blob/main/src/contract.rs#L222-L240
Copy link
Contributor

Choose a reason for hiding this comment

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

The question mark operator does the same as their map_err. Remove TODO comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed.

@@ -212,6 +213,7 @@ pub(crate) fn juno_get_token1_amount_required(
token2_reserve: Uint128,
token1_reserve: Uint128,
) -> Result<Uint128, CwDexError> {
// TODO: why liquidity_supply is not used here?
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure even why they use it in juno_get_token2_amount_required, I guess because they are dividing by token1_reserve there, but then they should be checking if that value is zero and not liquidity_supply (even though they would likely be zero at the same time). Regardless, if you look at the code which calls juno_get_token1_amount_required you will see that token2_reserve which we divide with cannot be zero, but perhaps defensive coding here would be good. Feel free to add it if you want and pls remove TODO comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed the TODO.

@@ -252,6 +261,7 @@ pub(crate) fn juno_simulate_provide_liquidity(
let token1_to_use;
let token2_to_use;

// TODO: What happens if pool_ratio == asset_ratio?
Copy link
Contributor

Choose a reason for hiding this comment

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

It will go into the else statement. I don't see an issue here. Can you elaborate on what the problem is? Please remove TODO comment.

Copy link
Contributor Author

@apollo-pablo apollo-pablo Nov 23, 2022

Choose a reason for hiding this comment

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

If pool_ratio == asset_ratio then it goes by the else case.
The description of the else case is

        // We have a higher ratio of token 2 than token1, so calculate how much
        // token2 to use (and approve spend for, since we don't want to approve
        // spend on any extra).

This case doesnt implies that token2 > token1 -> for example suppose:

  • pool_ratio = 1.05 and asset_ratio = 1.05, meaning that the pool is unbalance and the relation between token1 and token2 to deposit is unbalance
  • for asset_ratio token1/token2 = 1.05 implies that token1 is greater than token2

Comment on lines 135 to 138
// Equality with the precision of 1
if d == d_previous {
break;
}
break;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why add extra spacing? Pls use rustfmt.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed.

Comment on lines 237 to 238
/// ### Note
/// This function does not take into account protocol_fee_percent and lp_fee_percent
Copy link
Contributor

Choose a reason for hiding this comment

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

Neither does Junoswap, so why mention it? Please remove comment.

Copy link
Contributor Author

@apollo-pablo apollo-pablo Nov 23, 2022

Choose a reason for hiding this comment

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

removed, but why they added it to the smart contract if they are not going to use it?

Comment on lines 233 to 235
/// ### Requirements
/// - pool_info.token2_reserve > 0
/// - token2.amount > 0
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure what this means. Can you please either remove this or explain it further so its understandable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I explained a little better. The idea of requirements is that a developer should just by seen the description knows what range the function parameters should be as normal path and is great for testers since constrains the SUT. We should add requirements in the future to our descriptions.

token1_denom: usdc.info.0,
token2_reserve: Uint128::from(reserve_b),
token2_denom: dai.info.0,
lp_token_supply: usdc.amount + dai.amount, // should this be reserve_a+reserve_b?
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't matter what this value is. Remove comment.

Copy link
Contributor Author

@apollo-pablo apollo-pablo Nov 23, 2022

Choose a reason for hiding this comment

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

remove.

#[test_case(0,1,0,1 => Ok( (0,0,0) ); "when amount_a and amount_b zero should work")]
#[test_case(30,1,1,1 => with |i: Result<(u128,u128,u128),StdError> | assert!(i.unwrap().2 == 1u128); "when asset_ratio gt pool_ratio with amount_a gt amount_b")] // TODO: what happens with the rest of amount_a?
#[test_case(1,2,1,2 => Ok( (1,2,1) ); "when pool_ratio greater than asset_ratio")]
fn juno_simulate_provide_liquidity_test(
Copy link
Contributor

Choose a reason for hiding this comment

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

Some of these tests fail. Please fix before request review.

Copy link
Contributor Author

@apollo-pablo apollo-pablo Nov 23, 2022

Choose a reason for hiding this comment

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

I fix them, but what happens if someone deposit amount_a = 0 and amount_b = 0 in a balance pool = 1? the result is token2_to_use=1 :
#[test_case(0,1,0,1 => Ok( (0,1,0) ); "when amount_a and amount_b zero should work?")]

Where:

  • input
        amount_a: u128,
        reserve_a: u128,
        amount_b: u128,
        reserve_b: u128
  • output
            result.token1_to_use.amount.u128(),
            result.token2_to_use.amount.u128(),
            result.lp_token_expected_amount.u128(),

@pacmanifold pacmanifold deleted the feat-add-ut-to-helpers branch February 13, 2023 21:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add unit tests for all helper functions
3 participants