-
Notifications
You must be signed in to change notification settings - Fork 22
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(smart-contracts): add stableswap support for provide liquidity #351
Conversation
…so we can provide liquidity with 2, 3, or N assets
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## release/v2_contracts #351 +/- ##
========================================================
- Coverage 91.15% 90.90% -0.26%
========================================================
Files 279 280 +1
Lines 31119 31830 +711
========================================================
+ Hits 28368 28936 +568
- Misses 2751 2894 +143 ☔ View full report in Codecov by Sentry. |
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.
LGTM great work you did it exactly as I was thinking it needed to be done.
I think now with mimimal changes we can bump N_coins to offer more pools down the line.
@@ -18,15 +18,15 @@ const NEWTON_ITERATIONS: u64 = 32; | |||
|
|||
// todo isn't this for the 3pool? shouldn't it be 3 | |||
// the number of assets in the pool | |||
const N_COINS: Uint256 = Uint256::from_u128(2); | |||
pub const N_COINS: u8 = 3; |
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, was hoping other than some calculation changes it would work like 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.
using Uint256::from(pool_info.assets.len() as u128)
now
if d > d_prev { | ||
if d.checked_sub(d_prev).unwrap() <= Uint256::one() { | ||
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.
Recommend adding some unit tests here. Logic looks right but its complicated
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.
+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.
All 3pool tests && proptests have been refactored and integrated into the pool-manager
if total_share == Uint128::zero() { | ||
// Make sure at least MINIMUM_LIQUIDITY_AMOUNT is deposited to mitigate the risk of the first | ||
// depositor preventing small liquidity providers from joining the pool | ||
let min_lp_token_amount = MINIMUM_LIQUIDITY_AMOUNT * Uint128::from(3u8); |
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.
Beautiful
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 actually change it to work with N amount of assets let min_lp_token_amount = MINIMUM_LIQUIDITY_AMOUNT * Uint128::from(pool_assets.len() as u128)
vec![ | ||
Coin { | ||
denom: "uwhale".to_string(), | ||
amount: Uint128::from(MINIMUM_LIQUIDITY_AMOUNT), |
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.
can you add a test or enhance this test to do a swap against the 3 pool
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 doing a swap a lil bit further down.
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 looks good overall, however i think it won't work for a stableswap with 2 assets as there's N_COINS
and other hardcoded value equal to 3
. Also, the unit tests for computing the d and other values for the stableswap were not transferred from the stableswap code.
I'd suggest all these compute_d and related methods to be moved to a file called math.
if d > d_prev { | ||
if d.checked_sub(d_prev).unwrap() <= Uint256::one() { | ||
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.
+1
contracts/liquidity_hub/pool-manager/src/tests/integration_tests.rs
Outdated
Show resolved
Hide resolved
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.
Only re-reviewed changes since my last review.
Looks really good! I like how you were able to preserve what looked like deccent test coverage from the stableswap contract.
Some nice descriptive comments in here explaining the hard math too I love to see it
LGTM and great work 🚀
offer_pool: Decimal256, | ||
ask_pool: Decimal256, | ||
amp: &u64, | ||
precision: u8, | ||
) -> Result<Decimal256, ContractError> { | ||
let n_coins = Decimal256::from_ratio(Uint256::from(N_COINS), Uint256::from_u128(1)); | ||
let n_coins_decimal = Decimal256::from_ratio(n_coins, Uint256::one()); |
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.
Good change, N_COINS was only ever meant to be a placeholder CONSTANT, better to have it as an input like u did here and now its generalized to N
@@ -180,6 +192,7 @@ pub fn compute_swap( | |||
let offer_amount = Decimal256::decimal_with_precision(offer_amount, offer_precision)?; | |||
|
|||
let new_pool = calculate_stableswap_y( | |||
n_coins, |
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.
Good stuff, I am sure ill see it lower in the rewview but I think the N value here becomes very important for all calculcations now
.fold(Uint256::zero(), |acc, x| acc.checked_add(x).unwrap()); | ||
let deposits_total: Uint256 = deposits | ||
.into_iter() | ||
.fold(Uint256::zero(), |acc, x| acc.checked_add(x).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.
Im fine with you keeping the unwraps, I learned over my journey unwraps are actually sound enough if you are checking all the usual stuff, overflow errors will be fine to depend on as long as you have added them to the errors file.
@@ -688,26 +714,27 @@ pub fn compute_d(amp_factor: &u64, deposits: &Vec<Coin>) -> Option<Uint256> { | |||
// Newton's method to approximate D | |||
let mut d_prev: Uint256; | |||
let mut d: Uint256 = sum_x.into(); | |||
for amount in amount_times_coins.into_iter() { | |||
for _ in 0..256 { |
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.
is this just like removing the outer loop? Cool if so
.checked_add(no_swap.into()) | ||
.unwrap(); | ||
|
||
// Solve for y by approximating: y**2 + b*y = c |
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.
good comments, we could maybe have even more of them but im happy with these.
This is super complex stuff and the code is in no way 'self-documenting'.. hate that term lol these comments are huge to help understand what all these purple functions are doing
Test with diff amp factors on our integration test PR branch |
Schema generation had missing jobs:
Please run |
Co-authored-by: 0xFable <[email protected]>
Co-authored-by: 0xFable <[email protected]>
) * fix: Rework all v2 contracts to use bonding-manager not whale-lair + Removes all references to whale-lair for V2 contracts + Updates all schemas and most unit tests + Start of integration test rework for incentive manager The tests rework will take a bigger effort/another pass * fix: Update reference to whale_lair
37aef80
to
8302636
Compare
Description and Motivation
This PR adds support for
StableSwap
pools when providing liquidity through the Pool Manager.Related Issues
#311
Checklist:
Update index.md
)cargo fmt --all --
.cargo clippy -- -D warnings
.cargo schema
.