From 64ffdf99f1c5e522f887341939065f89576fb909 Mon Sep 17 00:00:00 2001 From: illjewminati Date: Sat, 13 Jan 2024 19:10:30 +0700 Subject: [PATCH] changes --- README.md | 6 - contract.sol | 968 ++++++----------------------------------------- stake/30day.html | 719 ----------------------------------- 3 files changed, 113 insertions(+), 1580 deletions(-) delete mode 100644 stake/30day.html diff --git a/README.md b/README.md index 1918db0..e69de29 100644 --- a/README.md +++ b/README.md @@ -1,6 +0,0 @@ -# staking #staking platform #tokenstaking -Staking platform for any token ERC20 - -Watch video how to edit: https://youtu.be/LoS2TuVlQKA - -Join my telegram: https://t.me/automatecrypto diff --git a/contract.sol b/contract.sol index 268d87a..27034ad 100644 --- a/contract.sol +++ b/contract.sol @@ -1,911 +1,169 @@ -//SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.11; - -//import "@nomiclabs/buidler/console.sol"; - -/* - * @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 GSN 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. - */ -contract Context { - // Empty internal constructor, to prevent people from mistakenly deploying - // an instance of this contract, which should be used via inheritance. - constructor() {} - - function _msgSender() internal view returns (address payable) { - return payable(msg.sender); - } +// SPDX-License-Identifier: MIT - function _msgData() internal view returns (bytes memory) { - this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 - 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. - */ -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() { - address msgSender = _msgSender(); - _owner = msgSender; - emit OwnershipTransferred(address(0), msgSender); - } - /** - * @dev Returns the address of the current owner. - */ - function owner() public view 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 onlyOwner { - emit OwnershipTransferred(_owner, address(0)); - _owner = 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 onlyOwner { - _transferOwnership(newOwner); - } - /** - * @dev Transfers ownership of the contract to a new account (`newOwner`). - */ - function _transferOwnership(address newOwner) internal { - require(newOwner != address(0), 'Ownable: new owner is the zero address'); - emit OwnershipTransferred(_owner, newOwner); - _owner = newOwner; - } -} -/** - * @dev Wrappers over Solidity's arithmetic operations with added overflow - * checks. - * - * Arithmetic operations in Solidity wrap on overflow. This can easily result - * in bugs, because programmers usually assume that an overflow raises an - * error, which is the standard behavior in high level programming languages. - * `SafeMath` restores this intuition by reverting the transaction when an - * operation overflows. - * - * Using this library instead of the unchecked operations eliminates an entire - * class of bugs, so it's recommended to use it always. - */ -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; - } - function min(uint256 x, uint256 y) internal pure returns (uint256 z) { - z = x < y ? x : y; - } +pragma solidity ^0.8.0; - // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) - 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; - } - } -} +import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/974c534210ab3347bdaa45f0f07cfe298a8a6866/contracts/utils/ReentrancyGuard.sol"; -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. - */ +interface IERC20 { + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 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); -} - -/** - * @title SafeBEP20 - * @dev Wrappers around BEP20 operations that throw on failure (when the token - * contract returns false). Tokens that return no value (and instead revert or - * throw on failure) are also supported, non-reverting calls are assumed to be - * successful. - * To use this library you can add a `using SafeBEP20 for IBEP20;` statement to your contract, - * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. - */ -library SafeBEP20 { - using SafeMath for uint256; - using Address for address; - - function safeTransfer( - IBEP20 token, - address to, - uint256 value - ) internal { - _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); - } - - function safeTransferFrom( - IBEP20 token, - address from, - address to, - uint256 value - ) internal { - _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); - } - - /** - * @dev Deprecated. This function has issues similar to the ones found in - * {IBEP20-approve}, and its usage is discouraged. - * - * Whenever possible, use {safeIncreaseAllowance} and - * {safeDecreaseAllowance} instead. - */ - function safeApprove( - IBEP20 token, - address spender, - uint256 value - ) internal { - // safeApprove should only be called when setting an initial allowance, - // or when resetting it to zero. To increase and decrease it, use - // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' - // solhint-disable-next-line max-line-length - require( - (value == 0) || (token.allowance(address(this), spender) == 0), - 'SafeBEP20: approve from non-zero to non-zero allowance' - ); - _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); - } - - function safeIncreaseAllowance( - IBEP20 token, - address spender, - uint256 value - ) internal { - uint256 newAllowance = token.allowance(address(this), spender).add(value); - _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); - } - - function safeDecreaseAllowance( - IBEP20 token, - address spender, - uint256 value - ) internal { - uint256 newAllowance = token.allowance(address(this), spender).sub( - value, - 'SafeBEP20: decreased allowance below zero' - ); - _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); - } - - /** - * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement - * on the return value: the return value is optional (but if data is returned, it must not be false). - * @param token The token targeted by the call. - * @param data The call data (encoded using abi.encode or one of its variants). - */ - function _callOptionalReturn(IBEP20 token, bytes memory data) private { - // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since - // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that - // the target address contains contract code and also asserts for success in the low-level call. - - bytes memory returndata = address(token).functionCall(data, 'SafeBEP20: low-level call failed'); - if (returndata.length > 0) { - // Return data is optional - // solhint-disable-next-line max-line-length - require(abi.decode(returndata, (bool)), 'SafeBEP20: BEP20 operation did not succeed'); - } - } + function allowance(address owner, address spender) external view returns (uint256); + function balanceOf(address account) external view returns (uint256); } -/** - * @dev Collection of functions related to the address type - */ -library Address { - /** - * @dev Returns true if `account` is a contract. - * - * [IMPORTANT] - * ==== - * It is unsafe to assume that an address for which this function returns - * false is an externally-owned account (EOA) and not a contract. - * - * Among others, `isContract` will return false for the following - * types of addresses: - * - * - an externally-owned account - * - a contract in construction - * - an address where a contract will be created - * - an address where a contract lived, but was destroyed - * ==== - */ - function isContract(address account) internal view returns (bool) { - // According to EIP-1052, 0x0 is the value returned for not-yet created accounts - // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned - // for accounts without code, i.e. `keccak256('')` - bytes32 codehash; - bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; - // solhint-disable-next-line no-inline-assembly - assembly { - codehash := extcodehash(account) - } - return (codehash != accountHash && codehash != 0x0); - } - /** - * @dev Replacement for Solidity's `transfer`: sends `amount` wei to - * `recipient`, forwarding all available gas and reverting on errors. - * - * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost - * of certain opcodes, possibly making contracts go over the 2300 gas limit - * imposed by `transfer`, making them unable to receive funds via - * `transfer`. {sendValue} removes this limitation. - * - * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. - * - * IMPORTANT: because control is transferred to `recipient`, care must be - * taken to not create reentrancy vulnerabilities. Consider using - * {ReentrancyGuard} or the - * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. - */ - 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'); - } - - /** - * @dev Performs a Solidity function call using a low level `call`. A - * plain`call` is an unsafe replacement for a function call: use this - * function instead. - * - * If `target` reverts with a revert reason, it is bubbled up by this - * function (like regular Solidity function calls). - * - * Returns the raw returned data. To convert to the expected return value, - * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. - * - * Requirements: - * - * - `target` must be a contract. - * - calling `target` with `data` must not revert. - * - * _Available since v3.1._ - */ - function functionCall(address target, bytes memory data) internal returns (bytes memory) { - return functionCall(target, data, 'Address: low-level call failed'); - } +contract MagicInternetStakers is ReentrancyGuard { + IERC20 public immutable token; - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with - * `errorMessage` as a fallback revert reason when `target` reverts. - * - * _Available since v3.1._ - */ - function functionCall( - address target, - bytes memory data, - string memory errorMessage - ) internal returns (bytes memory) { - return _functionCallWithValue(target, data, 0, errorMessage); - } + address private _owner; - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], - * but also transferring `value` wei to `target`. - * - * Requirements: - * - * - the calling contract must have an ETH balance of at least `value`. - * - the called Solidity function must be `payable`. - * - * _Available since v3.1._ - */ - 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'); - } + mapping(address => uint256) public totalStaked; + uint256 public totalRewards; - /** - * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but - * with `errorMessage` as a fallback revert reason when `target` reverts. - * - * _Available since v3.1._ - */ - 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'); - return _functionCallWithValue(target, data, value, errorMessage); - } + // Time constants in seconds (Immutable) + uint256 public constant REWARD_INTERVAL = 3600; // Interval for claiming rewards (1 hour) + uint256 public constant LOCK_PERIOD = 172800; // Lock period before users can unstake (48 hours) + uint256 public constant COOLDOWN_PERIOD = 600; // Cooldown period before users can restake (10 minutes) - 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); - } - } - } + + // Staker struct + struct StakerInfo { + uint256 balance; // Tokens staked by the user + uint256 reward; // Accumulated rewards + uint256 lastClaimTime; // Last time rewards were claimed + uint256 stakeStartTime; // Timestamp when the user started staking + uint256 lastStakeTime; // Timestamp of the last staking action + bool autoCompound; // Flag for auto-compounding rewards } -abstract contract ReentrancyGuard { - // Booleans are more expensive than uint256 or any type that takes up a full - // word because each write operation emits an extra SLOAD to first read the - // slot's contents, replace the bits taken up by the boolean, and then write - // back. This is the compiler's defense against contract upgrades and - // pointer aliasing, and it cannot be disabled. - - // The values being non-zero value makes deployment a bit more expensive, - // but in exchange the refund on every call to nonReentrant will be lower in - // amount. Since refunds are capped to a percentage of the total - // transaction's gas, it is best to keep them low in cases like this one, to - // increase the likelihood of the full refund coming into effect. - uint256 private constant _NOT_ENTERED = 1; - uint256 private constant _ENTERED = 2; - - uint256 private _status; - - constructor() { - _status = _NOT_ENTERED; - } - /** - * @dev Prevents a contract from calling itself, directly or indirectly. - * Calling a `nonReentrant` function from another `nonReentrant` - * function is not supported. It is possible to prevent this from happening - * by making the `nonReentrant` function external, and making it call a - * `private` function that does the actual work. - */ - modifier nonReentrant() { - // On the first call to nonReentrant, _notEntered will be true - require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); + // Mapping from user to staker info + mapping(address => StakerInfo) public stakers; - // Any calls to nonReentrant after this point will fail - _status = _ENTERED; + // Events for logging activities + event Staked(address indexed user, uint256 amount, bool autoCompound); + event Unstaked(address indexed user, uint256 amount); + event RewardClaimed(address indexed user, uint256 reward); + event RewardsDeposited(uint256 amount); + event Withdrawal(address indexed user, uint256 amount); + event AutoCompoundToggled(address indexed user, bool autoCompound); + + + // Modifier for owner-only functions + modifier onlyOwner() { + require(msg.sender == _owner, "Only owner can call this function."); _; - - // By storing the original value once again, a refund is triggered (see - // https://eips.ethereum.org/EIPS/eip-2200) - _status = _NOT_ENTERED; - } -} - -contract ShilaStaking is Ownable, ReentrancyGuard { - using SafeMath for uint256; - using SafeBEP20 for IBEP20; - - // Info of each user. - struct UserInfo { - uint256 amount; // How many LP tokens the user has provided. - uint256 rewardDebt; // Reward debt. See explanation below. } - // Info of each pool. - struct PoolInfo { - IBEP20 lpToken; // Address of LP token contract. - uint256 allocPoint; // How many allocation points assigned to this pool. Tokens to distribute per block. - uint256 lastRewardTimestamp; // Last block number that Tokens distribution occurs. - uint256 accTokensPerShare; // Accumulated Tokens per share, times 1e12. See below. - } - - IBEP20 public immutable stakingToken; - IBEP20 public immutable rewardToken; - mapping (address => uint256) public holderUnlockTime; - - uint256 public totalStaked; - uint256 public apy; - uint256 public lockDuration; - uint256 public exitPenaltyPerc; - - // Info of each pool. - PoolInfo[] public poolInfo; - // Info of each user that stakes LP tokens. - mapping (address => UserInfo) public userInfo; - // Total allocation poitns. Must be the sum of all allocation points in all pools. - uint256 private totalAllocPoint = 0; - - event Deposit(address indexed user, uint256 amount); - event Withdraw(address indexed user, uint256 amount); - event EmergencyWithdraw(address indexed user, uint256 amount); - - constructor( - ) { - stakingToken = IBEP20(0x20c3fa331A385b63EE39137e99d0cF2db142fCe1); - rewardToken = stakingToken; - - apy = 100; - lockDuration = 2 days; - exitPenaltyPerc = 10; - - // staking pool - poolInfo.push(PoolInfo({ - lpToken: stakingToken, - allocPoint: 1000, - lastRewardTimestamp: 21616747, - accTokensPerShare: 0 - })); - - totalAllocPoint = 1000; - - } - - function stopReward() external onlyOwner { - updatePool(0); - apy = 0; + + + // Constructor to initialize the contract + constructor(address tokenAddress) { + _owner = msg.sender; + token = IERC20(tokenAddress); } - function startReward() external onlyOwner { - require(poolInfo[0].lastRewardTimestamp == 21616747, "Can only start rewards once"); - poolInfo[0].lastRewardTimestamp = block.timestamp; + + + // Function for owner to deposit rewards + function depositMiningRewards(uint256 _amount) external onlyOwner { + require(token.transferFrom(msg.sender, address(this), _amount), "Transfer failed."); + totalRewards += _amount; + emit RewardsDeposited(_amount); } - // View function to see pending Reward on frontend. - function pendingReward(address _user) external view returns (uint256) { - PoolInfo storage pool = poolInfo[0]; - UserInfo storage user = userInfo[_user]; - if(pool.lastRewardTimestamp == 21616747){ - return 0; - } - uint256 accTokensPerShare = pool.accTokensPerShare; - uint256 lpSupply = totalStaked; - if (block.timestamp > pool.lastRewardTimestamp && lpSupply != 0) { - uint256 tokenReward = calculateNewRewards().mul(pool.allocPoint).div(totalAllocPoint); - accTokensPerShare = accTokensPerShare.add(tokenReward.mul(1e12).div(lpSupply)); - } - return user.amount.mul(accTokensPerShare).div(1e12).sub(user.rewardDebt); - } + + + // Function for users to stake tokens + function stakeMiners(uint256 _amount, bool _autoCompound) external nonReentrant { + require(_amount > 0, "Amount must be greater than 0."); + require(token.allowance(msg.sender, address(this)) >= _amount, "Insufficient allowance."); + require(token.transferFrom(msg.sender, address(this), _amount), "Transfer failed."); - // Update reward variables of the given pool to be up-to-date. - function updatePool(uint256 _pid) internal { - PoolInfo storage pool = poolInfo[_pid]; - if (block.timestamp <= pool.lastRewardTimestamp) { - return; - } - uint256 lpSupply = totalStaked; - if (lpSupply == 0) { - pool.lastRewardTimestamp = block.timestamp; - return; - } - uint256 tokenReward = calculateNewRewards().mul(pool.allocPoint).div(totalAllocPoint); - pool.accTokensPerShare = pool.accTokensPerShare.add(tokenReward.mul(1e12).div(lpSupply)); - pool.lastRewardTimestamp = block.timestamp; - } + StakerInfo storage staker = stakers[msg.sender]; + staker.balance += _amount; + staker.autoCompound = _autoCompound; + staker.stakeStartTime = block.timestamp; // Update the stake start time - // Update reward variables for all pools. Be careful of gas spending! - function massUpdatePools() public onlyOwner { - uint256 length = poolInfo.length; - for (uint256 pid = 0; pid < length; ++pid) { - updatePool(pid); - } + totalStaked[msg.sender] += _amount; + emit Staked(msg.sender, _amount, _autoCompound); } - // Stake primary tokens - function deposit(uint256 _amount) public nonReentrant { - if(holderUnlockTime[msg.sender] == 0){ - holderUnlockTime[msg.sender] = block.timestamp + lockDuration; - } - PoolInfo storage pool = poolInfo[0]; - UserInfo storage user = userInfo[msg.sender]; - - updatePool(0); - if (user.amount > 0) { - uint256 pending = user.amount.mul(pool.accTokensPerShare).div(1e12).sub(user.rewardDebt); - if(pending > 0) { - require(pending <= rewardsRemaining(), "Cannot withdraw other people's staked tokens. Contact an admin."); - rewardToken.safeTransfer(address(msg.sender), pending); - } - } - uint256 amountTransferred = 0; - if(_amount > 0) { - uint256 initialBalance = pool.lpToken.balanceOf(address(this)); - pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount); - amountTransferred = pool.lpToken.balanceOf(address(this)) - initialBalance; - user.amount = user.amount.add(amountTransferred); - totalStaked += amountTransferred; - } - user.rewardDebt = user.amount.mul(pool.accTokensPerShare).div(1e12); - - emit Deposit(msg.sender, _amount); - } - - // Withdraw primary tokens from STAKING. - - function withdraw() public nonReentrant { - - require(holderUnlockTime[msg.sender] <= block.timestamp, "May not do normal withdraw early"); - - PoolInfo storage pool = poolInfo[0]; - UserInfo storage user = userInfo[msg.sender]; - - uint256 _amount = user.amount; - updatePool(0); - uint256 pending = user.amount.mul(pool.accTokensPerShare).div(1e12).sub(user.rewardDebt); - if(pending > 0) { - require(pending <= rewardsRemaining(), "Cannot withdraw other people's staked tokens. Contact an admin."); - rewardToken.safeTransfer(address(msg.sender), pending); - } - - if(_amount > 0) { - user.amount = 0; - totalStaked -= _amount; - pool.lpToken.safeTransfer(address(msg.sender), _amount); - } - - user.rewardDebt = user.amount.mul(pool.accTokensPerShare).div(1e12); - - if(user.amount > 0){ - holderUnlockTime[msg.sender] = block.timestamp + lockDuration; - } else { - holderUnlockTime[msg.sender] = 0; - } + + + // Function for users to claim rewards + function claimMinerRewards() external nonReentrant { + StakerInfo storage staker = stakers[msg.sender]; + require(block.timestamp >= staker.lastClaimTime + REWARD_INTERVAL, "Reward interval not yet passed."); - emit Withdraw(msg.sender, _amount); - } + uint256 reward = calculateMinerReward(msg.sender); + require(reward > 0, "No rewards available to claim."); + staker.reward += reward; + staker.lastClaimTime = block.timestamp; - // Withdraw without caring about rewards. EMERGENCY ONLY. - function emergencyWithdraw() external nonReentrant { - PoolInfo storage pool = poolInfo[0]; - UserInfo storage user = userInfo[msg.sender]; - uint256 _amount = user.amount; - totalStaked -= _amount; - // exit penalty for early unstakers, penalty held on contract as rewards. - if(holderUnlockTime[msg.sender] >= block.timestamp){ - _amount -= _amount * exitPenaltyPerc / 100; + if (staker.autoCompound) { + staker.balance += reward; // Auto-compound the reward + totalStaked[msg.sender] += reward; } - holderUnlockTime[msg.sender] = 0; - pool.lpToken.safeTransfer(address(msg.sender), _amount); - user.amount = 0; - user.rewardDebt = 0; - emit EmergencyWithdraw(msg.sender, _amount); - } - // Withdraw reward. EMERGENCY ONLY. This allows the owner to migrate rewards to a new staking pool since we are not minting new tokens. - function emergencyWithdrawR(uint256 _amount) external onlyOwner { - require(_amount <= rewardToken.balanceOf(address(this)) - totalStaked, 'not enough tokens to take out'); - rewardToken.safeTransfer(address(msg.sender), _amount); + emit RewardClaimed(msg.sender, reward); } - function clearforeignToken(address tokenAddress, uint256 tokens) external onlyOwner returns (bool success) { - require(tokenAddress != address (rewardToken),"Cannot withdraw reward token"); - if(tokens == 0){ - tokens = IBEP20(tokenAddress).balanceOf(address(this)); - } - return IBEP20(tokenAddress).transfer(msg.sender, tokens); - } + + // Function for users to unstake tokens + function unstakeMiners(uint256 _amount) external nonReentrant { + StakerInfo storage staker = stakers[msg.sender]; + require(_amount > 0 && _amount <= staker.balance, "Invalid unstake amount."); + require(block.timestamp >= staker.lastStakeTime + LOCK_PERIOD, "Lock period has not passed."); - function calculateNewRewards() public view returns (uint256) { - PoolInfo storage pool = poolInfo[0]; - if(pool.lastRewardTimestamp > block.timestamp){ - return 0; - } - return (((block.timestamp - pool.lastRewardTimestamp) * totalStaked) * apy / 100 / 365 days); - } - - function rewardsRemaining() public view returns (uint256){ - return rewardToken.balanceOf(address(this)) - totalStaked; - } - - function updateApy(uint256 newApy) external onlyOwner { - require(newApy <= 10000, "APY must be below 10000%"); - updatePool(0); - apy = newApy; - } - - function updatelockduration(uint256 newlockDuration) external onlyOwner { - require(newlockDuration <= 4838400, "Duration must be below 4 weeks"); - lockDuration = newlockDuration; + staker.balance -= _amount; + totalStaked[msg.sender] -= _amount; + require(token.transfer(msg.sender, _amount), "Transfer failed."); + emit Unstaked(msg.sender, _amount); } - function updateExitPenalty(uint256 newPenaltyPerc) external onlyOwner { - require(newPenaltyPerc <= 30, "May not set higher than 30%"); - exitPenaltyPerc = newPenaltyPerc; + + + // Function to calculate the reward for a user + function calculateMinerReward(address _user) internal view returns (uint256) { + StakerInfo storage staker = stakers[_user]; + if (totalStaked[msg.sender] == 0) return 0; + uint256 stakerShare = staker.balance * totalRewards / totalStaked[msg.sender]; + + // Enhanced reward calculation considering staking duration to incentivize longer staking + uint256 stakingDuration = block.timestamp - staker.stakeStartTime; + return stakerShare * stakingDuration / REWARD_INTERVAL; + } + + + + // Function for users to withdraw their rewards + function withdrawMiningRewards() external nonReentrant { + StakerInfo storage staker = stakers[msg.sender]; + uint256 reward = staker.reward; + require(reward > 0, "No rewards to withdraw."); + + staker.reward = 0; + require(token.transfer(msg.sender, reward), "Transfer failed."); + emit Withdrawal(msg.sender, reward); } } \ No newline at end of file diff --git a/stake/30day.html b/stake/30day.html deleted file mode 100644 index 455460c..0000000 --- a/stake/30day.html +++ /dev/null @@ -1,719 +0,0 @@ - - - - - - - - - - - - - - Shila Inu | 30 Day Lock - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-

Do you want staking for your project but can’t afford the large costs?

-

Stake with us by contacting the team and receive a discount on pricing, alongside excellent exposure!

-
  • -
    Contact Us Today!
    -
  • - -
    -
    - - - - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    Welcome to


    -

    Projects Name


    -

    30 DAY Staking Platform!

    - -

    - JOIN THE TELEGRAM -
    -
    -
    screenshot
    -
    -
    -
    -
    - - -
    -
    - -
    -
    -
    - -
    - -
    Estimated APY : ----
    -
    -
    Total Staked Tokens : ----
    -
    -
    Rewards Remaining In Pool : ----
    -
    -
    Your Locked Tokens : ----
    -
    -
    Your Pending Rewards : ----
    -
    -
    Your $SHIL Tokens : ----
    -
    -
    Your Unlock Date : ----
    -
    -
    - -
    -
    -
    - -
    - -
    - -
    -
    -
    -
    - -
    -
    -
    -
    - - -
    - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -