fix accept challenge: don't change pool/probability
This commit is contained in:
parent
776e0cd86d
commit
cecf696e1f
|
@ -8,20 +8,22 @@ import { FieldValue } from 'firebase-admin/firestore'
|
||||||
import { removeUndefinedProps } from '../../common/util/object'
|
import { removeUndefinedProps } from '../../common/util/object'
|
||||||
import { Acceptance, Challenge } from '../../common/challenge'
|
import { Acceptance, Challenge } from '../../common/challenge'
|
||||||
import { CandidateBet } from '../../common/new-bet'
|
import { CandidateBet } from '../../common/new-bet'
|
||||||
import { getCpmmProbability } from '../../common/calculate-cpmm'
|
|
||||||
import { createChallengeAcceptedNotification } from './create-notification'
|
import { createChallengeAcceptedNotification } from './create-notification'
|
||||||
|
import { noFees } from 'common/fees'
|
||||||
|
import { formatMoney, formatPercent } from 'common/util/format'
|
||||||
|
|
||||||
const bodySchema = z.object({
|
const bodySchema = z.object({
|
||||||
contractId: z.string(),
|
contractId: z.string(),
|
||||||
challengeSlug: z.string(),
|
challengeSlug: z.string(),
|
||||||
|
outcomeType: z.literal('BINARY'),
|
||||||
|
closeTime: z.number().gte(Date.now()),
|
||||||
})
|
})
|
||||||
const firestore = admin.firestore()
|
const firestore = admin.firestore()
|
||||||
|
|
||||||
export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
||||||
log('Inside endpoint handler.')
|
|
||||||
const { challengeSlug, contractId } = validate(bodySchema, req.body)
|
const { challengeSlug, contractId } = validate(bodySchema, req.body)
|
||||||
|
|
||||||
const result = await firestore.runTransaction(async (trans) => {
|
const result = await firestore.runTransaction(async (trans) => {
|
||||||
log('Inside main transaction.')
|
|
||||||
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 challengeDoc = firestore.doc(
|
const challengeDoc = firestore.doc(
|
||||||
|
@ -35,7 +37,6 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
||||||
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.')
|
||||||
if (!challengeSnap.exists) throw new APIError(400, 'Challenge not found.')
|
if (!challengeSnap.exists) throw new APIError(400, 'Challenge not found.')
|
||||||
log('Loaded user and contract snapshots.')
|
|
||||||
|
|
||||||
const anyContract = contractSnap.data() as Contract
|
const anyContract = contractSnap.data() as Contract
|
||||||
const user = userSnap.data() as User
|
const user = userSnap.data() as User
|
||||||
|
@ -51,28 +52,28 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
||||||
|
|
||||||
const { creatorAmount, yourOutcome, creatorsOutcome, creatorsOutcomeProb } =
|
const { creatorAmount, yourOutcome, creatorsOutcome, creatorsOutcomeProb } =
|
||||||
challenge
|
challenge
|
||||||
|
|
||||||
const yourCost =
|
const yourCost =
|
||||||
((1 - creatorsOutcomeProb) / creatorsOutcomeProb) * creatorAmount
|
((1 - creatorsOutcomeProb) / creatorsOutcomeProb) * creatorAmount
|
||||||
|
|
||||||
if (user.balance < yourCost)
|
if (user.balance < yourCost)
|
||||||
throw new APIError(400, 'Insufficient balance.')
|
throw new APIError(400, 'Insufficient balance.')
|
||||||
|
|
||||||
const { closeTime, outcomeType } = anyContract
|
|
||||||
if (closeTime && Date.now() > closeTime)
|
|
||||||
throw new APIError(400, 'Trading is closed.')
|
|
||||||
if (outcomeType !== 'BINARY')
|
|
||||||
throw new APIError(400, 'Challenges only accepted for binary markets.')
|
|
||||||
|
|
||||||
const contract = anyContract as CPMMBinaryContract
|
const contract = anyContract as CPMMBinaryContract
|
||||||
const { YES: y, NO: n } = contract.pool
|
|
||||||
const shares = (1 / creatorsOutcomeProb) * creatorAmount
|
const shares = (1 / creatorsOutcomeProb) * creatorAmount
|
||||||
|
const createdTime = Date.now()
|
||||||
|
|
||||||
const newPool = {
|
log(
|
||||||
YES: y + shares,
|
'Creating challenge bet for',
|
||||||
NO: n + shares,
|
user.username,
|
||||||
}
|
shares,
|
||||||
const probBefore = getCpmmProbability(contract.pool, contract.p)
|
yourOutcome,
|
||||||
const probAfter = getCpmmProbability(newPool, contract.p)
|
'shares',
|
||||||
|
'at',
|
||||||
|
formatPercent(creatorsOutcomeProb),
|
||||||
|
'for',
|
||||||
|
formatMoney(yourCost)
|
||||||
|
)
|
||||||
|
|
||||||
const yourNewBet: CandidateBet = removeUndefinedProps({
|
const yourNewBet: CandidateBet = removeUndefinedProps({
|
||||||
orderAmount: yourCost,
|
orderAmount: yourCost,
|
||||||
|
@ -81,22 +82,21 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
||||||
isCancelled: false,
|
isCancelled: false,
|
||||||
contractId: contract.id,
|
contractId: contract.id,
|
||||||
outcome: yourOutcome,
|
outcome: yourOutcome,
|
||||||
probBefore,
|
probBefore: creatorsOutcomeProb,
|
||||||
probAfter,
|
probAfter: creatorsOutcomeProb,
|
||||||
loanAmount: 0,
|
loanAmount: 0,
|
||||||
createdTime: Date.now(),
|
createdTime,
|
||||||
fees: { creatorFee: 0, platformFee: 0, liquidityFee: 0 },
|
fees: noFees,
|
||||||
})
|
})
|
||||||
|
|
||||||
const yourNewBetDoc = contractDoc.collection('bets').doc()
|
const yourNewBetDoc = contractDoc.collection('bets').doc()
|
||||||
trans.create(yourNewBetDoc, {
|
trans.create(yourNewBetDoc, {
|
||||||
id: yourNewBetDoc.id,
|
id: yourNewBetDoc.id,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
...yourNewBet,
|
...yourNewBet,
|
||||||
})
|
})
|
||||||
log('Created new bet document.')
|
|
||||||
|
|
||||||
trans.update(userDoc, { balance: FieldValue.increment(-yourNewBet.amount) })
|
trans.update(userDoc, { balance: FieldValue.increment(-yourNewBet.amount) })
|
||||||
log('Updated user balance.')
|
|
||||||
|
|
||||||
const creatorNewBet: CandidateBet = removeUndefinedProps({
|
const creatorNewBet: CandidateBet = removeUndefinedProps({
|
||||||
orderAmount: creatorAmount,
|
orderAmount: creatorAmount,
|
||||||
|
@ -105,11 +105,11 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
||||||
isCancelled: false,
|
isCancelled: false,
|
||||||
contractId: contract.id,
|
contractId: contract.id,
|
||||||
outcome: creatorsOutcome,
|
outcome: creatorsOutcome,
|
||||||
probBefore,
|
probBefore: creatorsOutcomeProb,
|
||||||
probAfter,
|
probAfter: creatorsOutcomeProb,
|
||||||
loanAmount: 0,
|
loanAmount: 0,
|
||||||
createdTime: Date.now(),
|
createdTime,
|
||||||
fees: { creatorFee: 0, platformFee: 0, liquidityFee: 0 },
|
fees: noFees,
|
||||||
})
|
})
|
||||||
const creatorBetDoc = contractDoc.collection('bets').doc()
|
const creatorBetDoc = contractDoc.collection('bets').doc()
|
||||||
trans.create(creatorBetDoc, {
|
trans.create(creatorBetDoc, {
|
||||||
|
@ -117,21 +117,13 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
||||||
userId: creator.id,
|
userId: creator.id,
|
||||||
...creatorNewBet,
|
...creatorNewBet,
|
||||||
})
|
})
|
||||||
log('Created new bet document.')
|
|
||||||
|
|
||||||
trans.update(creatorDoc, {
|
trans.update(creatorDoc, {
|
||||||
balance: FieldValue.increment(-creatorNewBet.amount),
|
balance: FieldValue.increment(-creatorNewBet.amount),
|
||||||
})
|
})
|
||||||
log('Updated user balance.')
|
|
||||||
|
|
||||||
trans.update(
|
const volume = contract.volume + yourNewBet.amount + creatorNewBet.amount
|
||||||
contractDoc,
|
trans.update(contractDoc, { volume })
|
||||||
removeUndefinedProps({
|
|
||||||
pool: newPool,
|
|
||||||
volume: contract.volume + yourNewBet.amount + creatorNewBet.amount,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
log('Updated contract properties.')
|
|
||||||
|
|
||||||
trans.update(
|
trans.update(
|
||||||
challengeDoc,
|
challengeDoc,
|
||||||
|
@ -141,7 +133,7 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
||||||
{
|
{
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
betId: yourNewBetDoc.id,
|
betId: yourNewBetDoc.id,
|
||||||
createdTime: Date.now(),
|
createdTime,
|
||||||
amount: yourCost,
|
amount: yourCost,
|
||||||
userUsername: user.username,
|
userUsername: user.username,
|
||||||
userName: user.name,
|
userName: user.name,
|
||||||
|
@ -150,7 +142,6 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
log('Updated challenge properties with new acceptance.')
|
|
||||||
|
|
||||||
await createChallengeAcceptedNotification(
|
await createChallengeAcceptedNotification(
|
||||||
user,
|
user,
|
||||||
|
@ -159,7 +150,7 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
||||||
yourCost,
|
yourCost,
|
||||||
contract
|
contract
|
||||||
)
|
)
|
||||||
log('Created notification.')
|
log('Done, sent notification.')
|
||||||
return yourNewBetDoc
|
return yourNewBetDoc
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user