// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @title NaddieJump * @notice On-chain leaderboard and reward contract for Naddie Jump game. * @dev Designed for Monad EVM compatibility. */ contract NaddieJump { struct Score { address player; uint256 score; uint256 blockHeight; uint256 timestamp; } mapping(address => Score) public bestScores; Score[] public leaderboard; uint256 public constant LEADERBOARD_SIZE = 50; uint256 public constant REWARD_THRESHOLD = 50000; event ScoreSubmitted(address indexed player, uint256 score, uint256 blockHeight); event RewardClaimed(address indexed player, uint256 amount); function submitScore(uint256 score, uint256 blockHeight) external { require(score > 0, "Invalid score"); Score storage current = bestScores[msg.sender]; if (score > current.score) { current.player = msg.sender; current.score = score; current.blockHeight = blockHeight; current.timestamp = block.timestamp; _updateLeaderboard(current); } emit ScoreSubmitted(msg.sender, score, blockHeight); } function _updateLeaderboard(Score memory newScore) internal { // Simple insertion sort approach for leaderboard bool exists = false; for (uint256 i = 0; i < leaderboard.length; i++) { if (leaderboard[i].player == newScore.player) { leaderboard[i] = newScore; exists = true; break; } } if (!exists && leaderboard.length < LEADERBOARD_SIZE) { leaderboard.push(newScore); } // Sort descending by score (bubble sort for simplicity in prototype) for (uint256 i = 0; i < leaderboard.length; i++) { for (uint256 j = i + 1; j < leaderboard.length; j++) { if (leaderboard[j].score > leaderboard[i].score) { Score memory tmp = leaderboard[i]; leaderboard[i] = leaderboard[j]; leaderboard[j] = tmp; } } } } function getLeaderboard(uint256 count) external view returns (Score[] memory) { uint256 len = count > leaderboard.length ? leaderboard.length : count; Score[] memory result = new Score[](len); for (uint256 i = 0; i < len; i++) { result[i] = leaderboard[i]; } return result; } function getPlayerBest(address player) external view returns (Score memory) { return bestScores[player]; } // Placeholder for future ERC-20 reward integration function claimReward() external view returns (bool eligible) { Score storage s = bestScores[msg.sender]; eligible = s.score >= REWARD_THRESHOLD; // TODO: mint/transfer ERC-20 $GWEI tokens } }