Fix up lint configuration, lint line endings (#615)
* Make sure we ignore all built code in common and functions * Add lint for Unix line endings * Fix line endings in withdraw-liquidity.ts
This commit is contained in:
parent
b26648c1ce
commit
9bff858696
|
@ -1,6 +1,7 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
plugins: ['lodash'],
|
plugins: ['lodash'],
|
||||||
extends: ['eslint:recommended'],
|
extends: ['eslint:recommended'],
|
||||||
|
ignorePatterns: ['lib'],
|
||||||
env: {
|
env: {
|
||||||
browser: true,
|
browser: true,
|
||||||
node: true,
|
node: true,
|
||||||
|
@ -31,6 +32,7 @@ module.exports = {
|
||||||
rules: {
|
rules: {
|
||||||
'no-extra-semi': 'off',
|
'no-extra-semi': 'off',
|
||||||
'no-constant-condition': ['error', { checkLoops: false }],
|
'no-constant-condition': ['error', { checkLoops: false }],
|
||||||
|
'linebreak-style': ['error', 'unix'],
|
||||||
'lodash/import-scope': [2, 'member'],
|
'lodash/import-scope': [2, 'member'],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
plugins: ['lodash'],
|
plugins: ['lodash'],
|
||||||
extends: ['eslint:recommended'],
|
extends: ['eslint:recommended'],
|
||||||
ignorePatterns: ['lib'],
|
ignorePatterns: ['dist', 'lib'],
|
||||||
env: {
|
env: {
|
||||||
node: true,
|
node: true,
|
||||||
},
|
},
|
||||||
|
@ -30,6 +30,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
rules: {
|
rules: {
|
||||||
|
'linebreak-style': ['error', 'unix'],
|
||||||
'lodash/import-scope': [2, 'member'],
|
'lodash/import-scope': [2, 'member'],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,138 +1,138 @@
|
||||||
import * as functions from 'firebase-functions'
|
import * as functions from 'firebase-functions'
|
||||||
import * as admin from 'firebase-admin'
|
import * as admin from 'firebase-admin'
|
||||||
|
|
||||||
import { CPMMContract } from '../../common/contract'
|
import { CPMMContract } from '../../common/contract'
|
||||||
import { User } from '../../common/user'
|
import { User } from '../../common/user'
|
||||||
import { subtractObjects } from '../../common/util/object'
|
import { subtractObjects } from '../../common/util/object'
|
||||||
import { LiquidityProvision } from '../../common/liquidity-provision'
|
import { LiquidityProvision } from '../../common/liquidity-provision'
|
||||||
import { getUserLiquidityShares } from '../../common/calculate-cpmm'
|
import { getUserLiquidityShares } from '../../common/calculate-cpmm'
|
||||||
import { Bet } from '../../common/bet'
|
import { Bet } from '../../common/bet'
|
||||||
import { getProbability } from '../../common/calculate'
|
import { getProbability } from '../../common/calculate'
|
||||||
import { noFees } from '../../common/fees'
|
import { noFees } from '../../common/fees'
|
||||||
|
|
||||||
import { APIError } from './api'
|
import { APIError } from './api'
|
||||||
import { redeemShares } from './redeem-shares'
|
import { redeemShares } from './redeem-shares'
|
||||||
|
|
||||||
export const withdrawLiquidity = functions
|
export const withdrawLiquidity = functions
|
||||||
.runWith({ minInstances: 1 })
|
.runWith({ minInstances: 1 })
|
||||||
.https.onCall(
|
.https.onCall(
|
||||||
async (
|
async (
|
||||||
data: {
|
data: {
|
||||||
contractId: string
|
contractId: string
|
||||||
},
|
},
|
||||||
context
|
context
|
||||||
) => {
|
) => {
|
||||||
const userId = context?.auth?.uid
|
const userId = context?.auth?.uid
|
||||||
if (!userId) return { status: 'error', message: 'Not authorized' }
|
if (!userId) return { status: 'error', message: 'Not authorized' }
|
||||||
|
|
||||||
const { contractId } = data
|
const { contractId } = data
|
||||||
if (!contractId)
|
if (!contractId)
|
||||||
return { status: 'error', message: 'Missing contract id' }
|
return { status: 'error', message: 'Missing contract id' }
|
||||||
|
|
||||||
return await firestore
|
return await firestore
|
||||||
.runTransaction(async (trans) => {
|
.runTransaction(async (trans) => {
|
||||||
const lpDoc = firestore.doc(`users/${userId}`)
|
const lpDoc = firestore.doc(`users/${userId}`)
|
||||||
const lpSnap = await trans.get(lpDoc)
|
const lpSnap = await trans.get(lpDoc)
|
||||||
if (!lpSnap.exists) throw new APIError(400, 'User not found.')
|
if (!lpSnap.exists) throw new APIError(400, 'User not found.')
|
||||||
const lp = lpSnap.data() as User
|
const lp = lpSnap.data() as User
|
||||||
|
|
||||||
const contractDoc = firestore.doc(`contracts/${contractId}`)
|
const contractDoc = firestore.doc(`contracts/${contractId}`)
|
||||||
const contractSnap = await trans.get(contractDoc)
|
const contractSnap = await trans.get(contractDoc)
|
||||||
if (!contractSnap.exists)
|
if (!contractSnap.exists)
|
||||||
throw new APIError(400, 'Contract not found.')
|
throw new APIError(400, 'Contract not found.')
|
||||||
const contract = contractSnap.data() as CPMMContract
|
const contract = contractSnap.data() as CPMMContract
|
||||||
|
|
||||||
const liquidityCollection = firestore.collection(
|
const liquidityCollection = firestore.collection(
|
||||||
`contracts/${contractId}/liquidity`
|
`contracts/${contractId}/liquidity`
|
||||||
)
|
)
|
||||||
|
|
||||||
const liquiditiesSnap = await trans.get(liquidityCollection)
|
const liquiditiesSnap = await trans.get(liquidityCollection)
|
||||||
|
|
||||||
const liquidities = liquiditiesSnap.docs.map(
|
const liquidities = liquiditiesSnap.docs.map(
|
||||||
(doc) => doc.data() as LiquidityProvision
|
(doc) => doc.data() as LiquidityProvision
|
||||||
)
|
)
|
||||||
|
|
||||||
const userShares = getUserLiquidityShares(
|
const userShares = getUserLiquidityShares(
|
||||||
userId,
|
userId,
|
||||||
contract,
|
contract,
|
||||||
liquidities
|
liquidities
|
||||||
)
|
)
|
||||||
|
|
||||||
// zero all added amounts for now
|
// zero all added amounts for now
|
||||||
// can add support for partial withdrawals in the future
|
// can add support for partial withdrawals in the future
|
||||||
liquiditiesSnap.docs
|
liquiditiesSnap.docs
|
||||||
.filter(
|
.filter(
|
||||||
(_, i) =>
|
(_, i) =>
|
||||||
!liquidities[i].isAnte && liquidities[i].userId === userId
|
!liquidities[i].isAnte && liquidities[i].userId === userId
|
||||||
)
|
)
|
||||||
.forEach((doc) => trans.update(doc.ref, { amount: 0 }))
|
.forEach((doc) => trans.update(doc.ref, { amount: 0 }))
|
||||||
|
|
||||||
const payout = Math.min(...Object.values(userShares))
|
const payout = Math.min(...Object.values(userShares))
|
||||||
if (payout <= 0) return {}
|
if (payout <= 0) return {}
|
||||||
|
|
||||||
const newBalance = lp.balance + payout
|
const newBalance = lp.balance + payout
|
||||||
const newTotalDeposits = lp.totalDeposits + payout
|
const newTotalDeposits = lp.totalDeposits + payout
|
||||||
trans.update(lpDoc, {
|
trans.update(lpDoc, {
|
||||||
balance: newBalance,
|
balance: newBalance,
|
||||||
totalDeposits: newTotalDeposits,
|
totalDeposits: newTotalDeposits,
|
||||||
} as Partial<User>)
|
} as Partial<User>)
|
||||||
|
|
||||||
const newPool = subtractObjects(contract.pool, userShares)
|
const newPool = subtractObjects(contract.pool, userShares)
|
||||||
|
|
||||||
const minPoolShares = Math.min(...Object.values(newPool))
|
const minPoolShares = Math.min(...Object.values(newPool))
|
||||||
const adjustedTotal = contract.totalLiquidity - payout
|
const adjustedTotal = contract.totalLiquidity - payout
|
||||||
|
|
||||||
// total liquidity is a bogus number; use minPoolShares to prevent from going negative
|
// total liquidity is a bogus number; use minPoolShares to prevent from going negative
|
||||||
const newTotalLiquidity = Math.max(adjustedTotal, minPoolShares)
|
const newTotalLiquidity = Math.max(adjustedTotal, minPoolShares)
|
||||||
|
|
||||||
trans.update(contractDoc, {
|
trans.update(contractDoc, {
|
||||||
pool: newPool,
|
pool: newPool,
|
||||||
totalLiquidity: newTotalLiquidity,
|
totalLiquidity: newTotalLiquidity,
|
||||||
})
|
})
|
||||||
|
|
||||||
const prob = getProbability(contract)
|
const prob = getProbability(contract)
|
||||||
|
|
||||||
// surplus shares become user's bets
|
// surplus shares become user's bets
|
||||||
const bets = Object.entries(userShares)
|
const bets = Object.entries(userShares)
|
||||||
.map(([outcome, shares]) =>
|
.map(([outcome, shares]) =>
|
||||||
shares - payout < 1 // don't create bet if less than 1 share
|
shares - payout < 1 // don't create bet if less than 1 share
|
||||||
? undefined
|
? undefined
|
||||||
: ({
|
: ({
|
||||||
userId: userId,
|
userId: userId,
|
||||||
contractId: contract.id,
|
contractId: contract.id,
|
||||||
amount:
|
amount:
|
||||||
(outcome === 'YES' ? prob : 1 - prob) * (shares - payout),
|
(outcome === 'YES' ? prob : 1 - prob) * (shares - payout),
|
||||||
shares: shares - payout,
|
shares: shares - payout,
|
||||||
outcome,
|
outcome,
|
||||||
probBefore: prob,
|
probBefore: prob,
|
||||||
probAfter: prob,
|
probAfter: prob,
|
||||||
createdTime: Date.now(),
|
createdTime: Date.now(),
|
||||||
isLiquidityProvision: true,
|
isLiquidityProvision: true,
|
||||||
fees: noFees,
|
fees: noFees,
|
||||||
} as Omit<Bet, 'id'>)
|
} as Omit<Bet, 'id'>)
|
||||||
)
|
)
|
||||||
.filter((x) => x !== undefined)
|
.filter((x) => x !== undefined)
|
||||||
|
|
||||||
for (const bet of bets) {
|
for (const bet of bets) {
|
||||||
const doc = firestore
|
const doc = firestore
|
||||||
.collection(`contracts/${contract.id}/bets`)
|
.collection(`contracts/${contract.id}/bets`)
|
||||||
.doc()
|
.doc()
|
||||||
trans.create(doc, { id: doc.id, ...bet })
|
trans.create(doc, { id: doc.id, ...bet })
|
||||||
}
|
}
|
||||||
|
|
||||||
return userShares
|
return userShares
|
||||||
})
|
})
|
||||||
.then(async (result) => {
|
.then(async (result) => {
|
||||||
// redeem surplus bet with pre-existing bets
|
// redeem surplus bet with pre-existing bets
|
||||||
await redeemShares(userId, contractId)
|
await redeemShares(userId, contractId)
|
||||||
|
|
||||||
console.log('userid', userId, 'withdraws', result)
|
console.log('userid', userId, 'withdraws', result)
|
||||||
return { status: 'success', userShares: result }
|
return { status: 'success', userShares: result }
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
return { status: 'error', message: e.message }
|
return { status: 'error', message: e.message }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const firestore = admin.firestore()
|
const firestore = admin.firestore()
|
||||||
|
|
|
@ -19,6 +19,7 @@ module.exports = {
|
||||||
],
|
],
|
||||||
'@next/next/no-img-element': 'off',
|
'@next/next/no-img-element': 'off',
|
||||||
'@next/next/no-typos': 'off',
|
'@next/next/no-typos': 'off',
|
||||||
|
'linebreak-style': ['error', 'unix'],
|
||||||
'lodash/import-scope': [2, 'member'],
|
'lodash/import-scope': [2, 'member'],
|
||||||
},
|
},
|
||||||
env: {
|
env: {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user