Description:
Proxy contract enabling upgradeable smart contract patterns. Delegates calls to an implementation contract.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
/**
*Submitted for verification at Etherscan.io on 2025-08-27
*/
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.7.5;
library LowGasSafeMath {
/// @notice Returns x + y, reverts if sum overflows uint256
/// @param x The augend
/// @param y The addend
/// @return z The sum of x and y
function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x);
}
function add32(uint32 x, uint32 y) internal pure returns (uint32 z) {
require((z = x + y) >= x);
}
/// @notice Returns x - y, reverts if underflows
/// @param x The minuend
/// @param y The subtrahend
/// @return z The difference of x and y
function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x);
}
function sub32(uint32 x, uint32 y) internal pure returns (uint32 z) {
require((z = x - y) <= x);
}
/// @notice Returns x * y, reverts if overflows
/// @param x The multiplicand
/// @param y The multiplier
/// @return z The product of x and y
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(x == 0 || (z = x * y) / x == y);
}
/// @notice Returns x + y, reverts if overflows or underflows
/// @param x The augend
/// @param y The addend
/// @return z The sum of x and y
function add(int256 x, int256 y) internal pure returns (int256 z) {
require((z = x + y) >= x == (y >= 0));
}
/// @notice Returns x - y, reverts if overflows or underflows
/// @param x The minuend
/// @param y The subtrahend
/// @return z The difference of x and y
function sub(int256 x, int256 y) internal pure returns (int256 z) {
require((z = x - y) <= x == (y >= 0));
}
function div(uint256 x, uint256 y) internal pure returns(uint256 z){
require(y > 0);
z=x/y;
}
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
library Address {
function isContract(address account) internal view returns (bool) {
// This method relies in extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return _functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _functionCallWithValue(
address target,
bytes memory data,
uint256 weiValue,
string memory errorMessage
) private returns (bytes memory) {
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
function addressToString(address _address) internal pure returns(string memory) {
bytes32 _bytes = bytes32(uint256(_address));
bytes memory HEX = "0123456789abcdef";
bytes memory _addr = new bytes(42);
_addr[0] = '0';
_addr[1] = 'x';
for(uint256 i = 0; i < 20; i++) {
_addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];
_addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];
}
return string(_addr);
}
}
contract OwnableData {
address public owner;
address public Nodes;
address public pendingOwner;
}
contract Ownable is OwnableData {
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/// @notice `owner` defaults to msg.sender on construction.
constructor() {
owner = msg.sender;
emit OwnershipTransferred(address(0), msg.sender);
}
/// @notice Transfers ownership to `newOwner`. Either directly or claimable by the new pending owner.
/// Can only be invoked by the current `owner`.
/// @param newOwner Address of the new owner.
/// @param direct True if `newOwner` should be set immediately. False if `newOwner` needs to use `claimOwnership`.
/// @param renounce Allows the `newOwner` to be `address(0)` if `direct` and `renounce` is True. Has no effect otherwise.
function transferOwnership(
address newOwner,
bool direct,
bool renounce
) public onlyOwner {
if (direct) {
// Checks
require(newOwner != address(0) || renounce, "Ownable: zero address");
// Effects
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
pendingOwner = address(0);
} else {
// Effects
pendingOwner = newOwner;
}
}
/// @notice Needs to be called by `pendingOwner` to claim ownership.
function claimOwnership() public {
address _pendingOwner = pendingOwner;
// Checks
require(msg.sender == _pendingOwner, "Ownable: caller != pending owner");
// Effects
emit OwnershipTransferred(owner, _pendingOwner);
owner = _pendingOwner;
pendingOwner = address(0);
}
function setNodesAddress(address _nodes) public {
require(msg.sender == owner, "Ownable: caller is not the owner");
Nodes = _nodes;
}
/// @notice Only allows the `owner` to execute the function.
modifier onlyOwner() {
require(msg.sender == owner, "Ownable: caller is not the owner");
_;
}
modifier onlyNodes() {
require(msg.sender == Nodes, "Ownable: caller is not the nodes");
_;
}
}
interface INodes {
function walletOfOwner(address _owner) external view returns (uint256[] memory);
function mintFromRewards(uint256 _type, address to, uint256 n_tokens) external;
function getMintPrices() external view returns (uint256[5] memory);
}
contract rewardPool is Ownable {
using LowGasSafeMath for uint;
using LowGasSafeMath for uint256;
struct NftData{
uint256 nodeType;
address owner;
uint256 lastClaim;
uint256 expiry;
}
uint256[5] public rewardRates = [100000000,600000000,4000000000,12000000000,34000000000]; // In wei
uint256 public claimTax = 10; // Flat 10% claim tax
mapping (uint256 => NftData) public nftInfo;
uint256 totalNodes = 0;
address public PONZI;
mapping (address => uint256) public soldNodeRewards;
uint256 public monthsForMaintenance = 1;
uint256[5] public maintenanceCosts = [0, 0, 0, 0, 0]; // In wei
uint256 private mnth = 60 * 60 * 24 * 30;
uint256 private wk = 60 * 60 * 24 * 7;
uint256 public discount = 10; // Will get 10% if you mint with rewards
mapping (address => uint256) public lastClaimed;
constructor(address _PONZIAddress, address _nodeAddress) {
PONZI = _PONZIAddress;
Nodes = _nodeAddress;
}
receive() external payable {
}
function updateDiscount(uint256 _discount) public onlyOwner {
require(_discount <=100, "Discount must be less than 100%");
discount = _discount;
}
function updateMonthsForMaintenance(uint256 _monthsForMaintenance) public onlyOwner {
monthsForMaintenance = _monthsForMaintenance;
}
function updateMaintenanceCosts(uint256[5] memory _maintenanceCosts) public onlyOwner {
maintenanceCosts = _maintenanceCosts;
}
function updateClaimTax(uint256 _claimTax) public onlyOwner {
claimTax = _claimTax;
}
function addNodeInfo(uint256 _nftId, uint256 _nodeType, address _account) external onlyNodes returns (bool success) {
require(nftInfo[_nftId].owner == address(0), "Node already exists");
nftInfo[_nftId].nodeType = _nodeType;
nftInfo[_nftId].owner = _account;
nftInfo[_nftId].lastClaim = block.timestamp;
nftInfo[_nftId].expiry = block.timestamp + (mnth*monthsForMaintenance);
totalNodes += 1;
return true;
}
function updateNodeOwner(uint256 _nftId, address _account) external onlyNodes returns (bool success) {
require(nftInfo[_nftId].owner != address(0), "Node does not exist");
uint256 pendingRewards = pendingRewardFor(_nftId);
soldNodeRewards[nftInfo[_nftId].owner] += pendingRewards;
nftInfo[_nftId].lastClaim = block.timestamp;
nftInfo[_nftId].owner = _account;
return true;
}
function pendingRewardFor(uint256 _nftId) public view returns (uint256 _reward) {
uint256 _nodeType = nftInfo[_nftId].nodeType;
uint256 _lastClaim = nftInfo[_nftId].lastClaim;
uint256 _expiry = nftInfo[_nftId].expiry;
uint256 _currentTime = block.timestamp;
uint256 _daysSinceLastClaim;
if (_currentTime > _expiry) {
//node expired
if (_expiry <= _lastClaim){
_daysSinceLastClaim = 0;
}
else{
_daysSinceLastClaim = ((_expiry - _lastClaim).mul(1e9)) / 86400;
}
}
else{
_daysSinceLastClaim = ((_currentTime - _lastClaim).mul(1e9)) / 86400;
}
_reward = (_daysSinceLastClaim * rewardRates[_nodeType-1]).div(1e9);
return _reward;
}
function saveRewards(address _account) private{
uint256[] memory tokens = INodes(Nodes).walletOfOwner(_account);
uint256 totalReward = soldNodeRewards[_account];
for (uint256 i; i < tokens.length; i++) {
totalReward += pendingRewardFor(tokens[i]);
nftInfo[tokens[i]].lastClaim = block.timestamp;
}
soldNodeRewards[_account] = totalReward;
}
function mintNode(uint256 _type, uint256 n_tokens) public{
saveRewards(msg.sender);
require(n_tokens > 0, "Must mint at least 1 token");
require(_type>0 && _type<=5, "Node type must be between 1 and 5");
uint256 pendingRewards = soldNodeRewards[msg.sender];
uint256[5] memory mintPrices = INodes(Nodes).getMintPrices();
uint256 totalPrice = mintPrices[_type-1]*n_tokens;
uint256 priceAfterDiscount = totalPrice.sub(totalPrice.mul(discount).div(1e2));
require(pendingRewards >= priceAfterDiscount, "Not enough rewards");
soldNodeRewards[msg.sender] -= priceAfterDiscount;
INodes(Nodes).mintFromRewards(_type, msg.sender, n_tokens);
}
function claimRewards() public returns (bool success) {
saveRewards(msg.sender);
uint256 totalReward = soldNodeRewards[msg.sender];
uint256 totalTax = totalReward * claimTax / 100;
uint256 amount = totalReward.sub(totalTax);
IERC20(PONZI).transfer(msg.sender, amount);
lastClaimed[msg.sender] = block.timestamp;
soldNodeRewards[msg.sender] = 0;
return true;
}
function claimableRewards() public view returns (uint256 _reward) {
uint256 totalReward = soldNodeRewards[msg.sender];
uint256[] memory tokens = INodes(Nodes).walletOfOwner(msg.sender);
for (uint256 i; i < tokens.length; i++) {
totalReward += pendingRewardFor(tokens[i]);
}
return totalReward;
}
function nodeStats(address _account) public view returns (uint256 _nExpired, uint256 _amountdue){
uint256[] memory tokens = INodes(Nodes).walletOfOwner(_account);
_nExpired = 0;
_amountdue = 0;
uint256 expiry;
for (uint256 i; i < tokens.length; i++) {
expiry = nftInfo[tokens[i]].expiry;
if (expiry < block.timestamp){
_nExpired++;
_amountdue += maintenanceCosts[nftInfo[tokens[i]].nodeType-1];
}
}
return (_nExpired, _amountdue);
}
function payNodeFee() public payable {
(uint256 _nExpired, uint256 _amountdue) = nodeStats(msg.sender);
require(_amountdue > 0, "No fee due to pay");
require(msg.value == _amountdue, "Amount paid does not match amount due");
saveRewards(msg.sender);
uint256[] memory tokens = INodes(Nodes).walletOfOwner(msg.sender);
uint256 expiry;
for (uint256 i; i < tokens.length; i++) {
expiry = nftInfo[tokens[i]].expiry;
if (expiry < block.timestamp){
nftInfo[tokens[i]].expiry = block.timestamp + (mnth*monthsForMaintenance);
}
}
}
function emergencyWithdrawTokens() public onlyOwner {
IERC20(PONZI).transfer(owner, IERC20(PONZI).balanceOf(address(this)));
}
function withdraw() public payable onlyOwner {
(bool success, ) = payable(msg.sender).call{
value: address(this).balance
}("");
require(success);
}
}
Submitted on: 2025-10-24 15:29:55
Comments
Log in to comment.
No comments yet.