ABI's from //contract/out URLs; arbsep; placement fee considers upcoming fee changes; vault detection bugfixes; order placement bugfixes; BETA
This commit is contained in:
2
build.sh
2
build.sh
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# build.sh sets these env vars as output:
|
# build sets these env vars as output:
|
||||||
# DEXORDER_WEB_VERSION
|
# DEXORDER_WEB_VERSION
|
||||||
# DEXORDER_WEB_IMAGE
|
# DEXORDER_WEB_IMAGE
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
source ./build.sh $@
|
source ./build.sh "$@"
|
||||||
# build.sh sets these env vars:
|
# build sets these env vars:
|
||||||
# DEXORDER_WEB_VERSION
|
# DEXORDER_WEB_VERSION
|
||||||
# DEXORDER_WEB_IMAGE
|
# DEXORDER_WEB_IMAGE
|
||||||
|
|
||||||
|
|||||||
@@ -1,109 +0,0 @@
|
|||||||
|
|
||||||
export const factoryAbi = [
|
|
||||||
'function deployVault() returns (address payable vault)',
|
|
||||||
'function deployVault(uint8 num) returns (address payable vault)',
|
|
||||||
'function deployVault(address owner) returns (address payable vault)',
|
|
||||||
'function deployVault(address owner, uint8 num) returns (address payable vault)',
|
|
||||||
'function logic() view returns (address)',
|
|
||||||
'function upgrader() view returns (address)',
|
|
||||||
'function proposedLogicActivationTimestamp() view returns (uint32)',
|
|
||||||
'function proposedLogic() view returns (address)',
|
|
||||||
'function upgradeLogic(address newLogic)',
|
|
||||||
]
|
|
||||||
|
|
||||||
export const queryHelperAbi = [
|
|
||||||
'function getRoutes(address tokenA,address tokenB) view returns((uint8,uint24,address)[])',
|
|
||||||
]
|
|
||||||
|
|
||||||
export const uniswapV3PoolAbi = [
|
|
||||||
// {
|
|
||||||
// // the current price
|
|
||||||
// uint160 sqrtPriceX96;
|
|
||||||
// // the current tick
|
|
||||||
// int24 tick;
|
|
||||||
// // the most-recently updated index of the observations array
|
|
||||||
// uint16 observationIndex;
|
|
||||||
// // the current maximum number of observations that are being stored
|
|
||||||
// uint16 observationCardinality;
|
|
||||||
// // the next maximum number of observations to store, triggered in observations.write
|
|
||||||
// uint16 observationCardinalityNext;
|
|
||||||
// // the current protocol fee as a percentage of the swap fee taken on withdrawal
|
|
||||||
// // represented as an integer denominator (1/x)%
|
|
||||||
// uint8 feeProtocol;
|
|
||||||
// // whether the pool is locked
|
|
||||||
// bool unlocked;
|
|
||||||
// }
|
|
||||||
'function slot0() view returns(uint160,int24,uint16,uint16,uint16,uint8,bool)',
|
|
||||||
'function token0() view returns(address)',
|
|
||||||
'function token1() view returns(address)',
|
|
||||||
]
|
|
||||||
|
|
||||||
export const erc20Abi = [
|
|
||||||
'function name() view returns (string)',
|
|
||||||
'function symbol() view returns (string)',
|
|
||||||
'function decimals() view returns (uint8)',
|
|
||||||
'function totalSupply() view returns (uint256)',
|
|
||||||
'function balanceOf(address) view returns (uint256)',
|
|
||||||
'function transfer(address,uint256) returns (bool)',
|
|
||||||
'function transferFrom(address,address,uint256) returns (bool)',
|
|
||||||
'function approve(address,uint256) returns (bool success)',
|
|
||||||
'function allowance(address,address) view returns (uint256)',
|
|
||||||
'event Transfer(address indexed,address indexed,uint256)',
|
|
||||||
'event Approval(address indexed,address indexed,uint256)',
|
|
||||||
]
|
|
||||||
|
|
||||||
export const mockErc20Abi = [...erc20Abi,
|
|
||||||
'function mint(address,uint256)',
|
|
||||||
]
|
|
||||||
|
|
||||||
const Route = '(uint8 exchange, uint24 fee)'
|
|
||||||
const Tranche = `(
|
|
||||||
uint16 fraction,
|
|
||||||
bool startTimeIsRelative,
|
|
||||||
bool endTimeIsRelative,
|
|
||||||
bool minIsBarrier,
|
|
||||||
bool maxIsBarrier,
|
|
||||||
bool marketOrder,
|
|
||||||
bool minIsRatio,
|
|
||||||
bool maxIsRatio,
|
|
||||||
bool _reserved7,
|
|
||||||
uint16 rateLimitFraction,
|
|
||||||
uint24 rateLimitPeriod,
|
|
||||||
uint32 startTime,
|
|
||||||
uint32 endTime,
|
|
||||||
uint32 minIntercept,
|
|
||||||
uint32 minSlope,
|
|
||||||
uint32 maxIntercept,
|
|
||||||
uint32 maxSlope
|
|
||||||
)`
|
|
||||||
|
|
||||||
const SwapOrder = `(
|
|
||||||
address tokenIn,
|
|
||||||
address tokenOut,
|
|
||||||
${Route} route,
|
|
||||||
uint256 amount,
|
|
||||||
uint256 minFillAmount,
|
|
||||||
bool amountIsInput,
|
|
||||||
bool outputDirectlyToOwner,
|
|
||||||
uint64 conditionalOrder,
|
|
||||||
${Tranche}[] tranches
|
|
||||||
)`
|
|
||||||
|
|
||||||
export const vaultAbi = [
|
|
||||||
'function version() pure returns (uint8)',
|
|
||||||
'function logic() view returns (address)',
|
|
||||||
'function upgrade(address)',
|
|
||||||
'function feeManager() view returns (address)',
|
|
||||||
'function withdraw(uint256 amount)',
|
|
||||||
'function withdrawTo(address payable recipient, uint256 amount)',
|
|
||||||
'function withdraw(address token, uint256 amount)',
|
|
||||||
'function withdrawTo(address token, address recipient, uint256 amount)',
|
|
||||||
'function numSwapOrders() view returns (uint64 num)',
|
|
||||||
`function placementFee(${SwapOrder} order) view returns (uint256 orderFee, uint256 gasFee)`,
|
|
||||||
`function placeDexorder(${SwapOrder}) payable`,
|
|
||||||
`function placeDexorders(${SwapOrder}[], uint8 ocoMode) payable`,
|
|
||||||
'function cancelDexorder(uint64 orderIndex)',
|
|
||||||
'function cancelAllDexorders()',
|
|
||||||
// `function swapOrderStatus(uint64 orderIndex) view returns (${SwapOrderStatus} memory status)`,
|
|
||||||
'function orderCanceled(uint64 orderIndex) view returns (bool)',
|
|
||||||
]
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
import {ethers} from "ethers";
|
import {ethers} from "ethers";
|
||||||
import {queryHelperAbi} from "@/blockchain/abi.js";
|
import {AbiURLCache} from "../common.js";
|
||||||
|
|
||||||
|
export const abiCache = new AbiURLCache('/contract/out/')
|
||||||
|
|
||||||
|
|
||||||
export function vaultAddress( factory, vaultInitCodeHash, owner, num=0) {
|
export function vaultAddress( factory, vaultInitCodeHash, owner, num=0) {
|
||||||
@@ -20,6 +22,23 @@ export function contractOrNull(addr,abi,provider) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function queryHelperContract(helper, provider) {
|
export async function queryHelperContract(helper, provider) {
|
||||||
return contractOrNull(helper, queryHelperAbi, provider)
|
return newContract(helper, 'QueryHelper', provider)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// do not supply extensions with name or file: e.g.
|
||||||
|
// use newContract(addr, 'IVaultLogic', provider, 'IVault') to get the ABI from IVault.sol/IVaultLogic.json
|
||||||
|
export async function newContract(addr, name, provider) {
|
||||||
|
const abi = await abiCache.get(name)
|
||||||
|
return new ethers.Contract(addr, abi, provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function erc20Contract(addr, provider) {
|
||||||
|
return newContract(addr, 'IERC20Metadata', provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function vaultContract(addr, provider) {
|
||||||
|
return await newContract(addr, 'IVault', provider)
|
||||||
|
}
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ export function newTranche({
|
|||||||
endTime = DISTANT_FUTURE,
|
endTime = DISTANT_FUTURE,
|
||||||
minIsBarrier = false,
|
minIsBarrier = false,
|
||||||
minIsRatio = false,
|
minIsRatio = false,
|
||||||
minIntercept = 0,
|
|
||||||
slippage = 0, // may also set minIntercept instead
|
slippage = 0, // may also set minIntercept instead
|
||||||
|
minIntercept = 0,
|
||||||
minSlope = 0,
|
minSlope = 0,
|
||||||
maxIsBarrier = false,
|
maxIsBarrier = false,
|
||||||
maxIsRatio = false,
|
maxIsRatio = false,
|
||||||
@@ -200,3 +200,14 @@ export function parseTranche(tranche) {
|
|||||||
startTime, endTime, minIntercept, minSlope, maxIntercept, maxSlope,
|
startTime, endTime, minIntercept, minSlope, maxIntercept, maxSlope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function parseFeeSchedule(sched) {
|
||||||
|
const [orderFee, orderExp, gasFee, gasExp, fillFeeHalfBps] = sched
|
||||||
|
return {
|
||||||
|
orderFee: orderFee << orderExp, // orderFee is in native (ETH) currency
|
||||||
|
gasFee: gasFee << gasExp, // gasFee is in native (ETH) currency
|
||||||
|
fillFee: fillFeeHalfBps/1_000_000 // fillFee is a multiplier on the filled volume. 0.0001 = 0.1% of the output token taken as a fee
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,9 @@ import {socket} from "@/socket.js";
|
|||||||
import {useStore} from "@/store/store.js";
|
import {useStore} from "@/store/store.js";
|
||||||
import {Exchange} from "@/blockchain/orderlib.js";
|
import {Exchange} from "@/blockchain/orderlib.js";
|
||||||
import {uniswapV3PoolAddress} from "@/blockchain/uniswap.js";
|
import {uniswapV3PoolAddress} from "@/blockchain/uniswap.js";
|
||||||
import {ethers, FixedNumber} from "ethers";
|
import {FixedNumber} from "ethers";
|
||||||
import {uniswapV3PoolAbi} from "@/blockchain/abi.js";
|
|
||||||
import {subOHLCs} from "@/blockchain/ohlcs.js";
|
|
||||||
import {provider} from "@/blockchain/wallet.js";
|
import {provider} from "@/blockchain/wallet.js";
|
||||||
|
import {newContract} from "@/blockchain/contract.js";
|
||||||
|
|
||||||
const subscriptionCounts = {} // key is route and value is a subscription counter
|
const subscriptionCounts = {} // key is route and value is a subscription counter
|
||||||
export const WIDE_PRICE_FORMAT = {decimals:38, width:512, signed:false}; // 38 decimals is 127 bits
|
export const WIDE_PRICE_FORMAT = {decimals:38, width:512, signed:false}; // 38 decimals is 127 bits
|
||||||
@@ -84,7 +83,7 @@ async function getPriceForRoute(route) {
|
|||||||
console.error('provider was null during getPriceForRoute')
|
console.error('provider was null during getPriceForRoute')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const pool = new ethers.Contract(addr, uniswapV3PoolAbi, provider)
|
const pool = newContract(addr, 'IUniswapV3Pool', provider)
|
||||||
const got = await pool.slot0()
|
const got = await pool.slot0()
|
||||||
const [sqrtPrice,,,,,,] = got
|
const [sqrtPrice,,,,,,] = got
|
||||||
const spn = BigInt(sqrtPrice)
|
const spn = BigInt(sqrtPrice)
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import {socket} from "@/socket.js";
|
import {socket} from "@/socket.js";
|
||||||
import {useStore} from "@/store/store.js";
|
import {useStore} from "@/store/store.js";
|
||||||
import {erc20Abi} from "@/blockchain/abi.js";
|
|
||||||
import {ethers} from "ethers";
|
|
||||||
import {metadataMap} from "@/version.js";
|
import {metadataMap} from "@/version.js";
|
||||||
import {provider} from "@/blockchain/wallet.js";
|
import {provider} from "@/blockchain/wallet.js";
|
||||||
|
import {newContract} from "@/blockchain/contract.js";
|
||||||
|
|
||||||
|
|
||||||
// synchronous version may return null but will trigger a lookup
|
// synchronous version may return null but will trigger a lookup
|
||||||
@@ -64,7 +63,7 @@ export async function addExtraToken(chainId, addr) {
|
|||||||
resolve(null)
|
resolve(null)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const token = new ethers.Contract(addr, erc20Abi, provider)
|
const token = newContract(addr, 'IERC20Metadata', provider)
|
||||||
Promise.all( [token.name(), token.symbol(), token.decimals()] ).then((name,symbol,decimals)=>{
|
Promise.all( [token.name(), token.symbol(), token.decimals()] ).then((name,symbol,decimals)=>{
|
||||||
info = {
|
info = {
|
||||||
a: addr,
|
a: addr,
|
||||||
|
|||||||
@@ -2,13 +2,16 @@ import {ethers} from "ethers";
|
|||||||
|
|
||||||
const UNISWAPV3_POOL_INIT_CODE_HASH = '0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54'
|
const UNISWAPV3_POOL_INIT_CODE_HASH = '0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54'
|
||||||
const uniswapV3Addresses = {
|
const uniswapV3Addresses = {
|
||||||
1337: {
|
31337: { // Mockchain
|
||||||
factory: '0x1F98431c8aD98523631AE4a59f267346ea31F984',
|
factory: '0x1F98431c8aD98523631AE4a59f267346ea31F984',
|
||||||
},
|
},
|
||||||
42161: {
|
1337: { // Dexorder Alpha
|
||||||
factory: '0x1F98431c8aD98523631AE4a59f267346ea31F984',
|
factory: '0x1F98431c8aD98523631AE4a59f267346ea31F984',
|
||||||
},
|
},
|
||||||
31337: {
|
421614: { // Arbitrum Sepolia
|
||||||
|
factory: '0x1F98431c8aD98523631AE4a59f267346ea31F984',
|
||||||
|
},
|
||||||
|
42161: { // Arbitrum
|
||||||
factory: '0x1F98431c8aD98523631AE4a59f267346ea31F984',
|
factory: '0x1F98431c8aD98523631AE4a59f267346ea31F984',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import {BrowserProvider, ethers} from "ethers";
|
import {BrowserProvider, ethers} from "ethers";
|
||||||
import {useStore} from "@/store/store";
|
import {useStore} from "@/store/store";
|
||||||
import {socket} from "@/socket.js";
|
import {socket} from "@/socket.js";
|
||||||
import {contractOrNull, vaultAddress} from "@/blockchain/contract.js";
|
import {newContract, vaultAddress, vaultContract} from "@/blockchain/contract.js";
|
||||||
import {SingletonCoroutine, uuid} from "@/misc.js";
|
import {SingletonCoroutine, timestamp, uuid} from "@/misc.js";
|
||||||
import {factoryAbi, vaultAbi} from "@/blockchain/abi.js";
|
|
||||||
import {defineStore} from "pinia";
|
import {defineStore} from "pinia";
|
||||||
import {ref} from "vue";
|
import {ref} from "vue";
|
||||||
import {metadataMap, version} from "@/version.js";
|
import {metadataMap, version} from "@/version.js";
|
||||||
@@ -217,7 +216,7 @@ async function _discoverVaults(owner) {
|
|||||||
console.log('No provider')
|
console.log('No provider')
|
||||||
return // do not change whatever was already found
|
return // do not change whatever was already found
|
||||||
}
|
}
|
||||||
const vault = new ethers.Contract(addr, vaultAbi, provider)
|
const vault = await vaultContract(addr, provider)
|
||||||
try {
|
try {
|
||||||
const version = Number(await vault.version())
|
const version = Number(await vault.version())
|
||||||
console.log(`found vault #${num} v${version} at ${addr}`)
|
console.log(`found vault #${num} v${version} at ${addr}`)
|
||||||
@@ -295,11 +294,24 @@ export const PendingOrderState = {
|
|||||||
Sent: -102, // tx is awaiting blockchain mining
|
Sent: -102, // tx is awaiting blockchain mining
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const placementFeeSelector = 'placementFee((address,address,(uint8,uint24),uint256,uint256,bool,bool,uint64,(uint16,bool,bool,bool,bool,bool,bool,bool,bool,uint16,uint24,uint32,uint32,uint32,uint32,uint32,uint32)[]),(uint8,uint8,uint8,uint8,uint8))'
|
||||||
|
|
||||||
export async function placementFee(vault, order) {
|
export async function placementFee(vault, order, window=300) {
|
||||||
const v = new ethers.Contract(vault, vaultAbi, provider)
|
// If the fees are about to change within `window` seconds of now, we send the higher native amount of the two fees.
|
||||||
const [orderFee, gasFee] = await v.placementFee(order)
|
// If the fees sent are too much, the vault will refund the sender.
|
||||||
console.log('computed fees', orderFee, gasFee)
|
const v = await vaultContract(vault, provider)
|
||||||
|
const feeManagerAddr = await v.feeManager()
|
||||||
|
const feeManager = await newContract(feeManagerAddr, 'IFeeManager', provider)
|
||||||
|
const [sched, changeTimestamp] = await Promise.all([feeManager.fees(), feeManager.proposedFeeActivationTime()])
|
||||||
|
console.log('sched', order, sched)
|
||||||
|
let [orderFee, gasFee] = await v[placementFeeSelector](order, [...sched])
|
||||||
|
console.log('placementFee', orderFee, gasFee)
|
||||||
|
if (Number(changeTimestamp) - timestamp() < window) {
|
||||||
|
const nextSched = await feeManager.proposedFees()
|
||||||
|
const [nextOrderFee, nextGasFee] = await v[placementFeeSelector](order, [...nextSched])
|
||||||
|
if (nextOrderFee + nextGasFee > orderFee + gasFee)
|
||||||
|
[orderFee, gasFee] = [nextOrderFee, nextGasFee]
|
||||||
|
}
|
||||||
return [orderFee, gasFee]
|
return [orderFee, gasFee]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,7 +336,7 @@ export async function pendOrder(order, fee=null) {
|
|||||||
export async function cancelOrder(vault, orderIndex) {
|
export async function cancelOrder(vault, orderIndex) {
|
||||||
console.log('cancel order', vault, orderIndex)
|
console.log('cancel order', vault, orderIndex)
|
||||||
pendTransaction(async (signer)=> {
|
pendTransaction(async (signer)=> {
|
||||||
const contract = contractOrNull(vault, vaultAbi, signer)
|
const contract = await vaultContract(vault, signer)
|
||||||
if( contract === null ) {
|
if( contract === null ) {
|
||||||
console.error('vault contract was null while canceling order', vault, orderIndex)
|
console.error('vault contract was null while canceling order', vault, orderIndex)
|
||||||
return null
|
return null
|
||||||
@@ -335,7 +347,7 @@ export async function cancelOrder(vault, orderIndex) {
|
|||||||
|
|
||||||
export async function cancelAll(vault) {
|
export async function cancelAll(vault) {
|
||||||
pendTransaction(async (signer)=> {
|
pendTransaction(async (signer)=> {
|
||||||
const contract = contractOrNull(vault, vaultAbi, signer)
|
const contract = await vaultContract(vault, signer)
|
||||||
if( contract === null ) {
|
if( contract === null ) {
|
||||||
console.error('vault contract was null while canceling order', vault)
|
console.error('vault contract was null while canceling order', vault)
|
||||||
return null
|
return null
|
||||||
@@ -364,8 +376,12 @@ export function flushOrders(vault) {
|
|||||||
|
|
||||||
function pendOrderAsTransaction(pend) {
|
function pendOrderAsTransaction(pend) {
|
||||||
pendTransaction(async (signer)=> {
|
pendTransaction(async (signer)=> {
|
||||||
const contract = contractOrNull(pend.vault, vaultAbi, signer)
|
// console.log('pendTransaction')
|
||||||
if( contract === null ) {
|
let contract
|
||||||
|
try {
|
||||||
|
contract = await vaultContract(pend.vault, signer)
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
console.error('vault contract was null while sending order transaction', pend.vault)
|
console.error('vault contract was null while sending order transaction', pend.vault)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -491,15 +507,17 @@ export async function detectUpgrade() {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
console.log('factory', info.factory)
|
console.log('factory', info.factory)
|
||||||
const factory = new ethers.Contract(info.factory, factoryAbi, provider)
|
const [factory, vault] = await Promise.all([
|
||||||
const vault = new ethers.Contract(s.vault, vaultAbi, provider)
|
newContract(info.factory, 'IVaultFactory', provider),
|
||||||
|
newContract(s.vault, 'IVault', provider),
|
||||||
|
])
|
||||||
const vaultLogic = await vault.logic()
|
const vaultLogic = await vault.logic()
|
||||||
const latestLogic = await factory.logic()
|
const latestLogic = await factory.logic()
|
||||||
// const [vaultLogic, latestLogic] = await Promise.all( vault.logic(), factory.logic() )
|
// const [vaultLogic, latestLogic] = await Promise.all( vault.logic(), factory.logic() )
|
||||||
console.log('vaultLogic / latestLogic', vaultLogic, latestLogic)
|
console.log('vaultLogic / latestLogic', vaultLogic, latestLogic)
|
||||||
if ( vaultLogic !== latestLogic ) {
|
if ( vaultLogic !== latestLogic ) {
|
||||||
s.upgrade = latestLogic
|
s.upgrade = latestLogic
|
||||||
const logic = new ethers.Contract(latestLogic, vaultAbi, provider)
|
const logic = await newContract(latestLogic, 'IVault', provider)
|
||||||
const version = await logic.version()
|
const version = await logic.version()
|
||||||
console.log(`found vault version ${version}`)
|
console.log(`found vault version ${version}`)
|
||||||
return version
|
return version
|
||||||
@@ -514,7 +532,7 @@ export async function detectUpgrade() {
|
|||||||
|
|
||||||
function upgradeSender(vault, logic) {
|
function upgradeSender(vault, logic) {
|
||||||
return async function (signer) {
|
return async function (signer) {
|
||||||
const v = new ethers.Contract(vault, vaultAbi, signer)
|
const v = await vaultContract(vault, signer)
|
||||||
v.upgrade(logic)
|
v.upgrade(logic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import * as fs from "node:fs";
|
||||||
|
|
||||||
export function mixin(child, ...parents) {
|
export function mixin(child, ...parents) {
|
||||||
// child is modified directly, assigning fields from parents that are missing in child. parents fields are
|
// child is modified directly, assigning fields from parents that are missing in child. parents fields are
|
||||||
// assigned by parents order, highest priority first
|
// assigned by parents order, highest priority first
|
||||||
@@ -41,3 +43,99 @@ export function decodeIEE754(value) {
|
|||||||
view.setUint32(0, value, false)
|
view.setUint32(0, value, false)
|
||||||
return view.getFloat32(0, false)
|
return view.getFloat32(0, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// AsyncCache
|
||||||
|
//
|
||||||
|
|
||||||
|
export class AsyncCache {
|
||||||
|
// fetch(key) returns a value
|
||||||
|
constructor(fetch) {
|
||||||
|
this.cache = {}
|
||||||
|
this.fetchLocks = {}
|
||||||
|
this.fetch = fetch
|
||||||
|
}
|
||||||
|
|
||||||
|
async get(key) {
|
||||||
|
if (this.cache[key]) {
|
||||||
|
return this.cache[key]
|
||||||
|
}
|
||||||
|
if (this.fetchLocks[key]) {
|
||||||
|
return await this.fetchLocks[key]
|
||||||
|
}
|
||||||
|
const fetchPromise = this.fetch(key)
|
||||||
|
this.fetchLocks[key] = fetchPromise
|
||||||
|
const result = await fetchPromise
|
||||||
|
this.cache[key] = result
|
||||||
|
delete this.fetchLocks[key]
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class AsyncAbiCache extends AsyncCache {
|
||||||
|
constructor(fetch) {
|
||||||
|
super(async (key)=>{
|
||||||
|
const result = await fetch(key)
|
||||||
|
return result.abi
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class AsyncURLCache extends AsyncAbiCache {
|
||||||
|
constructor(urlForKey) {
|
||||||
|
super(async (key) => {
|
||||||
|
const URL = this.urlForKey(key)
|
||||||
|
const response = await fetch(URL)
|
||||||
|
if (!response.ok)
|
||||||
|
throw new Error(`Could not fetch ${URL} (status ${response.status})`)
|
||||||
|
return await response.json()
|
||||||
|
})
|
||||||
|
this.urlForKey = urlForKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class AsyncFileCache extends AsyncAbiCache {
|
||||||
|
constructor(pathForKey) {
|
||||||
|
super(async (key) => {
|
||||||
|
const path = this.pathForKey(key)
|
||||||
|
const data = fs.readFileSync(path, 'utf8');
|
||||||
|
return JSON.parse(data);
|
||||||
|
})
|
||||||
|
this.pathForKey = pathForKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class AbiURLCache extends AsyncURLCache {
|
||||||
|
constructor(baseUrl) {
|
||||||
|
super((name)=>{
|
||||||
|
return this.baseUrl+abiPath(name)
|
||||||
|
})
|
||||||
|
this.baseUrl = baseUrl.endsWith('/') ? baseUrl : baseUrl + '/'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class AbiFileCache extends AsyncFileCache {
|
||||||
|
constructor(basePath) {
|
||||||
|
super((name)=>{
|
||||||
|
return this.basePath+abiPath(name)
|
||||||
|
})
|
||||||
|
this.basePath = basePath.endsWith('/') ? basePath : basePath + '/'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const files = {
|
||||||
|
// If a contract is in a file different than its name, put the exception here
|
||||||
|
// 'IVaultLogic' : 'IVault', // for example
|
||||||
|
}
|
||||||
|
|
||||||
|
function abiPath(name) {
|
||||||
|
const file = files[name]
|
||||||
|
return `${file?file:name}.sol/${name}.json`
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-chip text="ALPHA" size='x-small' color="red" class="align-self-start" variant="text"/>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'alpha'
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
8
src/components/Beta.vue
Normal file
8
src/components/Beta.vue
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<template>
|
||||||
|
<v-chip text="BETA" size='x-small' color="red" class="align-self-start" variant="text"/>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'beta'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -2,16 +2,16 @@
|
|||||||
<span class="d-inline-flex align-center">
|
<span class="d-inline-flex align-center">
|
||||||
<v-icon icon="mdi-arrow-up-bold" color="primary" class="arrow"/>
|
<v-icon icon="mdi-arrow-up-bold" color="primary" class="arrow"/>
|
||||||
<span class="logo">dexorder</span>
|
<span class="logo">dexorder</span>
|
||||||
<alpha v-if="alpha"/>
|
<beta v-if="showTag"/>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|
||||||
import Alpha from "@/components/Alpha.vue";
|
import Beta from "@/components/Beta.vue";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
alpha: {type: Boolean, default: false}
|
showTag: {type: Boolean, default: false}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<v-card v-if="!loggedIn" rounded="0">
|
<v-card v-if="!loggedIn" rounded="0">
|
||||||
<v-card-title>
|
<v-card-title>
|
||||||
<!-- <v-icon icon="mdi-hand-wave" color="grey"/>-->
|
<!-- <v-icon icon="mdi-hand-wave" color="grey"/>-->
|
||||||
Welcome to Dexorder Alpha!
|
Welcome to Dexorder Beta!
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
This alpha test runs on the Dexorder Testnet blockchain, which gives you free testnet tokens to trade.
|
This alpha test runs on the Dexorder Testnet blockchain, which gives you free testnet tokens to trade.
|
||||||
|
|||||||
@@ -27,8 +27,7 @@
|
|||||||
import {useStore} from "@/store/store";
|
import {useStore} from "@/store/store";
|
||||||
import {computed, ref} from "vue";
|
import {computed, ref} from "vue";
|
||||||
import {tokenFloat} from "@/misc.js";
|
import {tokenFloat} from "@/misc.js";
|
||||||
import {contractOrNull} from "@/blockchain/contract.js"
|
import {vaultContract} from "@/blockchain/contract.js"
|
||||||
import {vaultAbi} from "@/blockchain/abi.js";
|
|
||||||
import {pendTransaction} from "@/blockchain/wallet.js";
|
import {pendTransaction} from "@/blockchain/wallet.js";
|
||||||
import {FixedNumber} from "ethers";
|
import {FixedNumber} from "ethers";
|
||||||
|
|
||||||
@@ -50,7 +49,7 @@ function withdraw() {
|
|||||||
if( amount === 0n )
|
if( amount === 0n )
|
||||||
return
|
return
|
||||||
pendTransaction(async (signer)=>{
|
pendTransaction(async (signer)=>{
|
||||||
const vault = contractOrNull(vaultAddr, vaultAbi, signer)
|
const vault = await vaultContract(vaultAddr, signer)
|
||||||
return await vault['withdraw(address,uint256)'](props.token.a, amount)
|
return await vault['withdraw(address,uint256)'](props.token.a, amount)
|
||||||
})
|
})
|
||||||
floatAmount.value = 0
|
floatAmount.value = 0
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="d-flex mb-1 align-center w-100">
|
<div class="d-flex mb-1 align-center w-100">
|
||||||
<logo class="d-flex align-end clickable logo-large" @click="nav('Order')" :alpha="true"/>
|
<logo class="d-flex align-end clickable logo-large" @click="nav('Order')" :show-tag="true"/>
|
||||||
<slot/>
|
<slot/>
|
||||||
<div class="ml-auto d-flex align-center">
|
<div class="ml-auto d-flex align-center">
|
||||||
<span class="title mr-4">{{title}}</span>
|
<span class="title mr-4">{{title}}</span>
|
||||||
@@ -19,7 +19,7 @@ import {useStore} from "@/store/store.js";
|
|||||||
import {useChartOrderStore} from "@/orderbuild.js";
|
import {useChartOrderStore} from "@/orderbuild.js";
|
||||||
import {useTheme} from "vuetify";
|
import {useTheme} from "vuetify";
|
||||||
import ToolbarButton from "@/components/chart/ToolbarButton.vue";
|
import ToolbarButton from "@/components/chart/ToolbarButton.vue";
|
||||||
import Alpha from "@/components/Alpha.vue";
|
import beta from "@/components/Beta.vue";
|
||||||
import Logo from "@/components/Logo.vue";
|
import Logo from "@/components/Logo.vue";
|
||||||
import {nav} from "@/misc.js";
|
import {nav} from "@/misc.js";
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,11 @@
|
|||||||
<v-list>
|
<v-list>
|
||||||
<v-list-item>
|
<v-list-item>
|
||||||
<uniswap-logo class="mr-2"/>
|
<uniswap-logo class="mr-2"/>
|
||||||
Supports Uniswap v3 <alpha/>
|
Supports Uniswap v3 <beta/>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-item><v-icon icon="mdi-ray-vertex" class="mr-2"/> Limit Orders <alpha/></v-list-item>
|
<v-list-item><v-icon icon="mdi-ray-vertex" class="mr-2"/> Limit Orders <beta/></v-list-item>
|
||||||
<v-list-item><v-icon icon="mdi-clock-outline" class="mr-2"/> DCA and TWAP Orders <alpha/></v-list-item>
|
<v-list-item><v-icon icon="mdi-clock-outline" class="mr-2"/> DCA and TWAP Orders <beta/></v-list-item>
|
||||||
<v-list-item><v-icon icon="mdi-vector-line" class="mr-2"/> Diagonal Limit Orders <alpha/></v-list-item>
|
<v-list-item><v-icon icon="mdi-vector-line" class="mr-2"/> Diagonal Limit Orders <beta/></v-list-item>
|
||||||
<v-list-item><v-icon icon="mdi-chart-timeline-variant-shimmer" class="mr-2"/> Stop Loss / Take Profit <soon/></v-list-item>
|
<v-list-item><v-icon icon="mdi-chart-timeline-variant-shimmer" class="mr-2"/> Stop Loss / Take Profit <soon/></v-list-item>
|
||||||
<v-list-item><v-icon icon="mdi-format-list-checks" class="mr-2"/> One-Cancels-the-Other (OCO) Groups <soon/></v-list-item>
|
<v-list-item><v-icon icon="mdi-format-list-checks" class="mr-2"/> One-Cancels-the-Other (OCO) Groups <soon/></v-list-item>
|
||||||
<v-list-item><v-icon icon="mdi-cancel" class="mr-2"/> Single-transaction Cancel All <soon/></v-list-item>
|
<v-list-item><v-icon icon="mdi-cancel" class="mr-2"/> Single-transaction Cancel All <soon/></v-list-item>
|
||||||
@@ -33,17 +33,14 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {useTheme} from "vuetify";
|
import {useTheme} from "vuetify";
|
||||||
import Alpha from "@/components/Alpha.vue";
|
import beta from "@/components/Beta.vue";
|
||||||
import Soon from "@/components/Soon.vue";
|
import Soon from "@/components/Soon.vue";
|
||||||
import HowItWorks from "@/corp/HowItWorks.vue";
|
import HowItWorks from "@/corp/HowItWorks.vue";
|
||||||
import HomeActions from "@/corp/HomeActions.vue";
|
|
||||||
import UniswapLogo from "@/corp/UniswapLogo.vue";
|
import UniswapLogo from "@/corp/UniswapLogo.vue";
|
||||||
import Logo from "@/components/Logo.vue";
|
import Logo from "@/components/Logo.vue";
|
||||||
import {nav} from "@/misc.js";
|
import {nav} from "@/misc.js";
|
||||||
import AppBtn from "@/corp/AppBtn.vue";
|
import AppBtn from "@/corp/AppBtn.vue";
|
||||||
|
|
||||||
const theme = useTheme().current
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -71,11 +71,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|
||||||
import Alpha from "@/components/Alpha.vue";
|
|
||||||
import Soon from "@/components/Soon.vue";
|
|
||||||
import UniswapLogo from "@/corp/UniswapLogo.vue";
|
import UniswapLogo from "@/corp/UniswapLogo.vue";
|
||||||
import Logo from "@/components/Logo.vue";
|
|
||||||
import HomeActions from "@/corp/HomeActions.vue";
|
|
||||||
import {nav} from "@/misc.js";
|
import {nav} from "@/misc.js";
|
||||||
import AppBtn from "@/corp/AppBtn.vue";
|
import AppBtn from "@/corp/AppBtn.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user