vault upgrades; fees; refactoring
This commit is contained in:
@@ -1,5 +1,14 @@
|
||||
|
||||
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 = [
|
||||
@@ -55,11 +64,11 @@ const Tranche = `(
|
||||
bool minIsBarrier,
|
||||
bool maxIsBarrier,
|
||||
bool marketOrder,
|
||||
bool _reserved5,
|
||||
bool _reserved6,
|
||||
bool minIsRatio,
|
||||
bool maxIsRatio,
|
||||
bool _reserved7,
|
||||
uint8 _reserved8,
|
||||
uint32 _reserved16,
|
||||
uint16 rateLimitFraction,
|
||||
uint24 rateLimitPeriod,
|
||||
uint32 startTime,
|
||||
uint32 endTime,
|
||||
uint32 minIntercept,
|
||||
@@ -67,6 +76,7 @@ const Tranche = `(
|
||||
uint32 maxIntercept,
|
||||
uint32 maxSlope
|
||||
)`
|
||||
|
||||
const SwapOrder = `(
|
||||
address tokenIn,
|
||||
address tokenOut,
|
||||
@@ -75,19 +85,23 @@ const SwapOrder = `(
|
||||
uint256 minFillAmount,
|
||||
bool amountIsInput,
|
||||
bool outputDirectlyToOwner,
|
||||
uint64 chainOrder,
|
||||
uint64 conditionalOrder,
|
||||
${Tranche}[] tranches
|
||||
)`
|
||||
|
||||
export const vaultAbi = [
|
||||
'function version() view returns (uint8)',
|
||||
'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 placeDexorder(${SwapOrder})`,
|
||||
`function placeDexorders(${SwapOrder}[], uint8 ocoMode)`,
|
||||
`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)`,
|
||||
|
||||
@@ -2,7 +2,7 @@ import {uint32max, uint64max} from "@/misc.js";
|
||||
import {decodeIEE754, encodeIEE754} from "@/common.js";
|
||||
|
||||
export const MAX_FRACTION = 65535;
|
||||
export const NO_CHAIN = uint64max;
|
||||
export const NO_CONDITIONAL_ORDER = uint64max;
|
||||
export const NO_OCO = uint64max;
|
||||
export const DISTANT_PAST = 0
|
||||
export const DISTANT_FUTURE = uint32max
|
||||
@@ -15,7 +15,7 @@ export const DISTANT_FUTURE = uint32max
|
||||
// uint256 minFillAmount; // if a tranche has less than this amount available to fill, it is considered completed
|
||||
// bool amountIsInput;
|
||||
// bool outputDirectlyToOwner;
|
||||
// uint64 chainOrder; // use NO_CHAIN for no chaining. chainOrder index must be < than this order's index for safety (written first) and chainOrder state must be Template
|
||||
// uint64 conditionalOrder; // use NO_CONDITIONAL_ORDER for no chaining. conditionalOrder index must be < than this order's index for safety (written first) and conditionalOrder state must be Template
|
||||
// Tranche[] tranches;
|
||||
// }
|
||||
// struct Route {
|
||||
@@ -23,7 +23,7 @@ export const DISTANT_FUTURE = uint32max
|
||||
// uint24 fee;
|
||||
// }
|
||||
export function newOrder(tokenIn, tokenOut, exchange, fee, amount, amountIsInput, tranches,
|
||||
minFillAmount=null, outputDirectlyToOwner = false, chainOrder = NO_CHAIN) {
|
||||
minFillAmount=null, outputDirectlyToOwner = false, conditionalOrder = NO_CONDITIONAL_ORDER) {
|
||||
amountIsInput = !!amountIsInput // force convert to bool
|
||||
outputDirectlyToOwner = !!outputDirectlyToOwner // force convert to bool
|
||||
amount = BigInt(amount)
|
||||
@@ -34,7 +34,7 @@ export function newOrder(tokenIn, tokenOut, exchange, fee, amount, amountIsInput
|
||||
return {
|
||||
tokenIn, tokenOut, route:{exchange, fee},
|
||||
amount, minFillAmount, amountIsInput,
|
||||
outputDirectlyToOwner, chainOrder, tranches
|
||||
outputDirectlyToOwner, conditionalOrder, tranches
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +46,11 @@ export function newOrder(tokenIn, tokenOut, exchange, fee, amount, amountIsInput
|
||||
// bool minIsBarrier;
|
||||
// bool maxIsBarrier;
|
||||
// bool marketOrder; // if true, both min and max lines are ignored, and minIntercept is treated as a maximum slippage value (use positive numbers)
|
||||
// bool _reserved5;
|
||||
// bool _reserved6;
|
||||
// bool minIsRatio;
|
||||
// bool maxIsRatio;
|
||||
// bool _reserved7;
|
||||
// uint8 _reserved8;
|
||||
// uint32 _reserved16;
|
||||
// uint16 rateLimitFraction;
|
||||
// uint24 rateLimitPeriod;
|
||||
//
|
||||
// uint32 startTime; // use DISTANT_PAST to disable
|
||||
// uint32 endTime; // use DISTANT_FUTURE to disable
|
||||
@@ -69,12 +69,16 @@ export function newTranche({
|
||||
endTimeIsRelative = false,
|
||||
endTime = DISTANT_FUTURE,
|
||||
minIsBarrier = false,
|
||||
minIsRatio = false,
|
||||
minIntercept = 0,
|
||||
slippage = 0, // may also set minIntercept instead
|
||||
minSlope = 0,
|
||||
maxIsBarrier = false,
|
||||
maxIsRatio = false,
|
||||
maxIntercept = 0,
|
||||
maxSlope = 0,
|
||||
rateLimitFraction = 0,
|
||||
rateLimitPeriod = 0,
|
||||
} = {}) {
|
||||
if( minIntercept === 0 && minSlope === 0 && maxIntercept === 0 && maxSlope === 0 )
|
||||
marketOrder = true
|
||||
@@ -90,7 +94,7 @@ export function newTranche({
|
||||
fraction: Math.min(MAX_FRACTION, Math.round(fraction)), marketOrder,
|
||||
startTimeIsRelative, startTime, endTimeIsRelative, endTime,
|
||||
minIsBarrier, minIntercept, minSlope, maxIsBarrier, maxIntercept, maxSlope,
|
||||
_reserved5: false, _reserved6: false, _reserved7: false, _reserved8: 0, _reserved16: 0,
|
||||
minIsRatio, maxIsRatio, _reserved7: false, rateLimitFraction, rateLimitPeriod,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,10 +114,6 @@ export const OrderState = {
|
||||
Error: 99,
|
||||
}
|
||||
|
||||
export function orderIsOpen(order) {
|
||||
return isOpen(order.state)
|
||||
}
|
||||
|
||||
export function isOpen(state) {
|
||||
return state >= 1 && state < 3
|
||||
}
|
||||
@@ -121,7 +121,7 @@ export function isOpen(state) {
|
||||
export function parseOrderStatus(chainId, status) {
|
||||
let [
|
||||
order,
|
||||
fillFeeBP,
|
||||
fillFeeHalfBps,
|
||||
state,
|
||||
start,
|
||||
ocoGroup,
|
||||
@@ -129,14 +129,17 @@ export function parseOrderStatus(chainId, status) {
|
||||
filledOut,
|
||||
trancheFilledIn,
|
||||
trancheFilledOut,
|
||||
trancheActivationTime,
|
||||
] = status
|
||||
order = parseOrder(order)
|
||||
filledIn = BigInt(filledIn)
|
||||
filledOut = BigInt(filledOut)
|
||||
trancheFilledIn = trancheFilledIn.map((f)=>BigInt(f))
|
||||
trancheFilledOut = trancheFilledOut.map((f)=>BigInt(f))
|
||||
trancheActivationTime = trancheActivationTime.map((v)=>Number(v))
|
||||
return {
|
||||
chainId, order, fillFeeBP, state, start, ocoGroup, filledIn, filledOut, trancheFilledIn, trancheFilledOut,
|
||||
chainId, order, fillFeeHalfBps, state, start, ocoGroup,
|
||||
filledIn, filledOut, trancheFilledIn, trancheFilledOut, trancheActivationTime
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +153,7 @@ export function parseOrder(order) {
|
||||
minFillAmount,
|
||||
amountIsInput,
|
||||
outputDirectlyToOwner,
|
||||
chainOrder,
|
||||
conditionalOrder,
|
||||
tranches,
|
||||
] = order
|
||||
route = parseRoute(route)
|
||||
@@ -158,7 +161,7 @@ export function parseOrder(order) {
|
||||
minFillAmount = BigInt(minFillAmount)
|
||||
tranches = tranches.map(parseTranche)
|
||||
return {
|
||||
tokenIn, tokenOut, route, amount, minFillAmount, amountIsInput, outputDirectlyToOwner, chainOrder, tranches
|
||||
tokenIn, tokenOut, route, amount, minFillAmount, amountIsInput, outputDirectlyToOwner, conditionalOrder, tranches
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,11 +178,11 @@ export function parseTranche(tranche) {
|
||||
minIsBarrier,
|
||||
maxIsBarrier,
|
||||
marketOrder,
|
||||
_reserved5,
|
||||
_reserved6,
|
||||
minIsRatio,
|
||||
maxIsRatio,
|
||||
_reserved7,
|
||||
_reserved8,
|
||||
_reserved16,
|
||||
rateLimitFraction,
|
||||
rateLimitPeriod,
|
||||
startTime,
|
||||
endTime,
|
||||
minIntercept,
|
||||
@@ -193,6 +196,7 @@ export function parseTranche(tranche) {
|
||||
maxSlope = decodeIEE754(maxSlope)
|
||||
return {
|
||||
fraction, startTimeIsRelative, endTimeIsRelative, minIsBarrier, maxIsBarrier, marketOrder,
|
||||
minIsRatio, maxIsRatio, rateLimitFraction, rateLimitPeriod,
|
||||
startTime, endTime, minIntercept, minSlope, maxIntercept, maxSlope,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ import {useStore} from "@/store/store";
|
||||
import {socket} from "@/socket.js";
|
||||
import {contractOrNull, vaultAddress} from "@/blockchain/contract.js";
|
||||
import {SingletonCoroutine, uuid} from "@/misc.js";
|
||||
import {vaultAbi} from "@/blockchain/abi.js";
|
||||
import {factoryAbi, vaultAbi} from "@/blockchain/abi.js";
|
||||
import {defineStore} from "pinia";
|
||||
import {ref} from "vue";
|
||||
import {metadataMap} from "@/version.js";
|
||||
import {metadataMap, version} from "@/version.js";
|
||||
|
||||
|
||||
export let provider = null
|
||||
@@ -198,6 +198,7 @@ function discoverVaults(owner) {
|
||||
const doDiscoverVaults = new SingletonCoroutine(_discoverVaults, 50, false)
|
||||
async function _discoverVaults(owner) {
|
||||
const result = []
|
||||
const versions = []
|
||||
const s = useStore()
|
||||
if( !owner || !s.chainId || !s.account) {
|
||||
s.vaults = []
|
||||
@@ -205,38 +206,34 @@ async function _discoverVaults(owner) {
|
||||
}
|
||||
// todo multi-vault scan
|
||||
// console.log('_discoverVaults',owner)
|
||||
const num = 0
|
||||
const addr = vaultAddress(s.factory, s.vaultInitCodeHash, owner, num)
|
||||
// console.log(`vault ${num} at`, addr)
|
||||
if( addr === null ) {
|
||||
s.vaults = []
|
||||
return
|
||||
}
|
||||
console.log('provider', provider)
|
||||
if (!provider) {
|
||||
console.log('No provider')
|
||||
return // do not change whatever was already found
|
||||
}
|
||||
const vault = new ethers.Contract(addr, vaultAbi, provider)
|
||||
let version = -1
|
||||
try {
|
||||
version = await vault.version();
|
||||
if( Number(version) === 1 ) {
|
||||
console.log(`found vault ${num} at ${addr}`)
|
||||
result.push(addr)
|
||||
for (let num=0; num < 1; num++) {
|
||||
const num = 0
|
||||
const addr = vaultAddress(s.factory, s.vaultInitCodeHash, owner, num)
|
||||
// console.log(`vault ${num} at`, addr)
|
||||
if (addr === null) // no more vaults
|
||||
break
|
||||
console.log('provider', provider)
|
||||
if (!provider) {
|
||||
console.log('No provider')
|
||||
return // do not change whatever was already found
|
||||
}
|
||||
const vault = new ethers.Contract(addr, vaultAbi, provider)
|
||||
try {
|
||||
const version = Number(await vault.version())
|
||||
console.log(`found vault #${num} v${version} at ${addr}`)
|
||||
result.push(addr)
|
||||
versions.push(version)
|
||||
} catch (e) {
|
||||
if (e.value === '0x' && e.code === 'BAD_DATA' || e.revert === null && e.code === 'CALL_EXCEPTION')
|
||||
console.log(`no vault ${num} at ${addr}`)
|
||||
else
|
||||
console.error(`discoverVaults failed`, e)
|
||||
return // do not change what was already found todo is this correct?
|
||||
}
|
||||
else
|
||||
console.error(`bad vault version ${version}`)
|
||||
}
|
||||
catch (e) {
|
||||
if( e.value==='0x' && e.code==='BAD_DATA' || e.revert===null && e.code==='CALL_EXCEPTION' )
|
||||
console.log(`no vault ${num} at ${addr}`)
|
||||
else
|
||||
console.error(`discoverVaults failed`, e)
|
||||
return // do not change what was already found todo is this correct?
|
||||
}
|
||||
if( s.account === owner ) { // double-check the account since it could have changed during our await
|
||||
s.vaults = result
|
||||
s.vaultVersions = versions
|
||||
if( useWalletStore().pendingOrders.length ) {
|
||||
if (result.length)
|
||||
flushOrders(result[0])
|
||||
@@ -287,7 +284,6 @@ async function doEnsureVault(chainId, owner, num) {
|
||||
socket.emit('ensureVault', chainId, owner, num)
|
||||
}
|
||||
}
|
||||
// await sleep(5000) // prevent this process from running more than once every 5 seconds
|
||||
|
||||
const ensureVaultRoutine = new SingletonCoroutine(doEnsureVault, 100)
|
||||
|
||||
@@ -300,18 +296,27 @@ export const PendingOrderState = {
|
||||
}
|
||||
|
||||
|
||||
export async function pendOrder(order) {
|
||||
export async function placementFee(vault, order) {
|
||||
const v = new ethers.Contract(vault, vaultAbi, provider)
|
||||
const [orderFee, gasFee] = await v.placementFee(order)
|
||||
console.log('computed fees', orderFee, gasFee)
|
||||
return [orderFee, gasFee]
|
||||
}
|
||||
|
||||
|
||||
export async function pendOrder(order, fee=null) {
|
||||
const s = useStore()
|
||||
const pend = {
|
||||
id: uuid(),
|
||||
chainId: s.chainId,
|
||||
placementTime: Date.now()/1000,
|
||||
fee: fee,
|
||||
vault: s.vaults.length ? s.vaults[0] : null,
|
||||
state: PendingOrderState.Submitted,
|
||||
order
|
||||
};
|
||||
useWalletStore().pendingOrders.splice(0,0, pend)
|
||||
console.log('pending order', pend.id, JSON.stringify(order))
|
||||
console.log('pended order', pend.id, JSON.stringify(order))
|
||||
ensureVault()
|
||||
}
|
||||
|
||||
@@ -378,8 +383,12 @@ function pendOrderAsTransaction(pend) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
if (pend.fee === null) {
|
||||
const [orderFee, gasFee] = await placementFee(pend.vault, pend.order)
|
||||
pend.fee = orderFee + gasFee
|
||||
}
|
||||
console.log('placing order', pend.id, pend.order)
|
||||
const tx = await contract.placeDexorder(pend.order)
|
||||
const tx = await contract.placeDexorder(pend.order, {value:pend.fee})
|
||||
pend.tx = tx
|
||||
pend.state = PendingOrderState.Sent
|
||||
console.log(`order ${pend.id} sent transaction`, tx)
|
||||
@@ -400,7 +409,7 @@ function pendOrderAsTransaction(pend) {
|
||||
})
|
||||
}
|
||||
|
||||
0
|
||||
|
||||
export function pendTransaction(sender, errHandler) {
|
||||
const s = useStore()
|
||||
s.transactionSenders.push([sender,errHandler])
|
||||
@@ -462,3 +471,60 @@ function doSendTransaction(sender, signer, errHandler) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export async function detectUpgrade() {
|
||||
if (!provider) {
|
||||
console.log('no provider!')
|
||||
return 0
|
||||
}
|
||||
const s = useStore()
|
||||
if (!s.vault) {
|
||||
console.log('no vault logged in')
|
||||
return 0
|
||||
}
|
||||
|
||||
const info = version.chainInfo[s.chainId]
|
||||
if (!info) {
|
||||
console.log(`couldn't get chainInfo for ${s.chainId}`)
|
||||
return 0
|
||||
}
|
||||
try {
|
||||
console.log('factory', info.factory)
|
||||
const factory = new ethers.Contract(info.factory, factoryAbi, provider)
|
||||
const vault = new ethers.Contract(s.vault, vaultAbi, provider)
|
||||
const vaultLogic = await vault.logic()
|
||||
const latestLogic = await factory.logic()
|
||||
// const [vaultLogic, latestLogic] = await Promise.all( vault.logic(), factory.logic() )
|
||||
console.log('vaultLogic / latestLogic', vaultLogic, latestLogic)
|
||||
if ( vaultLogic !== latestLogic ) {
|
||||
s.upgrade = latestLogic
|
||||
const logic = new ethers.Contract(latestLogic, vaultAbi, provider)
|
||||
const version = await logic.version()
|
||||
console.log(`found vault version ${version}`)
|
||||
return version
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.error('ignorable error while querying for an upgrade', e)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
function upgradeSender(vault, logic) {
|
||||
return async function (signer) {
|
||||
const v = new ethers.Contract(vault, vaultAbi, signer)
|
||||
v.upgrade(logic)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function upgradeError(e) {
|
||||
console.error('error while upgrading vault', e)
|
||||
}
|
||||
|
||||
export async function upgradeVault(vault, logic) {
|
||||
pendTransaction(upgradeSender(vault, logic), upgradeError)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user