Complete tournament system with FID-based entries, weighted rewards, mini games, and $TRIA token integration.
src/contracts/
โโโ EtherTrialsTRIAv2.sol # Main smart contract
โโโ EtherTrialsTRIAv2_DEPLOYMENT.md # Detailed deployment guide
โโโ UPDATE_ADDRESSES_GUIDE.md # How to update frontend after deployment
โโโ README.md # This file
src/lib/contracts/
โโโ etherTrialsTRIAv2ABI.ts # TypeScript ABI + contract addresses
src/hooks/
โโโ useTRIAContractv2.ts # React hook for contract interaction
scripts/
โโโ deploy-tria-v2.js # Hardhat deployment script
hardhat.config.js # Hardhat configuration
.env.example # Environment variables template
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-verify# Copy environment template
cp .env.example .env
# Edit .env and add:
# - Your deployer private key
# - BaseScan API key (for verification)Edit scripts/deploy-tria-v2.js:
const TRIA_TOKEN = "0xYOUR_TRIA_FROM_CLANKER"; // Update this
const BACKEND_SERVER = "0xYOUR_BACKEND_ADDRESS"; // Update this# Deploy to Base mainnet
npx hardhat run scripts/deploy-tria-v2.js --network base
# Deploy to testnet first (recommended)
npx hardhat run scripts/deploy-tria-v2.js --network baseGoerlinpx hardhat verify --network base DEPLOYED_ADDRESS "TRIA_TOKEN" "UNISWAP_ROUTER" "BACKEND_SERVER"Open src/lib/contracts/etherTrialsTRIAv2ABI.ts and update:
export const CONTRACT_ADDRESSES_V2 = {
base: {
etherTrialsTRIAv2: '0xYOUR_DEPLOYED_CONTRACT', // Update here
triaToken: '0xYOUR_TRIA_TOKEN',
uniswapRouter: '0x4752ba5dbc23f44d87826276bf6fd6b1c372ad24',
}
};See UPDATE_ADDRESSES_GUIDE.md for detailed instructions.
- Entry Range: 0.00001 - 1 ETH
- 100% ETH โ $TRIA swap via Uniswap
- Weighted Rewards: Higher entry = higher reward share
- FID-Based: 1 entry per FID per 24h period
Entry โ 100% swapped to $TRIA:
โโ 80% โ Prize Pool (in $TRIA)
โโ 10% โ Buyback Pool (owner withdrawable)
โโ 5% โ Treasury (ETH kept)
โโ 5% โ Mini Games Pool (ETH)
- Entry: 0.00001 ETH (fixed)
- Instant wins: 50% chance, 0.5x-2x prize
- Lucky Burst: 1:500 chance, 0.001 ETH prize
Entry Weight = (entry_amount / MIN_ENTRY) * 1e18
Weighted Score = user_score * entry_weight
Reward = (weighted_score / total_weighted_score) * prize_pool
Example:
- Player A: 0.00001 ETH entry, score 1000 โ Weight 1
- Player B: 1 ETH entry, score 1000 โ Weight 100,000
- Prize split: A gets 0.001%, B gets 99.999%
This ensures fairness: whales pay more, get more, but skill still matters.
- โ FID-based entry system (Farcaster integration)
- โ 24-hour periods with auto-rollover
- โ Weighted rewards (entry amount + score)
- โ Multi-period claiming
- โ Backend score submission
- โ Period finalization (anyone can trigger)
- โ Max 3 wallets per FID
- โ 7-day cooldown between additions
- โ Any approved wallet can claim rewards
- โ Must keep at least 1 wallet
- โ Ether Dice game
- โ Ether Spin game
- โ Lucky Burst mechanic
- โ Instant prize distribution
- โ Auto-inject to main prize pool
- โ Withdraw buyback $TRIA (for giveaways)
- โ Withdraw treasury ETH (for ops)
- โ Inject $TRIA to prize pool
- โ Withdraw mini maintenance
- โ Set lucky burst chance
-
Access Control:
- Owner-only administrative functions
- Backend-only score submission
- FID-wallet verification
-
Anti-Spam:
- 1-second cooldown between mini game plays
- 1 entry per FID per period
- 7-day wallet addition cooldown
-
Fail-Safes:
- Slippage protection on swaps (2%)
- Balance checks before withdrawals
- Period finalization guards
-
Auditing:
- All events logged on-chain
- Transparent reward calculations
- Public view functions
import { useTRIAContractV2 } from '@/hooks/useTRIAContractv2';
function TournamentPage() {
const fid = 12345n; // User's Farcaster FID
const {
currentPeriod,
periodInfo,
balances,
canEnterTournament,
enterTournament,
playDice,
playSpin,
claimAllRewards,
} = useTRIAContractV2(fid);
// Enter tournament
const handleEntry = async () => {
await enterTournament(fid, "0.001"); // 0.001 ETH
};
// Play mini game
const handleDice = async () => {
await playDice(fid); // 0.00001 ETH (auto)
};
return (
<div>
<h1>Period {currentPeriod.toString()}</h1>
<p>Prize Pool: {formatEther(periodInfo?.triaPool || 0n)} $TRIA</p>
<button onClick={handleEntry} disabled={!canEnterTournament}>
Enter Tournament
</button>
<button onClick={handleDice}>
Play Dice (0.00001 ETH)
</button>
</div>
);
}Before going live:
- Deploy to Base Goerli testnet
- Test tournament entry (various amounts)
- Test weighted reward calculations
- Test wallet management (add/remove)
- Test mini games (dice & spin)
- Test lucky burst (set chance to 2 for testing)
- Test period finalization
- Test claims (single & multi-period)
- Test owner functions
- Verify $TRIA swap works (check liquidity)
- Load test with multiple users
- Check all events emit correctly
- Detailed Deployment: EtherTrialsTRIAv2_DEPLOYMENT.md
- Address Update: UPDATE_ADDRESSES_GUIDE.md
- BaseScan: https://basescan.org
- BaseSwap: https://baseswap.fi
- Base Docs: https://docs.base.org
- Liquidity Required: $TRIA must have sufficient liquidity on BaseSwap before deployment
- Backend Setup: Configure backend server to submit scores via
submitScore() - Initial Funding: Send ETH to contract for mini game prizes and lucky burst
- Gas Costs: Entry requires ~300k gas (higher than normal due to swap)
- Period Management: Anyone can call
finalizePeriod()after 24h
After deployment, your addresses will be:
EtherTrialsTRIAv2: 0x... (from deployment)
$TRIA Token: 0x... (from Clanker)
BaseSwap Router: 0x4752ba5dbc23f44d87826276bf6fd6b1c372ad24
Backend Server: 0x... (your backend)
Update these in: src/lib/contracts/etherTrialsTRIAv2ABI.ts
- โ Read EtherTrialsTRIAv2_DEPLOYMENT.md
- โ
Configure
scripts/deploy-tria-v2.js - โ
Setup
.envfile - โ Deploy to testnet first
- โ Test thoroughly
- โ Deploy to mainnet
- โ Update frontend addresses
- โ Go live! ๐