Overview
ETH Balance
ETH Value
$0.00Latest 10 from a total of 10 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Create Pair | 11488316 | 647 days ago | IN | 0 ETH | 0.00010435 | ||||
| Create Pair | 11122558 | 655 days ago | IN | 0 ETH | 0.00006919 | ||||
| Create Pair | 11121658 | 655 days ago | IN | 0 ETH | 0.00006961 | ||||
| Create Pair | 11104788 | 655 days ago | IN | 0 ETH | 0.00006903 | ||||
| Create Pair | 10279755 | 675 days ago | IN | 0 ETH | 0.00005485 | ||||
| Create Pair | 10174124 | 677 days ago | IN | 0 ETH | 0.00003508 | ||||
| Create Pair | 10120190 | 678 days ago | IN | 0 ETH | 0.00002683 | ||||
| Create Pair | 9527671 | 692 days ago | IN | 0 ETH | 0.00021974 | ||||
| Transfer Ownersh... | 9527658 | 692 days ago | IN | 0 ETH | 0.00002838 | ||||
| Add Existing Pai... | 9527655 | 692 days ago | IN | 0 ETH | 0.00003341 |
Latest 9 internal transactions
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 11488316 | 647 days ago | Contract Creation | 0 ETH | |||
| 11122558 | 655 days ago | Contract Creation | 0 ETH | |||
| 11121658 | 655 days ago | Contract Creation | 0 ETH | |||
| 11104788 | 655 days ago | Contract Creation | 0 ETH | |||
| 10778415 | 663 days ago | Contract Creation | 0 ETH | |||
| 10279755 | 675 days ago | Contract Creation | 0 ETH | |||
| 10174124 | 677 days ago | Contract Creation | 0 ETH | |||
| 10120190 | 678 days ago | Contract Creation | 0 ETH | |||
| 9527671 | 692 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Contract Source Code (Solidity)
/**
*Submitted for verification at basescan.org on 2024-01-21
*/
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)
// OpenZeppelin Contracts (last updated v4.9.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);
}
// 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);
}
// 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;
}
}
/**
* @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.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* 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}.
*
* 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 default value returned by this function, unless
* it's 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;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_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;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_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;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_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 {}
}
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20Metadata.sol)
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to
* 0 before setting it to a non-zero value.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
// OpenZeppelin Contracts (last updated v4.9.0) (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() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCast {
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toUint248(uint256 value) internal pure returns (uint248) {
require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toUint240(uint256 value) internal pure returns (uint240) {
require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toUint232(uint256 value) internal pure returns (uint232) {
require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.2._
*/
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toUint216(uint256 value) internal pure returns (uint216) {
require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toUint208(uint256 value) internal pure returns (uint208) {
require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toUint200(uint256 value) internal pure returns (uint200) {
require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toUint192(uint256 value) internal pure returns (uint192) {
require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toUint184(uint256 value) internal pure returns (uint184) {
require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toUint176(uint256 value) internal pure returns (uint176) {
require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toUint168(uint256 value) internal pure returns (uint168) {
require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toUint160(uint256 value) internal pure returns (uint160) {
require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toUint152(uint256 value) internal pure returns (uint152) {
require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toUint144(uint256 value) internal pure returns (uint144) {
require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toUint136(uint256 value) internal pure returns (uint136) {
require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v2.5._
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toUint120(uint256 value) internal pure returns (uint120) {
require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toUint112(uint256 value) internal pure returns (uint112) {
require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toUint104(uint256 value) internal pure returns (uint104) {
require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.2._
*/
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toUint88(uint256 value) internal pure returns (uint88) {
require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toUint80(uint256 value) internal pure returns (uint80) {
require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toUint72(uint256 value) internal pure returns (uint72) {
require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v2.5._
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toUint56(uint256 value) internal pure returns (uint56) {
require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toUint48(uint256 value) internal pure returns (uint48) {
require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toUint40(uint256 value) internal pure returns (uint40) {
require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v2.5._
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toUint24(uint256 value) internal pure returns (uint24) {
require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v2.5._
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v2.5._
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*
* _Available since v3.0._
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.7._
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.7._
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v3.1._
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*
* _Available since v3.0._
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}
struct TradeAction {
uint256 strategyId;
uint128 amount;
}
struct Order {
uint128 y;
uint128 z;
uint64 A;
uint64 B;
}
struct Strategy {
uint256 id;
address owner;
Token[2] tokens;
Order[2] orders;
}
type Token is address;
interface ICarbonController {
function tradeBySourceAmount(
Token sourceToken,
Token targetToken,
TradeAction[] calldata tradeActions,
uint256 deadline,
uint128 minReturn
) external payable returns (uint128);
function tradeByTargetAmount(
Token sourceToken,
Token targetToken,
TradeAction[] calldata tradeActions,
uint256 deadline,
uint128 maxInput
) external payable returns (uint128);
function calculateTradeSourceAmount(
Token sourceToken,
Token targetToken,
TradeAction[] calldata tradeActions
) external view returns (uint128);
function calculateTradeTargetAmount(
Token sourceToken,
Token targetToken,
TradeAction[] calldata tradeActions
) external view returns (uint128);
function createStrategy(
Token token0,
Token token1,
Order[2] calldata orders
) external payable returns (uint256);
function updateStrategy(
uint256 strategyId,
Order[2] calldata currentOrders,
Order[2] calldata newOrders
) external payable;
function deleteStrategy(uint256 strategyId) external;
function strategy(uint256 id) external view returns (Strategy memory);
}
contract CarbonPair is ERC20,ReentrancyGuard,IERC721Receiver{
//curent id of the strategy in carbon
uint256 public strategyId;
address public carbonController;
address public voter;
address public immutable factory;
address public externalBribe;
bool public hasGauge;
address public token0;
address public token1;
bool public initiated;
//errors
error SlippageTooHigh();
event Mint(address indexed sender, uint amount0, uint amount1,uint share);
event Burn(address indexed sender, uint amount0, uint amount1,uint share);
event ExternalBribeSet(address indexed externalBribe);
event HasGaugeSet(bool value);
constructor(string memory _name, string memory _symbol,address _carbonController,address _voter) ERC20(_name,_symbol) {
carbonController = _carbonController;
voter = _voter;
factory = msg.sender;
initiated = false;
}
function initStrategyExactCopy(uint256 _strategyIdToCopy) public {
require(!initiated, "vault started");
Strategy memory strategyToCopy = ICarbonController(carbonController).strategy(_strategyIdToCopy);
token0 = Token.unwrap(strategyToCopy.tokens[0]);
token1 = Token.unwrap(strategyToCopy.tokens[1]);
Order memory token0Order = strategyToCopy.orders[0];
Order memory token1Order = strategyToCopy.orders[1];
uint128 amountToken0 = token0Order.y;
uint128 amountToken1 = token1Order.y;
if(amountToken0 > 0)
SafeERC20.safeTransferFrom(IERC20(token0), msg.sender, address(this), amountToken0);
if(amountToken1 > 0)
SafeERC20.safeTransferFrom(IERC20(token1), msg.sender, address(this), amountToken1);
SafeERC20.safeApprove(IERC20(token0), carbonController, amountToken0);
SafeERC20.safeApprove(IERC20(token1), carbonController, amountToken1);
strategyId = ICarbonController(carbonController).createStrategy(strategyToCopy.tokens[0], strategyToCopy.tokens[1], [token0Order,token1Order]);
uint _amount18Shares = amountToken0 > amountToken1 ? _to18decimals(token0,amountToken0) : _to18decimals(token1,amountToken1);
_mint(msg.sender, _amount18Shares); // this i start share by defult is base on the amout of token that has higher vaule (first init is 100% of shares)
initiated = true;
}
function initStrategy(uint256 _strategyIdToCopy, uint128 _amountToken0,uint128 _amountToken1) public {
require(!initiated, "vault started");
require(_amountToken0 > 0 || _amountToken1 > 0, "amountTokens == 0");
Strategy memory strategyToCopy = ICarbonController(carbonController).strategy(_strategyIdToCopy);
token0 = Token.unwrap(strategyToCopy.tokens[0]);
token1 = Token.unwrap(strategyToCopy.tokens[1]);
if(_amountToken0 > 0)
SafeERC20.safeTransferFrom(IERC20(token0), msg.sender, address(this), _amountToken0);
if(_amountToken1 > 0)
SafeERC20.safeTransferFrom(IERC20(token1), msg.sender, address(this), _amountToken1);
Order memory token0Order = strategyToCopy.orders[0];
Order memory token1Order = strategyToCopy.orders[1];
token0Order.y = _amountToken0;
token0Order.z = _amountToken0;
token1Order.y = _amountToken1;
token1Order.z = _amountToken1;
SafeERC20.safeApprove(IERC20(token0), carbonController, _amountToken0);
SafeERC20.safeApprove(IERC20(token1), carbonController, _amountToken1);
strategyId = ICarbonController(carbonController).createStrategy(strategyToCopy.tokens[0], strategyToCopy.tokens[1], [token0Order,token1Order]);
uint _amount18Shares = _amountToken0 > _amountToken1 ? _to18decimals(token0,_amountToken0) : _to18decimals(token1,_amountToken1);
_mint(msg.sender, _amount18Shares); // this i start share by defult is base on the amout of token that has higher vaule (first init is 100% of shares)
initiated = true;
}
function deposit(address tokenToDeposit,uint128 _amount,uint128 _maxAmountSecondToken) public nonReentrant {
require(strategyId != 0, "vault not started");
require(tokenToDeposit == token0 || tokenToDeposit == token1, "deposit token is not part of the vault");
require(_amount > 0, "_amount == 0");
SafeERC20.safeTransferFrom(IERC20(tokenToDeposit), msg.sender, address(this), _amount);
Strategy memory strategy = ICarbonController(carbonController).strategy(strategyId);
bool isTargetToken0 = Token.unwrap(strategy.tokens[0]) == tokenToDeposit;
address secondTokenAddress = isTargetToken0 ? Token.unwrap(strategy.tokens[1]) : Token.unwrap(strategy.tokens[0]);
Order memory targetTokenOrder = isTargetToken0 ? strategy.orders[0] : strategy.orders[1];
Order memory secondTokenOrder = isTargetToken0 ? strategy.orders[1] : strategy.orders[0];
require(targetTokenOrder.y > secondTokenOrder.y, "you need to use other token as deposit token"); // defend against precision lost with dust amounts
require(targetTokenOrder.y != 0 && secondTokenOrder.y != 0, "out of range");
uint128 _amountSecondToken = SafeCast.toUint128((uint256(secondTokenOrder.y) * uint256(_amount)) / uint256(targetTokenOrder.y));
if (_amountSecondToken > _maxAmountSecondToken)
revert SlippageTooHigh();
if(_amountSecondToken > 0) {
SafeERC20.safeTransferFrom(IERC20(secondTokenAddress), msg.sender, address(this), _amountSecondToken);
SafeERC20.safeApprove(IERC20(secondTokenAddress), carbonController, _amountSecondToken);
}
uint256 depositShare = (totalSupply() * _amount) / targetTokenOrder.y;
Order memory updatedMainOrder;
updatedMainOrder.A = targetTokenOrder.A;
updatedMainOrder.B = targetTokenOrder.B;
updatedMainOrder.z = SafeCast.toUint128(((uint256(targetTokenOrder.y) + uint256(_amount)) * uint256(targetTokenOrder.z) ) / uint256(targetTokenOrder.y));
updatedMainOrder.y = targetTokenOrder.y + _amount;
Order memory updatedSecondOrder;
updatedSecondOrder.A = secondTokenOrder.A;
updatedSecondOrder.B = secondTokenOrder.B;
updatedSecondOrder.z = SafeCast.toUint128(((uint256(secondTokenOrder.y) + uint256(_amountSecondToken)) * uint256(secondTokenOrder.z )) / uint256(secondTokenOrder.y));
updatedSecondOrder.y = secondTokenOrder.y + _amountSecondToken;
(Order memory targetOrder, Order memory sourceOrder) = isTargetToken0
? (updatedMainOrder, updatedSecondOrder)
: (updatedSecondOrder, updatedMainOrder);
SafeERC20.safeApprove(IERC20(tokenToDeposit), carbonController, _amount);
ICarbonController(carbonController).updateStrategy(strategyId, strategy.orders, [targetOrder,sourceOrder]);
_mint(msg.sender, depositShare);
emit Mint(msg.sender, _amount, _amountSecondToken,depositShare);
}
function withdraw(uint256 _shares) public nonReentrant{
require(_shares > 0, "_shares == 0");
Strategy memory strategy = ICarbonController(carbonController).strategy(strategyId);
uint128 token0Amount = SafeCast.toUint128((uint256(strategy.orders[0].y) * _shares) / totalSupply());
uint128 token1Amount = SafeCast.toUint128((uint256(strategy.orders[1].y) * _shares) / totalSupply());
_burn(msg.sender, _shares);
require(token0Amount > 0 || token1Amount > 0,"0 to withdraw"); // in case if sombody try to burn small ammount that are lost in the uint256 -> uint128 convert
Order memory newOrder0;
if(token0Amount >0) {
newOrder0.A = strategy.orders[0].A;
newOrder0.B = strategy.orders[0].B;
newOrder0.z = SafeCast.toUint128(((uint256(strategy.orders[0].y) - uint256(token0Amount)) * uint256(strategy.orders[0].z) ) / uint256(strategy.orders[0].y));
newOrder0.y = strategy.orders[0].y - token0Amount;
} else {
newOrder0.A = strategy.orders[0].A;
newOrder0.B = strategy.orders[0].B;
newOrder0.z = strategy.orders[0].z;
newOrder0.y = strategy.orders[0].y;
}
Order memory newOrder1;
if(token1Amount >0) {
newOrder1.A = strategy.orders[1].A;
newOrder1.B = strategy.orders[1].B;
newOrder1.z = SafeCast.toUint128(((uint256(strategy.orders[1].y) - uint256(token1Amount)) * uint256(strategy.orders[1].z )) / uint256(strategy.orders[1].y));
newOrder1.y = strategy.orders[1].y - token1Amount;
} else {
newOrder1.A = strategy.orders[1].A;
newOrder1.B = strategy.orders[1].B;
newOrder1.z = strategy.orders[1].z;
newOrder1.y = strategy.orders[1].y;
}
if(token0Amount == 0 ) {
newOrder0.z = SafeCast.toUint128((uint256(newOrder1.z) * uint256(newOrder0.z)) / uint256(strategy.orders[1].z));
}
if(token1Amount == 0 ) {
newOrder1.z = SafeCast.toUint128((uint256(newOrder0.z) * uint256(newOrder1.z)) / uint256(strategy.orders[0].z));
}
ICarbonController(carbonController).updateStrategy(strategyId, strategy.orders, [newOrder0,newOrder1]);
if(token0Amount > 0) {
SafeERC20.safeTransfer(IERC20(Token.unwrap(strategy.tokens[0])), msg.sender, token0Amount);
}
if(token1Amount > 0) {
SafeERC20.safeTransfer(IERC20(Token.unwrap(strategy.tokens[1])), msg.sender, token1Amount);
}
emit Burn(msg.sender, token0Amount, token1Amount, _shares);
}
function carbonBalance() public view returns (address,address,uint,uint) {
Strategy memory strategy = ICarbonController(carbonController).strategy(strategyId);
return (Token.unwrap(strategy.tokens[0]),Token.unwrap(strategy.tokens[1]),strategy.orders[0].y,strategy.orders[1].y);
}
function outOfRange() public view returns (bool) {
Strategy memory strategy = ICarbonController(carbonController).strategy(strategyId);
return !(strategy.orders[0].y != 0 && strategy.orders[1].y != 0);
}
function quoteRemoveLiquidity(uint256 _shares) public view returns (address,address,uint,uint) {
Strategy memory strategy = ICarbonController(carbonController).strategy(strategyId);
uint128 token0Amount = SafeCast.toUint128((uint256(strategy.orders[0].y) * _shares) / totalSupply());
uint128 token1Amount = SafeCast.toUint128((uint256(strategy.orders[1].y) * _shares) / totalSupply());
return (Token.unwrap(strategy.tokens[0]),Token.unwrap(strategy.tokens[1]),token0Amount,token1Amount);
}
function getSecondTokenAmount(address tokenToDeposit,uint128 _amount) public view returns (uint) {
Strategy memory strategy = ICarbonController(carbonController).strategy(strategyId);
bool isTargetToken0 = Token.unwrap(strategy.tokens[0]) == tokenToDeposit;
address secondTokenAddress = isTargetToken0 ? Token.unwrap(strategy.tokens[1]) : Token.unwrap(strategy.tokens[0]);
Order memory targetTokenOrder = isTargetToken0 ? strategy.orders[0] : strategy.orders[1];
Order memory secondTokenOrder = isTargetToken0 ? strategy.orders[1] : strategy.orders[0];
return !(targetTokenOrder.y == 0) ? SafeCast.toUint128((uint256(secondTokenOrder.y) * uint256(_amount)) / uint256(targetTokenOrder.y)) : 0;
}
function balanceOfToken0() public view returns (uint) {
return IERC20(token0).balanceOf(address(this));
}
function balanceOfToken1() public view returns (uint) {
return IERC20(token1).balanceOf(address(this));
}
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4) {
return IERC721Receiver.onERC721Received.selector;
}
function emergencyWithdraw(address recipient) public {
require(msg.sender == factory,"access denied");
ICarbonController(carbonController).deleteStrategy(strategyId);
uint token0Amount = balanceOfToken0();
uint token1Amount = balanceOfToken1();
if(token0Amount > 0) {
SafeERC20.safeTransfer(IERC20(token0), recipient, token0Amount);
}
if(token1Amount > 0) {
SafeERC20.safeTransfer(IERC20(token1), recipient, token1Amount);
}
}
//functions required by voter
function setHasGauge(bool value) external {
require(msg.sender == voter, 'Only voter can set has gauge');
hasGauge = value;
emit HasGaugeSet(value);
}
function setExternalBribe(address _externalBribe) external {
require(msg.sender == voter, 'Only voter can set external bribe');
externalBribe = _externalBribe;
emit ExternalBribeSet(_externalBribe);
}
//precision functions
function _to18decimals(address _token,uint _amount) internal returns (uint amount) {
amount = _amount * 1e18 / 10**IERC20Metadata(_token).decimals();
}
function _from18decimals(address _token,uint _amount) internal returns (uint amount,uint amount18decimals) {
amount = _amount * 10**IERC20Metadata(_token).decimals() / 1e18;
amount18decimals = _to18decimals(_token,amount); // to cover precision lost
}
}
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
contract CarbonPairFactory is Ownable {
address public carbonController;
address public voter;
address[] public allPairs;
mapping(address => bool) public isPair; // only whitelisted ones
mapping(address => bool) public isCarbonPair;
bool betaPhase = true;
event PairCreated(uint indexed strategyId,uint strategyIdToCopy,address pair);
constructor(address _carbonController,address _voter,address _team) {
carbonController = _carbonController;
voter = _voter;
transferOwnership(_team);
}
function whitelistPair (address _pair) external onlyOwner {
require(isCarbonPair[_pair],"not a carbon pair");
isPair[_pair] = true;
}
function blacklistPair (address _pair) external onlyOwner {
require(isCarbonPair[_pair],"not a carbon pair");
isPair[_pair] = false;
}
function addExistingPair (address _pair) external onlyOwner {
require(!isCarbonPair[_pair],"existing carbon pair");
allPairs.push(_pair);
isCarbonPair[_pair] = true;
isPair[_pair] = true;
}
function createPair(uint256 _strategyIdToCopy) external returns (address pair) {
(address token0,address token1,uint token0Amount,uint token1Amount) = carbonBalance(_strategyIdToCopy);
string memory name = string(abi.encodePacked("Concentrated Liquidity - ", IERC20Metadata(token0).symbol(), "/", IERC20Metadata(token1).symbol()));
string memory symbol = string(abi.encodePacked("CL-", IERC20Metadata(token0).symbol(), "/", IERC20Metadata(token1).symbol()));
CarbonPair cp = new CarbonPair(name,symbol,carbonController,voter);
if(token0Amount > 0) {
SafeERC20.safeTransferFrom(IERC20(token0), msg.sender, address(this), token0Amount);
SafeERC20.safeApprove(IERC20(token0), address(cp), token0Amount);
}
if(token1Amount > 0) {
SafeERC20.safeTransferFrom(IERC20(token1), msg.sender, address(this), token1Amount);
SafeERC20.safeApprove(IERC20(token1), address(cp), token1Amount);
}
cp.initStrategyExactCopy(_strategyIdToCopy);
address newCPAddress = address(cp);
allPairs.push(newCPAddress);
isCarbonPair[newCPAddress] = true;
IERC20(newCPAddress).transfer(msg.sender,IERC20(newCPAddress).balanceOf(address(this)));
emit PairCreated(cp.strategyId(),_strategyIdToCopy,newCPAddress);
return newCPAddress;
}
function carbonBalance(uint strategyId) public view returns (address,address,uint,uint) {
Strategy memory strategy = ICarbonController(carbonController).strategy(strategyId);
return (Token.unwrap(strategy.tokens[0]),Token.unwrap(strategy.tokens[1]),strategy.orders[0].y,strategy.orders[1].y);
}
function allPairsLength() external view returns (uint) {
return allPairs.length;
}
function betaPhaseDone() public onlyOwner {
require(betaPhase,"not beta phase");
betaPhase = false;
}
function emergencyWithdraw(address pair) public onlyOwner {
require(betaPhase,"not beta phase");
require(isCarbonPair[pair],"not a carbon pair");
isCarbonPair[pair] = false;
isPair[pair] = false;
CarbonPair(pair).emergencyWithdraw(msg.sender);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_carbonController","type":"address"},{"internalType":"address","name":"_voter","type":"address"},{"internalType":"address","name":"_team","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"strategyId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"strategyIdToCopy","type":"uint256"},{"indexed":false,"internalType":"address","name":"pair","type":"address"}],"name":"PairCreated","type":"event"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"}],"name":"addExistingPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allPairs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allPairsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"betaPhaseDone","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"}],"name":"blacklistPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"strategyId","type":"uint256"}],"name":"carbonBalance","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"carbonController","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_strategyIdToCopy","type":"uint256"}],"name":"createPair","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isCarbonPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"voter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"}],"name":"whitelistPair","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040526006805460ff191660011790553480156200001e57600080fd5b5060405162004e0b38038062004e0b8339810160408190526200004191620001de565b6200004c3362000090565b600180546001600160a01b038086166001600160a01b03199283161790925560028054928516929091169190911790556200008781620000e0565b50505062000228565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b620000ea62000163565b6001600160a01b038116620001555760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b620001608162000090565b50565b6000546001600160a01b03163314620001bf5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016200014c565b565b80516001600160a01b0381168114620001d957600080fd5b919050565b600080600060608486031215620001f457600080fd5b620001ff84620001c1565b92506200020f60208501620001c1565b91506200021f60408501620001c1565b90509250925092565b614bd380620002386000396000f3fe60806040523480156200001157600080fd5b5060043610620001155760003560e01c80638da5cb5b11620000a3578063d9164817116200006e578063d9164817146200024f578063e5e31b131462000286578063f1e6c40614620002ac578063f2fde38b14620002c357600080fd5b80638da5cb5b14620001cc578063a1e1fdac14620001de578063ab87f2fd1462000221578063ced78e25146200023857600080fd5b8063567fd09e11620000e4578063567fd09e146200018f578063574f2ba314620001995780636ff1c9bc14620001ab578063715018a614620001c257600080fd5b80630362158f146200011a5780630850ad99146200014b5780631e3dd18b146200016457806346c96aac146200017b575b600080fd5b6001546200012e906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b620001626200015c36600462001157565b620002da565b005b6200012e620001753660046200117e565b620003c5565b6002546200012e906001600160a01b031681565b62000162620003f0565b60035460405190815260200162000142565b62000162620001bc36600462001157565b6200044b565b6200016262000561565b6000546001600160a01b03166200012e565b620001f5620001ef3660046200117e565b62000579565b604080516001600160a01b03958616815294909316602085015291830152606082015260800162000142565b620001626200023236600462001157565b62000628565b6200012e620002493660046200117e565b6200068e565b620002756200026036600462001157565b60056020526000908152604090205460ff1681565b604051901515815260200162000142565b620002756200029736600462001157565b60046020526000908152604090205460ff1681565b62000162620002bd36600462001157565b62000b8b565b62000162620002d436600462001157565b62000bf4565b620002e462000c73565b6001600160a01b03811660009081526005602052604090205460ff16156200034a5760405162461bcd60e51b815260206004820152601460248201527332bc34b9ba34b7339031b0b93137b7103830b4b960611b60448201526064015b60405180910390fd5b6003805460018181019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b039093166001600160a01b0319909316831790556000918252600560209081526040808420805460ff19908116851790915560049092529092208054909216179055565b60038181548110620003d657600080fd5b6000918252602090912001546001600160a01b0316905081565b620003fa62000c73565b60065460ff166200043f5760405162461bcd60e51b815260206004820152600e60248201526d6e6f74206265746120706861736560901b604482015260640162000341565b6006805460ff19169055565b6200045562000c73565b60065460ff166200049a5760405162461bcd60e51b815260206004820152600e60248201526d6e6f74206265746120706861736560901b604482015260640162000341565b6001600160a01b03811660009081526005602052604090205460ff16620004d55760405162461bcd60e51b8152600401620003419062001198565b6001600160a01b0381166000818152600560209081526040808320805460ff199081169091556004928390529281902080549093169092559051631bfc726f60e21b81523391810191909152636ff1c9bc90602401600060405180830381600087803b1580156200054557600080fd5b505af11580156200055a573d6000803e3d6000fd5b5050505050565b6200056b62000c73565b62000577600062000ccf565b565b600154604051632f2235f960e21b81526004810183905260009182918291829182916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015620005cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005f3919062001319565b604081015180516020918201516060909301518051519201515190999298506001600160801b03918216975016945092505050565b6200063262000c73565b6001600160a01b03811660009081526005602052604090205460ff166200066d5760405162461bcd60e51b8152600401620003419062001198565b6001600160a01b03166000908152600460205260409020805460ff19169055565b6000806000806000620006a18662000579565b93509350935093506000846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620006ea573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620007149190810190620013f9565b846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000753573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200077d9190810190620013f9565b60405160200162000790929190620014a7565b60405160208183030381529060405290506000856001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620007e2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200080c9190810190620013f9565b856001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156200084b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620008759190810190620013f9565b6040516020016200088892919062001510565b60408051601f1981840301815290829052600154600254919350600092859285926001600160a01b0390811692911690620008c39062001133565b620008d294939291906200158d565b604051809103906000f080158015620008ef573d6000803e3d6000fd5b50905084156200091457620009078733308862000d1f565b6200091487828762000d92565b83156200093657620009298633308762000d1f565b6200093686828662000d92565b604051630ad374dd60e41b8152600481018a90526001600160a01b0382169063ad374dd090602401600060405180830381600087803b1580156200097957600080fd5b505af11580156200098e573d6000803e3d6000fd5b50506003805460018082019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b03861690811790915560008181526005602052604090819020805460ff191690931790925590516370a0823160e01b815230600482015284935090915063a9059cbb90339083906370a0823190602401602060405180830381865afa15801562000a3f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a659190620015db565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af115801562000ab1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ad79190620015f5565b50816001600160a01b031663492f4e186040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000b17573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b3d9190620015db565b604080518c81526001600160a01b03841660208201527ff7ee1758a8519d7fe72714f8cfd41d75d71255250aa858f78cb859f6f3c78232910160405180910390a29998505050505050505050565b62000b9562000c73565b6001600160a01b03811660009081526005602052604090205460ff1662000bd05760405162461bcd60e51b8152600401620003419062001198565b6001600160a01b03166000908152600460205260409020805460ff19166001179055565b62000bfe62000c73565b6001600160a01b03811662000c655760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000341565b62000c708162000ccf565b50565b6000546001600160a01b03163314620005775760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000341565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038085166024830152831660448201526064810182905262000d8c9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915262000eb4565b50505050565b80158062000e105750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801562000de8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e0e9190620015db565b155b62000e7d5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840162000341565b6040516001600160a01b03831660248201526044810182905262000eaf90849063095ea7b360e01b9060640162000d54565b505050565b600062000f0b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031662000f909092919063ffffffff16565b905080516000148062000f2f57508080602001905181019062000f2f9190620015f5565b62000eaf5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000341565b606062000fa1848460008562000fa9565b949350505050565b6060824710156200100c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000341565b600080866001600160a01b031685876040516200102a919062001619565b60006040518083038185875af1925050503d806000811462001069576040519150601f19603f3d011682016040523d82523d6000602084013e6200106e565b606091505b509150915062001081878383876200108c565b979650505050505050565b6060831562001100578251600003620010f8576001600160a01b0385163b620010f85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000341565b508162000fa1565b62000fa18383815115620011175781518083602001fd5b8060405162461bcd60e51b815260040162000341919062001637565b613551806200164d83390190565b6001600160a01b038116811462000c7057600080fd5b6000602082840312156200116a57600080fd5b8135620011778162001141565b9392505050565b6000602082840312156200119157600080fd5b5035919050565b6020808252601190820152703737ba10309031b0b93137b7103830b4b960791b604082015260600190565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715620011ff57620011ff620011c3565b60405290565b6040805190810167ffffffffffffffff81118282101715620011ff57620011ff620011c3565b80516001600160801b03811681146200124357600080fd5b919050565b805167ffffffffffffffff811681146200124357600080fd5b600082601f8301126200127357600080fd5b6200127d62001205565b806101008401858111156200129157600080fd5b845b818110156200130e5760808188031215620012ae5760008081fd5b620012b8620011d9565b620012c3826200122b565b81526020620012d48184016200122b565b818301526040620012e781850162001248565b908301526060620012fa84820162001248565b908301529085529093019260800162001293565b509095945050505050565b600061018082840312156200132d57600080fd5b62001337620011d9565b825181526020808401516200134c8162001141565b82820152605f840185136200136057600080fd5b6200136a62001205565b8060808601878111156200137d57600080fd5b604087015b81811015620013a6578051620013988162001141565b845292840192840162001382565b50816040860152620013b9888262001261565b606086015250929695505050505050565b60005b83811015620013e7578181015183820152602001620013cd565b8381111562000d8c5750506000910152565b6000602082840312156200140c57600080fd5b815167ffffffffffffffff808211156200142557600080fd5b818401915084601f8301126200143a57600080fd5b8151818111156200144f576200144f620011c3565b604051601f8201601f19908116603f011681019083821181831017156200147a576200147a620011c3565b816040528281528760208487010111156200149457600080fd5b62001081836020830160208801620013ca565b7f436f6e63656e74726174656420204c6971756964697479202d20000000000000815260008351620014e181601a850160208801620013ca565b602f60f81b601a9184019182015283516200150481601b840160208801620013ca565b01601b01949350505050565b62434c2d60e81b81526000835162001530816003850160208801620013ca565b602f60f81b600391840191820152835162001553816004840160208801620013ca565b01600401949350505050565b6000815180845262001579816020860160208601620013ca565b601f01601f19169290920160200192915050565b608081526000620015a260808301876200155f565b8281036020840152620015b681876200155f565b6001600160a01b03958616604085015293909416606090920191909152509392505050565b600060208284031215620015ee57600080fd5b5051919050565b6000602082840312156200160857600080fd5b815180151581146200117757600080fd5b600082516200162d818460208701620013ca565b9190910192915050565b6020815260006200117760208301846200155f56fe60a06040523480156200001157600080fd5b506040516200355138038062003551833981016040819052620000349162000240565b8351849084906200004d906003906020850190620000b0565b50805162000063906004906020840190620000b0565b5050600160055550600780546001600160a01b039384166001600160a01b03199182161790915560088054929093169116179055505033608052600b805460ff60a01b191690556200030b565b828054620000be90620002cf565b90600052602060002090601f016020900481019282620000e257600085556200012d565b82601f10620000fd57805160ff19168380011785556200012d565b828001600101855582156200012d579182015b828111156200012d57825182559160200191906001019062000110565b506200013b9291506200013f565b5090565b5b808211156200013b576000815560010162000140565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200017e57600080fd5b81516001600160401b03808211156200019b576200019b62000156565b604051601f8301601f19908116603f01168101908282118183101715620001c657620001c662000156565b81604052838152602092508683858801011115620001e357600080fd5b600091505b83821015620002075785820183015181830184015290820190620001e8565b83821115620002195760008385830101525b9695505050505050565b80516001600160a01b03811681146200023b57600080fd5b919050565b600080600080608085870312156200025757600080fd5b84516001600160401b03808211156200026f57600080fd5b6200027d888389016200016c565b955060208701519150808211156200029457600080fd5b50620002a3878288016200016c565b935050620002b46040860162000223565b9150620002c46060860162000223565b905092959194509250565b600181811c90821680620002e457607f821691505b6020821081036200030557634e487b7160e01b600052602260045260246000fd5b50919050565b6080516132236200032e6000396000818161049901526110d501526132236000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c80636ff1c9bc1161011a578063ad374dd0116100ad578063c45a01551161007c578063c45a015514610494578063c8eaac0b146104bb578063d21220a7146104c3578063dd62ed3e146104d6578063e455dea8146104e957600080fd5b8063ad374dd014610448578063b22d8fe01461045b578063c3df46d81461046e578063c3fbc5ef1461048157600080fd5b80639f118536116100e95780639f11853614610406578063a0f821711461041a578063a457c2d714610422578063a9059cbb1461043557600080fd5b80636ff1c9bc146103ae57806370a08231146103c157806391f36d65146103ea57806395d89b41146103fe57600080fd5b806323b872dd1161019d578063395093511161016c578063395093511461035957806345a1de791461036c57806346c96aac1461037f578063492f4e18146103925780634a65f70b1461039b57600080fd5b806323b872dd146102f15780632644b97b146103045780632e1a7d4d14610337578063313ce5671461034a57600080fd5b80630dfe1681116101d95780630dfe168114610289578063150b7a021461029c57806318160ddd146102d457806319999566146102dc57600080fd5b80630134e0f41461020b5780630362158f1461022657806306fdde0314610251578063095ea7b314610266575b600080fd5b6102136104fc565b6040519081526020015b60405180910390f35b600754610239906001600160a01b031681565b6040516001600160a01b03909116815260200161021d565b61025961056f565b60405161021d9190612a40565b610279610274366004612a88565b610601565b604051901515815260200161021d565b600a54610239906001600160a01b031681565b6102bb6102aa366004612ab4565b630a85bd0160e11b95945050505050565b6040516001600160e01b0319909116815260200161021d565b600254610213565b6102ef6102ea366004612b53565b61061b565b005b6102796102ff366004612b70565b6106ce565b61030c6106f2565b604080516001600160a01b03958616815294909316602085015291830152606082015260800161021d565b6102ef610345366004612bb1565b6107a1565b6040516012815260200161021d565b610279610367366004612a88565b610d6a565b600954610239906001600160a01b031681565b600854610239906001600160a01b031681565b61021360065481565b6102ef6103a9366004612bdf565b610d8c565b6102ef6103bc366004612b53565b6110ca565b6102136103cf366004612b53565b6001600160a01b031660009081526020819052604090205490565b60095461027990600160a01b900460ff1681565b6102596111f0565b600b5461027990600160a01b900460ff1681565b6102796111ff565b610279610430366004612a88565b6112b4565b610279610443366004612a88565b61132f565b6102ef610456366004612bb1565b61133d565b6102ef610469366004612c2f565b6115d7565b61021361047c366004612c4c565b611689565b6102ef61048f366004612c85565b6117e6565b6102397f000000000000000000000000000000000000000000000000000000000000000081565b610213611e34565b600b54610239906001600160a01b031681565b6102136104e4366004612cb5565b611e65565b61030c6104f7366004612bb1565b611e90565b600b546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a08231906024015b602060405180830381865afa158015610546573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056a9190612ce3565b905090565b60606003805461057e90612cfc565b80601f01602080910402602001604051908101604052809291908181526020018280546105aa90612cfc565b80156105f75780601f106105cc576101008083540402835291602001916105f7565b820191906000526020600020905b8154815290600101906020018083116105da57829003601f168201915b5050505050905090565b60003361060f818585611f74565b60019150505b92915050565b6008546001600160a01b031633146106845760405162461bcd60e51b815260206004820152602160248201527f4f6e6c7920766f7465722063616e207365742065787465726e616c20627269626044820152606560f81b60648201526084015b60405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040517f03e9b76bf8c2d2d6948b20459194f64843d25ada1a13e3481bf88399831a046190600090a250565b6000336106dc858285612098565b6106e7858585612112565b506001949350505050565b600754600654604051632f2235f960e21b8152600481019190915260009182918291829182916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015610749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076d9190612e60565b604081015180516020918201516060909301518051519201515190989297506001600160801b039182169650169350915050565b6107a96122b6565b600081116107e85760405162461bcd60e51b815260206004820152600c60248201526b05f736861726573203d3d20360a41b604482015260640161067b565b600754600654604051632f2235f960e21b815260048101919091526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015610837573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085b9190612e60565b9050600061089d61086b60025490565b6060840151859060005b60200201515161088e91906001600160801b0316612f2e565b6108989190612f4d565b61230f565b905060006108bb6108ad60025490565b606085015186906001610875565b90506108c7338561237c565b6000826001600160801b031611806108e857506000816001600160801b0316115b6109245760405162461bcd60e51b815260206004820152600d60248201526c3020746f20776974686472617760981b604482015260640161067b565b6040805160808101825260008082526020820181905291810182905260608101919091526001600160801b038316156109ff57606084810180515160409081015167ffffffffffffffff9081169185019190915281515183015116918301919091525180518051602091909101516109cf926001600160801b03928316929182169187169060005b6020020151516109c591906001600160801b0316612f6f565b61088e9190612f2e565b6001600160801b03166020820152606084015151516109ef908490612f86565b6001600160801b03168152610a51565b606084810180515160409081015167ffffffffffffffff9081169185019190915281515183015116918301919091528051516020908101516001600160801b0390811691840191909152905151511681525b6040805160808101825260008082526020820181905291810182905260608101919091526001600160801b03831615610b1a576060858101805160209081015160409081015167ffffffffffffffff908116918601919091528251820151840151169284019290925251808201518051920151610ae3926001600160801b0390811692918116919087169060016109ac565b6001600160801b03166020820152606085015183906001602002015151610b0a9190612f86565b6001600160801b03168152610b72565b6060858101805160209081015160409081015167ffffffffffffffff908116918601919091528251820151840151169284019290925280518201518201516001600160801b0390811684840152905190910151511681525b836001600160801b0316600003610bd5576060850151610bc69060016020020151602001516001600160801b031683602001516001600160801b031683602001516001600160801b031661088e9190612f2e565b6001600160801b031660208301525b826001600160801b0316600003610c38576060850151610c299060006020020151602001516001600160801b031682602001516001600160801b031684602001516001600160801b031661088e9190612f2e565b6001600160801b031660208201525b60075460065460608701516040805180820182528681526020810186905290516321589fa160e01b81526001600160a01b03909416936321589fa193610c849390929091600401613012565b600060405180830381600087803b158015610c9e57600080fd5b505af1158015610cb2573d6000803e3d6000fd5b505050506001600160801b03841615610cdf57604085015151610cdf90336001600160801b0387166124ae565b6001600160801b03831615610d0b57604085015160200151610d0b90336001600160801b0386166124ae565b604080516001600160801b0380871682528516602082015290810187905233907f743033787f4738ff4d6a7225ce2bd0977ee5f86b91a902a58f5e4d0b297b46449060600160405180910390a25050505050610d676001600555565b50565b60003361060f818585610d7d8383611e65565b610d879190613035565b611f74565b600b54600160a01b900460ff1615610dd65760405162461bcd60e51b815260206004820152600d60248201526c1d985d5b1d081cdd185c9d1959609a1b604482015260640161067b565b6000826001600160801b03161180610df757506000816001600160801b0316115b610e375760405162461bcd60e51b81526020600482015260116024820152700616d6f756e74546f6b656e73203d3d203607c1b604482015260640161067b565b600754604051632f2235f960e21b8152600481018590526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015610e82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea69190612e60565b60408101518051600a80546001600160a01b03199081166001600160a01b0393841617909155602090920151600b8054909316911617905590506001600160801b03831615610f1057600a54610f10906001600160a01b031633306001600160801b038716612511565b6001600160801b03821615610f4057600b54610f40906001600160a01b031633306001600160801b038616612511565b606081015180516020918201516001600160801b0386811680845283850181905290861680835293820193909352600a5460075492939192610f91926001600160a01b039283169290911690612549565b600b54600754610fb7916001600160a01b0390811691166001600160801b038716612549565b6007546040848101518051602091820151835180850185528781529283018690529251637b93a39d60e11b81526001600160a01b039094169363f727473a9361100493909160040161304d565b6020604051808303816000875af1158015611023573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110479190612ce3565b60065560006001600160801b038086169087161161108357600b5461107e906001600160a01b03166001600160801b03871661265e565b6110a2565b600a546110a2906001600160a01b03166001600160801b03881661265e565b90506110ae33826126f0565b5050600b805460ff60a01b1916600160a01b1790555050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146111325760405162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015260640161067b565b600754600654604051638730203760e01b81526001600160a01b03909216916387302037916111679160040190815260200190565b600060405180830381600087803b15801561118157600080fd5b505af1158015611195573d6000803e3d6000fd5b5050505060006111a3611e34565b905060006111af6104fc565b905081156111ce57600a546111ce906001600160a01b031684846124ae565b80156111eb57600b546111eb906001600160a01b031684836124ae565b505050565b60606004805461057e90612cfc565b600754600654604051632f2235f960e21b815260009283926001600160a01b039091169163bc88d7e4916112399160040190815260200190565b61018060405180830381865afa158015611257573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127b9190612e60565b606081015151519091506001600160801b0316158015906112ad5750606081015160200151516001600160801b031615155b1591505090565b600033816112c28286611e65565b9050838110156113225760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161067b565b6106e78286868403611f74565b60003361060f818585612112565b600b54600160a01b900460ff16156113875760405162461bcd60e51b815260206004820152600d60248201526c1d985d5b1d081cdd185c9d1959609a1b604482015260640161067b565b600754604051632f2235f960e21b8152600481018390526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa1580156113d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f69190612e60565b60408101518051600a80546001600160a01b039283166001600160a01b031991821617909155602092830151600b8054919093169116179055606082015180519101518151815193945091929091906001600160801b0382161561147557600a54611475906001600160a01b031633306001600160801b038616612511565b6001600160801b038116156114a557600b546114a5906001600160a01b031633306001600160801b038516612511565b600a546007546114cb916001600160a01b0390811691166001600160801b038516612549565b600b546007546114f1916001600160a01b0390811691166001600160801b038416612549565b6007546040868101518051602091820151835180850185528981529283018890529251637b93a39d60e11b81526001600160a01b039094169363f727473a9361153e93909160040161304d565b6020604051808303816000875af115801561155d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115819190612ce3565b60065560006001600160801b03808316908416116115b857600b5461107e906001600160a01b03166001600160801b03841661265e565b600a546110a2906001600160a01b03166001600160801b03851661265e565b6008546001600160a01b031633146116315760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c7920766f7465722063616e207365742068617320676175676500000000604482015260640161067b565b60098054821515600160a01b0260ff60a01b199091161790556040517f352eb552c369d470b6f2286567a9f272a1210ad788562e697f254cad5611f1059061167e90831515815260200190565b60405180910390a150565b600754600654604051632f2235f960e21b815260009283926001600160a01b039091169163bc88d7e4916116c39160040190815260200190565b61018060405180830381865afa1580156116e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117059190612e60565b90506000846001600160a01b0316826040015160006002811061172a5761172a612f02565b60200201516001600160a01b031614905060008161174d57604083015151611757565b6040830151602001515b905060008261176e57606084015160200151611775565b6060840151515b905060008361178957606085015151611793565b6060850151602001515b82519091506001600160801b03166000036117af5760006117d1565b815181516117d1916001600160801b039081169161088e918b81169116612f2e565b6001600160801b031698975050505050505050565b6117ee6122b6565b6006546000036118345760405162461bcd60e51b81526020600482015260116024820152701d985d5b1d081b9bdd081cdd185c9d1959607a1b604482015260640161067b565b600a546001600160a01b038481169116148061185d5750600b546001600160a01b038481169116145b6118b85760405162461bcd60e51b815260206004820152602660248201527f6465706f73697420746f6b656e206973206e6f742070617274206f6620746865604482015265081d985d5b1d60d21b606482015260840161067b565b6000826001600160801b0316116119005760405162461bcd60e51b815260206004820152600c60248201526b05f616d6f756e74203d3d20360a41b604482015260640161067b565b611915833330856001600160801b0316612511565b600754600654604051632f2235f960e21b815260048101919091526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015611964573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119889190612e60565b90506000846001600160a01b031682604001516000600281106119ad576119ad612f02565b60200201516001600160a01b03161490506000816119d0576040830151516119da565b6040830151602001515b90506000826119f1576060840151602001516119f8565b6060840151515b9050600083611a0c57606085015151611a16565b6060850151602001515b805183519192506001600160801b03908116911611611a8c5760405162461bcd60e51b815260206004820152602c60248201527f796f75206e65656420746f20757365206f7468657220746f6b656e206173206460448201526b32b837b9b4ba103a37b5b2b760a11b606482015260840161067b565b81516001600160801b031615801590611aae575080516001600160801b031615155b611ae95760405162461bcd60e51b815260206004820152600c60248201526b6f7574206f662072616e676560a01b604482015260640161067b565b6000611b1e83600001516001600160801b0316896001600160801b031684600001516001600160801b031661088e9190612f2e565b9050866001600160801b0316816001600160801b03161115611b535760405163428637bb60e11b815260040160405180910390fd5b6001600160801b03811615611b9857611b77843330846001600160801b0316612511565b600754611b989085906001600160a01b03166001600160801b038416612549565b600083600001516001600160801b0316896001600160801b0316611bbb60025490565b611bc59190612f2e565b611bcf9190612f4d565b9050611bfb60408051608081018252600080825260208201819052918101829052606081019190915290565b60408086015167ffffffffffffffff908116918301919091526060808701519091169082015284516020860151611c47916001600160801b03908116918116906109c5908e1683613035565b6001600160801b031660208201528451611c62908b90613073565b6001600160801b03908116825260408051608081018252600080825260208083018290528284018281526060808501938452948a015167ffffffffffffffff9081169091529389015190931690528651918701519092611cce928116918116906109c590881683613035565b6001600160801b031660208201528451611ce9908590613073565b6001600160801b0316815260008089611d03578284611d06565b83835b91509150611d338e600760009054906101000a90046001600160a01b03168f6001600160801b0316612549565b60075460065460608d01516040805180820182528681526020810186905290516321589fa160e01b81526001600160a01b03909416936321589fa193611d7f9390929091600401613012565b600060405180830381600087803b158015611d9957600080fd5b505af1158015611dad573d6000803e3d6000fd5b50505050611dbb33866126f0565b336001600160a01b03167fb4c03061fb5b7fed76389d5af8f2e0ddb09f8c70d1333abbb62582835e10accb8e8888604051611e17939291906001600160801b039384168152919092166020820152604081019190915260600190565b60405180910390a250505050505050505050506111eb6001600555565b600a546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401610529565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600754600654604051632f2235f960e21b8152600481019190915260009182918291829182916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015611ee7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f0b9190612e60565b90506000611f29611f1b60025490565b606084015189906000610875565b90506000611f47611f3960025490565b60608501518a906001610875565b60409390930151805160209091015190999098506001600160801b03928316975091909216945092505050565b6001600160a01b038316611fd65760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161067b565b6001600160a01b0382166120375760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161067b565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006120a48484611e65565b9050600019811461210c57818110156120ff5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161067b565b61210c8484848403611f74565b50505050565b6001600160a01b0383166121765760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161067b565b6001600160a01b0382166121d85760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161067b565b6001600160a01b038316600090815260208190526040902054818110156122505760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161067b565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a361210c565b6002600554036123085760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161067b565b6002600555565b60006001600160801b038211156123785760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b606482015260840161067b565b5090565b6001600160a01b0382166123dc5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161067b565b6001600160a01b038216600090815260208190526040902054818110156124505760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161067b565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6040516001600160a01b0383166024820152604481018290526111eb90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526127af565b6040516001600160a01b038085166024830152831660448201526064810182905261210c9085906323b872dd60e01b906084016124da565b8015806125c35750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801561259d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c19190612ce3565b155b61262e5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840161067b565b6040516001600160a01b0383166024820152604481018290526111eb90849063095ea7b360e01b906064016124da565b6000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561269e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c2919061309e565b6126cd90600a6131a5565b6126df83670de0b6b3a7640000612f2e565b6126e99190612f4d565b9392505050565b6001600160a01b0382166127465760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161067b565b80600260008282546127589190613035565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6000612804826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166128849092919063ffffffff16565b905080516000148061282557508080602001905181019061282591906131b4565b6111eb5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161067b565b6060612893848460008561289b565b949350505050565b6060824710156128fc5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161067b565b600080866001600160a01b0316858760405161291891906131d1565b60006040518083038185875af1925050503d8060008114612955576040519150601f19603f3d011682016040523d82523d6000602084013e61295a565b606091505b509150915061296b87838387612976565b979650505050505050565b606083156129e55782516000036129de576001600160a01b0385163b6129de5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161067b565b5081612893565b61289383838151156129fa5781518083602001fd5b8060405162461bcd60e51b815260040161067b9190612a40565b60005b83811015612a2f578181015183820152602001612a17565b8381111561210c5750506000910152565b6020815260008251806020840152612a5f816040850160208701612a14565b601f01601f19169190910160400192915050565b6001600160a01b0381168114610d6757600080fd5b60008060408385031215612a9b57600080fd5b8235612aa681612a73565b946020939093013593505050565b600080600080600060808688031215612acc57600080fd5b8535612ad781612a73565b94506020860135612ae781612a73565b935060408601359250606086013567ffffffffffffffff80821115612b0b57600080fd5b818801915088601f830112612b1f57600080fd5b813581811115612b2e57600080fd5b896020828501011115612b4057600080fd5b9699959850939650602001949392505050565b600060208284031215612b6557600080fd5b81356126e981612a73565b600080600060608486031215612b8557600080fd5b8335612b9081612a73565b92506020840135612ba081612a73565b929592945050506040919091013590565b600060208284031215612bc357600080fd5b5035919050565b6001600160801b0381168114610d6757600080fd5b600080600060608486031215612bf457600080fd5b833592506020840135612c0681612bca565b91506040840135612c1681612bca565b809150509250925092565b8015158114610d6757600080fd5b600060208284031215612c4157600080fd5b81356126e981612c21565b60008060408385031215612c5f57600080fd5b8235612c6a81612a73565b91506020830135612c7a81612bca565b809150509250929050565b600080600060608486031215612c9a57600080fd5b8335612ca581612a73565b92506020840135612c0681612bca565b60008060408385031215612cc857600080fd5b8235612cd381612a73565b91506020830135612c7a81612a73565b600060208284031215612cf557600080fd5b5051919050565b600181811c90821680612d1057607f821691505b602082108103612d3057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715612d6f57612d6f612d36565b60405290565b6040805190810167ffffffffffffffff81118282101715612d6f57612d6f612d36565b805167ffffffffffffffff81168114612db057600080fd5b919050565b600082601f830112612dc657600080fd5b612dce612d75565b80610100840185811115612de157600080fd5b845b81811015612e555760808188031215612dfc5760008081fd5b612e04612d4c565b8151612e0f81612bca565b8152602082810151612e2081612bca565b828201526040612e31848201612d98565b908301526060612e42848201612d98565b9083015290855290930192608001612de3565b509095945050505050565b60006101808284031215612e7357600080fd5b612e7b612d4c565b82518152602080840151612e8e81612a73565b82820152605f84018513612ea157600080fd5b612ea9612d75565b806080860187811115612ebb57600080fd5b604087015b81811015612ee0578051612ed381612a73565b8452928401928401612ec0565b50816040860152612ef18882612db5565b606086015250929695505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615612f4857612f48612f18565b500290565b600082612f6a57634e487b7160e01b600052601260045260246000fd5b500490565b600082821015612f8157612f81612f18565b500390565b60006001600160801b0383811690831681811015612fa657612fa6612f18565b039392505050565b8060005b600281101561210c57815180516001600160801b0390811686526020808301519091168187015260408083015167ffffffffffffffff90811691880191909152606092830151169186019190915260809094019390910190600101612fb2565b83815261022081016130276020830185612fae565b612893610120830184612fae565b6000821982111561304857613048612f18565b500190565b6001600160a01b0384811682528316602082015261014081016128936040830184612fae565b60006001600160801b0380831681851680830382111561309557613095612f18565b01949350505050565b6000602082840312156130b057600080fd5b815160ff811681146126e957600080fd5b600181815b808511156130fc5781600019048211156130e2576130e2612f18565b808516156130ef57918102915b93841c93908002906130c6565b509250929050565b60008261311357506001610615565b8161312057506000610615565b816001811461313657600281146131405761315c565b6001915050610615565b60ff84111561315157613151612f18565b50506001821b610615565b5060208310610133831016604e8410600b841016171561317f575081810a610615565b61318983836130c1565b806000190482111561319d5761319d612f18565b029392505050565b60006126e960ff841683613104565b6000602082840312156131c657600080fd5b81516126e981612c21565b600082516131e3818460208701612a14565b919091019291505056fea264697066735822122018c675e2d28363563882fef05d6e2cee7860043fb4aa5affc08259bd54fcf2ac64736f6c634300080d0033a2646970667358221220a1125db0254c2f7e64ba27cb6aca02eb8c8eceda76a8e832c6fe1250b8e2545d64736f6c634300080d0033000000000000000000000000fbf069dbbf453c1ab23042083cfa980b3a672bba000000000000000000000000ab9b68c9e53c94d7c0949fb909e80e4a29f9134a0000000000000000000000003b91ca4d89b5156d456cbd0d6305f7f36b1517a4
Deployed Bytecode
0x60806040523480156200001157600080fd5b5060043610620001155760003560e01c80638da5cb5b11620000a3578063d9164817116200006e578063d9164817146200024f578063e5e31b131462000286578063f1e6c40614620002ac578063f2fde38b14620002c357600080fd5b80638da5cb5b14620001cc578063a1e1fdac14620001de578063ab87f2fd1462000221578063ced78e25146200023857600080fd5b8063567fd09e11620000e4578063567fd09e146200018f578063574f2ba314620001995780636ff1c9bc14620001ab578063715018a614620001c257600080fd5b80630362158f146200011a5780630850ad99146200014b5780631e3dd18b146200016457806346c96aac146200017b575b600080fd5b6001546200012e906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b620001626200015c36600462001157565b620002da565b005b6200012e620001753660046200117e565b620003c5565b6002546200012e906001600160a01b031681565b62000162620003f0565b60035460405190815260200162000142565b62000162620001bc36600462001157565b6200044b565b6200016262000561565b6000546001600160a01b03166200012e565b620001f5620001ef3660046200117e565b62000579565b604080516001600160a01b03958616815294909316602085015291830152606082015260800162000142565b620001626200023236600462001157565b62000628565b6200012e620002493660046200117e565b6200068e565b620002756200026036600462001157565b60056020526000908152604090205460ff1681565b604051901515815260200162000142565b620002756200029736600462001157565b60046020526000908152604090205460ff1681565b62000162620002bd36600462001157565b62000b8b565b62000162620002d436600462001157565b62000bf4565b620002e462000c73565b6001600160a01b03811660009081526005602052604090205460ff16156200034a5760405162461bcd60e51b815260206004820152601460248201527332bc34b9ba34b7339031b0b93137b7103830b4b960611b60448201526064015b60405180910390fd5b6003805460018181019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b039093166001600160a01b0319909316831790556000918252600560209081526040808420805460ff19908116851790915560049092529092208054909216179055565b60038181548110620003d657600080fd5b6000918252602090912001546001600160a01b0316905081565b620003fa62000c73565b60065460ff166200043f5760405162461bcd60e51b815260206004820152600e60248201526d6e6f74206265746120706861736560901b604482015260640162000341565b6006805460ff19169055565b6200045562000c73565b60065460ff166200049a5760405162461bcd60e51b815260206004820152600e60248201526d6e6f74206265746120706861736560901b604482015260640162000341565b6001600160a01b03811660009081526005602052604090205460ff16620004d55760405162461bcd60e51b8152600401620003419062001198565b6001600160a01b0381166000818152600560209081526040808320805460ff199081169091556004928390529281902080549093169092559051631bfc726f60e21b81523391810191909152636ff1c9bc90602401600060405180830381600087803b1580156200054557600080fd5b505af11580156200055a573d6000803e3d6000fd5b5050505050565b6200056b62000c73565b62000577600062000ccf565b565b600154604051632f2235f960e21b81526004810183905260009182918291829182916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015620005cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005f3919062001319565b604081015180516020918201516060909301518051519201515190999298506001600160801b03918216975016945092505050565b6200063262000c73565b6001600160a01b03811660009081526005602052604090205460ff166200066d5760405162461bcd60e51b8152600401620003419062001198565b6001600160a01b03166000908152600460205260409020805460ff19169055565b6000806000806000620006a18662000579565b93509350935093506000846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620006ea573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620007149190810190620013f9565b846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000753573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200077d9190810190620013f9565b60405160200162000790929190620014a7565b60405160208183030381529060405290506000856001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620007e2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200080c9190810190620013f9565b856001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156200084b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620008759190810190620013f9565b6040516020016200088892919062001510565b60408051601f1981840301815290829052600154600254919350600092859285926001600160a01b0390811692911690620008c39062001133565b620008d294939291906200158d565b604051809103906000f080158015620008ef573d6000803e3d6000fd5b50905084156200091457620009078733308862000d1f565b6200091487828762000d92565b83156200093657620009298633308762000d1f565b6200093686828662000d92565b604051630ad374dd60e41b8152600481018a90526001600160a01b0382169063ad374dd090602401600060405180830381600087803b1580156200097957600080fd5b505af11580156200098e573d6000803e3d6000fd5b50506003805460018082019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b03861690811790915560008181526005602052604090819020805460ff191690931790925590516370a0823160e01b815230600482015284935090915063a9059cbb90339083906370a0823190602401602060405180830381865afa15801562000a3f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a659190620015db565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af115801562000ab1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ad79190620015f5565b50816001600160a01b031663492f4e186040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000b17573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b3d9190620015db565b604080518c81526001600160a01b03841660208201527ff7ee1758a8519d7fe72714f8cfd41d75d71255250aa858f78cb859f6f3c78232910160405180910390a29998505050505050505050565b62000b9562000c73565b6001600160a01b03811660009081526005602052604090205460ff1662000bd05760405162461bcd60e51b8152600401620003419062001198565b6001600160a01b03166000908152600460205260409020805460ff19166001179055565b62000bfe62000c73565b6001600160a01b03811662000c655760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000341565b62000c708162000ccf565b50565b6000546001600160a01b03163314620005775760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000341565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038085166024830152831660448201526064810182905262000d8c9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915262000eb4565b50505050565b80158062000e105750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801562000de8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e0e9190620015db565b155b62000e7d5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840162000341565b6040516001600160a01b03831660248201526044810182905262000eaf90849063095ea7b360e01b9060640162000d54565b505050565b600062000f0b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031662000f909092919063ffffffff16565b905080516000148062000f2f57508080602001905181019062000f2f9190620015f5565b62000eaf5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000341565b606062000fa1848460008562000fa9565b949350505050565b6060824710156200100c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000341565b600080866001600160a01b031685876040516200102a919062001619565b60006040518083038185875af1925050503d806000811462001069576040519150601f19603f3d011682016040523d82523d6000602084013e6200106e565b606091505b509150915062001081878383876200108c565b979650505050505050565b6060831562001100578251600003620010f8576001600160a01b0385163b620010f85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000341565b508162000fa1565b62000fa18383815115620011175781518083602001fd5b8060405162461bcd60e51b815260040162000341919062001637565b613551806200164d83390190565b6001600160a01b038116811462000c7057600080fd5b6000602082840312156200116a57600080fd5b8135620011778162001141565b9392505050565b6000602082840312156200119157600080fd5b5035919050565b6020808252601190820152703737ba10309031b0b93137b7103830b4b960791b604082015260600190565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715620011ff57620011ff620011c3565b60405290565b6040805190810167ffffffffffffffff81118282101715620011ff57620011ff620011c3565b80516001600160801b03811681146200124357600080fd5b919050565b805167ffffffffffffffff811681146200124357600080fd5b600082601f8301126200127357600080fd5b6200127d62001205565b806101008401858111156200129157600080fd5b845b818110156200130e5760808188031215620012ae5760008081fd5b620012b8620011d9565b620012c3826200122b565b81526020620012d48184016200122b565b818301526040620012e781850162001248565b908301526060620012fa84820162001248565b908301529085529093019260800162001293565b509095945050505050565b600061018082840312156200132d57600080fd5b62001337620011d9565b825181526020808401516200134c8162001141565b82820152605f840185136200136057600080fd5b6200136a62001205565b8060808601878111156200137d57600080fd5b604087015b81811015620013a6578051620013988162001141565b845292840192840162001382565b50816040860152620013b9888262001261565b606086015250929695505050505050565b60005b83811015620013e7578181015183820152602001620013cd565b8381111562000d8c5750506000910152565b6000602082840312156200140c57600080fd5b815167ffffffffffffffff808211156200142557600080fd5b818401915084601f8301126200143a57600080fd5b8151818111156200144f576200144f620011c3565b604051601f8201601f19908116603f011681019083821181831017156200147a576200147a620011c3565b816040528281528760208487010111156200149457600080fd5b62001081836020830160208801620013ca565b7f436f6e63656e74726174656420204c6971756964697479202d20000000000000815260008351620014e181601a850160208801620013ca565b602f60f81b601a9184019182015283516200150481601b840160208801620013ca565b01601b01949350505050565b62434c2d60e81b81526000835162001530816003850160208801620013ca565b602f60f81b600391840191820152835162001553816004840160208801620013ca565b01600401949350505050565b6000815180845262001579816020860160208601620013ca565b601f01601f19169290920160200192915050565b608081526000620015a260808301876200155f565b8281036020840152620015b681876200155f565b6001600160a01b03958616604085015293909416606090920191909152509392505050565b600060208284031215620015ee57600080fd5b5051919050565b6000602082840312156200160857600080fd5b815180151581146200117757600080fd5b600082516200162d818460208701620013ca565b9190910192915050565b6020815260006200117760208301846200155f56fe60a06040523480156200001157600080fd5b506040516200355138038062003551833981016040819052620000349162000240565b8351849084906200004d906003906020850190620000b0565b50805162000063906004906020840190620000b0565b5050600160055550600780546001600160a01b039384166001600160a01b03199182161790915560088054929093169116179055505033608052600b805460ff60a01b191690556200030b565b828054620000be90620002cf565b90600052602060002090601f016020900481019282620000e257600085556200012d565b82601f10620000fd57805160ff19168380011785556200012d565b828001600101855582156200012d579182015b828111156200012d57825182559160200191906001019062000110565b506200013b9291506200013f565b5090565b5b808211156200013b576000815560010162000140565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200017e57600080fd5b81516001600160401b03808211156200019b576200019b62000156565b604051601f8301601f19908116603f01168101908282118183101715620001c657620001c662000156565b81604052838152602092508683858801011115620001e357600080fd5b600091505b83821015620002075785820183015181830184015290820190620001e8565b83821115620002195760008385830101525b9695505050505050565b80516001600160a01b03811681146200023b57600080fd5b919050565b600080600080608085870312156200025757600080fd5b84516001600160401b03808211156200026f57600080fd5b6200027d888389016200016c565b955060208701519150808211156200029457600080fd5b50620002a3878288016200016c565b935050620002b46040860162000223565b9150620002c46060860162000223565b905092959194509250565b600181811c90821680620002e457607f821691505b6020821081036200030557634e487b7160e01b600052602260045260246000fd5b50919050565b6080516132236200032e6000396000818161049901526110d501526132236000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c80636ff1c9bc1161011a578063ad374dd0116100ad578063c45a01551161007c578063c45a015514610494578063c8eaac0b146104bb578063d21220a7146104c3578063dd62ed3e146104d6578063e455dea8146104e957600080fd5b8063ad374dd014610448578063b22d8fe01461045b578063c3df46d81461046e578063c3fbc5ef1461048157600080fd5b80639f118536116100e95780639f11853614610406578063a0f821711461041a578063a457c2d714610422578063a9059cbb1461043557600080fd5b80636ff1c9bc146103ae57806370a08231146103c157806391f36d65146103ea57806395d89b41146103fe57600080fd5b806323b872dd1161019d578063395093511161016c578063395093511461035957806345a1de791461036c57806346c96aac1461037f578063492f4e18146103925780634a65f70b1461039b57600080fd5b806323b872dd146102f15780632644b97b146103045780632e1a7d4d14610337578063313ce5671461034a57600080fd5b80630dfe1681116101d95780630dfe168114610289578063150b7a021461029c57806318160ddd146102d457806319999566146102dc57600080fd5b80630134e0f41461020b5780630362158f1461022657806306fdde0314610251578063095ea7b314610266575b600080fd5b6102136104fc565b6040519081526020015b60405180910390f35b600754610239906001600160a01b031681565b6040516001600160a01b03909116815260200161021d565b61025961056f565b60405161021d9190612a40565b610279610274366004612a88565b610601565b604051901515815260200161021d565b600a54610239906001600160a01b031681565b6102bb6102aa366004612ab4565b630a85bd0160e11b95945050505050565b6040516001600160e01b0319909116815260200161021d565b600254610213565b6102ef6102ea366004612b53565b61061b565b005b6102796102ff366004612b70565b6106ce565b61030c6106f2565b604080516001600160a01b03958616815294909316602085015291830152606082015260800161021d565b6102ef610345366004612bb1565b6107a1565b6040516012815260200161021d565b610279610367366004612a88565b610d6a565b600954610239906001600160a01b031681565b600854610239906001600160a01b031681565b61021360065481565b6102ef6103a9366004612bdf565b610d8c565b6102ef6103bc366004612b53565b6110ca565b6102136103cf366004612b53565b6001600160a01b031660009081526020819052604090205490565b60095461027990600160a01b900460ff1681565b6102596111f0565b600b5461027990600160a01b900460ff1681565b6102796111ff565b610279610430366004612a88565b6112b4565b610279610443366004612a88565b61132f565b6102ef610456366004612bb1565b61133d565b6102ef610469366004612c2f565b6115d7565b61021361047c366004612c4c565b611689565b6102ef61048f366004612c85565b6117e6565b6102397f000000000000000000000000000000000000000000000000000000000000000081565b610213611e34565b600b54610239906001600160a01b031681565b6102136104e4366004612cb5565b611e65565b61030c6104f7366004612bb1565b611e90565b600b546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a08231906024015b602060405180830381865afa158015610546573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056a9190612ce3565b905090565b60606003805461057e90612cfc565b80601f01602080910402602001604051908101604052809291908181526020018280546105aa90612cfc565b80156105f75780601f106105cc576101008083540402835291602001916105f7565b820191906000526020600020905b8154815290600101906020018083116105da57829003601f168201915b5050505050905090565b60003361060f818585611f74565b60019150505b92915050565b6008546001600160a01b031633146106845760405162461bcd60e51b815260206004820152602160248201527f4f6e6c7920766f7465722063616e207365742065787465726e616c20627269626044820152606560f81b60648201526084015b60405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040517f03e9b76bf8c2d2d6948b20459194f64843d25ada1a13e3481bf88399831a046190600090a250565b6000336106dc858285612098565b6106e7858585612112565b506001949350505050565b600754600654604051632f2235f960e21b8152600481019190915260009182918291829182916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015610749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076d9190612e60565b604081015180516020918201516060909301518051519201515190989297506001600160801b039182169650169350915050565b6107a96122b6565b600081116107e85760405162461bcd60e51b815260206004820152600c60248201526b05f736861726573203d3d20360a41b604482015260640161067b565b600754600654604051632f2235f960e21b815260048101919091526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015610837573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085b9190612e60565b9050600061089d61086b60025490565b6060840151859060005b60200201515161088e91906001600160801b0316612f2e565b6108989190612f4d565b61230f565b905060006108bb6108ad60025490565b606085015186906001610875565b90506108c7338561237c565b6000826001600160801b031611806108e857506000816001600160801b0316115b6109245760405162461bcd60e51b815260206004820152600d60248201526c3020746f20776974686472617760981b604482015260640161067b565b6040805160808101825260008082526020820181905291810182905260608101919091526001600160801b038316156109ff57606084810180515160409081015167ffffffffffffffff9081169185019190915281515183015116918301919091525180518051602091909101516109cf926001600160801b03928316929182169187169060005b6020020151516109c591906001600160801b0316612f6f565b61088e9190612f2e565b6001600160801b03166020820152606084015151516109ef908490612f86565b6001600160801b03168152610a51565b606084810180515160409081015167ffffffffffffffff9081169185019190915281515183015116918301919091528051516020908101516001600160801b0390811691840191909152905151511681525b6040805160808101825260008082526020820181905291810182905260608101919091526001600160801b03831615610b1a576060858101805160209081015160409081015167ffffffffffffffff908116918601919091528251820151840151169284019290925251808201518051920151610ae3926001600160801b0390811692918116919087169060016109ac565b6001600160801b03166020820152606085015183906001602002015151610b0a9190612f86565b6001600160801b03168152610b72565b6060858101805160209081015160409081015167ffffffffffffffff908116918601919091528251820151840151169284019290925280518201518201516001600160801b0390811684840152905190910151511681525b836001600160801b0316600003610bd5576060850151610bc69060016020020151602001516001600160801b031683602001516001600160801b031683602001516001600160801b031661088e9190612f2e565b6001600160801b031660208301525b826001600160801b0316600003610c38576060850151610c299060006020020151602001516001600160801b031682602001516001600160801b031684602001516001600160801b031661088e9190612f2e565b6001600160801b031660208201525b60075460065460608701516040805180820182528681526020810186905290516321589fa160e01b81526001600160a01b03909416936321589fa193610c849390929091600401613012565b600060405180830381600087803b158015610c9e57600080fd5b505af1158015610cb2573d6000803e3d6000fd5b505050506001600160801b03841615610cdf57604085015151610cdf90336001600160801b0387166124ae565b6001600160801b03831615610d0b57604085015160200151610d0b90336001600160801b0386166124ae565b604080516001600160801b0380871682528516602082015290810187905233907f743033787f4738ff4d6a7225ce2bd0977ee5f86b91a902a58f5e4d0b297b46449060600160405180910390a25050505050610d676001600555565b50565b60003361060f818585610d7d8383611e65565b610d879190613035565b611f74565b600b54600160a01b900460ff1615610dd65760405162461bcd60e51b815260206004820152600d60248201526c1d985d5b1d081cdd185c9d1959609a1b604482015260640161067b565b6000826001600160801b03161180610df757506000816001600160801b0316115b610e375760405162461bcd60e51b81526020600482015260116024820152700616d6f756e74546f6b656e73203d3d203607c1b604482015260640161067b565b600754604051632f2235f960e21b8152600481018590526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015610e82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea69190612e60565b60408101518051600a80546001600160a01b03199081166001600160a01b0393841617909155602090920151600b8054909316911617905590506001600160801b03831615610f1057600a54610f10906001600160a01b031633306001600160801b038716612511565b6001600160801b03821615610f4057600b54610f40906001600160a01b031633306001600160801b038616612511565b606081015180516020918201516001600160801b0386811680845283850181905290861680835293820193909352600a5460075492939192610f91926001600160a01b039283169290911690612549565b600b54600754610fb7916001600160a01b0390811691166001600160801b038716612549565b6007546040848101518051602091820151835180850185528781529283018690529251637b93a39d60e11b81526001600160a01b039094169363f727473a9361100493909160040161304d565b6020604051808303816000875af1158015611023573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110479190612ce3565b60065560006001600160801b038086169087161161108357600b5461107e906001600160a01b03166001600160801b03871661265e565b6110a2565b600a546110a2906001600160a01b03166001600160801b03881661265e565b90506110ae33826126f0565b5050600b805460ff60a01b1916600160a01b1790555050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146111325760405162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015260640161067b565b600754600654604051638730203760e01b81526001600160a01b03909216916387302037916111679160040190815260200190565b600060405180830381600087803b15801561118157600080fd5b505af1158015611195573d6000803e3d6000fd5b5050505060006111a3611e34565b905060006111af6104fc565b905081156111ce57600a546111ce906001600160a01b031684846124ae565b80156111eb57600b546111eb906001600160a01b031684836124ae565b505050565b60606004805461057e90612cfc565b600754600654604051632f2235f960e21b815260009283926001600160a01b039091169163bc88d7e4916112399160040190815260200190565b61018060405180830381865afa158015611257573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127b9190612e60565b606081015151519091506001600160801b0316158015906112ad5750606081015160200151516001600160801b031615155b1591505090565b600033816112c28286611e65565b9050838110156113225760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161067b565b6106e78286868403611f74565b60003361060f818585612112565b600b54600160a01b900460ff16156113875760405162461bcd60e51b815260206004820152600d60248201526c1d985d5b1d081cdd185c9d1959609a1b604482015260640161067b565b600754604051632f2235f960e21b8152600481018390526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa1580156113d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f69190612e60565b60408101518051600a80546001600160a01b039283166001600160a01b031991821617909155602092830151600b8054919093169116179055606082015180519101518151815193945091929091906001600160801b0382161561147557600a54611475906001600160a01b031633306001600160801b038616612511565b6001600160801b038116156114a557600b546114a5906001600160a01b031633306001600160801b038516612511565b600a546007546114cb916001600160a01b0390811691166001600160801b038516612549565b600b546007546114f1916001600160a01b0390811691166001600160801b038416612549565b6007546040868101518051602091820151835180850185528981529283018890529251637b93a39d60e11b81526001600160a01b039094169363f727473a9361153e93909160040161304d565b6020604051808303816000875af115801561155d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115819190612ce3565b60065560006001600160801b03808316908416116115b857600b5461107e906001600160a01b03166001600160801b03841661265e565b600a546110a2906001600160a01b03166001600160801b03851661265e565b6008546001600160a01b031633146116315760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c7920766f7465722063616e207365742068617320676175676500000000604482015260640161067b565b60098054821515600160a01b0260ff60a01b199091161790556040517f352eb552c369d470b6f2286567a9f272a1210ad788562e697f254cad5611f1059061167e90831515815260200190565b60405180910390a150565b600754600654604051632f2235f960e21b815260009283926001600160a01b039091169163bc88d7e4916116c39160040190815260200190565b61018060405180830381865afa1580156116e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117059190612e60565b90506000846001600160a01b0316826040015160006002811061172a5761172a612f02565b60200201516001600160a01b031614905060008161174d57604083015151611757565b6040830151602001515b905060008261176e57606084015160200151611775565b6060840151515b905060008361178957606085015151611793565b6060850151602001515b82519091506001600160801b03166000036117af5760006117d1565b815181516117d1916001600160801b039081169161088e918b81169116612f2e565b6001600160801b031698975050505050505050565b6117ee6122b6565b6006546000036118345760405162461bcd60e51b81526020600482015260116024820152701d985d5b1d081b9bdd081cdd185c9d1959607a1b604482015260640161067b565b600a546001600160a01b038481169116148061185d5750600b546001600160a01b038481169116145b6118b85760405162461bcd60e51b815260206004820152602660248201527f6465706f73697420746f6b656e206973206e6f742070617274206f6620746865604482015265081d985d5b1d60d21b606482015260840161067b565b6000826001600160801b0316116119005760405162461bcd60e51b815260206004820152600c60248201526b05f616d6f756e74203d3d20360a41b604482015260640161067b565b611915833330856001600160801b0316612511565b600754600654604051632f2235f960e21b815260048101919091526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015611964573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119889190612e60565b90506000846001600160a01b031682604001516000600281106119ad576119ad612f02565b60200201516001600160a01b03161490506000816119d0576040830151516119da565b6040830151602001515b90506000826119f1576060840151602001516119f8565b6060840151515b9050600083611a0c57606085015151611a16565b6060850151602001515b805183519192506001600160801b03908116911611611a8c5760405162461bcd60e51b815260206004820152602c60248201527f796f75206e65656420746f20757365206f7468657220746f6b656e206173206460448201526b32b837b9b4ba103a37b5b2b760a11b606482015260840161067b565b81516001600160801b031615801590611aae575080516001600160801b031615155b611ae95760405162461bcd60e51b815260206004820152600c60248201526b6f7574206f662072616e676560a01b604482015260640161067b565b6000611b1e83600001516001600160801b0316896001600160801b031684600001516001600160801b031661088e9190612f2e565b9050866001600160801b0316816001600160801b03161115611b535760405163428637bb60e11b815260040160405180910390fd5b6001600160801b03811615611b9857611b77843330846001600160801b0316612511565b600754611b989085906001600160a01b03166001600160801b038416612549565b600083600001516001600160801b0316896001600160801b0316611bbb60025490565b611bc59190612f2e565b611bcf9190612f4d565b9050611bfb60408051608081018252600080825260208201819052918101829052606081019190915290565b60408086015167ffffffffffffffff908116918301919091526060808701519091169082015284516020860151611c47916001600160801b03908116918116906109c5908e1683613035565b6001600160801b031660208201528451611c62908b90613073565b6001600160801b03908116825260408051608081018252600080825260208083018290528284018281526060808501938452948a015167ffffffffffffffff9081169091529389015190931690528651918701519092611cce928116918116906109c590881683613035565b6001600160801b031660208201528451611ce9908590613073565b6001600160801b0316815260008089611d03578284611d06565b83835b91509150611d338e600760009054906101000a90046001600160a01b03168f6001600160801b0316612549565b60075460065460608d01516040805180820182528681526020810186905290516321589fa160e01b81526001600160a01b03909416936321589fa193611d7f9390929091600401613012565b600060405180830381600087803b158015611d9957600080fd5b505af1158015611dad573d6000803e3d6000fd5b50505050611dbb33866126f0565b336001600160a01b03167fb4c03061fb5b7fed76389d5af8f2e0ddb09f8c70d1333abbb62582835e10accb8e8888604051611e17939291906001600160801b039384168152919092166020820152604081019190915260600190565b60405180910390a250505050505050505050506111eb6001600555565b600a546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401610529565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600754600654604051632f2235f960e21b8152600481019190915260009182918291829182916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015611ee7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f0b9190612e60565b90506000611f29611f1b60025490565b606084015189906000610875565b90506000611f47611f3960025490565b60608501518a906001610875565b60409390930151805160209091015190999098506001600160801b03928316975091909216945092505050565b6001600160a01b038316611fd65760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161067b565b6001600160a01b0382166120375760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161067b565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006120a48484611e65565b9050600019811461210c57818110156120ff5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161067b565b61210c8484848403611f74565b50505050565b6001600160a01b0383166121765760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161067b565b6001600160a01b0382166121d85760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161067b565b6001600160a01b038316600090815260208190526040902054818110156122505760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161067b565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a361210c565b6002600554036123085760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161067b565b6002600555565b60006001600160801b038211156123785760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b606482015260840161067b565b5090565b6001600160a01b0382166123dc5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161067b565b6001600160a01b038216600090815260208190526040902054818110156124505760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161067b565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6040516001600160a01b0383166024820152604481018290526111eb90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526127af565b6040516001600160a01b038085166024830152831660448201526064810182905261210c9085906323b872dd60e01b906084016124da565b8015806125c35750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801561259d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c19190612ce3565b155b61262e5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840161067b565b6040516001600160a01b0383166024820152604481018290526111eb90849063095ea7b360e01b906064016124da565b6000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561269e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c2919061309e565b6126cd90600a6131a5565b6126df83670de0b6b3a7640000612f2e565b6126e99190612f4d565b9392505050565b6001600160a01b0382166127465760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161067b565b80600260008282546127589190613035565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6000612804826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166128849092919063ffffffff16565b905080516000148061282557508080602001905181019061282591906131b4565b6111eb5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161067b565b6060612893848460008561289b565b949350505050565b6060824710156128fc5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161067b565b600080866001600160a01b0316858760405161291891906131d1565b60006040518083038185875af1925050503d8060008114612955576040519150601f19603f3d011682016040523d82523d6000602084013e61295a565b606091505b509150915061296b87838387612976565b979650505050505050565b606083156129e55782516000036129de576001600160a01b0385163b6129de5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161067b565b5081612893565b61289383838151156129fa5781518083602001fd5b8060405162461bcd60e51b815260040161067b9190612a40565b60005b83811015612a2f578181015183820152602001612a17565b8381111561210c5750506000910152565b6020815260008251806020840152612a5f816040850160208701612a14565b601f01601f19169190910160400192915050565b6001600160a01b0381168114610d6757600080fd5b60008060408385031215612a9b57600080fd5b8235612aa681612a73565b946020939093013593505050565b600080600080600060808688031215612acc57600080fd5b8535612ad781612a73565b94506020860135612ae781612a73565b935060408601359250606086013567ffffffffffffffff80821115612b0b57600080fd5b818801915088601f830112612b1f57600080fd5b813581811115612b2e57600080fd5b896020828501011115612b4057600080fd5b9699959850939650602001949392505050565b600060208284031215612b6557600080fd5b81356126e981612a73565b600080600060608486031215612b8557600080fd5b8335612b9081612a73565b92506020840135612ba081612a73565b929592945050506040919091013590565b600060208284031215612bc357600080fd5b5035919050565b6001600160801b0381168114610d6757600080fd5b600080600060608486031215612bf457600080fd5b833592506020840135612c0681612bca565b91506040840135612c1681612bca565b809150509250925092565b8015158114610d6757600080fd5b600060208284031215612c4157600080fd5b81356126e981612c21565b60008060408385031215612c5f57600080fd5b8235612c6a81612a73565b91506020830135612c7a81612bca565b809150509250929050565b600080600060608486031215612c9a57600080fd5b8335612ca581612a73565b92506020840135612c0681612bca565b60008060408385031215612cc857600080fd5b8235612cd381612a73565b91506020830135612c7a81612a73565b600060208284031215612cf557600080fd5b5051919050565b600181811c90821680612d1057607f821691505b602082108103612d3057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715612d6f57612d6f612d36565b60405290565b6040805190810167ffffffffffffffff81118282101715612d6f57612d6f612d36565b805167ffffffffffffffff81168114612db057600080fd5b919050565b600082601f830112612dc657600080fd5b612dce612d75565b80610100840185811115612de157600080fd5b845b81811015612e555760808188031215612dfc5760008081fd5b612e04612d4c565b8151612e0f81612bca565b8152602082810151612e2081612bca565b828201526040612e31848201612d98565b908301526060612e42848201612d98565b9083015290855290930192608001612de3565b509095945050505050565b60006101808284031215612e7357600080fd5b612e7b612d4c565b82518152602080840151612e8e81612a73565b82820152605f84018513612ea157600080fd5b612ea9612d75565b806080860187811115612ebb57600080fd5b604087015b81811015612ee0578051612ed381612a73565b8452928401928401612ec0565b50816040860152612ef18882612db5565b606086015250929695505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615612f4857612f48612f18565b500290565b600082612f6a57634e487b7160e01b600052601260045260246000fd5b500490565b600082821015612f8157612f81612f18565b500390565b60006001600160801b0383811690831681811015612fa657612fa6612f18565b039392505050565b8060005b600281101561210c57815180516001600160801b0390811686526020808301519091168187015260408083015167ffffffffffffffff90811691880191909152606092830151169186019190915260809094019390910190600101612fb2565b83815261022081016130276020830185612fae565b612893610120830184612fae565b6000821982111561304857613048612f18565b500190565b6001600160a01b0384811682528316602082015261014081016128936040830184612fae565b60006001600160801b0380831681851680830382111561309557613095612f18565b01949350505050565b6000602082840312156130b057600080fd5b815160ff811681146126e957600080fd5b600181815b808511156130fc5781600019048211156130e2576130e2612f18565b808516156130ef57918102915b93841c93908002906130c6565b509250929050565b60008261311357506001610615565b8161312057506000610615565b816001811461313657600281146131405761315c565b6001915050610615565b60ff84111561315157613151612f18565b50506001821b610615565b5060208310610133831016604e8410600b841016171561317f575081810a610615565b61318983836130c1565b806000190482111561319d5761319d612f18565b029392505050565b60006126e960ff841683613104565b6000602082840312156131c657600080fd5b81516126e981612c21565b600082516131e3818460208701612a14565b919091019291505056fea264697066735822122018c675e2d28363563882fef05d6e2cee7860043fb4aa5affc08259bd54fcf2ac64736f6c634300080d0033a2646970667358221220a1125db0254c2f7e64ba27cb6aca02eb8c8eceda76a8e832c6fe1250b8e2545d64736f6c634300080d0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000fbf069dbbf453c1ab23042083cfa980b3a672bba000000000000000000000000ab9b68c9e53c94d7c0949fb909e80e4a29f9134a0000000000000000000000003b91ca4d89b5156d456cbd0d6305f7f36b1517a4
-----Decoded View---------------
Arg [0] : _carbonController (address): 0xfbF069Dbbf453C1ab23042083CFa980B3a672BbA
Arg [1] : _voter (address): 0xab9B68c9e53c94D7c0949FB909E80e4a29F9134A
Arg [2] : _team (address): 0x3b91Ca4D89B5156d456CbD0D6305F7f36B1517a4
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000fbf069dbbf453c1ab23042083cfa980b3a672bba
Arg [1] : 000000000000000000000000ab9b68c9e53c94d7c0949fb909e80e4a29f9134a
Arg [2] : 0000000000000000000000003b91ca4d89b5156d456cbd0d6305f7f36b1517a4
Deployed Bytecode Sourcemap
94579:3474:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94630:31;;;;;-1:-1:-1;;;;;94630:31:0;;;;;;-1:-1:-1;;;;;178:32:1;;;160:51;;148:2;133:18;94630:31:0;;;;;;;;95489:240;;;;;;:::i;:::-;;:::i;:::-;;94697:25;;;;;;:::i;:::-;;:::i;94668:20::-;;;;;-1:-1:-1;;;;;94668:20:0;;;97611:124;;;:::i;97507:96::-;97580:8;:15;97507:96;;941:25:1;;;929:2;914:18;97507:96:0;795:177:1;97743:307:0;;;;;;:::i;:::-;;:::i;93760:103::-;;;:::i;93119:87::-;93165:7;93192:6;-1:-1:-1;;;;;93192:6:0;93119:87;;97169:330;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;1264:15:1;;;1246:34;;1316:15;;;;1311:2;1296:18;;1289:43;1348:18;;;1341:34;1406:2;1391:18;;1384:34;1195:3;1180:19;97169:330:0;977:447:1;95324:157:0;;;;;;:::i;:::-;;:::i;95737:1424::-;;;;;;:::i;:::-;;:::i;94799:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;1594:14:1;;1587:22;1569:41;;1557:2;1542:18;94799:44:0;1429:187:1;94729:38:0;;;;;;:::i;:::-;;;;;;;;;;;;;;;;95160:156;;;;;;:::i;:::-;;:::i;94018:201::-;;;;;;:::i;:::-;;:::i;95489:240::-;93005:13;:11;:13::i;:::-;-1:-1:-1;;;;;95569:19:0;::::1;;::::0;;;:12:::1;:19;::::0;;;;;::::1;;95568:20;95560:52;;;::::0;-1:-1:-1;;;95560:52:0;;1823:2:1;95560:52:0::1;::::0;::::1;1805:21:1::0;1862:2;1842:18;;;1835:30;-1:-1:-1;;;1881:18:1;;;1874:50;1941:18;;95560:52:0::1;;;;;;;;;95633:8;:20:::0;;::::1;::::0;;::::1;::::0;;;;::::1;::::0;;-1:-1:-1;;;;;95633:20:0;;::::1;-1:-1:-1::0;;;;;;95633:20:0;;::::1;::::0;::::1;::::0;;-1:-1:-1;95664:19:0;;;:12:::1;95633:20;95664:19:::0;;;;;;;:26;;-1:-1:-1;;95664:26:0;;::::1;::::0;::::1;::::0;;;95701:6:::1;:13:::0;;;;;;:20;;;;::::1;;::::0;;95489:240::o;94697:25::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;94697:25:0;;-1:-1:-1;94697:25:0;:::o;97611:124::-;93005:13;:11;:13::i;:::-;97672:9:::1;::::0;::::1;;97664:35;;;::::0;-1:-1:-1;;;97664:35:0;;2172:2:1;97664:35:0::1;::::0;::::1;2154:21:1::0;2211:2;2191:18;;;2184:30;-1:-1:-1;;;2230:18:1;;;2223:44;2284:18;;97664:35:0::1;1970:338:1::0;97664:35:0::1;97710:9;:17:::0;;-1:-1:-1;;97710:17:0::1;::::0;;97611:124::o;97743:307::-;93005:13;:11;:13::i;:::-;97820:9:::1;::::0;::::1;;97812:35;;;::::0;-1:-1:-1;;;97812:35:0;;2172:2:1;97812:35:0::1;::::0;::::1;2154:21:1::0;2211:2;2191:18;;;2184:30;-1:-1:-1;;;2230:18:1;;;2223:44;2284:18;;97812:35:0::1;1970:338:1::0;97812:35:0::1;-1:-1:-1::0;;;;;97866:18:0;::::1;;::::0;;;:12:::1;:18;::::0;;;;;::::1;;97858:47;;;;-1:-1:-1::0;;;97858:47:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;97918:18:0;::::1;97939:5;97918:18:::0;;;:12:::1;:18;::::0;;;;;;;:26;;-1:-1:-1;;97918:26:0;;::::1;::::0;;;97955:6:::1;:12:::0;;;;;;;;:20;;;;::::1;::::0;;;97996:46;;-1:-1:-1;;;97996:46:0;;98031:10:::1;97996:46:::0;;::::1;160:51:1::0;;;;97996:34:0::1;::::0;133:18:1;;97996:46:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;97743:307:::0;:::o;93760:103::-;93005:13;:11;:13::i;:::-;93825:30:::1;93852:1;93825:18;:30::i;:::-;93760:103::o:0;97169:330::-;97314:16;;97296:56;;-1:-1:-1;;;97296:56:0;;;;;941:25:1;;;97230:7:0;;;;;;;;;;-1:-1:-1;;;;;97314:16:0;;97296:44;;914:18:1;;97296:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;97396:15;;;;:18;;;97429;;;;97449:15;;;;;:18;;:20;97470:18;;;:20;97396:18;;97429;;-1:-1:-1;;;;;;97375:116:0;;;;-1:-1:-1;97375:116:0;;-1:-1:-1;97375:116:0;-1:-1:-1;;;97169:330:0:o;95324:157::-;93005:13;:11;:13::i;:::-;-1:-1:-1;;;;;95401:19:0;::::1;;::::0;;;:12:::1;:19;::::0;;;;;::::1;;95393:48;;;;-1:-1:-1::0;;;95393:48:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;95452:13:0::1;95468:5;95452:13:::0;;;:6:::1;:13;::::0;;;;:21;;-1:-1:-1;;95452:21:0::1;::::0;;95324:157::o;95737:1424::-;95802:12;95828:14;95843;95858:17;95876;95897:32;95911:17;95897:13;:32::i;:::-;95827:102;;;;;;;;95944:18;96034:6;-1:-1:-1;;;;;96019:29:0;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96019:31:0;;;;;;;;;;;;:::i;:::-;96072:6;-1:-1:-1;;;;;96057:29:0;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96057:31:0;;;;;;;;;;;;:::i;:::-;95972:117;;;;;;;;;:::i;:::-;;;;;;;;;;;;;95944:146;;96101:20;96170:6;-1:-1:-1;;;;;96155:29:0;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96155:31:0;;;;;;;;;;;;:::i;:::-;96208:6;-1:-1:-1;;;;;96193:29:0;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96193:31:0;;;;;;;;;;;;:::i;:::-;96131:94;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;96131:94:0;;;;;;;;;;96282:16;;96299:5;;96131:94;;-1:-1:-1;96239:13:0;;96270:4;;96131:94;;-1:-1:-1;;;;;96282:16:0;;;;96299:5;;;96255:50;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;96239:66:0;-1:-1:-1;96321:16:0;;96318:210;;96354:83;96388:6;96397:10;96417:4;96424:12;96354:26;:83::i;:::-;96452:64;96481:6;96498:2;96503:12;96452:21;:64::i;:::-;96543:16;;96540:210;;96576:83;96610:6;96619:10;96639:4;96646:12;96576:26;:83::i;:::-;96674:64;96703:6;96720:2;96725:12;96674:21;:64::i;:::-;96762:43;;-1:-1:-1;;;96762:43:0;;;;;941:25:1;;;-1:-1:-1;;;;;96762:24:0;;;;;914:18:1;;96762:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96873:8:0;:27;;;;;;;;;;;;;-1:-1:-1;;;;;;96873:27:0;-1:-1:-1;;;;;96873:27:0;;;;;;;;-1:-1:-1;96911:26:0;;;:12;96873:27;96911:26;;;;;;:33;;-1:-1:-1;;96911:33:0;;;;;;;96998:45;;-1:-1:-1;;;96998:45:0;;97037:4;96998:45;;;160:51:1;96873:27:0;;-1:-1:-1;96873:27:0;;-1:-1:-1;96957:29:0;;96987:10;;96873:27;;96998:30;;133:18:1;;96998:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;96957:87;;-1:-1:-1;;;;;;96957:87:0;;;;;;;-1:-1:-1;;;;;9815:32:1;;;96957:87:0;;;9797:51:1;9864:18;;;9857:34;9770:18;;96957:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;97074:2;-1:-1:-1;;;;;97074:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;97062:59;;;10358:25:1;;;-1:-1:-1;;;;;10419:32:1;;10414:2;10399:18;;10392:60;97062:59:0;;10331:18:1;97062:59:0;;;;;;;97141:12;95737:1424;-1:-1:-1;;;;;;;;;95737:1424:0:o;95160:156::-;93005:13;:11;:13::i;:::-;-1:-1:-1;;;;;95237:19:0;::::1;;::::0;;;:12:::1;:19;::::0;;;;;::::1;;95229:48;;;;-1:-1:-1::0;;;95229:48:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;95288:13:0::1;;::::0;;;:6:::1;:13;::::0;;;;:20;;-1:-1:-1;;95288:20:0::1;95304:4;95288:20;::::0;;95160:156::o;94018:201::-;93005:13;:11;:13::i;:::-;-1:-1:-1;;;;;94107:22:0;::::1;94099:73;;;::::0;-1:-1:-1;;;94099:73:0;;10665:2:1;94099:73:0::1;::::0;::::1;10647:21:1::0;10704:2;10684:18;;;10677:30;10743:34;10723:18;;;10716:62;-1:-1:-1;;;10794:18:1;;;10787:36;10840:19;;94099:73:0::1;10463:402:1::0;94099:73:0::1;94183:28;94202:8;94183:18;:28::i;:::-;94018:201:::0;:::o;93284:132::-;93165:7;93192:6;-1:-1:-1;;;;;93192:6:0;4228:10;93348:23;93340:68;;;;-1:-1:-1;;;93340:68:0;;11072:2:1;93340:68:0;;;11054:21:1;;;11091:18;;;11084:30;11150:34;11130:18;;;11123:62;11202:18;;93340:68:0;10870:356:1;94379:191:0;94453:16;94472:6;;-1:-1:-1;;;;;94489:17:0;;;-1:-1:-1;;;;;;94489:17:0;;;;;;94522:40;;94472:6;;;;;;;94522:40;;94453:16;94522:40;94442:128;94379:191;:::o;30471:205::-;30599:68;;-1:-1:-1;;;;;11489:15:1;;;30599:68:0;;;11471:34:1;11541:15;;11521:18;;;11514:43;11573:18;;;11566:34;;;30572:96:0;;30592:5;;-1:-1:-1;;;30622:27:0;11406:18:1;;30599:68:0;;;;-1:-1:-1;;30599:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;30599:68:0;-1:-1:-1;;;;;;30599:68:0;;;;;;;;;;30572:19;:96::i;:::-;30471:205;;;;:::o;30945:582::-;31275:10;;;31274:62;;-1:-1:-1;31291:39:0;;-1:-1:-1;;;31291:39:0;;31315:4;31291:39;;;11823:34:1;-1:-1:-1;;;;;11893:15:1;;;11873:18;;;11866:43;31291:15:0;;;;;11758:18:1;;31291:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;31274:62;31252:166;;;;-1:-1:-1;;;31252:166:0;;12122:2:1;31252:166:0;;;12104:21:1;12161:2;12141:18;;;12134:30;12200:34;12180:18;;;12173:62;-1:-1:-1;;;12251:18:1;;;12244:52;12313:19;;31252:166:0;11920:418:1;31252:166:0;31456:62;;-1:-1:-1;;;;;9815:32:1;;31456:62:0;;;9797:51:1;9864:18;;;9857:34;;;31429:90:0;;31449:5;;-1:-1:-1;;;31479:22:0;9770:18:1;;31456:62:0;9623:274:1;31429:90:0;30945:582;;;:::o;34372:649::-;34796:23;34822:69;34850:4;34822:69;;;;;;;;;;;;;;;;;34830:5;-1:-1:-1;;;;;34822:27:0;;;:69;;;;;:::i;:::-;34796:95;;34910:10;:17;34931:1;34910:22;:56;;;;34947:10;34936:30;;;;;;;;;;;;:::i;:::-;34902:111;;;;-1:-1:-1;;;34902:111:0;;12545:2:1;34902:111:0;;;12527:21:1;12584:2;12564:18;;;12557:30;12623:34;12603:18;;;12596:62;-1:-1:-1;;;12674:18:1;;;12667:40;12724:19;;34902:111:0;12343:406:1;23929:229:0;24066:12;24098:52;24120:6;24128:4;24134:1;24137:12;24098:21;:52::i;:::-;24091:59;23929:229;-1:-1:-1;;;;23929:229:0:o;25015:455::-;25185:12;25243:5;25218:21;:30;;25210:81;;;;-1:-1:-1;;;25210:81:0;;12956:2:1;25210:81:0;;;12938:21:1;12995:2;12975:18;;;12968:30;13034:34;13014:18;;;13007:62;-1:-1:-1;;;13085:18:1;;;13078:36;13131:19;;25210:81:0;12754:402:1;25210:81:0;25303:12;25317:23;25344:6;-1:-1:-1;;;;;25344:11:0;25363:5;25370:4;25344:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25302:73;;;;25393:69;25420:6;25428:7;25437:10;25449:12;25393:26;:69::i;:::-;25386:76;25015:455;-1:-1:-1;;;;;;;25015:455:0:o;27588:644::-;27773:12;27802:7;27798:427;;;27830:10;:17;27851:1;27830:22;27826:290;;-1:-1:-1;;;;;21469:19:0;;;28040:60;;;;-1:-1:-1;;;28040:60:0;;13642:2:1;28040:60:0;;;13624:21:1;13681:2;13661:18;;;13654:30;13720:31;13700:18;;;13693:59;13769:18;;28040:60:0;13440:353:1;28040:60:0;-1:-1:-1;28137:10:0;28130:17;;27798:427;28180:33;28188:10;28200:12;28935:17;;:21;28931:388;;29167:10;29161:17;29224:15;29211:10;29207:2;29203:19;29196:44;28931:388;29294:12;29287:20;;-1:-1:-1;;;29287:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;:::o;222:131:1:-;-1:-1:-1;;;;;297:31:1;;287:42;;277:70;;343:1;340;333:12;358:247;417:6;470:2;458:9;449:7;445:23;441:32;438:52;;;486:1;483;476:12;438:52;525:9;512:23;544:31;569:5;544:31;:::i;:::-;594:5;358:247;-1:-1:-1;;;358:247:1:o;610:180::-;669:6;722:2;710:9;701:7;697:23;693:32;690:52;;;738:1;735;728:12;690:52;-1:-1:-1;761:23:1;;610:180;-1:-1:-1;610:180:1:o;2313:341::-;2515:2;2497:21;;;2554:2;2534:18;;;2527:30;-1:-1:-1;;;2588:2:1;2573:18;;2566:47;2645:2;2630:18;;2313:341::o;2659:127::-;2720:10;2715:3;2711:20;2708:1;2701:31;2751:4;2748:1;2741:15;2775:4;2772:1;2765:15;2791:253;2863:2;2857:9;2905:4;2893:17;;2940:18;2925:34;;2961:22;;;2922:62;2919:88;;;2987:18;;:::i;:::-;3023:2;3016:22;2791:253;:::o;3049:246::-;3116:2;3110:9;;;3146:15;;3191:18;3176:34;;3212:22;;;3173:62;3170:88;;;3238:18;;:::i;3300:192::-;3379:13;;-1:-1:-1;;;;;3421:46:1;;3411:57;;3401:85;;3482:1;3479;3472:12;3401:85;3300:192;;;:::o;3497:175::-;3575:13;;3628:18;3617:30;;3607:41;;3597:69;;3662:1;3659;3652:12;3677:1032;3743:5;3796:3;3789:4;3781:6;3777:17;3773:27;3763:55;;3814:1;3811;3804:12;3763:55;3838:17;;:::i;:::-;3877:3;3915;3907:6;3903:16;3942:3;3934:6;3931:15;3928:35;;;3959:1;3956;3949:12;3928:35;3983:6;3998:682;4014:6;4009:3;4006:15;3998:682;;;4092:4;4086:3;4081;4077:13;4073:24;4070:114;;;4138:1;4167:2;4163;4156:14;4070:114;4210:22;;:::i;:::-;4259:34;4289:3;4259:34;:::i;:::-;4252:5;4245:49;4317:2;4355:43;4394:2;4389:3;4385:12;4355:43;:::i;:::-;4350:2;4343:5;4339:14;4332:67;4422:2;4460:42;4498:2;4493:3;4489:12;4460:42;:::i;:::-;4444:14;;;4437:66;4526:2;4564:42;4593:12;;;4564:42;:::i;:::-;4548:14;;;4541:66;4620:18;;;4658:12;;;;4040:4;4031:14;3998:682;;;-1:-1:-1;4698:5:1;;3677:1032;-1:-1:-1;;;;;3677:1032:1:o;4714:1051::-;4810:6;4863:3;4851:9;4842:7;4838:23;4834:33;4831:53;;;4880:1;4877;4870:12;4831:53;4906:22;;:::i;:::-;4957:9;4951:16;4944:5;4937:31;4987:2;5034;5023:9;5019:18;5013:25;5047:33;5072:7;5047:33;:::i;:::-;5096:14;;;5089:31;5158:2;5143:18;;5139:32;-1:-1:-1;5129:60:1;;5185:1;5182;5175:12;5129:60;5209:17;;:::i;:::-;5248:3;5289:4;5278:9;5274:20;5317:7;5309:6;5306:19;5303:39;;;5338:1;5335;5328:12;5303:39;5377:2;5366:9;5362:18;5389:216;5405:6;5400:3;5397:15;5389:216;;;5480:3;5474:10;5497:33;5522:7;5497:33;:::i;:::-;5543:20;;5583:12;;;;5422;;5389:216;;;5393:3;5637:5;5632:2;5625:5;5621:14;5614:29;5677:57;5726:7;5718:6;5677:57;:::i;:::-;5670:4;5659:16;;5652:83;-1:-1:-1;5663:5:1;;4714:1051;-1:-1:-1;;;;;;4714:1051:1:o;5902:258::-;5974:1;5984:113;5998:6;5995:1;5992:13;5984:113;;;6074:11;;;6068:18;6055:11;;;6048:39;6020:2;6013:10;5984:113;;;6115:6;6112:1;6109:13;6106:48;;;-1:-1:-1;;6150:1:1;6132:16;;6125:27;5902:258::o;6165:884::-;6245:6;6298:2;6286:9;6277:7;6273:23;6269:32;6266:52;;;6314:1;6311;6304:12;6266:52;6347:9;6341:16;6376:18;6417:2;6409:6;6406:14;6403:34;;;6433:1;6430;6423:12;6403:34;6471:6;6460:9;6456:22;6446:32;;6516:7;6509:4;6505:2;6501:13;6497:27;6487:55;;6538:1;6535;6528:12;6487:55;6567:2;6561:9;6589:2;6585;6582:10;6579:36;;;6595:18;;:::i;:::-;6670:2;6664:9;6638:2;6724:13;;-1:-1:-1;;6720:22:1;;;6744:2;6716:31;6712:40;6700:53;;;6768:18;;;6788:22;;;6765:46;6762:72;;;6814:18;;:::i;:::-;6854:10;6850:2;6843:22;6889:2;6881:6;6874:18;6929:7;6924:2;6919;6915;6911:11;6907:20;6904:33;6901:53;;;6950:1;6947;6940:12;6901:53;6963:55;7015:2;7010;7002:6;6998:15;6993:2;6989;6985:11;6963:55;:::i;7054:773::-;7465:28;7460:3;7453:41;7435:3;7523:6;7517:13;7539:62;7594:6;7589:2;7584:3;7580:12;7573:4;7565:6;7561:17;7539:62;:::i;:::-;-1:-1:-1;;;7660:2:1;7620:16;;;7652:11;;;7645:24;7694:13;;7716:63;7694:13;7765:2;7757:11;;7750:4;7738:17;;7716:63;:::i;:::-;7799:17;7818:2;7795:26;;7054:773;-1:-1:-1;;;;7054:773:1:o;7832:746::-;-1:-1:-1;;;8238:3:1;8231:18;8213:3;8278:6;8272:13;8294:61;8348:6;8344:1;8339:3;8335:11;8328:4;8320:6;8316:17;8294:61;:::i;:::-;-1:-1:-1;;;8414:1:1;8374:16;;;8406:10;;;8399:23;8447:13;;8469:62;8447:13;8518:1;8510:10;;8503:4;8491:17;;8469:62;:::i;:::-;8551:17;8570:1;8547:25;;7832:746;-1:-1:-1;;;;7832:746:1:o;8583:258::-;8625:3;8663:5;8657:12;8690:6;8685:3;8678:19;8706:63;8762:6;8755:4;8750:3;8746:14;8739:4;8732:5;8728:16;8706:63;:::i;:::-;8823:2;8802:15;-1:-1:-1;;8798:29:1;8789:39;;;;8830:4;8785:50;;8583:258;-1:-1:-1;;8583:258:1:o;8846:583::-;9099:3;9088:9;9081:22;9062:4;9126:46;9167:3;9156:9;9152:19;9144:6;9126:46;:::i;:::-;9220:9;9212:6;9208:22;9203:2;9192:9;9188:18;9181:50;9248:33;9274:6;9266;9248:33;:::i;:::-;-1:-1:-1;;;;;9355:15:1;;;9350:2;9335:18;;9328:43;9407:15;;;;9402:2;9387:18;;;9380:43;;;;-1:-1:-1;9240:41:1;8846:583;-1:-1:-1;;;8846:583:1:o;9434:184::-;9504:6;9557:2;9545:9;9536:7;9532:23;9528:32;9525:52;;;9573:1;9570;9563:12;9525:52;-1:-1:-1;9596:16:1;;9434:184;-1:-1:-1;9434:184:1:o;9902:277::-;9969:6;10022:2;10010:9;10001:7;9997:23;9993:32;9990:52;;;10038:1;10035;10028:12;9990:52;10070:9;10064:16;10123:5;10116:13;10109:21;10102:5;10099:32;10089:60;;10145:1;10142;10135:12;13161:274;13290:3;13328:6;13322:13;13344:53;13390:6;13385:3;13378:4;13370:6;13366:17;13344:53;:::i;:::-;13413:16;;;;;13161:274;-1:-1:-1;;13161:274:1:o;13798:220::-;13947:2;13936:9;13929:21;13910:4;13967:45;14008:2;13997:9;13993:18;13985:6;13967:45;:::i
Swarm Source
ipfs://a1125db0254c2f7e64ba27cb6aca02eb8c8eceda76a8e832c6fe1250b8e2545d
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.