Two contracts: RGTToken (basic ERC20) and AssetManager (the main logic). Users deposit RGT tokens, get "assets" in return, and earn 0.1 RWT per asset per day.
RGT_TOKEN_ADDRESS: 0x... ASSET_MANAGER_ADDRESS: 0x... REWARD_TOKEN_ADDRESS: 0x...
Daily faucet — anyone can grab 100 RGT every 24 hours.
function mint() public { require(block.timestamp >= lastMintTime[msg.sender] + 1 days, "Wait 24 hours"); _mint(msg.sender, 100 * 10**decimals()); }
Owner can mint any amount to any address for testing.
function adminMint(address to, uint256 amount) public { require(msg.sender == owner, "Only owner"); _mint(to, amount); }
Allows users to deposit RGT tokens and receive corresponding asset units (10 tokens = 1 asset). Tokens are transferred to the contract and converted to tracked assets.
Reasoning: The function enforces deposits in multiples of 10 tokens to standardize asset units and simplify reward calculation
(1 asset = 10 tokens). This avoids fractional assets and ensures predictable behavior. Using transferFrom also ensures proper token custody by verifying that the user has approved the contract to spend the tokens on their behalf. daily.
function deposit(uint256 tokenAmount, address assetholder) public { // Must be at least 10 tokens and multiple of 10 require(tokenAmount >= (10 * 1e18), "invalid amount"); require(tokenAmount % (10 * 1e18) == 0, "Amount should be multiples of 10"); // Transfer tokens from user to contract require(rgtToken.transferFrom(msg.sender, address(this), tokenAmount), "Transfer failed"); // Convert to assets: 10 tokens = 1 asset uint256 assetAmount = tokenAmount / (10 * 1e18); createAsset(assetholder, assetAmount); }
Allows users to claim accumulated reward tokens based on their deposited assets and the time elapsed.
Reasoning: Before claiming, the function calls rewardCalculator to ensure rewards are up to date based on the latest time difference. It checks if the user has a non-zero claimable balance and ensures that the contract has enough reward tokens to fulfill the claim. Resetting claimableAmount before the transfer prevents reentrancy risks. This logic ensures fairness, avoids overclaims, and maintains the contract’s internal accounting integrity.
function claimReward() external { // Calculate and update rewards first rewardCalculator(msg.sender); uint256 claimable = assetStorage[msg.sender].claimableAmount; require(claimable > 0, "Nothing to claim"); // Check if pool has enough balance uint256 rewardBalance = rewardToken.balanceOf(address(this)); require(rewardBalance >= claimable, "Insufficient pool"); // Reset claimable and transfer assetStorage[msg.sender].claimableAmount = 0; rewardToken.transfer(msg.sender, claimable); }
This shows users the amount of RWT tokens they have acquired overtime.
Reasoning: This function is to help users know how much they have without them having to interact with the contract. Without it users won't know how much they have until they are ready to claim.
function pendingRewards(address holder) public view returns (uint256) { uint256 last = assetStorage[holder].lastRewardTime; if (block.timestamp < last + 1 days) return 0; // Too early uint256 daysPassed = (block.timestamp - last) / 1 days; return assetStorage[holder].totalAssets * daysPassed * 0.1 ether; }
This shows when next a user can claim after they have claimed all the claimable rewards.
Reasoning: This helps the user track the next time they can claim i.e if they want to be consitent with daily claims. It also takes away the confusion of not know what is going on in the background and helps build user trust.
function nextClaimTime(address user) public view returns (uint256) { uint256 last = assetStorage[user].lastRewardTime; if (last == 0) return 0; // Never deposited return last + 1 days; }
Check if user has any assets or their first time interacting with contract succesfully.
Reasoning: This function was introduced to help improve the user experience in providing detailed information on what to do and expect as a first time user.
function isFirstDeposit(address user) public view returns (bool) { return assetStorage[user].totalAssets == 0; }
Allows the contract owner to withdraw a specific amount of tokens from the reward pool.
Reasoning: This function is useful for managing excess or unused rewards in the pool, allowing the owner to reclaim unused tokens.
function withdrawPool(uint256 amount) external onlyOwner { uint256 rewardBalance = rewardToken.balanceOf(address(this)); require(rewardBalance >= amount, "Insufficient balance"); bool success = rewardToken.transfer(msg.sender, amount); require(success, "Withdraw failed"); emit PoolWithdrawn(amount); }
Allows the owner to withdraw a specific amount of RGT tokens that were deposited by users.
Reasoning: In case tokens need to be migrated, refunded, or repurposed, this function provides controlled access for withdrawal by the owner.
function withdrawDeposits(address to, uint256 amount) external onlyOwner { require(rgtToken.balanceOf(address(this)) >= amount, "Insufficient balance"); rgtToken.transfer(to, amount); }
Allows the owner to withdraw all RGT tokens from the contract in case of an emergency.
Reasoning: This function is designed for safety and recovery purposes. In case of critical failure or shutdown, the owner can recover all user deposits from the contract.
function emergencyWithdrawAllDeposits(address to) external onlyOwner { uint256 balance = rgtToken.balanceOf(address(this)); require(balance > 0, "Nothing to withdraw"); rgtToken.transfer(to, balance); }
Admin uses this function to deposit poolRewards in the contract.
function fundRewardPool(uint256 amount) external onlyOwner { require(amount > 0, "Amount must be > 0"); // Transfer RWT from owner to contract require(rewardToken.transferFrom(msg.sender, address(this), amount), "Funding failed"); }
// Every day, each asset earns 0.1 RWT daysPassed = (now - lastRewardTime) / 1 day reward = totalAssets * daysPassed * 0.1 // Example: 5 assets, 3 days passed reward = 5 * 3 * 0.1 = 1.5 RWT
The contract tracks when you last claimed, calculates days since then, and gives you that many days worth of rewards.
struct Asset { address holder; // Who owns this uint256 totalAssets; // How many asset units they have uint256 lastRewardTime; // When rewards were last calculated uint256 lastClaimed; // When they last claimed (unused currently) uint256 claimableAmount; // Rewards ready to claim }