Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers.
Latest 4 internal transactions
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
TimedLocker
Compiler Version
v0.8.26+commit.8a97fa7a
Contract Source Code (Solidity)
/**
*Submitted for verification at fraxscan.com on 2024-06-13
*/
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.8.0;
// node_modules/@openzeppelin/contracts/security/ReentrancyGuard.sol
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
/**
* @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;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
// node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
/**
* @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 amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
// node_modules/@openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with 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;
}
}
// node_modules/@openzeppelin/contracts/utils/math/Math.sol
// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1);
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`.
// We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.
// This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.
// Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a
// good first aproximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1;
uint256 x = a;
if (x >> 128 > 0) {
x >>= 128;
result <<= 64;
}
if (x >> 64 > 0) {
x >>= 64;
result <<= 32;
}
if (x >> 32 > 0) {
x >>= 32;
result <<= 16;
}
if (x >> 16 > 0) {
x >>= 16;
result <<= 8;
}
if (x >> 8 > 0) {
x >>= 8;
result <<= 4;
}
if (x >> 4 > 0) {
x >>= 4;
result <<= 2;
}
if (x >> 2 > 0) {
result <<= 1;
}
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
uint256 result = sqrt(a);
if (rounding == Rounding.Up && result * result < a) {
result += 1;
}
return result;
}
}
// src/contracts/Miscellany/OwnedV2.sol
// https://docs.synthetix.io/contracts/Owned
contract OwnedV2 {
error OwnerCannotBeZero();
error InvalidOwnershipAcceptance();
error OnlyOwner();
address public owner;
address public nominatedOwner;
constructor(address _owner) {
// require(_owner != address(0), "Owner address cannot be 0");
if (_owner == address(0)) revert OwnerCannotBeZero();
owner = _owner;
emit OwnerChanged(address(0), _owner);
}
function nominateNewOwner(address _owner) external onlyOwner {
nominatedOwner = _owner;
emit OwnerNominated(_owner);
}
function acceptOwnership() external {
// require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership");
if (msg.sender != nominatedOwner) revert InvalidOwnershipAcceptance();
emit OwnerChanged(owner, nominatedOwner);
owner = nominatedOwner;
nominatedOwner = address(0);
}
modifier onlyOwner() {
// require(msg.sender == owner, "Only the contract owner may perform this action");
if (msg.sender != owner) revert OnlyOwner();
_;
}
event OwnerNominated(address newOwner);
event OwnerChanged(address oldOwner, address newOwner);
}
// src/contracts/Miscellany/interfaces/IERC20PermitPermissionedOptiMintable.sol
// @version 0.2.8
interface IERC20PermitPermissionedOptiMintable {
function BRIDGE() external view returns (address);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function REMOTE_TOKEN() external view returns (address);
function acceptOwnership() external;
function addMinter(address minter_address) external;
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function balanceOf(address account) external view returns (uint256);
function bridge() external view returns (address);
function burn(uint256 value) external;
function burn(address _from, uint256 _amount) external;
function burnFrom(address account, uint256 value) external;
function decimals() external view returns (uint8);
function eip712Domain()
external
view
returns (
bytes1 fields,
string memory name,
string memory version,
uint256 chainId,
address verifyingContract,
bytes32 salt,
uint256[] memory extensions
);
function l1Token() external view returns (address);
function l2Bridge() external view returns (address);
function mint(address _to, uint256 _amount) external;
function minter_burn_from(address b_address, uint256 b_amount) external;
function minter_mint(address m_address, uint256 m_amount) external;
function minters(address) external view returns (bool);
function minters_array(uint256) external view returns (address);
function name() external view returns (string memory);
function nominateNewOwner(address _owner) external;
function nominatedOwner() external view returns (address);
function nonces(address owner) external view returns (uint256);
function owner() external view returns (address);
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function remoteToken() external view returns (address);
function removeMinter(address minter_address) external;
function setTimelock(address _timelock_address) external;
function supportsInterface(bytes4 _interfaceId) external pure returns (bool);
function symbol() external view returns (string memory);
function timelock_address() external view returns (address);
function totalSupply() external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
function version() external view returns (string memory);
}
// src/contracts/VestedFXS-and-Flox/Flox/TransferHelper.sol
// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
error TransferHelperApproveFailed();
error TransferHelperTransferFailed();
error TransferHelperTransferFromFailed();
error TransferHelperTransferETHFailed();
function safeApprove(address token, address to, uint256 value) internal {
// bytes4(keccak256(bytes('approve(address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
// require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED');
if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert TransferHelperApproveFailed();
}
function safeTransfer(address token, address to, uint256 value) internal {
// bytes4(keccak256(bytes('transfer(address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
// require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED');
if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert TransferHelperTransferFailed();
}
function safeTransferFrom(address token, address from, address to, uint256 value) internal {
// bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
// require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED');
if (!success || (data.length != 0 && !abi.decode(data, (bool)))) revert TransferHelperTransferFromFailed();
}
function safeTransferETH(address to, uint256 value) internal {
(bool success, ) = to.call{ value: value }(new bytes(0));
// require(success, 'TransferHelper: ETH_TRANSFER_FAILED');
if (!success) revert TransferHelperTransferETHFailed();
}
}
// node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
// node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* The default value of {decimals} is 18. To select a different value for
* {decimals} you should overload it.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless this function is
* overridden;
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
}
_balances[to] += amount;
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
// src/contracts/Miscellany/TimedLocker.sol
// @version 0.2.8
/**
* ====================================================================
* | ______ _______ |
* | / _____________ __ __ / ____(_____ ____ _____ ________ |
* | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
* | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
* | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
* | |
* ====================================================================
* =========================== TimedLocker ============================
* ====================================================================
* Fixed-rate FXS rewards for locking tokens.
* Total amount of staking token lockable is capped
* Locked positions are transferable as vault tokens
* After a set ending timestamp, all positions are unlockable
* Frax Finance: https://github.com/FraxFinance
*/
// import "forge-std/console2.sol";
contract TimedLocker is ERC20, OwnedV2, ReentrancyGuard {
/* ========== STATE VARIABLES ========== */
// Core variables
// ----------------------------------------
/// @notice When the locker was deployed
uint256 public immutable deployTimestamp;
/// @notice When the locker ends
uint256 public immutable endingTimestamp;
/// @notice Maximum amount of staking token that can be staked
uint256 public immutable cap;
/// @notice The token being staked
ERC20 public stakingToken;
// Global reward-related
// ----------------------------------------
/// @notice Helper to see if a token is a reward token on this locker
mapping(address => bool) public isRewardToken;
/// @notice The last time rewards were sent in
uint256 public lastRewardPull;
/// @notice The last time this contract was updated
uint256 public lastUpdateTime;
/// @notice The time the rewards period should finish. Should be endingTimestamp
uint256 public immutable periodFinish;
/// @notice The duration of the reward period. Should be endingTimestamp - deploy block.timestamp
uint256 public immutable rewardsDuration;
/// @notice Mapping of addresses that are allowed to deposit reward tokens
mapping(address => bool) public rewardNotifiers;
/// @notice Accumulator for rewardsPerToken
// https://www.paradigm.xyz/2021/05/liquidity-mining-on-uniswap-v3
uint256[] public rewardsPerTokenStored;
/// @notice The reward tokens per second
uint256[] public rewardRates;
/// @notice Helper to get the reward token index, given the address of the token
mapping(address => uint256) public rewardTokenAddrToIdx;
/// @notice Array of all the reward tokens
address[] public rewardTokens;
// User reward-related
// ----------------------------------------
/// @notice The last time a farmer claimed their rewards
mapping(address => uint256) public lastRewardClaimTime; // staker addr -> timestamp
/// @notice Used for tracking stored/collectible rewards. earned()
mapping(address => mapping(uint256 => uint256)) public rewards; // staker addr -> token id -> reward amount
/// @notice Accumulator for userRewardsPerTokenPaid
mapping(address => mapping(uint256 => uint256)) public userRewardsPerTokenPaid; // staker addr -> token id -> paid amount
// Emergency variables
// ----------------------------------------
/// @notice If external syncEarned calls via bulkSyncEarnedUsers are allowed
bool public externalSyncEarningPaused;
/// @notice If reward collections are paused
bool public rewardsCollectionPaused;
/// @notice If staking is paused
bool public stakingPaused;
/// @notice Release locked stakes in case of system migration or emergency
bool public stakesUnlocked;
// For emergencies if a token is overemitted or something else. Only callable once.
// Bypasses certain logic, which will cause reward calculations to be off
// But the goal is for the users to recover LP, and they couldn't claim the erroneous rewards anyways.
// Reward reimbursement claims would be handled with pre-issue earned() snapshots and a claim contract, or similar.
bool public withdrawalOnlyShutdown;
/// @notice If withdrawals are paused
bool public withdrawalsPaused;
/* ========== CONSTRUCTOR ========== */
/// @notice Constructor
/// @param _owner The owner of the locker
/// @param _rewardTokens Array of reward tokens
/// @param _name Name for the vault token
/// @param _symbol Symbol for the vault token
/// @param _stakingToken The token being staked
/// @param _endingTimestamp Timestamp when all locks become unlocked
/// @param _cap Maximum amount of staking tokens allowed to be locked
/// @param _extraNotifier Additional reward notifier to add when constructing. Can add more / remove later
constructor(
address _owner,
address[] memory _rewardTokens,
address _stakingToken,
string memory _name,
string memory _symbol,
uint256 _endingTimestamp,
uint256 _cap,
address _extraNotifier
) ERC20(_name, _symbol) OwnedV2(_owner) {
// Set state variables
stakingToken = ERC20(_stakingToken);
rewardTokens = _rewardTokens;
endingTimestamp = _endingTimestamp;
cap = _cap;
// Loop through the reward tokens
for (uint256 i = 0; i < _rewardTokens.length; i++) {
// For fast token address -> token ID lookups later
rewardTokenAddrToIdx[_rewardTokens[i]] = i;
// Add to the mapping
isRewardToken[_rewardTokens[i]] = true;
// Initialize the stored rewards
rewardsPerTokenStored.push(0);
// Initialize the reward rates
rewardRates.push(0);
}
// Set the owner as an allowed reward notifier
rewardNotifiers[_owner] = true;
// Add the additional reward notifier, if present
if (_extraNotifier != address(0)) rewardNotifiers[_extraNotifier] = true;
// Other booleans
stakesUnlocked = false;
// For initialization
deployTimestamp = block.timestamp;
lastUpdateTime = block.timestamp;
rewardsDuration = _endingTimestamp - block.timestamp;
periodFinish = _endingTimestamp;
}
/* ========== MODIFIERS ========== */
/// @notice Staking should not be paused
modifier notStakingPaused() {
require(!stakingPaused, "Staking paused");
_;
}
/// @notice Update rewards and balances
modifier updateRewards(address account) {
_updateRewards(account);
_;
}
/* ========== VIEWS ========== */
/// @notice Remaining amount of stakingToken you can lock before hitting the cap
/// @return _amount The amount
function availableToLock() public view returns (uint256 _amount) {
_amount = (cap - totalSupply());
}
/// @notice The last time rewards were applicable. Should be the lesser of the current timestamp, or the end of the last period
/// @return uint256 The last timestamp where rewards were applicable
function lastTimeRewardApplicable() internal view returns (uint256) {
return Math.min(block.timestamp, periodFinish);
}
/// @notice The calculated rewardPerTokenStored accumulator
/// @return _rtnRewardsPerTokenStored Array of rewardsPerTokenStored
function rewardPerToken() public view returns (uint256[] memory _rtnRewardsPerTokenStored) {
// Prepare the return variable
_rtnRewardsPerTokenStored = new uint256[](rewardTokens.length);
// Calculate
if (totalSupply() == 0) {
// Return 0 if there are no vault tokens
_rtnRewardsPerTokenStored = rewardsPerTokenStored;
} else {
// Loop through the reward tokens
for (uint256 i = 0; i < rewardTokens.length; ) {
_rtnRewardsPerTokenStored[i] =
rewardsPerTokenStored[i] +
(((lastTimeRewardApplicable() - lastUpdateTime) * rewardRates[i] * 1e18) / totalSupply());
unchecked {
++i;
}
}
}
}
/// @notice The currently earned rewards for a user
/// @param _account The staker's address
/// @return _rtnEarned Array of the amounts of reward tokens the staker can currently collect
function earned(address _account) public view returns (uint256[] memory _rtnEarned) {
// Prepare the return variable
_rtnEarned = new uint256[](rewardTokens.length);
// Get the reward rate per token
uint256[] memory _rtnRewardsPerToken = rewardPerToken();
// Loop through the reward tokens
for (uint256 i = 0; i < rewardTokens.length; ) {
_rtnEarned[i] =
rewards[_account][i] +
((balanceOf(_account) * ((_rtnRewardsPerToken[i] - userRewardsPerTokenPaid[_account][i]))) / 1e18);
unchecked {
++i;
}
}
}
/// @notice Amount of rewards remaining
/// @return _rtnRewardsRemaining Array of the amounts of the reward tokens
function getRewardsRemaining() external view returns (uint256[] memory _rtnRewardsRemaining) {
// Prepare the return variable
_rtnRewardsRemaining = new uint256[](rewardTokens.length);
// Return 0 if the locker has already ended
if (endingTimestamp <= block.timestamp) return _rtnRewardsRemaining;
// See how much time is left
uint256 _timeLeft = endingTimestamp - block.timestamp;
// Calculate the duration rewards
for (uint256 i = 0; i < rewardTokens.length; ) {
_rtnRewardsRemaining[i] = rewardRates[i] * _timeLeft;
unchecked {
++i;
}
}
}
/* ========== ERC20 OVERRIDES ========== */
/// @notice Override the _update logic to claim/sync earnings before transferring.
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 value) internal override {
// TODO for auditors: Make sure this is not manipulatable
// If you aren't minting, sync rewards first so the owner doesn't lose them after transferring
// Also so the recipient doesn't get free rewards
// withdrawalOnlyShutdown sacrifices rewards buts lets the token move, for emergencies only.
if (!withdrawalOnlyShutdown && (from != address(0))) {
sync();
_syncEarnedInner(from);
_syncEarnedInner(to);
}
}
/* ========== MUTATIVE FUNCTIONS ========== */
/// @notice Sync earnings for many users. Convenience function
/// @param _users The account to sync
/// @dev _beforeTokenTransfer essentially does this
function bulkSyncEarnedUsers(address[] memory _users) external {
// Check for withdrawal-only shutdown as well as the pause
if (withdrawalOnlyShutdown || externalSyncEarningPaused) revert ExternalSyncEarningPaused();
// Sync normally first
sync();
// Loop through the users and sync them. Skip global sync() to save gas
for (uint256 i = 0; i < _users.length; ) {
_syncEarnedInner(_users[i]);
unchecked {
++i;
}
}
}
/// @notice Sync contract-wide variables
function sync() public {
// Update rewardsPerTokenStored
rewardsPerTokenStored = rewardPerToken();
// Update the last update time
lastUpdateTime = lastTimeRewardApplicable();
}
/// @notice Update the reward and balance state for a staker
/// @param account The address of the user
function _updateRewards(address account) internal {
if (account != address(0)) {
// Calculate the earnings first
// Skip if we are in emergency shutdown
if (!withdrawalOnlyShutdown) _syncEarned(account);
}
}
/// @notice [MUST be proceeded by global sync()] Sync earnings for a specific staker. Skips the global sync() to save gas (mainly for bulkSyncEarnedUsers())
/// @param _account The account to sync
function _syncEarnedInner(address _account) internal {
if (_account != address(0)) {
// Calculate the earnings
uint256[] memory _earneds = earned(_account);
// Update the stake
for (uint256 i = 0; i < rewardTokens.length; ) {
rewards[_account][i] = _earneds[i];
userRewardsPerTokenPaid[_account][i] = rewardsPerTokenStored[i];
unchecked {
++i;
}
}
}
}
/// @notice Sync earnings for a specific staker
/// @param _account The account to sync
function _syncEarned(address _account) internal {
// Update rewardsPerTokenStored and last update time
sync();
// Sync the account's earnings
_syncEarnedInner(_account);
}
/// @notice Stake stakingToken for vault tokens
/// @param _amount The amount of stakingToken
function stake(uint256 _amount) public updateRewards(msg.sender) {
// Do checks
if (block.timestamp >= endingTimestamp) revert LockerHasEnded();
if (stakingPaused) revert StakingPaused();
if (stakesUnlocked) revert StakesAreUnlocked();
if (withdrawalOnlyShutdown) revert OnlyWithdrawalsAllowed();
if (_amount == 0) revert MustBeNonZero();
if ((totalSupply() + _amount) > cap) revert Capped();
// Pull the staking tokens from the msg.sender
TransferHelper.safeTransferFrom(address(stakingToken), msg.sender, address(this), _amount);
// Mint an equal amount of vault tokens to the staker
_mint(msg.sender, _amount);
// Update rewards
_updateRewards(msg.sender);
emit Stake(msg.sender, _amount, msg.sender);
}
/// @notice Withdraw stakingToken from vault tokens.
/// @param _vaultTknAmount Amount of vault tokens to use
/// @param _collectRewards Whether to also collect rewards
function withdraw(uint256 _vaultTknAmount, bool _collectRewards) public returns (uint256[] memory _rtnRewards) {
if ((block.timestamp < endingTimestamp) && !(stakesUnlocked || withdrawalOnlyShutdown)) {
revert LockerStillActive();
}
if (withdrawalsPaused) revert WithdrawalsPaused();
// Burn the vault token from the sender
_burn(msg.sender, _vaultTknAmount);
// Give the stakingToken to the msg.sender
// Should throw if insufficient balance
stakingToken.transfer(msg.sender, _vaultTknAmount);
// Collect rewards
_rtnRewards = new uint256[](rewardTokens.length);
if (_collectRewards) _rtnRewards = getReward(msg.sender);
emit Withdrawal(msg.sender, _vaultTknAmount);
}
/// @notice Collect rewards
/// @param _destinationAddress Destination address for the rewards
/// @return _rtnRewards The amounts of collected reward tokens
function getReward(
address _destinationAddress
) public updateRewards(msg.sender) returns (uint256[] memory _rtnRewards) {
// Make sure you are not in shutdown
if (withdrawalOnlyShutdown) revert OnlyWithdrawalsAllowed();
// Make sure reward collections are not paused
if (rewardsCollectionPaused) revert RewardCollectionIsPaused();
// Prepare the return variable
_rtnRewards = new uint256[](rewardTokens.length);
// Loop through the rewards
for (uint256 i = 0; i < rewardTokens.length; ) {
_rtnRewards[i] = rewards[msg.sender][i];
// Do reward accounting
if (_rtnRewards[i] > 0) {
rewards[msg.sender][i] = 0;
ERC20(rewardTokens[i]).transfer(_destinationAddress, _rtnRewards[i]);
emit RewardPaid(msg.sender, _rtnRewards[i], rewardTokens[i], _destinationAddress);
}
unchecked {
++i;
}
}
// Update the last reward claim time
lastRewardClaimTime[msg.sender] = block.timestamp;
}
/// @notice Supply rewards. Only callable by whitelisted addresses.
/// @param _amounts Amount of each reward token to add
function notifyRewardAmounts(uint256[] memory _amounts) external {
// Only whitelisted addresses can notify rewards
if (!rewardNotifiers[msg.sender]) revert SenderNotRewarder();
// Make sure the locker has not ended
if (block.timestamp >= endingTimestamp) revert LockerHasEnded();
// Pull in the reward tokens from the sender
for (uint256 i = 0; i < rewardTokens.length; ) {
// Handle the transfer of emission tokens via `transferFrom` to reduce the number
// of transactions required and ensure correctness of the emission amount
TransferHelper.safeTransferFrom(rewardTokens[i], msg.sender, address(this), _amounts[i]);
unchecked {
++i;
}
}
// Update rewardsPerTokenStored and last update time
sync();
// Calculate the reward rate
for (uint256 i = 0; i < rewardTokens.length; ) {
// Account for unemitted tokens
uint256 remainingTime = periodFinish - block.timestamp;
uint256 leftoverRwd = remainingTime * rewardRates[i];
// Replace rewardsDuration with remainingTime here since we only have one big period
// rewardRates[i] = (_amounts[i] + leftoverRwd) / rewardsDuration;
rewardRates[i] = (_amounts[i] + leftoverRwd) / remainingTime;
emit RewardAdded(rewardTokens[i], _amounts[i], rewardRates[i]);
unchecked {
++i;
}
}
// Update rewardsPerTokenStored and last update time (again)
sync();
}
/* ========== RESTRICTED FUNCTIONS ========== */
/// @notice Only settable to true
function initiateWithdrawalOnlyShutdown() external onlyOwner {
withdrawalOnlyShutdown = true;
}
/// @notice Added to support recovering LP Rewards and other mistaken tokens from other systems to be distributed to holders
/// @param tokenAddress The address of the token
/// @param tokenAmount The amount of the token
function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner {
// Only the owner address can ever receive the recovery withdrawal
ERC20(tokenAddress).transfer(owner, tokenAmount);
emit Recovered(tokenAddress, tokenAmount);
}
/// @notice Toggle the ability to syncEarned externally via bulkSyncEarnedUsers
function toggleExternalSyncEarning() external onlyOwner {
externalSyncEarningPaused = !externalSyncEarningPaused;
}
/// @notice Toggle the ability to stake
function toggleStaking() external onlyOwner {
stakingPaused = !stakingPaused;
}
/// @notice Toggle the ability to collect rewards
function toggleRewardsCollection() external onlyOwner {
rewardsCollectionPaused = !rewardsCollectionPaused;
}
/// @notice Toggle an address as being able to be a reward notifier
/// @param _notifierAddr The address to toggle
function toggleRewardNotifier(address _notifierAddr) external onlyOwner {
rewardNotifiers[_notifierAddr] = !rewardNotifiers[_notifierAddr];
}
/// @notice Toggle the ability to withdraw
function toggleWithdrawals() external onlyOwner {
withdrawalsPaused = !withdrawalsPaused;
}
/// @notice Unlock all stakes, in the case of an emergency
function unlockStakes() external onlyOwner {
stakesUnlocked = !stakesUnlocked;
}
/* ========== ERRORS ========== */
/// @notice When you are trying to lock more tokens than are allowed
error Capped();
/// @notice If syncEarned should only be callable indirectly through methods or internally. Also occurs if in a withdrawal-only shutdown
error ExternalSyncEarningPaused();
/// @notice If the locker ending timestamp has passed
error LockerHasEnded();
/// @notice If the locker ending timestamp has not yet passed
error LockerStillActive();
/// @notice If an input value must be non-zero
error MustBeNonZero();
/// @notice If only withdrawals are allowed
error OnlyWithdrawalsAllowed();
/// @notice If reward collections are paused
error RewardCollectionIsPaused();
/// @notice If the sender is not a rewarder
error SenderNotRewarder();
/// @notice If staking has been paused
error StakingPaused();
/// @notice If you are trying to stake after stakes have been unlock
error StakesAreUnlocked();
/// @notice If you didn't acknowledge the notifyRewardAmounts sync warning
error MustSyncAllUsersBeforeNotifying();
/// @notice If withdrawals have been paused
error WithdrawalsPaused();
/* ========== EVENTS ========== */
/// @notice When LP tokens are locked
/// @param user The staker
/// @param amount Amount of LP staked
/// @param source_address The origin address of the LP tokens. Usually the same as the user unless there is a migration in progress
event Stake(address indexed user, uint256 amount, address source_address);
/// @notice When LP tokens are withdrawn
/// @param user The staker
/// @param amount Amount of LP withdrawn
event Withdrawal(address indexed user, uint256 amount);
/// @notice When tokens are recovered, in the case of an emergency
/// @param token Address of the token
/// @param amount Amount of the recovered tokens
event Recovered(address token, uint256 amount);
/// @notice When a reward is deposited
/// @param reward_address The address of the reward token
/// @param reward Amount of tokens deposited
/// @param yieldRate The resultant yield/emission rate
event RewardAdded(address indexed reward_address, uint256 reward, uint256 yieldRate);
/// @notice When a staker collects rewards
/// @param user The staker
/// @param reward Amount of reward tokens
/// @param token_address Address of the reward token
/// @param destination_address Destination address of the reward tokens
event RewardPaid(address indexed user, uint256 reward, address token_address, address destination_address);
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address[]","name":"_rewardTokens","type":"address[]"},{"internalType":"address","name":"_stakingToken","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_endingTimestamp","type":"uint256"},{"internalType":"uint256","name":"_cap","type":"uint256"},{"internalType":"address","name":"_extraNotifier","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Capped","type":"error"},{"inputs":[],"name":"ExternalSyncEarningPaused","type":"error"},{"inputs":[],"name":"InvalidOwnershipAcceptance","type":"error"},{"inputs":[],"name":"LockerHasEnded","type":"error"},{"inputs":[],"name":"LockerStillActive","type":"error"},{"inputs":[],"name":"MustBeNonZero","type":"error"},{"inputs":[],"name":"MustSyncAllUsersBeforeNotifying","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[],"name":"OnlyWithdrawalsAllowed","type":"error"},{"inputs":[],"name":"OwnerCannotBeZero","type":"error"},{"inputs":[],"name":"RewardCollectionIsPaused","type":"error"},{"inputs":[],"name":"SenderNotRewarder","type":"error"},{"inputs":[],"name":"StakesAreUnlocked","type":"error"},{"inputs":[],"name":"StakingPaused","type":"error"},{"inputs":[],"name":"TransferHelperTransferFromFailed","type":"error"},{"inputs":[],"name":"WithdrawalsPaused","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reward_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"yieldRate","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"address","name":"token_address","type":"address"},{"indexed":false,"internalType":"address","name":"destination_address","type":"address"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"source_address","type":"address"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawal","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"availableToLock","outputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"}],"name":"bulkSyncEarnedUsers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deployTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256[]","name":"_rtnEarned","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endingTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"externalSyncEarningPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_destinationAddress","type":"address"}],"name":"getReward","outputs":[{"internalType":"uint256[]","name":"_rtnRewards","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getRewardsRemaining","outputs":[{"internalType":"uint256[]","name":"_rtnRewardsRemaining","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initiateWithdrawalOnlyShutdown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isRewardToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastRewardClaimTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRewardPull","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"notifyRewardAmounts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardNotifiers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerToken","outputs":[{"internalType":"uint256[]","name":"_rtnRewardsPerTokenStored","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardRates","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardTokenAddrToIdx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsCollectionPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardsPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakesUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sync","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleExternalSyncEarning","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_notifierAddr","type":"address"}],"name":"toggleRewardNotifier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleRewardsCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleStaking","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockStakes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userRewardsPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vaultTknAmount","type":"uint256"},{"internalType":"bool","name":"_collectRewards","type":"bool"}],"name":"withdraw","outputs":[{"internalType":"uint256[]","name":"_rtnRewards","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawalOnlyShutdown","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalsPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]Contract Creation Code
610120604052348015610010575f80fd5b5060405161384738038061384783398101604081905261002f91610457565b878585600361003e83826105b0565b50600461004b82826105b0565b5050506001600160a01b03811661007557604051639b15e16f60e01b815260040160405180910390fd5b600580546001600160a01b0319166001600160a01b038316908117909155604080515f815260208101929092527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1506001600755600880546001600160a01b0319166001600160a01b03881617905586516101019060109060208a0190610290565b5060a083905260c08290525f5b875181101561020c5780600f5f8a848151811061012d5761012d61066a565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2081905550600160095f8a848151811061016f5761016f61066a565b6020908102919091018101516001600160a01b031682528101919091526040015f908120805460ff191692151592909217909155600d805460018181019092557fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb501829055600e805480830182559083527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd01919091550161010e565b506001600160a01b038089165f908152600c60205260409020805460ff1916600117905581161561025a576001600160a01b0381165f908152600c60205260409020805460ff191660011790555b6014805463ff00000019169055426080819052600b81905561027c908461067e565b61010052505060e052506106a39350505050565b828054828255905f5260205f209081019282156102e3579160200282015b828111156102e357825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906102ae565b506102ef9291506102f3565b5090565b5b808211156102ef575f81556001016102f4565b80516001600160a01b038116811461031d575f80fd5b919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561035e5761035e610322565b604052919050565b5f82601f830112610375575f80fd5b81516001600160401b0381111561038e5761038e610322565b8060051b61039e60208201610336565b918252602081850181019290810190868411156103b9575f80fd5b6020860192505b838310156103e2576103d183610307565b8252602092830192909101906103c0565b9695505050505050565b5f82601f8301126103fb575f80fd5b81516001600160401b0381111561041457610414610322565b610427601f8201601f1916602001610336565b81815284602083860101111561043b575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f805f805f805f80610100898b03121561046f575f80fd5b61047889610307565b60208a01519098506001600160401b03811115610493575f80fd5b61049f8b828c01610366565b9750506104ae60408a01610307565b60608a01519096506001600160401b038111156104c9575f80fd5b6104d58b828c016103ec565b60808b015190965090506001600160401b038111156104f2575f80fd5b6104fe8b828c016103ec565b60a08b015160c08c01519196509450925061051d905060e08a01610307565b90509295985092959890939650565b600181811c9082168061054057607f821691505b60208210810361055e57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156105ab57805f5260205f20601f840160051c810160208510156105895750805b601f840160051c820191505b818110156105a8575f8155600101610595565b50505b505050565b81516001600160401b038111156105c9576105c9610322565b6105dd816105d7845461052c565b84610564565b6020601f82116001811461060f575f83156105f85750848201515b5f19600385901b1c1916600184901b1784556105a8565b5f84815260208120601f198516915b8281101561063e578785015182556020948501946001909201910161061e565b508482101561065b57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b634e487b7160e01b5f52603260045260245ffd5b8181038181111561069d57634e487b7160e01b5f52601160045260245ffd5b92915050565b60805160a05160c05160e0516101005161312861071f5f395f61046501525f81816108490152818161159a0152612b3401525f818161043e01528181610f9f015261193601525f818161052f01528181610c140152818161101501528181611043015281816114b401526117d801525f61055601526131285ff3fe608060405234801561000f575f80fd5b5060043610610366575f3560e01c806372f702f3116101c9578063b933ceac116100fe578063dd62ed3e1161009e578063e9f2838e11610079578063e9f2838e1461082e578063ebe2b12b14610844578063f2caeb1e1461086b578063fff6cae91461087e575f80fd5b8063dd62ed3e146107d9578063dfa43f921461081e578063e1ba95d214610826575f80fd5b8063c8f33c91116100d9578063c8f33c911461079e578063cd3daf9d146107a7578063d15166ff146107af578063d239f003146107d1575f80fd5b8063b933ceac1461074e578063bbb781cc14610778578063c00007b01461078b575f80fd5b806395d89b4111610169578063a457c2d711610144578063a457c2d7146106f3578063a694fc3a14610706578063a9059cbb14610719578063b5fd73f81461072c575f80fd5b806395d89b41146106c457806396234502146106cc5780639637927f146106df575f80fd5b80637bb7bed1116101a45780637bb7bed1146106695780638980f11f1461067c57806389b5f00b1461068f5780638da5cb5b146106a4575f80fd5b806372f702f31461063957806379ba5097146106595780637b31c19a14610661575f80fd5b806342c92f6e1161029f57806361c1b3641161023f578063693392451161021a57806369339245146105bd5780636c430dbb146105dc5780636cea0b0d146105fb57806370a0823114610604575f80fd5b806361c1b3641461057857806364373aa8146105a25780636885d316146105b5575f80fd5b806353a47bb71161027a57806353a47bb7146104d85780635d69b62c1461051d5780635e5294b71461052a578063607ad0d714610551575f80fd5b806342c92f6e146104b55780634b329ae4146104c8578063527e8684146104d0575f80fd5b8063313ce5671161030a578063386a9525116102e5578063386a95251461046057806338d0743614610487578063395093511461049a5780633b8105b3146104ad575f80fd5b8063313ce56714610418578063323331ca14610427578063355274ea14610439575f80fd5b8063095ea7b311610345578063095ea7b3146103bd5780631627540c146103e057806318160ddd146103f357806323b872dd14610405575f80fd5b80628cc2621461036a57806305b9e26f1461039357806306fdde03146103a8575b5f80fd5b61037d610378366004612c4b565b610886565b60405161038a9190612c64565b60405180910390f35b6103a66103a1366004612d45565b6109e7565b005b6103b0610a7a565b60405161038a9190612de2565b6103d06103cb366004612e35565b610b0a565b604051901515815260200161038a565b6103a66103ee366004612c4b565b610b23565b6002545b60405190815260200161038a565b6103d0610413366004612e5d565b610bed565b6040516012815260200161038a565b6014546103d090610100900460ff1681565b6103f77f000000000000000000000000000000000000000000000000000000000000000081565b6103f77f000000000000000000000000000000000000000000000000000000000000000081565b61037d610495366004612ea4565b610c10565b6103d06104a8366004612e35565b610e14565b6103a6610e5f565b6103a66104c3366004612c4b565b610eeb565b6103f7610f8f565b61037d610fc8565b6006546104f89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161038a565b6014546103d09060ff1681565b6103f77f000000000000000000000000000000000000000000000000000000000000000081565b6103f77f000000000000000000000000000000000000000000000000000000000000000081565b6103f7610586366004612e35565b601360209081525f928352604080842090915290825290205481565b6103f76105b0366004612ed2565b6110c6565b6103a66110e5565b6103f76105cb366004612c4b565b600f6020525f908152604090205481565b6103f76105ea366004612c4b565b60116020525f908152604090205481565b6103f7600a5481565b6103f7610612366004612c4b565b73ffffffffffffffffffffffffffffffffffffffff165f9081526020819052604090205490565b6008546104f89073ffffffffffffffffffffffffffffffffffffffff1681565b6103a6611167565b6103a661125c565b6104f8610677366004612ed2565b6112e7565b6103a661068a366004612e35565b61131c565b6014546103d090640100000000900460ff1681565b6005546104f89073ffffffffffffffffffffffffffffffffffffffff1681565b6103b061145b565b6103a66106da366004612ee9565b61146a565b6014546103d0906301000000900460ff1681565b6103d0610701366004612e35565b6116f7565b6103a6610714366004612ed2565b6117cc565b6103d0610727366004612e35565b611a18565b6103d061073a366004612c4b565b60096020525f908152604090205460ff1681565b6103f761075c366004612e35565b601260209081525f928352604080842090915290825290205481565b6014546103d09062010000900460ff1681565b61037d610799366004612c4b565b611a25565b6103f7600b5481565b61037d611d3a565b6103d06107bd366004612c4b565b600c6020525f908152604090205460ff1681565b6103a6611e9b565b6103f76107e7366004612f70565b73ffffffffffffffffffffffffffffffffffffffff9182165f90815260016020908152604080832093909416825291909152205490565b6103a6611f2a565b6103a6611fad565b6014546103d09065010000000000900460ff1681565b6103f77f000000000000000000000000000000000000000000000000000000000000000081565b6103f7610879366004612ed2565b61203a565b6103a6612049565b60105460609067ffffffffffffffff8111156108a4576108a4612ca6565b6040519080825280602002602001820160405280156108cd578160200160208202803683370190505b5090505f6108d9611d3a565b90505f5b6010548110156109e05773ffffffffffffffffffffffffffffffffffffffff84165f9081526013602090815260408083208484529091529020548251670de0b6b3a7640000919084908490811061093657610936612fa1565b60200260200101516109489190612ffb565b73ffffffffffffffffffffffffffffffffffffffff86165f90815260208190526040902054610977919061300e565b6109819190613025565b73ffffffffffffffffffffffffffffffffffffffff85165f9081526012602090815260408083208584529091529020546109bb919061305d565b8382815181106109cd576109cd612fa1565b60209081029190910101526001016108dd565b5050919050565b601454640100000000900460ff1680610a02575060145460ff165b15610a39576040517f41dcf03e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a41612049565b5f5b8151811015610a7657610a6e828281518110610a6157610a61612fa1565b6020026020010151612073565b600101610a43565b5050565b606060038054610a8990613070565b80601f0160208091040260200160405190810160405280929190818152602001828054610ab590613070565b8015610b005780601f10610ad757610100808354040283529160200191610b00565b820191905f5260205f20905b815481529060010190602001808311610ae357829003601f168201915b5050505050905090565b5f33610b1781858561214d565b60019150505b92915050565b60055473ffffffffffffffffffffffffffffffffffffffff163314610b74576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229060200160405180910390a150565b5f33610bfa8582856122ff565b610c058585856123d5565b506001949350505050565b60607f000000000000000000000000000000000000000000000000000000000000000042108015610c6057506014546301000000900460ff1680610c5e5750601454640100000000900460ff165b155b15610c97576040517f54d2c56500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60145465010000000000900460ff1615610cdd576040517f6022a9e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ce73384612691565b6008546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810185905273ffffffffffffffffffffffffffffffffffffffff9091169063a9059cbb906044016020604051808303815f875af1158015610d5b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d7f91906130c1565b5060105467ffffffffffffffff811115610d9b57610d9b612ca6565b604051908082528060200260200182016040528015610dc4578160200160208202803683370190505b5090508115610dd957610dd633611a25565b90505b60405183815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a292915050565b335f81815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190610b179082908690610e5a90879061305d565b61214d565b60055473ffffffffffffffffffffffffffffffffffffffff163314610eb0576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff8116620100009182900460ff1615909102179055565b60055473ffffffffffffffffffffffffffffffffffffffff163314610f3c576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff165f908152600c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b5f610f9960025490565b610fc3907f0000000000000000000000000000000000000000000000000000000000000000612ffb565b905090565b60105460609067ffffffffffffffff811115610fe657610fe6612ca6565b60405190808252806020026020018201604052801561100f578160200160208202803683370190505b509050427f00000000000000000000000000000000000000000000000000000000000000001161103c5790565b5f611067427f0000000000000000000000000000000000000000000000000000000000000000612ffb565b90505f5b6010548110156110c15781600e828154811061108957611089612fa1565b905f5260205f20015461109c919061300e565b8382815181106110ae576110ae612fa1565b602090810291909101015260010161106b565b505090565b600d81815481106110d5575f80fd5b5f91825260209091200154905081565b60055473ffffffffffffffffffffffffffffffffffffffff163314611136576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000179055565b60065473ffffffffffffffffffffffffffffffffffffffff1633146111b8576040517fd74b334e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546006546040805173ffffffffffffffffffffffffffffffffffffffff93841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160068054600580547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b60055473ffffffffffffffffffffffffffffffffffffffff1633146112ad576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff81166101009182900460ff1615909102179055565b601081815481106112f6575f80fd5b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b60055473ffffffffffffffffffffffffffffffffffffffff16331461136d576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152602481018390529083169063a9059cbb906044016020604051808303815f875af11580156113e3573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061140791906130c1565b506040805173ffffffffffffffffffffffffffffffffffffffff84168152602081018390527f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa28910160405180910390a15050565b606060048054610a8990613070565b335f908152600c602052604090205460ff166114b2576040517fae582d4300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000421061150b576040517f5a82b59600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5b60105481101561157e576115766010828154811061152d5761152d612fa1565b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16333085858151811061156957611569612fa1565b6020026020010151612886565b60010161150d565b50611587612049565b5f5b6010548110156116eb575f6115be427f0000000000000000000000000000000000000000000000000000000000000000612ffb565b90505f600e83815481106115d4576115d4612fa1565b905f5260205f200154826115e8919061300e565b905081818585815181106115fe576115fe612fa1565b6020026020010151611610919061305d565b61161a9190613025565b600e848154811061162d5761162d612fa1565b905f5260205f2001819055506010838154811061164c5761164c612fa1565b5f91825260209091200154845173ffffffffffffffffffffffffffffffffffffffff909116907f6a6f77044107a33658235d41bedbbaf2fe9ccdceb313143c947a5e76e1ec8474908690869081106116a6576116a6612fa1565b6020026020010151600e86815481106116c1576116c1612fa1565b5f918252602091829020015460408051938452918301520160405180910390a25050600101611589565b506116f4612049565b50565b335f81815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190838110156117bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610c05828686840361214d565b336117d6816129ce565b7f0000000000000000000000000000000000000000000000000000000000000000421061182f576040517f5a82b59600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60145462010000900460ff1615611872576040517f26d1807b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6014546301000000900460ff16156118b6576040517f579d51b400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601454640100000000900460ff16156118fb576040517f35b1b73c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815f03611934576040517fe646e33500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000008261195f60025490565b611969919061305d565b11156119a1576040517f0ed0768a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008546119c69073ffffffffffffffffffffffffffffffffffffffff16333085612886565b6119d03383612a05565b6119d9336129ce565b604080518381523360208201819052917fcc2e01638b08266366840f4a2ac8755c01e6932f730d5b707835cf4e23a15245910160405180910390a25050565b5f33610b178185856123d5565b606033611a31816129ce565b601454640100000000900460ff1615611a76576040517f35b1b73c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601454610100900460ff1615611ab8576040517f28810b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60105467ffffffffffffffff811115611ad357611ad3612ca6565b604051908082528060200260200182016040528015611afc578160200160208202803683370190505b5091505f5b601054811015611d2257335f9081526012602090815260408083208484529091529020548351849083908110611b3957611b39612fa1565b6020026020010181815250505f838281518110611b5857611b58612fa1565b60200260200101511115611d1a57335f9081526012602090815260408083208484529091528120556010805482908110611b9457611b94612fa1565b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85858481518110611bea57611bea612fa1565b60200260200101516040518363ffffffff1660e01b8152600401611c3092919073ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6020604051808303815f875af1158015611c4c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c7091906130c1565b503373ffffffffffffffffffffffffffffffffffffffff167f1d2f2ca53af5d2f333bd32fdd45f9c52ad8ebe31414f7792912077fcb3876dff848381518110611cbb57611cbb612fa1565b602002602001015160108481548110611cd657611cd6612fa1565b5f91825260209182902001546040805193845273ffffffffffffffffffffffffffffffffffffffff9182169284019290925288169082015260600160405180910390a25b600101611b01565b5050335f908152601160205260409020429055919050565b60105460609067ffffffffffffffff811115611d5857611d58612ca6565b604051908082528060200260200182016040528015611d81578160200160208202803683370190505b509050611d8d60025490565b5f03611de657600d805480602002602001604051908101604052809291908181526020018280548015610b0057602002820191905f5260205f20905b815481526020019060010190808311611dc9575050505050905090565b5f5b601054811015611e9757600254600e8281548110611e0857611e08612fa1565b905f5260205f200154600b54611e1c612b2d565b611e269190612ffb565b611e30919061300e565b611e4290670de0b6b3a764000061300e565b611e4c9190613025565b600d8281548110611e5f57611e5f612fa1565b905f5260205f200154611e72919061305d565b828281518110611e8457611e84612fa1565b6020908102919091010152600101611de8565b5090565b60055473ffffffffffffffffffffffffffffffffffffffff163314611eec576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff8116650100000000009182900460ff1615909102179055565b60055473ffffffffffffffffffffffffffffffffffffffff163314611f7b576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b60055473ffffffffffffffffffffffffffffffffffffffff163314611ffe576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff811663010000009182900460ff1615909102179055565b600e81815481106110d5575f80fd5b612051611d3a565b805161206591600d91602090910190612bcf565b5061206e612b2d565b600b55565b73ffffffffffffffffffffffffffffffffffffffff8116156116f4575f61209982610886565b90505f5b601054811015612148578181815181106120b9576120b9612fa1565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff85165f9081526012835260408082208583529093529190912055600d80548290811061210857612108612fa1565b5f91825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8616835260138252604080842085855290925291205560010161209d565b505050565b73ffffffffffffffffffffffffffffffffffffffff83166121ef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016117b6565b73ffffffffffffffffffffffffffffffffffffffff8216612292576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016117b6565b73ffffffffffffffffffffffffffffffffffffffff8381165f8181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381165f908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146123cf57818110156123c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016117b6565b6123cf848484840361214d565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612478576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016117b6565b73ffffffffffffffffffffffffffffffffffffffff821661251b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016117b6565b612526838383612b58565b73ffffffffffffffffffffffffffffffffffffffff83165f90815260208190526040902054818110156125db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016117b6565b73ffffffffffffffffffffffffffffffffffffffff8085165f9081526020819052604080822085850390559185168152908120805484929061261e90849061305d565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161268491815260200190565b60405180910390a36123cf565b73ffffffffffffffffffffffffffffffffffffffff8216612734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016117b6565b61273f825f83612b58565b73ffffffffffffffffffffffffffffffffffffffff82165f90815260208190526040902054818110156127f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016117b6565b73ffffffffffffffffffffffffffffffffffffffff83165f90815260208190526040812083830390556002805484929061282f908490612ffb565b90915550506040518281525f9073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291515f9283929088169161292491906130dc565b5f604051808303815f865af19150503d805f811461295d576040519150601f19603f3d011682016040523d82523d5f602084013e612962565b606091505b5091509150811580612990575080511580159061299057508080602001905181019061298e91906130c1565b155b156129c6576040517e298ffd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116156116f457601454640100000000900460ff166116f4576116f481612ba7565b73ffffffffffffffffffffffffffffffffffffffff8216612a82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016117b6565b612a8d5f8383612b58565b8060025f828254612a9e919061305d565b909155505073ffffffffffffffffffffffffffffffffffffffff82165f9081526020819052604081208054839290612ad790849061305d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b5f610fc3427f0000000000000000000000000000000000000000000000000000000000000000612bb8565b601454640100000000900460ff16158015612b88575073ffffffffffffffffffffffffffffffffffffffff831615155b1561214857612b95612049565b612b9e83612073565b61214882612073565b612baf612049565b6116f481612073565b5f818310612bc65781612bc8565b825b9392505050565b828054828255905f5260205f20908101928215612c08579160200282015b82811115612c08578251825591602001919060010190612bed565b50611e979291505b80821115611e97575f8155600101612c10565b803573ffffffffffffffffffffffffffffffffffffffff81168114612c46575f80fd5b919050565b5f60208284031215612c5b575f80fd5b612bc882612c23565b602080825282518282018190525f918401906040840190835b81811015612c9b578351835260209384019390920191600101612c7d565b509095945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612d1a57612d1a612ca6565b604052919050565b5f67ffffffffffffffff821115612d3b57612d3b612ca6565b5060051b60200190565b5f60208284031215612d55575f80fd5b813567ffffffffffffffff811115612d6b575f80fd5b8201601f81018413612d7b575f80fd5b8035612d8e612d8982612d22565b612cd3565b8082825260208201915060208360051b850101925086831115612daf575f80fd5b6020840193505b82841015612dd857612dc784612c23565b825260209384019390910190612db6565b9695505050505050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f8060408385031215612e46575f80fd5b612e4f83612c23565b946020939093013593505050565b5f805f60608486031215612e6f575f80fd5b612e7884612c23565b9250612e8660208501612c23565b929592945050506040919091013590565b80151581146116f4575f80fd5b5f8060408385031215612eb5575f80fd5b823591506020830135612ec781612e97565b809150509250929050565b5f60208284031215612ee2575f80fd5b5035919050565b5f60208284031215612ef9575f80fd5b813567ffffffffffffffff811115612f0f575f80fd5b8201601f81018413612f1f575f80fd5b8035612f2d612d8982612d22565b8082825260208201915060208360051b850101925086831115612f4e575f80fd5b6020840193505b82841015612dd8578335825260209384019390910190612f55565b5f8060408385031215612f81575f80fd5b612f8a83612c23565b9150612f9860208401612c23565b90509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115610b1d57610b1d612fce565b8082028115828204841417610b1d57610b1d612fce565b5f82613058577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b80820180821115610b1d57610b1d612fce565b600181811c9082168061308457607f821691505b6020821081036130bb577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b5f602082840312156130d1575f80fd5b8151612bc881612e97565b5f82518060208501845e5f92019182525091905056fea2646970667358221220c0594e09832e9104466a045f4c529fce5b6df6ca7e8e6acce58f66136d3165b664736f6c634300081a0033000000000000000000000000c4eb45d80dc1f079045e75d5d55de8ed1c1090e600000000000000000000000000000000000000000000000000000000000001000000000000000000000000008e9c334afc76106f08e0383907f4fca9bb10ba3e00000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000006b36ec8000000000000000000000000000000000000000000002116545850052128000000000000000000000000000005180db0237291a6449dda9ed33ad90a38787621c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000fc0000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000134c6f636b65642046584220323032363132333100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d6c4658425f323032363132333100000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610366575f3560e01c806372f702f3116101c9578063b933ceac116100fe578063dd62ed3e1161009e578063e9f2838e11610079578063e9f2838e1461082e578063ebe2b12b14610844578063f2caeb1e1461086b578063fff6cae91461087e575f80fd5b8063dd62ed3e146107d9578063dfa43f921461081e578063e1ba95d214610826575f80fd5b8063c8f33c91116100d9578063c8f33c911461079e578063cd3daf9d146107a7578063d15166ff146107af578063d239f003146107d1575f80fd5b8063b933ceac1461074e578063bbb781cc14610778578063c00007b01461078b575f80fd5b806395d89b4111610169578063a457c2d711610144578063a457c2d7146106f3578063a694fc3a14610706578063a9059cbb14610719578063b5fd73f81461072c575f80fd5b806395d89b41146106c457806396234502146106cc5780639637927f146106df575f80fd5b80637bb7bed1116101a45780637bb7bed1146106695780638980f11f1461067c57806389b5f00b1461068f5780638da5cb5b146106a4575f80fd5b806372f702f31461063957806379ba5097146106595780637b31c19a14610661575f80fd5b806342c92f6e1161029f57806361c1b3641161023f578063693392451161021a57806369339245146105bd5780636c430dbb146105dc5780636cea0b0d146105fb57806370a0823114610604575f80fd5b806361c1b3641461057857806364373aa8146105a25780636885d316146105b5575f80fd5b806353a47bb71161027a57806353a47bb7146104d85780635d69b62c1461051d5780635e5294b71461052a578063607ad0d714610551575f80fd5b806342c92f6e146104b55780634b329ae4146104c8578063527e8684146104d0575f80fd5b8063313ce5671161030a578063386a9525116102e5578063386a95251461046057806338d0743614610487578063395093511461049a5780633b8105b3146104ad575f80fd5b8063313ce56714610418578063323331ca14610427578063355274ea14610439575f80fd5b8063095ea7b311610345578063095ea7b3146103bd5780631627540c146103e057806318160ddd146103f357806323b872dd14610405575f80fd5b80628cc2621461036a57806305b9e26f1461039357806306fdde03146103a8575b5f80fd5b61037d610378366004612c4b565b610886565b60405161038a9190612c64565b60405180910390f35b6103a66103a1366004612d45565b6109e7565b005b6103b0610a7a565b60405161038a9190612de2565b6103d06103cb366004612e35565b610b0a565b604051901515815260200161038a565b6103a66103ee366004612c4b565b610b23565b6002545b60405190815260200161038a565b6103d0610413366004612e5d565b610bed565b6040516012815260200161038a565b6014546103d090610100900460ff1681565b6103f77f000000000000000000000000000000000000000000021165458500521280000081565b6103f77f0000000000000000000000000000000000000000000000000000000004ccb10381565b61037d610495366004612ea4565b610c10565b6103d06104a8366004612e35565b610e14565b6103a6610e5f565b6103a66104c3366004612c4b565b610eeb565b6103f7610f8f565b61037d610fc8565b6006546104f89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161038a565b6014546103d09060ff1681565b6103f77f000000000000000000000000000000000000000000000000000000006b36ec8081565b6103f77f00000000000000000000000000000000000000000000000000000000666a3b7d81565b6103f7610586366004612e35565b601360209081525f928352604080842090915290825290205481565b6103f76105b0366004612ed2565b6110c6565b6103a66110e5565b6103f76105cb366004612c4b565b600f6020525f908152604090205481565b6103f76105ea366004612c4b565b60116020525f908152604090205481565b6103f7600a5481565b6103f7610612366004612c4b565b73ffffffffffffffffffffffffffffffffffffffff165f9081526020819052604090205490565b6008546104f89073ffffffffffffffffffffffffffffffffffffffff1681565b6103a6611167565b6103a661125c565b6104f8610677366004612ed2565b6112e7565b6103a661068a366004612e35565b61131c565b6014546103d090640100000000900460ff1681565b6005546104f89073ffffffffffffffffffffffffffffffffffffffff1681565b6103b061145b565b6103a66106da366004612ee9565b61146a565b6014546103d0906301000000900460ff1681565b6103d0610701366004612e35565b6116f7565b6103a6610714366004612ed2565b6117cc565b6103d0610727366004612e35565b611a18565b6103d061073a366004612c4b565b60096020525f908152604090205460ff1681565b6103f761075c366004612e35565b601260209081525f928352604080842090915290825290205481565b6014546103d09062010000900460ff1681565b61037d610799366004612c4b565b611a25565b6103f7600b5481565b61037d611d3a565b6103d06107bd366004612c4b565b600c6020525f908152604090205460ff1681565b6103a6611e9b565b6103f76107e7366004612f70565b73ffffffffffffffffffffffffffffffffffffffff9182165f90815260016020908152604080832093909416825291909152205490565b6103a6611f2a565b6103a6611fad565b6014546103d09065010000000000900460ff1681565b6103f77f000000000000000000000000000000000000000000000000000000006b36ec8081565b6103f7610879366004612ed2565b61203a565b6103a6612049565b60105460609067ffffffffffffffff8111156108a4576108a4612ca6565b6040519080825280602002602001820160405280156108cd578160200160208202803683370190505b5090505f6108d9611d3a565b90505f5b6010548110156109e05773ffffffffffffffffffffffffffffffffffffffff84165f9081526013602090815260408083208484529091529020548251670de0b6b3a7640000919084908490811061093657610936612fa1565b60200260200101516109489190612ffb565b73ffffffffffffffffffffffffffffffffffffffff86165f90815260208190526040902054610977919061300e565b6109819190613025565b73ffffffffffffffffffffffffffffffffffffffff85165f9081526012602090815260408083208584529091529020546109bb919061305d565b8382815181106109cd576109cd612fa1565b60209081029190910101526001016108dd565b5050919050565b601454640100000000900460ff1680610a02575060145460ff165b15610a39576040517f41dcf03e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a41612049565b5f5b8151811015610a7657610a6e828281518110610a6157610a61612fa1565b6020026020010151612073565b600101610a43565b5050565b606060038054610a8990613070565b80601f0160208091040260200160405190810160405280929190818152602001828054610ab590613070565b8015610b005780601f10610ad757610100808354040283529160200191610b00565b820191905f5260205f20905b815481529060010190602001808311610ae357829003601f168201915b5050505050905090565b5f33610b1781858561214d565b60019150505b92915050565b60055473ffffffffffffffffffffffffffffffffffffffff163314610b74576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229060200160405180910390a150565b5f33610bfa8582856122ff565b610c058585856123d5565b506001949350505050565b60607f000000000000000000000000000000000000000000000000000000006b36ec8042108015610c6057506014546301000000900460ff1680610c5e5750601454640100000000900460ff165b155b15610c97576040517f54d2c56500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60145465010000000000900460ff1615610cdd576040517f6022a9e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ce73384612691565b6008546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810185905273ffffffffffffffffffffffffffffffffffffffff9091169063a9059cbb906044016020604051808303815f875af1158015610d5b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d7f91906130c1565b5060105467ffffffffffffffff811115610d9b57610d9b612ca6565b604051908082528060200260200182016040528015610dc4578160200160208202803683370190505b5090508115610dd957610dd633611a25565b90505b60405183815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a292915050565b335f81815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190610b179082908690610e5a90879061305d565b61214d565b60055473ffffffffffffffffffffffffffffffffffffffff163314610eb0576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff8116620100009182900460ff1615909102179055565b60055473ffffffffffffffffffffffffffffffffffffffff163314610f3c576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff165f908152600c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b5f610f9960025490565b610fc3907f0000000000000000000000000000000000000000000211654585005212800000612ffb565b905090565b60105460609067ffffffffffffffff811115610fe657610fe6612ca6565b60405190808252806020026020018201604052801561100f578160200160208202803683370190505b509050427f000000000000000000000000000000000000000000000000000000006b36ec801161103c5790565b5f611067427f000000000000000000000000000000000000000000000000000000006b36ec80612ffb565b90505f5b6010548110156110c15781600e828154811061108957611089612fa1565b905f5260205f20015461109c919061300e565b8382815181106110ae576110ae612fa1565b602090810291909101015260010161106b565b505090565b600d81815481106110d5575f80fd5b5f91825260209091200154905081565b60055473ffffffffffffffffffffffffffffffffffffffff163314611136576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000179055565b60065473ffffffffffffffffffffffffffffffffffffffff1633146111b8576040517fd74b334e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546006546040805173ffffffffffffffffffffffffffffffffffffffff93841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160068054600580547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b60055473ffffffffffffffffffffffffffffffffffffffff1633146112ad576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff81166101009182900460ff1615909102179055565b601081815481106112f6575f80fd5b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b60055473ffffffffffffffffffffffffffffffffffffffff16331461136d576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152602481018390529083169063a9059cbb906044016020604051808303815f875af11580156113e3573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061140791906130c1565b506040805173ffffffffffffffffffffffffffffffffffffffff84168152602081018390527f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa28910160405180910390a15050565b606060048054610a8990613070565b335f908152600c602052604090205460ff166114b2576040517fae582d4300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000006b36ec80421061150b576040517f5a82b59600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5b60105481101561157e576115766010828154811061152d5761152d612fa1565b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16333085858151811061156957611569612fa1565b6020026020010151612886565b60010161150d565b50611587612049565b5f5b6010548110156116eb575f6115be427f000000000000000000000000000000000000000000000000000000006b36ec80612ffb565b90505f600e83815481106115d4576115d4612fa1565b905f5260205f200154826115e8919061300e565b905081818585815181106115fe576115fe612fa1565b6020026020010151611610919061305d565b61161a9190613025565b600e848154811061162d5761162d612fa1565b905f5260205f2001819055506010838154811061164c5761164c612fa1565b5f91825260209091200154845173ffffffffffffffffffffffffffffffffffffffff909116907f6a6f77044107a33658235d41bedbbaf2fe9ccdceb313143c947a5e76e1ec8474908690869081106116a6576116a6612fa1565b6020026020010151600e86815481106116c1576116c1612fa1565b5f918252602091829020015460408051938452918301520160405180910390a25050600101611589565b506116f4612049565b50565b335f81815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190838110156117bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610c05828686840361214d565b336117d6816129ce565b7f000000000000000000000000000000000000000000000000000000006b36ec80421061182f576040517f5a82b59600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60145462010000900460ff1615611872576040517f26d1807b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6014546301000000900460ff16156118b6576040517f579d51b400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601454640100000000900460ff16156118fb576040517f35b1b73c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815f03611934576040517fe646e33500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000002116545850052128000008261195f60025490565b611969919061305d565b11156119a1576040517f0ed0768a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008546119c69073ffffffffffffffffffffffffffffffffffffffff16333085612886565b6119d03383612a05565b6119d9336129ce565b604080518381523360208201819052917fcc2e01638b08266366840f4a2ac8755c01e6932f730d5b707835cf4e23a15245910160405180910390a25050565b5f33610b178185856123d5565b606033611a31816129ce565b601454640100000000900460ff1615611a76576040517f35b1b73c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601454610100900460ff1615611ab8576040517f28810b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60105467ffffffffffffffff811115611ad357611ad3612ca6565b604051908082528060200260200182016040528015611afc578160200160208202803683370190505b5091505f5b601054811015611d2257335f9081526012602090815260408083208484529091529020548351849083908110611b3957611b39612fa1565b6020026020010181815250505f838281518110611b5857611b58612fa1565b60200260200101511115611d1a57335f9081526012602090815260408083208484529091528120556010805482908110611b9457611b94612fa1565b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85858481518110611bea57611bea612fa1565b60200260200101516040518363ffffffff1660e01b8152600401611c3092919073ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6020604051808303815f875af1158015611c4c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c7091906130c1565b503373ffffffffffffffffffffffffffffffffffffffff167f1d2f2ca53af5d2f333bd32fdd45f9c52ad8ebe31414f7792912077fcb3876dff848381518110611cbb57611cbb612fa1565b602002602001015160108481548110611cd657611cd6612fa1565b5f91825260209182902001546040805193845273ffffffffffffffffffffffffffffffffffffffff9182169284019290925288169082015260600160405180910390a25b600101611b01565b5050335f908152601160205260409020429055919050565b60105460609067ffffffffffffffff811115611d5857611d58612ca6565b604051908082528060200260200182016040528015611d81578160200160208202803683370190505b509050611d8d60025490565b5f03611de657600d805480602002602001604051908101604052809291908181526020018280548015610b0057602002820191905f5260205f20905b815481526020019060010190808311611dc9575050505050905090565b5f5b601054811015611e9757600254600e8281548110611e0857611e08612fa1565b905f5260205f200154600b54611e1c612b2d565b611e269190612ffb565b611e30919061300e565b611e4290670de0b6b3a764000061300e565b611e4c9190613025565b600d8281548110611e5f57611e5f612fa1565b905f5260205f200154611e72919061305d565b828281518110611e8457611e84612fa1565b6020908102919091010152600101611de8565b5090565b60055473ffffffffffffffffffffffffffffffffffffffff163314611eec576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff8116650100000000009182900460ff1615909102179055565b60055473ffffffffffffffffffffffffffffffffffffffff163314611f7b576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b60055473ffffffffffffffffffffffffffffffffffffffff163314611ffe576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff811663010000009182900460ff1615909102179055565b600e81815481106110d5575f80fd5b612051611d3a565b805161206591600d91602090910190612bcf565b5061206e612b2d565b600b55565b73ffffffffffffffffffffffffffffffffffffffff8116156116f4575f61209982610886565b90505f5b601054811015612148578181815181106120b9576120b9612fa1565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff85165f9081526012835260408082208583529093529190912055600d80548290811061210857612108612fa1565b5f91825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8616835260138252604080842085855290925291205560010161209d565b505050565b73ffffffffffffffffffffffffffffffffffffffff83166121ef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016117b6565b73ffffffffffffffffffffffffffffffffffffffff8216612292576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016117b6565b73ffffffffffffffffffffffffffffffffffffffff8381165f8181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381165f908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146123cf57818110156123c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016117b6565b6123cf848484840361214d565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612478576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016117b6565b73ffffffffffffffffffffffffffffffffffffffff821661251b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016117b6565b612526838383612b58565b73ffffffffffffffffffffffffffffffffffffffff83165f90815260208190526040902054818110156125db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016117b6565b73ffffffffffffffffffffffffffffffffffffffff8085165f9081526020819052604080822085850390559185168152908120805484929061261e90849061305d565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161268491815260200190565b60405180910390a36123cf565b73ffffffffffffffffffffffffffffffffffffffff8216612734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016117b6565b61273f825f83612b58565b73ffffffffffffffffffffffffffffffffffffffff82165f90815260208190526040902054818110156127f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016117b6565b73ffffffffffffffffffffffffffffffffffffffff83165f90815260208190526040812083830390556002805484929061282f908490612ffb565b90915550506040518281525f9073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291515f9283929088169161292491906130dc565b5f604051808303815f865af19150503d805f811461295d576040519150601f19603f3d011682016040523d82523d5f602084013e612962565b606091505b5091509150811580612990575080511580159061299057508080602001905181019061298e91906130c1565b155b156129c6576040517e298ffd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116156116f457601454640100000000900460ff166116f4576116f481612ba7565b73ffffffffffffffffffffffffffffffffffffffff8216612a82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016117b6565b612a8d5f8383612b58565b8060025f828254612a9e919061305d565b909155505073ffffffffffffffffffffffffffffffffffffffff82165f9081526020819052604081208054839290612ad790849061305d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b5f610fc3427f000000000000000000000000000000000000000000000000000000006b36ec80612bb8565b601454640100000000900460ff16158015612b88575073ffffffffffffffffffffffffffffffffffffffff831615155b1561214857612b95612049565b612b9e83612073565b61214882612073565b612baf612049565b6116f481612073565b5f818310612bc65781612bc8565b825b9392505050565b828054828255905f5260205f20908101928215612c08579160200282015b82811115612c08578251825591602001919060010190612bed565b50611e979291505b80821115611e97575f8155600101612c10565b803573ffffffffffffffffffffffffffffffffffffffff81168114612c46575f80fd5b919050565b5f60208284031215612c5b575f80fd5b612bc882612c23565b602080825282518282018190525f918401906040840190835b81811015612c9b578351835260209384019390920191600101612c7d565b509095945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612d1a57612d1a612ca6565b604052919050565b5f67ffffffffffffffff821115612d3b57612d3b612ca6565b5060051b60200190565b5f60208284031215612d55575f80fd5b813567ffffffffffffffff811115612d6b575f80fd5b8201601f81018413612d7b575f80fd5b8035612d8e612d8982612d22565b612cd3565b8082825260208201915060208360051b850101925086831115612daf575f80fd5b6020840193505b82841015612dd857612dc784612c23565b825260209384019390910190612db6565b9695505050505050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f8060408385031215612e46575f80fd5b612e4f83612c23565b946020939093013593505050565b5f805f60608486031215612e6f575f80fd5b612e7884612c23565b9250612e8660208501612c23565b929592945050506040919091013590565b80151581146116f4575f80fd5b5f8060408385031215612eb5575f80fd5b823591506020830135612ec781612e97565b809150509250929050565b5f60208284031215612ee2575f80fd5b5035919050565b5f60208284031215612ef9575f80fd5b813567ffffffffffffffff811115612f0f575f80fd5b8201601f81018413612f1f575f80fd5b8035612f2d612d8982612d22565b8082825260208201915060208360051b850101925086831115612f4e575f80fd5b6020840193505b82841015612dd8578335825260209384019390910190612f55565b5f8060408385031215612f81575f80fd5b612f8a83612c23565b9150612f9860208401612c23565b90509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115610b1d57610b1d612fce565b8082028115828204841417610b1d57610b1d612fce565b5f82613058577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b80820180821115610b1d57610b1d612fce565b600181811c9082168061308457607f821691505b6020821081036130bb577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b5f602082840312156130d1575f80fd5b8151612bc881612e97565b5f82518060208501845e5f92019182525091905056fea2646970667358221220c0594e09832e9104466a045f4c529fce5b6df6ca7e8e6acce58f66136d3165b664736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c4eb45d80dc1f079045e75d5d55de8ed1c1090e600000000000000000000000000000000000000000000000000000000000001000000000000000000000000008e9c334afc76106f08e0383907f4fca9bb10ba3e00000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000006b36ec8000000000000000000000000000000000000000000002116545850052128000000000000000000000000000005180db0237291a6449dda9ed33ad90a38787621c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000fc0000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000134c6f636b65642046584220323032363132333100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d6c4658425f323032363132333100000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _owner (address): 0xC4EB45d80DC1F079045E75D5d55de8eD1c1090E6
Arg [1] : _rewardTokens (address[]): 0xFc00000000000000000000000000000000000002
Arg [2] : _stakingToken (address): 0x8e9C334afc76106F08E0383907F4Fca9bB10BA3e
Arg [3] : _name (string): Locked FXB 20261231
Arg [4] : _symbol (string): lFXB_20261231
Arg [5] : _endingTimestamp (uint256): 1798761600
Arg [6] : _cap (uint256): 2500000000000000000000000
Arg [7] : _extraNotifier (address): 0x5180db0237291A6449DdA9ed33aD90a38787621c
-----Encoded View---------------
14 Constructor Arguments found :
Arg [0] : 000000000000000000000000c4eb45d80dc1f079045e75d5d55de8ed1c1090e6
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [2] : 0000000000000000000000008e9c334afc76106f08e0383907f4fca9bb10ba3e
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [5] : 000000000000000000000000000000000000000000000000000000006b36ec80
Arg [6] : 0000000000000000000000000000000000000000000211654585005212800000
Arg [7] : 0000000000000000000000005180db0237291a6449dda9ed33ad90a38787621c
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [9] : 000000000000000000000000fc00000000000000000000000000000000000002
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000013
Arg [11] : 4c6f636b65642046584220323032363132333100000000000000000000000000
Arg [12] : 000000000000000000000000000000000000000000000000000000000000000d
Arg [13] : 6c4658425f323032363132333100000000000000000000000000000000000000
Deployed Bytecode Sourcemap
36851:22799:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44602:664;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47656:544;;;;;;:::i;:::-;;:::i;:::-;;24950:100;;;:::i;:::-;;;;;;;:::i;27301:201::-;;;;;;:::i;:::-;;:::i;:::-;;;3587:14:1;;3580:22;3562:41;;3550:2;3535:18;27301:201:0;3422:187:1;16128:141:0;;;;;;:::i;:::-;;:::i;26070:108::-;26158:12;;26070:108;;;3760:25:1;;;3748:2;3733:18;26070:108:0;3614:177:1;28082:295:0;;;;;;:::i;:::-;;:::i;25912:93::-;;;25995:2;4317:36:1;;4305:2;4290:18;25912:93:0;4175:184:1;39560:35:0;;;;;;;;;;;;37287:28;;;;;38028:40;;;;;51080:803;;;;;;:::i;:::-;;:::i;28786:238::-;;;;;;:::i;:::-;;:::i;56025:93::-;;;:::i;56437:155::-;;;;;;:::i;:::-;;:::i;42956:115::-;;;:::i;45399:691::-;;;:::i;15838:29::-;;;;;;;;;;;;5029:42:1;5017:55;;;4999:74;;4987:2;4972:18;15838:29:0;4853:226:1;39464:37:0;;;;;;;;;37170:40;;;;;37083;;;;;39176:78;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;38334:38;;;;;;:::i;:::-;;:::i;55118:109::-;;;:::i;38550:55::-;;;;;;:::i;:::-;;;;;;;;;;;;;;38841:54;;;;;;:::i;:::-;;;;;;;;;;;;;;37660:29;;;;;;26241:127;;;;;;:::i;:::-;26342:18;;26315:7;26342:18;;;;;;;;;;;;26241:127;37364:25;;;;;;;;;16277:354;;;:::i;56181:123::-;;;:::i;38662:29::-;;;;;;:::i;:::-;;:::i;55471:279::-;;;;;;:::i;:::-;;:::i;40188:34::-;;;;;;;;;;;;15811:20;;;;;;;;;25169:104;;;:::i;53358:1657::-;;;;;;:::i;:::-;;:::i;39756:26::-;;;;;;;;;;;;29527:436;;;;;;:::i;:::-;;:::i;50043:845::-;;;;;;:::i;:::-;;:::i;26574:193::-;;;;;;:::i;:::-;;:::i;37554:45::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;39004:62;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;39642:25;;;;;;;;;;;;52064:1153;;;;;;:::i;:::-;;:::i;37755:29::-;;;;;;43566:826;;;:::i;38157:47::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;56648:105;;;:::i;26830:151::-;;;;;;:::i;:::-;26946:18;;;;26919:7;26946:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;26830:151;55843:129;;;:::i;56825:94::-;;;:::i;40274:29::-;;;;;;;;;;;;37879:37;;;;;38427:28;;;;;;:::i;:::-;;:::i;48254:219::-;;;:::i;44602:664::-;44764:12;:19;44657:27;;44750:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44750:34:0;;44737:47;;44839:36;44878:16;:14;:16::i;:::-;44839:55;;44955:9;44950:309;44974:12;:19;44970:23;;44950:309;;;45136:33;;;;;;;:23;:33;;;;;;;;:36;;;;;;;;;45111:22;;45178:4;;45136:36;45111:19;;45170:1;;45111:22;;;;;;:::i;:::-;;;;;;;:61;;;;:::i;:::-;26342:18;;;26315:7;26342:18;;;;;;;;;;;45087:87;;;;:::i;:::-;45086:96;;;;:::i;:::-;45045:17;;;;;;;:7;:17;;;;;;;;:20;;;;;;;;;:138;;;;:::i;:::-;45012:10;45023:1;45012:13;;;;;;;;:::i;:::-;;;;;;;;;;:171;45229:3;;44950:309;;;;44686:580;44602:664;;;:::o;47656:544::-;47802:22;;;;;;;;:51;;-1:-1:-1;47828:25:0;;;;47802:51;47798:91;;;47862:27;;;;;;;;;;;;;;47798:91;47934:6;:4;:6::i;:::-;48039:9;48034:159;48058:6;:13;48054:1;:17;48034:159;;;48090:27;48107:6;48114:1;48107:9;;;;;;;;:::i;:::-;;;;;;;48090:16;:27::i;:::-;48163:3;;48034:159;;;;47656:544;:::o;24950:100::-;25004:13;25037:5;25030:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24950:100;:::o;27301:201::-;27384:4;6407:10;27440:32;6407:10;27456:7;27465:6;27440:8;:32::i;:::-;27490:4;27483:11;;;27301:201;;;;;:::o;16128:141::-;16782:5;;;;16768:10;:19;16764:43;;16796:11;;;;;;;;;;;;;;16764:43;16200:14:::1;:23:::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;16239:22:::1;::::0;4999:74:1;;;16239:22:0::1;::::0;4987:2:1;4972:18;16239:22:0::1;;;;;;;16128:141:::0;:::o;28082:295::-;28213:4;6407:10;28271:38;28287:4;6407:10;28302:6;28271:15;:38::i;:::-;28320:27;28330:4;28336:2;28340:6;28320:9;:27::i;:::-;-1:-1:-1;28365:4:0;;28082:295;-1:-1:-1;;;;28082:295:0:o;51080:803::-;51161:28;51225:15;51207;:33;51206:82;;;;-1:-1:-1;51247:14:0;;;;;;;;:40;;-1:-1:-1;51265:22:0;;;;;;;51247:40;51245:43;51206:82;51202:141;;;51312:19;;;;;;;;;;;;;;51202:141;51357:17;;;;;;;51353:49;;;51383:19;;;;;;;;;;;;;;51353:49;51464:34;51470:10;51482:15;51464:5;:34::i;:::-;51612:12;;:50;;;;;51634:10;51612:50;;;8479:74:1;8569:18;;;8562:34;;;51612:12:0;;;;;:21;;8452:18:1;;51612:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;51731:12:0;:19;51717:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51717:34:0;;51703:48;;51766:15;51762:56;;;51797:21;51807:10;51797:9;:21::i;:::-;51783:35;;51762:56;51836:39;;3760:25:1;;;51847:10:0;;51836:39;;3748:2:1;3733:18;51836:39:0;;;;;;;51080:803;;;;:::o;28786:238::-;6407:10;28874:4;26946:18;;;:11;:18;;;;;;;;;:27;;;;;;;;;;28874:4;;6407:10;28930:64;;6407:10;;26946:27;;28955:38;;28983:10;;28955:38;:::i;:::-;28930:8;:64::i;56025:93::-;16782:5;;;;16768:10;:19;16764:43;;16796:11;;;;;;;;;;;;;;16764:43;56097:13:::1;::::0;;56080:30;;::::1;56097:13:::0;;;;::::1;;;56096:14;56080:30:::0;;::::1;;::::0;;56025:93::o;56437:155::-;16782:5;;;;16768:10;:19;16764:43;;16796:11;;;;;;;;;;;;;;16764:43;56554:30:::1;;;::::0;;;:15:::1;:30;::::0;;;;;;56520:64;;::::1;56554:30;::::0;;::::1;56553:31;56520:64;::::0;;56437:155::o;42956:115::-;43004:15;43049:13;26158:12;;;26070:108;43049:13;43043:19;;:3;:19;:::i;:::-;43032:31;;42956:115;:::o;45399:691::-;45580:12;:19;45453:37;;45566:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45566:34:0;;45543:57;;45689:15;45670;:34;45666:67;;45399:691;:::o;45666:67::-;45784:17;45804:33;45822:15;45804;:33;:::i;:::-;45784:53;;45898:9;45893:190;45917:12;:19;45913:23;;45893:190;;;45998:9;45981:11;45993:1;45981:14;;;;;;;;:::i;:::-;;;;;;;;;:26;;;;:::i;:::-;45955:20;45976:1;45955:23;;;;;;;;:::i;:::-;;;;;;;;;;:52;46053:3;;45893:190;;;;45492:598;45399:691;:::o;38334:38::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38334:38:0;:::o;55118:109::-;16782:5;;;;16768:10;:19;16764:43;;16796:11;;;;;;;;;;;;;;16764:43;55190:22:::1;:29:::0;;;::::1;::::0;::::1;::::0;;55118:109::o;16277:354::-;16450:14;;;;16436:10;:28;16432:69;;16473:28;;;;;;;;;;;;;;16432:69;16530:5;;16537:14;;16517:35;;;16530:5;;;;9031:74:1;;16537:14:0;;;;9136:2:1;9121:18;;9114:83;16517:35:0;;9004:18:1;16517:35:0;;;;;;;16571:14;;;16563:5;:22;;;;;;16571:14;;;16563:22;;;;16596:27;;;16277:354::o;56181:123::-;16782:5;;;;16768:10;:19;16764:43;;16796:11;;;;;;;;;;;;;;16764:43;56273:23:::1;::::0;;56246:50;;::::1;56273:23;::::0;;;::::1;;;56272:24;56246:50:::0;;::::1;;::::0;;56181:123::o;38662:29::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38662:29:0;:::o;55471:279::-;16782:5;;;;16768:10;:19;16764:43;;16796:11;;;;;;;;;;;;;;16764:43;55671:5:::1;::::0;55642:48:::1;::::0;;;;:28:::1;55671:5:::0;;::::1;55642:48;::::0;::::1;8479:74:1::0;8569:18;;;8562:34;;;55642:28:0;;::::1;::::0;::::1;::::0;8452:18:1;;55642:48:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;55706:36:0::1;::::0;;8509:42:1;8497:55;;8479:74;;8584:2;8569:18;;8562:34;;;55706:36:0::1;::::0;8452:18:1;55706:36:0::1;;;;;;;55471:279:::0;;:::o;25169:104::-;25225:13;25258:7;25251:14;;;;;:::i;53358:1657::-;53513:10;53497:27;;;;:15;:27;;;;;;;;53492:60;;53533:19;;;;;;;;;;;;;;53492:60;53635:15;53616;:34;53612:63;;53659:16;;;;;;;;;;;;;;53612:63;53747:9;53742:408;53766:12;:19;53762:23;;53742:408;;;53986:88;54018:12;54031:1;54018:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;54035:10;54055:4;54062:8;54071:1;54062:11;;;;;;;;:::i;:::-;;;;;;;53986:31;:88::i;:::-;54120:3;;53742:408;;;;54224:6;:4;:6::i;:::-;54286:9;54281:638;54305:12;:19;54301:23;;54281:638;;;54388:21;54412:30;54427:15;54412:12;:30;:::i;:::-;54388:54;;54457:19;54495:11;54507:1;54495:14;;;;;;;;:::i;:::-;;;;;;;;;54479:13;:30;;;;:::i;:::-;54457:52;;54751:13;54736:11;54722:8;54731:1;54722:11;;;;;;;;:::i;:::-;;;;;;;:25;;;;:::i;:::-;54721:43;;;;:::i;:::-;54704:11;54716:1;54704:14;;;;;;;;:::i;:::-;;;;;;;;:60;;;;54798:12;54811:1;54798:15;;;;;;;;:::i;:::-;;;;;;;;;;;54815:11;;54798:15;;;;;54786:57;;54815:8;;54824:1;;54815:11;;;;;;:::i;:::-;;;;;;;54828;54840:1;54828:14;;;;;;;;:::i;:::-;;;;;;;;;;;;54786:57;;;9382:25:1;;;9423:18;;;9416:34;9355:18;54786:57:0;;;;;;;-1:-1:-1;;54889:3:0;;54281:638;;;;55001:6;:4;:6::i;:::-;53358:1657;:::o;29527:436::-;6407:10;29620:4;26946:18;;;:11;:18;;;;;;;;;:27;;;;;;;;;;29620:4;;6407:10;29767:15;29747:16;:35;;29739:85;;;;;;;9663:2:1;29739:85:0;;;9645:21:1;9702:2;9682:18;;;9675:30;9741:34;9721:18;;;9714:62;9812:7;9792:18;;;9785:35;9837:19;;29739:85:0;;;;;;;;;29860:60;29869:5;29876:7;29904:15;29885:16;:34;29860:8;:60::i;50043:845::-;50096:10;42742:23;42757:7;42742:14;:23::i;:::-;50164:15:::1;50145;:34;50141:63;;50188:16;;;;;;;;;;;;;;50141:63;50219:13;::::0;;;::::1;;;50215:41;;;50241:15;;;;;;;;;;;;;;50215:41;50271:14;::::0;;;::::1;;;50267:46;;;50294:19;;;;;;;;;;;;;;50267:46;50328:22;::::0;;;::::1;;;50324:59;;;50359:24;;;;;;;;;;;;;;50324:59;50398:7;50409:1;50398:12:::0;50394:40:::1;;50419:15;;;;;;;;;;;;;;50394:40;50477:3;50466:7;50450:13;26158:12:::0;;;26070:108;50450:13:::1;:23;;;;:::i;:::-;50449:31;50445:52;;;50489:8;;;;;;;;;;;;;;50445:52;50606:12;::::0;50566:90:::1;::::0;50606:12:::1;;50621:10;50641:4;50648:7:::0;50566:31:::1;:90::i;:::-;50732:26;50738:10;50750:7;50732:5;:26::i;:::-;50798;50813:10;50798:14;:26::i;:::-;50842:38;::::0;;10041:25:1;;;50848:10:0::1;10097:2:1::0;10082:18;;10075:83;;;50848:10:0;50842:38:::1;::::0;10014:18:1;50842:38:0::1;;;;;;;50043:845:::0;;:::o;26574:193::-;26653:4;6407:10;26709:28;6407:10;26726:2;26730:6;26709:9;:28::i;52064:1153::-;52170:28;52149:10;42742:23;42757:7;42742:14;:23::i;:::-;52261:22:::1;::::0;;;::::1;;;52257:59;;;52292:24;;;;;;;;;;;;;;52257:59;52389:23;::::0;::::1;::::0;::::1;;;52385:62;;;52421:26;;;;;;;;;;;;;;52385:62;52528:12;:19:::0;52514:34:::1;::::0;::::1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;52514:34:0::1;;52500:48;;52603:9;52598:504;52622:12;:19:::0;52618:23;::::1;52598:504;;;52685:10;52677:19;::::0;;;:7:::1;:19;::::0;;;;;;;:22;;;;;;;;;52660:14;;:11;;52697:1;;52660:14;::::1;;;;;:::i;:::-;;;;;;:39;;;::::0;::::1;52774:1;52757:11;52769:1;52757:14;;;;;;;;:::i;:::-;;;;;;;:18;52753:274;;;52804:10;52821:1;52796:19:::0;;;:7:::1;:19;::::0;;;;;;;:22;;;;;;;;:26;52847:12:::1;:15:::0;;52816:1;;52847:15;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;52841:31;;;52873:19;52894:11;52906:1;52894:14;;;;;;;;:::i;:::-;;;;;;;52841:68;;;;;;;;;;;;;;;8509:42:1::0;8497:55;;;;8479:74;;8584:2;8569:18;;8562:34;8467:2;8452:18;;8305:297;52841:68:0::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;52946:10;52935:76;;;52958:11;52970:1;52958:14;;;;;;;;:::i;:::-;;;;;;;52974:12;52987:1;52974:15;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;::::1;::::0;52935:76:::1;::::0;;10371:25:1;;;52974:15:0::1;::::0;;::::1;10412:18:1::0;;;10405:83;;;;10524:55;;10504:18;;;10497:83;10359:2;10344:18;52935:76:0::1;;;;;;;52753:274;53072:3;;52598:504;;;-1:-1:-1::0;;53180:10:0::1;53160:31;::::0;;;:19:::1;:31;::::0;;;;53194:15:::1;53160:49:::0;;52064:1153;;-1:-1:-1;52064:1153:0:o;43566:826::-;43750:12;:19;43613:42;;43736:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43736:34:0;;43708:62;;43809:13;26158:12;;;26070:108;43809:13;43826:1;43809:18;43805:580;;43926:21;43898:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43566:826;:::o;43805:580::-;44032:9;44027:347;44051:12;:19;44047:23;;44027:347;;;26158:12;;44243:11;44255:1;44243:14;;;;;;;;:::i;:::-;;;;;;;;;44225;;44196:26;:24;:26::i;:::-;:43;;;;:::i;:::-;44195:62;;;;:::i;:::-;:69;;44260:4;44195:69;:::i;:::-;44194:87;;;;:::i;:::-;44145:21;44167:1;44145:24;;;;;;;;:::i;:::-;;;;;;;;;:137;;;;:::i;:::-;44093:25;44119:1;44093:28;;;;;;;;:::i;:::-;;;;;;;;;;:189;44336:3;;44027:347;;;;43566:826;:::o;56648:105::-;16782:5;;;;16768:10;:19;16764:43;;16796:11;;;;;;;;;;;;;;16764:43;56728:17:::1;::::0;;56707:38;;::::1;56728:17:::0;;;;::::1;;;56727:18;56707:38:::0;;::::1;;::::0;;56648:105::o;55843:129::-;16782:5;;;;16768:10;:19;16764:43;;16796:11;;;;;;;;;;;;;;16764:43;55939:25:::1;::::0;;55910:54;;::::1;55939:25;::::0;;::::1;55938:26;55910:54;::::0;;55843:129::o;56825:94::-;16782:5;;;;16768:10;:19;16764:43;;16796:11;;;;;;;;;;;;;;16764:43;56897:14:::1;::::0;;56879:32;;::::1;56897:14:::0;;;;::::1;;;56896:15;56879:32:::0;;::::1;;::::0;;56825:94::o;38427:28::-;;;;;;;;;;;;48254:219;48353:16;:14;:16::i;:::-;48329:40;;;;:21;;:40;;;;;;:::i;:::-;;48439:26;:24;:26::i;:::-;48422:14;:43;48254:219::o;49079:532::-;49147:22;;;;49143:461;;49225:25;49253:16;49260:8;49253:6;:16::i;:::-;49225:44;;49324:9;49319:274;49343:12;:19;49339:23;;49319:274;;;49408:8;49417:1;49408:11;;;;;;;;:::i;:::-;;;;;;;;;;;;49385:17;;;;;;;:7;:17;;;;;;:20;;;;;;;;;;:34;49477:21;:24;;49403:1;;49477:24;;;;;;:::i;:::-;;;;;;;;;;;;;49438:33;;;;;:23;:33;;;;;;:36;;;;;;;;:63;49555:3;;49319:274;;;;49171:433;49079:532;:::o;33152:380::-;33288:19;;;33280:68;;;;;;;10793:2:1;33280:68:0;;;10775:21:1;10832:2;10812:18;;;10805:30;10871:34;10851:18;;;10844:62;10942:6;10922:18;;;10915:34;10966:19;;33280:68:0;10591:400:1;33280:68:0;33367:21;;;33359:68;;;;;;;11198:2:1;33359:68:0;;;11180:21:1;11237:2;11217:18;;;11210:30;11276:34;11256:18;;;11249:62;11347:4;11327:18;;;11320:32;11369:19;;33359:68:0;10996:398:1;33359:68:0;33440:18;;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;33492:32;;3760:25:1;;;33492:32:0;;3733:18:1;33492:32:0;;;;;;;33152:380;;;:::o;33823:453::-;26946:18;;;;33958:24;26946:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;34045:17;34025:37;;34021:248;;34107:6;34087:16;:26;;34079:68;;;;;;;11601:2:1;34079:68:0;;;11583:21:1;11640:2;11620:18;;;11613:30;11679:31;11659:18;;;11652:59;11728:18;;34079:68:0;11399:353:1;34079:68:0;34191:51;34200:5;34207:7;34235:6;34216:16;:25;34191:8;:51::i;:::-;33947:329;33823:453;;;:::o;30433:671::-;30564:18;;;30556:68;;;;;;;11959:2:1;30556:68:0;;;11941:21:1;11998:2;11978:18;;;11971:30;12037:34;12017:18;;;12010:62;12108:7;12088:18;;;12081:35;12133:19;;30556:68:0;11757:401:1;30556:68:0;30643:16;;;30635:64;;;;;;;12365:2:1;30635:64:0;;;12347:21:1;12404:2;12384:18;;;12377:30;12443:34;12423:18;;;12416:62;12514:5;12494:18;;;12487:33;12537:19;;30635:64:0;12163:399:1;30635:64:0;30712:38;30733:4;30739:2;30743:6;30712:20;:38::i;:::-;30785:15;;;30763:19;30785:15;;;;;;;;;;;30819:21;;;;30811:72;;;;;;;12769:2:1;30811:72:0;;;12751:21:1;12808:2;12788:18;;;12781:30;12847:34;12827:18;;;12820:62;12918:8;12898:18;;;12891:36;12944:19;;30811:72:0;12567:402:1;30811:72:0;30919:15;;;;:9;:15;;;;;;;;;;;30937:20;;;30919:38;;30979:13;;;;;;;;:23;;30951:6;;30919:9;30979:23;;30951:6;;30979:23;:::i;:::-;;;;;;;;31035:2;31020:26;;31029:4;31020:26;;;31039:6;31020:26;;;;3760:25:1;;3748:2;3733:18;;3614:177;31020:26:0;;;;;;;;31059:37;49079:532;32123:591;32207:21;;;32199:67;;;;;;;13176:2:1;32199:67:0;;;13158:21:1;13215:2;13195:18;;;13188:30;13254:34;13234:18;;;13227:62;13325:3;13305:18;;;13298:31;13346:19;;32199:67:0;12974:397:1;32199:67:0;32279:49;32300:7;32317:1;32321:6;32279:20;:49::i;:::-;32366:18;;;32341:22;32366:18;;;;;;;;;;;32403:24;;;;32395:71;;;;;;;13578:2:1;32395:71:0;;;13560:21:1;13617:2;13597:18;;;13590:30;13656:34;13636:18;;;13629:62;13727:4;13707:18;;;13700:32;13749:19;;32395:71:0;13376:398:1;32395:71:0;32502:18;;;:9;:18;;;;;;;;;;32523:23;;;32502:44;;32568:12;:22;;32540:6;;32502:9;32568:22;;32540:6;;32568:22;:::i;:::-;;;;-1:-1:-1;;32608:37:0;;3760:25:1;;;32634:1:0;;32608:37;;;;;;3748:2:1;3733:18;32608:37:0;;;;;;;49319:274;49171:433;49079:532;:::o;21311:525::-;21539:51;;;21528:10;13999:55:1;;;21539:51:0;;;13981:74:1;14091:55;;;14071:18;;;14064:83;14163:18;;;;14156:34;;;21539:51:0;;;;;;;;;;13954:18:1;;;;21539:51:0;;;;;;;;;;;;;21528:63;;-1:-1:-1;;;;21528:10:0;;;;:63;;21539:51;21528:63;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21492:99;;;;21727:7;21726:8;:59;;;-1:-1:-1;21739:11:0;;:16;;;;:45;;;21771:4;21760:24;;;;;;;;;;;;:::i;:::-;21759:25;21739:45;21722:106;;;21794:34;;;;;;;;;;;;;;21722:106;21402:434;;21311:525;;;;:::o;48595:269::-;48660:21;;;;48656:201;;48801:22;;;;;;;48796:49;;48825:20;48837:7;48825:11;:20::i;31391:399::-;31475:21;;;31467:65;;;;;;;14709:2:1;31467:65:0;;;14691:21:1;14748:2;14728:18;;;14721:30;14787:33;14767:18;;;14760:61;14838:18;;31467:65:0;14507:355:1;31467:65:0;31545:49;31574:1;31578:7;31587:6;31545:20;:49::i;:::-;31623:6;31607:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;31640:18:0;;;:9;:18;;;;;;;;;;:28;;31662:6;;31640:9;:28;;31662:6;;31640:28;:::i;:::-;;;;-1:-1:-1;;31684:37:0;;3760:25:1;;;31684:37:0;;;;31701:1;;31684:37;;3748:2:1;3733:18;31684:37:0;;;;;;;48034:159;47656:544;:::o;43286:133::-;43345:7;43372:39;43381:15;43398:12;43372:8;:39::i;46829:597::-;47266:22;;;;;;;47265:23;:47;;;;-1:-1:-1;47293:18:0;;;;;47265:47;47261:158;;;47329:6;:4;:6::i;:::-;47350:22;47367:4;47350:16;:22::i;:::-;47387:20;47404:2;47387:16;:20::i;49717:214::-;49838:6;:4;:6::i;:::-;49897:26;49914:8;49897:16;:26::i;7158:106::-;7216:7;7247:1;7243;:5;:13;;7255:1;7243:13;;;7251:1;7243:13;7236:20;7158:106;-1:-1:-1;;;7158:106:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:196:1;82:20;;142:42;131:54;;121:65;;111:93;;200:1;197;190:12;111:93;14:196;;;:::o;215:186::-;274:6;327:2;315:9;306:7;302:23;298:32;295:52;;;343:1;340;333:12;295:52;366:29;385:9;366:29;:::i;406:611::-;596:2;608:21;;;678:13;;581:18;;;700:22;;;548:4;;779:15;;;753:2;738:18;;;548:4;822:169;836:6;833:1;830:13;822:169;;;897:13;;885:26;;940:2;966:15;;;;931:12;;;;858:1;851:9;822:169;;;-1:-1:-1;1008:3:1;;406:611;-1:-1:-1;;;;;406:611:1:o;1022:184::-;1074:77;1071:1;1064:88;1171:4;1168:1;1161:15;1195:4;1192:1;1185:15;1211:334;1282:2;1276:9;1338:2;1328:13;;1343:66;1324:86;1312:99;;1441:18;1426:34;;1462:22;;;1423:62;1420:88;;;1488:18;;:::i;:::-;1524:2;1517:22;1211:334;;-1:-1:-1;1211:334:1:o;1550:183::-;1610:4;1643:18;1635:6;1632:30;1629:56;;;1665:18;;:::i;:::-;-1:-1:-1;1710:1:1;1706:14;1722:4;1702:25;;1550:183::o;1738:892::-;1822:6;1875:2;1863:9;1854:7;1850:23;1846:32;1843:52;;;1891:1;1888;1881:12;1843:52;1931:9;1918:23;1964:18;1956:6;1953:30;1950:50;;;1996:1;1993;1986:12;1950:50;2019:22;;2072:4;2064:13;;2060:27;-1:-1:-1;2050:55:1;;2101:1;2098;2091:12;2050:55;2141:2;2128:16;2164:64;2180:47;2220:6;2180:47;:::i;:::-;2164:64;:::i;:::-;2250:3;2274:6;2269:3;2262:19;2306:2;2301:3;2297:12;2290:19;;2361:2;2351:6;2348:1;2344:14;2340:2;2336:23;2332:32;2318:46;;2387:7;2379:6;2376:19;2373:39;;;2408:1;2405;2398:12;2373:39;2440:2;2436;2432:11;2421:22;;2452:148;2468:6;2463:3;2460:15;2452:148;;;2534:23;2553:3;2534:23;:::i;:::-;2522:36;;2587:2;2485:12;;;;2578;;;;2452:148;;;2619:5;1738:892;-1:-1:-1;;;;;;1738:892:1:o;2635:477::-;2784:2;2773:9;2766:21;2747:4;2816:6;2810:13;2859:6;2854:2;2843:9;2839:18;2832:34;2918:6;2913:2;2905:6;2901:15;2896:2;2885:9;2881:18;2875:50;2974:1;2969:2;2960:6;2949:9;2945:22;2941:31;2934:42;3103:2;3033:66;3028:2;3020:6;3016:15;3012:88;3001:9;2997:104;2993:113;2985:121;;;2635:477;;;;:::o;3117:300::-;3185:6;3193;3246:2;3234:9;3225:7;3221:23;3217:32;3214:52;;;3262:1;3259;3252:12;3214:52;3285:29;3304:9;3285:29;:::i;:::-;3275:39;3383:2;3368:18;;;;3355:32;;-1:-1:-1;;;3117:300:1:o;3796:374::-;3873:6;3881;3889;3942:2;3930:9;3921:7;3917:23;3913:32;3910:52;;;3958:1;3955;3948:12;3910:52;3981:29;4000:9;3981:29;:::i;:::-;3971:39;;4029:38;4063:2;4052:9;4048:18;4029:38;:::i;:::-;3796:374;;4019:48;;-1:-1:-1;;;4136:2:1;4121:18;;;;4108:32;;3796:374::o;4364:118::-;4450:5;4443:13;4436:21;4429:5;4426:32;4416:60;;4472:1;4469;4462:12;4487:361;4552:6;4560;4613:2;4601:9;4592:7;4588:23;4584:32;4581:52;;;4629:1;4626;4619:12;4581:52;4674:23;;;-1:-1:-1;4773:2:1;4758:18;;4745:32;4786:30;4745:32;4786:30;:::i;:::-;4835:7;4825:17;;;4487:361;;;;;:::o;5084:226::-;5143:6;5196:2;5184:9;5175:7;5171:23;5167:32;5164:52;;;5212:1;5209;5202:12;5164:52;-1:-1:-1;5257:23:1;;5084:226;-1:-1:-1;5084:226:1:o;5560:940::-;5644:6;5697:2;5685:9;5676:7;5672:23;5668:32;5665:52;;;5713:1;5710;5703:12;5665:52;5753:9;5740:23;5786:18;5778:6;5775:30;5772:50;;;5818:1;5815;5808:12;5772:50;5841:22;;5894:4;5886:13;;5882:27;-1:-1:-1;5872:55:1;;5923:1;5920;5913:12;5872:55;5963:2;5950:16;5986:64;6002:47;6042:6;6002:47;:::i;5986:64::-;6072:3;6096:6;6091:3;6084:19;6128:2;6123:3;6119:12;6112:19;;6183:2;6173:6;6170:1;6166:14;6162:2;6158:23;6154:32;6140:46;;6209:7;6201:6;6198:19;6195:39;;;6230:1;6227;6220:12;6195:39;6262:2;6258;6254:11;6243:22;;6274:196;6290:6;6285:3;6282:15;6274:196;;;6380:17;;6410:18;;6457:2;6307:12;;;;6448;;;;6274:196;;6505:260;6573:6;6581;6634:2;6622:9;6613:7;6609:23;6605:32;6602:52;;;6650:1;6647;6640:12;6602:52;6673:29;6692:9;6673:29;:::i;:::-;6663:39;;6721:38;6755:2;6744:9;6740:18;6721:38;:::i;:::-;6711:48;;6505:260;;;;;:::o;6770:184::-;6822:77;6819:1;6812:88;6919:4;6916:1;6909:15;6943:4;6940:1;6933:15;6959:184;7011:77;7008:1;7001:88;7108:4;7105:1;7098:15;7132:4;7129:1;7122:15;7148:128;7215:9;;;7236:11;;;7233:37;;;7250:18;;:::i;7281:168::-;7354:9;;;7385;;7402:15;;;7396:22;;7382:37;7372:71;;7423:18;;:::i;7454:274::-;7494:1;7520;7510:189;;7555:77;7552:1;7545:88;7656:4;7653:1;7646:15;7684:4;7681:1;7674:15;7510:189;-1:-1:-1;7713:9:1;;7454:274::o;7733:125::-;7798:9;;;7819:10;;;7816:36;;;7832:18;;:::i;7863:437::-;7942:1;7938:12;;;;7985;;;8006:61;;8060:4;8052:6;8048:17;8038:27;;8006:61;8113:2;8105:6;8102:14;8082:18;8079:38;8076:218;;8150:77;8147:1;8140:88;8251:4;8248:1;8241:15;8279:4;8276:1;8269:15;8076:218;;7863:437;;;:::o;8607:245::-;8674:6;8727:2;8715:9;8706:7;8702:23;8698:32;8695:52;;;8743:1;8740;8733:12;8695:52;8775:9;8769:16;8794:28;8816:5;8794:28;:::i;14201:301::-;14330:3;14368:6;14362:13;14414:6;14407:4;14399:6;14395:17;14390:3;14384:37;14476:1;14440:16;;14465:13;;;-1:-1:-1;14440:16:1;14201:301;-1:-1:-1;14201:301:1:o
Swarm Source
ipfs://c0594e09832e9104466a045f4c529fce5b6df6ca7e8e6acce58f66136d3165b6
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.