Files
naddie-jump/contracts/NaddieJump.sol

85 lines
2.8 KiB
Solidity

// 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
}
}