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(smart-contracts): add stableswap support for provide liquidity #351

Merged
merged 52 commits into from
Jun 4, 2024

Conversation

nseguias
Copy link
Contributor

@nseguias nseguias commented May 6, 2024

Description and Motivation

This PR adds support for StableSwap pools when providing liquidity through the Pool Manager.

Related Issues

#311


Checklist:

  • I have read Migaloo's contribution guidelines.
  • My pull request has a sound title and description (not something vague like Update index.md)
  • All existing and new tests are passing.
  • I updated/added relevant documentation.
  • The code is formatted properly cargo fmt --all --.
  • Clippy doesn't report any issues cargo clippy -- -D warnings.
  • I have regenerated the schemas if needed cargo schema.

Copy link

codecov bot commented May 7, 2024

Codecov Report

Attention: Patch coverage is 83.91304% with 111 lines in your changes missing coverage. Please review.

Project coverage is 90.90%. Comparing base (1d6ffbc) to head (2f40957).
Report is 36 commits behind head on release/v2_contracts.

Files Patch % Lines
...ontracts/liquidity_hub/pool-manager/sim/src/lib.rs 25.45% 82 Missing ⚠️
...ontracts/liquidity_hub/pool-manager/src/helpers.rs 92.75% 20 Missing ⚠️
...quidity_hub/pool-manager/src/liquidity/commands.rs 64.70% 6 Missing ⚠️
...work/stableswap_3pool/src/stableswap_math/curve.rs 60.00% 2 Missing ⚠️
...ty_hub/pool-manager/src/tests/integration_tests.rs 99.64% 1 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@0xFable 0xFable left a 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;
Copy link
Contributor

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.

Copy link
Contributor Author

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;
}
Copy link
Contributor

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

Copy link
Contributor

Choose a reason for hiding this comment

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

+1

Copy link
Contributor Author

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);
Copy link
Contributor

Choose a reason for hiding this comment

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

Beautiful

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 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),
Copy link
Contributor

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

Copy link
Contributor Author

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.

Copy link
Contributor

@kerber0x kerber0x left a 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.

contracts/liquidity_hub/pool-manager/src/helpers.rs Outdated Show resolved Hide resolved
if d > d_prev {
if d.checked_sub(d_prev).unwrap() <= Uint256::one() {
break;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

+1

Copy link
Contributor

@0xFable 0xFable left a 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());
Copy link
Contributor

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,
Copy link
Contributor

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());
Copy link
Contributor

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 {
Copy link
Contributor

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
Copy link
Contributor

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

@0xFable
Copy link
Contributor

0xFable commented May 30, 2024

Test with diff amp factors on our integration test PR branch

Copy link

Schema generation had missing jobs:


Please run just schemas locally and upload the generated schemas.

kerber0x and others added 24 commits June 4, 2024 11:35
)

* 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
@kerber0x kerber0x force-pushed the feat/stableswap-case-for-lp branch from 37aef80 to 8302636 Compare June 4, 2024 10:39
@nseguias nseguias merged commit e6e6d2a into release/v2_contracts Jun 4, 2024
6 of 7 checks passed
@nseguias nseguias deleted the feat/stableswap-case-for-lp branch June 4, 2024 16:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants