Source Code
Latest 25 from a total of 2,715 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Withdraw | 17534833 | 302 days ago | IN | 0 ETH | 0.00000014 | ||||
| Withdraw | 15544753 | 348 days ago | IN | 0 ETH | 0.00000091 | ||||
| Withdraw | 14893026 | 363 days ago | IN | 0 ETH | 0.00000047 | ||||
| Withdraw | 14319847 | 376 days ago | IN | 0 ETH | 0.00000016 | ||||
| Withdraw | 14177006 | 380 days ago | IN | 0 ETH | 0.00000072 | ||||
| Withdraw | 14176877 | 380 days ago | IN | 0 ETH | 0.00000051 | ||||
| Withdraw | 13161055 | 403 days ago | IN | 0 ETH | 0.00000057 | ||||
| Withdraw | 13139992 | 404 days ago | IN | 0 ETH | 0.00000008 | ||||
| Withdraw | 12261461 | 424 days ago | IN | 0 ETH | 0.00000139 | ||||
| Withdraw | 12260058 | 424 days ago | IN | 0 ETH | 0.00000078 | ||||
| Withdraw | 12124098 | 427 days ago | IN | 0 ETH | 0.00000039 | ||||
| Withdraw | 12123909 | 427 days ago | IN | 0 ETH | 0.00000036 | ||||
| Withdraw | 12119033 | 427 days ago | IN | 0 ETH | 0.00000032 | ||||
| Withdraw | 11758973 | 436 days ago | IN | 0 ETH | 0.00000107 | ||||
| Withdraw | 11758757 | 436 days ago | IN | 0 ETH | 0.00000123 | ||||
| Withdraw | 11580803 | 440 days ago | IN | 0 ETH | 0.0000003 | ||||
| Withdraw | 11572982 | 440 days ago | IN | 0 ETH | 0.00000044 | ||||
| Withdraw | 11568664 | 440 days ago | IN | 0 ETH | 0.00000053 | ||||
| Withdraw | 11501904 | 442 days ago | IN | 0 ETH | 0.00000123 | ||||
| Withdraw | 11411718 | 444 days ago | IN | 0 ETH | 0.000001 | ||||
| Withdraw | 11276841 | 447 days ago | IN | 0 ETH | 0.00000138 | ||||
| Withdraw | 11169927 | 449 days ago | IN | 0 ETH | 0.0000028 | ||||
| Withdraw | 10927761 | 455 days ago | IN | 0 ETH | 0.00000039 | ||||
| Withdraw | 10927676 | 455 days ago | IN | 0 ETH | 0.00000047 | ||||
| Withdraw | 10513486 | 465 days ago | IN | 0 ETH | 0.00000018 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Dividends
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 1 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
pragma abicoder v2;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
contract Dividends is Ownable, ReentrancyGuard {
using SafeERC20 for IERC20Metadata;
// Whether a limit is set for users
bool public hasUserLimit;
// Accrued token per share
uint256 public accTokenPerShare;
// The block number of the last pool update
uint256 public lastRewardTime;
// The pool limit (0 if none)
uint256 public poolLimitPerUser;
// The precision factor
uint256 public PRECISION_FACTOR;
// The reward token
IERC20Metadata public rewardToken;
// The staked token
IERC20Metadata public stakedToken;
// Info of each user that stakes tokens (stakedToken)
mapping(address => UserInfo) public userInfo;
uint256 public epochTime;
uint256 public epochInitialTime;
mapping(uint256 => Epoch) public epochs;
struct Epoch {
uint256 rewardPerSecond;
uint256 totalAmount;
}
struct UserInfo {
uint256 amount; // How many staked tokens the user has provided
uint256 rewardDebt; // Reward debt
}
event AdminTokenRecovery(address tokenRecovered, uint256 amount);
event Deposit(address indexed user, uint256 amount);
event EmergencyWithdraw(address indexed user, uint256 amount);
event NewRewardPerBlock(uint256 rewardPerBlock);
event NewPoolLimit(uint256 poolLimitPerUser);
event Withdraw(address indexed user, uint256 amount);
event AddEpochReward(uint256 epochNumber, uint256 amount, Epoch epoch);
constructor(
IERC20Metadata _stakedToken,
IERC20Metadata _rewardToken,
uint256 _poolLimitPerUser,
uint256 _epochTime
) Ownable(msg.sender) {
stakedToken = _stakedToken;
rewardToken = _rewardToken;
epochTime = _epochTime;
if (_poolLimitPerUser > 0) {
hasUserLimit = true;
poolLimitPerUser = _poolLimitPerUser;
}
uint256 decimalsRewardToken = uint256(rewardToken.decimals());
require(decimalsRewardToken < 30, "Must be inferior to 30");
PRECISION_FACTOR = uint256(10 ** (uint256(30) - (decimalsRewardToken)));
// Set the lastRewardTime as the startBlock
lastRewardTime = block.timestamp;
}
function initializeEpoch(
uint256 _epochInitialTime,
uint256 _initializeReward
) external onlyOwner {
require(epochInitialTime == 0, "Already initialized");
require(_epochInitialTime > block.timestamp, "Invalid initial time");
epochInitialTime = _epochInitialTime;
uint256 currentEpoch = getEpoch(block.timestamp);
epochs[currentEpoch].totalAmount = _initializeReward;
epochs[currentEpoch].rewardPerSecond =
_initializeReward /
(epochTime + 1);
rewardToken.safeTransferFrom(
address(msg.sender),
address(this),
_initializeReward
);
}
/*
* @notice Deposit staked tokens and collect reward tokens (if any)
* @param _amount: amount to withdraw (in rewardToken)
*/
function deposit(uint256 _amount) external nonReentrant {
UserInfo storage user = userInfo[msg.sender];
if (hasUserLimit) {
require(
_amount + (user.amount) <= poolLimitPerUser,
"User amount above limit"
);
}
_updatePool();
if (user.amount > 0) {
uint256 pending = (user.amount * (accTokenPerShare)) /
(PRECISION_FACTOR) -
(user.rewardDebt);
if (pending > 0) {
rewardToken.safeTransfer(address(msg.sender), pending);
}
}
if (_amount > 0) {
user.amount = user.amount + (_amount);
stakedToken.safeTransferFrom(
address(msg.sender),
address(this),
_amount
);
}
user.rewardDebt =
(user.amount * (accTokenPerShare)) /
(PRECISION_FACTOR);
emit Deposit(msg.sender, _amount);
}
/*
* @notice Withdraw staked tokens and collect reward tokens
* @param _amount: amount to withdraw (in rewardToken)
*/
function withdraw(uint256 _amount) external nonReentrant {
UserInfo storage user = userInfo[msg.sender];
require(user.amount >= _amount, "Amount to withdraw too high");
_updatePool();
uint256 pending = (user.amount * (accTokenPerShare)) /
(PRECISION_FACTOR) -
(user.rewardDebt);
if (_amount > 0) {
user.amount = user.amount - (_amount);
stakedToken.safeTransfer(address(msg.sender), _amount);
}
if (pending > 0) {
rewardToken.safeTransfer(address(msg.sender), pending);
}
user.rewardDebt =
(user.amount * (accTokenPerShare)) /
(PRECISION_FACTOR);
emit Withdraw(msg.sender, _amount);
}
/*
* @notice Withdraw staked tokens without caring about rewards rewards
* @dev Needs to be for emergency.
*/
function emergencyWithdraw() external nonReentrant {
UserInfo storage user = userInfo[msg.sender];
uint256 amountToTransfer = user.amount;
user.amount = 0;
user.rewardDebt = 0;
if (amountToTransfer > 0) {
stakedToken.safeTransfer(address(msg.sender), amountToTransfer);
}
emit EmergencyWithdraw(msg.sender, user.amount);
}
/*
* @notice Stop rewards
* @dev Only callable by owner. Needs to be for emergency.
*/
function emergencyRewardWithdraw(uint256 _amount) external onlyOwner {
rewardToken.safeTransfer(address(msg.sender), _amount);
}
/**
* @notice It allows the admin to recover wrong tokens sent to the contract
* @param _tokenAddress: the address of the token to withdraw
* @param _tokenAmount: the number of tokens to withdraw
* @dev This function is only callable by admin.
*/
function recoverWrongTokens(
address _tokenAddress,
uint256 _tokenAmount
) external onlyOwner {
require(
_tokenAddress != address(stakedToken),
"Cannot be staked token"
);
require(
_tokenAddress != address(rewardToken),
"Cannot be reward token"
);
IERC20Metadata(_tokenAddress).safeTransfer(
address(msg.sender),
_tokenAmount
);
emit AdminTokenRecovery(_tokenAddress, _tokenAmount);
}
/*
* @notice Update pool limit per user
* @dev Only callable by owner.
* @param _hasUserLimit: whether the limit remains forced
* @param _poolLimitPerUser: new pool limit per user
*/
function updatePoolLimitPerUser(
bool _hasUserLimit,
uint256 _poolLimitPerUser
) external onlyOwner {
require(hasUserLimit, "Must be set");
if (_hasUserLimit) {
require(
_poolLimitPerUser > poolLimitPerUser,
"New limit must be higher"
);
poolLimitPerUser = _poolLimitPerUser;
} else {
hasUserLimit = _hasUserLimit;
poolLimitPerUser = 0;
}
emit NewPoolLimit(poolLimitPerUser);
}
function addRewardCurrentEpoch(uint256 _amount) external onlyOwner {
_updatePool();
rewardToken.safeTransferFrom(
address(msg.sender),
address(this),
_amount
);
uint256 currentEpoch = getEpoch(block.timestamp);
uint256 from = block.timestamp;
if (block.timestamp < epochInitialTime) {
from = epochInitialTime;
}
epochs[currentEpoch].totalAmount += _amount;
epochs[currentEpoch].rewardPerSecond +=
_amount /
((currentEpoch + 1) * epochTime + epochInitialTime - from + 1);
emit AddEpochReward(currentEpoch, _amount, epochs[currentEpoch]);
}
function addRewardNextEpoch(uint256 _amount) external onlyOwner {
_updatePool();
rewardToken.safeTransferFrom(
address(msg.sender),
address(this),
_amount
);
uint256 currentEpoch = getEpoch(block.timestamp);
epochs[currentEpoch + 1].totalAmount += _amount;
epochs[currentEpoch + 1].rewardPerSecond =
epochs[currentEpoch + 1].totalAmount /
(epochTime + 1);
emit AddEpochReward(
currentEpoch + 1,
_amount,
epochs[currentEpoch + 1]
);
}
function addRewardEpoch(
uint256 _epoch,
uint256 _amount
) external onlyOwner {
require(
_epoch >= getEpoch(block.timestamp),
"Cannot add reward to past epochs"
);
_updatePool();
rewardToken.safeTransferFrom(
address(msg.sender),
address(this),
_amount
);
epochs[_epoch].totalAmount += _amount;
epochs[_epoch].rewardPerSecond = epochs[_epoch].totalAmount / epochTime;
emit AddEpochReward(_epoch, _amount, epochs[_epoch]);
}
/*
* @notice View function to see pending reward on frontend.
* @param _user: user address
* @return Pending reward for a given user
*/
function pendingReward(address _user) external view returns (uint256) {
UserInfo storage user = userInfo[_user];
uint256 stakedTokenSupply = stakedToken.balanceOf(address(this));
if (block.timestamp > lastRewardTime && stakedTokenSupply != 0) {
uint256 cumulateReward = _getCumulateReward(
lastRewardTime,
block.timestamp
);
uint256 adjustedTokenPerShare = accTokenPerShare +
((cumulateReward * (PRECISION_FACTOR)) / (stakedTokenSupply));
return
(user.amount * (adjustedTokenPerShare)) /
(PRECISION_FACTOR) -
(user.rewardDebt);
} else {
return
(user.amount * (accTokenPerShare)) /
(PRECISION_FACTOR) -
(user.rewardDebt);
}
}
/*
* @notice Update reward variables of the given pool to be up-to-date.
*/
function _updatePool() internal {
if (block.timestamp <= lastRewardTime) {
return;
}
uint256 stakedTokenSupply = stakedToken.balanceOf(address(this));
if (stakedTokenSupply == 0) {
lastRewardTime = block.timestamp;
return;
}
uint256 acumulateReward = _getCumulateReward(
lastRewardTime,
block.timestamp
);
accTokenPerShare =
accTokenPerShare +
((acumulateReward * (PRECISION_FACTOR)) / (stakedTokenSupply));
lastRewardTime = block.timestamp;
}
/*
* @notice Return reward multiplier over the given _from to _to block.
* @param _from: block to start
* @param _to: block to finish
*/
function _getCumulateReward(
uint256 _from,
uint256 _to
) internal view returns (uint256) {
if (_to < epochInitialTime) {
return 0;
}
if (_from < epochInitialTime) {
_from = epochInitialTime;
}
uint256 fromEpoch = getEpoch(_from);
uint256 toEpoch = getEpoch(_to);
uint256 cumulateReward;
for (uint256 i = fromEpoch; i <= toEpoch; i++) {
if (i == toEpoch) {
cumulateReward += (_to - _from) * epochs[i].rewardPerSecond;
} else {
cumulateReward =
cumulateReward +
epochs[i].rewardPerSecond *
(epochTime * (i + 1) + epochInitialTime - _from);
_from = epochInitialTime + (i + 1) * epochTime;
}
}
return cumulateReward;
}
function getEpoch(uint256 _timestamp) public view returns (uint256) {
if (_timestamp < epochInitialTime) {
return 0;
}
return (_timestamp - epochInitialTime) / epochTime;
}
function getNextEpochTime() public view returns (uint256) {
return epochInitialTime + (getEpoch(block.timestamp) + 1) * epochTime;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../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.
*
* The initial owner is set to the address provided by the deployer. 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;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @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 {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling 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 {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_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 v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 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 SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev An operation with an ERC20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @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(IERC20 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);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @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).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// 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 cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error AddressInsufficientBalance(address account);
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedInnerCall();
/**
* @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
/**
* @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 or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {FailedInnerCall} error.
*
* 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.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @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`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
* unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {FailedInnerCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
*/
function _revert(bytes memory returndata) private pure {
// 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
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
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;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
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() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}{
"optimizer": {
"enabled": true,
"runs": 1
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IERC20Metadata","name":"_stakedToken","type":"address"},{"internalType":"contract IERC20Metadata","name":"_rewardToken","type":"address"},{"internalType":"uint256","name":"_poolLimitPerUser","type":"uint256"},{"internalType":"uint256","name":"_epochTime","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epochNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"uint256","name":"rewardPerSecond","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"indexed":false,"internalType":"struct Dividends.Epoch","name":"epoch","type":"tuple"}],"name":"AddEpochReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"tokenRecovered","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AdminTokenRecovery","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"poolLimitPerUser","type":"uint256"}],"name":"NewPoolLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rewardPerBlock","type":"uint256"}],"name":"NewRewardPerBlock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"PRECISION_FACTOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accTokenPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"addRewardCurrentEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"addRewardEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"addRewardNextEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"emergencyRewardWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"epochInitialTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epochTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochs","outputs":[{"internalType":"uint256","name":"rewardPerSecond","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNextEpochTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasUserLimit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epochInitialTime","type":"uint256"},{"internalType":"uint256","name":"_initializeReward","type":"uint256"}],"name":"initializeEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastRewardTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"pendingReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLimitPerUser","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"recoverWrongTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20Metadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakedToken","outputs":[{"internalType":"contract IERC20Metadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_hasUserLimit","type":"bool"},{"internalType":"uint256","name":"_poolLimitPerUser","type":"uint256"}],"name":"updatePoolLimitPerUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b506040516200199c3803806200199c83398101604081905262000034916200021d565b33806200005c57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200006781620001b0565b5060018055600880546001600160a01b038087166001600160a01b0319928316179092556007805492861692909116919091179055600a8190558115620000bb576002805460ff1916600117905560058290555b6007546040805163313ce56760e01b815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa15801562000106573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200012c919062000265565b60ff169050601e8110620001835760405162461bcd60e51b815260206004820152601660248201527f4d75737420626520696e666572696f7220746f20333000000000000000000000604482015260640162000053565b6200019081601e620002a7565b6200019d90600a620003c0565b60065550504260045550620003ce915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200021857600080fd5b919050565b600080600080608085870312156200023457600080fd5b6200023f8562000200565b93506200024f6020860162000200565b6040860151606090960151949790965092505050565b6000602082840312156200027857600080fd5b815160ff811681146200028a57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b81810381811115620002bd57620002bd62000291565b92915050565b600181815b8085111562000304578160001904821115620002e857620002e862000291565b80851615620002f657918102915b93841c9390800290620002c8565b509250929050565b6000826200031d57506001620002bd565b816200032c57506000620002bd565b8160018114620003455760028114620003505762000370565b6001915050620002bd565b60ff84111562000364576200036462000291565b50506001821b620002bd565b5060208310610133831016604e8410600b841016171562000395575081810a620002bd565b620003a18383620002c3565b8060001904821115620003b857620003b862000291565b029392505050565b60006200028a83836200030c565b6115be80620003de6000396000f3fe608060405234801561001057600080fd5b50600436106101495760003560e01c806317a493bd1461014e5780631959a0021461016357806324635216146101a45780632e1a7d4d146101b75780633279beab146101ca5780633f138d4b146101dd5780635053e461146101f0578063596293301461020757806366fe9f8a1461020f578063715018a6146102185780637d82ce3914610220578063880e21fa146102335780638da5cb5b146102465780638f6629151461025b5780639231cf741461026457806392e8990e1461026d578063a0b409051461028a578063a16b15fc1461029d578063b6b55f25146102a6578063bc0bc6ba146102b9578063c6b61e4c146102cc578063cc7a262e146102f3578063ccd34cd514610306578063db2e21bc1461030f578063f2fde38b14610317578063f40f0f521461032a578063f7c618c11461033d575b600080fd5b61016161015c36600461135f565b610350565b005b61018a61017136600461139d565b6009602052600090815260409020805460019091015482565b604080519283526020830191909152015b60405180910390f35b6101616101b23660046113b8565b610457565b6101616101c53660046113b8565b610561565b6101616101d83660046113b8565b6106ae565b6101616101eb3660046113d1565b6106cd565b6101f9600a5481565b60405190815260200161019b565b6101f96107c8565b6101f960055481565b6101616107fd565b61016161022e36600461135f565b610811565b6101616102413660046113b8565b610911565b61024e610a24565b60405161019b91906113fb565b6101f960035481565b6101f960045481565b60025461027a9060ff1681565b604051901515815260200161019b565b61016161029836600461141d565b610a33565b6101f9600b5481565b6101616102b43660046113b8565b610b1e565b6101f96102c73660046113b8565b610c84565b61018a6102da3660046113b8565b600c602052600090815260409020805460019091015482565b60085461024e906001600160a01b031681565b6101f960065481565b610161610cb8565b61016161032536600461139d565b610d3c565b6101f961033836600461139d565b610d77565b60075461024e906001600160a01b031681565b610358610eb9565b61036142610c84565b8210156103b55760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f74206164642072657761726420746f20706173742065706f63687360448201526064015b60405180910390fd5b6103bd610eeb565b6007546103d5906001600160a01b0316333084610fba565b6000828152600c6020526040812060010180548392906103f6908490611451565b9091555050600a546000838152600c602052604090206001015461041a9190611464565b6000838152600c602052604090819020918255516000805160206115698339815191529161044b9185918591611486565b60405180910390a15050565b61045f610eb9565b610467610eeb565b60075461047f906001600160a01b0316333084610fba565b600061048a42610c84565b905081600c600061049c846001611451565b815260200190815260200160002060010160008282546104bc9190611451565b9091555050600a546104cf906001611451565b600c60006104de846001611451565b8152602001908152602001600020600101546104fa9190611464565b600c6000610509846001611451565b8152602081019190915260400160002055600080516020611569833981519152610534826001611451565b83600c6000610544866001611451565b815260200190815260200160002060405161044b93929190611486565b610569611027565b33600090815260096020526040902080548211156105c75760405162461bcd60e51b815260206004820152601b60248201527a082dadeeadce840e8de40eed2e8d0c8e4c2ee40e8dede40d0d2ced602b1b60448201526064016103ac565b6105cf610eeb565b6000816001015460065460035484600001546105eb91906114a7565b6105f59190611464565b6105ff91906114be565b9050821561062d5781546106149084906114be565b825560085461062d906001600160a01b03163385611051565b801561064a5760075461064a906001600160a01b03163383611051565b600654600354835461065c91906114a7565b6106669190611464565b600183015560405183815233907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243649060200160405180910390a250506106ab60018055565b50565b6106b6610eb9565b6007546106ab906001600160a01b03163383611051565b6106d5610eb9565b6008546001600160a01b039081169083160361072c5760405162461bcd60e51b815260206004820152601660248201527521b0b73737ba1031329039ba30b5b2b2103a37b5b2b760511b60448201526064016103ac565b6007546001600160a01b03908116908316036107835760405162461bcd60e51b815260206004820152601660248201527521b0b73737ba103132903932bbb0b932103a37b5b2b760511b60448201526064016103ac565b6107976001600160a01b0383163383611051565b7f74545154aac348a3eac92596bd1971957ca94795f4e954ec5f613b55fab78129828260405161044b9291906114d1565b6000600a546107d642610c84565b6107e1906001611451565b6107eb91906114a7565b600b546107f89190611451565b905090565b610805610eb9565b61080f6000611077565b565b610819610eb9565b600b541561085f5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b60448201526064016103ac565b4282116108a55760405162461bcd60e51b8152602060048201526014602482015273496e76616c696420696e697469616c2074696d6560601b60448201526064016103ac565b600b82905560006108b542610c84565b6000818152600c602052604090206001908101849055600a549192506108db9190611451565b6108e59083611464565b6000828152600c602052604090205560075461090c906001600160a01b0316333085610fba565b505050565b610919610eb9565b610921610eeb565b600754610939906001600160a01b0316333084610fba565b600061094442610c84565b600b5490915042908110156109585750600b545b6000828152600c602052604081206001018054859290610979908490611451565b9091555050600b54600a54829190610992856001611451565b61099c91906114a7565b6109a69190611451565b6109b091906114be565b6109bb906001611451565b6109c59084611464565b6000838152600c6020526040812080549091906109e3908490611451565b90915550506000828152600c602052604090819020905160008051602061156983398151915291610a179185918791611486565b60405180910390a1505050565b6000546001600160a01b031690565b610a3b610eb9565b60025460ff16610a7b5760405162461bcd60e51b815260206004820152600b60248201526a135d5cdd081899481cd95d60aa1b60448201526064016103ac565b8115610ad7576005548111610acd5760405162461bcd60e51b81526020600482015260186024820152772732bb903634b6b4ba1036bab9ba103132903434b3b432b960411b60448201526064016103ac565b6005819055610aeb565b6002805460ff191683151517905560006005555b7f241f67ee5f41b7a5cabf911367329be7215900f602ebfc47f89dce2a6bcd847c60055460405161044b91815260200190565b610b26611027565b33600090815260096020526040902060025460ff1615610b97576005548154610b4f9084611451565b1115610b975760405162461bcd60e51b8152602060048201526017602482015276155cd95c88185b5bdd5b9d0818589bdd99481b1a5b5a5d604a1b60448201526064016103ac565b610b9f610eeb565b805415610bf757600081600101546006546003548460000154610bc291906114a7565b610bcc9190611464565b610bd691906114be565b90508015610bf557600754610bf5906001600160a01b03163383611051565b505b8115610c24578054610c0a908390611451565b8155600854610c24906001600160a01b0316333085610fba565b6006546003548254610c3691906114a7565b610c409190611464565b600182015560405182815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2506106ab60018055565b6000600b54821015610c9857506000919050565b600a54600b54610ca890846114be565b610cb29190611464565b92915050565b610cc0611027565b33600090815260096020526040812080548282556001820192909255908015610cfa57600854610cfa906001600160a01b03163383611051565b815460405190815233907f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd96959060200160405180910390a2505061080f60018055565b610d44610eb9565b6001600160a01b038116610d6e576000604051631e4fbdf760e01b81526004016103ac91906113fb565b6106ab81611077565b6001600160a01b0380821660009081526009602052604080822060085491516370a0823160e01b8152929390928492909116906370a0823190610dbe9030906004016113fb565b602060405180830381865afa158015610ddb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dff91906114ea565b905060045442118015610e1157508015155b15610e86576000610e24600454426110c7565b905060008260065483610e3791906114a7565b610e419190611464565b600354610e4e9190611451565b90508360010154600654828660000154610e6891906114a7565b610e729190611464565b610e7c91906114be565b9695505050505050565b60018201546006546003548454610e9d91906114a7565b610ea79190611464565b610eb191906114be565b949350505050565b33610ec2610a24565b6001600160a01b03161461080f573360405163118cdaa760e01b81526004016103ac91906113fb565b6004544211610ef657565b6008546040516370a0823160e01b81526000916001600160a01b0316906370a0823190610f279030906004016113fb565b602060405180830381865afa158015610f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6891906114ea565b905080600003610f79575042600455565b6000610f87600454426110c7565b90508160065482610f9891906114a7565b610fa29190611464565b600354610faf9190611451565b600355505042600455565b6040516001600160a01b0384811660248301528381166044830152606482018390526110219186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506111e6565b50505050565b60026001540361104a57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155565b61090c83846001600160a01b031663a9059cbb8585604051602401610fef9291906114d1565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000600b548210156110db57506000610cb2565b600b548310156110eb57600b5492505b60006110f684610c84565b9050600061110384610c84565b90506000825b8281116111dc5782810361114b576000818152600c602052604090205461113088886114be565b61113a91906114a7565b6111449083611451565b91506111ca565b600b54879061115b836001611451565b600a5461116891906114a7565b6111729190611451565b61117c91906114be565b6000828152600c602052604090205461119591906114a7565b61119f9083611451565b600a549092506111b0826001611451565b6111ba91906114a7565b600b546111c79190611451565b96505b806111d481611503565b915050611109565b5095945050505050565b60006111fb6001600160a01b03841683611240565b9050805160001415801561122057508080602001905181019061121e919061151c565b155b1561090c5782604051635274afe760e01b81526004016103ac91906113fb565b606061124e83836000611255565b9392505050565b60608147101561127a573060405163cd78605960e01b81526004016103ac91906113fb565b600080856001600160a01b031684866040516112969190611539565b60006040518083038185875af1925050503d80600081146112d3576040519150601f19603f3d011682016040523d82523d6000602084013e6112d8565b606091505b5091509150610e7c8683836060826112f8576112f382611336565b61124e565b815115801561130f57506001600160a01b0384163b155b1561132f5783604051639996b31560e01b81526004016103ac91906113fb565b508061124e565b8051156113465780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6000806040838503121561137257600080fd5b50508035926020909101359150565b80356001600160a01b038116811461139857600080fd5b919050565b6000602082840312156113af57600080fd5b61124e82611381565b6000602082840312156113ca57600080fd5b5035919050565b600080604083850312156113e457600080fd5b6113ed83611381565b946020939093013593505050565b6001600160a01b0391909116815260200190565b80151581146106ab57600080fd5b6000806040838503121561143057600080fd5b82356113ed8161140f565b634e487b7160e01b600052601160045260246000fd5b80820180821115610cb257610cb261143b565b60008261148157634e487b7160e01b600052601260045260246000fd5b500490565b92835260208301919091528054604083015260010154606082015260800190565b8082028115828204841417610cb257610cb261143b565b81810381811115610cb257610cb261143b565b6001600160a01b03929092168252602082015260400190565b6000602082840312156114fc57600080fd5b5051919050565b6000600182016115155761151561143b565b5060010190565b60006020828403121561152e57600080fd5b815161124e8161140f565b6000825160005b8181101561155a5760208186018101518583015201611540565b50600092019182525091905056fe26341ece4e32399464f7b06b085afdd815547782e1c5b4bddb0d37f2db839a8ca26469706673582212205701275529e41868ca15ca57a32f0b8b7f9b9fecfc505331e726474255051c6d64736f6c6343000814003300000000000000000000000028a922ad2d2a02250473b30f3444e20b138354d1000000000000000000000000837fe561e9c5dfa73f607fda679295dbc2be5e4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000093a80
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101495760003560e01c806317a493bd1461014e5780631959a0021461016357806324635216146101a45780632e1a7d4d146101b75780633279beab146101ca5780633f138d4b146101dd5780635053e461146101f0578063596293301461020757806366fe9f8a1461020f578063715018a6146102185780637d82ce3914610220578063880e21fa146102335780638da5cb5b146102465780638f6629151461025b5780639231cf741461026457806392e8990e1461026d578063a0b409051461028a578063a16b15fc1461029d578063b6b55f25146102a6578063bc0bc6ba146102b9578063c6b61e4c146102cc578063cc7a262e146102f3578063ccd34cd514610306578063db2e21bc1461030f578063f2fde38b14610317578063f40f0f521461032a578063f7c618c11461033d575b600080fd5b61016161015c36600461135f565b610350565b005b61018a61017136600461139d565b6009602052600090815260409020805460019091015482565b604080519283526020830191909152015b60405180910390f35b6101616101b23660046113b8565b610457565b6101616101c53660046113b8565b610561565b6101616101d83660046113b8565b6106ae565b6101616101eb3660046113d1565b6106cd565b6101f9600a5481565b60405190815260200161019b565b6101f96107c8565b6101f960055481565b6101616107fd565b61016161022e36600461135f565b610811565b6101616102413660046113b8565b610911565b61024e610a24565b60405161019b91906113fb565b6101f960035481565b6101f960045481565b60025461027a9060ff1681565b604051901515815260200161019b565b61016161029836600461141d565b610a33565b6101f9600b5481565b6101616102b43660046113b8565b610b1e565b6101f96102c73660046113b8565b610c84565b61018a6102da3660046113b8565b600c602052600090815260409020805460019091015482565b60085461024e906001600160a01b031681565b6101f960065481565b610161610cb8565b61016161032536600461139d565b610d3c565b6101f961033836600461139d565b610d77565b60075461024e906001600160a01b031681565b610358610eb9565b61036142610c84565b8210156103b55760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f74206164642072657761726420746f20706173742065706f63687360448201526064015b60405180910390fd5b6103bd610eeb565b6007546103d5906001600160a01b0316333084610fba565b6000828152600c6020526040812060010180548392906103f6908490611451565b9091555050600a546000838152600c602052604090206001015461041a9190611464565b6000838152600c602052604090819020918255516000805160206115698339815191529161044b9185918591611486565b60405180910390a15050565b61045f610eb9565b610467610eeb565b60075461047f906001600160a01b0316333084610fba565b600061048a42610c84565b905081600c600061049c846001611451565b815260200190815260200160002060010160008282546104bc9190611451565b9091555050600a546104cf906001611451565b600c60006104de846001611451565b8152602001908152602001600020600101546104fa9190611464565b600c6000610509846001611451565b8152602081019190915260400160002055600080516020611569833981519152610534826001611451565b83600c6000610544866001611451565b815260200190815260200160002060405161044b93929190611486565b610569611027565b33600090815260096020526040902080548211156105c75760405162461bcd60e51b815260206004820152601b60248201527a082dadeeadce840e8de40eed2e8d0c8e4c2ee40e8dede40d0d2ced602b1b60448201526064016103ac565b6105cf610eeb565b6000816001015460065460035484600001546105eb91906114a7565b6105f59190611464565b6105ff91906114be565b9050821561062d5781546106149084906114be565b825560085461062d906001600160a01b03163385611051565b801561064a5760075461064a906001600160a01b03163383611051565b600654600354835461065c91906114a7565b6106669190611464565b600183015560405183815233907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243649060200160405180910390a250506106ab60018055565b50565b6106b6610eb9565b6007546106ab906001600160a01b03163383611051565b6106d5610eb9565b6008546001600160a01b039081169083160361072c5760405162461bcd60e51b815260206004820152601660248201527521b0b73737ba1031329039ba30b5b2b2103a37b5b2b760511b60448201526064016103ac565b6007546001600160a01b03908116908316036107835760405162461bcd60e51b815260206004820152601660248201527521b0b73737ba103132903932bbb0b932103a37b5b2b760511b60448201526064016103ac565b6107976001600160a01b0383163383611051565b7f74545154aac348a3eac92596bd1971957ca94795f4e954ec5f613b55fab78129828260405161044b9291906114d1565b6000600a546107d642610c84565b6107e1906001611451565b6107eb91906114a7565b600b546107f89190611451565b905090565b610805610eb9565b61080f6000611077565b565b610819610eb9565b600b541561085f5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b60448201526064016103ac565b4282116108a55760405162461bcd60e51b8152602060048201526014602482015273496e76616c696420696e697469616c2074696d6560601b60448201526064016103ac565b600b82905560006108b542610c84565b6000818152600c602052604090206001908101849055600a549192506108db9190611451565b6108e59083611464565b6000828152600c602052604090205560075461090c906001600160a01b0316333085610fba565b505050565b610919610eb9565b610921610eeb565b600754610939906001600160a01b0316333084610fba565b600061094442610c84565b600b5490915042908110156109585750600b545b6000828152600c602052604081206001018054859290610979908490611451565b9091555050600b54600a54829190610992856001611451565b61099c91906114a7565b6109a69190611451565b6109b091906114be565b6109bb906001611451565b6109c59084611464565b6000838152600c6020526040812080549091906109e3908490611451565b90915550506000828152600c602052604090819020905160008051602061156983398151915291610a179185918791611486565b60405180910390a1505050565b6000546001600160a01b031690565b610a3b610eb9565b60025460ff16610a7b5760405162461bcd60e51b815260206004820152600b60248201526a135d5cdd081899481cd95d60aa1b60448201526064016103ac565b8115610ad7576005548111610acd5760405162461bcd60e51b81526020600482015260186024820152772732bb903634b6b4ba1036bab9ba103132903434b3b432b960411b60448201526064016103ac565b6005819055610aeb565b6002805460ff191683151517905560006005555b7f241f67ee5f41b7a5cabf911367329be7215900f602ebfc47f89dce2a6bcd847c60055460405161044b91815260200190565b610b26611027565b33600090815260096020526040902060025460ff1615610b97576005548154610b4f9084611451565b1115610b975760405162461bcd60e51b8152602060048201526017602482015276155cd95c88185b5bdd5b9d0818589bdd99481b1a5b5a5d604a1b60448201526064016103ac565b610b9f610eeb565b805415610bf757600081600101546006546003548460000154610bc291906114a7565b610bcc9190611464565b610bd691906114be565b90508015610bf557600754610bf5906001600160a01b03163383611051565b505b8115610c24578054610c0a908390611451565b8155600854610c24906001600160a01b0316333085610fba565b6006546003548254610c3691906114a7565b610c409190611464565b600182015560405182815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2506106ab60018055565b6000600b54821015610c9857506000919050565b600a54600b54610ca890846114be565b610cb29190611464565b92915050565b610cc0611027565b33600090815260096020526040812080548282556001820192909255908015610cfa57600854610cfa906001600160a01b03163383611051565b815460405190815233907f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd96959060200160405180910390a2505061080f60018055565b610d44610eb9565b6001600160a01b038116610d6e576000604051631e4fbdf760e01b81526004016103ac91906113fb565b6106ab81611077565b6001600160a01b0380821660009081526009602052604080822060085491516370a0823160e01b8152929390928492909116906370a0823190610dbe9030906004016113fb565b602060405180830381865afa158015610ddb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dff91906114ea565b905060045442118015610e1157508015155b15610e86576000610e24600454426110c7565b905060008260065483610e3791906114a7565b610e419190611464565b600354610e4e9190611451565b90508360010154600654828660000154610e6891906114a7565b610e729190611464565b610e7c91906114be565b9695505050505050565b60018201546006546003548454610e9d91906114a7565b610ea79190611464565b610eb191906114be565b949350505050565b33610ec2610a24565b6001600160a01b03161461080f573360405163118cdaa760e01b81526004016103ac91906113fb565b6004544211610ef657565b6008546040516370a0823160e01b81526000916001600160a01b0316906370a0823190610f279030906004016113fb565b602060405180830381865afa158015610f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6891906114ea565b905080600003610f79575042600455565b6000610f87600454426110c7565b90508160065482610f9891906114a7565b610fa29190611464565b600354610faf9190611451565b600355505042600455565b6040516001600160a01b0384811660248301528381166044830152606482018390526110219186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506111e6565b50505050565b60026001540361104a57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155565b61090c83846001600160a01b031663a9059cbb8585604051602401610fef9291906114d1565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000600b548210156110db57506000610cb2565b600b548310156110eb57600b5492505b60006110f684610c84565b9050600061110384610c84565b90506000825b8281116111dc5782810361114b576000818152600c602052604090205461113088886114be565b61113a91906114a7565b6111449083611451565b91506111ca565b600b54879061115b836001611451565b600a5461116891906114a7565b6111729190611451565b61117c91906114be565b6000828152600c602052604090205461119591906114a7565b61119f9083611451565b600a549092506111b0826001611451565b6111ba91906114a7565b600b546111c79190611451565b96505b806111d481611503565b915050611109565b5095945050505050565b60006111fb6001600160a01b03841683611240565b9050805160001415801561122057508080602001905181019061121e919061151c565b155b1561090c5782604051635274afe760e01b81526004016103ac91906113fb565b606061124e83836000611255565b9392505050565b60608147101561127a573060405163cd78605960e01b81526004016103ac91906113fb565b600080856001600160a01b031684866040516112969190611539565b60006040518083038185875af1925050503d80600081146112d3576040519150601f19603f3d011682016040523d82523d6000602084013e6112d8565b606091505b5091509150610e7c8683836060826112f8576112f382611336565b61124e565b815115801561130f57506001600160a01b0384163b155b1561132f5783604051639996b31560e01b81526004016103ac91906113fb565b508061124e565b8051156113465780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6000806040838503121561137257600080fd5b50508035926020909101359150565b80356001600160a01b038116811461139857600080fd5b919050565b6000602082840312156113af57600080fd5b61124e82611381565b6000602082840312156113ca57600080fd5b5035919050565b600080604083850312156113e457600080fd5b6113ed83611381565b946020939093013593505050565b6001600160a01b0391909116815260200190565b80151581146106ab57600080fd5b6000806040838503121561143057600080fd5b82356113ed8161140f565b634e487b7160e01b600052601160045260246000fd5b80820180821115610cb257610cb261143b565b60008261148157634e487b7160e01b600052601260045260246000fd5b500490565b92835260208301919091528054604083015260010154606082015260800190565b8082028115828204841417610cb257610cb261143b565b81810381811115610cb257610cb261143b565b6001600160a01b03929092168252602082015260400190565b6000602082840312156114fc57600080fd5b5051919050565b6000600182016115155761151561143b565b5060010190565b60006020828403121561152e57600080fd5b815161124e8161140f565b6000825160005b8181101561155a5760208186018101518583015201611540565b50600092019182525091905056fe26341ece4e32399464f7b06b085afdd815547782e1c5b4bddb0d37f2db839a8ca26469706673582212205701275529e41868ca15ca57a32f0b8b7f9b9fecfc505331e726474255051c6d64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000028a922ad2d2a02250473b30f3444e20b138354d1000000000000000000000000837fe561e9c5dfa73f607fda679295dbc2be5e4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000093a80
-----Decoded View---------------
Arg [0] : _stakedToken (address): 0x28A922aD2d2A02250473b30F3444E20b138354d1
Arg [1] : _rewardToken (address): 0x837fE561e9C5DFa73F607fDa679295DBC2Be5E40
Arg [2] : _poolLimitPerUser (uint256): 0
Arg [3] : _epochTime (uint256): 604800
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000028a922ad2d2a02250473b30f3444e20b138354d1
Arg [1] : 000000000000000000000000837fe561e9c5dfa73f607fda679295dbc2be5e40
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 0000000000000000000000000000000000000000000000000000000000093a80
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.