bugfixes
This commit is contained in:
@@ -6,12 +6,14 @@ import {ethers} from "ethers";
|
||||
|
||||
// synchronous version may return null but will trigger a lookup
|
||||
export function token(addr) {
|
||||
console.log('token', addr)
|
||||
if( !addr ) {
|
||||
// console.log('ignoring call to token', addr)
|
||||
return null
|
||||
}
|
||||
const s = useStore()
|
||||
if( !(addr in s.tokens) ) {
|
||||
// noinspection JSIgnoredPromiseFromCall
|
||||
getToken(addr)
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -24,12 +24,7 @@
|
||||
</suspense>
|
||||
</template>
|
||||
<template v-slot:item.avg="{ item }">
|
||||
{{ pairPrice(item.order.tokenIn, item.order.tokenOut, item.avg) }}
|
||||
<btn v-if="pairPrice(item.order.tokenIn, item.order.tokenOut, item.avg)!==''" size="small"
|
||||
variant="plain"
|
||||
@click="inverted[[vaultAddr,item.index]] = !inverted[[vaultAddr,item.index]]">
|
||||
{{ pair(item.order.tokenIn, item.order.tokenOut, vaultAddr, item.index) }}
|
||||
</btn>
|
||||
<pair-price :base-addr="item.order.tokenIn" :quote-addr="item.order.tokenOut" :value="item.avg" :show-btn="true"/>
|
||||
</template>
|
||||
<template v-slot:item.status="{ item }">
|
||||
<v-chip v-if="item.state===OrderState.Signing" prepend-icon="mdi-signature" color="yellow">Signing</v-chip>
|
||||
@@ -101,12 +96,12 @@
|
||||
import {FixedNumber} from "ethers";
|
||||
import {useStore} from "@/store/store";
|
||||
import {computed, defineAsyncComponent, reactive} from "vue";
|
||||
import {token} from "@/blockchain/token.js";
|
||||
import Btn from "@/components/Btn.vue"
|
||||
import {cancelAll, cancelOrder} from "@/blockchain/wallet.js";
|
||||
import {dateString} from "@/misc.js";
|
||||
import {dateString, pairPriceAddr} from "@/misc.js";
|
||||
import {isOpen, OrderState} from "@/blockchain/orderlib.js";
|
||||
import NewOrder from "@/components/NewOrder.vue";
|
||||
import PairPrice from "@/components/PairPrice.vue";
|
||||
|
||||
const TokenAmount = defineAsyncComponent(()=>import('./TokenAmount.vue'))
|
||||
|
||||
@@ -116,39 +111,6 @@ const vaultAddr = computed(()=>props.vault?props.vault:s.vault)
|
||||
const inverted = reactive({})
|
||||
|
||||
|
||||
// todo create a Price component that keeps inversion flags in the store and defaults to stablecoins as the quote
|
||||
function pairPrice(inTokenAddr, outTokenAddr, price) {
|
||||
if( price === null )
|
||||
return ''
|
||||
const inToken = token(inTokenAddr)
|
||||
const outToken = token(outTokenAddr)
|
||||
if( !inToken || !outToken )
|
||||
return ''
|
||||
|
||||
const decimals = inToken.decimals-outToken.decimals
|
||||
if( decimals > 0 )
|
||||
price /= 10 ** decimals
|
||||
else
|
||||
price *= 10 ** -decimals
|
||||
const token0 = inTokenAddr < outTokenAddr ? inTokenAddr : outTokenAddr
|
||||
const token1 = inTokenAddr > outTokenAddr ? inTokenAddr : outTokenAddr
|
||||
const invertedKey = [token0, token1];
|
||||
if( !(invertedKey in inverted) ) {
|
||||
// todo prefer stablecoins as the quote asset
|
||||
inverted[invertedKey] = false
|
||||
}
|
||||
const inv = inverted[invertedKey]
|
||||
return inv ? (1 / price).toPrecision(5) : price.toPrecision(5)
|
||||
}
|
||||
|
||||
function pair(inTokenAddr, outTokenAddr, vaultAddr, index) {
|
||||
const inToken = token(inTokenAddr)
|
||||
const outToken = token(outTokenAddr)
|
||||
return !inToken || !outToken ? null : inverted[[vaultAddr,index]] ?
|
||||
outToken.symbol+'\\'+inToken.symbol : inToken.symbol+'\\'+outToken.symbol
|
||||
}
|
||||
|
||||
|
||||
// <thead>
|
||||
// <tr>
|
||||
// <th className="num d-none d-md-table-cell">Date</th>
|
||||
@@ -233,10 +195,14 @@ const orders = computed(()=>{
|
||||
})
|
||||
const fmtX18 = {decimals: 18, width: 256, signed: false};
|
||||
st.filled = o.amountIsInput ? st.filledIn : st.filledOut
|
||||
st.avg = BigInt(st.filled) === 0n ? null :
|
||||
FixedNumber.fromValue(status.filledOut, 0, fmtX18)
|
||||
.div(FixedNumber.fromValue(status.filledIn, 0, fmtX18))
|
||||
.toUnsafeFloat().toPrecision(5) // todo precision
|
||||
if(BigInt(st.filled) === 0n)
|
||||
st.avg = null
|
||||
else {
|
||||
st.avg = FixedNumber.fromValue(status.filledOut, 0, fmtX18)
|
||||
.div(FixedNumber.fromValue(status.filledIn, 0, fmtX18)).toUnsafeFloat();
|
||||
if( o.tokenIn > o.tokenOut )
|
||||
st.avg = 1/st.avg
|
||||
}
|
||||
st.trancheFilled = o.amountIsInput ? st.trancheFilledIn : st.trancheFilledOut
|
||||
st.amountToken = o.amountIsInput ? o.tokenIn : o.tokenOut
|
||||
st.input = o.amountIsInput ? o.amount : 0
|
||||
@@ -270,12 +236,17 @@ function describeTrancheTime(st, isStart, t) {
|
||||
function describeTrancheLine(st, isMin, b, m) {
|
||||
// todo make this a PairPrice
|
||||
if( b===0 && m===0 ) return ''
|
||||
// console.log('tranche line', isMin, b, m)
|
||||
console.log('tranche line', isMin, b, m)
|
||||
const inverted = st.order.tokenIn > st.order.tokenOut
|
||||
const t0 = inverted ? st.order.tokenIn : st.order.tokenOut
|
||||
const t1 = !inverted ? st.order.tokenIn : st.order.tokenOut
|
||||
if( m !== 0 ) {
|
||||
const limit = b + m * s.time
|
||||
return 'diagonal ' + pairPrice(st.order.tokenIn, st.order.tokenOut, limit)
|
||||
const price = pairPriceAddr(t0, t1, limit);
|
||||
return 'diagonal ' + (price === null ? null : price.toPrecision(5))
|
||||
}
|
||||
return (isMin === st.order.amountIsInput ? 'dont-chase ' : 'limit ') + pairPrice(st.order.tokenIn, st.order.tokenOut, b)
|
||||
const price = pairPriceAddr(t0, t1, b)
|
||||
return (isMin === st.order.amountIsInput ? 'dont-chase ' : 'limit ') + (price === null ? null : price.toPrecision(5))
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@@ -42,11 +42,11 @@ const os = useOrderStore()
|
||||
|
||||
const tokenA = computed({
|
||||
get() {
|
||||
return os.tokenA
|
||||
return os.baseToken
|
||||
},
|
||||
set(value) {
|
||||
if( !os.tokenA || os.tokenA.address !== value.address ) {
|
||||
os.tokenA = value
|
||||
if( !os.baseToken || os.baseToken.address !== value.address ) {
|
||||
os.baseToken = value
|
||||
routeFinder.invoke()
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ const routes = computed({
|
||||
})
|
||||
|
||||
async function componentFindRoute() {
|
||||
const tokenA = os.tokenA
|
||||
const tokenA = os.baseToken
|
||||
const tokenB = os.tokenB
|
||||
os.routes = []
|
||||
if (!tokenA || !tokenB)
|
||||
|
||||
@@ -1,39 +1,38 @@
|
||||
<template>
|
||||
<span>{{adjValue}}</span>
|
||||
<!-- todo optional pair label and inversion button -->
|
||||
<span>
|
||||
{{adjValue}}
|
||||
<btn v-if="showBtn && adjValue!==null" size="small" variant="plain" @click="invert()">{{pair}}</btn>
|
||||
</span>
|
||||
<!-- todo optional pair label and inversion button -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {usePrefStore, useStore} from "@/store/store";
|
||||
import {computed} from "vue";
|
||||
import {token} from "@/blockchain/token.js";
|
||||
import {pairKey, pairPrice} from "@/misc.js";
|
||||
import Btn from "@/components/Btn.vue";
|
||||
|
||||
const props = defineProps(['value','tokenA','tokenB','addrA','addrB',])
|
||||
const props = defineProps(['value', 'baseToken', 'quoteToken', 'baseAddr', 'quoteAddr', 'showBtn', 'decimals'])
|
||||
|
||||
const s = useStore()
|
||||
const prefs = usePrefStore()
|
||||
|
||||
const adjValue = computed(()=>{
|
||||
const a = props.tokenA ? props.tokenA : token(s.chainId,props.addrA)
|
||||
const b = props.tokenB ? props.tokenB : token(s.chainId,props.addrB)
|
||||
if( !a || !b )
|
||||
return ''
|
||||
let price = props.value
|
||||
const decimals = b.decimals-a.decimals
|
||||
if( decimals > 0 )
|
||||
price /= 10 ** decimals
|
||||
else
|
||||
price *= 10 ** -decimals
|
||||
const token0 = a.address < b.address ? a.address : b.address
|
||||
const token1 = a.address > b.address ? a.address : b.address
|
||||
const invertedKey = [token0, token1];
|
||||
if( !(invertedKey in prefs.inverted) ) {
|
||||
// todo prefer stablecoins as the quote asset
|
||||
prefs.inverted[invertedKey] = false
|
||||
}
|
||||
if( prefs.inverted[invertedKey] )
|
||||
price = 1/price
|
||||
return price.toPrecision(5)
|
||||
const base = computed(() => props.baseToken ? props.baseToken : token(props.baseAddr))
|
||||
const quote = computed(() => props.quoteToken ? props.quoteToken : token(props.quoteAddr))
|
||||
|
||||
function invert() {
|
||||
const k = pairKey(base.value,quote.value)
|
||||
prefs.inverted[k] = !prefs.inverted[k]
|
||||
}
|
||||
|
||||
const adjValue = computed(() => !base.value || !quote.value ? null : pairPrice(base.value, quote.value, props.value, props.decimals).toPrecision(5))
|
||||
|
||||
const pair = computed(() => {
|
||||
const inToken = props.baseToken ? props.baseToken : token(props.baseAddr)
|
||||
const outToken = props.quoteToken ? props.quoteToken : token(props.quoteAddr)
|
||||
return !inToken || !outToken ? '___\\___' : prefs.inverted[pairKey(inToken, outToken)] ?
|
||||
outToken.symbol + '\\' + inToken.symbol : inToken.symbol + '\\' + outToken.symbol
|
||||
})
|
||||
|
||||
|
||||
|
||||
42
src/misc.js
42
src/misc.js
@@ -1,5 +1,6 @@
|
||||
import {FixedNumber} from "ethers";
|
||||
import {useStore} from "@/store/store.js";
|
||||
import {usePrefStore, useStore} from "@/store/store.js";
|
||||
import {token} from "@/blockchain/token.js";
|
||||
|
||||
export class SingletonCoroutine {
|
||||
constructor(f, delay=10, retry=true) {
|
||||
@@ -84,3 +85,42 @@ export function timestamp(date=null) {
|
||||
date = new Date()
|
||||
return Math.round(date.getTime() / 1000)
|
||||
}
|
||||
|
||||
|
||||
export function pairKey(tokenA, tokenB) {
|
||||
const token0 = tokenA.address < tokenB.address ? tokenA.address : tokenB.address
|
||||
const token1 = tokenA.address > tokenB.address ? tokenA.address : tokenB.address
|
||||
return [token0, token1];
|
||||
}
|
||||
|
||||
|
||||
export function pairPriceAddr(baseTokenAddr, quoteTokenAddr, price) {
|
||||
const baseToken = token(baseTokenAddr)
|
||||
const quoteToken = token(quoteTokenAddr)
|
||||
if( !baseToken || !quoteToken )
|
||||
return null
|
||||
return pairPrice(baseToken, quoteToken, price)
|
||||
}
|
||||
|
||||
|
||||
export function pairPrice(baseToken, quoteToken, price, decimals=null) {
|
||||
if( price === null || price === undefined )
|
||||
return price
|
||||
if( decimals === null )
|
||||
decimals = baseToken.decimals-quoteToken.decimals
|
||||
console.log('pairPrice', baseToken, quoteToken, price, decimals)
|
||||
if( decimals >= 0 )
|
||||
price /= 10 ** decimals
|
||||
else
|
||||
price *= 10 ** -decimals
|
||||
const invertedKey = pairKey(baseToken, quoteToken);
|
||||
const prefs = usePrefStore()
|
||||
if( !(invertedKey in prefs.inverted) ) {
|
||||
// todo prefer stablecoins as the quote asset
|
||||
prefs.inverted[invertedKey] = false
|
||||
}
|
||||
if( prefs.inverted[invertedKey] )
|
||||
price = 1/price
|
||||
return price
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import {knownTokens} from "@/knownTokens.js";
|
||||
import {computed, ref} from "vue";
|
||||
import {timestamp} from "@/misc.js";
|
||||
|
||||
|
||||
// USING THE STORE:
|
||||
@@ -28,6 +27,9 @@ import {timestamp} from "@/misc.js";
|
||||
// const stuff = [ {}, [], true ]
|
||||
// if( s.obj.value in stuff || s.obj.value === {} ) ... // use .value to access the raw object instead of its reference
|
||||
|
||||
function timestamp() {
|
||||
return Math.round(new Date().getTime() / 1000)
|
||||
}
|
||||
|
||||
export const useStore = defineStore('app', ()=> {
|
||||
const time = ref(timestamp())
|
||||
@@ -179,7 +181,7 @@ export const useOrderStore = defineStore('order', ()=> {
|
||||
})
|
||||
|
||||
|
||||
export const usePrefStore = defineStore('order', ()=> {
|
||||
export const usePrefStore = defineStore('prefs', ()=> {
|
||||
// user preferences
|
||||
const inverted = ref({})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user