文件 1 的 1:RewardPoolTokens.sol
pragma solidity 0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
this;
return msg.data;
}
}
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);
}
interface IERC20Metadata is IERC20{
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
_balances[to] += amount;
}
emit Transfer(from, to, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_totalSupply += amount;
unchecked {
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
}
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
}
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() external virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(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 functionCallWithValue(target, data, 0, "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");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, 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) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
}
interface ILpPair {
function sync() external;
}
interface IDexRouter {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function swapExactTokensForETHSupportingFeeOnTransferTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}
interface IDexFactory {
function createPair(address tokenA, address tokenB) external returns (address pair);
}
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, 'SafeMath: addition overflow');
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, 'SafeMath: subtraction overflow');
}
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, 'SafeMath: multiplication overflow');
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, 'SafeMath: division by zero');
}
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, 'SafeMath: modulo by zero');
}
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x < y ? x : y;
}
function sqrt(uint256 y) internal pure returns (uint256 z) {
if (y > 3) {
z = y;
uint256 x = y / 2 + 1;
while (x < z) {
z = x;
x = (y / x + x) / 2;
}
} else if (y != 0) {
z = 1;
}
}
}
library SafeMathInt {
int256 private constant MIN_INT256 = int256(1) << 255;
int256 private constant MAX_INT256 = ~(int256(1) << 255);
function mul(int256 a, int256 b) internal pure returns (int256) {
int256 c = a * b;
require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256));
require((b == 0) || (c / b == a));
return c;
}
function div(int256 a, int256 b) internal pure returns (int256) {
require(b != -1 || a != MIN_INT256);
return a / b;
}
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a));
return c;
}
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && c < a));
return c;
}
function abs(int256 a) internal pure returns (int256) {
require(a != MIN_INT256);
return a < 0 ? -a : a;
}
function toUint256Safe(int256 a) internal pure returns (uint256) {
require(a >= 0);
return uint256(a);
}
}
library SafeMathUint {
function toInt256Safe(uint256 a) internal pure returns (int256) {
int256 b = int256(a);
require(b >= 0);
return b;
}
}
contract RewardPoolETH is Ownable {
using SafeMath for uint256;
using SafeMathUint for uint256;
using SafeMathInt for int256;
event Claim(address indexed account, uint256 amount, bool indexed automatic);
event DividendsDistributed(
address indexed from,
uint256 weiAmount
);
event DividendWithdrawn(
address indexed to,
uint256 weiAmount
);
mapping (address => bool) public authorized;
uint256 public fee;
address public feeReceiver;
PoolInfo public poolInfo;
string public poolName;
struct PoolInfo {
uint64 poolStartTime;
uint48 poolDuration;
uint64 payoutFrequency;
uint64 lastPayout;
uint8 totalPayouts;
}
uint256 constant internal magnitude = 2**128;
uint256 internal magnifiedDividendPerShare;
mapping(address => int256) internal magnifiedDividendCorrections;
mapping(address => uint256) internal withdrawnDividends;
mapping (address => uint256) public holderPoints;
uint256 public totalPoints;
uint256 public totalDividendsDistributed;
uint256 public totalForDistribution;
constructor(address _feeReceiver, uint256 _fee, string memory _poolName, uint64 _poolStartTime, uint48 _poolDuration, uint64 _payoutFrequency, address _pointSetter){
PoolInfo memory poolInfoMem;
fee = _fee;
feeReceiver = _feeReceiver;
require(_poolDuration % _payoutFrequency == 0, "Duration must be evenly divisible by payout frequency");
poolName = _poolName;
poolInfoMem.poolDuration = _poolDuration;
poolInfoMem.poolStartTime = _poolStartTime;
poolInfoMem.payoutFrequency = _payoutFrequency;
poolInfoMem.lastPayout = _poolStartTime;
poolInfoMem.totalPayouts = uint8(_poolDuration / _payoutFrequency);
poolInfo = poolInfoMem;
authorized[_pointSetter] = true;
}
modifier onlyAuthorized(){
require(authorized[msg.sender] || msg.sender == owner(), "Not Authorized");
_;
}
function setAuthorized(address _wallet, bool _authorized) external onlyOwner {
authorized[_wallet] = _authorized;
}
receive() external payable {
uint256 amountForFee;
if(fee > 0){
amountForFee = msg.value * fee / 100;
(bool success,) = feeReceiver.call{value: amountForFee}("");
require(success, "Distribution failed");
}
totalForDistribution += msg.value - amountForFee;
}
function distributeDividends() external onlyAuthorized {
PoolInfo memory poolInfoMem = poolInfo;
require(totalPoints > 0, "No shares to distribute to");
require(block.timestamp >= poolInfoMem.payoutFrequency + poolInfoMem.lastPayout, "Too early for distribution");
uint256 payouts = (block.timestamp - poolInfoMem.lastPayout) / poolInfoMem.payoutFrequency;
uint256 amountToAdd = totalForDistribution * payouts / poolInfoMem.totalPayouts;
poolInfoMem.lastPayout += uint64(payouts * poolInfoMem.payoutFrequency);
poolInfo = poolInfoMem;
if(amountToAdd + totalDividendsDistributed > totalForDistribution){
amountToAdd = totalForDistribution - totalDividendsDistributed;
}
if(amountToAdd > 0){
magnifiedDividendPerShare = magnifiedDividendPerShare.add(
(amountToAdd).mul(magnitude) / totalPoints
);
emit DividendsDistributed(msg.sender, amountToAdd);
totalDividendsDistributed = totalDividendsDistributed.add(amountToAdd);
}
}
function withdrawDividend() external {
_withdrawDividendOfUser(payable(msg.sender));
}
function _withdrawDividendOfUser(address payable user) internal returns (uint256) {
uint256 _withdrawableDividend = withdrawableDividendOf(user);
if (_withdrawableDividend > 0) {
withdrawnDividends[user] = withdrawnDividends[user].add(_withdrawableDividend);
emit DividendWithdrawn(user, _withdrawableDividend);
(bool success,) = user.call{value: _withdrawableDividend}("");
if(!success) {
withdrawnDividends[user] = withdrawnDividends[user].sub(_withdrawableDividend);
return 0;
}
return _withdrawableDividend;
}
return 0;
}
function dividendOf(address _owner) external view returns(uint256) {
return withdrawableDividendOf(_owner);
}
function withdrawableDividendOf(address _owner) public view returns(uint256) {
return accumulativeDividendOf(_owner).sub(withdrawnDividends[_owner]);
}
function withdrawnDividendOf(address _owner) external view returns(uint256) {
return withdrawnDividends[_owner];
}
function accumulativeDividendOf(address _owner) public view returns(uint256) {
return magnifiedDividendPerShare.mul(holderPoints[_owner]).toInt256Safe()
.add(magnifiedDividendCorrections[_owner]).toUint256Safe() / magnitude;
}
function _increase(address account, uint256 value) internal {
magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account]
.sub( (magnifiedDividendPerShare.mul(value)).toInt256Safe() );
}
function _reduce(address account, uint256 value) internal {
magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account]
.add( (magnifiedDividendPerShare.mul(value)).toInt256Safe() );
}
function _setBalance(address account, uint256 newBalance) internal {
uint256 currentBalance = holderPoints[account];
holderPoints[account] = newBalance;
if(newBalance > currentBalance) {
uint256 increaseAmount = newBalance.sub(currentBalance);
_increase(account, increaseAmount);
totalPoints += increaseAmount;
} else if(newBalance < currentBalance) {
uint256 reduceAmount = currentBalance.sub(newBalance);
_reduce(account, reduceAmount);
totalPoints -= reduceAmount;
}
}
function getAccount(address _account)
public view returns (
address account,
uint256 withdrawableDividends,
uint256 totalDividends,
uint256 balance) {
account = _account;
withdrawableDividends = withdrawableDividendOf(account);
totalDividends = accumulativeDividendOf(account);
balance = holderPoints[account];
}
function setBalance(address payable account, uint256 newBalance) external onlyAuthorized {
_setBalance(account, newBalance);
processAccount(account, true);
}
function setBalances(address payable[] memory accounts, uint256[] memory newBalances) external onlyAuthorized {
address payable account;
uint256 newBalance;
for(uint8 i = 0; i < accounts.length; i++){
account = accounts[i];
newBalance = newBalances[i];
_setBalance(account, newBalance);
processAccount(account, true);
}
}
function processAccount(address payable account, bool automatic) internal returns (bool) {
uint256 amount = _withdrawDividendOfUser(account);
if(amount > 0) {
emit Claim(account, amount, automatic);
return true;
}
return false;
}
function getTotalDividendsDistributed() external view returns (uint256) {
return totalDividendsDistributed;
}
function dividendTokenBalanceOf(address account) public view returns (uint256) {
return holderPoints[account];
}
function getNumberOfDividends() external view returns(uint256) {
return totalPoints;
}
function claim() external {
processAccount(payable(msg.sender), false);
}
}
contract RewardPoolTokens is Ownable {
using SafeMath for uint256;
using SafeMathUint for uint256;
using SafeMathInt for int256;
event Claim(address indexed account, uint256 amount, bool indexed automatic);
event DividendsDistributed(
address indexed from,
uint256 weiAmount
);
event DividendWithdrawn(
address indexed to,
uint256 weiAmount
);
mapping (address => bool) public authorized;
uint256 public fee;
address public feeReceiver;
PoolInfo public poolInfo;
string public poolName;
address public rewardToken;
struct PoolInfo {
uint64 poolStartTime;
uint48 poolDuration;
uint64 payoutFrequency;
uint64 lastPayout;
uint8 totalPayouts;
}
uint256 constant internal magnitude = 2**128;
uint256 internal magnifiedDividendPerShare;
mapping(address => int256) internal magnifiedDividendCorrections;
mapping(address => uint256) internal withdrawnDividends;
mapping (address => uint256) public holderPoints;
uint256 public totalPoints;
uint256 public totalDividendsDistributed;
uint256 public totalForDistribution;
constructor(address _feeReceiver, uint256 _fee, string memory _poolName, uint64 _poolStartTime, uint48 _poolDuration, uint64 _payoutFrequency, address _pointSetter, address _rewardToken){
PoolInfo memory poolInfoMem;
fee = _fee;
feeReceiver = _feeReceiver;
require(_poolDuration % _payoutFrequency == 0, "Duration must be evenly divisible by payout frequency");
poolName = _poolName;
poolInfoMem.poolDuration = _poolDuration;
poolInfoMem.poolStartTime = _poolStartTime;
poolInfoMem.payoutFrequency = _payoutFrequency;
poolInfoMem.lastPayout = _poolStartTime;
poolInfoMem.totalPayouts = uint8(_poolDuration / _payoutFrequency);
poolInfo = poolInfoMem;
authorized[_pointSetter] = true;
require(_rewardToken != address(0), "Reward Token Address not Set");
rewardToken = _rewardToken;
}
modifier onlyAuthorized(){
require(authorized[msg.sender] || msg.sender == owner(), "Not Authorized");
_;
}
function setAuthorized(address _wallet, bool _authorized) external onlyOwner {
authorized[_wallet] = _authorized;
}
function addTokensForDistribution() public onlyAuthorized {
uint256 amountForFee;
uint256 tokenBalance = IERC20(rewardToken).balanceOf(address(this));
require(tokenBalance > 0, "No tokens to distribute");
if(fee > 0 && tokenBalance > totalForDistribution){
amountForFee = (tokenBalance - totalForDistribution) * fee / 100;
if(tokenBalance - amountForFee > totalForDistribution){
totalForDistribution += tokenBalance - amountForFee - totalForDistribution;
SafeERC20.safeTransfer(IERC20(rewardToken), feeReceiver, amountForFee);
}
}
}
function distributeDividends() external onlyAuthorized {
PoolInfo memory poolInfoMem = poolInfo;
require(totalPoints > 0, "No shares to distribute to");
require(block.timestamp >= poolInfoMem.payoutFrequency + poolInfoMem.lastPayout, "Too early for distribution");
uint256 payouts = (block.timestamp - poolInfoMem.lastPayout) / poolInfoMem.payoutFrequency;
uint256 amountToAdd = totalForDistribution * payouts / poolInfoMem.totalPayouts;
poolInfoMem.lastPayout += uint64(payouts * poolInfoMem.payoutFrequency);
poolInfo = poolInfoMem;
if(amountToAdd + totalDividendsDistributed > totalForDistribution){
amountToAdd = totalForDistribution - totalDividendsDistributed;
}
if(amountToAdd > 0){
magnifiedDividendPerShare = magnifiedDividendPerShare.add(
(amountToAdd).mul(magnitude) / totalPoints
);
emit DividendsDistributed(msg.sender, amountToAdd);
totalDividendsDistributed = totalDividendsDistributed.add(amountToAdd);
}
}
function withdrawDividend() external {
_withdrawDividendOfUser(payable(msg.sender));
}
function _withdrawDividendOfUser(address payable user) internal returns (uint256) {
uint256 _withdrawableDividend = withdrawableDividendOf(user);
if (_withdrawableDividend > 0) {
withdrawnDividends[user] = withdrawnDividends[user].add(_withdrawableDividend);
emit DividendWithdrawn(user, _withdrawableDividend);
SafeERC20.safeTransfer(IERC20(rewardToken), user, _withdrawableDividend);
}
return 0;
}
function dividendOf(address _owner) external view returns(uint256) {
return withdrawableDividendOf(_owner);
}
function withdrawableDividendOf(address _owner) public view returns(uint256) {
return accumulativeDividendOf(_owner).sub(withdrawnDividends[_owner]);
}
function withdrawnDividendOf(address _owner) external view returns(uint256) {
return withdrawnDividends[_owner];
}
function accumulativeDividendOf(address _owner) public view returns(uint256) {
return magnifiedDividendPerShare.mul(holderPoints[_owner]).toInt256Safe()
.add(magnifiedDividendCorrections[_owner]).toUint256Safe() / magnitude;
}
function _increase(address account, uint256 value) internal {
magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account]
.sub( (magnifiedDividendPerShare.mul(value)).toInt256Safe() );
}
function _reduce(address account, uint256 value) internal {
magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account]
.add( (magnifiedDividendPerShare.mul(value)).toInt256Safe() );
}
function _setBalance(address account, uint256 newBalance) internal {
uint256 currentBalance = holderPoints[account];
holderPoints[account] = newBalance;
if(newBalance > currentBalance) {
uint256 increaseAmount = newBalance.sub(currentBalance);
_increase(account, increaseAmount);
totalPoints += increaseAmount;
} else if(newBalance < currentBalance) {
uint256 reduceAmount = currentBalance.sub(newBalance);
_reduce(account, reduceAmount);
totalPoints -= reduceAmount;
}
}
function getAccount(address _account)
public view returns (
address account,
uint256 withdrawableDividends,
uint256 totalDividends,
uint256 balance) {
account = _account;
withdrawableDividends = withdrawableDividendOf(account);
totalDividends = accumulativeDividendOf(account);
balance = holderPoints[account];
}
function setBalance(address payable account, uint256 newBalance) external onlyAuthorized {
if(totalForDistribution == 0){
addTokensForDistribution();
}
_setBalance(account, newBalance);
processAccount(account, true);
}
function setBalances(address payable[] memory accounts, uint256[] memory newBalances) external onlyAuthorized {
if(totalForDistribution == 0){
addTokensForDistribution();
}
address payable account;
uint256 newBalance;
for(uint8 i = 0; i < accounts.length; i++){
account = accounts[i];
newBalance = newBalances[i];
_setBalance(account, newBalance);
processAccount(account, true);
}
}
function processAccount(address payable account, bool automatic) internal returns (bool) {
uint256 amount = _withdrawDividendOfUser(account);
if(amount > 0) {
emit Claim(account, amount, automatic);
return true;
}
return false;
}
function getTotalDividendsDistributed() external view returns (uint256) {
return totalDividendsDistributed;
}
function dividendTokenBalanceOf(address account) public view returns (uint256) {
return holderPoints[account];
}
function getNumberOfDividends() external view returns(uint256) {
return totalPoints;
}
function claim() external {
processAccount(payable(msg.sender), false);
}
}
contract ViralXRewardPoolFactory is Ownable {
address public feeReceiverETH;
address public feeReceiverTokens;
uint256 public fee;
address public pointSetter;
address[] public rewardPools;
event ETHRewardPoolCreated(address rewardPool);
event TokensRewardPoolCreated(address rewardPool);
constructor(address _feeReceiverETH, address _feeReceiverTokens, uint256 _fee, address _pointSetter){
feeReceiverETH = _feeReceiverETH;
feeReceiverTokens = _feeReceiverTokens;
fee = _fee;
pointSetter = _pointSetter;
}
function createETHRewardPool(string memory _poolName, uint64 _poolStartTime, uint48 _poolDuration, uint64 _payoutFrequency) external onlyOwner {
RewardPoolETH newPool = new RewardPoolETH(feeReceiverETH, fee, _poolName, _poolStartTime, _poolDuration, _payoutFrequency, pointSetter);
rewardPools.push(address(newPool));
newPool.transferOwnership(msg.sender);
emit ETHRewardPoolCreated(address(newPool));
}
function createTokenRewardPool(string memory _poolName, uint64 _poolStartTime, uint48 _poolDuration, uint64 _payoutFrequency, address _rewardToken) external onlyOwner {
RewardPoolTokens newPool = new RewardPoolTokens(feeReceiverTokens, fee, _poolName, _poolStartTime, _poolDuration, _payoutFrequency, pointSetter, _rewardToken);
rewardPools.push(address(newPool));
newPool.transferOwnership(msg.sender);
emit TokensRewardPoolCreated(address(newPool));
}
function updateFeeReceiverETH(address _newAddress) external onlyOwner {
require(_newAddress != address(0), "Zero Address");
feeReceiverETH = _newAddress;
}
function updateFeeReceiverTokens(address _newAddress) external onlyOwner {
require(_newAddress != address(0), "Zero Address");
feeReceiverTokens = _newAddress;
}
function updatePointSetter(address _newAddress) external onlyOwner {
require(_newAddress != address(0), "Zero Address");
pointSetter = _newAddress;
}
function updateFee(uint256 _newFee) external onlyOwner {
require(_newFee <= 20, "Fee must be 0-20%");
fee = _newFee;
}
}