-
Notifications
You must be signed in to change notification settings - Fork 4
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
Conversation
Signed-off-by: apollo-pablo <[email protected]>
Signed-off-by: apollo-pablo <[email protected]>
There was a problem hiding this 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
// do we need clone here since the reference d_product is mut? -> d.clone() | ||
let mut d_product = d; |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed the todo
/// | ||
/// [Paper](https://curve.fi/files/stableswap-paper.pdf) | ||
/// [playground](https://github.com/asquare08/AMM-Models/blob/main/Curve%20AMM%20plots.ipynb) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
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()) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
Signed-off-by: apollo-pablo <[email protected]>
…lpers files Signed-off-by: apollo-pablo <[email protected]>
Cargo.toml
Outdated
# 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"] } |
There was a problem hiding this comment.
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.
# 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"] } |
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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? |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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? |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
// Equality with the precision of 1 | ||
if d == d_previous { | ||
break; | ||
} | ||
break; | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed.
/// ### Note | ||
/// This function does not take into account protocol_fee_percent and lp_fee_percent |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
/// ### Requirements | ||
/// - pool_info.token2_reserve > 0 | ||
/// - token2.amount > 0 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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? |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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(),
Signed-off-by: apollo-pablo <[email protected]>
Signed-off-by: apollo-pablo <[email protected]>
Closes #54
We dont have any test on math functions.
Format and lints failures are from develop branch, we should make a PR and fix them first.