Set shares to equal each other
This commit is contained in:
parent
c8586e7703
commit
13aa1f9540
|
@ -11,7 +11,7 @@ export type Challenge = {
|
||||||
message: string
|
message: string
|
||||||
|
|
||||||
// How much to put up
|
// How much to put up
|
||||||
amount: number
|
creatorAmount: number
|
||||||
|
|
||||||
// YES or NO for now
|
// YES or NO for now
|
||||||
creatorsOutcome: string
|
creatorsOutcome: string
|
||||||
|
@ -49,6 +49,9 @@ export type Acceptance = {
|
||||||
userName: string
|
userName: string
|
||||||
userAvatarUrl: string
|
userAvatarUrl: string
|
||||||
|
|
||||||
|
// The amount acceptor put up
|
||||||
|
amount: number
|
||||||
|
|
||||||
// The ID of the successful bet that tracks the money moved
|
// The ID of the successful bet that tracks the money moved
|
||||||
betId: string
|
betId: string
|
||||||
|
|
||||||
|
|
|
@ -49,9 +49,13 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
||||||
if (!creatorSnap.exists) throw new APIError(400, 'User not found.')
|
if (!creatorSnap.exists) throw new APIError(400, 'User not found.')
|
||||||
const creator = creatorSnap.data() as User
|
const creator = creatorSnap.data() as User
|
||||||
|
|
||||||
const { amount, yourOutcome, creatorsOutcome, creatorsOutcomeProb } =
|
const { creatorAmount, yourOutcome, creatorsOutcome, creatorsOutcomeProb } =
|
||||||
challenge
|
challenge
|
||||||
if (user.balance < amount) throw new APIError(400, 'Insufficient balance.')
|
const yourCost =
|
||||||
|
((1 - creatorsOutcomeProb) / creatorsOutcomeProb) * creatorAmount
|
||||||
|
|
||||||
|
if (user.balance < yourCost)
|
||||||
|
throw new APIError(400, 'Insufficient balance.')
|
||||||
|
|
||||||
const { closeTime, outcomeType } = anyContract
|
const { closeTime, outcomeType } = anyContract
|
||||||
if (closeTime && Date.now() > closeTime)
|
if (closeTime && Date.now() > closeTime)
|
||||||
|
@ -61,22 +65,19 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
||||||
|
|
||||||
const contract = anyContract as CPMMBinaryContract
|
const contract = anyContract as CPMMBinaryContract
|
||||||
const { YES: y, NO: n } = contract.pool
|
const { YES: y, NO: n } = contract.pool
|
||||||
const yourShares = (1 / (1 - creatorsOutcomeProb)) * amount
|
const shares = (1 / creatorsOutcomeProb) * creatorAmount
|
||||||
const creatorShares = (1 / creatorsOutcomeProb) * amount
|
|
||||||
|
|
||||||
const newYesShares = creatorsOutcome === 'YES' ? creatorShares : yourShares
|
|
||||||
const newNoShares = creatorsOutcome === 'NO' ? creatorShares : yourShares
|
|
||||||
const newPool = {
|
const newPool = {
|
||||||
YES: y + newYesShares,
|
YES: y + shares,
|
||||||
NO: n + newNoShares,
|
NO: n + shares,
|
||||||
}
|
}
|
||||||
const probBefore = getCpmmProbability(contract.pool, contract.p)
|
const probBefore = getCpmmProbability(contract.pool, contract.p)
|
||||||
const probAfter = getCpmmProbability(newPool, contract.p)
|
const probAfter = getCpmmProbability(newPool, contract.p)
|
||||||
|
|
||||||
const yourNewBet: CandidateBet = removeUndefinedProps({
|
const yourNewBet: CandidateBet = removeUndefinedProps({
|
||||||
orderAmount: amount,
|
orderAmount: yourCost,
|
||||||
amount: amount,
|
amount: yourCost,
|
||||||
shares: yourShares,
|
shares: shares,
|
||||||
isCancelled: false,
|
isCancelled: false,
|
||||||
contractId: contract.id,
|
contractId: contract.id,
|
||||||
outcome: yourOutcome,
|
outcome: yourOutcome,
|
||||||
|
@ -98,9 +99,9 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
||||||
log('Updated user balance.')
|
log('Updated user balance.')
|
||||||
|
|
||||||
const creatorNewBet: CandidateBet = removeUndefinedProps({
|
const creatorNewBet: CandidateBet = removeUndefinedProps({
|
||||||
orderAmount: amount,
|
orderAmount: creatorAmount,
|
||||||
amount: amount,
|
amount: creatorAmount,
|
||||||
shares: creatorShares,
|
shares: shares,
|
||||||
isCancelled: false,
|
isCancelled: false,
|
||||||
contractId: contract.id,
|
contractId: contract.id,
|
||||||
outcome: creatorsOutcome,
|
outcome: creatorsOutcome,
|
||||||
|
@ -141,6 +142,7 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
betId: yourNewBetDoc.id,
|
betId: yourNewBetDoc.id,
|
||||||
createdTime: Date.now(),
|
createdTime: Date.now(),
|
||||||
|
amount: yourCost,
|
||||||
userUsername: user.username,
|
userUsername: user.username,
|
||||||
userName: user.name,
|
userName: user.name,
|
||||||
userAvatarUrl: user.avatarUrl,
|
userAvatarUrl: user.avatarUrl,
|
||||||
|
@ -154,6 +156,7 @@ export const acceptchallenge = newEndpoint({}, async (req, auth) => {
|
||||||
user,
|
user,
|
||||||
creator,
|
creator,
|
||||||
challenge,
|
challenge,
|
||||||
|
yourCost,
|
||||||
contract
|
contract
|
||||||
)
|
)
|
||||||
log('Created notification.')
|
log('Created notification.')
|
||||||
|
|
|
@ -474,6 +474,7 @@ export const createChallengeAcceptedNotification = async (
|
||||||
challenger: User,
|
challenger: User,
|
||||||
challengeCreator: User,
|
challengeCreator: User,
|
||||||
challenge: Challenge,
|
challenge: Challenge,
|
||||||
|
acceptedAmount: number,
|
||||||
contract: Contract
|
contract: Contract
|
||||||
) => {
|
) => {
|
||||||
const notificationRef = firestore
|
const notificationRef = firestore
|
||||||
|
@ -491,7 +492,7 @@ export const createChallengeAcceptedNotification = async (
|
||||||
sourceUserName: challenger.name,
|
sourceUserName: challenger.name,
|
||||||
sourceUserUsername: challenger.username,
|
sourceUserUsername: challenger.username,
|
||||||
sourceUserAvatarUrl: challenger.avatarUrl,
|
sourceUserAvatarUrl: challenger.avatarUrl,
|
||||||
sourceText: challenge.amount.toString(),
|
sourceText: acceptedAmount.toString(),
|
||||||
sourceContractCreatorUsername: contract.creatorUsername,
|
sourceContractCreatorUsername: contract.creatorUsername,
|
||||||
sourceContractTitle: contract.question,
|
sourceContractTitle: contract.question,
|
||||||
sourceContractSlug: contract.slug,
|
sourceContractSlug: contract.slug,
|
||||||
|
|
|
@ -21,8 +21,9 @@ export function AcceptChallengeButton(props: {
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
const [errorText, setErrorText] = useState('')
|
const [errorText, setErrorText] = useState('')
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const yourProb = 1 - challenge.creatorsOutcomeProb
|
const { creatorsOutcomeProb, creatorAmount } = challenge
|
||||||
|
const yourCost =
|
||||||
|
((1 - creatorsOutcomeProb) / creatorsOutcomeProb) * creatorAmount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setErrorText('')
|
setErrorText('')
|
||||||
}, [open])
|
}, [open])
|
||||||
|
@ -66,9 +67,7 @@ export function AcceptChallengeButton(props: {
|
||||||
<Col className="w-full items-center justify-start gap-2">
|
<Col className="w-full items-center justify-start gap-2">
|
||||||
<Row className={'w-full justify-start gap-20'}>
|
<Row className={'w-full justify-start gap-20'}>
|
||||||
<span className={'min-w-[4rem] font-bold'}>Cost to you:</span>{' '}
|
<span className={'min-w-[4rem] font-bold'}>Cost to you:</span>{' '}
|
||||||
<span className={'text-red-500'}>
|
<span className={'text-red-500'}>{formatMoney(yourCost)}</span>
|
||||||
{formatMoney(challenge.amount)}
|
|
||||||
</span>
|
|
||||||
</Row>
|
</Row>
|
||||||
{/*<Row className={'w-full justify-start gap-8'}>*/}
|
{/*<Row className={'w-full justify-start gap-8'}>*/}
|
||||||
{/* <span className={'min-w-[4rem] font-bold'}>Probability:</span>{' '}*/}
|
{/* <span className={'min-w-[4rem] font-bold'}>Probability:</span>{' '}*/}
|
||||||
|
@ -84,7 +83,7 @@ export function AcceptChallengeButton(props: {
|
||||||
</span>{' '}
|
</span>{' '}
|
||||||
<Row className={'items-center justify-center'}>
|
<Row className={'items-center justify-center'}>
|
||||||
<span className={'text-primary'}>
|
<span className={'text-primary'}>
|
||||||
{formatMoney(challenge.amount / yourProb)}
|
{formatMoney(challenge.creatorAmount)}
|
||||||
</span>
|
</span>
|
||||||
{/*<InfoTooltip text={"If you're right"} />*/}
|
{/*<InfoTooltip text={"If you're right"} />*/}
|
||||||
</Row>
|
</Row>
|
||||||
|
|
|
@ -46,7 +46,7 @@ export async function createChallenge(data: {
|
||||||
slug,
|
slug,
|
||||||
creatorId: creator.id,
|
creatorId: creator.id,
|
||||||
creatorUsername: creator.username,
|
creatorUsername: creator.username,
|
||||||
amount,
|
creatorAmount: amount,
|
||||||
contractSlug: contract.slug,
|
contractSlug: contract.slug,
|
||||||
contractId: contract.id,
|
contractId: contract.id,
|
||||||
creatorsOutcome: outcome.toString(),
|
creatorsOutcome: outcome.toString(),
|
||||||
|
|
|
@ -133,7 +133,7 @@ function ClosedChallengeContent(props: {
|
||||||
const { resolution } = contract
|
const { resolution } = contract
|
||||||
const {
|
const {
|
||||||
acceptances,
|
acceptances,
|
||||||
amount,
|
creatorAmount,
|
||||||
creatorsOutcome,
|
creatorsOutcome,
|
||||||
creatorsOutcomeProb,
|
creatorsOutcomeProb,
|
||||||
yourOutcome,
|
yourOutcome,
|
||||||
|
@ -148,10 +148,13 @@ function ClosedChallengeContent(props: {
|
||||||
setShowConfetti(true)
|
setShowConfetti(true)
|
||||||
}, [acceptances])
|
}, [acceptances])
|
||||||
const creatorWon = resolution === creatorsOutcome
|
const creatorWon = resolution === creatorsOutcome
|
||||||
|
const amountWon = creatorWon ? acceptances[0].amount : creatorAmount
|
||||||
|
const yourCost =
|
||||||
|
((1 - creatorsOutcomeProb) / creatorsOutcomeProb) * creatorAmount
|
||||||
|
|
||||||
if (!user) return <LoadingIndicator />
|
if (!user) return <LoadingIndicator />
|
||||||
|
|
||||||
const userWonCol = (user: User) => (
|
const userWonCol = (user: User, amount: number) => (
|
||||||
<Col className="w-full items-start justify-center gap-1 p-4">
|
<Col className="w-full items-start justify-center gap-1 p-4">
|
||||||
<Row className={'mb-2 w-full items-center justify-center gap-2'}>
|
<Row className={'mb-2 w-full items-center justify-center gap-2'}>
|
||||||
<span className={'mx-2 text-3xl'}>🥇</span>
|
<span className={'mx-2 text-3xl'}>🥇</span>
|
||||||
|
@ -171,7 +174,7 @@ function ClosedChallengeContent(props: {
|
||||||
</Col>
|
</Col>
|
||||||
)
|
)
|
||||||
|
|
||||||
const userLostCol = (challenger: User) => (
|
const userLostCol = (challenger: User, amount: number) => (
|
||||||
<Col className="w-full items-start justify-center gap-1">
|
<Col className="w-full items-start justify-center gap-1">
|
||||||
{userRow(challenger)}
|
{userRow(challenger)}
|
||||||
<Row className={'w-full items-center justify-center'}>
|
<Row className={'w-full items-center justify-center'}>
|
||||||
|
@ -186,23 +189,17 @@ function ClosedChallengeContent(props: {
|
||||||
challenger: User,
|
challenger: User,
|
||||||
outcome: string,
|
outcome: string,
|
||||||
prob: number,
|
prob: number,
|
||||||
lost?: boolean
|
amount: number
|
||||||
) => (
|
) => (
|
||||||
<Col className="w-full items-start justify-center gap-1">
|
<Col className="w-full items-start justify-center gap-1">
|
||||||
{userRow(challenger)}
|
{userRow(challenger)}
|
||||||
<Row className={'w-full items-center justify-center'}>
|
<Row className={'w-full items-center justify-center'}>
|
||||||
{!lost ? (
|
<span className={'text-lg'}>
|
||||||
<span className={'text-lg'}>
|
is betting {formatMoney(amount)}
|
||||||
is betting {formatMoney(amount)}
|
{' on '}
|
||||||
{' on '}
|
<BinaryOutcomeLabel outcome={outcome as any} /> at{' '}
|
||||||
<BinaryOutcomeLabel outcome={outcome as any} /> at{' '}
|
{Math.round(prob * 100)}%
|
||||||
{Math.round(prob * 100)}%
|
</span>
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
<span className={'text-lg'}>
|
|
||||||
LOST <span className={'text-red-500'}>{formatMoney(amount)}</span>
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</Row>
|
</Row>
|
||||||
</Col>
|
</Col>
|
||||||
)
|
)
|
||||||
|
@ -242,10 +239,10 @@ function ClosedChallengeContent(props: {
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Row className={'mt-4 w-full'}>
|
<Row className={'mt-4 w-full'}>
|
||||||
{userWonCol(creatorWon ? creator : user)}
|
{userWonCol(creatorWon ? creator : user, amountWon)}
|
||||||
</Row>
|
</Row>
|
||||||
<Row className={'mt-4'}>
|
<Row className={'mt-4'}>
|
||||||
{userLostCol(creatorWon ? user : creator)}
|
{userLostCol(creatorWon ? user : creator, amountWon)}
|
||||||
</Row>
|
</Row>
|
||||||
</Col>
|
</Col>
|
||||||
) : (
|
) : (
|
||||||
|
@ -254,9 +251,14 @@ function ClosedChallengeContent(props: {
|
||||||
'h-full w-full content-between justify-between gap-1 py-10 sm:flex-row'
|
'h-full w-full content-between justify-between gap-1 py-10 sm:flex-row'
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{userCol(creator, creatorsOutcome, creatorsOutcomeProb)}
|
{userCol(
|
||||||
|
creator,
|
||||||
|
creatorsOutcome,
|
||||||
|
creatorsOutcomeProb,
|
||||||
|
creatorAmount
|
||||||
|
)}
|
||||||
<Col className="items-center justify-center py-4 text-xl">VS</Col>
|
<Col className="items-center justify-center py-4 text-xl">VS</Col>
|
||||||
{userCol(user, yourOutcome, 1 - creatorsOutcomeProb)}
|
{userCol(user, yourOutcome, 1 - creatorsOutcomeProb, yourCost)}
|
||||||
</Col>
|
</Col>
|
||||||
)}
|
)}
|
||||||
<Spacer h={3} />
|
<Spacer h={3} />
|
||||||
|
@ -302,7 +304,7 @@ function OpenChallengeContent(props: {
|
||||||
const { contract, challenge, creator, user, bets } = props
|
const { contract, challenge, creator, user, bets } = props
|
||||||
const { question } = contract
|
const { question } = contract
|
||||||
const {
|
const {
|
||||||
amount,
|
creatorAmount,
|
||||||
creatorId,
|
creatorId,
|
||||||
creatorsOutcome,
|
creatorsOutcome,
|
||||||
creatorsOutcomeProb,
|
creatorsOutcomeProb,
|
||||||
|
@ -331,11 +333,14 @@ function OpenChallengeContent(props: {
|
||||||
|
|
||||||
const isBinary = contract.outcomeType === 'BINARY'
|
const isBinary = contract.outcomeType === 'BINARY'
|
||||||
const isPseudoNumeric = contract.outcomeType === 'PSEUDO_NUMERIC'
|
const isPseudoNumeric = contract.outcomeType === 'PSEUDO_NUMERIC'
|
||||||
|
const yourCost =
|
||||||
|
((1 - creatorsOutcomeProb) / creatorsOutcomeProb) * creatorAmount
|
||||||
|
|
||||||
const userColumn = (
|
const userColumn = (
|
||||||
challenger: User | null | undefined,
|
challenger: User | null | undefined,
|
||||||
portfolioHistory: PortfolioMetrics[],
|
portfolioHistory: PortfolioMetrics[],
|
||||||
outcome: string
|
outcome: string,
|
||||||
|
amount: number
|
||||||
) => {
|
) => {
|
||||||
const lastPortfolioMetrics = last(portfolioHistory)
|
const lastPortfolioMetrics = last(portfolioHistory)
|
||||||
const prob =
|
const prob =
|
||||||
|
@ -408,12 +413,18 @@ function OpenChallengeContent(props: {
|
||||||
'h-full max-h-[50vh] w-full content-between justify-between gap-1 py-10 sm:flex-row'
|
'h-full max-h-[50vh] w-full content-between justify-between gap-1 py-10 sm:flex-row'
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{userColumn(creator, creatorPortfolioHistory, creatorsOutcome)}
|
{userColumn(
|
||||||
|
creator,
|
||||||
|
creatorPortfolioHistory,
|
||||||
|
creatorsOutcome,
|
||||||
|
creatorAmount
|
||||||
|
)}
|
||||||
<Col className="items-center justify-center py-4 text-4xl">VS</Col>
|
<Col className="items-center justify-center py-4 text-4xl">VS</Col>
|
||||||
{userColumn(
|
{userColumn(
|
||||||
user?.id === creatorId ? undefined : user,
|
user?.id === creatorId ? undefined : user,
|
||||||
portfolioHistory,
|
portfolioHistory,
|
||||||
yourOutcome
|
yourOutcome,
|
||||||
|
yourCost
|
||||||
)}
|
)}
|
||||||
</Col>
|
</Col>
|
||||||
<Spacer h={3} />
|
<Spacer h={3} />
|
||||||
|
|
|
@ -205,7 +205,7 @@ function LinkSummaryRow(props: {
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td className="px-5 py-4 font-medium text-gray-900">
|
<td className="px-5 py-4 font-medium text-gray-900">
|
||||||
{formatMoney(link.amount)}
|
{formatMoney(link.creatorAmount)}
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
className="relative px-5 py-4"
|
className="relative px-5 py-4"
|
||||||
|
@ -304,7 +304,7 @@ function PublicLinkSummaryRow(props: { link: Challenge; highlight: boolean }) {
|
||||||
return (
|
return (
|
||||||
<tr id={link.slug} key={link.slug} className={className}>
|
<tr id={link.slug} key={link.slug} className={className}>
|
||||||
<td className="px-5 py-4 font-medium text-gray-900">
|
<td className="px-5 py-4 font-medium text-gray-900">
|
||||||
{formatMoney(link.amount)}
|
{formatMoney(link.creatorAmount)}
|
||||||
</td>
|
</td>
|
||||||
<td className="relative px-2 py-4">
|
<td className="relative px-2 py-4">
|
||||||
<SiteLink href={getChallengeUrl(link)}>
|
<SiteLink href={getChallengeUrl(link)}>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user