Skip to content

Commit

Permalink
chore: impr ffee (#2738)
Browse files Browse the repository at this point in the history
  • Loading branch information
stackchain authored Oct 2, 2023
2 parents 4c9be30 + 470abca commit dec7825
Show file tree
Hide file tree
Showing 9 changed files with 542 additions and 28 deletions.
4 changes: 2 additions & 2 deletions packages/swap/src/helpers/orders/getBuyAmount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ export const getBuyAmount = (
return {
tokenId,
quantity: asQuantity(
BigNumber(sell.quantity)
.dividedToIntegerBy(BigNumber(limit))
new BigNumber(sell.quantity)
.dividedToIntegerBy(new BigNumber(limit))
.toString(),
),
}
Expand Down
387 changes: 387 additions & 0 deletions packages/swap/src/helpers/orders/getFrontendFee.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,387 @@
import {Balance} from '@yoroi/types'

import {getFrontendFee} from './getFrontendFee'
import {milkHoldersDiscountTiers} from '../../translators/constants'
import {Quantities} from '../../utils/quantities'
import {asQuantity} from '../../utils/asQuantity'

describe('getFrontendFee', () => {
const primaryTokenInfo: Balance.TokenInfo = {
id: '',
decimals: 6,
description: 'primary',
fingerprint: '',
image: '',
group: '',
icon: '',
kind: 'ft',
name: 'ttADA',
symbol: 'ttADA',
ticker: 'ttADA',
metadatas: {},
}

const notPrimaryTokenAmount: Balance.Amount = {
tokenId: 'not.primary.token',
quantity: '99',
}

describe('selling side is primary token', () => {
it('< 100 and whatever milk in balance', () => {
// arrange
const sellAmount: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(99_999_999),
}
// act
const fee = getFrontendFee({
sellAmount: sellAmount,
buyAmount: notPrimaryTokenAmount,
sellInPrimaryTokenValue: sellAmount,
milkBalance: '999999999999999999',
buyInPrimaryTokenValue: sellAmount,
primaryTokenInfo,
discountTiers: milkHoldersDiscountTiers,
})
// assert
expect(fee).toEqual({
tokenId: primaryTokenInfo.id,
quantity: Quantities.zero,
})
})

it('>= 100 and milk in balance = 0', () => {
// arrange
const sellPrimaryAmountOver99: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(100_000_000),
}
// act
const fee = getFrontendFee({
sellAmount: sellPrimaryAmountOver99,
buyAmount: notPrimaryTokenAmount,
sellInPrimaryTokenValue: sellPrimaryAmountOver99,
milkBalance: Quantities.zero,
buyInPrimaryTokenValue: sellPrimaryAmountOver99,
primaryTokenInfo,
discountTiers: milkHoldersDiscountTiers,
})
// assert
expect(fee).toEqual({
tokenId: primaryTokenInfo.id,
quantity: asQuantity(1_050_000), // no milk, 100 ADA * 0.05% + 1 = 1.05 ADA
})
})

it('>= 100 and milk in balance >= 100', () => {
// arrange
const sellPrimaryAmountOver99: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(100_000_000),
}
// act
const fee = getFrontendFee({
sellAmount: sellPrimaryAmountOver99,
buyAmount: notPrimaryTokenAmount,
milkBalance: '499',
sellInPrimaryTokenValue: sellPrimaryAmountOver99,
buyInPrimaryTokenValue: sellPrimaryAmountOver99,
primaryTokenInfo,
discountTiers: milkHoldersDiscountTiers,
})
// assert
expect(fee).toEqual({
tokenId: primaryTokenInfo.id,
quantity: asQuantity(1_025_000), // hold 100-499 milk, 100 ADA * 0.025% + 1 = 1.025 ADA
})
})

it('>= 100 and milk in balance >= 500', () => {
// arrange
const sellPrimaryAmountOver99: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(100_000_000),
}
// act
const fee = getFrontendFee({
sellAmount: sellPrimaryAmountOver99,
buyAmount: notPrimaryTokenAmount,
milkBalance: '500',
sellInPrimaryTokenValue: sellPrimaryAmountOver99,
buyInPrimaryTokenValue: sellPrimaryAmountOver99,
primaryTokenInfo,
discountTiers: milkHoldersDiscountTiers,
})
// assert
expect(fee).toEqual({
tokenId: primaryTokenInfo.id,
quantity: asQuantity(1_020_000), // hold 500+ milk, 100 ADA * 0.020% + 1 = 1.02 ADA
})
})
})

describe('buying side is primary token', () => {
it('< 100 and whatever milk in balance', () => {
// arrange
const buyPrimaryTokenAmount: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(99_999_999),
}
// act
const fee = getFrontendFee({
sellAmount: notPrimaryTokenAmount,
buyAmount: buyPrimaryTokenAmount,
sellInPrimaryTokenValue: buyPrimaryTokenAmount,
milkBalance: '999999999999999999',
buyInPrimaryTokenValue: buyPrimaryTokenAmount,
primaryTokenInfo,
discountTiers: milkHoldersDiscountTiers,
})
// assert
expect(fee).toEqual({
tokenId: primaryTokenInfo.id,
quantity: Quantities.zero,
})
})

it('>= 100 and milk in balance = 0', () => {
// arrange
const buyPrimaryAmountOver99: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(100_000_000),
}
// act
const fee = getFrontendFee({
sellAmount: notPrimaryTokenAmount,
buyAmount: buyPrimaryAmountOver99,
sellInPrimaryTokenValue: buyPrimaryAmountOver99,
milkBalance: Quantities.zero,
buyInPrimaryTokenValue: buyPrimaryAmountOver99,
primaryTokenInfo,
discountTiers: milkHoldersDiscountTiers,
})
// assert
expect(fee).toEqual({
tokenId: primaryTokenInfo.id,
quantity: asQuantity(1_050_000), // no milk, 100 ADA * 0.05% + 1 = 1.05 ADA
})
})

it('>= 100 and milk in balance >= 100', () => {
// arrange
const buyPrimaryAmountOver99: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(100_000_000),
}
// act
const fee = getFrontendFee({
sellAmount: notPrimaryTokenAmount,
buyAmount: buyPrimaryAmountOver99,
milkBalance: '499',
sellInPrimaryTokenValue: buyPrimaryAmountOver99,
buyInPrimaryTokenValue: buyPrimaryAmountOver99,
primaryTokenInfo,
discountTiers: milkHoldersDiscountTiers,
})
// assert
expect(fee).toEqual({
tokenId: primaryTokenInfo.id,
quantity: asQuantity(1_025_000), // hold 100-499 milk, 100 ADA * 0.025% + 1 = 1.025 ADA
})
})

it('>= 100 and milk in balance >= 500', () => {
// arrange
const buyPrimaryAmountOver99: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(100_000_000),
}
// act
const fee = getFrontendFee({
sellAmount: notPrimaryTokenAmount,
buyAmount: buyPrimaryAmountOver99,
milkBalance: '500',
sellInPrimaryTokenValue: buyPrimaryAmountOver99,
buyInPrimaryTokenValue: buyPrimaryAmountOver99,
primaryTokenInfo,
discountTiers: milkHoldersDiscountTiers,
})
// assert
expect(fee).toEqual({
tokenId: primaryTokenInfo.id,
quantity: asQuantity(1_020_000), // hold 500+ milk, 100 ADA * 0.020% + 1= 1.02 ADA
})
})
})
it('should calc 0 fee if no tier', () => {
// arrange
const buyPrimaryAmountOver99: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(100_000_000),
}
// act
const fee = getFrontendFee({
sellAmount: notPrimaryTokenAmount,
buyAmount: buyPrimaryAmountOver99,
milkBalance: '999999999999999',
sellInPrimaryTokenValue: buyPrimaryAmountOver99,
buyInPrimaryTokenValue: buyPrimaryAmountOver99,
primaryTokenInfo,
discountTiers: [],
})
// assert
expect(fee).toEqual({
tokenId: primaryTokenInfo.id,
quantity: Quantities.zero,
})
})

it('should fallback - coverage only', () => {
// arrange
const buyPrimaryAmountOver99: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(1_000_000),
}
// act
const fee = getFrontendFee({
sellAmount: notPrimaryTokenAmount,
buyAmount: buyPrimaryAmountOver99,
milkBalance: '999999999999999',
sellInPrimaryTokenValue: buyPrimaryAmountOver99,
buyInPrimaryTokenValue: buyPrimaryAmountOver99,
primaryTokenInfo,
})
// assert
expect(fee).toEqual({
tokenId: primaryTokenInfo.id,
quantity: Quantities.zero,
})
})

// TODO: check with openswap
describe('neither sell nor buy are primary token, it should use the value in ADA (paired)', () => {
it('< 100 and whatever milk in balance', () => {
// arrange
const sellNotPrimaryAmount: Balance.Amount = {
tokenId: 'not.primary.token',
quantity: asQuantity(99_999_999),
}
const sellValueInPrimaryToken: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(99_999_999),
}
const buyValueInPrimaryToken: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(99_999_998),
}
// act
const fee = getFrontendFee({
sellAmount: sellNotPrimaryAmount,
buyAmount: notPrimaryTokenAmount,
sellInPrimaryTokenValue: sellValueInPrimaryToken,
milkBalance: '999999999999999999',
buyInPrimaryTokenValue: buyValueInPrimaryToken,
primaryTokenInfo,
discountTiers: milkHoldersDiscountTiers,
})
// assert
expect(fee).toEqual({
tokenId: primaryTokenInfo.id,
quantity: Quantities.zero,
})
})

it('>= 100 and milk in balance = 0', () => {
// arrange
const sellNotPrimaryAmountOver99: Balance.Amount = {
tokenId: 'not.primary.token',
quantity: asQuantity(100_000_000),
}
const sellValueInPrimaryToken: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(100_000_000),
}
const buyValueInPrimaryToken: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(99_999_998),
}
// act
const fee = getFrontendFee({
sellAmount: sellNotPrimaryAmountOver99,
buyAmount: notPrimaryTokenAmount,
sellInPrimaryTokenValue: sellValueInPrimaryToken,
milkBalance: Quantities.zero,
buyInPrimaryTokenValue: buyValueInPrimaryToken,
primaryTokenInfo,
discountTiers: milkHoldersDiscountTiers,
})
// assert
expect(fee).toEqual({
tokenId: primaryTokenInfo.id,
quantity: asQuantity(1_050_000), // no milk, 100 ADA * 0.05% + 1 = 1.05 ADA
})
})

it('>= 100 and milk in balance >= 100 (buy side higher)', () => {
// arrange
const sellNotPrimaryAmountOver99: Balance.Amount = {
tokenId: 'not.primary.token',
quantity: asQuantity(100_000_000),
}
const sellValueInPrimaryToken: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(99_000_000),
}
const buyValueInPrimaryToken: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(100_000_000),
}
// act
const fee = getFrontendFee({
sellAmount: sellNotPrimaryAmountOver99,
buyAmount: notPrimaryTokenAmount,
milkBalance: '499',
sellInPrimaryTokenValue: sellValueInPrimaryToken,
buyInPrimaryTokenValue: buyValueInPrimaryToken,
primaryTokenInfo,
discountTiers: milkHoldersDiscountTiers,
})
// assert
expect(fee).toEqual({
tokenId: primaryTokenInfo.id,
quantity: asQuantity(1_025_000), // hold 100-499 milk, 100 ADA * 0.025% + 1= 1.025 ADA
})
})

it('>= 100 and milk in balance >= 500 (50/50)', () => {
// arrange
const sellNotPrimaryAmountOver99: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(100_000_000),
}
const sellValueInPrimaryToken: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(100_000_000),
}
const buyValueInPrimaryToken: Balance.Amount = {
tokenId: primaryTokenInfo.id,
quantity: asQuantity(100_000_000),
}
// act
const fee = getFrontendFee({
sellAmount: sellNotPrimaryAmountOver99,
buyAmount: notPrimaryTokenAmount,
milkBalance: '500',
sellInPrimaryTokenValue: sellValueInPrimaryToken,
buyInPrimaryTokenValue: buyValueInPrimaryToken,
primaryTokenInfo,
discountTiers: milkHoldersDiscountTiers,
})
// assert
expect(fee).toEqual({
tokenId: primaryTokenInfo.id,
quantity: asQuantity(1_020_000), // hold 500+ milk, 100 ADA * 0.020% + 1 = 1.02 ADA
})
})
})
})
Loading

0 comments on commit dec7825

Please sign in to comment.