Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 33 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Deposit Rewards | 23366199 | 181 days ago | IN | 0.001 ETH | 0.00012328 | ||||
| Deposit Rewards | 23344366 | 184 days ago | IN | 0.01 ETH | 0.0001245 | ||||
| Deposit Rewards | 22600977 | 288 days ago | IN | 0.01 ETH | 0.00018153 | ||||
| Deposit Rewards | 22593232 | 289 days ago | IN | 0.01 ETH | 0.00018304 | ||||
| Deposit Rewards | 22565801 | 292 days ago | IN | 0.01 ETH | 0.00017294 | ||||
| Deposit Rewards | 22459659 | 307 days ago | IN | 0.01 ETH | 0.00027038 | ||||
| Deposit Rewards | 22394419 | 317 days ago | IN | 0.001 ETH | 0.00011103 | ||||
| Deposit Rewards | 22358566 | 322 days ago | IN | 0.001 ETH | 0.00009116 | ||||
| Deposit Rewards | 22356926 | 322 days ago | IN | 0.001 ETH | 0.00009654 | ||||
| Deposit Rewards | 22343838 | 324 days ago | IN | 0.001 ETH | 0.00012413 | ||||
| Deposit Rewards | 22336145 | 325 days ago | IN | 0.0001 ETH | 0.00011566 | ||||
| Set Percentages | 22336140 | 325 days ago | IN | 0 ETH | 0.00004708 | ||||
| Set Lockup Perio... | 21776643 | 403 days ago | IN | 0 ETH | 0.00011932 | ||||
| Set Lockup Perio... | 21776458 | 403 days ago | IN | 0 ETH | 0.00012701 | ||||
| Set Lockup Perio... | 21776388 | 403 days ago | IN | 0 ETH | 0.0001586 | ||||
| Set Lockup Perio... | 21776379 | 403 days ago | IN | 0 ETH | 0.00018024 | ||||
| Set Lockup Perio... | 21776370 | 403 days ago | IN | 0 ETH | 0.00017811 | ||||
| Set Lockup Perio... | 21776342 | 403 days ago | IN | 0 ETH | 0.00017114 | ||||
| Transfer Ownersh... | 21768794 | 404 days ago | IN | 0 ETH | 0.00024586 | ||||
| Deposit Rewards | 21181670 | 486 days ago | IN | 0.5 ETH | 0.0050918 | ||||
| Deposit Rewards | 21178024 | 486 days ago | IN | 0.01 ETH | 0.00206407 | ||||
| Set Lockup Perio... | 20947875 | 519 days ago | IN | 0 ETH | 0.0007194 | ||||
| Withdraw Tokens ... | 20941988 | 519 days ago | IN | 0 ETH | 0.00116203 | ||||
| Withdraw From Po... | 20941981 | 519 days ago | IN | 0 ETH | 0.00278039 | ||||
| Set Lockup Perio... | 20939632 | 520 days ago | IN | 0 ETH | 0.00322191 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Deposit Rewards | 23366199 | 181 days ago | 0.00096 ETH | ||||
| Deposit Rewards | 23366199 | 181 days ago | 0.00003 ETH | ||||
| Deposit Rewards | 23366199 | 181 days ago | 0.00001 ETH | ||||
| Deposit Rewards | 23344366 | 184 days ago | 0.0096 ETH | ||||
| Deposit Rewards | 23344366 | 184 days ago | 0.0003 ETH | ||||
| Deposit Rewards | 23344366 | 184 days ago | 0.0001 ETH | ||||
| Deposit Rewards | 22600977 | 288 days ago | 0.0096 ETH | ||||
| Deposit Rewards | 22600977 | 288 days ago | 0.0003 ETH | ||||
| Deposit Rewards | 22600977 | 288 days ago | 0.0001 ETH | ||||
| Deposit Rewards | 22593232 | 289 days ago | 0.0096 ETH | ||||
| Deposit Rewards | 22593232 | 289 days ago | 0.0003 ETH | ||||
| Deposit Rewards | 22593232 | 289 days ago | 0.0001 ETH | ||||
| Deposit Rewards | 22565801 | 292 days ago | 0.0096 ETH | ||||
| Deposit Rewards | 22565801 | 292 days ago | 0.0003 ETH | ||||
| Deposit Rewards | 22565801 | 292 days ago | 0.0001 ETH | ||||
| Deposit Rewards | 22459659 | 307 days ago | 0.0096 ETH | ||||
| Deposit Rewards | 22459659 | 307 days ago | 0.0003 ETH | ||||
| Deposit Rewards | 22459659 | 307 days ago | 0.0001 ETH | ||||
| Deposit Rewards | 22394419 | 317 days ago | 0.00096 ETH | ||||
| Deposit Rewards | 22394419 | 317 days ago | 0.00003 ETH | ||||
| Deposit Rewards | 22394419 | 317 days ago | 0.00001 ETH | ||||
| Deposit Rewards | 22358566 | 322 days ago | 0.00096 ETH | ||||
| Deposit Rewards | 22358566 | 322 days ago | 0.00003 ETH | ||||
| Deposit Rewards | 22358566 | 322 days ago | 0.00001 ETH | ||||
| Deposit Rewards | 22356926 | 322 days ago | 0.00096 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
PoolManager
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import '@openzeppelin/contracts/access/Ownable.sol';
import './interfaces/IPoolExtension.sol';
import './StakingPool.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
contract PoolManager is Ownable {
using SafeERC20 for IERC20;
uint256 constant FACTOR = 10000;
address constant DEXROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
address public stakingToken;
uint256 _totalPercentages;
bool public adminCanWithdraw = true;
struct PoolInfo {
address pool;
uint256 percentage;
}
PoolInfo[] public pools;
constructor(address _stakingToken) Ownable(msg.sender) {
stakingToken = _stakingToken;
_totalPercentages = FACTOR;
pools.push(
PoolInfo({
pool: address(new StakingPool(_stakingToken, 14 days, DEXROUTER)),
percentage: (FACTOR * 10) / 100 // 10%
})
);
pools.push(
PoolInfo({
pool: address(new StakingPool(_stakingToken, 28 days, DEXROUTER)),
percentage: (FACTOR * 30) / 100 // 30%
})
);
pools.push(
PoolInfo({
pool: address(new StakingPool(_stakingToken, 56 days, DEXROUTER)),
percentage: (FACTOR * 60) / 100 // 60%
})
);
}
function getAllPools() external view returns (PoolInfo[] memory) {
return pools;
}
function depositRewards() external payable {
require(msg.value > 0, 'no rewards');
uint256 _totalETH;
for (uint256 _i; _i < pools.length; _i++) {
uint256 _totalBefore = _totalETH;
_totalETH += (msg.value * pools[_i].percentage) / FACTOR;
StakingPool(pools[_i].pool).depositRewards{
value: _totalETH - _totalBefore
}();
}
uint256 _refund = msg.value - _totalETH;
if (_refund > 0) {
(bool _refunded, ) = payable(_msgSender()).call{ value: _refund }('');
require(_refunded, 'could not refund');
}
}
function claimRewardsBulk(
bool[] memory _compound,
uint256[] memory _minTokens
) external {
for (uint256 _i; _i < _compound.length; _i++) {
StakingPool(pools[_i].pool).claimRewardAdmin(
_msgSender(),
_compound[_i],
_minTokens[_i]
);
}
}
function setLockupPeriods(uint256[] memory _seconds) external onlyOwner {
for (uint256 _i; _i < _seconds.length; _i++) {
StakingPool(pools[_i].pool).setLockupPeriod(_seconds[_i]);
}
}
function setPercentages(uint256[] memory _percentages) external onlyOwner {
_totalPercentages = 0;
for (uint256 _i; _i < _percentages.length; _i++) {
_totalPercentages += _percentages[_i];
pools[_i].percentage = _percentages[_i];
}
require(_totalPercentages <= FACTOR, 'lte 100%');
}
function setExtension(IPoolExtension[] memory _ext) external onlyOwner {
for (uint256 _i; _i < _ext.length; _i++) {
StakingPool(pools[_i].pool).setPoolExtension(_ext[_i]);
}
}
function removeWithdrawAbility() external onlyOwner {
require(adminCanWithdraw, 'already disabled');
adminCanWithdraw = false;
}
function withdrawFromPools(uint256[] memory _amounts) external onlyOwner {
require(adminCanWithdraw, 'disabled');
for (uint256 _i; _i < _amounts.length; _i++) {
StakingPool(pools[_i].pool).withdrawTokens(_amounts[_i]);
}
}
function createPool(
uint256 _lockupSeconds,
uint256 _percentage
) external onlyOwner {
require(_totalPercentages + _percentage <= FACTOR, 'max percentage');
_totalPercentages += _percentage;
pools.push(
PoolInfo({
pool: address(new StakingPool(stakingToken, _lockupSeconds, DEXROUTER)),
percentage: _percentage
})
);
}
function removePool(uint256 _idx) external onlyOwner {
PoolInfo memory _pool = pools[_idx];
_totalPercentages -= _pool.percentage;
pools[_idx] = pools[pools.length - 1];
pools.pop();
}
function renounceAllOwnership() external onlyOwner {
for (uint256 _i; _i < pools.length; _i++) {
StakingPool(pools[_i].pool).renounceOwnership();
}
renounceOwnership();
}
function withdrawTokensFromManager(uint256 _amount) external onlyOwner {
IERC20 _token = IERC20(stakingToken);
uint256 tokenBalance = _token.balanceOf(address(this));
require(_amount <= tokenBalance, "Not enough tokens in the PoolManager");
_token.safeTransfer(_msgSender(), _amount);
}
}// 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/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;
}
}pragma solidity >=0.6.2;
interface IUniswapV2Router01 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
function removeLiquidity(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB);
function removeLiquidityETH(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountToken, uint amountETH);
function removeLiquidityWithPermit(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountA, uint amountB);
function removeLiquidityETHWithPermit(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountToken, uint amountETH);
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapTokensForExactTokens(
uint amountOut,
uint amountInMax,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}pragma solidity >=0.6.2;
import './IUniswapV2Router01.sol';
interface IUniswapV2Router02 is IUniswapV2Router01 {
function removeLiquidityETHSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountETH);
function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountETH);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IPoolExtension {
function setShare(
address wallet,
uint256 balanceChange,
bool isRemoving
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import '@openzeppelin/contracts/access/Ownable.sol';
import '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import '@openzeppelin/contracts/utils/Context.sol';
import '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';
import './interfaces/IPoolExtension.sol';
contract StakingPool is Context, Ownable, ReentrancyGuard {
using SafeERC20 for IERC20;
IUniswapV2Router02 immutable _router;
uint256 constant MULTIPLIER = 10 ** 36;
address public token;
uint256 public lockupPeriod;
uint256 public totalStakedUsers;
uint256 public totalSharesDeposited;
IPoolExtension public extension;
struct Share {
uint256 amount;
uint256 stakedTime;
}
struct Reward {
uint256 excluded;
uint256 realised;
}
mapping(address => Share) public shares;
mapping(address => Reward) public rewards;
uint256 public rewardsPerShare;
uint256 public totalDistributed;
uint256 public totalRewards;
event Stake(address indexed user, uint256 amount);
event Unstake(address indexed user, uint256 amount);
event ClaimReward(address user);
event DepositRewards(address indexed user, uint256 amountTokens);
event DistributeReward(
address indexed user,
uint256 amount,
bool _wasCompounded
);
constructor(address _token, uint256 _lockupPeriod, address __router) Ownable(msg.sender) {
token = _token;
lockupPeriod = _lockupPeriod;
_router = IUniswapV2Router02(__router);
}
function stake(uint256 _amount) external nonReentrant {
IERC20(token).safeTransferFrom(_msgSender(), address(this), _amount);
_setShare(_msgSender(), _amount, false);
}
function stakeForWallets(
address[] memory _wallets,
uint256[] memory _amounts
) external nonReentrant {
require(_wallets.length == _amounts.length, 'INSYNC');
uint256 _totalAmount;
for (uint256 _i; _i < _wallets.length; _i++) {
_totalAmount += _amounts[_i];
_setShare(_wallets[_i], _amounts[_i], false);
}
IERC20(token).safeTransferFrom(_msgSender(), address(this), _totalAmount);
}
function unstake(uint256 _amount) external nonReentrant {
IERC20(token).safeTransfer(_msgSender(), _amount);
_setShare(_msgSender(), _amount, true);
}
function _setShare(
address wallet,
uint256 balanceUpdate,
bool isRemoving
) internal {
if (address(extension) != address(0)) {
try extension.setShare(wallet, balanceUpdate, isRemoving) {} catch {}
}
if (isRemoving) {
_removeShares(wallet, balanceUpdate);
emit Unstake(wallet, balanceUpdate);
} else {
_addShares(wallet, balanceUpdate);
emit Stake(wallet, balanceUpdate);
}
}
function _addShares(address wallet, uint256 amount) private {
if (shares[wallet].amount > 0) {
_distributeReward(wallet, false, 0);
}
uint256 sharesBefore = shares[wallet].amount;
totalSharesDeposited += amount;
shares[wallet].amount += amount;
shares[wallet].stakedTime = block.timestamp;
if (sharesBefore == 0 && shares[wallet].amount > 0) {
totalStakedUsers++;
}
rewards[wallet].excluded = _cumulativeRewards(shares[wallet].amount);
}
function _removeShares(address wallet, uint256 amount) private {
require(
shares[wallet].amount > 0 && amount <= shares[wallet].amount,
'REM: amount'
);
require(
block.timestamp > shares[wallet].stakedTime + lockupPeriod,
'REM: timelock'
);
uint256 _unclaimed = getUnpaid(wallet);
bool _otherStakersPresent = totalSharesDeposited - amount > 0;
if (!_otherStakersPresent) {
_distributeReward(wallet, false, 0);
}
totalSharesDeposited -= amount;
shares[wallet].amount -= amount;
if (shares[wallet].amount == 0) {
totalStakedUsers--;
}
rewards[wallet].excluded = _cumulativeRewards(shares[wallet].amount);
// if there are other stakers and unclaimed rewards,
// deposit them back into the pool for other stakers to claim
if (_otherStakersPresent && _unclaimed > 0) {
_depositRewards(wallet, _unclaimed);
}
}
function depositRewards() external payable {
_depositRewards(_msgSender(), msg.value);
}
function _depositRewards(address _wallet, uint256 _amountETH) internal {
require(_amountETH > 0, 'ETH');
require(totalSharesDeposited > 0, 'SHARES');
totalRewards += _amountETH;
rewardsPerShare += (MULTIPLIER * _amountETH) / totalSharesDeposited;
emit DepositRewards(_wallet, _amountETH);
}
function _distributeReward(
address _wallet,
bool _compound,
uint256 _compoundMinTokensToReceive
) internal {
if (shares[_wallet].amount == 0) {
return;
}
shares[_wallet].stakedTime = block.timestamp; // reset every claim
uint256 _amountWei = getUnpaid(_wallet);
rewards[_wallet].realised += _amountWei;
rewards[_wallet].excluded = _cumulativeRewards(shares[_wallet].amount);
if (_amountWei > 0) {
totalDistributed += _amountWei;
if (_compound) {
_compoundRewards(_wallet, _amountWei, _compoundMinTokensToReceive);
} else {
uint256 _balBefore = address(this).balance;
(bool success, ) = payable(_wallet).call{ value: _amountWei }('');
require(success, 'DIST0');
require(address(this).balance >= _balBefore - _amountWei, 'DIST1');
}
emit DistributeReward(_wallet, _amountWei, _compound);
}
}
function _compoundRewards(
address _wallet,
uint256 _wei,
uint256 _minTokensToReceive
) internal {
address[] memory path = new address[](2);
path[0] = _router.WETH();
path[1] = token;
IERC20 _token = IERC20(token);
uint256 _tokenBalBefore = _token.balanceOf(address(this));
_router.swapExactETHForTokensSupportingFeeOnTransferTokens{ value: _wei }(
_minTokensToReceive,
path,
address(this),
block.timestamp
);
uint256 _compoundAmount = _token.balanceOf(address(this)) - _tokenBalBefore;
_setShare(_wallet, _compoundAmount, false);
}
function claimReward(
bool _compound,
uint256 _compMinTokensToReceive
) external nonReentrant {
_distributeReward(_msgSender(), _compound, _compMinTokensToReceive);
emit ClaimReward(_msgSender());
}
function claimRewardAdmin(
address _wallet,
bool _compound,
uint256 _compMinTokensToReceive
) external nonReentrant onlyOwner {
_distributeReward(_wallet, _compound, _compMinTokensToReceive);
emit ClaimReward(_wallet);
}
function getUnpaid(address wallet) public view returns (uint256) {
if (shares[wallet].amount == 0) {
return 0;
}
uint256 earnedRewards = _cumulativeRewards(shares[wallet].amount);
uint256 rewardsExcluded = rewards[wallet].excluded;
if (earnedRewards <= rewardsExcluded) {
return 0;
}
return earnedRewards - rewardsExcluded;
}
function _cumulativeRewards(uint256 share) internal view returns (uint256) {
return (share * rewardsPerShare) / MULTIPLIER;
}
function setPoolExtension(IPoolExtension _extension) external onlyOwner {
extension = _extension;
}
function setLockupPeriod(uint256 _seconds) external onlyOwner {
require(_seconds < 365 days, 'lte 1 year');
lockupPeriod = _seconds;
}
function withdrawTokens(uint256 _amount) external onlyOwner {
IERC20 _token = IERC20(token);
_token.safeTransfer(
_msgSender(),
_amount == 0 ? _token.balanceOf(address(this)) : _amount
);
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"viaIR": true,
"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":"address","name":"_stakingToken","type":"address"}],"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":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"adminCanWithdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool[]","name":"_compound","type":"bool[]"},{"internalType":"uint256[]","name":"_minTokens","type":"uint256[]"}],"name":"claimRewardsBulk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lockupSeconds","type":"uint256"},{"internalType":"uint256","name":"_percentage","type":"uint256"}],"name":"createPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositRewards","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getAllPools","outputs":[{"components":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct PoolManager.PoolInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pools","outputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_idx","type":"uint256"}],"name":"removePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"removeWithdrawAbility","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceAllOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IPoolExtension[]","name":"_ext","type":"address[]"}],"name":"setExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_seconds","type":"uint256[]"}],"name":"setLockupPeriods","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_percentages","type":"uint256[]"}],"name":"setPercentages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"withdrawFromPools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawTokensFromManager","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6080346200025b57601f6200440138819003918201601f19168301916001600160401b039190828411858510176200026057808592604095865283396020948591810103126200025b57516001600160a01b0390818116908190036200025b57331562000243576000928354918060018060a01b031933818616178755875194863391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08980a3600160ff19600354161760035560015416176001556127106002556117339081840191848310848411176200022f5762002cce9481868239828452621275008a850152606081737a250d5630b4cf539739df2c5dacb4c659f2488d95868c82015203019088f0801562000211576200013590876200012462000276565b911681526103e88b82015262000296565b8751818101818110868211176200021b5781606091848983398581526224ea008d820152868c82015203019088f0801562000211576200018b90876200017a62000276565b91168152610bb88b82015262000296565b87519481860194851186861017620001fd579185939160609593853982526249d400898301528782015203019083f0918215620001f25750620001e4929361177091620001d762000276565b9316835282015262000296565b516129cc9081620003028239f35b8351903d90823e3d90fd5b634e487b7160e01b88526041600452602488fd5b88513d89823e3d90fd5b634e487b7160e01b89526041600452602489fd5b634e487b7160e01b87526041600452602487fd5b8351631e4fbdf760e01b815260006004820152602490fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b60408051919082016001600160401b038111838210176200026057604052565b6004546801000000000000000081101562000260576001810180600455811015620002eb57602060019160046000528160002090831b0192828060a01b03815116838060a01b03198554161784550151910155565b634e487b7160e01b600052603260045260246000fdfe6040608081526004803610156200001557600080fd5b600091823560e01c80631324968d1462000eaf578063152111f71462000d445780631d8092f31462000c0057806347c319451462000b925780634845d23214620009f9578063676346ad14620009445780637102068c14620007d6578063715018a614620007b957806372f702f3146200078e57806374a110c214620006065780638da5cb5b14620005dc578063a38dcbd014620004b5578063ac4afa381462000463578063c81bf2b1146200043d57838163c88f8f5b146200039557508063d88ff1f414620002a4578063f2fde38b14620002115763fd8ce4cd14620000fb57600080fd5b346200020d5760203660031901126200020d57813567ffffffffffffffff8111620001d8576200012f90369084016200100e565b906200013a620010ca565b60ff6003541615620001e05783805b8351811015620001dc576200015e8162001079565b50546001600160a01b0316620001758286620011e6565b51813b15620001d8578391602483928751948593849263315a095d60e01b84528c8401525af18015620001ce5790620001b69291620001bc575b5062001160565b62000149565b620001c79062000f8a565b38620001af565b84513d85823e3d90fd5b8380fd5b5080f35b5162461bcd60e51b81526020818401526008602482015267191a5cd8589b195960c21b6044820152606490fd5b8280fd5b50346200020d5760203660031901126200020d576001600160a01b03823581811693919290849003620002a05762000248620010ca565b83156200028a57505082546001600160a01b0319811683178455167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b51631e4fbdf760e01b8152908101849052602490fd5b8480fd5b50913462000392578060031936011262000392579190805492620002c88462000ff5565b620002d68451918262000fd2565b848152602094858201809484527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b84915b838310620003665750505050835194859481860192828752518093528086019493905b838210620003385786860387f35b845180516001600160a01b03168752830151868401528796509485019493820193600191909101906200032a565b6002896001926200037d859c99989a9b9c62001137565b81520192019201919097969593949762000307565b80fd5b919050346200043957816003193601126200043957620003b4620010ca565b815b83548110156200042157620003cb8162001079565b50546001600160a01b0316803b15620001d857838091868551809481936338a80c5360e11b83525af180156200041457906200040e9291620001bc575062001160565b620003b6565b50505051903d90823e3d90fd5b826200042c620010ca565b62000436620010f7565b80f35b5080fd5b838234620004395781600319360112620004395760209060ff6003541690519015158152f35b50913462000392576020366003190112620003925781359154821015620003925750620004909062001079565b50805460019091015491516001600160a01b0390911681526020810191909152604090f35b5050346200043957602036600319011262000439578035620004d6620010ca565b620004fd6020620004f2620004eb8462001079565b5062001137565b015160025462001194565b60025581546000199190828101908111620005c95762000521620005299162001079565b509162001079565b919091620005b75780820362000589575b50508154801562000576570190620005528262001079565b62000564576001818580935501555580f35b634e487b7160e01b8452838252602484fd5b634e487b7160e01b845260318352602484fd5b805482546001600160a01b0319166001600160a01b039190911617825560019081015491015538806200053a565b634e487b7160e01b8552848452602485fd5b634e487b7160e01b855260118452602485fd5b8382346200043957816003193601126200043957905490516001600160a01b039091168152602090f35b50829034620004395780600319360112620004395760243562000628620010ca565b6002546127106200063a838362001186565b116200075a57816200064c9162001186565b60025560015482516001600160a01b03916117338083019184169067ffffffffffffffff8311848410176200074757918391606093620012648439815288356020820152737a250d5630b4cf539739df2c5dacb4c659f2488d8782015203019085f09283156200073e5781905193620006c58562000fb5565b168352602083019182528454680100000000000000008110156200072b57806001620006f49201875562001079565b93909362000719575183546001600160a01b0319169116178255516001919091015580f35b634e487b7160e01b8552848652602485fd5b634e487b7160e01b855260418652602485fd5b513d85823e3d90fd5b634e487b7160e01b885260418952602488fd5b825162461bcd60e51b8152602081870152600e60248201526d6d61782070657263656e7461676560901b6044820152606490fd5b838234620004395781600319360112620004395760015490516001600160a01b039091168152602090f35b833462000392578060031936011262000392576200042c620010ca565b50346200020d57806003193601126200020d5781359067ffffffffffffffff808311620002a05736602384011215620002a0578284013590620008198262000ff5565b93620008288451958662000fd2565b8285526020908186016024809560051b83010191368311620009405790858a969594939201905b82821062000916575050505081359081116200020d576200087490369087016200100e565b93825b815181101562000912576200088c8162001079565b50546001600160a01b0316620008a38284620011e6565b51151590620008b38389620011e6565b5191813b156200090e5760648a8880948b5196879586946320d778b160e11b865233908601528b85015260448401525af18015620009045790620008fe9291620001bc575062001160565b62000877565b86513d87823e3d90fd5b8680fd5b8380f35b90809293949596503580151581036200093c57815289959493929183019083016200084f565b8a80fd5b8980fd5b50346200020d5760203660031901126200020d57813567ffffffffffffffff8111620001d8576200097990369084016200100e565b9062000984620010ca565b83805b8351811015620001dc576200099c8162001079565b50546001600160a01b0316620009b38286620011e6565b51813b15620001d85783916024839287519485938492630c771c3960e41b84528c8401525af18015620001ce5790620009f39291620001bc575062001160565b62000987565b50346200020d5760209081600319360112620001d85782359162000a1c620010ca565b60015482516370a0823160e01b815230868201526001600160a01b0390911693908281602481885afa90811562000b8857879162000b55575b50811162000b0657825163a9059cbb60e01b83820190815233602483015260448083019390935291815262000aae91879182919062000a9660648262000fd2565b519082885af162000aa6620011a2565b9085620011fb565b805191821515918262000ade575b5050905062000ac9578380f35b51635274afe760e01b81529182015260249150fd5b80925081938101031262000b02570151801590811503620002a05780388062000abc565b8580fd5b825162461bcd60e51b81528086018390526024808201527f4e6f7420656e6f75676820746f6b656e7320696e2074686520506f6f6c4d616e60448201526330b3b2b960e11b6064820152608490fd5b90508281813d831162000b80575b62000b6f818362000fd2565b810103126200090e57513862000a55565b503d62000b63565b84513d89823e3d90fd5b5090346200020d57826003193601126200020d5762000bb0620010ca565b6003549160ff83161562000bca57505060ff191660035580f35b906020606492519162461bcd60e51b8352820152601060248201526f185b1c9958591e48191a5cd8589b195960821b6044820152fd5b5090346200020d5760209182600319360112620001d85781359167ffffffffffffffff8311620002a05736602384011215620002a057828101359362000c468562000ff5565b9362000c558451958662000fd2565b8585528185016024809760051b8301019136831162000d40579087899594939201905b82821062000d13575050505062000c8e620010ca565b815b845181101562000d0f5762000ca58162001079565b50546001600160a01b039081169062000cbf8388620011e6565b5116813b15620002a057849188839288519485938492632ca9f88960e21b8452898401525af1801562000d05579062000cff9291620001bc575062001160565b62000c90565b85513d86823e3d90fd5b8280f35b939450919290919081356001600160a01b0381168103620009405781528894939291830190830162000c78565b8880fd5b5090826003193601126200020d57341562000e80578291835b84835482101562000e15575083600162000d778362001079565b500154803402903482040362000e02579061271062000d9892049062001186565b938562000dbc62000da98462001079565b50546001600160a01b0316928762001194565b91803b1562000439578585518094819363152111f760e01b83525af1801562000df8579062000df29291620001bc575062001160565b62000d5d565b83513d88823e3d90fd5b634e487b7160e01b875260118552602487fd5b83838262000e24883462001194565b8062000e2e575080f35b81808092335af162000e3f620011a2565b501562000e4a578280f35b906020606492519162461bcd60e51b8352820152601060248201526f18dbdd5b19081b9bdd081c99599d5b9960821b6044820152fd5b6020606492519162461bcd60e51b8352820152600a6024820152696e6f207265776172647360b01b6044820152fd5b508234620003925760203660031901126200039257823567ffffffffffffffff8111620004395762000ee590369085016200100e565b9062000ef0620010ca565b600293818555815b835181101562000f4b578062000f2062000f1762000f459387620011e6565b51885462001186565b875562000f2e8186620011e6565b51600162000f3c8362001079565b50015562001160565b62000ef8565b508361271086541162000f5c578280f35b906020606492519162461bcd60e51b835282015260086024820152676c7465203130302560c01b6044820152fd5b67ffffffffffffffff811162000f9f57604052565b634e487b7160e01b600052604160045260246000fd5b6040810190811067ffffffffffffffff82111762000f9f57604052565b90601f8019910116810190811067ffffffffffffffff82111762000f9f57604052565b67ffffffffffffffff811162000f9f5760051b60200190565b81601f820112156200107457803591620010288362000ff5565b9262001038604051948562000fd2565b808452602092838086019260051b82010192831162001074578301905b82821062001064575050505090565b8135815290830190830162001055565b600080fd5b600454811015620010b457600460005260011b7f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0190600090565b634e487b7160e01b600052603260045260246000fd5b6000546001600160a01b03163303620010df57565b60405163118cdaa760e01b8152336004820152602490fd5b600080546001600160a01b0319811682556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3565b90604051620011468162000fb5565b82546001600160a01b031681526001909201546020830152565b6000198114620011705760010190565b634e487b7160e01b600052601160045260246000fd5b919082018092116200117057565b919082039182116200117057565b3d15620011e1573d9067ffffffffffffffff821162000f9f5760405191620011d5601f8201601f19166020018462000fd2565b82523d6000602084013e565b606090565b8051821015620010b45760209160051b010190565b906200122457508051156200121257805190602001fd5b604051630a12f52160e11b8152600490fd5b8151158062001259575b62001237575090565b604051639996b31560e01b81526001600160a01b039091166004820152602490fd5b50803b156200122e56fe60a0346100ec57601f61173338819003918201601f19168301916001600160401b038311848410176100f1578084926060946040528339810103126100ec5761004781610107565b610058604060208401519301610107565b33156100d3576000549260018060a01b031933818616176000556040519460018060a01b03948591823391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3600180551690600254161760025560035516608052611617908161011c8239608051816113a70152f35b604051631e4fbdf760e01b815260006004820152602490fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b03821682036100ec5756fe608060408181526004918236101561001657600080fd5b600092833560e01c9182630700037d14610847575081630e15561a14610828578163152111f7146108125781632d5537b0146107e95781632e17de78146107b2578163315a095d146106fc5781633c6e6789146106dd57816341aef16214610659578163472f13f3146105f7578163715018a61461059d57816380bb40551461057f57816389d96917146105525781638da5cb5b1461052a578163953194351461036e578163a694fc3a14610322578163b2a7e224146102d9578163c771c39014610277578163c7e1d0b114610258578163ce7c2ac214610216578163ee947a7c146101f7578163efca2eed146101d8578163f2fde38b1461014d575063fc0c546a1461012257600080fd5b3461014957816003193601126101495760025490516001600160a01b039091168152602090f35b5080fd5b9050346101d45760203660031901126101d457610168610887565b90610171610911565b6001600160a01b039182169283156101be57505082546001600160a01b0319811683178455167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b51631e4fbdf760e01b8152908101849052602490fd5b8280fd5b505034610149578160031936011261014957602090600a549051908152f35b5050346101495781600319360112610149576020906003549051908152f35b505034610149576020366003190112610149579081906001600160a01b0361023c610887565b1681526007602052206001815491015482519182526020820152f35b5050346101495781600319360112610149576020906009549051908152f35b9050346101d45760203660031901126101d457803591610295610911565b6301e133808310156102a957505060035580f35b906020606492519162461bcd60e51b8352820152600a602482015269363a329018903cb2b0b960b11b6044820152fd5b83903461014957602036600319011261014957356001600160a01b0381169081900361014957610307610911565b6bffffffffffffffffffffffff60a01b600654161760065580f35b8390346101495781602036600319011261036b576103649135610343610abd565b60025461035e908290309033906001600160a01b031661093d565b33610bb5565b6001805580f35b80fd5b9050346101d457816003193601126101d45767ffffffffffffffff90803582811161052657366023820112156105265780820135906103ac826108f9565b946103b9815196876108d7565b8286526020918287016024809560051b830101913683116104fb578501905b8282106105035750505082359485116104ff57366023860112156104ff578484013594610404866108f9565b95610411835197886108d7565b808752848488019160051b830101913683116104fb5785859101915b8383106104eb5750505050610440610abd565b85518551036104c35750505050829183925b81518410156104a8576104736104a29161046c8686610b38565b5190610b4c565b9361049d866001600160a01b0361048a8487610b38565b51166104968488610b38565b5190610bb5565b610ae0565b92610452565b600254859161036491309033906001600160a01b031661093d565b5162461bcd60e51b81529283015260069082015265494e53594e4360d01b6044820152606490fd5b823581529181019185910161042d565b8980fd5b8680fd5b81356001600160a01b03811681036105225781529084019084016103d8565b8a80fd5b8480fd5b505034610149578160031936011261014957905490516001600160a01b039091168152602090f35b50503461014957602036600319011261014957602090610578610573610887565b611559565b9051908152f35b9050346101d457826003193601126101d45760209250549051908152f35b833461036b578060031936011261036b576105b6610911565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b9050346101d457816003193601126101d4573580151581036101d4577f63e32091e4445d16e29c33a6b264577c2d86694021aa4e6f4dd590048f5792e89161064d602092610643610abd565b6024359033611138565b51338152a16001805580f35b50503461014957606036600319011261014957610674610887565b6024359081151582036106d9577f63e32091e4445d16e29c33a6b264577c2d86694021aa4e6f4dd590048f5792e8926106c36020936106b1610abd565b6106b9610911565b6044359084611138565b516001600160a01b039091168152a16001805580f35b8380fd5b5050346101495781600319360112610149576020906005549051908152f35b919050346101d45760203660031901126101d45781359061071b610911565b6002546001600160a01b031691806107a557508051926370a0823160e01b84523090840152602083602481855afa90811561079c57508390610769575b6107669250905b3390610b59565b80f35b506020823d8211610794575b81610782602093836108d7565b810103126101d4576107669151610758565b3d9150610775565b513d85823e3d90fd5b905061076692509061075f565b83903461014957602036600319011261014957600161036491356107d4610abd565b61035e81838060a01b03600254163390610b59565b50503461014957816003193601126101495760065490516001600160a01b039091168152602090f35b838060031936011261036b576107663433610ff5565b505034610149578160031936011261014957602090600b549051908152f35b8390853461036b57602036600319011261036b5782906001600160a01b0361086d610887565b168152600860205220600181549101549082526020820152f35b600435906001600160a01b038216820361089d57565b600080fd5b600091031261089d57565b67ffffffffffffffff81116108c157604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff8211176108c157604052565b67ffffffffffffffff81116108c15760051b60200190565b6000546001600160a01b0316330361092557565b60405163118cdaa760e01b8152336004820152602490fd5b6040516323b872dd60e01b60208201526001600160a01b03928316602482015292909116604483015260648083019390935291815260a081019181831067ffffffffffffffff8411176108c15761099692604052610998565b565b60018060a01b0316906109c2600080836020829551910182875af16109bb610a1a565b9084610a5a565b9081519182151592836109f2575b5050506109da5750565b60249060405190635274afe760e01b82526004820152fd5b81929350906020918101031261014957602001519081159182150361036b57503880806109d0565b3d15610a55573d9067ffffffffffffffff82116108c15760405191610a49601f8201601f1916602001846108d7565b82523d6000602084013e565b606090565b90610a815750805115610a6f57805190602001fd5b604051630a12f52160e11b8152600490fd5b81511580610ab4575b610a92575090565b604051639996b31560e01b81526001600160a01b039091166004820152602490fd5b50803b15610a8a565b600260015414610ace576002600155565b604051633ee5aeb560e01b8152600490fd5b6000198114610aef5760010190565b634e487b7160e01b600052601160045260246000fd5b805115610b125760200190565b634e487b7160e01b600052603260045260246000fd5b805160011015610b125760400190565b8051821015610b125760209160051b010190565b91908201809211610aef57565b60405163a9059cbb60e01b60208201526001600160a01b039092166024830152604480830193909352918152608081019167ffffffffffffffff8311828410176108c15761099692604052610998565b6040513d6000823e3d90fd5b600654919290916001600160a01b039190821680610c51575b5015610c1357610bde8383610e6b565b60405192835216907f85082129d87b2fe11527cb1b3b7a520aeb5aa6913f88a3d8757fe40d1db02fdd9080602081015b0390a2565b610c1d8383610cb0565b60405192835216907febedb8b3c678666e7f36970bc8f57abf6d8fa2e828c0da91ea5b75bf68ed101a908060208101610c0e565b803b1561089d576040516329cc05cf60e01b81526001600160a01b0385166004820152602481018690528215156044820152906000908290606490829084905af115610bce5780610ca4610caa926108ad565b806108a2565b38610bce565b9060018060a01b0382166000526007602052604060002054610dca575b6001600160a01b03821660009081526007602052604090205490610cfb610cf682600554610b4c565b600555565b6001600160a01b0383166000908152600760205260409020610d1f90918254610b4c565b90556001600160a01b03821660009081526007602052604090204290600101551580610da9575b610d91575b6001600160a01b0381166000908152600760205260409020610d8e90610d72905b546115c0565b6001600160a01b03909216600090815260086020526040902090565b55565b610da4610d9f600454610ae0565b600455565b610d4b565b506001600160a01b0381166000908152600760205260409020541515610d46565b610dd660008084611138565b610ccd565b15610de257565b60405162461bcd60e51b815260206004820152600b60248201526a1491534e88185b5bdd5b9d60aa1b6044820152606490fd5b15610e1c57565b60405162461bcd60e51b815260206004820152600d60248201526c52454d3a2074696d656c6f636b60981b6044820152606490fd5b91908203918211610aef57565b8015610aef576000190190565b6001600160a01b038116600090815260076020526040902090919054151580610fc0575b610e9890610ddb565b610ece610ec76001610ebc8560018060a01b03166000526007602052604060002090565b015460035490610b4c565b4211610e15565b610ed782611559565b90610ee481600554610e51565b1590811591610faf575b610efd610cf682600554610e51565b6001600160a01b0384166000908152600760205260409020610f2190918254610e51565b90556001600160a01b03831660009081526007602052604090205415610f9c575b6001600160a01b0383166000908152600760205260409020610f6390610d6c565b6001600160a01b03841660009081526008602052604090205580610f93575b610f8a575050565b61099691610ff5565b50801515610f82565b610faa610d9f600454610e5e565b610f42565b610fbb60008086611138565b610eee565b506001600160a01b038216600090815260076020526040902054811115610e8f565b81810292918115918404141715610aef57565b81156110a55760055480156110775761101083600b54610b4c565b600b556ec097ce7bc90715b34b9f1000000000918383029283048403610aef576110616020927fb9ad861b752f80117b35bea6dec99933d8a5ae360f2839ee8784b750d56134099404600954610b4c565b6009556040519384526001600160a01b031692a2565b60405162461bcd60e51b815260206004820152600660248201526553484152455360d01b6044820152606490fd5b60405162461bcd60e51b815260206004820152600360248201526208aa8960eb1b6044820152606490fd5b156110d757565b60405162461bcd60e51b8152602060048201526005602482015264044495354360dc1b6044820152606490fd5b1561110b57565b60405162461bcd60e51b8152602060048201526005602482015264444953543160d81b6044820152606490fd5b6001600160a01b038116600090815260076020526040902090919054156112bf576001600160a01b038216600090815260076020526040902042906001015561118082611559565b92600161119f8460018060a01b03166000526008602052604060002090565b016111ab858254610b4c565b90556001600160a01b03831660009081526007602052604090206111ce90610d6c565b6001600160a01b038416600090815260086020526040902055836111f3575b50505050565b61120761120285600a54610b4c565b600a55565b811561125e57611218908484611383565b7ff34664cb7e3473d9bcd089297cc2ec340fede133eaf733d0ca506f1e05e2fee0915b6040805194855291151560208501526001600160a01b031692a2388080806111ed565b507ff34664cb7e3473d9bcd089297cc2ec340fede133eaf733d0ca506f1e05e2fee0916112ba476112a860008080808a6001600160a01b0389165af16112a2610a1a565b506110d0565b6112b3864792610e51565b1115611104565b61123b565b505050565b604051906060820182811067ffffffffffffffff8211176108c15760405260028252604082602036910137565b9081602091031261089d57516001600160a01b038116810361089d5790565b9081602091031261089d575190565b9190949392946080830190835260209060808285015282518091528160a0850193019160005b8281106113665750505050906060919460018060a01b031660408201520152565b83516001600160a01b031685529381019392810192600101611345565b61138b6112c4565b6040516315ab88c960e31b815290936020916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116918481600481865afa80156114f5576113fc9160009161152c575b506113ed89610b05565b6001600160a01b039091169052565b6002546001600160a01b0316611415816113ed8a610b28565b6040516370a0823160e01b80825230600483015290989190921696919285896024818b5afa9889156114f55760009961150d575b50803b1561089d5760405163b6f9de9560e01b81529460009386938492839161147991429130916004860161131f565b03925af19182156114f55783926114fa575b5060405190815230600482015293849060249082905afa9384156114f557610996946000946114c29386926114c8575b5050610e51565b90610bb5565b6114e79250803d106114ee575b6114df81836108d7565b810190611310565b38806114bb565b503d6114d5565b610ba9565b80610ca4611507926108ad565b3861148b565b611525919950863d88116114ee576114df81836108d7565b9738611449565b61154c9150863d8811611552575b61154481836108d7565b8101906112f1565b386113e3565b503d61153a565b6001600160a01b031660008181526007602052604081205490919080156115bb576115976ec097ce7bc90715b34b9f10000000009160095490610fe2565b049082526008602052604082205490818111156115bb576115b89250610e51565b90565b505090565b6115dd6ec097ce7bc90715b34b9f10000000009160095490610fe2565b049056fea2646970667358221220c0b0032b60d01a795b68072b5e6741297cbbbefd14af912d5afcd6a0f44e487364736f6c63430008140033a2646970667358221220bc51d40b71a07f9b9a3c96b7e9cf35b3c53d2bfff64bdd6147ff9c84dd5cf44164736f6c6343000814003360a0346100ec57601f61173338819003918201601f19168301916001600160401b038311848410176100f1578084926060946040528339810103126100ec5761004781610107565b610058604060208401519301610107565b33156100d3576000549260018060a01b031933818616176000556040519460018060a01b03948591823391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3600180551690600254161760025560035516608052611617908161011c8239608051816113a70152f35b604051631e4fbdf760e01b815260006004820152602490fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b03821682036100ec5756fe608060408181526004918236101561001657600080fd5b600092833560e01c9182630700037d14610847575081630e15561a14610828578163152111f7146108125781632d5537b0146107e95781632e17de78146107b2578163315a095d146106fc5781633c6e6789146106dd57816341aef16214610659578163472f13f3146105f7578163715018a61461059d57816380bb40551461057f57816389d96917146105525781638da5cb5b1461052a578163953194351461036e578163a694fc3a14610322578163b2a7e224146102d9578163c771c39014610277578163c7e1d0b114610258578163ce7c2ac214610216578163ee947a7c146101f7578163efca2eed146101d8578163f2fde38b1461014d575063fc0c546a1461012257600080fd5b3461014957816003193601126101495760025490516001600160a01b039091168152602090f35b5080fd5b9050346101d45760203660031901126101d457610168610887565b90610171610911565b6001600160a01b039182169283156101be57505082546001600160a01b0319811683178455167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b51631e4fbdf760e01b8152908101849052602490fd5b8280fd5b505034610149578160031936011261014957602090600a549051908152f35b5050346101495781600319360112610149576020906003549051908152f35b505034610149576020366003190112610149579081906001600160a01b0361023c610887565b1681526007602052206001815491015482519182526020820152f35b5050346101495781600319360112610149576020906009549051908152f35b9050346101d45760203660031901126101d457803591610295610911565b6301e133808310156102a957505060035580f35b906020606492519162461bcd60e51b8352820152600a602482015269363a329018903cb2b0b960b11b6044820152fd5b83903461014957602036600319011261014957356001600160a01b0381169081900361014957610307610911565b6bffffffffffffffffffffffff60a01b600654161760065580f35b8390346101495781602036600319011261036b576103649135610343610abd565b60025461035e908290309033906001600160a01b031661093d565b33610bb5565b6001805580f35b80fd5b9050346101d457816003193601126101d45767ffffffffffffffff90803582811161052657366023820112156105265780820135906103ac826108f9565b946103b9815196876108d7565b8286526020918287016024809560051b830101913683116104fb578501905b8282106105035750505082359485116104ff57366023860112156104ff578484013594610404866108f9565b95610411835197886108d7565b808752848488019160051b830101913683116104fb5785859101915b8383106104eb5750505050610440610abd565b85518551036104c35750505050829183925b81518410156104a8576104736104a29161046c8686610b38565b5190610b4c565b9361049d866001600160a01b0361048a8487610b38565b51166104968488610b38565b5190610bb5565b610ae0565b92610452565b600254859161036491309033906001600160a01b031661093d565b5162461bcd60e51b81529283015260069082015265494e53594e4360d01b6044820152606490fd5b823581529181019185910161042d565b8980fd5b8680fd5b81356001600160a01b03811681036105225781529084019084016103d8565b8a80fd5b8480fd5b505034610149578160031936011261014957905490516001600160a01b039091168152602090f35b50503461014957602036600319011261014957602090610578610573610887565b611559565b9051908152f35b9050346101d457826003193601126101d45760209250549051908152f35b833461036b578060031936011261036b576105b6610911565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b9050346101d457816003193601126101d4573580151581036101d4577f63e32091e4445d16e29c33a6b264577c2d86694021aa4e6f4dd590048f5792e89161064d602092610643610abd565b6024359033611138565b51338152a16001805580f35b50503461014957606036600319011261014957610674610887565b6024359081151582036106d9577f63e32091e4445d16e29c33a6b264577c2d86694021aa4e6f4dd590048f5792e8926106c36020936106b1610abd565b6106b9610911565b6044359084611138565b516001600160a01b039091168152a16001805580f35b8380fd5b5050346101495781600319360112610149576020906005549051908152f35b919050346101d45760203660031901126101d45781359061071b610911565b6002546001600160a01b031691806107a557508051926370a0823160e01b84523090840152602083602481855afa90811561079c57508390610769575b6107669250905b3390610b59565b80f35b506020823d8211610794575b81610782602093836108d7565b810103126101d4576107669151610758565b3d9150610775565b513d85823e3d90fd5b905061076692509061075f565b83903461014957602036600319011261014957600161036491356107d4610abd565b61035e81838060a01b03600254163390610b59565b50503461014957816003193601126101495760065490516001600160a01b039091168152602090f35b838060031936011261036b576107663433610ff5565b505034610149578160031936011261014957602090600b549051908152f35b8390853461036b57602036600319011261036b5782906001600160a01b0361086d610887565b168152600860205220600181549101549082526020820152f35b600435906001600160a01b038216820361089d57565b600080fd5b600091031261089d57565b67ffffffffffffffff81116108c157604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff8211176108c157604052565b67ffffffffffffffff81116108c15760051b60200190565b6000546001600160a01b0316330361092557565b60405163118cdaa760e01b8152336004820152602490fd5b6040516323b872dd60e01b60208201526001600160a01b03928316602482015292909116604483015260648083019390935291815260a081019181831067ffffffffffffffff8411176108c15761099692604052610998565b565b60018060a01b0316906109c2600080836020829551910182875af16109bb610a1a565b9084610a5a565b9081519182151592836109f2575b5050506109da5750565b60249060405190635274afe760e01b82526004820152fd5b81929350906020918101031261014957602001519081159182150361036b57503880806109d0565b3d15610a55573d9067ffffffffffffffff82116108c15760405191610a49601f8201601f1916602001846108d7565b82523d6000602084013e565b606090565b90610a815750805115610a6f57805190602001fd5b604051630a12f52160e11b8152600490fd5b81511580610ab4575b610a92575090565b604051639996b31560e01b81526001600160a01b039091166004820152602490fd5b50803b15610a8a565b600260015414610ace576002600155565b604051633ee5aeb560e01b8152600490fd5b6000198114610aef5760010190565b634e487b7160e01b600052601160045260246000fd5b805115610b125760200190565b634e487b7160e01b600052603260045260246000fd5b805160011015610b125760400190565b8051821015610b125760209160051b010190565b91908201809211610aef57565b60405163a9059cbb60e01b60208201526001600160a01b039092166024830152604480830193909352918152608081019167ffffffffffffffff8311828410176108c15761099692604052610998565b6040513d6000823e3d90fd5b600654919290916001600160a01b039190821680610c51575b5015610c1357610bde8383610e6b565b60405192835216907f85082129d87b2fe11527cb1b3b7a520aeb5aa6913f88a3d8757fe40d1db02fdd9080602081015b0390a2565b610c1d8383610cb0565b60405192835216907febedb8b3c678666e7f36970bc8f57abf6d8fa2e828c0da91ea5b75bf68ed101a908060208101610c0e565b803b1561089d576040516329cc05cf60e01b81526001600160a01b0385166004820152602481018690528215156044820152906000908290606490829084905af115610bce5780610ca4610caa926108ad565b806108a2565b38610bce565b9060018060a01b0382166000526007602052604060002054610dca575b6001600160a01b03821660009081526007602052604090205490610cfb610cf682600554610b4c565b600555565b6001600160a01b0383166000908152600760205260409020610d1f90918254610b4c565b90556001600160a01b03821660009081526007602052604090204290600101551580610da9575b610d91575b6001600160a01b0381166000908152600760205260409020610d8e90610d72905b546115c0565b6001600160a01b03909216600090815260086020526040902090565b55565b610da4610d9f600454610ae0565b600455565b610d4b565b506001600160a01b0381166000908152600760205260409020541515610d46565b610dd660008084611138565b610ccd565b15610de257565b60405162461bcd60e51b815260206004820152600b60248201526a1491534e88185b5bdd5b9d60aa1b6044820152606490fd5b15610e1c57565b60405162461bcd60e51b815260206004820152600d60248201526c52454d3a2074696d656c6f636b60981b6044820152606490fd5b91908203918211610aef57565b8015610aef576000190190565b6001600160a01b038116600090815260076020526040902090919054151580610fc0575b610e9890610ddb565b610ece610ec76001610ebc8560018060a01b03166000526007602052604060002090565b015460035490610b4c565b4211610e15565b610ed782611559565b90610ee481600554610e51565b1590811591610faf575b610efd610cf682600554610e51565b6001600160a01b0384166000908152600760205260409020610f2190918254610e51565b90556001600160a01b03831660009081526007602052604090205415610f9c575b6001600160a01b0383166000908152600760205260409020610f6390610d6c565b6001600160a01b03841660009081526008602052604090205580610f93575b610f8a575050565b61099691610ff5565b50801515610f82565b610faa610d9f600454610e5e565b610f42565b610fbb60008086611138565b610eee565b506001600160a01b038216600090815260076020526040902054811115610e8f565b81810292918115918404141715610aef57565b81156110a55760055480156110775761101083600b54610b4c565b600b556ec097ce7bc90715b34b9f1000000000918383029283048403610aef576110616020927fb9ad861b752f80117b35bea6dec99933d8a5ae360f2839ee8784b750d56134099404600954610b4c565b6009556040519384526001600160a01b031692a2565b60405162461bcd60e51b815260206004820152600660248201526553484152455360d01b6044820152606490fd5b60405162461bcd60e51b815260206004820152600360248201526208aa8960eb1b6044820152606490fd5b156110d757565b60405162461bcd60e51b8152602060048201526005602482015264044495354360dc1b6044820152606490fd5b1561110b57565b60405162461bcd60e51b8152602060048201526005602482015264444953543160d81b6044820152606490fd5b6001600160a01b038116600090815260076020526040902090919054156112bf576001600160a01b038216600090815260076020526040902042906001015561118082611559565b92600161119f8460018060a01b03166000526008602052604060002090565b016111ab858254610b4c565b90556001600160a01b03831660009081526007602052604090206111ce90610d6c565b6001600160a01b038416600090815260086020526040902055836111f3575b50505050565b61120761120285600a54610b4c565b600a55565b811561125e57611218908484611383565b7ff34664cb7e3473d9bcd089297cc2ec340fede133eaf733d0ca506f1e05e2fee0915b6040805194855291151560208501526001600160a01b031692a2388080806111ed565b507ff34664cb7e3473d9bcd089297cc2ec340fede133eaf733d0ca506f1e05e2fee0916112ba476112a860008080808a6001600160a01b0389165af16112a2610a1a565b506110d0565b6112b3864792610e51565b1115611104565b61123b565b505050565b604051906060820182811067ffffffffffffffff8211176108c15760405260028252604082602036910137565b9081602091031261089d57516001600160a01b038116810361089d5790565b9081602091031261089d575190565b9190949392946080830190835260209060808285015282518091528160a0850193019160005b8281106113665750505050906060919460018060a01b031660408201520152565b83516001600160a01b031685529381019392810192600101611345565b61138b6112c4565b6040516315ab88c960e31b815290936020916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116918481600481865afa80156114f5576113fc9160009161152c575b506113ed89610b05565b6001600160a01b039091169052565b6002546001600160a01b0316611415816113ed8a610b28565b6040516370a0823160e01b80825230600483015290989190921696919285896024818b5afa9889156114f55760009961150d575b50803b1561089d5760405163b6f9de9560e01b81529460009386938492839161147991429130916004860161131f565b03925af19182156114f55783926114fa575b5060405190815230600482015293849060249082905afa9384156114f557610996946000946114c29386926114c8575b5050610e51565b90610bb5565b6114e79250803d106114ee575b6114df81836108d7565b810190611310565b38806114bb565b503d6114d5565b610ba9565b80610ca4611507926108ad565b3861148b565b611525919950863d88116114ee576114df81836108d7565b9738611449565b61154c9150863d8811611552575b61154481836108d7565b8101906112f1565b386113e3565b503d61153a565b6001600160a01b031660008181526007602052604081205490919080156115bb576115976ec097ce7bc90715b34b9f10000000009160095490610fe2565b049082526008602052604082205490818111156115bb576115b89250610e51565b90565b505090565b6115dd6ec097ce7bc90715b34b9f10000000009160095490610fe2565b049056fea2646970667358221220c0b0032b60d01a795b68072b5e6741297cbbbefd14af912d5afcd6a0f44e487364736f6c634300081400330000000000000000000000008e0eef788350f40255d86dfe8d91ec0ad3a4547f
Deployed Bytecode
0x6040608081526004803610156200001557600080fd5b600091823560e01c80631324968d1462000eaf578063152111f71462000d445780631d8092f31462000c0057806347c319451462000b925780634845d23214620009f9578063676346ad14620009445780637102068c14620007d6578063715018a614620007b957806372f702f3146200078e57806374a110c214620006065780638da5cb5b14620005dc578063a38dcbd014620004b5578063ac4afa381462000463578063c81bf2b1146200043d57838163c88f8f5b146200039557508063d88ff1f414620002a4578063f2fde38b14620002115763fd8ce4cd14620000fb57600080fd5b346200020d5760203660031901126200020d57813567ffffffffffffffff8111620001d8576200012f90369084016200100e565b906200013a620010ca565b60ff6003541615620001e05783805b8351811015620001dc576200015e8162001079565b50546001600160a01b0316620001758286620011e6565b51813b15620001d8578391602483928751948593849263315a095d60e01b84528c8401525af18015620001ce5790620001b69291620001bc575b5062001160565b62000149565b620001c79062000f8a565b38620001af565b84513d85823e3d90fd5b8380fd5b5080f35b5162461bcd60e51b81526020818401526008602482015267191a5cd8589b195960c21b6044820152606490fd5b8280fd5b50346200020d5760203660031901126200020d576001600160a01b03823581811693919290849003620002a05762000248620010ca565b83156200028a57505082546001600160a01b0319811683178455167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b51631e4fbdf760e01b8152908101849052602490fd5b8480fd5b50913462000392578060031936011262000392579190805492620002c88462000ff5565b620002d68451918262000fd2565b848152602094858201809484527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b84915b838310620003665750505050835194859481860192828752518093528086019493905b838210620003385786860387f35b845180516001600160a01b03168752830151868401528796509485019493820193600191909101906200032a565b6002896001926200037d859c99989a9b9c62001137565b81520192019201919097969593949762000307565b80fd5b919050346200043957816003193601126200043957620003b4620010ca565b815b83548110156200042157620003cb8162001079565b50546001600160a01b0316803b15620001d857838091868551809481936338a80c5360e11b83525af180156200041457906200040e9291620001bc575062001160565b620003b6565b50505051903d90823e3d90fd5b826200042c620010ca565b62000436620010f7565b80f35b5080fd5b838234620004395781600319360112620004395760209060ff6003541690519015158152f35b50913462000392576020366003190112620003925781359154821015620003925750620004909062001079565b50805460019091015491516001600160a01b0390911681526020810191909152604090f35b5050346200043957602036600319011262000439578035620004d6620010ca565b620004fd6020620004f2620004eb8462001079565b5062001137565b015160025462001194565b60025581546000199190828101908111620005c95762000521620005299162001079565b509162001079565b919091620005b75780820362000589575b50508154801562000576570190620005528262001079565b62000564576001818580935501555580f35b634e487b7160e01b8452838252602484fd5b634e487b7160e01b845260318352602484fd5b805482546001600160a01b0319166001600160a01b039190911617825560019081015491015538806200053a565b634e487b7160e01b8552848452602485fd5b634e487b7160e01b855260118452602485fd5b8382346200043957816003193601126200043957905490516001600160a01b039091168152602090f35b50829034620004395780600319360112620004395760243562000628620010ca565b6002546127106200063a838362001186565b116200075a57816200064c9162001186565b60025560015482516001600160a01b03916117338083019184169067ffffffffffffffff8311848410176200074757918391606093620012648439815288356020820152737a250d5630b4cf539739df2c5dacb4c659f2488d8782015203019085f09283156200073e5781905193620006c58562000fb5565b168352602083019182528454680100000000000000008110156200072b57806001620006f49201875562001079565b93909362000719575183546001600160a01b0319169116178255516001919091015580f35b634e487b7160e01b8552848652602485fd5b634e487b7160e01b855260418652602485fd5b513d85823e3d90fd5b634e487b7160e01b885260418952602488fd5b825162461bcd60e51b8152602081870152600e60248201526d6d61782070657263656e7461676560901b6044820152606490fd5b838234620004395781600319360112620004395760015490516001600160a01b039091168152602090f35b833462000392578060031936011262000392576200042c620010ca565b50346200020d57806003193601126200020d5781359067ffffffffffffffff808311620002a05736602384011215620002a0578284013590620008198262000ff5565b93620008288451958662000fd2565b8285526020908186016024809560051b83010191368311620009405790858a969594939201905b82821062000916575050505081359081116200020d576200087490369087016200100e565b93825b815181101562000912576200088c8162001079565b50546001600160a01b0316620008a38284620011e6565b51151590620008b38389620011e6565b5191813b156200090e5760648a8880948b5196879586946320d778b160e11b865233908601528b85015260448401525af18015620009045790620008fe9291620001bc575062001160565b62000877565b86513d87823e3d90fd5b8680fd5b8380f35b90809293949596503580151581036200093c57815289959493929183019083016200084f565b8a80fd5b8980fd5b50346200020d5760203660031901126200020d57813567ffffffffffffffff8111620001d8576200097990369084016200100e565b9062000984620010ca565b83805b8351811015620001dc576200099c8162001079565b50546001600160a01b0316620009b38286620011e6565b51813b15620001d85783916024839287519485938492630c771c3960e41b84528c8401525af18015620001ce5790620009f39291620001bc575062001160565b62000987565b50346200020d5760209081600319360112620001d85782359162000a1c620010ca565b60015482516370a0823160e01b815230868201526001600160a01b0390911693908281602481885afa90811562000b8857879162000b55575b50811162000b0657825163a9059cbb60e01b83820190815233602483015260448083019390935291815262000aae91879182919062000a9660648262000fd2565b519082885af162000aa6620011a2565b9085620011fb565b805191821515918262000ade575b5050905062000ac9578380f35b51635274afe760e01b81529182015260249150fd5b80925081938101031262000b02570151801590811503620002a05780388062000abc565b8580fd5b825162461bcd60e51b81528086018390526024808201527f4e6f7420656e6f75676820746f6b656e7320696e2074686520506f6f6c4d616e60448201526330b3b2b960e11b6064820152608490fd5b90508281813d831162000b80575b62000b6f818362000fd2565b810103126200090e57513862000a55565b503d62000b63565b84513d89823e3d90fd5b5090346200020d57826003193601126200020d5762000bb0620010ca565b6003549160ff83161562000bca57505060ff191660035580f35b906020606492519162461bcd60e51b8352820152601060248201526f185b1c9958591e48191a5cd8589b195960821b6044820152fd5b5090346200020d5760209182600319360112620001d85781359167ffffffffffffffff8311620002a05736602384011215620002a057828101359362000c468562000ff5565b9362000c558451958662000fd2565b8585528185016024809760051b8301019136831162000d40579087899594939201905b82821062000d13575050505062000c8e620010ca565b815b845181101562000d0f5762000ca58162001079565b50546001600160a01b039081169062000cbf8388620011e6565b5116813b15620002a057849188839288519485938492632ca9f88960e21b8452898401525af1801562000d05579062000cff9291620001bc575062001160565b62000c90565b85513d86823e3d90fd5b8280f35b939450919290919081356001600160a01b0381168103620009405781528894939291830190830162000c78565b8880fd5b5090826003193601126200020d57341562000e80578291835b84835482101562000e15575083600162000d778362001079565b500154803402903482040362000e02579061271062000d9892049062001186565b938562000dbc62000da98462001079565b50546001600160a01b0316928762001194565b91803b1562000439578585518094819363152111f760e01b83525af1801562000df8579062000df29291620001bc575062001160565b62000d5d565b83513d88823e3d90fd5b634e487b7160e01b875260118552602487fd5b83838262000e24883462001194565b8062000e2e575080f35b81808092335af162000e3f620011a2565b501562000e4a578280f35b906020606492519162461bcd60e51b8352820152601060248201526f18dbdd5b19081b9bdd081c99599d5b9960821b6044820152fd5b6020606492519162461bcd60e51b8352820152600a6024820152696e6f207265776172647360b01b6044820152fd5b508234620003925760203660031901126200039257823567ffffffffffffffff8111620004395762000ee590369085016200100e565b9062000ef0620010ca565b600293818555815b835181101562000f4b578062000f2062000f1762000f459387620011e6565b51885462001186565b875562000f2e8186620011e6565b51600162000f3c8362001079565b50015562001160565b62000ef8565b508361271086541162000f5c578280f35b906020606492519162461bcd60e51b835282015260086024820152676c7465203130302560c01b6044820152fd5b67ffffffffffffffff811162000f9f57604052565b634e487b7160e01b600052604160045260246000fd5b6040810190811067ffffffffffffffff82111762000f9f57604052565b90601f8019910116810190811067ffffffffffffffff82111762000f9f57604052565b67ffffffffffffffff811162000f9f5760051b60200190565b81601f820112156200107457803591620010288362000ff5565b9262001038604051948562000fd2565b808452602092838086019260051b82010192831162001074578301905b82821062001064575050505090565b8135815290830190830162001055565b600080fd5b600454811015620010b457600460005260011b7f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0190600090565b634e487b7160e01b600052603260045260246000fd5b6000546001600160a01b03163303620010df57565b60405163118cdaa760e01b8152336004820152602490fd5b600080546001600160a01b0319811682556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3565b90604051620011468162000fb5565b82546001600160a01b031681526001909201546020830152565b6000198114620011705760010190565b634e487b7160e01b600052601160045260246000fd5b919082018092116200117057565b919082039182116200117057565b3d15620011e1573d9067ffffffffffffffff821162000f9f5760405191620011d5601f8201601f19166020018462000fd2565b82523d6000602084013e565b606090565b8051821015620010b45760209160051b010190565b906200122457508051156200121257805190602001fd5b604051630a12f52160e11b8152600490fd5b8151158062001259575b62001237575090565b604051639996b31560e01b81526001600160a01b039091166004820152602490fd5b50803b156200122e56fe60a0346100ec57601f61173338819003918201601f19168301916001600160401b038311848410176100f1578084926060946040528339810103126100ec5761004781610107565b610058604060208401519301610107565b33156100d3576000549260018060a01b031933818616176000556040519460018060a01b03948591823391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3600180551690600254161760025560035516608052611617908161011c8239608051816113a70152f35b604051631e4fbdf760e01b815260006004820152602490fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b03821682036100ec5756fe608060408181526004918236101561001657600080fd5b600092833560e01c9182630700037d14610847575081630e15561a14610828578163152111f7146108125781632d5537b0146107e95781632e17de78146107b2578163315a095d146106fc5781633c6e6789146106dd57816341aef16214610659578163472f13f3146105f7578163715018a61461059d57816380bb40551461057f57816389d96917146105525781638da5cb5b1461052a578163953194351461036e578163a694fc3a14610322578163b2a7e224146102d9578163c771c39014610277578163c7e1d0b114610258578163ce7c2ac214610216578163ee947a7c146101f7578163efca2eed146101d8578163f2fde38b1461014d575063fc0c546a1461012257600080fd5b3461014957816003193601126101495760025490516001600160a01b039091168152602090f35b5080fd5b9050346101d45760203660031901126101d457610168610887565b90610171610911565b6001600160a01b039182169283156101be57505082546001600160a01b0319811683178455167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b51631e4fbdf760e01b8152908101849052602490fd5b8280fd5b505034610149578160031936011261014957602090600a549051908152f35b5050346101495781600319360112610149576020906003549051908152f35b505034610149576020366003190112610149579081906001600160a01b0361023c610887565b1681526007602052206001815491015482519182526020820152f35b5050346101495781600319360112610149576020906009549051908152f35b9050346101d45760203660031901126101d457803591610295610911565b6301e133808310156102a957505060035580f35b906020606492519162461bcd60e51b8352820152600a602482015269363a329018903cb2b0b960b11b6044820152fd5b83903461014957602036600319011261014957356001600160a01b0381169081900361014957610307610911565b6bffffffffffffffffffffffff60a01b600654161760065580f35b8390346101495781602036600319011261036b576103649135610343610abd565b60025461035e908290309033906001600160a01b031661093d565b33610bb5565b6001805580f35b80fd5b9050346101d457816003193601126101d45767ffffffffffffffff90803582811161052657366023820112156105265780820135906103ac826108f9565b946103b9815196876108d7565b8286526020918287016024809560051b830101913683116104fb578501905b8282106105035750505082359485116104ff57366023860112156104ff578484013594610404866108f9565b95610411835197886108d7565b808752848488019160051b830101913683116104fb5785859101915b8383106104eb5750505050610440610abd565b85518551036104c35750505050829183925b81518410156104a8576104736104a29161046c8686610b38565b5190610b4c565b9361049d866001600160a01b0361048a8487610b38565b51166104968488610b38565b5190610bb5565b610ae0565b92610452565b600254859161036491309033906001600160a01b031661093d565b5162461bcd60e51b81529283015260069082015265494e53594e4360d01b6044820152606490fd5b823581529181019185910161042d565b8980fd5b8680fd5b81356001600160a01b03811681036105225781529084019084016103d8565b8a80fd5b8480fd5b505034610149578160031936011261014957905490516001600160a01b039091168152602090f35b50503461014957602036600319011261014957602090610578610573610887565b611559565b9051908152f35b9050346101d457826003193601126101d45760209250549051908152f35b833461036b578060031936011261036b576105b6610911565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b9050346101d457816003193601126101d4573580151581036101d4577f63e32091e4445d16e29c33a6b264577c2d86694021aa4e6f4dd590048f5792e89161064d602092610643610abd565b6024359033611138565b51338152a16001805580f35b50503461014957606036600319011261014957610674610887565b6024359081151582036106d9577f63e32091e4445d16e29c33a6b264577c2d86694021aa4e6f4dd590048f5792e8926106c36020936106b1610abd565b6106b9610911565b6044359084611138565b516001600160a01b039091168152a16001805580f35b8380fd5b5050346101495781600319360112610149576020906005549051908152f35b919050346101d45760203660031901126101d45781359061071b610911565b6002546001600160a01b031691806107a557508051926370a0823160e01b84523090840152602083602481855afa90811561079c57508390610769575b6107669250905b3390610b59565b80f35b506020823d8211610794575b81610782602093836108d7565b810103126101d4576107669151610758565b3d9150610775565b513d85823e3d90fd5b905061076692509061075f565b83903461014957602036600319011261014957600161036491356107d4610abd565b61035e81838060a01b03600254163390610b59565b50503461014957816003193601126101495760065490516001600160a01b039091168152602090f35b838060031936011261036b576107663433610ff5565b505034610149578160031936011261014957602090600b549051908152f35b8390853461036b57602036600319011261036b5782906001600160a01b0361086d610887565b168152600860205220600181549101549082526020820152f35b600435906001600160a01b038216820361089d57565b600080fd5b600091031261089d57565b67ffffffffffffffff81116108c157604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff8211176108c157604052565b67ffffffffffffffff81116108c15760051b60200190565b6000546001600160a01b0316330361092557565b60405163118cdaa760e01b8152336004820152602490fd5b6040516323b872dd60e01b60208201526001600160a01b03928316602482015292909116604483015260648083019390935291815260a081019181831067ffffffffffffffff8411176108c15761099692604052610998565b565b60018060a01b0316906109c2600080836020829551910182875af16109bb610a1a565b9084610a5a565b9081519182151592836109f2575b5050506109da5750565b60249060405190635274afe760e01b82526004820152fd5b81929350906020918101031261014957602001519081159182150361036b57503880806109d0565b3d15610a55573d9067ffffffffffffffff82116108c15760405191610a49601f8201601f1916602001846108d7565b82523d6000602084013e565b606090565b90610a815750805115610a6f57805190602001fd5b604051630a12f52160e11b8152600490fd5b81511580610ab4575b610a92575090565b604051639996b31560e01b81526001600160a01b039091166004820152602490fd5b50803b15610a8a565b600260015414610ace576002600155565b604051633ee5aeb560e01b8152600490fd5b6000198114610aef5760010190565b634e487b7160e01b600052601160045260246000fd5b805115610b125760200190565b634e487b7160e01b600052603260045260246000fd5b805160011015610b125760400190565b8051821015610b125760209160051b010190565b91908201809211610aef57565b60405163a9059cbb60e01b60208201526001600160a01b039092166024830152604480830193909352918152608081019167ffffffffffffffff8311828410176108c15761099692604052610998565b6040513d6000823e3d90fd5b600654919290916001600160a01b039190821680610c51575b5015610c1357610bde8383610e6b565b60405192835216907f85082129d87b2fe11527cb1b3b7a520aeb5aa6913f88a3d8757fe40d1db02fdd9080602081015b0390a2565b610c1d8383610cb0565b60405192835216907febedb8b3c678666e7f36970bc8f57abf6d8fa2e828c0da91ea5b75bf68ed101a908060208101610c0e565b803b1561089d576040516329cc05cf60e01b81526001600160a01b0385166004820152602481018690528215156044820152906000908290606490829084905af115610bce5780610ca4610caa926108ad565b806108a2565b38610bce565b9060018060a01b0382166000526007602052604060002054610dca575b6001600160a01b03821660009081526007602052604090205490610cfb610cf682600554610b4c565b600555565b6001600160a01b0383166000908152600760205260409020610d1f90918254610b4c565b90556001600160a01b03821660009081526007602052604090204290600101551580610da9575b610d91575b6001600160a01b0381166000908152600760205260409020610d8e90610d72905b546115c0565b6001600160a01b03909216600090815260086020526040902090565b55565b610da4610d9f600454610ae0565b600455565b610d4b565b506001600160a01b0381166000908152600760205260409020541515610d46565b610dd660008084611138565b610ccd565b15610de257565b60405162461bcd60e51b815260206004820152600b60248201526a1491534e88185b5bdd5b9d60aa1b6044820152606490fd5b15610e1c57565b60405162461bcd60e51b815260206004820152600d60248201526c52454d3a2074696d656c6f636b60981b6044820152606490fd5b91908203918211610aef57565b8015610aef576000190190565b6001600160a01b038116600090815260076020526040902090919054151580610fc0575b610e9890610ddb565b610ece610ec76001610ebc8560018060a01b03166000526007602052604060002090565b015460035490610b4c565b4211610e15565b610ed782611559565b90610ee481600554610e51565b1590811591610faf575b610efd610cf682600554610e51565b6001600160a01b0384166000908152600760205260409020610f2190918254610e51565b90556001600160a01b03831660009081526007602052604090205415610f9c575b6001600160a01b0383166000908152600760205260409020610f6390610d6c565b6001600160a01b03841660009081526008602052604090205580610f93575b610f8a575050565b61099691610ff5565b50801515610f82565b610faa610d9f600454610e5e565b610f42565b610fbb60008086611138565b610eee565b506001600160a01b038216600090815260076020526040902054811115610e8f565b81810292918115918404141715610aef57565b81156110a55760055480156110775761101083600b54610b4c565b600b556ec097ce7bc90715b34b9f1000000000918383029283048403610aef576110616020927fb9ad861b752f80117b35bea6dec99933d8a5ae360f2839ee8784b750d56134099404600954610b4c565b6009556040519384526001600160a01b031692a2565b60405162461bcd60e51b815260206004820152600660248201526553484152455360d01b6044820152606490fd5b60405162461bcd60e51b815260206004820152600360248201526208aa8960eb1b6044820152606490fd5b156110d757565b60405162461bcd60e51b8152602060048201526005602482015264044495354360dc1b6044820152606490fd5b1561110b57565b60405162461bcd60e51b8152602060048201526005602482015264444953543160d81b6044820152606490fd5b6001600160a01b038116600090815260076020526040902090919054156112bf576001600160a01b038216600090815260076020526040902042906001015561118082611559565b92600161119f8460018060a01b03166000526008602052604060002090565b016111ab858254610b4c565b90556001600160a01b03831660009081526007602052604090206111ce90610d6c565b6001600160a01b038416600090815260086020526040902055836111f3575b50505050565b61120761120285600a54610b4c565b600a55565b811561125e57611218908484611383565b7ff34664cb7e3473d9bcd089297cc2ec340fede133eaf733d0ca506f1e05e2fee0915b6040805194855291151560208501526001600160a01b031692a2388080806111ed565b507ff34664cb7e3473d9bcd089297cc2ec340fede133eaf733d0ca506f1e05e2fee0916112ba476112a860008080808a6001600160a01b0389165af16112a2610a1a565b506110d0565b6112b3864792610e51565b1115611104565b61123b565b505050565b604051906060820182811067ffffffffffffffff8211176108c15760405260028252604082602036910137565b9081602091031261089d57516001600160a01b038116810361089d5790565b9081602091031261089d575190565b9190949392946080830190835260209060808285015282518091528160a0850193019160005b8281106113665750505050906060919460018060a01b031660408201520152565b83516001600160a01b031685529381019392810192600101611345565b61138b6112c4565b6040516315ab88c960e31b815290936020916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116918481600481865afa80156114f5576113fc9160009161152c575b506113ed89610b05565b6001600160a01b039091169052565b6002546001600160a01b0316611415816113ed8a610b28565b6040516370a0823160e01b80825230600483015290989190921696919285896024818b5afa9889156114f55760009961150d575b50803b1561089d5760405163b6f9de9560e01b81529460009386938492839161147991429130916004860161131f565b03925af19182156114f55783926114fa575b5060405190815230600482015293849060249082905afa9384156114f557610996946000946114c29386926114c8575b5050610e51565b90610bb5565b6114e79250803d106114ee575b6114df81836108d7565b810190611310565b38806114bb565b503d6114d5565b610ba9565b80610ca4611507926108ad565b3861148b565b611525919950863d88116114ee576114df81836108d7565b9738611449565b61154c9150863d8811611552575b61154481836108d7565b8101906112f1565b386113e3565b503d61153a565b6001600160a01b031660008181526007602052604081205490919080156115bb576115976ec097ce7bc90715b34b9f10000000009160095490610fe2565b049082526008602052604082205490818111156115bb576115b89250610e51565b90565b505090565b6115dd6ec097ce7bc90715b34b9f10000000009160095490610fe2565b049056fea2646970667358221220c0b0032b60d01a795b68072b5e6741297cbbbefd14af912d5afcd6a0f44e487364736f6c63430008140033a2646970667358221220bc51d40b71a07f9b9a3c96b7e9cf35b3c53d2bfff64bdd6147ff9c84dd5cf44164736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000008e0eef788350f40255d86dfe8d91ec0ad3a4547f
-----Decoded View---------------
Arg [0] : _stakingToken (address): 0x8e0EeF788350f40255D86DFE8D91ec0AD3a4547F
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000008e0eef788350f40255d86dfe8d91ec0ad3a4547f
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.