Scoop n Score Overview
Scoop n Score is a sports betting protocol that allows users to bet on a market that contains a ranked order of results. A market is comprised of multiple tokens that each resolve to a predefined fixed price. The resolved price of each token sums to $1.
For example, a market could be created for a Formula 1 race. This market resolves to 30c for the winner, 20c for 2nd place, 10c for 3rd, etc. The sum of all places is $1. Each racer is represented as a token that can be freely traded on the market until resolution occurs. When a market is resolved, shareholders receive $x per share, as determined by the relative ranking of the racer.
Resolution occurs through an oracle. It will probably be built with an UMA oracle. https://docs.polymarket.com/developers/resolution/UMA#overview
Design
- Token minting contract - Allows users to mint new tokens by depositing USDC. USDC stored in this contract is paid out upon market resolution.
- Token pools - Each token is traded on a Uniswap v3 concentrated liquidity pool. Users provide liquidity to each pool individually after minting tokens with the minting contract.
- Oracle - An oracle. To start will just be an EOA controlled by the deployer.
-
Token minting contract
- CreateMarket: creates ERC20 tokens; one for each entrant. Stores the payout weights.
- Mint: mints 1/(tokens.count) of each token for each 1 USDC deposited into the contract. Transfers all minted tokens to the msg sender.
- Resolve: The user passes in an array of tokens that represents the final rankings. The function locks the order of the tokens according to the rankings, closes minting, and allows redemption to occur.
- Redeem: Only active after resolution occurs. Allows user to redeem their tokens for a certain price determined by the payout values array and token ranking.
-
Token curves/market
- Each token curve is a Uniswap v3 curve that can be traded on the open market.
- Upon resolution it is expected that LPs redeem their liquidity and cash it out in the minting contract.
Deployment Script Pseudocode
const payoutValues = [...] // array of payout values
const tokenMetadata = [...] // array of token metadata
const mintingContract = new MintingContract(payoutValues)
const tokens = mintingContract.getTokens() // returns an array of token ids
const balances = mintingContract.mint({ usdc: 1e18 })
const expectedValues = [...] // array of expected payout values based on prior research
// create a new pool and seed some liquidity at a predetermined price
tokens.forEach(token =>{
const pool = new UniswapV3Pool(token, USDC)
const balance = getTokenBalance(token.id)
const position = UniswapV3Position (pool, tickLower, tickUpper, amount0, amount1);
const { calldata, value } = NonfungiblePositionManager.addCallParameters(
positionToMint,
mintOptions
)
})