What it does:
Automatically distributes rewards (tokens, NFTs, or in-game currency) to players based on achievements, milestones, or gameplay events on-chain.
Why it matters:
Ensures transparent, tamper-proof reward distribution, incentivizes player engagement, and allows developers to implement programmable reward structures.
How it works:
Players register or connect wallets to the reward engine
Smart contracts track in-game achievements, milestones, or events
Rewards are calculated automatically based on predefined rules (time played, challenges completed, or leaderboard rank)
Rewards are distributed in tokens, NFTs, or other on-chain assets
Integrates with Gaming Asset Ownership, Creator Collaboration Revenue Split, or NFT Marketplaces
Dashboards visualize earned rewards, pending payouts, and achievement history
Supports multi-game or cross-platform reward tracking
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title PlayToEarnRewardEngine
* @author Nam
* @notice Distributes on-chain P2E rewards based on achievements and milestones
*/
contract PlayToEarnRewardEngine is Ownable {
IERC20 public rewardToken;
struct Player {
uint256 totalRewards;
mapping(string => bool) achievements;
}
mapping(address => Player) public players;
mapping(address => bool) public authorizedValidators;
// -------------------- EVENTS --------------------
event ValidatorApproved(address validator);
event ValidatorRevoked(address validator);
event AchievementUnlocked(address player, string achievementId, uint256 rewardAmount);
event RewardClaimed(address player, uint256 amount);
// -------------------- VALIDATOR MANAGEMENT --------------------
function approveValidator(address _validator) external onlyOwner {
authorizedValidators[_validator] = true;
emit ValidatorApproved(_validator);
}
function revokeValidator(address _validator) external onlyOwner {
authorizedValidators[_validator] = false;
emit ValidatorRevoked(_validator);
}
modifier onlyValidator() {
require(authorizedValidators[msg.sender], "Not authorized validator");
_;
}
// -------------------- CONSTRUCTOR --------------------
constructor(address _rewardToken) {
rewardToken = IERC20(_rewardToken);
}
// -------------------- ACHIEVEMENT & REWARD MANAGEMENT --------------------
function unlockAchievement(address _player, string calldata _achievementId, uint256 _rewardAmount) external onlyValidator {
Player storage p = players[_player];
require(!p.achievements[_achievementId], "Achievement already unlocked");
p.achievements[_achievementId] = true;
p.totalRewards += _rewardAmount;
emit AchievementUnlocked(_player, _achievementId, _rewardAmount);
}
function claimRewards() external {
Player storage p = players[msg.sender];
uint256 amount = p.totalRewards;
require(amount > 0, "No rewards to claim");
p.totalRewards = 0;
rewardToken.transfer(msg.sender, amount);
emit RewardClaimed(msg.sender, amount);
}
// -------------------- VIEW FUNCTIONS --------------------
function hasAchievement(address _player, string calldata _achievementId) external view returns (bool) {
return players[_player].achievements[_achievementId];
}
function pendingRewards(address _player) external view returns (uint256) {
return players[_player].totalRewards;
}
}
Build and Grow By Nam Le Thanh