separate logic to payouts-dpm, payouts-fixed
This commit is contained in:
parent
a315f6d841
commit
9c5478d3d5
146
common/payouts-dpm.ts
Normal file
146
common/payouts-dpm.ts
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
import * as _ from 'lodash'
|
||||||
|
|
||||||
|
import { Bet } from './bet'
|
||||||
|
import { deductDpmFees, getDpmProbability } from './calculate-dpm'
|
||||||
|
import { DPM, FreeResponse, FullContract, Multi } from './contract'
|
||||||
|
import { CREATOR_FEE, FEES } from './fees'
|
||||||
|
|
||||||
|
export const getDpmCancelPayouts = (
|
||||||
|
contract: FullContract<DPM, any>,
|
||||||
|
bets: Bet[]
|
||||||
|
) => {
|
||||||
|
const { pool } = contract
|
||||||
|
const poolTotal = _.sum(Object.values(pool))
|
||||||
|
console.log('resolved N/A, pool M$', poolTotal)
|
||||||
|
|
||||||
|
const betSum = _.sumBy(bets, (b) => b.amount)
|
||||||
|
|
||||||
|
return bets.map((bet) => ({
|
||||||
|
userId: bet.userId,
|
||||||
|
payout: (bet.amount / betSum) * poolTotal,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getDpmStandardPayouts = (
|
||||||
|
outcome: string,
|
||||||
|
contract: FullContract<DPM, any>,
|
||||||
|
bets: Bet[]
|
||||||
|
) => {
|
||||||
|
const winningBets = bets.filter((bet) => bet.outcome === outcome)
|
||||||
|
|
||||||
|
const poolTotal = _.sum(Object.values(contract.pool))
|
||||||
|
const totalShares = _.sumBy(winningBets, (b) => b.shares)
|
||||||
|
|
||||||
|
const payouts = winningBets.map(({ userId, amount, shares }) => {
|
||||||
|
const winnings = (shares / totalShares) * poolTotal
|
||||||
|
const profit = winnings - amount
|
||||||
|
|
||||||
|
// profit can be negative if using phantom shares
|
||||||
|
const payout = amount + (1 - FEES) * Math.max(0, profit)
|
||||||
|
return { userId, profit, payout }
|
||||||
|
})
|
||||||
|
|
||||||
|
const profits = _.sumBy(payouts, (po) => Math.max(0, po.profit))
|
||||||
|
const creatorPayout = CREATOR_FEE * profits
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
'resolved',
|
||||||
|
outcome,
|
||||||
|
'pool',
|
||||||
|
poolTotal,
|
||||||
|
'profits',
|
||||||
|
profits,
|
||||||
|
'creator fee',
|
||||||
|
creatorPayout
|
||||||
|
)
|
||||||
|
|
||||||
|
return payouts
|
||||||
|
.map(({ userId, payout }) => ({ userId, payout }))
|
||||||
|
.concat([{ userId: contract.creatorId, payout: creatorPayout }]) // add creator fee
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getDpmMktPayouts = (
|
||||||
|
contract: FullContract<DPM, any>,
|
||||||
|
bets: Bet[],
|
||||||
|
resolutionProbability?: number
|
||||||
|
) => {
|
||||||
|
const p =
|
||||||
|
resolutionProbability === undefined
|
||||||
|
? getDpmProbability(contract.totalShares)
|
||||||
|
: resolutionProbability
|
||||||
|
|
||||||
|
const weightedShareTotal = _.sumBy(bets, (b) =>
|
||||||
|
b.outcome === 'YES' ? p * b.shares : (1 - p) * b.shares
|
||||||
|
)
|
||||||
|
|
||||||
|
const pool = contract.pool.YES + contract.pool.NO
|
||||||
|
|
||||||
|
const payouts = bets.map(({ userId, outcome, amount, shares }) => {
|
||||||
|
const betP = outcome === 'YES' ? p : 1 - p
|
||||||
|
const winnings = ((betP * shares) / weightedShareTotal) * pool
|
||||||
|
const profit = winnings - amount
|
||||||
|
const payout = deductDpmFees(amount, winnings)
|
||||||
|
return { userId, profit, payout }
|
||||||
|
})
|
||||||
|
|
||||||
|
const profits = _.sumBy(payouts, (po) => Math.max(0, po.profit))
|
||||||
|
const creatorPayout = CREATOR_FEE * profits
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
'resolved MKT',
|
||||||
|
p,
|
||||||
|
'pool',
|
||||||
|
pool,
|
||||||
|
'profits',
|
||||||
|
profits,
|
||||||
|
'creator fee',
|
||||||
|
creatorPayout
|
||||||
|
)
|
||||||
|
|
||||||
|
return payouts
|
||||||
|
.map(({ userId, payout }) => ({ userId, payout }))
|
||||||
|
.concat([{ userId: contract.creatorId, payout: creatorPayout }]) // add creator fee
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getPayoutsMultiOutcome = (
|
||||||
|
resolutions: { [outcome: string]: number },
|
||||||
|
contract: FullContract<DPM, Multi | FreeResponse>,
|
||||||
|
bets: Bet[]
|
||||||
|
) => {
|
||||||
|
const poolTotal = _.sum(Object.values(contract.pool))
|
||||||
|
const winningBets = bets.filter((bet) => resolutions[bet.outcome])
|
||||||
|
|
||||||
|
const betsByOutcome = _.groupBy(winningBets, (bet) => bet.outcome)
|
||||||
|
const sharesByOutcome = _.mapValues(betsByOutcome, (bets) =>
|
||||||
|
_.sumBy(bets, (bet) => bet.shares)
|
||||||
|
)
|
||||||
|
|
||||||
|
const probTotal = _.sum(Object.values(resolutions))
|
||||||
|
|
||||||
|
const payouts = winningBets.map(({ userId, outcome, amount, shares }) => {
|
||||||
|
const prob = resolutions[outcome] / probTotal
|
||||||
|
const winnings = (shares / sharesByOutcome[outcome]) * prob * poolTotal
|
||||||
|
const profit = winnings - amount
|
||||||
|
|
||||||
|
const payout = amount + (1 - FEES) * Math.max(0, profit)
|
||||||
|
return { userId, profit, payout }
|
||||||
|
})
|
||||||
|
|
||||||
|
const profits = _.sumBy(payouts, (po) => po.profit)
|
||||||
|
const creatorPayout = CREATOR_FEE * profits
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
'resolved',
|
||||||
|
resolutions,
|
||||||
|
'pool',
|
||||||
|
poolTotal,
|
||||||
|
'profits',
|
||||||
|
profits,
|
||||||
|
'creator fee',
|
||||||
|
creatorPayout
|
||||||
|
)
|
||||||
|
|
||||||
|
return payouts
|
||||||
|
.map(({ userId, payout }) => ({ userId, payout }))
|
||||||
|
.concat([{ userId: contract.creatorId, payout: creatorPayout }]) // add creator fee
|
||||||
|
}
|
103
common/payouts-fixed.ts
Normal file
103
common/payouts-fixed.ts
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
import * as _ from 'lodash'
|
||||||
|
|
||||||
|
import { Bet } from './bet'
|
||||||
|
import { getProbability } from './calculate'
|
||||||
|
import { deductFixedFees } from './calculate-fixed-payouts'
|
||||||
|
import { Binary, CPMM, FixedPayouts, FullContract } from './contract'
|
||||||
|
import { CREATOR_FEE } from './fees'
|
||||||
|
|
||||||
|
export const getFixedCancelPayouts = (bets: Bet[]) => {
|
||||||
|
return bets.map((bet) => ({
|
||||||
|
userId: bet.userId,
|
||||||
|
payout: bet.amount,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getStandardFixedPayouts = (
|
||||||
|
outcome: string,
|
||||||
|
contract: FullContract<FixedPayouts, Binary>,
|
||||||
|
bets: Bet[]
|
||||||
|
) => {
|
||||||
|
const winningBets = bets.filter((bet) => bet.outcome === outcome)
|
||||||
|
|
||||||
|
const payouts = winningBets.map(({ userId, amount, shares }) => {
|
||||||
|
const winnings = shares
|
||||||
|
const profit = winnings - amount
|
||||||
|
const payout = deductFixedFees(amount, winnings)
|
||||||
|
return { userId, profit, payout }
|
||||||
|
})
|
||||||
|
|
||||||
|
const profits = _.sumBy(payouts, (po) => Math.max(0, po.profit))
|
||||||
|
const creatorPayout = CREATOR_FEE * profits
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
'resolved',
|
||||||
|
outcome,
|
||||||
|
'pool',
|
||||||
|
contract.pool,
|
||||||
|
'profits',
|
||||||
|
profits,
|
||||||
|
'creator fee',
|
||||||
|
creatorPayout
|
||||||
|
)
|
||||||
|
|
||||||
|
return payouts
|
||||||
|
.map(({ userId, payout }) => ({ userId, payout }))
|
||||||
|
.concat([{ userId: contract.creatorId, payout: creatorPayout }]) // add creator fee
|
||||||
|
.concat(getLiquidityPoolPayouts(contract, outcome))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getLiquidityPoolPayouts = (
|
||||||
|
contract: FullContract<CPMM, Binary>,
|
||||||
|
outcome: string
|
||||||
|
) => {
|
||||||
|
const { creatorId, pool } = contract
|
||||||
|
return [{ userId: creatorId, payout: pool[outcome] }]
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getMktFixedPayouts = (
|
||||||
|
contract: FullContract<FixedPayouts, Binary>,
|
||||||
|
bets: Bet[],
|
||||||
|
resolutionProbability?: number
|
||||||
|
) => {
|
||||||
|
const p =
|
||||||
|
resolutionProbability === undefined
|
||||||
|
? getProbability(contract)
|
||||||
|
: resolutionProbability
|
||||||
|
|
||||||
|
const payouts = bets.map(({ userId, outcome, amount, shares }) => {
|
||||||
|
const betP = outcome === 'YES' ? p : 1 - p
|
||||||
|
const winnings = betP * shares
|
||||||
|
const profit = winnings - amount
|
||||||
|
const payout = deductFixedFees(amount, winnings)
|
||||||
|
return { userId, profit, payout }
|
||||||
|
})
|
||||||
|
|
||||||
|
const profits = _.sumBy(payouts, (po) => Math.max(0, po.profit))
|
||||||
|
const creatorPayout = CREATOR_FEE * profits
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
'resolved MKT',
|
||||||
|
p,
|
||||||
|
'pool',
|
||||||
|
contract.pool,
|
||||||
|
'profits',
|
||||||
|
profits,
|
||||||
|
'creator fee',
|
||||||
|
creatorPayout
|
||||||
|
)
|
||||||
|
|
||||||
|
return payouts
|
||||||
|
.map(({ userId, payout }) => ({ userId, payout }))
|
||||||
|
.concat([{ userId: contract.creatorId, payout: creatorPayout }]) // add creator fee
|
||||||
|
.concat(getLiquidityPoolProbPayouts(contract, p))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getLiquidityPoolProbPayouts = (
|
||||||
|
contract: FullContract<CPMM, Binary>,
|
||||||
|
p: number
|
||||||
|
) => {
|
||||||
|
const { creatorId, pool } = contract
|
||||||
|
const payout = p * pool.YES + (1 - p) * pool.NO
|
||||||
|
return [{ userId: creatorId, payout }]
|
||||||
|
}
|
|
@ -1,225 +1,36 @@
|
||||||
import * as _ from 'lodash'
|
import * as _ from 'lodash'
|
||||||
|
|
||||||
import { Bet } from './bet'
|
import { Bet } from './bet'
|
||||||
import { deductDpmFees, getDpmProbability } from './calculate-dpm'
|
import { Contract, DPM, FreeResponse, FullContract, Multi } from './contract'
|
||||||
import {
|
import {
|
||||||
Binary,
|
getDpmCancelPayouts,
|
||||||
Contract,
|
getDpmMktPayouts,
|
||||||
CPMM,
|
getDpmStandardPayouts,
|
||||||
DPM,
|
getPayoutsMultiOutcome,
|
||||||
FreeResponse,
|
} from './payouts-dpm'
|
||||||
FullContract,
|
import {
|
||||||
Multi,
|
getFixedCancelPayouts,
|
||||||
} from './contract'
|
getMktFixedPayouts,
|
||||||
import { CREATOR_FEE, FEES } from './fees'
|
getStandardFixedPayouts,
|
||||||
|
} from './payouts-fixed'
|
||||||
export const getDpmCancelPayouts = (
|
|
||||||
contract: FullContract<DPM, any>,
|
|
||||||
bets: Bet[]
|
|
||||||
) => {
|
|
||||||
const { pool } = contract
|
|
||||||
const poolTotal = _.sum(Object.values(pool))
|
|
||||||
console.log('resolved N/A, pool M$', poolTotal)
|
|
||||||
|
|
||||||
const betSum = _.sumBy(bets, (b) => b.amount)
|
|
||||||
|
|
||||||
return bets.map((bet) => ({
|
|
||||||
userId: bet.userId,
|
|
||||||
payout: (bet.amount / betSum) * poolTotal,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getFixedCancelPayouts = (bets: Bet[]) => {
|
|
||||||
return bets.map((bet) => ({
|
|
||||||
userId: bet.userId,
|
|
||||||
payout: bet.amount,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getStandardFixedPayouts = (
|
|
||||||
outcome: string,
|
|
||||||
contract: FullContract<CPMM, Binary>,
|
|
||||||
bets: Bet[]
|
|
||||||
) => {
|
|
||||||
const winningBets = bets.filter((bet) => bet.outcome === outcome)
|
|
||||||
|
|
||||||
const payouts = winningBets.map(({ userId, amount, shares }) => {
|
|
||||||
const winnings = shares
|
|
||||||
const profit = winnings - amount
|
|
||||||
|
|
||||||
const payout = amount + (1 - FEES) * profit
|
|
||||||
return { userId, profit, payout }
|
|
||||||
})
|
|
||||||
|
|
||||||
const profits = _.sumBy(payouts, (po) => Math.max(0, po.profit))
|
|
||||||
const creatorPayout = CREATOR_FEE * profits
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
'resolved',
|
|
||||||
outcome,
|
|
||||||
'pool',
|
|
||||||
contract.pool,
|
|
||||||
'profits',
|
|
||||||
profits,
|
|
||||||
'creator fee',
|
|
||||||
creatorPayout
|
|
||||||
)
|
|
||||||
|
|
||||||
return payouts
|
|
||||||
.map(({ userId, payout }) => ({ userId, payout }))
|
|
||||||
.concat([{ userId: contract.creatorId, payout: creatorPayout }]) // add creator fee
|
|
||||||
.concat(getLiquidityPoolPayouts(contract, outcome))
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getLiquidityPoolPayouts = (
|
|
||||||
contract: FullContract<CPMM, Binary>,
|
|
||||||
outcome: string
|
|
||||||
) => {
|
|
||||||
const { creatorId, pool } = contract
|
|
||||||
return [{ userId: creatorId, payout: pool[outcome] }]
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getStandardPayouts = (
|
|
||||||
outcome: string,
|
|
||||||
contract: FullContract<DPM, any>,
|
|
||||||
bets: Bet[]
|
|
||||||
) => {
|
|
||||||
const winningBets = bets.filter((bet) => bet.outcome === outcome)
|
|
||||||
|
|
||||||
const poolTotal = _.sum(Object.values(contract.pool))
|
|
||||||
const totalShares = _.sumBy(winningBets, (b) => b.shares)
|
|
||||||
|
|
||||||
const payouts = winningBets.map(({ userId, amount, shares }) => {
|
|
||||||
const winnings = (shares / totalShares) * poolTotal
|
|
||||||
const profit = winnings - amount
|
|
||||||
|
|
||||||
// profit can be negative if using phantom shares
|
|
||||||
const payout = amount + (1 - FEES) * Math.max(0, profit)
|
|
||||||
return { userId, profit, payout }
|
|
||||||
})
|
|
||||||
|
|
||||||
const profits = _.sumBy(payouts, (po) => Math.max(0, po.profit))
|
|
||||||
const creatorPayout = CREATOR_FEE * profits
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
'resolved',
|
|
||||||
outcome,
|
|
||||||
'pool',
|
|
||||||
poolTotal,
|
|
||||||
'profits',
|
|
||||||
profits,
|
|
||||||
'creator fee',
|
|
||||||
creatorPayout
|
|
||||||
)
|
|
||||||
|
|
||||||
return payouts
|
|
||||||
.map(({ userId, payout }) => ({ userId, payout }))
|
|
||||||
.concat([{ userId: contract.creatorId, payout: creatorPayout }]) // add creator fee
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getMktPayouts = (
|
|
||||||
contract: FullContract<DPM, any>,
|
|
||||||
bets: Bet[],
|
|
||||||
resolutionProbability?: number
|
|
||||||
) => {
|
|
||||||
const p =
|
|
||||||
resolutionProbability === undefined
|
|
||||||
? getDpmProbability(contract.totalShares)
|
|
||||||
: resolutionProbability
|
|
||||||
|
|
||||||
const weightedShareTotal = _.sumBy(bets, (b) =>
|
|
||||||
b.outcome === 'YES' ? p * b.shares : (1 - p) * b.shares
|
|
||||||
)
|
|
||||||
|
|
||||||
const pool = contract.pool.YES + contract.pool.NO
|
|
||||||
|
|
||||||
const payouts = bets.map(({ userId, outcome, amount, shares }) => {
|
|
||||||
const betP = outcome === 'YES' ? p : 1 - p
|
|
||||||
const winnings = ((betP * shares) / weightedShareTotal) * pool
|
|
||||||
const profit = winnings - amount
|
|
||||||
const payout = deductDpmFees(amount, winnings)
|
|
||||||
return { userId, profit, payout }
|
|
||||||
})
|
|
||||||
|
|
||||||
const profits = _.sumBy(payouts, (po) => Math.max(0, po.profit))
|
|
||||||
const creatorPayout = CREATOR_FEE * profits
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
'resolved MKT',
|
|
||||||
p,
|
|
||||||
'pool',
|
|
||||||
pool,
|
|
||||||
'profits',
|
|
||||||
profits,
|
|
||||||
'creator fee',
|
|
||||||
creatorPayout
|
|
||||||
)
|
|
||||||
|
|
||||||
return payouts
|
|
||||||
.map(({ userId, payout }) => ({ userId, payout }))
|
|
||||||
.concat([{ userId: contract.creatorId, payout: creatorPayout }]) // add creator fee
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getMktFixedPayouts = (
|
|
||||||
contract: FullContract<CPMM, Binary>,
|
|
||||||
bets: Bet[],
|
|
||||||
resolutionProbability?: number
|
|
||||||
) => {
|
|
||||||
const p =
|
|
||||||
resolutionProbability === undefined
|
|
||||||
? getDpmProbability(contract.pool)
|
|
||||||
: resolutionProbability
|
|
||||||
|
|
||||||
const payouts = bets.map(({ userId, outcome, amount, shares }) => {
|
|
||||||
const betP = outcome === 'YES' ? p : 1 - p
|
|
||||||
const winnings = betP * shares
|
|
||||||
const profit = winnings - amount
|
|
||||||
const payout = deductDpmFees(amount, winnings)
|
|
||||||
return { userId, profit, payout }
|
|
||||||
})
|
|
||||||
|
|
||||||
const profits = _.sumBy(payouts, (po) => Math.max(0, po.profit))
|
|
||||||
const creatorPayout = CREATOR_FEE * profits
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
'resolved MKT',
|
|
||||||
p,
|
|
||||||
'pool',
|
|
||||||
contract.pool,
|
|
||||||
'profits',
|
|
||||||
profits,
|
|
||||||
'creator fee',
|
|
||||||
creatorPayout
|
|
||||||
)
|
|
||||||
|
|
||||||
return payouts
|
|
||||||
.map(({ userId, payout }) => ({ userId, payout }))
|
|
||||||
.concat([{ userId: contract.creatorId, payout: creatorPayout }]) // add creator fee
|
|
||||||
.concat(getLiquidityPoolProbPayouts(contract, p))
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getLiquidityPoolProbPayouts = (
|
|
||||||
contract: FullContract<CPMM, Binary>,
|
|
||||||
p: number
|
|
||||||
) => {
|
|
||||||
const { creatorId, pool } = contract
|
|
||||||
const payout = p * pool.YES + (1 - p) * pool.NO
|
|
||||||
return [{ userId: creatorId, payout }]
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getPayouts = (
|
export const getPayouts = (
|
||||||
outcome: string,
|
outcome:
|
||||||
|
| string
|
||||||
|
| {
|
||||||
|
[outcome: string]: number
|
||||||
|
},
|
||||||
contract: Contract,
|
contract: Contract,
|
||||||
bets: Bet[],
|
bets: Bet[],
|
||||||
resolutionProbability?: number
|
resolutionProbability?: number
|
||||||
) => {
|
) => {
|
||||||
if (contract.mechanism === 'cpmm-1') {
|
if (contract.mechanism === 'cpmm-1' && contract.outcomeType === 'BINARY') {
|
||||||
switch (outcome) {
|
switch (outcome) {
|
||||||
case 'YES':
|
case 'YES':
|
||||||
case 'NO':
|
case 'NO':
|
||||||
return getStandardFixedPayouts(outcome, contract as any, bets)
|
return getStandardFixedPayouts(outcome, contract, bets)
|
||||||
case 'MKT':
|
case 'MKT':
|
||||||
return getMktFixedPayouts(contract as any, bets, resolutionProbability)
|
return getMktFixedPayouts(contract, bets, resolutionProbability)
|
||||||
case 'CANCEL':
|
case 'CANCEL':
|
||||||
return getFixedCancelPayouts(bets)
|
return getFixedCancelPayouts(bets)
|
||||||
}
|
}
|
||||||
|
@ -228,58 +39,21 @@ export const getPayouts = (
|
||||||
switch (outcome) {
|
switch (outcome) {
|
||||||
case 'YES':
|
case 'YES':
|
||||||
case 'NO':
|
case 'NO':
|
||||||
return getStandardPayouts(outcome, contract, bets)
|
return getDpmStandardPayouts(outcome, contract, bets)
|
||||||
case 'MKT':
|
case 'MKT':
|
||||||
return getMktPayouts(contract, bets, resolutionProbability)
|
return getDpmMktPayouts(contract, bets, resolutionProbability)
|
||||||
case 'CANCEL':
|
case 'CANCEL':
|
||||||
return getDpmCancelPayouts(contract, bets)
|
return getDpmCancelPayouts(contract, bets)
|
||||||
default:
|
default:
|
||||||
// Multi outcome.
|
// Multi outcome.
|
||||||
return getStandardPayouts(outcome, contract, bets)
|
return getPayoutsMultiOutcome(
|
||||||
}
|
outcome as {
|
||||||
}
|
[outcome: string]: number
|
||||||
|
},
|
||||||
export const getPayoutsMultiOutcome = (
|
contract as FullContract<DPM, Multi | FreeResponse>,
|
||||||
resolutions: { [outcome: string]: number },
|
bets
|
||||||
contract: FullContract<DPM, Multi | FreeResponse>,
|
|
||||||
bets: Bet[]
|
|
||||||
) => {
|
|
||||||
const poolTotal = _.sum(Object.values(contract.pool))
|
|
||||||
const winningBets = bets.filter((bet) => resolutions[bet.outcome])
|
|
||||||
|
|
||||||
const betsByOutcome = _.groupBy(winningBets, (bet) => bet.outcome)
|
|
||||||
const sharesByOutcome = _.mapValues(betsByOutcome, (bets) =>
|
|
||||||
_.sumBy(bets, (bet) => bet.shares)
|
|
||||||
)
|
)
|
||||||
|
}
|
||||||
const probTotal = _.sum(Object.values(resolutions))
|
|
||||||
|
|
||||||
const payouts = winningBets.map(({ userId, outcome, amount, shares }) => {
|
|
||||||
const prob = resolutions[outcome] / probTotal
|
|
||||||
const winnings = (shares / sharesByOutcome[outcome]) * prob * poolTotal
|
|
||||||
const profit = winnings - amount
|
|
||||||
|
|
||||||
const payout = amount + (1 - FEES) * Math.max(0, profit)
|
|
||||||
return { userId, profit, payout }
|
|
||||||
})
|
|
||||||
|
|
||||||
const profits = _.sumBy(payouts, (po) => po.profit)
|
|
||||||
const creatorPayout = CREATOR_FEE * profits
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
'resolved',
|
|
||||||
resolutions,
|
|
||||||
'pool',
|
|
||||||
poolTotal,
|
|
||||||
'profits',
|
|
||||||
profits,
|
|
||||||
'creator fee',
|
|
||||||
creatorPayout
|
|
||||||
)
|
|
||||||
|
|
||||||
return payouts
|
|
||||||
.map(({ userId, payout }) => ({ userId, payout }))
|
|
||||||
.concat([{ userId: contract.creatorId, payout: creatorPayout }]) // add creator fee
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getLoanPayouts = (bets: Bet[]) => {
|
export const getLoanPayouts = (bets: Bet[]) => {
|
||||||
|
|
|
@ -7,11 +7,7 @@ import { User } from '../../common/user'
|
||||||
import { Bet } from '../../common/bet'
|
import { Bet } from '../../common/bet'
|
||||||
import { getUser, payUser } from './utils'
|
import { getUser, payUser } from './utils'
|
||||||
import { sendMarketResolutionEmail } from './emails'
|
import { sendMarketResolutionEmail } from './emails'
|
||||||
import {
|
import { getLoanPayouts, getPayouts } from '../../common/payouts'
|
||||||
getLoanPayouts,
|
|
||||||
getPayouts,
|
|
||||||
getPayoutsMultiOutcome,
|
|
||||||
} from '../../common/payouts'
|
|
||||||
import { removeUndefinedProps } from '../../common/util/object'
|
import { removeUndefinedProps } from '../../common/util/object'
|
||||||
|
|
||||||
export const resolveMarket = functions
|
export const resolveMarket = functions
|
||||||
|
@ -98,10 +94,12 @@ export const resolveMarket = functions
|
||||||
const bets = betsSnap.docs.map((doc) => doc.data() as Bet)
|
const bets = betsSnap.docs.map((doc) => doc.data() as Bet)
|
||||||
const openBets = bets.filter((b) => !b.isSold && !b.sale)
|
const openBets = bets.filter((b) => !b.isSold && !b.sale)
|
||||||
|
|
||||||
const payouts =
|
const payouts = getPayouts(
|
||||||
outcomeType === 'FREE_RESPONSE' && resolutions
|
resolutions ?? outcome,
|
||||||
? getPayoutsMultiOutcome(resolutions, contract as any, openBets)
|
contract,
|
||||||
: getPayouts(outcome, contract, openBets, resolutionProbability)
|
openBets,
|
||||||
|
resolutionProbability
|
||||||
|
)
|
||||||
|
|
||||||
const loanPayouts = getLoanPayouts(openBets)
|
const loanPayouts = getLoanPayouts(openBets)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user