Pay back loan on sell shares
This commit is contained in:
parent
31606a191c
commit
8740de50bd
|
@ -79,8 +79,8 @@ export const getCpmmSellBetInfo = (
|
||||||
shares: number,
|
shares: number,
|
||||||
outcome: 'YES' | 'NO',
|
outcome: 'YES' | 'NO',
|
||||||
contract: CPMMContract,
|
contract: CPMMContract,
|
||||||
prevLoanAmount: number,
|
unfilledBets: LimitBet[],
|
||||||
unfilledBets: LimitBet[]
|
loanPaid: number
|
||||||
) => {
|
) => {
|
||||||
const { pool, p } = contract
|
const { pool, p } = contract
|
||||||
|
|
||||||
|
@ -91,7 +91,6 @@ export const getCpmmSellBetInfo = (
|
||||||
unfilledBets
|
unfilledBets
|
||||||
)
|
)
|
||||||
|
|
||||||
const loanPaid = Math.min(prevLoanAmount, saleValue)
|
|
||||||
const probBefore = getCpmmProbability(pool, p)
|
const probBefore = getCpmmProbability(pool, p)
|
||||||
const probAfter = getCpmmProbability(cpmmState.pool, cpmmState.p)
|
const probAfter = getCpmmProbability(cpmmState.pool, cpmmState.p)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Contract, CPMM_MIN_POOL_QTY } from '../../common/contract'
|
||||||
import { User } from '../../common/user'
|
import { User } from '../../common/user'
|
||||||
import { getCpmmSellBetInfo } from '../../common/sell-bet'
|
import { getCpmmSellBetInfo } from '../../common/sell-bet'
|
||||||
import { addObjects, removeUndefinedProps } from '../../common/util/object'
|
import { addObjects, removeUndefinedProps } from '../../common/util/object'
|
||||||
import { getValues, log } from './utils'
|
import { log } from './utils'
|
||||||
import { Bet } from '../../common/bet'
|
import { Bet } from '../../common/bet'
|
||||||
import { floatingEqual, floatingLesserEqual } from '../../common/util/math'
|
import { floatingEqual, floatingLesserEqual } from '../../common/util/math'
|
||||||
import { getUnfilledBetsQuery, updateMakers } from './place-bet'
|
import { getUnfilledBetsQuery, updateMakers } from './place-bet'
|
||||||
|
@ -28,12 +28,16 @@ export const sellshares = newEndpoint({}, async (req, auth) => {
|
||||||
const contractDoc = firestore.doc(`contracts/${contractId}`)
|
const contractDoc = firestore.doc(`contracts/${contractId}`)
|
||||||
const userDoc = firestore.doc(`users/${auth.uid}`)
|
const userDoc = firestore.doc(`users/${auth.uid}`)
|
||||||
const betsQ = contractDoc.collection('bets').where('userId', '==', auth.uid)
|
const betsQ = contractDoc.collection('bets').where('userId', '==', auth.uid)
|
||||||
const [[contractSnap, userSnap], userBets] = await Promise.all([
|
const [[contractSnap, userSnap], userBetsSnap, unfilledBetsSnap] =
|
||||||
|
await Promise.all([
|
||||||
transaction.getAll(contractDoc, userDoc),
|
transaction.getAll(contractDoc, userDoc),
|
||||||
getValues<Bet>(betsQ), // TODO: why is this not in the transaction??
|
transaction.get(betsQ),
|
||||||
|
transaction.get(getUnfilledBetsQuery(contractDoc)),
|
||||||
])
|
])
|
||||||
if (!contractSnap.exists) throw new APIError(400, 'Contract not found.')
|
if (!contractSnap.exists) throw new APIError(400, 'Contract not found.')
|
||||||
if (!userSnap.exists) throw new APIError(400, 'User not found.')
|
if (!userSnap.exists) throw new APIError(400, 'User not found.')
|
||||||
|
const userBets = userBetsSnap.docs.map((doc) => doc.data() as Bet)
|
||||||
|
const unfilledBets = unfilledBetsSnap.docs.map((doc) => doc.data())
|
||||||
|
|
||||||
const contract = contractSnap.data() as Contract
|
const contract = contractSnap.data() as Contract
|
||||||
const user = userSnap.data() as User
|
const user = userSnap.data() as User
|
||||||
|
@ -45,7 +49,7 @@ export const sellshares = newEndpoint({}, async (req, auth) => {
|
||||||
if (closeTime && Date.now() > closeTime)
|
if (closeTime && Date.now() > closeTime)
|
||||||
throw new APIError(400, 'Trading is closed.')
|
throw new APIError(400, 'Trading is closed.')
|
||||||
|
|
||||||
const prevLoanAmount = sumBy(userBets, (bet) => bet.loanAmount ?? 0)
|
const loanAmount = sumBy(userBets, (bet) => bet.loanAmount ?? 0)
|
||||||
const betsByOutcome = groupBy(userBets, (bet) => bet.outcome)
|
const betsByOutcome = groupBy(userBets, (bet) => bet.outcome)
|
||||||
const sharesByOutcome = mapValues(betsByOutcome, (bets) =>
|
const sharesByOutcome = mapValues(betsByOutcome, (bets) =>
|
||||||
sumBy(bets, (b) => b.shares)
|
sumBy(bets, (b) => b.shares)
|
||||||
|
@ -77,18 +81,16 @@ export const sellshares = newEndpoint({}, async (req, auth) => {
|
||||||
throw new APIError(400, `You can only sell up to ${maxShares} shares.`)
|
throw new APIError(400, `You can only sell up to ${maxShares} shares.`)
|
||||||
|
|
||||||
const soldShares = Math.min(sharesToSell, maxShares)
|
const soldShares = Math.min(sharesToSell, maxShares)
|
||||||
|
const saleFrac = soldShares / maxShares
|
||||||
const unfilledBetsSnap = await transaction.get(
|
let loanPaid = saleFrac * loanAmount
|
||||||
getUnfilledBetsQuery(contractDoc)
|
if (!isFinite(loanPaid)) loanPaid = 0
|
||||||
)
|
|
||||||
const unfilledBets = unfilledBetsSnap.docs.map((doc) => doc.data())
|
|
||||||
|
|
||||||
const { newBet, newPool, newP, fees, makers } = getCpmmSellBetInfo(
|
const { newBet, newPool, newP, fees, makers } = getCpmmSellBetInfo(
|
||||||
soldShares,
|
soldShares,
|
||||||
chosenOutcome,
|
chosenOutcome,
|
||||||
contract,
|
contract,
|
||||||
prevLoanAmount,
|
unfilledBets,
|
||||||
unfilledBets
|
loanPaid
|
||||||
)
|
)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -104,7 +106,7 @@ export const sellshares = newEndpoint({}, async (req, auth) => {
|
||||||
updateMakers(makers, newBetDoc.id, contractDoc, transaction)
|
updateMakers(makers, newBetDoc.id, contractDoc, transaction)
|
||||||
|
|
||||||
transaction.update(userDoc, {
|
transaction.update(userDoc, {
|
||||||
balance: FieldValue.increment(-newBet.amount),
|
balance: FieldValue.increment(-newBet.amount + (newBet.loanAmount ?? 0)),
|
||||||
})
|
})
|
||||||
transaction.create(newBetDoc, {
|
transaction.create(newBetDoc, {
|
||||||
id: newBetDoc.id,
|
id: newBetDoc.id,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user