Overview
FTM Balance
FTM Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 3 internal transactions
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
76042020 | 395 days ago | Contract Creation | 0 FTM | |||
75864706 | 398 days ago | Contract Creation | 0 FTM | |||
75864659 | 398 days ago | Contract Creation | 0 FTM |
Contract Source Code (Solidity)
/** *Submitted for verification at ftmscan.com on 2024-02-18 */ // 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
60806040526006805460ff191660011790553480156200001e57600080fd5b5060405162004e0b38038062004e0b8339810160408190526200004191620001de565b6200004c3362000090565b600180546001600160a01b038086166001600160a01b03199283161790925560028054928516929091169190911790556200008781620000e0565b50505062000228565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b620000ea62000163565b6001600160a01b038116620001555760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b620001608162000090565b50565b6000546001600160a01b03163314620001bf5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016200014c565b565b80516001600160a01b0381168114620001d957600080fd5b919050565b600080600060608486031215620001f457600080fd5b620001ff84620001c1565b92506200020f60208501620001c1565b91506200021f60408501620001c1565b90509250925092565b614bd380620002386000396000f3fe60806040523480156200001157600080fd5b5060043610620001155760003560e01c80638da5cb5b11620000a3578063d9164817116200006e578063d9164817146200024f578063e5e31b131462000286578063f1e6c40614620002ac578063f2fde38b14620002c357600080fd5b80638da5cb5b14620001cc578063a1e1fdac14620001de578063ab87f2fd1462000221578063ced78e25146200023857600080fd5b8063567fd09e11620000e4578063567fd09e146200018f578063574f2ba314620001995780636ff1c9bc14620001ab578063715018a614620001c257600080fd5b80630362158f146200011a5780630850ad99146200014b5780631e3dd18b146200016457806346c96aac146200017b575b600080fd5b6001546200012e906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b620001626200015c36600462001157565b620002da565b005b6200012e620001753660046200117e565b620003c5565b6002546200012e906001600160a01b031681565b62000162620003f0565b60035460405190815260200162000142565b62000162620001bc36600462001157565b6200044b565b6200016262000561565b6000546001600160a01b03166200012e565b620001f5620001ef3660046200117e565b62000579565b604080516001600160a01b03958616815294909316602085015291830152606082015260800162000142565b620001626200023236600462001157565b62000628565b6200012e620002493660046200117e565b6200068e565b620002756200026036600462001157565b60056020526000908152604090205460ff1681565b604051901515815260200162000142565b620002756200029736600462001157565b60046020526000908152604090205460ff1681565b62000162620002bd36600462001157565b62000b8b565b62000162620002d436600462001157565b62000bf4565b620002e462000c73565b6001600160a01b03811660009081526005602052604090205460ff16156200034a5760405162461bcd60e51b815260206004820152601460248201527332bc34b9ba34b7339031b0b93137b7103830b4b960611b60448201526064015b60405180910390fd5b6003805460018181019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b039093166001600160a01b0319909316831790556000918252600560209081526040808420805460ff19908116851790915560049092529092208054909216179055565b60038181548110620003d657600080fd5b6000918252602090912001546001600160a01b0316905081565b620003fa62000c73565b60065460ff166200043f5760405162461bcd60e51b815260206004820152600e60248201526d6e6f74206265746120706861736560901b604482015260640162000341565b6006805460ff19169055565b6200045562000c73565b60065460ff166200049a5760405162461bcd60e51b815260206004820152600e60248201526d6e6f74206265746120706861736560901b604482015260640162000341565b6001600160a01b03811660009081526005602052604090205460ff16620004d55760405162461bcd60e51b8152600401620003419062001198565b6001600160a01b0381166000818152600560209081526040808320805460ff199081169091556004928390529281902080549093169092559051631bfc726f60e21b81523391810191909152636ff1c9bc90602401600060405180830381600087803b1580156200054557600080fd5b505af11580156200055a573d6000803e3d6000fd5b5050505050565b6200056b62000c73565b62000577600062000ccf565b565b600154604051632f2235f960e21b81526004810183905260009182918291829182916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015620005cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005f3919062001319565b604081015180516020918201516060909301518051519201515190999298506001600160801b03918216975016945092505050565b6200063262000c73565b6001600160a01b03811660009081526005602052604090205460ff166200066d5760405162461bcd60e51b8152600401620003419062001198565b6001600160a01b03166000908152600460205260409020805460ff19169055565b6000806000806000620006a18662000579565b93509350935093506000846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620006ea573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620007149190810190620013f9565b846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000753573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200077d9190810190620013f9565b60405160200162000790929190620014a7565b60405160208183030381529060405290506000856001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620007e2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200080c9190810190620013f9565b856001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156200084b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620008759190810190620013f9565b6040516020016200088892919062001510565b60408051601f1981840301815290829052600154600254919350600092859285926001600160a01b0390811692911690620008c39062001133565b620008d294939291906200158d565b604051809103906000f080158015620008ef573d6000803e3d6000fd5b50905084156200091457620009078733308862000d1f565b6200091487828762000d92565b83156200093657620009298633308762000d1f565b6200093686828662000d92565b604051630ad374dd60e41b8152600481018a90526001600160a01b0382169063ad374dd090602401600060405180830381600087803b1580156200097957600080fd5b505af11580156200098e573d6000803e3d6000fd5b50506003805460018082019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b03861690811790915560008181526005602052604090819020805460ff191690931790925590516370a0823160e01b815230600482015284935090915063a9059cbb90339083906370a0823190602401602060405180830381865afa15801562000a3f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a659190620015db565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af115801562000ab1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ad79190620015f5565b50816001600160a01b031663492f4e186040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000b17573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b3d9190620015db565b604080518c81526001600160a01b03841660208201527ff7ee1758a8519d7fe72714f8cfd41d75d71255250aa858f78cb859f6f3c78232910160405180910390a29998505050505050505050565b62000b9562000c73565b6001600160a01b03811660009081526005602052604090205460ff1662000bd05760405162461bcd60e51b8152600401620003419062001198565b6001600160a01b03166000908152600460205260409020805460ff19166001179055565b62000bfe62000c73565b6001600160a01b03811662000c655760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000341565b62000c708162000ccf565b50565b6000546001600160a01b03163314620005775760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000341565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038085166024830152831660448201526064810182905262000d8c9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915262000eb4565b50505050565b80158062000e105750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801562000de8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e0e9190620015db565b155b62000e7d5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840162000341565b6040516001600160a01b03831660248201526044810182905262000eaf90849063095ea7b360e01b9060640162000d54565b505050565b600062000f0b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031662000f909092919063ffffffff16565b905080516000148062000f2f57508080602001905181019062000f2f9190620015f5565b62000eaf5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000341565b606062000fa1848460008562000fa9565b949350505050565b6060824710156200100c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000341565b600080866001600160a01b031685876040516200102a919062001619565b60006040518083038185875af1925050503d806000811462001069576040519150601f19603f3d011682016040523d82523d6000602084013e6200106e565b606091505b509150915062001081878383876200108c565b979650505050505050565b6060831562001100578251600003620010f8576001600160a01b0385163b620010f85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000341565b508162000fa1565b62000fa18383815115620011175781518083602001fd5b8060405162461bcd60e51b815260040162000341919062001637565b613551806200164d83390190565b6001600160a01b038116811462000c7057600080fd5b6000602082840312156200116a57600080fd5b8135620011778162001141565b9392505050565b6000602082840312156200119157600080fd5b5035919050565b6020808252601190820152703737ba10309031b0b93137b7103830b4b960791b604082015260600190565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715620011ff57620011ff620011c3565b60405290565b6040805190810167ffffffffffffffff81118282101715620011ff57620011ff620011c3565b80516001600160801b03811681146200124357600080fd5b919050565b805167ffffffffffffffff811681146200124357600080fd5b600082601f8301126200127357600080fd5b6200127d62001205565b806101008401858111156200129157600080fd5b845b818110156200130e5760808188031215620012ae5760008081fd5b620012b8620011d9565b620012c3826200122b565b81526020620012d48184016200122b565b818301526040620012e781850162001248565b908301526060620012fa84820162001248565b908301529085529093019260800162001293565b509095945050505050565b600061018082840312156200132d57600080fd5b62001337620011d9565b825181526020808401516200134c8162001141565b82820152605f840185136200136057600080fd5b6200136a62001205565b8060808601878111156200137d57600080fd5b604087015b81811015620013a6578051620013988162001141565b845292840192840162001382565b50816040860152620013b9888262001261565b606086015250929695505050505050565b60005b83811015620013e7578181015183820152602001620013cd565b8381111562000d8c5750506000910152565b6000602082840312156200140c57600080fd5b815167ffffffffffffffff808211156200142557600080fd5b818401915084601f8301126200143a57600080fd5b8151818111156200144f576200144f620011c3565b604051601f8201601f19908116603f011681019083821181831017156200147a576200147a620011c3565b816040528281528760208487010111156200149457600080fd5b62001081836020830160208801620013ca565b7f436f6e63656e74726174656420204c6971756964697479202d20000000000000815260008351620014e181601a850160208801620013ca565b602f60f81b601a9184019182015283516200150481601b840160208801620013ca565b01601b01949350505050565b62434c2d60e81b81526000835162001530816003850160208801620013ca565b602f60f81b600391840191820152835162001553816004840160208801620013ca565b01600401949350505050565b6000815180845262001579816020860160208601620013ca565b601f01601f19169290920160200192915050565b608081526000620015a260808301876200155f565b8281036020840152620015b681876200155f565b6001600160a01b03958616604085015293909416606090920191909152509392505050565b600060208284031215620015ee57600080fd5b5051919050565b6000602082840312156200160857600080fd5b815180151581146200117757600080fd5b600082516200162d818460208701620013ca565b9190910192915050565b6020815260006200117760208301846200155f56fe60a06040523480156200001157600080fd5b506040516200355138038062003551833981016040819052620000349162000240565b8351849084906200004d906003906020850190620000b0565b50805162000063906004906020840190620000b0565b5050600160055550600780546001600160a01b039384166001600160a01b03199182161790915560088054929093169116179055505033608052600b805460ff60a01b191690556200030b565b828054620000be90620002cf565b90600052602060002090601f016020900481019282620000e257600085556200012d565b82601f10620000fd57805160ff19168380011785556200012d565b828001600101855582156200012d579182015b828111156200012d57825182559160200191906001019062000110565b506200013b9291506200013f565b5090565b5b808211156200013b576000815560010162000140565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200017e57600080fd5b81516001600160401b03808211156200019b576200019b62000156565b604051601f8301601f19908116603f01168101908282118183101715620001c657620001c662000156565b81604052838152602092508683858801011115620001e357600080fd5b600091505b83821015620002075785820183015181830184015290820190620001e8565b83821115620002195760008385830101525b9695505050505050565b80516001600160a01b03811681146200023b57600080fd5b919050565b600080600080608085870312156200025757600080fd5b84516001600160401b03808211156200026f57600080fd5b6200027d888389016200016c565b955060208701519150808211156200029457600080fd5b50620002a3878288016200016c565b935050620002b46040860162000223565b9150620002c46060860162000223565b905092959194509250565b600181811c90821680620002e457607f821691505b6020821081036200030557634e487b7160e01b600052602260045260246000fd5b50919050565b6080516132236200032e6000396000818161049901526110d501526132236000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c80636ff1c9bc1161011a578063ad374dd0116100ad578063c45a01551161007c578063c45a015514610494578063c8eaac0b146104bb578063d21220a7146104c3578063dd62ed3e146104d6578063e455dea8146104e957600080fd5b8063ad374dd014610448578063b22d8fe01461045b578063c3df46d81461046e578063c3fbc5ef1461048157600080fd5b80639f118536116100e95780639f11853614610406578063a0f821711461041a578063a457c2d714610422578063a9059cbb1461043557600080fd5b80636ff1c9bc146103ae57806370a08231146103c157806391f36d65146103ea57806395d89b41146103fe57600080fd5b806323b872dd1161019d578063395093511161016c578063395093511461035957806345a1de791461036c57806346c96aac1461037f578063492f4e18146103925780634a65f70b1461039b57600080fd5b806323b872dd146102f15780632644b97b146103045780632e1a7d4d14610337578063313ce5671461034a57600080fd5b80630dfe1681116101d95780630dfe168114610289578063150b7a021461029c57806318160ddd146102d457806319999566146102dc57600080fd5b80630134e0f41461020b5780630362158f1461022657806306fdde0314610251578063095ea7b314610266575b600080fd5b6102136104fc565b6040519081526020015b60405180910390f35b600754610239906001600160a01b031681565b6040516001600160a01b03909116815260200161021d565b61025961056f565b60405161021d9190612a40565b610279610274366004612a88565b610601565b604051901515815260200161021d565b600a54610239906001600160a01b031681565b6102bb6102aa366004612ab4565b630a85bd0160e11b95945050505050565b6040516001600160e01b0319909116815260200161021d565b600254610213565b6102ef6102ea366004612b53565b61061b565b005b6102796102ff366004612b70565b6106ce565b61030c6106f2565b604080516001600160a01b03958616815294909316602085015291830152606082015260800161021d565b6102ef610345366004612bb1565b6107a1565b6040516012815260200161021d565b610279610367366004612a88565b610d6a565b600954610239906001600160a01b031681565b600854610239906001600160a01b031681565b61021360065481565b6102ef6103a9366004612bdf565b610d8c565b6102ef6103bc366004612b53565b6110ca565b6102136103cf366004612b53565b6001600160a01b031660009081526020819052604090205490565b60095461027990600160a01b900460ff1681565b6102596111f0565b600b5461027990600160a01b900460ff1681565b6102796111ff565b610279610430366004612a88565b6112b4565b610279610443366004612a88565b61132f565b6102ef610456366004612bb1565b61133d565b6102ef610469366004612c2f565b6115d7565b61021361047c366004612c4c565b611689565b6102ef61048f366004612c85565b6117e6565b6102397f000000000000000000000000000000000000000000000000000000000000000081565b610213611e34565b600b54610239906001600160a01b031681565b6102136104e4366004612cb5565b611e65565b61030c6104f7366004612bb1565b611e90565b600b546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a08231906024015b602060405180830381865afa158015610546573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056a9190612ce3565b905090565b60606003805461057e90612cfc565b80601f01602080910402602001604051908101604052809291908181526020018280546105aa90612cfc565b80156105f75780601f106105cc576101008083540402835291602001916105f7565b820191906000526020600020905b8154815290600101906020018083116105da57829003601f168201915b5050505050905090565b60003361060f818585611f74565b60019150505b92915050565b6008546001600160a01b031633146106845760405162461bcd60e51b815260206004820152602160248201527f4f6e6c7920766f7465722063616e207365742065787465726e616c20627269626044820152606560f81b60648201526084015b60405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040517f03e9b76bf8c2d2d6948b20459194f64843d25ada1a13e3481bf88399831a046190600090a250565b6000336106dc858285612098565b6106e7858585612112565b506001949350505050565b600754600654604051632f2235f960e21b8152600481019190915260009182918291829182916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015610749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076d9190612e60565b604081015180516020918201516060909301518051519201515190989297506001600160801b039182169650169350915050565b6107a96122b6565b600081116107e85760405162461bcd60e51b815260206004820152600c60248201526b05f736861726573203d3d20360a41b604482015260640161067b565b600754600654604051632f2235f960e21b815260048101919091526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015610837573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085b9190612e60565b9050600061089d61086b60025490565b6060840151859060005b60200201515161088e91906001600160801b0316612f2e565b6108989190612f4d565b61230f565b905060006108bb6108ad60025490565b606085015186906001610875565b90506108c7338561237c565b6000826001600160801b031611806108e857506000816001600160801b0316115b6109245760405162461bcd60e51b815260206004820152600d60248201526c3020746f20776974686472617760981b604482015260640161067b565b6040805160808101825260008082526020820181905291810182905260608101919091526001600160801b038316156109ff57606084810180515160409081015167ffffffffffffffff9081169185019190915281515183015116918301919091525180518051602091909101516109cf926001600160801b03928316929182169187169060005b6020020151516109c591906001600160801b0316612f6f565b61088e9190612f2e565b6001600160801b03166020820152606084015151516109ef908490612f86565b6001600160801b03168152610a51565b606084810180515160409081015167ffffffffffffffff9081169185019190915281515183015116918301919091528051516020908101516001600160801b0390811691840191909152905151511681525b6040805160808101825260008082526020820181905291810182905260608101919091526001600160801b03831615610b1a576060858101805160209081015160409081015167ffffffffffffffff908116918601919091528251820151840151169284019290925251808201518051920151610ae3926001600160801b0390811692918116919087169060016109ac565b6001600160801b03166020820152606085015183906001602002015151610b0a9190612f86565b6001600160801b03168152610b72565b6060858101805160209081015160409081015167ffffffffffffffff908116918601919091528251820151840151169284019290925280518201518201516001600160801b0390811684840152905190910151511681525b836001600160801b0316600003610bd5576060850151610bc69060016020020151602001516001600160801b031683602001516001600160801b031683602001516001600160801b031661088e9190612f2e565b6001600160801b031660208301525b826001600160801b0316600003610c38576060850151610c299060006020020151602001516001600160801b031682602001516001600160801b031684602001516001600160801b031661088e9190612f2e565b6001600160801b031660208201525b60075460065460608701516040805180820182528681526020810186905290516321589fa160e01b81526001600160a01b03909416936321589fa193610c849390929091600401613012565b600060405180830381600087803b158015610c9e57600080fd5b505af1158015610cb2573d6000803e3d6000fd5b505050506001600160801b03841615610cdf57604085015151610cdf90336001600160801b0387166124ae565b6001600160801b03831615610d0b57604085015160200151610d0b90336001600160801b0386166124ae565b604080516001600160801b0380871682528516602082015290810187905233907f743033787f4738ff4d6a7225ce2bd0977ee5f86b91a902a58f5e4d0b297b46449060600160405180910390a25050505050610d676001600555565b50565b60003361060f818585610d7d8383611e65565b610d879190613035565b611f74565b600b54600160a01b900460ff1615610dd65760405162461bcd60e51b815260206004820152600d60248201526c1d985d5b1d081cdd185c9d1959609a1b604482015260640161067b565b6000826001600160801b03161180610df757506000816001600160801b0316115b610e375760405162461bcd60e51b81526020600482015260116024820152700616d6f756e74546f6b656e73203d3d203607c1b604482015260640161067b565b600754604051632f2235f960e21b8152600481018590526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015610e82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea69190612e60565b60408101518051600a80546001600160a01b03199081166001600160a01b0393841617909155602090920151600b8054909316911617905590506001600160801b03831615610f1057600a54610f10906001600160a01b031633306001600160801b038716612511565b6001600160801b03821615610f4057600b54610f40906001600160a01b031633306001600160801b038616612511565b606081015180516020918201516001600160801b0386811680845283850181905290861680835293820193909352600a5460075492939192610f91926001600160a01b039283169290911690612549565b600b54600754610fb7916001600160a01b0390811691166001600160801b038716612549565b6007546040848101518051602091820151835180850185528781529283018690529251637b93a39d60e11b81526001600160a01b039094169363f727473a9361100493909160040161304d565b6020604051808303816000875af1158015611023573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110479190612ce3565b60065560006001600160801b038086169087161161108357600b5461107e906001600160a01b03166001600160801b03871661265e565b6110a2565b600a546110a2906001600160a01b03166001600160801b03881661265e565b90506110ae33826126f0565b5050600b805460ff60a01b1916600160a01b1790555050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146111325760405162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015260640161067b565b600754600654604051638730203760e01b81526001600160a01b03909216916387302037916111679160040190815260200190565b600060405180830381600087803b15801561118157600080fd5b505af1158015611195573d6000803e3d6000fd5b5050505060006111a3611e34565b905060006111af6104fc565b905081156111ce57600a546111ce906001600160a01b031684846124ae565b80156111eb57600b546111eb906001600160a01b031684836124ae565b505050565b60606004805461057e90612cfc565b600754600654604051632f2235f960e21b815260009283926001600160a01b039091169163bc88d7e4916112399160040190815260200190565b61018060405180830381865afa158015611257573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127b9190612e60565b606081015151519091506001600160801b0316158015906112ad5750606081015160200151516001600160801b031615155b1591505090565b600033816112c28286611e65565b9050838110156113225760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161067b565b6106e78286868403611f74565b60003361060f818585612112565b600b54600160a01b900460ff16156113875760405162461bcd60e51b815260206004820152600d60248201526c1d985d5b1d081cdd185c9d1959609a1b604482015260640161067b565b600754604051632f2235f960e21b8152600481018390526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa1580156113d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f69190612e60565b60408101518051600a80546001600160a01b039283166001600160a01b031991821617909155602092830151600b8054919093169116179055606082015180519101518151815193945091929091906001600160801b0382161561147557600a54611475906001600160a01b031633306001600160801b038616612511565b6001600160801b038116156114a557600b546114a5906001600160a01b031633306001600160801b038516612511565b600a546007546114cb916001600160a01b0390811691166001600160801b038516612549565b600b546007546114f1916001600160a01b0390811691166001600160801b038416612549565b6007546040868101518051602091820151835180850185528981529283018890529251637b93a39d60e11b81526001600160a01b039094169363f727473a9361153e93909160040161304d565b6020604051808303816000875af115801561155d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115819190612ce3565b60065560006001600160801b03808316908416116115b857600b5461107e906001600160a01b03166001600160801b03841661265e565b600a546110a2906001600160a01b03166001600160801b03851661265e565b6008546001600160a01b031633146116315760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c7920766f7465722063616e207365742068617320676175676500000000604482015260640161067b565b60098054821515600160a01b0260ff60a01b199091161790556040517f352eb552c369d470b6f2286567a9f272a1210ad788562e697f254cad5611f1059061167e90831515815260200190565b60405180910390a150565b600754600654604051632f2235f960e21b815260009283926001600160a01b039091169163bc88d7e4916116c39160040190815260200190565b61018060405180830381865afa1580156116e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117059190612e60565b90506000846001600160a01b0316826040015160006002811061172a5761172a612f02565b60200201516001600160a01b031614905060008161174d57604083015151611757565b6040830151602001515b905060008261176e57606084015160200151611775565b6060840151515b905060008361178957606085015151611793565b6060850151602001515b82519091506001600160801b03166000036117af5760006117d1565b815181516117d1916001600160801b039081169161088e918b81169116612f2e565b6001600160801b031698975050505050505050565b6117ee6122b6565b6006546000036118345760405162461bcd60e51b81526020600482015260116024820152701d985d5b1d081b9bdd081cdd185c9d1959607a1b604482015260640161067b565b600a546001600160a01b038481169116148061185d5750600b546001600160a01b038481169116145b6118b85760405162461bcd60e51b815260206004820152602660248201527f6465706f73697420746f6b656e206973206e6f742070617274206f6620746865604482015265081d985d5b1d60d21b606482015260840161067b565b6000826001600160801b0316116119005760405162461bcd60e51b815260206004820152600c60248201526b05f616d6f756e74203d3d20360a41b604482015260640161067b565b611915833330856001600160801b0316612511565b600754600654604051632f2235f960e21b815260048101919091526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015611964573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119889190612e60565b90506000846001600160a01b031682604001516000600281106119ad576119ad612f02565b60200201516001600160a01b03161490506000816119d0576040830151516119da565b6040830151602001515b90506000826119f1576060840151602001516119f8565b6060840151515b9050600083611a0c57606085015151611a16565b6060850151602001515b805183519192506001600160801b03908116911611611a8c5760405162461bcd60e51b815260206004820152602c60248201527f796f75206e65656420746f20757365206f7468657220746f6b656e206173206460448201526b32b837b9b4ba103a37b5b2b760a11b606482015260840161067b565b81516001600160801b031615801590611aae575080516001600160801b031615155b611ae95760405162461bcd60e51b815260206004820152600c60248201526b6f7574206f662072616e676560a01b604482015260640161067b565b6000611b1e83600001516001600160801b0316896001600160801b031684600001516001600160801b031661088e9190612f2e565b9050866001600160801b0316816001600160801b03161115611b535760405163428637bb60e11b815260040160405180910390fd5b6001600160801b03811615611b9857611b77843330846001600160801b0316612511565b600754611b989085906001600160a01b03166001600160801b038416612549565b600083600001516001600160801b0316896001600160801b0316611bbb60025490565b611bc59190612f2e565b611bcf9190612f4d565b9050611bfb60408051608081018252600080825260208201819052918101829052606081019190915290565b60408086015167ffffffffffffffff908116918301919091526060808701519091169082015284516020860151611c47916001600160801b03908116918116906109c5908e1683613035565b6001600160801b031660208201528451611c62908b90613073565b6001600160801b03908116825260408051608081018252600080825260208083018290528284018281526060808501938452948a015167ffffffffffffffff9081169091529389015190931690528651918701519092611cce928116918116906109c590881683613035565b6001600160801b031660208201528451611ce9908590613073565b6001600160801b0316815260008089611d03578284611d06565b83835b91509150611d338e600760009054906101000a90046001600160a01b03168f6001600160801b0316612549565b60075460065460608d01516040805180820182528681526020810186905290516321589fa160e01b81526001600160a01b03909416936321589fa193611d7f9390929091600401613012565b600060405180830381600087803b158015611d9957600080fd5b505af1158015611dad573d6000803e3d6000fd5b50505050611dbb33866126f0565b336001600160a01b03167fb4c03061fb5b7fed76389d5af8f2e0ddb09f8c70d1333abbb62582835e10accb8e8888604051611e17939291906001600160801b039384168152919092166020820152604081019190915260600190565b60405180910390a250505050505050505050506111eb6001600555565b600a546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401610529565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600754600654604051632f2235f960e21b8152600481019190915260009182918291829182916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015611ee7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f0b9190612e60565b90506000611f29611f1b60025490565b606084015189906000610875565b90506000611f47611f3960025490565b60608501518a906001610875565b60409390930151805160209091015190999098506001600160801b03928316975091909216945092505050565b6001600160a01b038316611fd65760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161067b565b6001600160a01b0382166120375760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161067b565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006120a48484611e65565b9050600019811461210c57818110156120ff5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161067b565b61210c8484848403611f74565b50505050565b6001600160a01b0383166121765760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161067b565b6001600160a01b0382166121d85760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161067b565b6001600160a01b038316600090815260208190526040902054818110156122505760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161067b565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a361210c565b6002600554036123085760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161067b565b6002600555565b60006001600160801b038211156123785760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b606482015260840161067b565b5090565b6001600160a01b0382166123dc5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161067b565b6001600160a01b038216600090815260208190526040902054818110156124505760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161067b565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6040516001600160a01b0383166024820152604481018290526111eb90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526127af565b6040516001600160a01b038085166024830152831660448201526064810182905261210c9085906323b872dd60e01b906084016124da565b8015806125c35750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801561259d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c19190612ce3565b155b61262e5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840161067b565b6040516001600160a01b0383166024820152604481018290526111eb90849063095ea7b360e01b906064016124da565b6000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561269e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c2919061309e565b6126cd90600a6131a5565b6126df83670de0b6b3a7640000612f2e565b6126e99190612f4d565b9392505050565b6001600160a01b0382166127465760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161067b565b80600260008282546127589190613035565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6000612804826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166128849092919063ffffffff16565b905080516000148061282557508080602001905181019061282591906131b4565b6111eb5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161067b565b6060612893848460008561289b565b949350505050565b6060824710156128fc5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161067b565b600080866001600160a01b0316858760405161291891906131d1565b60006040518083038185875af1925050503d8060008114612955576040519150601f19603f3d011682016040523d82523d6000602084013e61295a565b606091505b509150915061296b87838387612976565b979650505050505050565b606083156129e55782516000036129de576001600160a01b0385163b6129de5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161067b565b5081612893565b61289383838151156129fa5781518083602001fd5b8060405162461bcd60e51b815260040161067b9190612a40565b60005b83811015612a2f578181015183820152602001612a17565b8381111561210c5750506000910152565b6020815260008251806020840152612a5f816040850160208701612a14565b601f01601f19169190910160400192915050565b6001600160a01b0381168114610d6757600080fd5b60008060408385031215612a9b57600080fd5b8235612aa681612a73565b946020939093013593505050565b600080600080600060808688031215612acc57600080fd5b8535612ad781612a73565b94506020860135612ae781612a73565b935060408601359250606086013567ffffffffffffffff80821115612b0b57600080fd5b818801915088601f830112612b1f57600080fd5b813581811115612b2e57600080fd5b896020828501011115612b4057600080fd5b9699959850939650602001949392505050565b600060208284031215612b6557600080fd5b81356126e981612a73565b600080600060608486031215612b8557600080fd5b8335612b9081612a73565b92506020840135612ba081612a73565b929592945050506040919091013590565b600060208284031215612bc357600080fd5b5035919050565b6001600160801b0381168114610d6757600080fd5b600080600060608486031215612bf457600080fd5b833592506020840135612c0681612bca565b91506040840135612c1681612bca565b809150509250925092565b8015158114610d6757600080fd5b600060208284031215612c4157600080fd5b81356126e981612c21565b60008060408385031215612c5f57600080fd5b8235612c6a81612a73565b91506020830135612c7a81612bca565b809150509250929050565b600080600060608486031215612c9a57600080fd5b8335612ca581612a73565b92506020840135612c0681612bca565b60008060408385031215612cc857600080fd5b8235612cd381612a73565b91506020830135612c7a81612a73565b600060208284031215612cf557600080fd5b5051919050565b600181811c90821680612d1057607f821691505b602082108103612d3057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715612d6f57612d6f612d36565b60405290565b6040805190810167ffffffffffffffff81118282101715612d6f57612d6f612d36565b805167ffffffffffffffff81168114612db057600080fd5b919050565b600082601f830112612dc657600080fd5b612dce612d75565b80610100840185811115612de157600080fd5b845b81811015612e555760808188031215612dfc5760008081fd5b612e04612d4c565b8151612e0f81612bca565b8152602082810151612e2081612bca565b828201526040612e31848201612d98565b908301526060612e42848201612d98565b9083015290855290930192608001612de3565b509095945050505050565b60006101808284031215612e7357600080fd5b612e7b612d4c565b82518152602080840151612e8e81612a73565b82820152605f84018513612ea157600080fd5b612ea9612d75565b806080860187811115612ebb57600080fd5b604087015b81811015612ee0578051612ed381612a73565b8452928401928401612ec0565b50816040860152612ef18882612db5565b606086015250929695505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615612f4857612f48612f18565b500290565b600082612f6a57634e487b7160e01b600052601260045260246000fd5b500490565b600082821015612f8157612f81612f18565b500390565b60006001600160801b0383811690831681811015612fa657612fa6612f18565b039392505050565b8060005b600281101561210c57815180516001600160801b0390811686526020808301519091168187015260408083015167ffffffffffffffff90811691880191909152606092830151169186019190915260809094019390910190600101612fb2565b83815261022081016130276020830185612fae565b612893610120830184612fae565b6000821982111561304857613048612f18565b500190565b6001600160a01b0384811682528316602082015261014081016128936040830184612fae565b60006001600160801b0380831681851680830382111561309557613095612f18565b01949350505050565b6000602082840312156130b057600080fd5b815160ff811681146126e957600080fd5b600181815b808511156130fc5781600019048211156130e2576130e2612f18565b808516156130ef57918102915b93841c93908002906130c6565b509250929050565b60008261311357506001610615565b8161312057506000610615565b816001811461313657600281146131405761315c565b6001915050610615565b60ff84111561315157613151612f18565b50506001821b610615565b5060208310610133831016604e8410600b841016171561317f575081810a610615565b61318983836130c1565b806000190482111561319d5761319d612f18565b029392505050565b60006126e960ff841683613104565b6000602082840312156131c657600080fd5b81516126e981612c21565b600082516131e3818460208701612a14565b919091019291505056fea264697066735822122018c675e2d28363563882fef05d6e2cee7860043fb4aa5affc08259bd54fcf2ac64736f6c634300080d0033a2646970667358221220a1125db0254c2f7e64ba27cb6aca02eb8c8eceda76a8e832c6fe1250b8e2545d64736f6c634300080d0033000000000000000000000000f37102e11e06276ac9d393277bd7b63b3393b361000000000000000000000000c9ea7a2337f27935cd3ccfb2f725b0428e731fbf0000000000000000000000003b91ca4d89b5156d456cbd0d6305f7f36b1517a4
Deployed Bytecode
0x60806040523480156200001157600080fd5b5060043610620001155760003560e01c80638da5cb5b11620000a3578063d9164817116200006e578063d9164817146200024f578063e5e31b131462000286578063f1e6c40614620002ac578063f2fde38b14620002c357600080fd5b80638da5cb5b14620001cc578063a1e1fdac14620001de578063ab87f2fd1462000221578063ced78e25146200023857600080fd5b8063567fd09e11620000e4578063567fd09e146200018f578063574f2ba314620001995780636ff1c9bc14620001ab578063715018a614620001c257600080fd5b80630362158f146200011a5780630850ad99146200014b5780631e3dd18b146200016457806346c96aac146200017b575b600080fd5b6001546200012e906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b620001626200015c36600462001157565b620002da565b005b6200012e620001753660046200117e565b620003c5565b6002546200012e906001600160a01b031681565b62000162620003f0565b60035460405190815260200162000142565b62000162620001bc36600462001157565b6200044b565b6200016262000561565b6000546001600160a01b03166200012e565b620001f5620001ef3660046200117e565b62000579565b604080516001600160a01b03958616815294909316602085015291830152606082015260800162000142565b620001626200023236600462001157565b62000628565b6200012e620002493660046200117e565b6200068e565b620002756200026036600462001157565b60056020526000908152604090205460ff1681565b604051901515815260200162000142565b620002756200029736600462001157565b60046020526000908152604090205460ff1681565b62000162620002bd36600462001157565b62000b8b565b62000162620002d436600462001157565b62000bf4565b620002e462000c73565b6001600160a01b03811660009081526005602052604090205460ff16156200034a5760405162461bcd60e51b815260206004820152601460248201527332bc34b9ba34b7339031b0b93137b7103830b4b960611b60448201526064015b60405180910390fd5b6003805460018181019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b039093166001600160a01b0319909316831790556000918252600560209081526040808420805460ff19908116851790915560049092529092208054909216179055565b60038181548110620003d657600080fd5b6000918252602090912001546001600160a01b0316905081565b620003fa62000c73565b60065460ff166200043f5760405162461bcd60e51b815260206004820152600e60248201526d6e6f74206265746120706861736560901b604482015260640162000341565b6006805460ff19169055565b6200045562000c73565b60065460ff166200049a5760405162461bcd60e51b815260206004820152600e60248201526d6e6f74206265746120706861736560901b604482015260640162000341565b6001600160a01b03811660009081526005602052604090205460ff16620004d55760405162461bcd60e51b8152600401620003419062001198565b6001600160a01b0381166000818152600560209081526040808320805460ff199081169091556004928390529281902080549093169092559051631bfc726f60e21b81523391810191909152636ff1c9bc90602401600060405180830381600087803b1580156200054557600080fd5b505af11580156200055a573d6000803e3d6000fd5b5050505050565b6200056b62000c73565b62000577600062000ccf565b565b600154604051632f2235f960e21b81526004810183905260009182918291829182916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015620005cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005f3919062001319565b604081015180516020918201516060909301518051519201515190999298506001600160801b03918216975016945092505050565b6200063262000c73565b6001600160a01b03811660009081526005602052604090205460ff166200066d5760405162461bcd60e51b8152600401620003419062001198565b6001600160a01b03166000908152600460205260409020805460ff19169055565b6000806000806000620006a18662000579565b93509350935093506000846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620006ea573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620007149190810190620013f9565b846001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000753573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200077d9190810190620013f9565b60405160200162000790929190620014a7565b60405160208183030381529060405290506000856001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620007e2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200080c9190810190620013f9565b856001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156200084b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620008759190810190620013f9565b6040516020016200088892919062001510565b60408051601f1981840301815290829052600154600254919350600092859285926001600160a01b0390811692911690620008c39062001133565b620008d294939291906200158d565b604051809103906000f080158015620008ef573d6000803e3d6000fd5b50905084156200091457620009078733308862000d1f565b6200091487828762000d92565b83156200093657620009298633308762000d1f565b6200093686828662000d92565b604051630ad374dd60e41b8152600481018a90526001600160a01b0382169063ad374dd090602401600060405180830381600087803b1580156200097957600080fd5b505af11580156200098e573d6000803e3d6000fd5b50506003805460018082019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b03861690811790915560008181526005602052604090819020805460ff191690931790925590516370a0823160e01b815230600482015284935090915063a9059cbb90339083906370a0823190602401602060405180830381865afa15801562000a3f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a659190620015db565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af115801562000ab1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ad79190620015f5565b50816001600160a01b031663492f4e186040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000b17573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b3d9190620015db565b604080518c81526001600160a01b03841660208201527ff7ee1758a8519d7fe72714f8cfd41d75d71255250aa858f78cb859f6f3c78232910160405180910390a29998505050505050505050565b62000b9562000c73565b6001600160a01b03811660009081526005602052604090205460ff1662000bd05760405162461bcd60e51b8152600401620003419062001198565b6001600160a01b03166000908152600460205260409020805460ff19166001179055565b62000bfe62000c73565b6001600160a01b03811662000c655760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000341565b62000c708162000ccf565b50565b6000546001600160a01b03163314620005775760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000341565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038085166024830152831660448201526064810182905262000d8c9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915262000eb4565b50505050565b80158062000e105750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801562000de8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e0e9190620015db565b155b62000e7d5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840162000341565b6040516001600160a01b03831660248201526044810182905262000eaf90849063095ea7b360e01b9060640162000d54565b505050565b600062000f0b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031662000f909092919063ffffffff16565b905080516000148062000f2f57508080602001905181019062000f2f9190620015f5565b62000eaf5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000341565b606062000fa1848460008562000fa9565b949350505050565b6060824710156200100c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000341565b600080866001600160a01b031685876040516200102a919062001619565b60006040518083038185875af1925050503d806000811462001069576040519150601f19603f3d011682016040523d82523d6000602084013e6200106e565b606091505b509150915062001081878383876200108c565b979650505050505050565b6060831562001100578251600003620010f8576001600160a01b0385163b620010f85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000341565b508162000fa1565b62000fa18383815115620011175781518083602001fd5b8060405162461bcd60e51b815260040162000341919062001637565b613551806200164d83390190565b6001600160a01b038116811462000c7057600080fd5b6000602082840312156200116a57600080fd5b8135620011778162001141565b9392505050565b6000602082840312156200119157600080fd5b5035919050565b6020808252601190820152703737ba10309031b0b93137b7103830b4b960791b604082015260600190565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715620011ff57620011ff620011c3565b60405290565b6040805190810167ffffffffffffffff81118282101715620011ff57620011ff620011c3565b80516001600160801b03811681146200124357600080fd5b919050565b805167ffffffffffffffff811681146200124357600080fd5b600082601f8301126200127357600080fd5b6200127d62001205565b806101008401858111156200129157600080fd5b845b818110156200130e5760808188031215620012ae5760008081fd5b620012b8620011d9565b620012c3826200122b565b81526020620012d48184016200122b565b818301526040620012e781850162001248565b908301526060620012fa84820162001248565b908301529085529093019260800162001293565b509095945050505050565b600061018082840312156200132d57600080fd5b62001337620011d9565b825181526020808401516200134c8162001141565b82820152605f840185136200136057600080fd5b6200136a62001205565b8060808601878111156200137d57600080fd5b604087015b81811015620013a6578051620013988162001141565b845292840192840162001382565b50816040860152620013b9888262001261565b606086015250929695505050505050565b60005b83811015620013e7578181015183820152602001620013cd565b8381111562000d8c5750506000910152565b6000602082840312156200140c57600080fd5b815167ffffffffffffffff808211156200142557600080fd5b818401915084601f8301126200143a57600080fd5b8151818111156200144f576200144f620011c3565b604051601f8201601f19908116603f011681019083821181831017156200147a576200147a620011c3565b816040528281528760208487010111156200149457600080fd5b62001081836020830160208801620013ca565b7f436f6e63656e74726174656420204c6971756964697479202d20000000000000815260008351620014e181601a850160208801620013ca565b602f60f81b601a9184019182015283516200150481601b840160208801620013ca565b01601b01949350505050565b62434c2d60e81b81526000835162001530816003850160208801620013ca565b602f60f81b600391840191820152835162001553816004840160208801620013ca565b01600401949350505050565b6000815180845262001579816020860160208601620013ca565b601f01601f19169290920160200192915050565b608081526000620015a260808301876200155f565b8281036020840152620015b681876200155f565b6001600160a01b03958616604085015293909416606090920191909152509392505050565b600060208284031215620015ee57600080fd5b5051919050565b6000602082840312156200160857600080fd5b815180151581146200117757600080fd5b600082516200162d818460208701620013ca565b9190910192915050565b6020815260006200117760208301846200155f56fe60a06040523480156200001157600080fd5b506040516200355138038062003551833981016040819052620000349162000240565b8351849084906200004d906003906020850190620000b0565b50805162000063906004906020840190620000b0565b5050600160055550600780546001600160a01b039384166001600160a01b03199182161790915560088054929093169116179055505033608052600b805460ff60a01b191690556200030b565b828054620000be90620002cf565b90600052602060002090601f016020900481019282620000e257600085556200012d565b82601f10620000fd57805160ff19168380011785556200012d565b828001600101855582156200012d579182015b828111156200012d57825182559160200191906001019062000110565b506200013b9291506200013f565b5090565b5b808211156200013b576000815560010162000140565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200017e57600080fd5b81516001600160401b03808211156200019b576200019b62000156565b604051601f8301601f19908116603f01168101908282118183101715620001c657620001c662000156565b81604052838152602092508683858801011115620001e357600080fd5b600091505b83821015620002075785820183015181830184015290820190620001e8565b83821115620002195760008385830101525b9695505050505050565b80516001600160a01b03811681146200023b57600080fd5b919050565b600080600080608085870312156200025757600080fd5b84516001600160401b03808211156200026f57600080fd5b6200027d888389016200016c565b955060208701519150808211156200029457600080fd5b50620002a3878288016200016c565b935050620002b46040860162000223565b9150620002c46060860162000223565b905092959194509250565b600181811c90821680620002e457607f821691505b6020821081036200030557634e487b7160e01b600052602260045260246000fd5b50919050565b6080516132236200032e6000396000818161049901526110d501526132236000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c80636ff1c9bc1161011a578063ad374dd0116100ad578063c45a01551161007c578063c45a015514610494578063c8eaac0b146104bb578063d21220a7146104c3578063dd62ed3e146104d6578063e455dea8146104e957600080fd5b8063ad374dd014610448578063b22d8fe01461045b578063c3df46d81461046e578063c3fbc5ef1461048157600080fd5b80639f118536116100e95780639f11853614610406578063a0f821711461041a578063a457c2d714610422578063a9059cbb1461043557600080fd5b80636ff1c9bc146103ae57806370a08231146103c157806391f36d65146103ea57806395d89b41146103fe57600080fd5b806323b872dd1161019d578063395093511161016c578063395093511461035957806345a1de791461036c57806346c96aac1461037f578063492f4e18146103925780634a65f70b1461039b57600080fd5b806323b872dd146102f15780632644b97b146103045780632e1a7d4d14610337578063313ce5671461034a57600080fd5b80630dfe1681116101d95780630dfe168114610289578063150b7a021461029c57806318160ddd146102d457806319999566146102dc57600080fd5b80630134e0f41461020b5780630362158f1461022657806306fdde0314610251578063095ea7b314610266575b600080fd5b6102136104fc565b6040519081526020015b60405180910390f35b600754610239906001600160a01b031681565b6040516001600160a01b03909116815260200161021d565b61025961056f565b60405161021d9190612a40565b610279610274366004612a88565b610601565b604051901515815260200161021d565b600a54610239906001600160a01b031681565b6102bb6102aa366004612ab4565b630a85bd0160e11b95945050505050565b6040516001600160e01b0319909116815260200161021d565b600254610213565b6102ef6102ea366004612b53565b61061b565b005b6102796102ff366004612b70565b6106ce565b61030c6106f2565b604080516001600160a01b03958616815294909316602085015291830152606082015260800161021d565b6102ef610345366004612bb1565b6107a1565b6040516012815260200161021d565b610279610367366004612a88565b610d6a565b600954610239906001600160a01b031681565b600854610239906001600160a01b031681565b61021360065481565b6102ef6103a9366004612bdf565b610d8c565b6102ef6103bc366004612b53565b6110ca565b6102136103cf366004612b53565b6001600160a01b031660009081526020819052604090205490565b60095461027990600160a01b900460ff1681565b6102596111f0565b600b5461027990600160a01b900460ff1681565b6102796111ff565b610279610430366004612a88565b6112b4565b610279610443366004612a88565b61132f565b6102ef610456366004612bb1565b61133d565b6102ef610469366004612c2f565b6115d7565b61021361047c366004612c4c565b611689565b6102ef61048f366004612c85565b6117e6565b6102397f000000000000000000000000000000000000000000000000000000000000000081565b610213611e34565b600b54610239906001600160a01b031681565b6102136104e4366004612cb5565b611e65565b61030c6104f7366004612bb1565b611e90565b600b546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a08231906024015b602060405180830381865afa158015610546573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056a9190612ce3565b905090565b60606003805461057e90612cfc565b80601f01602080910402602001604051908101604052809291908181526020018280546105aa90612cfc565b80156105f75780601f106105cc576101008083540402835291602001916105f7565b820191906000526020600020905b8154815290600101906020018083116105da57829003601f168201915b5050505050905090565b60003361060f818585611f74565b60019150505b92915050565b6008546001600160a01b031633146106845760405162461bcd60e51b815260206004820152602160248201527f4f6e6c7920766f7465722063616e207365742065787465726e616c20627269626044820152606560f81b60648201526084015b60405180910390fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040517f03e9b76bf8c2d2d6948b20459194f64843d25ada1a13e3481bf88399831a046190600090a250565b6000336106dc858285612098565b6106e7858585612112565b506001949350505050565b600754600654604051632f2235f960e21b8152600481019190915260009182918291829182916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015610749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076d9190612e60565b604081015180516020918201516060909301518051519201515190989297506001600160801b039182169650169350915050565b6107a96122b6565b600081116107e85760405162461bcd60e51b815260206004820152600c60248201526b05f736861726573203d3d20360a41b604482015260640161067b565b600754600654604051632f2235f960e21b815260048101919091526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015610837573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085b9190612e60565b9050600061089d61086b60025490565b6060840151859060005b60200201515161088e91906001600160801b0316612f2e565b6108989190612f4d565b61230f565b905060006108bb6108ad60025490565b606085015186906001610875565b90506108c7338561237c565b6000826001600160801b031611806108e857506000816001600160801b0316115b6109245760405162461bcd60e51b815260206004820152600d60248201526c3020746f20776974686472617760981b604482015260640161067b565b6040805160808101825260008082526020820181905291810182905260608101919091526001600160801b038316156109ff57606084810180515160409081015167ffffffffffffffff9081169185019190915281515183015116918301919091525180518051602091909101516109cf926001600160801b03928316929182169187169060005b6020020151516109c591906001600160801b0316612f6f565b61088e9190612f2e565b6001600160801b03166020820152606084015151516109ef908490612f86565b6001600160801b03168152610a51565b606084810180515160409081015167ffffffffffffffff9081169185019190915281515183015116918301919091528051516020908101516001600160801b0390811691840191909152905151511681525b6040805160808101825260008082526020820181905291810182905260608101919091526001600160801b03831615610b1a576060858101805160209081015160409081015167ffffffffffffffff908116918601919091528251820151840151169284019290925251808201518051920151610ae3926001600160801b0390811692918116919087169060016109ac565b6001600160801b03166020820152606085015183906001602002015151610b0a9190612f86565b6001600160801b03168152610b72565b6060858101805160209081015160409081015167ffffffffffffffff908116918601919091528251820151840151169284019290925280518201518201516001600160801b0390811684840152905190910151511681525b836001600160801b0316600003610bd5576060850151610bc69060016020020151602001516001600160801b031683602001516001600160801b031683602001516001600160801b031661088e9190612f2e565b6001600160801b031660208301525b826001600160801b0316600003610c38576060850151610c299060006020020151602001516001600160801b031682602001516001600160801b031684602001516001600160801b031661088e9190612f2e565b6001600160801b031660208201525b60075460065460608701516040805180820182528681526020810186905290516321589fa160e01b81526001600160a01b03909416936321589fa193610c849390929091600401613012565b600060405180830381600087803b158015610c9e57600080fd5b505af1158015610cb2573d6000803e3d6000fd5b505050506001600160801b03841615610cdf57604085015151610cdf90336001600160801b0387166124ae565b6001600160801b03831615610d0b57604085015160200151610d0b90336001600160801b0386166124ae565b604080516001600160801b0380871682528516602082015290810187905233907f743033787f4738ff4d6a7225ce2bd0977ee5f86b91a902a58f5e4d0b297b46449060600160405180910390a25050505050610d676001600555565b50565b60003361060f818585610d7d8383611e65565b610d879190613035565b611f74565b600b54600160a01b900460ff1615610dd65760405162461bcd60e51b815260206004820152600d60248201526c1d985d5b1d081cdd185c9d1959609a1b604482015260640161067b565b6000826001600160801b03161180610df757506000816001600160801b0316115b610e375760405162461bcd60e51b81526020600482015260116024820152700616d6f756e74546f6b656e73203d3d203607c1b604482015260640161067b565b600754604051632f2235f960e21b8152600481018590526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015610e82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea69190612e60565b60408101518051600a80546001600160a01b03199081166001600160a01b0393841617909155602090920151600b8054909316911617905590506001600160801b03831615610f1057600a54610f10906001600160a01b031633306001600160801b038716612511565b6001600160801b03821615610f4057600b54610f40906001600160a01b031633306001600160801b038616612511565b606081015180516020918201516001600160801b0386811680845283850181905290861680835293820193909352600a5460075492939192610f91926001600160a01b039283169290911690612549565b600b54600754610fb7916001600160a01b0390811691166001600160801b038716612549565b6007546040848101518051602091820151835180850185528781529283018690529251637b93a39d60e11b81526001600160a01b039094169363f727473a9361100493909160040161304d565b6020604051808303816000875af1158015611023573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110479190612ce3565b60065560006001600160801b038086169087161161108357600b5461107e906001600160a01b03166001600160801b03871661265e565b6110a2565b600a546110a2906001600160a01b03166001600160801b03881661265e565b90506110ae33826126f0565b5050600b805460ff60a01b1916600160a01b1790555050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146111325760405162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015260640161067b565b600754600654604051638730203760e01b81526001600160a01b03909216916387302037916111679160040190815260200190565b600060405180830381600087803b15801561118157600080fd5b505af1158015611195573d6000803e3d6000fd5b5050505060006111a3611e34565b905060006111af6104fc565b905081156111ce57600a546111ce906001600160a01b031684846124ae565b80156111eb57600b546111eb906001600160a01b031684836124ae565b505050565b60606004805461057e90612cfc565b600754600654604051632f2235f960e21b815260009283926001600160a01b039091169163bc88d7e4916112399160040190815260200190565b61018060405180830381865afa158015611257573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127b9190612e60565b606081015151519091506001600160801b0316158015906112ad5750606081015160200151516001600160801b031615155b1591505090565b600033816112c28286611e65565b9050838110156113225760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161067b565b6106e78286868403611f74565b60003361060f818585612112565b600b54600160a01b900460ff16156113875760405162461bcd60e51b815260206004820152600d60248201526c1d985d5b1d081cdd185c9d1959609a1b604482015260640161067b565b600754604051632f2235f960e21b8152600481018390526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa1580156113d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f69190612e60565b60408101518051600a80546001600160a01b039283166001600160a01b031991821617909155602092830151600b8054919093169116179055606082015180519101518151815193945091929091906001600160801b0382161561147557600a54611475906001600160a01b031633306001600160801b038616612511565b6001600160801b038116156114a557600b546114a5906001600160a01b031633306001600160801b038516612511565b600a546007546114cb916001600160a01b0390811691166001600160801b038516612549565b600b546007546114f1916001600160a01b0390811691166001600160801b038416612549565b6007546040868101518051602091820151835180850185528981529283018890529251637b93a39d60e11b81526001600160a01b039094169363f727473a9361153e93909160040161304d565b6020604051808303816000875af115801561155d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115819190612ce3565b60065560006001600160801b03808316908416116115b857600b5461107e906001600160a01b03166001600160801b03841661265e565b600a546110a2906001600160a01b03166001600160801b03851661265e565b6008546001600160a01b031633146116315760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c7920766f7465722063616e207365742068617320676175676500000000604482015260640161067b565b60098054821515600160a01b0260ff60a01b199091161790556040517f352eb552c369d470b6f2286567a9f272a1210ad788562e697f254cad5611f1059061167e90831515815260200190565b60405180910390a150565b600754600654604051632f2235f960e21b815260009283926001600160a01b039091169163bc88d7e4916116c39160040190815260200190565b61018060405180830381865afa1580156116e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117059190612e60565b90506000846001600160a01b0316826040015160006002811061172a5761172a612f02565b60200201516001600160a01b031614905060008161174d57604083015151611757565b6040830151602001515b905060008261176e57606084015160200151611775565b6060840151515b905060008361178957606085015151611793565b6060850151602001515b82519091506001600160801b03166000036117af5760006117d1565b815181516117d1916001600160801b039081169161088e918b81169116612f2e565b6001600160801b031698975050505050505050565b6117ee6122b6565b6006546000036118345760405162461bcd60e51b81526020600482015260116024820152701d985d5b1d081b9bdd081cdd185c9d1959607a1b604482015260640161067b565b600a546001600160a01b038481169116148061185d5750600b546001600160a01b038481169116145b6118b85760405162461bcd60e51b815260206004820152602660248201527f6465706f73697420746f6b656e206973206e6f742070617274206f6620746865604482015265081d985d5b1d60d21b606482015260840161067b565b6000826001600160801b0316116119005760405162461bcd60e51b815260206004820152600c60248201526b05f616d6f756e74203d3d20360a41b604482015260640161067b565b611915833330856001600160801b0316612511565b600754600654604051632f2235f960e21b815260048101919091526000916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015611964573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119889190612e60565b90506000846001600160a01b031682604001516000600281106119ad576119ad612f02565b60200201516001600160a01b03161490506000816119d0576040830151516119da565b6040830151602001515b90506000826119f1576060840151602001516119f8565b6060840151515b9050600083611a0c57606085015151611a16565b6060850151602001515b805183519192506001600160801b03908116911611611a8c5760405162461bcd60e51b815260206004820152602c60248201527f796f75206e65656420746f20757365206f7468657220746f6b656e206173206460448201526b32b837b9b4ba103a37b5b2b760a11b606482015260840161067b565b81516001600160801b031615801590611aae575080516001600160801b031615155b611ae95760405162461bcd60e51b815260206004820152600c60248201526b6f7574206f662072616e676560a01b604482015260640161067b565b6000611b1e83600001516001600160801b0316896001600160801b031684600001516001600160801b031661088e9190612f2e565b9050866001600160801b0316816001600160801b03161115611b535760405163428637bb60e11b815260040160405180910390fd5b6001600160801b03811615611b9857611b77843330846001600160801b0316612511565b600754611b989085906001600160a01b03166001600160801b038416612549565b600083600001516001600160801b0316896001600160801b0316611bbb60025490565b611bc59190612f2e565b611bcf9190612f4d565b9050611bfb60408051608081018252600080825260208201819052918101829052606081019190915290565b60408086015167ffffffffffffffff908116918301919091526060808701519091169082015284516020860151611c47916001600160801b03908116918116906109c5908e1683613035565b6001600160801b031660208201528451611c62908b90613073565b6001600160801b03908116825260408051608081018252600080825260208083018290528284018281526060808501938452948a015167ffffffffffffffff9081169091529389015190931690528651918701519092611cce928116918116906109c590881683613035565b6001600160801b031660208201528451611ce9908590613073565b6001600160801b0316815260008089611d03578284611d06565b83835b91509150611d338e600760009054906101000a90046001600160a01b03168f6001600160801b0316612549565b60075460065460608d01516040805180820182528681526020810186905290516321589fa160e01b81526001600160a01b03909416936321589fa193611d7f9390929091600401613012565b600060405180830381600087803b158015611d9957600080fd5b505af1158015611dad573d6000803e3d6000fd5b50505050611dbb33866126f0565b336001600160a01b03167fb4c03061fb5b7fed76389d5af8f2e0ddb09f8c70d1333abbb62582835e10accb8e8888604051611e17939291906001600160801b039384168152919092166020820152604081019190915260600190565b60405180910390a250505050505050505050506111eb6001600555565b600a546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401610529565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600754600654604051632f2235f960e21b8152600481019190915260009182918291829182916001600160a01b03169063bc88d7e49060240161018060405180830381865afa158015611ee7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f0b9190612e60565b90506000611f29611f1b60025490565b606084015189906000610875565b90506000611f47611f3960025490565b60608501518a906001610875565b60409390930151805160209091015190999098506001600160801b03928316975091909216945092505050565b6001600160a01b038316611fd65760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161067b565b6001600160a01b0382166120375760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161067b565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006120a48484611e65565b9050600019811461210c57818110156120ff5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161067b565b61210c8484848403611f74565b50505050565b6001600160a01b0383166121765760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161067b565b6001600160a01b0382166121d85760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161067b565b6001600160a01b038316600090815260208190526040902054818110156122505760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161067b565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a361210c565b6002600554036123085760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161067b565b6002600555565b60006001600160801b038211156123785760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b606482015260840161067b565b5090565b6001600160a01b0382166123dc5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161067b565b6001600160a01b038216600090815260208190526040902054818110156124505760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161067b565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6040516001600160a01b0383166024820152604481018290526111eb90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526127af565b6040516001600160a01b038085166024830152831660448201526064810182905261210c9085906323b872dd60e01b906084016124da565b8015806125c35750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801561259d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c19190612ce3565b155b61262e5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840161067b565b6040516001600160a01b0383166024820152604481018290526111eb90849063095ea7b360e01b906064016124da565b6000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561269e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c2919061309e565b6126cd90600a6131a5565b6126df83670de0b6b3a7640000612f2e565b6126e99190612f4d565b9392505050565b6001600160a01b0382166127465760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161067b565b80600260008282546127589190613035565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6000612804826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166128849092919063ffffffff16565b905080516000148061282557508080602001905181019061282591906131b4565b6111eb5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161067b565b6060612893848460008561289b565b949350505050565b6060824710156128fc5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161067b565b600080866001600160a01b0316858760405161291891906131d1565b60006040518083038185875af1925050503d8060008114612955576040519150601f19603f3d011682016040523d82523d6000602084013e61295a565b606091505b509150915061296b87838387612976565b979650505050505050565b606083156129e55782516000036129de576001600160a01b0385163b6129de5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161067b565b5081612893565b61289383838151156129fa5781518083602001fd5b8060405162461bcd60e51b815260040161067b9190612a40565b60005b83811015612a2f578181015183820152602001612a17565b8381111561210c5750506000910152565b6020815260008251806020840152612a5f816040850160208701612a14565b601f01601f19169190910160400192915050565b6001600160a01b0381168114610d6757600080fd5b60008060408385031215612a9b57600080fd5b8235612aa681612a73565b946020939093013593505050565b600080600080600060808688031215612acc57600080fd5b8535612ad781612a73565b94506020860135612ae781612a73565b935060408601359250606086013567ffffffffffffffff80821115612b0b57600080fd5b818801915088601f830112612b1f57600080fd5b813581811115612b2e57600080fd5b896020828501011115612b4057600080fd5b9699959850939650602001949392505050565b600060208284031215612b6557600080fd5b81356126e981612a73565b600080600060608486031215612b8557600080fd5b8335612b9081612a73565b92506020840135612ba081612a73565b929592945050506040919091013590565b600060208284031215612bc357600080fd5b5035919050565b6001600160801b0381168114610d6757600080fd5b600080600060608486031215612bf457600080fd5b833592506020840135612c0681612bca565b91506040840135612c1681612bca565b809150509250925092565b8015158114610d6757600080fd5b600060208284031215612c4157600080fd5b81356126e981612c21565b60008060408385031215612c5f57600080fd5b8235612c6a81612a73565b91506020830135612c7a81612bca565b809150509250929050565b600080600060608486031215612c9a57600080fd5b8335612ca581612a73565b92506020840135612c0681612bca565b60008060408385031215612cc857600080fd5b8235612cd381612a73565b91506020830135612c7a81612a73565b600060208284031215612cf557600080fd5b5051919050565b600181811c90821680612d1057607f821691505b602082108103612d3057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715612d6f57612d6f612d36565b60405290565b6040805190810167ffffffffffffffff81118282101715612d6f57612d6f612d36565b805167ffffffffffffffff81168114612db057600080fd5b919050565b600082601f830112612dc657600080fd5b612dce612d75565b80610100840185811115612de157600080fd5b845b81811015612e555760808188031215612dfc5760008081fd5b612e04612d4c565b8151612e0f81612bca565b8152602082810151612e2081612bca565b828201526040612e31848201612d98565b908301526060612e42848201612d98565b9083015290855290930192608001612de3565b509095945050505050565b60006101808284031215612e7357600080fd5b612e7b612d4c565b82518152602080840151612e8e81612a73565b82820152605f84018513612ea157600080fd5b612ea9612d75565b806080860187811115612ebb57600080fd5b604087015b81811015612ee0578051612ed381612a73565b8452928401928401612ec0565b50816040860152612ef18882612db5565b606086015250929695505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615612f4857612f48612f18565b500290565b600082612f6a57634e487b7160e01b600052601260045260246000fd5b500490565b600082821015612f8157612f81612f18565b500390565b60006001600160801b0383811690831681811015612fa657612fa6612f18565b039392505050565b8060005b600281101561210c57815180516001600160801b0390811686526020808301519091168187015260408083015167ffffffffffffffff90811691880191909152606092830151169186019190915260809094019390910190600101612fb2565b83815261022081016130276020830185612fae565b612893610120830184612fae565b6000821982111561304857613048612f18565b500190565b6001600160a01b0384811682528316602082015261014081016128936040830184612fae565b60006001600160801b0380831681851680830382111561309557613095612f18565b01949350505050565b6000602082840312156130b057600080fd5b815160ff811681146126e957600080fd5b600181815b808511156130fc5781600019048211156130e2576130e2612f18565b808516156130ef57918102915b93841c93908002906130c6565b509250929050565b60008261311357506001610615565b8161312057506000610615565b816001811461313657600281146131405761315c565b6001915050610615565b60ff84111561315157613151612f18565b50506001821b610615565b5060208310610133831016604e8410600b841016171561317f575081810a610615565b61318983836130c1565b806000190482111561319d5761319d612f18565b029392505050565b60006126e960ff841683613104565b6000602082840312156131c657600080fd5b81516126e981612c21565b600082516131e3818460208701612a14565b919091019291505056fea264697066735822122018c675e2d28363563882fef05d6e2cee7860043fb4aa5affc08259bd54fcf2ac64736f6c634300080d0033a2646970667358221220a1125db0254c2f7e64ba27cb6aca02eb8c8eceda76a8e832c6fe1250b8e2545d64736f6c634300080d0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f37102e11e06276ac9d393277bd7b63b3393b361000000000000000000000000c9ea7a2337f27935cd3ccfb2f725b0428e731fbf0000000000000000000000003b91ca4d89b5156d456cbd0d6305f7f36b1517a4
-----Decoded View---------------
Arg [0] : _carbonController (address): 0xf37102e11E06276ac9D393277BD7b63b3393b361
Arg [1] : _voter (address): 0xc9Ea7A2337f27935Cd3ccFB2f725B0428e731FBF
Arg [2] : _team (address): 0x3b91Ca4D89B5156d456CbD0D6305F7f36B1517a4
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000f37102e11e06276ac9d393277bd7b63b3393b361
Arg [1] : 000000000000000000000000c9ea7a2337f27935cd3ccfb2f725b0428e731fbf
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 | 35 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.