Skip to content

Instantly share code, notes, and snippets.

@korrio
Created December 9, 2021 03:51
Show Gist options
  • Save korrio/6a74d4219e41b5daca236a1a501aeab7 to your computer and use it in GitHub Desktop.
Save korrio/6a74d4219e41b5daca236a1a501aeab7 to your computer and use it in GitHub Desktop.
BonusReward.sol
pragma solidity ^0.6.12;
library SafeMath {
/**
* @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) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @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 sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @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) {
// 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 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts 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) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts 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) {
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts 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 mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
interface IBEP20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the token decimals.
*/
function decimals() external view returns (uint8);
/**
* @dev Returns the token symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the token name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the bep token owner.
*/
function getOwner() external view returns (address);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address _owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
/**
* @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() public {
_setOwner(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
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 {
_setOwner(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");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
contract BonusReward is Ownable {
using SafeMath for uint256;
mapping(address => uint256) private _balances;
// customize to lock reward 100% deposited and release in 100days
uint256 private _rewardLock = 10000; // lock 100%
uint256 private _totalBlockRelease = 100 * 24 * 60 * 60 / 3; // BKC Blocktime 5 sec
mapping(address => uint256) public _balancesLock;
mapping(address => uint256) public _rewardPerBlock;
mapping(address => uint256) public _lastClaimBlock;
mapping(address => uint256) public _endClaimBlock;
IBEP20 public JUTC;
IBEP20 public ROYX;
address public dev;
// constructor (address JUTCaddress, address ROYXaddress,address _devAddr) public {
// JUTC = IBEP20(JUTCaddress); // 0x5e7d3c2045c914316f26c1f5ad35c16aa4c92acf
// ROYX = IBEP20(ROYXaddress); // 0x47199d51a9f0dd669585f4ac2c327dac699289fd
// dev = address(_devAddr); // 0x3eaDA1aAd931bb956e29563fB5f35ad27C1B7bbE
// }
constructor () public {
JUTC = IBEP20(0xB0306E9186F2a6288901B573BD9118D123e5Ee53); // 0x5e7d3c2045c914316f26c1f5ad35c16aa4c92acf
ROYX = IBEP20(0xb69c883e7711137fE835628F78f9b9678b85B30A); // 0x47199d51a9f0dd669585f4ac2c327dac699289fd
dev = address(0x3eaDA1aAd931bb956e29563fB5f35ad27C1B7bbE); // 0x3eaDA1aAd931bb956e29563fB5f35ad27C1B7bbE
}
/**
* Harvest reward holding system (Algorithm sarun release)
*
* After Harvest, you will get the rewards as following:
* - 30% of your rewards will return to your wallet immediately.
* - 70% of your remaining rewards must be divided by 7 days and remaining reward renew to 7 days everytime reward harvested again.
*/
// onlyOwner is MasterChef can setRewardLock
function setRewardLock(uint256 lock) public onlyOwner {
require(lock <= 10000, "lock: invalid reward lock");
_rewardLock = lock;
}
// onlyOwner is MasterChef can setTotalBlockRelease
function setTotalBlockRelease(uint256 totalBlockRelease) public onlyOwner {
_totalBlockRelease = totalBlockRelease;
}
// onlyOwner is MasterChef to transferWithLock
// function transferWithLock(address recipient, uint256 amount) public onlyOwner returns (bool) {
// require(amount > 0, "amount: invalid amount");
// _transferWithLock(_msgSender(), recipient, amount);
// return true;
// }
function withdrawROYX() public onlyOwner {
ROYX.transferFrom(address(this),dev,ROYX.balanceOf(address(this)));
}
function withdrawJUTC() public onlyOwner {
JUTC.transferFrom(address(this),dev,JUTC.balanceOf(address(this)));
}
function depositROYX(uint256 amountROYX) public {
require(amountROYX > 0, "amount: invalid amount");
ROYX.transferFrom(msg.sender,dev,amountROYX); // 100,000 ROYX // checked
uint256 amountJUTC = amountROYX.div(125); // 100% Get 8,000 instantly checked
JUTC.transfer(msg.sender,amountJUTC); // checked
// WIP
uint256 amountJUTCLock = getBonus(amountROYX); // 400%
depositJUTCLock(amountJUTCLock);
}
function depositJUTCLock(uint256 amountJUTC) public {
require(amountJUTC > 0, "amount: invalid amount");
// ROYX.transfer(address(this),amountROYX);
_transferWithLockOriginal(msg.sender,address(this),amountJUTC);
// ROYX.transfer(address(this),amountJUTC);
// JUTC.transferFrom(dev,address(this),amountJUTC);
}
function getBonus(uint256 amountROYX) public pure returns(uint256) {
uint256 amountJUTC = amountROYX.div(125).mul(4); // 500%
return amountJUTC;
}
// Call when migrate
function _transferWithLockOriginal (address sender,address recipient,uint256 amount) internal {
require(sender != address(0), 'BEP20: transfer from the zero address');
require(recipient != address(0), 'BEP20: transfer to the zero address');
// claim locked reward
_claimRewardLock(sender);
uint256 _amountLock = amount;
// uint256 _amount = 0;
// _balances[sender] = _balances[sender].sub(amount, 'BEP20: transfer amount exceeds balance');
// _balances[recipient] = _balances[recipient].add(_amount);
// update lock balance
_balancesLock[sender] = _balancesLock[sender].add(_amountLock);
_lastClaimBlock[sender] = block.number;
_endClaimBlock[sender] = block.number.add(_totalBlockRelease); // renew last claim block
_rewardPerBlock[sender] = _balancesLock[sender].mul(10000).div(_totalBlockRelease);
// JUTC.transferFrom(msg.sender,address(this),amount);
// emit Transfer(sender, recipient, amount);
}
function claimRewardLock() public {
_claimRewardLock(_msgSender());
}
function _claimRewardLock(address account) internal {
uint256 release = getRewardLockToClaim(account);
if (release > 0) {
uint256 remain = _balancesLock[account].sub(release);
if (_endClaimBlock[account] < block.number) {
_balances[account] = _balances[account].add(_balancesLock[account]);
_balancesLock[account] = 0;
} else {
_balances[account] = _balances[account].add(release);
_balancesLock[account] = remain;
}
// set last claim block
_lastClaimBlock[account] = block.number;
// transfer
JUTC.transfer(msg.sender,release);
}
}
function getCurrentBlock() public view returns (uint) {
return block.number;
}
function getRewardLockToClaim(address account) public view returns (uint256) {
if (block.number > _endClaimBlock[account]) {
return _balancesLock[account];
} else {
return (block.number.sub(_lastClaimBlock[account])).mul(_rewardPerBlock[account]).div(10000);
}
}
function getTotalRewardLock(address account) public view returns (uint256) {
return _balancesLock[account];
}
function getLastClaimBlock(address account) public view returns (uint256) {
return _lastClaimBlock[account];
}
function getEndClaimBlock(address account) public view returns (uint256) {
return _endClaimBlock[account];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment