import _ from 'lodash' import { Col } from '../components/layout/col' import { Leaderboard } from '../components/leaderboard' import { Page } from '../components/page' import { getTopCreators, getTopTraders, User } from '../lib/firebase/users' import { formatMoney } from '../../common/util/format' import { fromPropz, usePropz } from '../hooks/use-propz' import { Manaboard } from '../components/manaboard' import { Title } from '../components/title' import { useTransactions } from '../hooks/use-transactions' import { Transaction } from '../lib/firebase/transactions' export const getStaticProps = fromPropz(getStaticPropz) export async function getStaticPropz() { const [topTraders, topCreators] = await Promise.all([ getTopTraders().catch((_) => {}), getTopCreators().catch((_) => {}), ]) return { props: { topTraders, topCreators, }, revalidate: 60, // regenerate after a minute } } function Leaderboards(props: { topTraders: User[]; topCreators: User[] }) { props = usePropz(props, getStaticPropz) ?? { topTraders: [], topCreators: [], } const { topTraders, topCreators } = props return ( formatMoney(user.totalPnLCached), }, ]} /> formatMoney(user.creatorVolumeCached), }, ]} /> ) } function Explanation() { return (

How this works

  1. Every slot has an "assessed value": what the current holder thinks their slot is worth.
  2. Slot holders pay a continuous fee of 10% per hour to Manafold.
  3. At any time, you can pay the assessed value of a slot to buy it from the current holder.
  4. The slot is now yours! You can customize the message, or reassess it to a new value.

Note: this mechanism is known as a{' '} Harberger Tax !

) } // TODOs // [ ] Correctly calculate tax // [ ] List history of purchases at the bottom // [ ] Restrict to at most buying one slot per user? // [ ] Set to 50 top traders // [ ] Deduct amount from user's balance, either in UX or for real export default function Manaboards(props: { topTraders: User[] topCreators: User[] }) { props = usePropz(props, getStaticPropz) ?? { topTraders: [], topCreators: [], } const { topTraders, topCreators } = props // Find the most recent purchases of each slot, and replace the entries in topTraders const transactions = useTransactions() ?? [] // Iterate from oldest to newest transactions, so recent purchases overwrite older ones const sortedTxns = _.sortBy(transactions, 'createdTime') for (const txn of sortedTxns) { if (txn.category === 'BUY_LEADERBOARD_SLOT') { const buyer = userFromBuy(txn) const slot = txn.data?.slot ?? 0 topTraders[slot - 1] = buyer } } console.log('sorted txn', sortedTxns) function userFromBuy(txn: Transaction): User { return { id: txn.fromId, // @ts-ignore name: txn.data?.message ?? txn.fromName, username: txn.fromUsername, avatarUrl: txn.fromAvatarUrl, // Dummy data which shouldn't be relied on createdTime: 0, creatorVolumeCached: 0, totalPnLCached: 0, balance: 0, totalDeposits: 0, } } return ( }> {/* <div className="absolute right-[700px] top-8"> <img className="h-18 mx-auto w-24 object-cover transition hover:rotate-12" src="https://i.etsystatic.com/8800089/r/il/b79fe6/1591362635/il_fullxfull.1591362635_4523.jpg" /> </div> */} <div className="prose mb-8 text-gray-600"> <p> Manafold Markets is running low on mana, so we're selling our leaderboard slots to make up the deficit. Buy one now for ephemeral glory, and help keep Manafold afloat! </p> </div> <Col className="mt-6 items-center gap-10"> <Manaboard title="" users={topTraders} /> {/* <Manaboard title="🏅 Top creators" users={topCreators} /> */} </Col> </Page> ) }