diff --git a/README.md b/README.md index f51386b..3f02783 100644 --- a/README.md +++ b/README.md @@ -8,21 +8,15 @@ Infinity Pool is an automated market maker (AMM) protocol that allows for the bu This protocol is a derivative of the [sudoswap](https://github.com/sudoswap/lssvm) protocol written in Solidity. Infinity Pool makes use of the sudoswap design, but is written for [CosmWasm](https://github.com/CosmWasm/cosmwasm) so that it may be used on Cosmos SDK based chains. -## AMM Vs Order Book - -The Infinity Pool protocol could offer some distinct advantages over the traditional order book model. Apart from being a fun tool for crypto natives, it allows for more expressive order types to be specified on chain. For example, by creating a one-sided pool with a special bonding curve, a user could effectively be creating a limit order that mutates after each trade it processes. This is difficult to do with the traditional order book model. - -Additionally, there are special mechanics native to double-sided pools that are not as familar to order books. An NFT project could use a double-sided to pool to easliy create a market with liquidity on both the buy and sell side. Liquidity providers could also be incentivized to provide liquidity to the pool by offering a portion of the fees generated by the pool. If a community wanted to induce liquidity they could make use of this feature. - -Most notably, this protocol would not necessarily hinder the performance of an on-chain orderbook as long as it exists on the same chain. Trades could easily be routed between the two protocols the same way an NFT aggregator like Genie routes between OpenSea and sudoswap. - ## How It Works -As described by the sudoswap protocol: +> 1. Liquidity providers begin by creating a pool with specific parameters. They define which pools the assets will hold and the bonding curve which will be used to determine the price. Once the pool is created, liquidity providers can deposit tokens and/or NFTs into the pool. Once the pool is funded, liquidity providers can activate the pool so that it can begin trading. +> 2. Traders can then buy and sell NFTs from the pool. The price of the NFTs is determined by the bonding curve and the assets held by the pool. The price of the NFTs will change as the pool is traded. +> 3. Liquidity providers can withdraw their assets from the pool at any time. + +### Creating Pools -> 1. Liquidity providers deposit NFTs and/or a fungible token into liquidity pools. They choose whether they would like to buy or sell NFTs (or both) and specify a starting price and bonding curve parameters. -> 2. Users can then buy NFTs from or sell NFTs into these pools. Every time an item is bought or sold, the price to buy or sell another item changes for the pool based on its bonding curve. -> 3. At any time, liquidity providers can change the parameters of their pool or withdraw assets. +Creating pools follows a three message process where the first message creates the pool, the second message deposits assets into the pool, and the third message activates the pool. The three messages can be concatenated into a single transaction by the client. ### Types of Pools @@ -38,14 +32,28 @@ The `pool_type` parameter refers to the asset that the pool holds: - A `Exponential` bonding curve has a slope that increases or decreases by a percentage with each NFT that is bought or sold to the pool. - A `Constant Product` bonding curve specifies that the product of two reserve assets remains constant after every trade. - +- Pool pricing indexed within the contract for optimized price discovery +- Respects listing price of marketplace contract +- Respects the minimum price of marketplace contract +- Respects the maximum finders fee of marketplace contract +- Respects the trading fee percentage of the marketplace contract +- Pool owner can set a finders fee that is paid to the finder address on a trade +- Pool owner can set a swap fee that is paid to the pool owner of a Trade pool +- Reinvestment of tokens and NFTs back into Trade pools based on parameter flags +- Flexible asset redirection for trader and pool owner +- Queries that allow for simulation of swaps +- User slippage tolerance for swaps +- User may decide to revert whole transaction or revert individual swaps using the robust flag diff --git a/contracts/infinity-pool/src/lib.rs b/contracts/infinity-pool/src/lib.rs index a052eab..819314a 100644 --- a/contracts/infinity-pool/src/lib.rs +++ b/contracts/infinity-pool/src/lib.rs @@ -1,3 +1,5 @@ +#![allow(clippy::too_many_arguments)] + pub mod execute; pub mod instantiate; pub mod msg; diff --git a/contracts/infinity-pool/src/swap_processor.rs b/contracts/infinity-pool/src/swap_processor.rs index 4338a2b..0e0762c 100644 --- a/contracts/infinity-pool/src/swap_processor.rs +++ b/contracts/infinity-pool/src/swap_processor.rs @@ -76,6 +76,8 @@ pub struct Swap { pub seller_payment: Option, } +type IterResults = StdResult<(u64, PoolQuote)>; + /// A struct for managing a series of swaps pub struct SwapProcessor<'a> { /// The type of transaction (buy or sell) @@ -97,7 +99,7 @@ pub struct SwapProcessor<'a> { /// The latest pool that was retrieved pub latest: Option, /// An iterator for retrieving sorted pool quotes - pub pool_quote_iter: Option> + 'a>>, + pub pool_quote_iter: Option + 'a>>, /// A list of swaps that have been processed pub swaps: Vec, } diff --git a/contracts/infinity-pool/src/testing/helpers/fixtures.rs b/contracts/infinity-pool/src/testing/helpers/fixtures.rs index f5d4b6e..194fcf9 100644 --- a/contracts/infinity-pool/src/testing/helpers/fixtures.rs +++ b/contracts/infinity-pool/src/testing/helpers/fixtures.rs @@ -1,214 +1,181 @@ +use crate::msg::ExecuteMsg; use crate::state::{BondingCurve, Pool, PoolType}; use crate::testing::helpers::nft_functions::{approve, mint}; use crate::testing::helpers::pool_functions::create_pool; use cosmwasm_std::{Addr, Uint128}; use sg_multi_test::StargazeApp; -use std::collections::BTreeSet; use super::pool_functions::{activate, deposit_nfts, deposit_tokens}; -pub fn get_pool_fixtures( - collection: Addr, - creator: Addr, - user: Addr, - asset_account: Addr, -) -> Vec { +pub fn get_pool_fixtures(collection: &Addr, asset_account: &Addr) -> Vec { vec![ - Pool { - id: 1, - collection: collection.clone(), - owner: creator.clone(), - asset_recipient: Some(asset_account.clone()), + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), pool_type: PoolType::Token, bonding_curve: BondingCurve::Linear, spot_price: Uint128::from(100u64), delta: Uint128::from(10u64), - total_tokens: Uint128::from(0u64), - nft_token_ids: BTreeSet::new(), - fee_bps: None, - is_active: false, + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_nfts: false, + reinvest_tokens: false, }, - Pool { - id: 2, - collection: collection.clone(), - owner: creator.clone(), - asset_recipient: Some(asset_account.clone()), + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), pool_type: PoolType::Token, bonding_curve: BondingCurve::Exponential, spot_price: Uint128::from(200u64), delta: Uint128::from(20u64), - total_tokens: Uint128::from(0u64), - nft_token_ids: BTreeSet::new(), - fee_bps: None, - is_active: false, + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_nfts: false, + reinvest_tokens: false, }, - Pool { - id: 3, - collection: collection.clone(), - owner: creator.clone(), - asset_recipient: Some(asset_account.clone()), + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), pool_type: PoolType::Nft, bonding_curve: BondingCurve::Linear, spot_price: Uint128::from(300u64), delta: Uint128::from(30u64), - total_tokens: Uint128::from(0u64), - nft_token_ids: BTreeSet::new(), - fee_bps: None, - is_active: false, + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_nfts: false, + reinvest_tokens: false, }, - Pool { - id: 4, - collection: collection.clone(), - owner: creator.clone(), - asset_recipient: Some(asset_account.clone()), + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), pool_type: PoolType::Nft, bonding_curve: BondingCurve::Exponential, spot_price: Uint128::from(400u64), delta: Uint128::from(40u64), - total_tokens: Uint128::from(0u64), - nft_token_ids: BTreeSet::new(), - fee_bps: None, - is_active: false, + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_nfts: false, + reinvest_tokens: false, }, - Pool { - id: 5, - collection: collection.clone(), - owner: creator.clone(), - asset_recipient: Some(asset_account.clone()), + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), pool_type: PoolType::Trade, bonding_curve: BondingCurve::Linear, spot_price: Uint128::from(500u64), delta: Uint128::from(50u64), - total_tokens: Uint128::from(0u64), - nft_token_ids: BTreeSet::new(), - fee_bps: Some(50u16), - is_active: false, + finders_fee_bps: 0, + swap_fee_bps: 50, + reinvest_nfts: false, + reinvest_tokens: false, }, - Pool { - id: 6, - collection: collection.clone(), - owner: creator.clone(), - asset_recipient: Some(asset_account.clone()), + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), pool_type: PoolType::Trade, bonding_curve: BondingCurve::Exponential, spot_price: Uint128::from(600u64), delta: Uint128::from(60u64), - total_tokens: Uint128::from(0u64), - nft_token_ids: BTreeSet::new(), - fee_bps: Some(60u16), - is_active: false, + finders_fee_bps: 0, + swap_fee_bps: 60, + reinvest_nfts: false, + reinvest_tokens: false, }, - Pool { - id: 7, - collection: collection.clone(), - owner: creator, - asset_recipient: Some(asset_account.clone()), + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), pool_type: PoolType::Trade, bonding_curve: BondingCurve::ConstantProduct, spot_price: Uint128::from(700u64), delta: Uint128::from(70u64), - total_tokens: Uint128::from(0u64), - nft_token_ids: BTreeSet::new(), - fee_bps: Some(70u16), - is_active: false, + finders_fee_bps: 0, + swap_fee_bps: 70, + reinvest_nfts: false, + reinvest_tokens: false, }, - Pool { - id: 8, - collection: collection.clone(), - owner: user.clone(), - asset_recipient: Some(asset_account.clone()), + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), pool_type: PoolType::Token, bonding_curve: BondingCurve::Linear, spot_price: Uint128::from(800u64), delta: Uint128::from(80u64), - total_tokens: Uint128::from(0u64), - nft_token_ids: BTreeSet::new(), - fee_bps: None, - is_active: false, + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_nfts: false, + reinvest_tokens: false, }, - Pool { - id: 9, - collection: collection.clone(), - owner: user.clone(), - asset_recipient: Some(asset_account.clone()), + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), pool_type: PoolType::Token, bonding_curve: BondingCurve::Exponential, spot_price: Uint128::from(900u64), delta: Uint128::from(90u64), - total_tokens: Uint128::from(0u64), - nft_token_ids: BTreeSet::new(), - fee_bps: None, - is_active: false, + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_nfts: false, + reinvest_tokens: false, }, - Pool { - id: 10, - collection: collection.clone(), - owner: user.clone(), - asset_recipient: Some(asset_account.clone()), + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), pool_type: PoolType::Nft, bonding_curve: BondingCurve::Linear, spot_price: Uint128::from(1000u64), delta: Uint128::from(100u64), - total_tokens: Uint128::from(0u64), - nft_token_ids: BTreeSet::new(), - fee_bps: None, - is_active: false, + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_nfts: false, + reinvest_tokens: false, }, - Pool { - id: 11, - collection: collection.clone(), - owner: user.clone(), - asset_recipient: Some(asset_account.clone()), + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), pool_type: PoolType::Nft, bonding_curve: BondingCurve::Exponential, spot_price: Uint128::from(1100u64), delta: Uint128::from(110u64), - total_tokens: Uint128::from(0u64), - nft_token_ids: BTreeSet::new(), - fee_bps: None, - is_active: false, + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_nfts: false, + reinvest_tokens: false, }, - Pool { - id: 12, - collection: collection.clone(), - owner: user.clone(), - asset_recipient: Some(asset_account.clone()), + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), pool_type: PoolType::Trade, bonding_curve: BondingCurve::Linear, spot_price: Uint128::from(1200u64), delta: Uint128::from(120u64), - total_tokens: Uint128::from(0u64), - nft_token_ids: BTreeSet::new(), - fee_bps: Some(50u16), - is_active: false, + finders_fee_bps: 0, + swap_fee_bps: 50, + reinvest_nfts: false, + reinvest_tokens: false, }, - Pool { - id: 13, - collection: collection.clone(), - owner: user.clone(), - asset_recipient: Some(asset_account.clone()), + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), pool_type: PoolType::Trade, bonding_curve: BondingCurve::Exponential, spot_price: Uint128::from(1300u64), delta: Uint128::from(130u64), - total_tokens: Uint128::from(0u64), - nft_token_ids: BTreeSet::new(), - fee_bps: Some(60u16), - is_active: false, + finders_fee_bps: 0, + swap_fee_bps: 60, + reinvest_nfts: false, + reinvest_tokens: false, }, - Pool { - id: 14, - collection, - owner: user, - asset_recipient: Some(asset_account), + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), pool_type: PoolType::Trade, bonding_curve: BondingCurve::ConstantProduct, spot_price: Uint128::from(1400u64), delta: Uint128::from(140u64), - total_tokens: Uint128::from(0u64), - nft_token_ids: BTreeSet::new(), - fee_bps: Some(70u16), - is_active: false, + finders_fee_bps: 0, + swap_fee_bps: 70, + reinvest_nfts: false, + reinvest_tokens: false, }, ] } @@ -221,21 +188,15 @@ pub fn create_pool_fixtures( user: Addr, asset_account: Addr, ) -> Vec { - let pools = get_pool_fixtures(collection, creator, user, asset_account); - for pool in pools.iter() { - create_pool( - router, - infinity_pool.clone(), - pool.owner.clone(), - pool.collection.clone(), - pool.asset_recipient.clone(), - pool.pool_type.clone(), - pool.bonding_curve.clone(), - pool.spot_price, - pool.delta, - pool.fee_bps, - ) - .unwrap(); + let msgs = get_pool_fixtures(&collection, &asset_account); + let mut pools = vec![]; + for (usize, msg) in msgs.into_iter().enumerate() { + let sender = if usize < 7 { + creator.clone() + } else { + user.clone() + }; + pools.push(create_pool(router, infinity_pool.clone(), sender.clone(), msg).unwrap()); } pools } @@ -246,24 +207,13 @@ pub fn create_and_activate_pool_fixtures( minter: Addr, collection: Addr, creator: Addr, - user: Addr, + _user: Addr, asset_account: Addr, ) -> Vec { - let pools = get_pool_fixtures(collection.clone(), creator, user, asset_account); - for pool in pools.iter() { - create_pool( - router, - infinity_pool.clone(), - pool.owner.clone(), - pool.collection.clone(), - pool.asset_recipient.clone(), - pool.pool_type.clone(), - pool.bonding_curve.clone(), - pool.spot_price, - pool.delta, - pool.fee_bps, - ) - .unwrap(); + let msgs = get_pool_fixtures(&collection, &asset_account); + let mut pools = vec![]; + for msg in msgs.into_iter() { + let pool = create_pool(router, infinity_pool.clone(), creator.clone(), msg).unwrap(); if pool.can_buy_nfts() { deposit_tokens( router, @@ -300,6 +250,7 @@ pub fn create_and_activate_pool_fixtures( true, ) .unwrap(); + pools.push(pool); } pools } diff --git a/contracts/infinity-pool/src/testing/helpers/pool_functions.rs b/contracts/infinity-pool/src/testing/helpers/pool_functions.rs index d9852be..56d3268 100644 --- a/contracts/infinity-pool/src/testing/helpers/pool_functions.rs +++ b/contracts/infinity-pool/src/testing/helpers/pool_functions.rs @@ -1,5 +1,5 @@ -use crate::msg::ExecuteMsg; -use crate::state::{BondingCurve, PoolType}; +use crate::msg::{ExecuteMsg, PoolsByIdResponse, QueryMsg}; +use crate::state::Pool; use anyhow::Error; use cosmwasm_std::{coins, Addr, Uint128}; use cw_multi_test::Executor; @@ -10,30 +10,25 @@ pub fn create_pool( router: &mut StargazeApp, infinity_pool: Addr, creator: Addr, - collection: Addr, - asset_account: Option, - pool_type: PoolType, - bonding_curve: BondingCurve, - spot_price: Uint128, - delta: Uint128, - fee_bps: Option, -) -> Result { - let msg = ExecuteMsg::CreatePool { - collection: collection.to_string(), - asset_recipient: asset_account.map(|a| a.to_string()), - pool_type, - bonding_curve, - spot_price, - delta, - fee_bps, - }; - let res = router.execute_contract(creator, infinity_pool, &msg, &[]); + msg: ExecuteMsg, +) -> Result { + let res = router.execute_contract(creator, infinity_pool.clone(), &msg, &[]); assert!(res.is_ok()); let pool_id = res.unwrap().events[1].attributes[1] .value .parse::() .unwrap(); - Ok(pool_id) + + let query_msg = QueryMsg::PoolsById { + pool_ids: vec![pool_id], + }; + let res: PoolsByIdResponse = router + .wrap() + .query_wasm_smart(infinity_pool, &query_msg) + .unwrap(); + + let pool = res.pools[0].1.clone().unwrap(); + Ok(pool) } pub fn deposit_tokens( diff --git a/contracts/infinity-pool/src/testing/setup/setup_infinity_pool.rs b/contracts/infinity-pool/src/testing/setup/setup_infinity_pool.rs index b8346f6..c9803cd 100644 --- a/contracts/infinity-pool/src/testing/setup/setup_infinity_pool.rs +++ b/contracts/infinity-pool/src/testing/setup/setup_infinity_pool.rs @@ -14,6 +14,7 @@ pub fn setup_infinity_pool( let msg = crate::msg::InstantiateMsg { denom: NATIVE_DENOM.to_string(), marketplace_addr: marketplace_addr.to_string(), + developer: None, }; let infinity_pool = router .instantiate_contract(infinity_pool_id, sender, &msg, &[], "Infinity Pool", None) diff --git a/contracts/infinity-pool/src/testing/tests/multitest.rs b/contracts/infinity-pool/src/testing/tests/multitest.rs index b5c5f41..769b65f 100644 --- a/contracts/infinity-pool/src/testing/tests/multitest.rs +++ b/contracts/infinity-pool/src/testing/tests/multitest.rs @@ -17,6 +17,7 @@ fn proper_initialization() { let msg = InstantiateMsg { denom: NATIVE_DENOM.to_string(), marketplace_addr: marketplace_addr.to_string(), + developer: None, }; let info = mock_info("creator", &coins(1000, NATIVE_DENOM)); diff --git a/contracts/infinity-pool/src/testing/tests/pool_tests/nft_pool_tests.rs b/contracts/infinity-pool/src/testing/tests/pool_tests/nft_pool_tests.rs index 561f38d..7dc7622 100644 --- a/contracts/infinity-pool/src/testing/tests/pool_tests/nft_pool_tests.rs +++ b/contracts/infinity-pool/src/testing/tests/pool_tests/nft_pool_tests.rs @@ -35,7 +35,10 @@ fn create_nft_pool() { bonding_curve: BondingCurve::ConstantProduct, spot_price: Uint128::from(2400u64), delta: Uint128::from(120u64), - fee_bps: None, + finders_fee_bps: 0, + swap_fee_bps: 0u64, + reinvest_nfts: false, + reinvest_tokens: false, }; let res = router.execute_contract(creator.clone(), infinity_pool.clone(), &msg, &[]); assert_error( @@ -53,12 +56,15 @@ fn create_nft_pool() { bonding_curve: BondingCurve::Linear, spot_price: Uint128::from(2400u64), delta: Uint128::from(120u64), - fee_bps: Some(0u16), + finders_fee_bps: 0, + swap_fee_bps: 100u64, + reinvest_nfts: false, + reinvest_tokens: false, }; let res = router.execute_contract(creator.clone(), infinity_pool.clone(), &msg, &[]); assert_error( res, - ContractError::InvalidPool(String::from("fee_bps must be 0 for nft pool")), + ContractError::InvalidPool(String::from("swap_fee_percent must be 0 for nft pool")), ); // Can create a Linear Nft Pool @@ -69,7 +75,10 @@ fn create_nft_pool() { bonding_curve: BondingCurve::Linear, spot_price: Uint128::from(2400u64), delta: Uint128::from(120u64), - fee_bps: None, + finders_fee_bps: 0, + swap_fee_bps: 0u64, + reinvest_nfts: false, + reinvest_tokens: false, }; let res = router.execute_contract(creator.clone(), infinity_pool.clone(), &msg, &[]); assert!(res.is_ok()); @@ -82,7 +91,10 @@ fn create_nft_pool() { bonding_curve: BondingCurve::Exponential, spot_price: Uint128::from(2400u64), delta: Uint128::from(120u64), - fee_bps: None, + finders_fee_bps: 0, + swap_fee_bps: 0u64, + reinvest_nfts: false, + reinvest_tokens: false, }; let res = router.execute_contract(creator, infinity_pool, &msg, &[]); assert!(res.is_ok()); @@ -106,17 +118,22 @@ fn deposit_assets_nft_pool() { let marketplace = setup_marketplace(&mut router, creator.clone()).unwrap(); let infinity_pool = setup_infinity_pool(&mut router, creator.clone(), marketplace).unwrap(); - let pool_id = create_pool( + let pool = create_pool( &mut router, infinity_pool.clone(), creator.clone(), - collection.clone(), - Some(asset_account), - PoolType::Nft, - BondingCurve::Linear, - Uint128::from(2400u64), - Uint128::from(100u64), - None, + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), + pool_type: PoolType::Nft, + bonding_curve: BondingCurve::Linear, + spot_price: Uint128::from(2400u64), + delta: Uint128::from(100u64), + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_tokens: false, + reinvest_nfts: false, + }, ) .unwrap(); @@ -126,7 +143,7 @@ fn deposit_assets_nft_pool() { let token_id_2 = mint(&mut router, &user1, minter); approve(&mut router, &user1, &collection, &infinity_pool, token_id_2); let msg = ExecuteMsg::DepositNfts { - pool_id, + pool_id: pool.id, collection: collection.to_string(), nft_token_ids: vec![token_id_1.to_string(), token_id_2.to_string()], }; @@ -154,7 +171,7 @@ fn deposit_assets_nft_pool() { token_id_2, ); let msg = ExecuteMsg::DepositNfts { - pool_id, + pool_id: pool.id, collection: collection.to_string(), nft_token_ids: vec![token_id_1.to_string(), token_id_2.to_string()], }; @@ -163,7 +180,7 @@ fn deposit_assets_nft_pool() { // Owner cannot deposit tokens into nft pool let deposit_amount = 1000u128; - let msg = ExecuteMsg::DepositTokens { pool_id }; + let msg = ExecuteMsg::DepositTokens { pool_id: pool.id }; let res = router.execute_contract( creator, infinity_pool, diff --git a/contracts/infinity-pool/src/testing/tests/pool_tests/token_pool_tests.rs b/contracts/infinity-pool/src/testing/tests/pool_tests/token_pool_tests.rs index d74bdda..26bde79 100644 --- a/contracts/infinity-pool/src/testing/tests/pool_tests/token_pool_tests.rs +++ b/contracts/infinity-pool/src/testing/tests/pool_tests/token_pool_tests.rs @@ -35,7 +35,10 @@ fn create_token_pool() { bonding_curve: BondingCurve::ConstantProduct, spot_price: Uint128::from(2400u64), delta: Uint128::from(120u64), - fee_bps: None, + finders_fee_bps: 0, + swap_fee_bps: 0u64, + reinvest_nfts: false, + reinvest_tokens: false, }; let res = router.execute_contract(creator.clone(), infinity_pool.clone(), &msg, &[]); assert_error( @@ -53,12 +56,15 @@ fn create_token_pool() { bonding_curve: BondingCurve::Linear, spot_price: Uint128::from(2400u64), delta: Uint128::from(120u64), - fee_bps: Some(0u16), + finders_fee_bps: 0, + swap_fee_bps: 100u64, + reinvest_nfts: false, + reinvest_tokens: false, }; let res = router.execute_contract(creator.clone(), infinity_pool.clone(), &msg, &[]); assert_error( res, - ContractError::InvalidPool(String::from("fee_bps must be 0 for token pool")), + ContractError::InvalidPool(String::from("swap_fee_percent must be 0 for token pool")), ); // Can create a Linear Token Pool @@ -69,7 +75,10 @@ fn create_token_pool() { bonding_curve: BondingCurve::Linear, spot_price: Uint128::from(2400u64), delta: Uint128::from(120u64), - fee_bps: None, + finders_fee_bps: 0, + swap_fee_bps: 0u64, + reinvest_nfts: false, + reinvest_tokens: false, }; let res = router.execute_contract(creator.clone(), infinity_pool.clone(), &msg, &[]); assert!(res.is_ok()); @@ -82,7 +91,10 @@ fn create_token_pool() { bonding_curve: BondingCurve::Exponential, spot_price: Uint128::from(2400u64), delta: Uint128::from(120u64), - fee_bps: None, + finders_fee_bps: 0, + swap_fee_bps: 0u64, + reinvest_nfts: false, + reinvest_tokens: false, }; let res = router.execute_contract(creator, infinity_pool, &msg, &[]); assert!(res.is_ok()); @@ -106,23 +118,28 @@ fn deposit_assets_token_pool() { let marketplace = setup_marketplace(&mut router, creator.clone()).unwrap(); let infinity_pool = setup_infinity_pool(&mut router, creator.clone(), marketplace).unwrap(); - let pool_id = create_pool( + let pool = create_pool( &mut router, infinity_pool.clone(), creator.clone(), - collection.clone(), - Some(asset_account), - PoolType::Token, - BondingCurve::Linear, - Uint128::from(2400u64), - Uint128::from(100u64), - None, + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), + pool_type: PoolType::Token, + bonding_curve: BondingCurve::Linear, + spot_price: Uint128::from(2400u64), + delta: Uint128::from(100u64), + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_tokens: false, + reinvest_nfts: false, + }, ) .unwrap(); // Only owner of pool can deposit tokens let deposit_amount = 1000u128; - let msg = ExecuteMsg::DepositTokens { pool_id }; + let msg = ExecuteMsg::DepositTokens { pool_id: pool.id }; let res = router.execute_contract( user1, infinity_pool.clone(), @@ -136,7 +153,7 @@ fn deposit_assets_token_pool() { // Owner can deposit tokens let deposit_amount_1 = 1250u128; - let msg = ExecuteMsg::DepositTokens { pool_id }; + let msg = ExecuteMsg::DepositTokens { pool_id: pool.id }; let res = router.execute_contract( creator.clone(), infinity_pool.clone(), @@ -151,7 +168,7 @@ fn deposit_assets_token_pool() { &mut router, infinity_pool.clone(), creator.clone(), - pool_id, + pool.id, Uint128::from(deposit_amount_2), ) .unwrap(); @@ -175,7 +192,7 @@ fn deposit_assets_token_pool() { token_id_2, ); let msg = ExecuteMsg::DepositNfts { - pool_id, + pool_id: pool.id, collection: collection.to_string(), nft_token_ids: vec![token_id_1.to_string(), token_id_2.to_string()], }; @@ -203,17 +220,22 @@ fn withdraw_assets_token_pool() { let marketplace = setup_marketplace(&mut router, creator.clone()).unwrap(); let infinity_pool = setup_infinity_pool(&mut router, creator.clone(), marketplace).unwrap(); - let pool_id = create_pool( + let pool = create_pool( &mut router, infinity_pool.clone(), creator.clone(), - collection, - Some(asset_account.clone()), - PoolType::Token, - BondingCurve::Linear, - Uint128::from(2400u64), - Uint128::from(100u64), - None, + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), + pool_type: PoolType::Token, + bonding_curve: BondingCurve::Linear, + spot_price: Uint128::from(2400u64), + delta: Uint128::from(100u64), + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_tokens: false, + reinvest_nfts: false, + }, ) .unwrap(); @@ -222,14 +244,14 @@ fn withdraw_assets_token_pool() { &mut router, infinity_pool.clone(), creator.clone(), - pool_id, + pool.id, deposit_amount, ) .unwrap(); // Only owner of pool can withdraw tokens let msg = ExecuteMsg::WithdrawTokens { - pool_id, + pool_id: pool.id, amount: Uint128::from(300u64), asset_recipient: None, }; @@ -242,7 +264,7 @@ fn withdraw_assets_token_pool() { // Owner of pool can withdraw tokens, tokens are directed to asset_recipient let withdraw_amount = Uint128::from(300u64); let msg = ExecuteMsg::WithdrawTokens { - pool_id, + pool_id: pool.id, amount: withdraw_amount, asset_recipient: Some(asset_account.to_string()), }; @@ -267,7 +289,7 @@ fn withdraw_assets_token_pool() { // Owner of pool can withdraw remaining tokens, tokens are directed toward owner let msg = ExecuteMsg::WithdrawAllTokens { - pool_id, + pool_id: pool.id, asset_recipient: None, }; let res = router.execute_contract(creator.clone(), infinity_pool.clone(), &msg, &[]); @@ -293,7 +315,7 @@ fn withdraw_assets_token_pool() { // Owner of pool cannot withdraw NFTs from a token pool let msg = ExecuteMsg::WithdrawNfts { - pool_id, + pool_id: pool.id, nft_token_ids: vec!["1".to_string()], asset_recipient: None, }; @@ -305,7 +327,7 @@ fn withdraw_assets_token_pool() { // Owner of pool cannot withdraw NFTs from a token pool let msg = ExecuteMsg::WithdrawAllNfts { - pool_id, + pool_id: pool.id, asset_recipient: None, }; let res = router.execute_contract(creator, infinity_pool, &msg, &[]); @@ -332,27 +354,35 @@ fn update_token_pool() { let marketplace = setup_marketplace(&mut router, creator.clone()).unwrap(); let infinity_pool = setup_infinity_pool(&mut router, creator.clone(), marketplace).unwrap(); - let pool_id = create_pool( + let pool = create_pool( &mut router, infinity_pool.clone(), creator.clone(), - collection, - None, - PoolType::Token, - BondingCurve::Linear, - Uint128::from(2400u64), - Uint128::from(100u64), - None, + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: None, + pool_type: PoolType::Token, + bonding_curve: BondingCurve::Linear, + spot_price: Uint128::from(2400u64), + delta: Uint128::from(100u64), + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_tokens: false, + reinvest_nfts: false, + }, ) .unwrap(); // Only owner of pool can update pool let msg = ExecuteMsg::UpdatePoolConfig { - pool_id, + pool_id: pool.id, asset_recipient: Some(asset_account.to_string()), delta: Some(Uint128::from(101u64)), spot_price: Some(Uint128::from(102u64)), - fee_bps: None, + finders_fee_bps: Some(0), + swap_fee_bps: Some(0u64), + reinvest_nfts: Some(false), + reinvest_tokens: Some(false), }; let res = router.execute_contract(user1, infinity_pool.clone(), &msg, &[]); assert_error( @@ -362,27 +392,33 @@ fn update_token_pool() { // Fee cannot be set on token pool let msg = ExecuteMsg::UpdatePoolConfig { - pool_id, + pool_id: pool.id, asset_recipient: Some(asset_account.to_string()), delta: Some(Uint128::from(101u64)), spot_price: Some(Uint128::from(102u64)), - fee_bps: Some(1000), + finders_fee_bps: Some(0), + swap_fee_bps: Some(100u64), + reinvest_nfts: Some(false), + reinvest_tokens: Some(false), }; let res = router.execute_contract(creator.clone(), infinity_pool.clone(), &msg, &[]); assert_error( res, - ContractError::InvalidPool("fee_bps must be 0 for token pool".to_string()), + ContractError::InvalidPool("swap_fee_percent must be 0 for token pool".to_string()), ); // Properties on pool are updated correctly let new_spot_price = Uint128::from(2400u64); let new_delta = Uint128::from(100u64); let msg = ExecuteMsg::UpdatePoolConfig { - pool_id, + pool_id: pool.id, asset_recipient: Some(asset_account.to_string()), spot_price: Some(new_spot_price), delta: Some(new_delta), - fee_bps: None, + finders_fee_bps: Some(0), + swap_fee_bps: Some(0u64), + reinvest_nfts: Some(false), + reinvest_tokens: Some(false), }; let res = router.execute_contract(creator, infinity_pool, &msg, &[]); assert!(res.is_ok()); @@ -391,7 +427,7 @@ fn update_token_pool() { attrs[1], Attribute { key: "id".to_string(), - value: pool_id.to_string() + value: pool.id.to_string() } ); assert_eq!( @@ -434,17 +470,22 @@ fn remove_token_pool() { let marketplace = setup_marketplace(&mut router, creator.clone()).unwrap(); let infinity_pool = setup_infinity_pool(&mut router, creator.clone(), marketplace).unwrap(); - let pool_id = create_pool( + let pool = create_pool( &mut router, infinity_pool.clone(), creator.clone(), - collection, - None, - PoolType::Token, - BondingCurve::Linear, - Uint128::from(2400u64), - Uint128::from(100u64), - None, + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: None, + pool_type: PoolType::Token, + bonding_curve: BondingCurve::Linear, + spot_price: Uint128::from(2400u64), + delta: Uint128::from(100u64), + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_tokens: false, + reinvest_nfts: false, + }, ) .unwrap(); @@ -453,14 +494,14 @@ fn remove_token_pool() { &mut router, infinity_pool.clone(), creator.clone(), - pool_id, + pool.id, deposit_amount, ) .unwrap(); // Only owner of pool can remove pool let msg = ExecuteMsg::RemovePool { - pool_id, + pool_id: pool.id, asset_recipient: Some(asset_account.to_string()), }; let res = router.execute_contract(user1, infinity_pool.clone(), &msg, &[]); @@ -471,7 +512,7 @@ fn remove_token_pool() { // Owner of pool can remove pool, and asset_recipient is transferred remaining tokens let msg = ExecuteMsg::RemovePool { - pool_id, + pool_id: pool.id, asset_recipient: Some(asset_account.to_string()), }; let res = router.execute_contract(creator, infinity_pool, &msg, &[]); @@ -497,17 +538,22 @@ fn activate_token_pool() { let marketplace = setup_marketplace(&mut router, creator.clone()).unwrap(); let infinity_pool = setup_infinity_pool(&mut router, creator.clone(), marketplace).unwrap(); - let pool_id = create_pool( + let pool = create_pool( &mut router, infinity_pool.clone(), creator.clone(), - collection, - None, - PoolType::Token, - BondingCurve::Linear, - Uint128::from(2400u64), - Uint128::from(100u64), - None, + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: None, + pool_type: PoolType::Token, + bonding_curve: BondingCurve::Linear, + spot_price: Uint128::from(2400u64), + delta: Uint128::from(100u64), + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_tokens: false, + reinvest_nfts: false, + }, ) .unwrap(); @@ -516,7 +562,7 @@ fn activate_token_pool() { &mut router, infinity_pool.clone(), creator.clone(), - pool_id, + pool.id, deposit_amount, ) .unwrap(); @@ -524,7 +570,7 @@ fn activate_token_pool() { // Only owner of pool can activate pool let msg = ExecuteMsg::SetActivePool { is_active: true, - pool_id, + pool_id: pool.id, }; let res = router.execute_contract(user1, infinity_pool.clone(), &msg, &[]); assert_error( @@ -535,7 +581,7 @@ fn activate_token_pool() { // Owner of pool can activate pool let msg = ExecuteMsg::SetActivePool { is_active: true, - pool_id, + pool_id: pool.id, }; let res = router.execute_contract(creator, infinity_pool, &msg, &[]); let is_active = &res.as_ref().unwrap().events[1].attributes[2].value; diff --git a/contracts/infinity-pool/src/testing/tests/pool_tests/trade_pool_tests.rs b/contracts/infinity-pool/src/testing/tests/pool_tests/trade_pool_tests.rs index bc089a3..8a5eee1 100644 --- a/contracts/infinity-pool/src/testing/tests/pool_tests/trade_pool_tests.rs +++ b/contracts/infinity-pool/src/testing/tests/pool_tests/trade_pool_tests.rs @@ -34,12 +34,15 @@ fn create_trade_pool() { bonding_curve: BondingCurve::Linear, spot_price: Uint128::from(2400u64), delta: Uint128::from(120u64), - fee_bps: Some(9001u16), + finders_fee_bps: 0, + swap_fee_bps: 9001u64, + reinvest_nfts: false, + reinvest_tokens: false, }; let res = router.execute_contract(creator.clone(), infinity_pool.clone(), &msg, &[]); assert_error( res, - ContractError::InvalidPool(String::from("fee_bps is greater than 9000")), + ContractError::InvalidPool(String::from("swap_fee_percent is greater than 90%")), ); // Can create a Linear Trade Pool w/ no fee @@ -50,7 +53,10 @@ fn create_trade_pool() { bonding_curve: BondingCurve::Linear, spot_price: Uint128::from(2400u64), delta: Uint128::from(120u64), - fee_bps: None, + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_nfts: false, + reinvest_tokens: false, }; let res = router.execute_contract(creator.clone(), infinity_pool.clone(), &msg, &[]); assert!(res.is_ok()); @@ -63,7 +69,10 @@ fn create_trade_pool() { bonding_curve: BondingCurve::Exponential, spot_price: Uint128::from(2400u64), delta: Uint128::from(120u64), - fee_bps: Some(2000u16), + finders_fee_bps: 0, + swap_fee_bps: 200u64, + reinvest_nfts: false, + reinvest_tokens: false, }; let res = router.execute_contract(creator.clone(), infinity_pool.clone(), &msg, &[]); assert!(res.is_ok()); @@ -76,7 +85,10 @@ fn create_trade_pool() { bonding_curve: BondingCurve::ConstantProduct, spot_price: Uint128::from(2400u64), delta: Uint128::from(120u64), - fee_bps: Some(2000u16), + finders_fee_bps: 0, + swap_fee_bps: 200u64, + reinvest_nfts: false, + reinvest_tokens: false, }; let res = router.execute_contract(creator, infinity_pool, &msg, &[]); assert!(res.is_ok()); @@ -99,23 +111,28 @@ fn deposit_assets_trade_pool() { let marketplace = setup_marketplace(&mut router, creator.clone()).unwrap(); let infinity_pool = setup_infinity_pool(&mut router, creator.clone(), marketplace).unwrap(); - let pool_id = create_pool( + let pool = create_pool( &mut router, infinity_pool.clone(), creator.clone(), - collection.clone(), - Some(asset_account), - PoolType::Trade, - BondingCurve::Linear, - Uint128::from(2400u64), - Uint128::from(100u64), - None, + ExecuteMsg::CreatePool { + collection: collection.to_string(), + asset_recipient: Some(asset_account.to_string()), + pool_type: PoolType::Trade, + bonding_curve: BondingCurve::Linear, + spot_price: Uint128::from(2400u64), + delta: Uint128::from(100u64), + finders_fee_bps: 0, + swap_fee_bps: 0, + reinvest_tokens: false, + reinvest_nfts: false, + }, ) .unwrap(); // Only owner of pool can deposit tokens let deposit_amount = 1000u128; - let msg = ExecuteMsg::DepositTokens { pool_id }; + let msg = ExecuteMsg::DepositTokens { pool_id: pool.id }; let res = router.execute_contract( user1.clone(), infinity_pool.clone(), @@ -129,7 +146,7 @@ fn deposit_assets_trade_pool() { // Owner can deposit tokens let deposit_amount = 1000u128; - let msg = ExecuteMsg::DepositTokens { pool_id }; + let msg = ExecuteMsg::DepositTokens { pool_id: pool.id }; let res = router.execute_contract( creator.clone(), infinity_pool.clone(), @@ -144,7 +161,7 @@ fn deposit_assets_trade_pool() { let token_id_2 = mint(&mut router, &user1, minter); approve(&mut router, &user1, &collection, &infinity_pool, token_id_2); let msg = ExecuteMsg::DepositNfts { - pool_id, + pool_id: pool.id, collection: collection.to_string(), nft_token_ids: vec![token_id_1.to_string(), token_id_2.to_string()], }; @@ -172,7 +189,7 @@ fn deposit_assets_trade_pool() { token_id_2, ); let msg = ExecuteMsg::DepositNfts { - pool_id, + pool_id: pool.id, collection: collection.to_string(), nft_token_ids: vec![token_id_1.to_string(), token_id_2.to_string()], }; diff --git a/contracts/infinity-pool/src/testing/tests/query_tests.rs b/contracts/infinity-pool/src/testing/tests/query_tests.rs index c7bf9e2..7e51df2 100644 --- a/contracts/infinity-pool/src/testing/tests/query_tests.rs +++ b/contracts/infinity-pool/src/testing/tests/query_tests.rs @@ -36,7 +36,8 @@ fn try_query_config() { res.config, Config { denom: NATIVE_DENOM.to_string(), - marketplace_addr: marketplace + marketplace_addr: marketplace, + developer: None, } ) } @@ -156,7 +157,6 @@ fn try_query_pools_by_buy_price() { let (mut router, creator, bidder) = (vt.router, vt.accts.creator, vt.accts.bidder); let collection = vt.collection_response_vec[0].collection.clone().unwrap(); let minter = vt.collection_response_vec[0].minter.clone().unwrap(); - // let user = Addr::unchecked(USER); let asset_account = Addr::unchecked(ASSET_ACCOUNT); let marketplace = setup_marketplace(&mut router, creator.clone()).unwrap(); @@ -192,25 +192,25 @@ fn try_query_pools_by_buy_price() { assert_eq!( res.pool_quotes[0], PoolQuote { - id: 6, + id: 8, collection: collection.clone(), - quote_price: Uint128::from(603u64) + quote_price: Uint128::from(800u64) } ); assert_eq!( res.pool_quotes[1], PoolQuote { - id: 8, + id: 9, collection: collection.clone(), - quote_price: Uint128::from(800u64) + quote_price: Uint128::from(900u64) } ); assert_eq!( res.pool_quotes[2], PoolQuote { - id: 9, + id: 12, collection, - quote_price: Uint128::from(900u64) + quote_price: Uint128::from(1320u64) } ); }