@vechain/vebetterdao-contracts
Version:
Open-source repository that houses the smart contracts powering the decentralized VeBetterDAO on the VeChain Thor blockchain.
140 lines (139 loc) • 6.64 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const config_1 = require("@repo/config");
const contracts_1 = require("@repo/config/contracts");
const hardhat_1 = require("hardhat");
const typechain_types_1 = require("../../typechain-types");
const CHUNK_SIZE = 25;
const ChallengeStatusLabels = ["Pending", "Active", "Completed", "Cancelled", "Invalid"];
const ChallengeKindLabels = ["Stake", "Sponsored"];
const ChallengeTypeLabels = ["MaxActions", "SplitWin"];
const ChallengeVisibilityLabels = ["Public", "Private"];
const SettlementModeLabels = ["None", "TopWinners", "CreatorRefund", "SplitWinCompleted"];
function inc(map, key) {
map.set(key, (map.get(key) ?? 0) + 1);
}
function addBig(map, key, delta) {
map.set(key, (map.get(key) ?? 0n) + delta);
}
function printBreakdown(title, labels, counts, total) {
console.log(`\n----- ${title} -----`);
for (let i = 0; i < labels.length; i++) {
const c = counts.get(i) ?? 0;
const pct = total > 0 ? ((c / total) * 100).toFixed(1) : "0.0";
console.log(`${labels[i].padEnd(22)} ${String(c).padStart(8)} (${pct}%)`);
}
}
function printB3trByStatus(statusCounts, b3trByStatus) {
console.log("\n----- Total B3TR (totalPrize) by status -----");
console.log("STATUS".padEnd(14) + "COUNT".padStart(8) + " TOTAL_B3TR");
console.log("─".repeat(50));
for (let s = 0; s < ChallengeStatusLabels.length; s++) {
const count = statusCounts.get(s) ?? 0;
const wei = b3trByStatus.get(s) ?? 0n;
console.log(ChallengeStatusLabels[s].padEnd(14) + String(count).padStart(8) + " " + hardhat_1.ethers.formatEther(wei));
}
}
async function fetchAllChallenges(challenges, count) {
const ids = Array.from({ length: count }, (_, i) => i + 1);
const out = [];
for (let i = 0; i < ids.length; i += CHUNK_SIZE) {
const slice = ids.slice(i, i + CHUNK_SIZE);
const batch = await Promise.all(slice.map(id => challenges.getChallenge(id)));
out.push(...batch);
}
return out;
}
async function main() {
const [signer] = await hardhat_1.ethers.getSigners();
const config = (0, config_1.getConfig)(contracts_1.AppEnv.MAINNET);
const challenges = typechain_types_1.B3TRChallenges__factory.connect(config.challengesContractAddress, signer);
const xAllocation = typechain_types_1.XAllocationVotingGovernor__factory.connect(config.xAllocationVotingContractAddress, signer);
const [challengeCountBn, currentRoundBn, maxParticipantsBn, minBetBn] = await Promise.all([
challenges.challengeCount(),
xAllocation.currentRoundId(),
challenges.maxParticipants(),
challenges.minBetAmount(),
]);
const total = Number(challengeCountBn);
const currentRound = Number(currentRoundBn);
console.log("\n======== VeBetterDAO Quest (B3TRChallenges) stats =========\n");
console.log(`Network: ${config.environment}`);
console.log(`Challenges contract: ${config.challengesContractAddress}`);
console.log(`Current allocation round: ${currentRound}`);
console.log(`maxParticipants (MaxActions cap): ${maxParticipantsBn.toString()}`);
console.log(`minBetAmount: ${hardhat_1.ethers.formatEther(minBetBn)} B3TR`);
console.log(`Total quests created: ${total}`);
if (total === 0) {
console.log("\nNo challenges on chain.");
return;
}
const rows = await fetchAllChallenges(challenges, total);
const byStatus = new Map();
const byKind = new Map();
const byType = new Map();
const byVisibility = new Map();
const bySettlement = new Map();
const b3trByStatus = new Map();
let sumParticipants = 0n;
let sumInvited = 0n;
let sumDeclined = 0n;
let totalB3tr = 0n;
const creatorCounts = new Map();
for (const r of rows) {
const s = Number(r.status);
const k = Number(r.kind);
const t = Number(r.challengeType);
const v = Number(r.visibility);
const m = Number(r.settlementMode);
inc(byStatus, s);
inc(byKind, k);
inc(byType, t);
inc(byVisibility, v);
inc(bySettlement, m);
addBig(b3trByStatus, s, r.totalPrize);
sumParticipants += r.participantCount;
sumInvited += r.invitedCount;
sumDeclined += r.declinedCount;
totalB3tr += r.totalPrize;
const c = r.creator.toLowerCase();
creatorCounts.set(c, (creatorCounts.get(c) ?? 0) + 1);
}
const avgParticipants = total > 0 ? Number(sumParticipants) / total : 0;
const avgInvited = total > 0 ? Number(sumInvited) / total : 0;
const avgDeclined = total > 0 ? Number(sumDeclined) / total : 0;
const finished = (byStatus.get(2) ?? 0) + (byStatus.get(3) ?? 0) + (byStatus.get(4) ?? 0); // Completed + Cancelled + Invalid
printBreakdown("By status", ChallengeStatusLabels, byStatus, total);
printBreakdown("By kind", ChallengeKindLabels, byKind, total);
printBreakdown("By type", ChallengeTypeLabels, byType, total);
printBreakdown("By visibility", ChallengeVisibilityLabels, byVisibility, total);
printBreakdown("By settlementMode", SettlementModeLabels, bySettlement, total);
printB3trByStatus(byStatus, b3trByStatus);
console.log("\n----- B3TR (totalPrize) -----");
console.log(`Sum across all quests: ${hardhat_1.ethers.formatEther(totalB3tr)} B3TR`);
console.log("\n----- Participation (sums / averages) -----");
console.log(`Sum participantCount: ${sumParticipants.toString()}`);
console.log(`Sum invitedCount: ${sumInvited.toString()}`);
console.log(`Sum declinedCount: ${sumDeclined.toString()}`);
console.log(`Avg participants/quest: ${avgParticipants.toFixed(2)}`);
console.log(`Avg invited/quest: ${avgInvited.toFixed(2)}`);
console.log(`Avg declined/quest: ${avgDeclined.toFixed(2)}`);
console.log("\n----- Lifecycle snapshot -----");
console.log(`Pending: ${byStatus.get(0) ?? 0}`);
console.log(`Active: ${byStatus.get(1) ?? 0}`);
console.log(`Terminal (2+3+4): ${finished}`);
const topCreators = [...creatorCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10);
console.log("\n----- Top 10 creators by quest count -----");
console.log("RANK COUNT ADDRESS");
console.log("─".repeat(60));
topCreators.forEach(([addr, n], idx) => {
console.log(`${String(idx + 1).padStart(4)} ${String(n).padStart(5)} ${addr}`);
});
console.log("\n" + "=".repeat(60) + "\n");
}
main()
.then(() => process.exit(0))
.catch(err => {
console.error(err);
process.exit(1);
});