Skip to content

Commit

Permalink
Adjust total tokens calculations, add swap unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tasiov committed Aug 22, 2023
1 parent 15e34c8 commit 8303ccf
Show file tree
Hide file tree
Showing 15 changed files with 1,521 additions and 136 deletions.
32 changes: 14 additions & 18 deletions contracts/infinity-pair/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,9 @@ pub fn execute_deposit_tokens(
_deps: DepsMut,
info: MessageInfo,
_env: Env,
mut pair: Pair,
pair: Pair,
) -> Result<(Pair, Response), ContractError> {
pair.total_tokens += must_pay(&info, &pair.immutable.denom)?;

must_pay(&info, &pair.immutable.denom)?;
Ok((pair, Response::new()))
}

Expand Down Expand Up @@ -346,17 +345,18 @@ pub fn execute_swap_tokens_for_specific_nft(
token_id: String,
asset_recipient: Option<Addr>,
) -> Result<(Pair, Response), ContractError> {
let max_input = must_pay(&info, &pair.immutable.denom)?;
let received_amount = must_pay(&info, &pair.immutable.denom)?;

let quote_summary = pair
.internal
.buy_from_pair_quote_summary
.as_ref()
.ok_or(ContractError::InvalidPair("pair cannot produce quote".to_string()))?;

ensure!(
max_input >= quote_summary.total(),
ContractError::InvalidPairQuote("payment required is greater than max input".to_string())
ensure_eq!(
received_amount,
quote_summary.total(),
InfinityError::InvalidInput("received funds does not equal quote".to_string())
);

let mut response = Response::new();
Expand All @@ -370,21 +370,17 @@ pub fn execute_swap_tokens_for_specific_nft(
response = quote_summary.payout(&pair.immutable.denom, &seller_recipient, response)?;

// Payout NFT
ensure!(
NFT_DEPOSITS.has(deps.storage, token_id.clone()),
InfinityError::InvalidInput("pair does not own NFT".to_string())
);
NFT_DEPOSITS.remove(deps.storage, token_id.clone());

let nft_recipient = address_or(asset_recipient.as_ref(), &info.sender);
response = transfer_nft(&pair.immutable.collection, &token_id, &nft_recipient, response);
NFT_DEPOSITS.remove(deps.storage, token_id);

// Refund excess tokens
let refund_amount = max_input - quote_summary.total();
if !refund_amount.is_zero() {
response = transfer_coin(
coin(refund_amount.u128(), &pair.immutable.denom),
&info.sender,
response,
);
}

// Update pair state
pair.total_tokens -= received_amount;
pair.swap_tokens_for_nft();

Ok((pair, response))
Expand Down
8 changes: 4 additions & 4 deletions contracts/infinity-pair/src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ pub fn calc_exponential_spot_price_user_submits_nft(
spot_price: Uint128,
delta: Decimal,
) -> Result<Uint128, ContractError> {
let net_delta = Decimal::one().checked_div(Decimal::one().checked_add(delta)?)?;
Ok(spot_price.mul_floor(net_delta))
let net_delta = Decimal::one().checked_add(delta)?;
Ok(spot_price.checked_div_floor(net_delta)?)
}

pub fn calc_exponential_spot_price_user_submits_tokens(
Expand Down Expand Up @@ -54,7 +54,7 @@ pub fn calc_cp_trade_sell_to_pair_price(
ContractError::InvalidPair("pair must have at least 1 NFT".to_string(),)
);
let fraction = (Uint128::from(total_nfts + 1u64), Uint128::one());
Ok(total_tokens.checked_div_ceil(fraction)?)
Ok(total_tokens.checked_div_floor(fraction)?)
}

pub fn calc_cp_trade_buy_from_pair_price(
Expand All @@ -66,7 +66,7 @@ pub fn calc_cp_trade_buy_from_pair_price(
ContractError::InvalidPair("pair must have greater than 1 NFT".to_string(),)
);
let fraction = (Uint128::from(total_nfts - 1u64), Uint128::one());
Ok(total_tokens.checked_div_floor(fraction)?)
Ok(total_tokens.checked_div_ceil(fraction)?)
}

#[cfg(test)]
Expand Down
7 changes: 5 additions & 2 deletions contracts/infinity-pair/src/pair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ impl Pair {
}

fn update_sell_to_pair_quote_summary(&mut self, payout_context: &PayoutContext) {
if !self.config.is_active {
if !self.config.is_active || self.config.pair_type == PairType::Nft {
self.internal.sell_to_pair_quote_summary = None;
return;
}
Expand Down Expand Up @@ -273,7 +273,10 @@ impl Pair {
}

fn update_buy_from_pair_quote_summary(&mut self, payout_context: &PayoutContext) {
if !self.config.is_active || self.internal.total_nfts == 0u64 {
if !self.config.is_active
|| self.internal.total_nfts == 0u64
|| self.config.pair_type == PairType::Token
{
self.internal.buy_from_pair_quote_summary = None;
return;
}
Expand Down
6 changes: 3 additions & 3 deletions unit-tests/src/helpers/constants.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub const MIN_PRICE: u128 = 1000000;
pub const _MIN_PRICE: u128 = 1000000;

pub const POOL_CREATION_FEE: u128 = 2000000;
pub const _POOL_CREATION_FEE: u128 = 2000000;

pub const TRADING_FEE_BPS: u64 = 200;
pub const _TRADING_FEE_BPS: u64 = 200;
17 changes: 11 additions & 6 deletions unit-tests/src/helpers/nft_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ use sg721_base::msg::CollectionInfoResponse;
use sg_multi_test::StargazeApp;
use sg_std::NATIVE_DENOM;

pub const MINT_PRICE: u128 = 100_000_000;
pub const _MINT_PRICE: u128 = 100_000_000;

// Mints an NFT for a creator
pub fn mint(router: &mut StargazeApp, creator: &Addr, minter_addr: &Addr) -> String {
pub fn _mint(router: &mut StargazeApp, creator: &Addr, minter_addr: &Addr) -> String {
let minter_msg = vending_minter::msg::ExecuteMsg::Mint {};
let res = router.execute_contract(
creator.clone(),
minter_addr.clone(),
&minter_msg,
&coins(MINT_PRICE, NATIVE_DENOM),
&coins(_MINT_PRICE, NATIVE_DENOM),
);
assert!(res.is_ok());

Expand Down Expand Up @@ -58,7 +58,12 @@ pub fn approve(
assert!(res.is_ok());
}

pub fn approve_all(router: &mut StargazeApp, owner: &Addr, collection: &Addr, approve_addr: &Addr) {
pub fn _approve_all(
router: &mut StargazeApp,
owner: &Addr,
collection: &Addr,
approve_addr: &Addr,
) {
let approve_msg: Sg721ExecuteMsg<CollectionInfoResponse, Empty> = Sg721ExecuteMsg::ApproveAll {
operator: approve_addr.to_string(),
expires: None,
Expand Down Expand Up @@ -90,7 +95,7 @@ pub fn _burn(router: &mut StargazeApp, creator: &Addr, collection: &Addr, token_
assert!(res.is_ok());
}

pub fn mint_and_approve_many(
pub fn _mint_and_approve_many(
router: &mut StargazeApp,
creator: &Addr,
owner: &Addr,
Expand All @@ -104,7 +109,7 @@ pub fn mint_and_approve_many(
let token_id = mint_to(router, creator, owner, minter_addr);
token_ids.push(token_id);
}
approve_all(router, owner, collection, approve_addr);
_approve_all(router, owner, collection, approve_addr);
token_ids
}

Expand Down
16 changes: 9 additions & 7 deletions unit-tests/src/helpers/pair_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,15 @@ pub fn create_pair_with_deposits(
token_ids.push(token_id)
}

let response = router.execute_contract(
owner.clone(),
pair_addr.clone(),
&InfinityPairExecuteMsg::DepositTokens {},
&[coin(num_tokens.u128(), NATIVE_DENOM)],
);
assert!(response.is_ok());
if !num_tokens.is_zero() {
let response = router.execute_contract(
owner.clone(),
pair_addr.clone(),
&InfinityPairExecuteMsg::DepositTokens {},
&[coin(num_tokens.u128(), NATIVE_DENOM)],
);
assert!(response.is_ok());
}

let pair = router
.wrap()
Expand Down
8 changes: 4 additions & 4 deletions unit-tests/src/helpers/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ pub fn assert_error(response: Result<AppResponse, Error>, expected: String) {
assert_eq!(response.unwrap_err().source().unwrap().to_string(), expected);
}

pub fn assert_event(response: Result<AppResponse, Error>, ty: &str) {
pub fn _assert_event(response: Result<AppResponse, Error>, ty: &str) {
assert!(response.unwrap().events.iter().find(|event| event.ty == ty).is_some());
}

pub fn get_native_balances(router: &StargazeApp, addresses: &Vec<Addr>) -> HashMap<Addr, Coin> {
pub fn _get_native_balances(router: &StargazeApp, addresses: &Vec<Addr>) -> HashMap<Addr, Coin> {
let mut balances: HashMap<Addr, Coin> = HashMap::new();
for address in addresses {
let native_balance = router.wrap().query_balance(address, NATIVE_DENOM).unwrap();
Expand All @@ -22,6 +22,6 @@ pub fn get_native_balances(router: &StargazeApp, addresses: &Vec<Addr>) -> HashM
balances
}

pub fn get_native_balance(router: &StargazeApp, address: Addr) -> Uint128 {
get_native_balances(router, &vec![address.clone()]).get(&address).unwrap().amount
pub fn _get_native_balance(router: &StargazeApp, address: Addr) -> Uint128 {
_get_native_balances(router, &vec![address.clone()]).get(&address).unwrap().amount
}
14 changes: 9 additions & 5 deletions unit-tests/src/infinity_pair_tests/deposit_assets_tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::helpers::nft_functions::{assert_nft_owner, mint_to};
use crate::helpers::pair_functions::create_pair;
use crate::helpers::utils::assert_error;
use crate::setup::templates::{setup_infinity_test, InfinityTestSetup};
use crate::setup::templates::{setup_infinity_test, standard_minter_template, InfinityTestSetup};

use cosmwasm_std::{coin, to_binary, Empty, Uint128};
use cw721::Cw721ExecuteMsg;
Expand All @@ -14,6 +14,7 @@ use test_suite::common_setup::msg::MinterTemplateResponse;

#[test]
fn try_deposit_nft() {
let vt = standard_minter_template(1000u32);
let InfinityTestSetup {
vending_template:
MinterTemplateResponse {
Expand All @@ -24,7 +25,7 @@ fn try_deposit_nft() {
infinity_global,
infinity_factory,
..
} = setup_infinity_test(1000).unwrap();
} = setup_infinity_test(vt).unwrap();

let collection_resp = &collection_response_vec[0];
let minter = collection_resp.minter.clone().unwrap();
Expand Down Expand Up @@ -63,6 +64,7 @@ fn try_deposit_nft() {

#[test]
fn try_withdraw_nfts() {
let vt = standard_minter_template(1000u32);
let InfinityTestSetup {
vending_template:
MinterTemplateResponse {
Expand All @@ -73,7 +75,7 @@ fn try_withdraw_nfts() {
infinity_global,
infinity_factory,
..
} = setup_infinity_test(1000).unwrap();
} = setup_infinity_test(vt).unwrap();

let collection_resp = &collection_response_vec[0];
let minter = collection_resp.minter.clone().unwrap();
Expand Down Expand Up @@ -183,6 +185,7 @@ fn try_withdraw_nfts() {

#[test]
fn try_deposit_tokens() {
let vt = standard_minter_template(1000u32);
let InfinityTestSetup {
vending_template:
MinterTemplateResponse {
Expand All @@ -193,7 +196,7 @@ fn try_deposit_tokens() {
infinity_global,
infinity_factory,
..
} = setup_infinity_test(1000).unwrap();
} = setup_infinity_test(vt).unwrap();

let collection_resp = &collection_response_vec[0];
let _minter = collection_resp.minter.clone().unwrap();
Expand Down Expand Up @@ -247,6 +250,7 @@ fn try_deposit_tokens() {

#[test]
fn try_withdraw_tokens() {
let vt = standard_minter_template(1000u32);
let InfinityTestSetup {
vending_template:
MinterTemplateResponse {
Expand All @@ -257,7 +261,7 @@ fn try_withdraw_tokens() {
infinity_global,
infinity_factory,
..
} = setup_infinity_test(1000).unwrap();
} = setup_infinity_test(vt).unwrap();

let collection_resp = &collection_response_vec[0];
let _minter = collection_resp.minter.clone().unwrap();
Expand Down
4 changes: 4 additions & 0 deletions unit-tests/src/infinity_pair_tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#[cfg(test)]
mod deposit_assets_tests;
#[cfg(test)]
mod nft_pair_swap_tests;
#[cfg(test)]
mod pair_creation_tests;
#[cfg(test)]
mod token_pair_swap_tests;
#[cfg(test)]
mod trade_pair_swap_tests;
Loading

0 comments on commit 8303ccf

Please sign in to comment.