// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
interface ICitizen {
function balanceOf(address owner) external view returns (uint256);
}
interface IOuterCitizen {
function balanceOf(address owner) external view returns (uint256);
}
interface IStakedOuterCitizen {
function balanceOf(address owner) external view returns (uint256);
}
interface ILegacyOuterCitizen {
function balanceOf(address owner) external view returns (uint256);
}
interface ILegacyCitizen {
function balanceOf(address owner) external view returns (uint256);
}
interface IStakedCitizen {
function balanceOf(address owner) external view returns (uint256);
}
interface IERC20 {
function owner() external view returns (address);
function balanceOf(address address_) external view returns (uint256);
function transfer(address to_, uint256 amount_) external returns (bool);
function transferFrom(address from_, address to_, uint256 amount_) external;
function approve(address spender, uint256 amount) external;
}
contract NTRewardSystem {
using SafeMath for uint256;
error RecipientIsNotACitizen();
error ArrayLenghtsNotEqual();
error PercentagesMaxExceeded();
error NotDesignedToHandle();
error SplitPercentageHasToEqualOneHundred();
error NotAnAdmin();
error BlackListed();
address public vault = 0xfdAb2c282f6481010A92d20BAc46c8becd06b012;
ICitizen public citizenContract =
ICitizen(0xB9951B43802dCF3ef5b14567cb17adF367ed1c0F);
IERC20 public BYTES = IERC20(0xa19f5264F7D7Be11c451C093D8f92592820Bea86);
IOuterCitizen public outerCitizenContract =
IOuterCitizen(0x4481507cc228FA19D203BD42110d679571f7912E);
IStakedCitizen public stakedCitizenContract =
IStakedCitizen(0xd37ea75Dd3c499eDA76304f538CbF356Ed9e7Ed9);
ILegacyCitizen public legacyCitizenContract =
ILegacyCitizen(0xb668beB1Fa440F6cF2Da0399f8C28caB993Bdd65);
ILegacyOuterCitizen public legacyOuterCitizenContract =
ILegacyOuterCitizen(0x9b091d2E0Bb88acE4fe8f0faB87b93D8bA932EC4);
bool public vaultActive;
uint256 public vaultTax = 5 * 1 ether;
mapping(uint8 => uint256) private _calculateReward;
mapping(address => bool) private _controllers;
mapping(address => bool) private _blacklisted;
event BronzeRewarded(
address indexed sender,
uint256 amountInBytes,
address[] indexed recipient
);
event SilverRewarded(
address indexed sender,
uint256 amountInBytes,
address[] indexed recipient
);
event GoldRewarded(
address indexed sender,
uint256 amountInBytes,
address[] indexed recipient
);
event PlatinumRewarded(
address indexed sender,
uint256 amountInBytes,
address[] indexed recipient
);
event AdminAdded(address indexed msgSender, address[] indexed newAdmins);
event AdminRemoved(address indexed msgSender, address[] indexed retiredAdmins);
mapping(address => uint256) public userRewardsTotal;
constructor() {
_controllers[msg.sender] = true;
_calculateReward[1] = 5 * 1 ether;
_calculateReward[2] = 25 * 1 ether;
_calculateReward[3] = 50 * 1 ether;
_calculateReward[4] = 100 * 1 ether;
}
modifier onlyAdmin() {
if (!_controllers[msg.sender]) revert NotAnAdmin();
_;
}
function addAdmins(address[] calldata _controller) external onlyAdmin {
for (uint256 i = 0; i < _controller.length; i++) {
_controllers[_controller[i]] = true;
}
emit AdminAdded(msg.sender, _controller);
}
function removeAdmins(address[] calldata _controller) external onlyAdmin {
for (uint256 i = 0; i < _controller.length; i++) {
_controllers[_controller[i]] = false;
}
emit AdminRemoved(msg.sender, _controller);
}
function addBlacklistAddress(
address[] calldata _addresses
) external onlyAdmin {
for (uint256 i = 0; i < _addresses.length; i++) {
_blacklisted[_addresses[i]] = true;
}
}
function removeBlacklistAddress(
address[] calldata _addresses
) external onlyAdmin {
for (uint256 i = 0; i < _addresses.length; i++) {
_blacklisted[_addresses[i]] = false;
}
}
function setRewardForSpecificReward(
uint8 _typeOfReward,
uint256 _bytesInEther
) external onlyAdmin {
_calculateReward[_typeOfReward] = _bytesInEther;
}
function setVault(address _newVault) external onlyAdmin {
vault = _newVault;
}
function setOuterCitizenContract(
IOuterCitizen _outerCitizenContract
) external onlyAdmin {
outerCitizenContract = _outerCitizenContract;
}
function setCitizenContract(ICitizen _citizenContract) external onlyAdmin {
citizenContract = _citizenContract;
}
function setStakedCitizenContract(
IStakedCitizen _stakedCitizenContract
) external onlyAdmin {
stakedCitizenContract = _stakedCitizenContract;
}
function setLegacyCitizenContract(
ILegacyCitizen _legacyCitizenContract
) external onlyAdmin {
legacyCitizenContract = _legacyCitizenContract;
}
function setLegacyOuterCitizenContract(
ILegacyOuterCitizen _legacyOuterCitizenContract
) external onlyAdmin {
legacyOuterCitizenContract = _legacyOuterCitizenContract;
}
function setBYTESContract(IERC20 _BYTES) external onlyAdmin {
BYTES = _BYTES;
}
function toggleVaultActive() external onlyAdmin {
vaultActive = !vaultActive;
}
function setVaultTax(uint256 _newTax) external onlyAdmin {
vaultTax = _newTax;
}
function isCitizen(address _recipient) private view {
if (
citizenContract.balanceOf(_recipient) == 0 &&
outerCitizenContract.balanceOf(_recipient) == 0 &&
stakedCitizenContract.balanceOf(_recipient) == 0 &&
legacyCitizenContract.balanceOf(_recipient) == 0 &&
legacyOuterCitizenContract.balanceOf(_recipient) == 0
) {
revert RecipientIsNotACitizen();
}
if (msg.sender == _recipient) {
revert NotDesignedToHandle();
}
}
function rewardBytesSpecificWithCustomSplit(
address[] calldata _recipient,
uint256 _amount,
uint256[] calldata _split
) external {
if (_recipient.length != _split.length) revert ArrayLenghtsNotEqual();
if (!vaultActive) {
if (_recipient.length == 3) {
isCitizen(_recipient[0]);
isCitizen(_recipient[1]);
isCitizen(_recipient[2]);
rewardBytesPeerToPeerHandleThreeSplit(
_recipient,
_amount,
_split
);
} else {
if (_recipient.length == 2) {
isCitizen(_recipient[0]);
isCitizen(_recipient[1]);
rewardBytesPeerToPeerHandleTwoSplit(
_recipient,
_amount,
_split
);
} else {
if (_recipient.length != 1) revert NotDesignedToHandle();
rewardBytesPeerToPeerOne(_recipient[0], _amount);
}
}
} else {
if (_recipient.length == 3) {
isCitizen(_recipient[0]);
isCitizen(_recipient[1]);
isCitizen(_recipient[2]);
rewardBytesVaultHandleThreeSplit(_recipient, _amount, _split);
} else {
if (_recipient.length == 2) {
isCitizen(_recipient[0]);
isCitizen(_recipient[1]);
rewardBytesVaultHandleTwoSplit(_recipient, _amount, _split);
} else {
if (_recipient.length != 1) revert NotDesignedToHandle();
rewardBytesVaultOne(_recipient[0], _amount);
}
}
}
}
function rewardBytesPeerToPeerHandleTwoSplit(
address[] calldata _recipient,
uint256 _amount,
uint256[] calldata _split
) private {
if (_blacklisted[msg.sender]) revert BlackListed();
uint256 splitAdded = _split[0] + _split[1];
if (splitAdded > 100 * 1 ether)
revert SplitPercentageHasToEqualOneHundred();
BYTES.transferFrom(
msg.sender,
_recipient[0],
_amount.mul(_split[0]).div(100 * 1 ether)
);
BYTES.transferFrom(
msg.sender,
_recipient[1],
_amount.mul(_split[1]).div(100 * 1 ether)
);
userRewardsTotal[_recipient[0]] += _amount.mul(_split[0]).div(
100 * 1 ether
);
userRewardsTotal[_recipient[1]] += _amount.mul(_split[1]).div(
100 * 1 ether
);
if (100 * 1 ether - splitAdded > 0) {
BYTES.transferFrom(
msg.sender,
_recipient[0],
_amount.mul((100 * 1 ether - splitAdded)).div(100 * 1 ether)
);
userRewardsTotal[_recipient[0]] += _amount
.mul((100 * 1 ether - splitAdded))
.div(100 * 1 ether);
}
emitReward(_recipient, _amount);
}
function rewardBytesPeerToPeerHandleThreeSplit(
address[] calldata _recipient,
uint256 _amount,
uint256[] calldata _split
) private {
if (_blacklisted[msg.sender]) revert BlackListed();
uint256 splitAdded = _split[0] + _split[1] + _split[2];
if (splitAdded > 100 * 1 ether)
revert SplitPercentageHasToEqualOneHundred();
BYTES.transferFrom(
msg.sender,
_recipient[0],
_amount.mul(_split[0]).div(100 * 1 ether)
);
BYTES.transferFrom(
msg.sender,
_recipient[1],
_amount.mul(_split[1]).div(100 * 1 ether)
);
BYTES.transferFrom(
msg.sender,
_recipient[2],
_amount.mul(_split[2]).div(100 * 1 ether)
);
userRewardsTotal[_recipient[0]] += _amount.mul(_split[0]).div(
100 * 1 ether
);
userRewardsTotal[_recipient[1]] += _amount.mul(_split[1]).div(
100 * 1 ether
);
userRewardsTotal[_recipient[2]] += _amount.mul(_split[2]).div(
100 * 1 ether
);
if (100 * 1 ether - splitAdded > 0) {
BYTES.transferFrom(
msg.sender,
_recipient[0],
_amount.mul((100 * 1 ether - splitAdded)).div(100 * 1 ether)
);
userRewardsTotal[_recipient[0]] += _amount
.mul((100 * 1 ether - splitAdded))
.div(100 * 1 ether);
}
emitReward(_recipient, _amount);
}
function rewardBytesVaultHandleTwoSplit(
address[] calldata _recipient,
uint256 _amount,
uint256[] calldata _split
) private {
if (_blacklisted[msg.sender]) revert BlackListed();
uint256 splitAdded = _split[0] + _split[1];
if (splitAdded > 100 * 1 ether)
revert SplitPercentageHasToEqualOneHundred();
uint256 balance = _amount;
uint256 executedVaultTax = balance.mul(vaultTax).div(100 * 1 ether);
BYTES.transferFrom(msg.sender, vault, executedVaultTax);
balance -= executedVaultTax;
BYTES.transferFrom(
msg.sender,
_recipient[0],
balance.mul(_split[0]).div(100 * 1 ether)
);
BYTES.transferFrom(
msg.sender,
_recipient[1],
balance.mul(_split[1]).div(100 * 1 ether)
);
userRewardsTotal[_recipient[0]] += balance.mul(_split[0]).div(
100 * 1 ether
);
userRewardsTotal[_recipient[1]] += balance.mul(_split[1]).div(
100 * 1 ether
);
if (100 * 1 ether - splitAdded > 0) {
BYTES.transferFrom(
msg.sender,
_recipient[0],
balance.mul((100 * 1 ether - splitAdded)).div(100 * 1 ether)
);
userRewardsTotal[_recipient[0]] += balance
.mul((100 * 1 ether - splitAdded))
.div(100 * 1 ether);
}
emitReward(_recipient, _amount);
}
function rewardBytesVaultHandleThreeSplit(
address[] calldata _recipient,
uint256 _amount,
uint256[] calldata _split
) private {
if (_blacklisted[msg.sender]) revert BlackListed();
uint256 splitAdded = _split[0] + _split[1] + _split[2];
if (splitAdded > 100 * 1 ether)
revert SplitPercentageHasToEqualOneHundred();
uint256 balance = _amount;
uint256 executedVaultTax = balance.mul(vaultTax).div(100 * 1 ether);
BYTES.transferFrom(msg.sender, vault, executedVaultTax);
balance -= executedVaultTax;
BYTES.transferFrom(
msg.sender,
_recipient[0],
balance.mul(_split[0]).div(100 * 1 ether)
);
BYTES.transferFrom(
msg.sender,
_recipient[1],
balance.mul(_split[1]).div(100 * 1 ether)
);
BYTES.transferFrom(
msg.sender,
_recipient[2],
balance.mul(_split[2]).div(100 * 1 ether)
);
userRewardsTotal[_recipient[0]] += balance.mul(_split[0]).div(
100 * 1 ether
);
userRewardsTotal[_recipient[1]] += balance.mul(_split[1]).div(
100 * 1 ether
);
userRewardsTotal[_recipient[2]] += balance.mul(_split[2]).div(
100 * 1 ether
);
if (100 * 1 ether - splitAdded > 0) {
BYTES.transferFrom(
msg.sender,
_recipient[0],
balance.mul((100 * 1 ether - splitAdded)).div(100 * 1 ether)
);
userRewardsTotal[_recipient[0]] += balance
.mul((100 * 1 ether - splitAdded))
.div(100 * 1 ether);
}
emitReward(_recipient, _amount);
}
function rewardBytesSpecificWithoutCustomSplit(
address[] calldata _recipient,
uint256 _amount
) external {
if (!vaultActive) {
if (_recipient.length == 3) {
isCitizen(_recipient[0]);
isCitizen(_recipient[1]);
isCitizen(_recipient[2]);
rewardBytesPeerToPeerHandleThree(_recipient, _amount);
} else {
if (_recipient.length == 2) {
isCitizen(_recipient[0]);
isCitizen(_recipient[1]);
rewardBytesPeerToPeerHandleTwo(_recipient, _amount);
} else {
if (_recipient.length != 1) revert NotDesignedToHandle();
rewardBytesPeerToPeerOne(_recipient[0], _amount);
}
}
} else {
if (_recipient.length == 3) {
isCitizen(_recipient[0]);
isCitizen(_recipient[1]);
isCitizen(_recipient[2]);
rewardBytesVaultHandleThree(_recipient, _amount);
} else {
if (_recipient.length == 2) {
isCitizen(_recipient[0]);
isCitizen(_recipient[1]);
rewardBytesVaultHandleTwo(_recipient, _amount);
} else {
if (_recipient.length != 1) revert NotDesignedToHandle();
rewardBytesVaultOne(_recipient[0], _amount);
}
}
}
}
function rewardBytesVaultHandleTwo(
address[] calldata _recipient,
uint256 _amount
) private {
if (_blacklisted[msg.sender]) revert BlackListed();
uint256 balance = _amount;
uint256 executedVaultTax = balance.mul(vaultTax).div(100 * 1 ether);
BYTES.transferFrom(msg.sender, vault, executedVaultTax);
balance -= executedVaultTax;
uint256 cut = balance.div(2);
BYTES.transferFrom(msg.sender, _recipient[0], cut);
BYTES.transferFrom(msg.sender, _recipient[1], cut);
userRewardsTotal[_recipient[0]] += cut;
userRewardsTotal[_recipient[1]] += cut;
emitReward(_recipient, _amount);
}
function rewardBytesVaultHandleThree(
address[] calldata _recipient,
uint256 _amount
) private {
if (_blacklisted[msg.sender]) revert BlackListed();
uint256 balance = _amount;
uint256 executedVaultTax = _amount.mul(vaultTax).div(100 * 1 ether);
BYTES.transferFrom(msg.sender, vault, executedVaultTax);
balance -= executedVaultTax;
uint256 cut = balance.div(3);
BYTES.transferFrom(msg.sender, _recipient[0], cut);
BYTES.transferFrom(msg.sender, _recipient[1], cut);
BYTES.transferFrom(msg.sender, _recipient[2], cut);
userRewardsTotal[_recipient[0]] += cut;
userRewardsTotal[_recipient[1]] += cut;
userRewardsTotal[_recipient[2]] += cut;
emitReward(_recipient, _amount);
}
function rewardBytesPeerToPeerHandleOne(
address[] calldata _recipient,
uint256 _amount
) private {
if (_blacklisted[msg.sender]) revert BlackListed();
BYTES.transferFrom(msg.sender, _recipient[0], _amount);
userRewardsTotal[_recipient[0]] += _amount;
emitReward(_recipient, _amount);
}
function rewardBytesPeerToPeerHandleTwo(
address[] calldata _recipient,
uint256 _amount
) private {
if (_blacklisted[msg.sender]) revert BlackListed();
uint256 cut = _amount.div(2);
BYTES.transferFrom(msg.sender, _recipient[0], cut);
BYTES.transferFrom(msg.sender, _recipient[1], cut);
userRewardsTotal[_recipient[0]] += cut;
userRewardsTotal[_recipient[1]] += cut;
emitReward(_recipient, _amount);
}
function rewardBytesPeerToPeerHandleThree(
address[] calldata _recipient,
uint256 _amount
) private {
if (_blacklisted[msg.sender]) revert BlackListed();
uint256 cut = _amount.div(3);
BYTES.transferFrom(msg.sender, _recipient[0], cut);
BYTES.transferFrom(msg.sender, _recipient[1], cut);
BYTES.transferFrom(msg.sender, _recipient[2], cut);
userRewardsTotal[_recipient[0]] += cut;
userRewardsTotal[_recipient[1]] += cut;
userRewardsTotal[_recipient[2]] += cut;
emitReward(_recipient, _amount);
}
function rewardBytesPeerToPeer(
address[] calldata _recipient,
uint256 _amount,
uint256[] calldata _split
) private {
if (_blacklisted[msg.sender]) revert BlackListed();
uint256 balance = _amount;
uint256 temp;
uint256 cut;
for (uint256 j = 0; j < _recipient.length; j++) {
isCitizen(_recipient[j]);
cut = balance.mul(_split[j]).div(100 * 1 ether);
temp += balance.mul(_split[j]).div(100 * 1 ether);
BYTES.transferFrom(msg.sender, _recipient[j], cut);
userRewardsTotal[_recipient[j]] += cut;
}
balance -= temp;
if (balance > 0) {
BYTES.transferFrom(msg.sender, _recipient[0], balance);
userRewardsTotal[_recipient[0]] += balance;
}
emitReward(_recipient, _amount);
}
function emitReward(
address[] calldata _recipient,
uint256 _amount
) private {
uint256 calculateRewardTwo = _calculateReward[2];
uint256 calculateRewardThree = _calculateReward[3];
uint256 calculateRewardFour = _calculateReward[4];
if (_calculateReward[1] - 1 < _amount && _amount < calculateRewardTwo) {
emit BronzeRewarded(msg.sender, _amount, _recipient);
} else {
if (
calculateRewardTwo - 1 < _amount &&
_amount < calculateRewardThree
) {
emit SilverRewarded(msg.sender, _amount, _recipient);
} else {
if (
calculateRewardThree - 1 < _amount &&
_amount < calculateRewardFour
) {
emit GoldRewarded(msg.sender, _amount, _recipient);
} else {
if (calculateRewardFour - 1 < _amount) {
emit PlatinumRewarded(msg.sender, _amount, _recipient);
}
}
}
}
}
function rewardBytes(
address[] calldata _recipient,
uint256 _amount,
uint256[] calldata _split
) external {
if (_recipient.length != _split.length) revert ArrayLenghtsNotEqual();
uint256 splitCheck;
for (uint256 i = 0; i < _recipient.length; i++) {
splitCheck += _split[i];
}
if (splitCheck > 100 * 1 ether) revert PercentagesMaxExceeded();
if (!vaultActive) {
rewardBytesPeerToPeer(_recipient, _amount, _split);
} else {
rewardBytesVault(_recipient, _amount, _split);
}
}
function rewardBytesVault(
address[] calldata _recipient,
uint256 _amount,
uint256[] calldata _split
) private {
if (_blacklisted[msg.sender]) revert BlackListed();
uint256 balance = _amount;
uint256 executedVaultTax = balance.mul(vaultTax).div(100 * 1 ether);
BYTES.transferFrom(msg.sender, vault, executedVaultTax);
balance -= executedVaultTax;
uint256 temp;
uint256 cut;
for (uint256 j = 0; j < _recipient.length; j++) {
isCitizen(_recipient[j]);
cut = balance.mul(_split[j]).div(100 * 1 ether);
temp += cut;
BYTES.transferFrom(msg.sender, _recipient[j], cut);
userRewardsTotal[_recipient[j]] += cut;
}
balance -= temp;
if (balance > 0) {
BYTES.transferFrom(msg.sender, _recipient[0], balance);
}
emitReward(_recipient, _amount);
}
function rewardBytesOne(address _recipient, uint256 _amount) external {
if (!vaultActive) {
rewardBytesPeerToPeerOne(_recipient, _amount);
} else {
rewardBytesVaultOne(_recipient, _amount);
}
}
function rewardBytesPeerToPeerOne(
address _recipient,
uint256 _amount
) private {
if (_blacklisted[msg.sender]) revert BlackListed();
isCitizen(_recipient);
BYTES.transferFrom(msg.sender, _recipient, _amount);
userRewardsTotal[_recipient] += _amount;
emitRewardOne(_recipient, _amount);
}
function rewardBytesVaultOne(address _recipient, uint256 _amount) private {
isCitizen(_recipient);
if (_blacklisted[msg.sender]) revert BlackListed();
uint256 balance = _amount;
uint256 executedVaultTax = balance.mul(vaultTax).div(100 * 1 ether);
BYTES.transferFrom(msg.sender, vault, executedVaultTax);
balance -= executedVaultTax;
BYTES.transferFrom(msg.sender, _recipient, balance);
userRewardsTotal[_recipient] += _amount;
emitRewardOne(_recipient, _amount);
}
function emitRewardOne(address _recipient, uint256 _amount) private {
address[] memory recipient = new address[](1);
recipient[0] = _recipient;
uint256 calculateRewardTwo = _calculateReward[2];
uint256 calculateRewardThree = _calculateReward[3];
uint256 calculateRewardFour = _calculateReward[4];
if (_calculateReward[1] - 1 < _amount && _amount < calculateRewardTwo) {
emit BronzeRewarded(msg.sender, _amount, recipient);
} else {
if (
calculateRewardTwo - 1 < _amount &&
_amount < calculateRewardThree
) {
emit SilverRewarded(msg.sender, _amount, recipient);
} else {
if (
calculateRewardThree - 1 < _amount &&
_amount < calculateRewardFour
) {
emit GoldRewarded(msg.sender, _amount, recipient);
} else {
if (calculateRewardFour - 1 < _amount) {
emit PlatinumRewarded(msg.sender, _amount, recipient);
}
}
}
}
}
function isAddressBlacklisted(
address _address
) external view returns (bool) {
return _blacklisted[_address];
}
function whichReward(
uint256 _amount
) external view returns (string memory) {
if (
_calculateReward[1] - 1 < _amount && _amount < _calculateReward[2]
) {
return "Bronze";
} else {
if (
_calculateReward[2] - 1 < _amount &&
_amount < _calculateReward[3]
) {
return "Silver";
} else {
if (
_calculateReward[3] - 1 < _amount &&
_amount < _calculateReward[4]
) {
return "Gold";
} else {
if (_calculateReward[4] - 1 < _amount) {
return "Platinum";
}
}
}
}
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
{
"compilationTarget": {
"scripts/contracts/NTRewardSystem.sol": "NTRewardSystem"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArrayLenghtsNotEqual","type":"error"},{"inputs":[],"name":"BlackListed","type":"error"},{"inputs":[],"name":"NotAnAdmin","type":"error"},{"inputs":[],"name":"NotDesignedToHandle","type":"error"},{"inputs":[],"name":"PercentagesMaxExceeded","type":"error"},{"inputs":[],"name":"RecipientIsNotACitizen","type":"error"},{"inputs":[],"name":"SplitPercentageHasToEqualOneHundred","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"msgSender","type":"address"},{"indexed":true,"internalType":"address[]","name":"newAdmins","type":"address[]"}],"name":"AdminAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"msgSender","type":"address"},{"indexed":true,"internalType":"address[]","name":"retiredAdmins","type":"address[]"}],"name":"AdminRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountInBytes","type":"uint256"},{"indexed":true,"internalType":"address[]","name":"recipient","type":"address[]"}],"name":"BronzeRewarded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountInBytes","type":"uint256"},{"indexed":true,"internalType":"address[]","name":"recipient","type":"address[]"}],"name":"GoldRewarded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountInBytes","type":"uint256"},{"indexed":true,"internalType":"address[]","name":"recipient","type":"address[]"}],"name":"PlatinumRewarded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountInBytes","type":"uint256"},{"indexed":true,"internalType":"address[]","name":"recipient","type":"address[]"}],"name":"SilverRewarded","type":"event"},{"inputs":[],"name":"BYTES","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_controller","type":"address[]"}],"name":"addAdmins","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"addBlacklistAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"citizenContract","outputs":[{"internalType":"contract ICitizen","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isAddressBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"legacyCitizenContract","outputs":[{"internalType":"contract ILegacyCitizen","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"legacyOuterCitizenContract","outputs":[{"internalType":"contract ILegacyOuterCitizen","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"outerCitizenContract","outputs":[{"internalType":"contract IOuterCitizen","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_controller","type":"address[]"}],"name":"removeAdmins","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"removeBlacklistAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipient","type":"address[]"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256[]","name":"_split","type":"uint256[]"}],"name":"rewardBytes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"rewardBytesOne","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipient","type":"address[]"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256[]","name":"_split","type":"uint256[]"}],"name":"rewardBytesSpecificWithCustomSplit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipient","type":"address[]"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"rewardBytesSpecificWithoutCustomSplit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_BYTES","type":"address"}],"name":"setBYTESContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ICitizen","name":"_citizenContract","type":"address"}],"name":"setCitizenContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ILegacyCitizen","name":"_legacyCitizenContract","type":"address"}],"name":"setLegacyCitizenContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ILegacyOuterCitizen","name":"_legacyOuterCitizenContract","type":"address"}],"name":"setLegacyOuterCitizenContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IOuterCitizen","name":"_outerCitizenContract","type":"address"}],"name":"setOuterCitizenContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_typeOfReward","type":"uint8"},{"internalType":"uint256","name":"_bytesInEther","type":"uint256"}],"name":"setRewardForSpecificReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IStakedCitizen","name":"_stakedCitizenContract","type":"address"}],"name":"setStakedCitizenContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newVault","type":"address"}],"name":"setVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newTax","type":"uint256"}],"name":"setVaultTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakedCitizenContract","outputs":[{"internalType":"contract IStakedCitizen","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleVaultActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userRewardsTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultTax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"whichReward","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]