Skip to content

Commit

Permalink
[SWA-72] Set default limit price and toggle it
Browse files Browse the repository at this point in the history
  • Loading branch information
Wixzi committed Jul 21, 2023
1 parent 309d30f commit 4cacee5
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ export default function ConfirmLimitOrderModal({
fiatValueInput,
fiatValueOutput,
}: ConfirmLimitOrderModalProps) {
const { limitOrder, buyAmount, sellAmount, limitPrice, expiresAt, expiresAtUnit, kind } =
useContext(LimitOrderContext)
const { buyAmount, sellAmount, limitPrice, expiresAt, expiresAtUnit, kind } = useContext(LimitOrderContext)

//hardcoded for now
const market = 'CoW Protocol'
Expand All @@ -54,7 +53,7 @@ export default function ConfirmLimitOrderModal({
const askPrice = `${kind} ${baseTokenAmount?.currency?.symbol} at ${limitPrice} ${quoteTokenAmount?.currency?.symbol}`

let { marketPriceDiffPercentage, isDiffPositive } = calculateMarketPriceDiffPercentage(
limitOrder!.kind,
kind ?? Kind.Sell,
marketPrices,
limitPrice!
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { formatUnits, parseUnits } from '@ethersproject/units'
import { parseUnits } from '@ethersproject/units'
import { Currency, TokenAmount } from '@swapr/sdk'

import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'
import { Dispatch, SetStateAction, useEffect, useState } from 'react'
import { RefreshCw } from 'react-feather'
import { useTranslation } from 'react-i18next'

import { Kind, LimitOrderBase, MarketPrices } from '../../../../../services/LimitOrders'
import { InputGroup } from '../InputGroup'
import { calculateMarketPriceDiffPercentage } from '../utils'
// eslint-disable-next-line @typescript-eslint/no-unused-vars

import { MarketPriceButton } from './MarketPriceButton'
import {
Expand Down Expand Up @@ -57,90 +57,68 @@ export interface OrderLimitPriceFieldProps {
}

export function OrderLimitPriceField({
// eslint-disable-next-line @typescript-eslint/no-unused-vars
marketPrices,
fetchMarketPrice,
setFetchMarketPrice,
protocol,
sellAmount,
buyAmount,
kind,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
limitOrder = {},
sellToken,
buyToken,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
setSellAmount,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
setBuyAmount,
setKind,
}: OrderLimitPriceFieldProps) {
const { t } = useTranslation('swap')

const [formattedLimitPrice, setFormattedLimitPrice] = useState<string | number>(marketPrices.buy.toFixed(6))

const [{ baseToken, baseTokenAmount: _b, quoteToken, quoteTokenAmount: _q }, setBaseQuoteTokens] = useState(
const [{ baseToken, quoteToken }, setBaseQuoteTokens] = useState(
getBaseQuoteTokens({ sellAmount, buyAmount, kind, sellToken, buyToken })
)

useEffect(() => {
setBaseQuoteTokens(getBaseQuoteTokens({ sellAmount, buyAmount, kind, sellToken, buyToken }))
}, [sellToken, buyToken, sellAmount, buyAmount, kind])

const inputGroupLabel = `${kind} ${baseToken?.symbol} at`
const inputGroupLabel = `${kind} 1 ${baseToken?.symbol} at`
const toggleCurrencyButtonLabel = `${quoteToken?.symbol}`

const [formattedLimitPrice, setFormattedLimitPrice] = useState<string | number>(protocol.getTokenLimitPrices())
const [inputLimitPrice, setInputLimitPrice] = useState<string | number>(formattedLimitPrice)
const [inputFocus, setInputFocus] = useState(false)

const { marketPriceDiffPercentage, isDiffPositive } = calculateMarketPriceDiffPercentage(
kind ?? Kind.Sell,
marketPrices,
formattedLimitPrice.toString()
)
// const { marketPriceDiffPercentage, isDiffPositive } = calculateMarketPriceDiffPercentage(
// kind ?? Kind.Sell,
// marketPrices,
// formattedLimitPrice.toString()
// )

const showPercentage =
Number(marketPriceDiffPercentage.toFixed(1)) !== 0 && Number(marketPriceDiffPercentage) !== -100
// const showPercentage =
// Number(marketPriceDiffPercentage.toFixed(1)) !== 0 && Number(marketPriceDiffPercentage) !== -100

// useEffect(() => {
// setInputLimitPrice(formattedLimitPrice)
// }, [formattedLimitPrice])
const limitPrice = protocol.getTokenLimitPrices()
useEffect(() => {
setInputLimitPrice(formattedLimitPrice)
}, [formattedLimitPrice])

/**
* Handle the base currency change.
*/
const toggleBaseCurrency = useCallback(() => {
// Toggle between buy and sell currency
const kindSelected = kind === Kind.Sell ? Kind.Buy : Kind.Sell

if (!sellAmount || !buyAmount) return

const [baseTokenAmount, quoteTokenAmount] =
kindSelected === Kind.Sell ? [sellAmount, buyAmount] : [buyAmount, sellAmount]

const baseTokenAmountAsFloat = parseFloat(
formatUnits(baseTokenAmount.raw.toString(), baseTokenAmount.currency.decimals)
)
const quoteTokenAmountAsFloat = parseFloat(
formatUnits(quoteTokenAmount.raw.toString(), quoteTokenAmount.currency.decimals)
)

const nextLimitPriceFloat = quoteTokenAmountAsFloat / baseTokenAmountAsFloat
const nextLimitPriceFormatted = nextLimitPriceFloat.toFixed(6) // 6 is the lowest precision we support due to tokens like USDC
//const nextLimitPriceWei = parseUnits(nextLimitPriceFormatted, quoteTokenAmount?.currency?.decimals).toString()

setKind(kindSelected)
protocol.onLimitPriceChange(nextLimitPriceFormatted)
// protocol.onLimitOrderChange({
// ...limitOrder,
// kind,
// limitPrice: nextLimitPriceFormatted,
// })
// update the formatted limit price
setFormattedLimitPrice(nextLimitPriceFormatted)
setInputLimitPrice(nextLimitPriceFormatted)
}, [kind, sellAmount, buyAmount, setKind, protocol])
setFormattedLimitPrice(limitPrice)
if (!inputFocus) {
setInputLimitPrice(limitPrice)
}
}, [inputFocus, limitPrice])

/**
* Handle the limit price input change. Compute the buy amount and update the state.
*/
const onChangeHandler: React.ChangeEventHandler<HTMLInputElement> = event => {
const [_baseTokenAmount, quoteTokenAmount] = kind === Kind.Sell ? [sellAmount, buyAmount] : [buyAmount, sellAmount]
setInputFocus(true)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [baseTokenAmount, quoteTokenAmount] = kind === Kind.Sell ? [sellAmount, buyAmount] : [buyAmount, sellAmount]
// Parse the limit price
const nextLimitPriceFormatted = event.target.value // When the limit price is empty, set the limit price to 0
if (nextLimitPriceFormatted.split('.').length > 2) {
Expand All @@ -159,7 +137,9 @@ export function OrderLimitPriceField({
return setFormattedLimitPrice('0')
}
setInputLimitPrice(nextLimitPriceFormatted)
// When price is below or equal to 0, set the limit price to 0, but don't update the state

// const
// // When price is below or equal to 0, set the limit price to 0, but don't update the state

const { buyAmountWei, sellAmountWei, newBuyTokenAmount, newSellTokenAmount } = computeNewAmount(
buyAmount,
Expand All @@ -169,7 +149,7 @@ export function OrderLimitPriceField({
// inputFocus
)

setFormattedLimitPrice(nextLimitPriceFormatted)
// setFormattedLimitPrice(nextLimitPriceFormatted)

if (kind === Kind.Sell) {
setBuyAmount(newBuyTokenAmount)
Expand All @@ -184,19 +164,25 @@ export function OrderLimitPriceField({
// setFormattedSellAmount(amount.toString())
protocol.onLimitOrderChange({
...limitOrder,
limitPrice: parseUnits(nextLimitPriceFormatted, quoteTokenAmount?.currency?.decimals).toString(),
limitPrice: parseUnits(nextLimitPriceFormatted, baseTokenAmount?.currency?.decimals).toString(),
sellAmount: sellAmountWei,
})
}

setFetchMarketPrice(false)
}
}

const onClickGetMarketPrice = () => {
setInputFocus(false)
setFetchMarketPrice(true)
}

// const onChangeHandler = () => {}

// TODO: fix it
const showPercentage = false
const marketPriceDiffPercentage = 0
const isDiffPositive = false

return (
<InputGroup>
<LimitLabel htmlFor="limitPrice">
Expand Down Expand Up @@ -231,7 +217,7 @@ export function OrderLimitPriceField({
onChange={onChangeHandler}
/>
<InputGroup.ButtonAddonsWrapper>
<ToggleCurrencyButton onClick={toggleBaseCurrency}>
<ToggleCurrencyButton onClick={() => setKind(kind === Kind.Sell ? Kind.Buy : Kind.Sell)}>
<SwapTokenWrapper>
{toggleCurrencyButtonLabel}
<SwapTokenIconWrapper>
Expand Down
3 changes: 3 additions & 0 deletions src/services/LimitOrders/1Inch/OneInch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,7 @@ export class OneInch extends LimitOrderBase {
async getMarketPrice() {
return 0
}
getTokenLimitPrices() {
return '0'
}
}
19 changes: 19 additions & 0 deletions src/services/LimitOrders/CoW/CoW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,25 @@ export class CoW extends LimitOrderBase {
} as LimitOrder
}

getTokenLimitPrices() {
const { buyAmount, sellAmount, kind } = this
if (buyAmount && sellAmount && kind) {
const [baseAmount, quoteAmount] = kind === Kind.Sell ? [sellAmount, buyAmount] : [buyAmount, sellAmount]
const quoteAmountInUnits = parseFloat(quoteAmount.toExact())
const baseAmountInUnits = parseFloat(baseAmount.toExact())
if (
!Number.isNaN(quoteAmountInUnits) &&
quoteAmountInUnits > 0 &&
!Number.isNaN(baseAmountInUnits) &&
baseAmountInUnits > 0
) {
const limitPrice = parseFloat(quoteAmount.toExact()) / parseFloat(baseAmount.toExact())
return limitPrice.toFixed(6)
}
}
return '1'
}

#formatMarketPrice(amount: string, decimals: number, tokenAmount: string) {
return parseFloat(formatUnits(amount, decimals) ?? 0) / Number(tokenAmount)
}
Expand Down
2 changes: 1 addition & 1 deletion src/services/LimitOrders/LimitOrder.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export abstract class LimitOrderBase {

abstract getQuote(): Promise<void>
abstract getMarketPrice(): Promise<number>
// abstract setToMarket(sellPricePercentage: number, buyPricePercentage: number): Promise<void>
abstract getTokenLimitPrices(): string
abstract onSignerChange({ account, activeChainId, provider }: WalletData): Promise<void>
abstract approve(): Promise<void>
abstract createOrder(): Promise<void>
Expand Down

0 comments on commit 4cacee5

Please sign in to comment.