💰Rewards Summary
豚林vitalik.eth
🥇 Leaderboard & Hall of Fame
To be eligible for any reward (Airdrop or Jackpot), your incarnation have to be among the top 50 incarnations by lifescore. 😎
We call the top 50 incarnations by lifescore - the Hall of Fame (HoF). HoF changes constantly, and high lifescore incarnations will squeeze out low lifescore ones. 😭
🚀 Tributing - Buff or Curse
You can stake your $DEGEN on top incarnations to share the Airdrop & Jackpot. Like tributing to a tombstone. 🙏
The $DEGEN you tribute will be automatically burned.
There are two types of tributing -- Buff & Curse.
😘 When you buff a incarnation with you $DEGEN, its TVL and ranking will increase ⬆️
🤬 When you curse a incarnation with your $DEGEN, its TVL and ranking will decrease. ⬇️
You can still switch your $DEGEN stake to other incarnations anytime, with a 5% burn. 🪦
For all rewards, owner of the incarnation gets 20% of the rewards. Stakeholders get 80%, and it's distributed according to your shares of the pool. 🙌
🎲 How Random?
Onchain random airdrop and jackpot is a big topic. 🤔
As much as possible, we use Chainlink Automation and VRF. ✔️
We also open source the raffle source code so that anyone can run the raffle source code with random seed generated by predefined procedure, and verify the result themselves. 🫡
More measures are being added in subsequent seasons to make the game more fully onchain. 🐾
See below --
import System.Random
raffleWinners :: Int -> [Int] -> Int -> [Int]
raffleWinners numCandidates weights seed = take 10 $ pickWinners candidatesWithWeights sortedWeights (mkStdGen seed)
where
candidates = [1..numCandidates]
candidatesWithWeights = zip candidates weights
sortedWeights = map snd $ reverse $ sort candidatesWithWeights
pickWinners :: [(Int, Int)] -> [Int] -> StdGen -> [Int]
pickWinners [] _ _ = []
pickWinners _ [] _ = []
pickWinners candidatesWeights (x:xs) gen = winner : pickWinners remainingCandidatesWeights xs newGen
where
(index, newGen) = randomR (0, totalWeights - 1) gen
(winner, remainingCandidatesWeights, totalWeights) = pickWinner candidatesWeights [] 0 index
pickWinner :: [(Int, Int)] -> [(Int, Int)] -> Int -> Int -> (Int, [(Int, Int)], Int)
pickWinner ((candidate, weight):xs) acc cumIndex index
| cumIndex + weight > index = (candidate, reverse acc ++ xs, cumIndex + weight)
| otherwise = pickWinner xs ((candidate, weight):acc) (cumIndex + weight) index
Also in JavaScript --
const seedrandom = require('seedrandom');
function getRaffleWinners(candidates, weights, numWinners, seed) {
const rng = seedrandom(seed);
const weightedCandidates = candidates.flatMap((c, i) => Array.from({ length: weights[i] }).fill(c));
const winners = [];
while (winners.length < numWinners && weightedCandidates.length > 0) {
const randomIndex = Math.floor(rng() * weightedCandidates.length);
winners.push(weightedCandidates.splice(randomIndex, 1)[0]);
}
return winners;
}
const candidates = Array.from({ length: 100 }, (_, i) => `Candidate ${i + 1}`);
const weights = Array.from({ length: 100 }, () => Math.ceil(Math.random() * 10));
const numWinners = 10;
const seed = 'myRandomSeed';
const winners = getRaffleWinners(candidates, weights, numWinners, seed);
console.log('Winners:', winners);
♻️ TVL
TVL here refers to the amount of $DEGEN staked - buff and curse. When picking winners from Hall of Famers, TVL is the most important factor.
⏰ Daily & Seasonal Ranking
Daily Ranking: refers to the reset of TVLs & Tribute data everyday
Seasonal Ranking: refers to the overall ranking associated with Jackpot allocation
Last updated