Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
21476837 | 37 days ago | 0.00040959 ETH | ||||
21476837 | 37 days ago | 0.00040959 ETH | ||||
21476837 | 37 days ago | 0.01479825 ETH | ||||
21476837 | 37 days ago | 0.01479825 ETH | ||||
21105390 | 89 days ago | 0.0005123 ETH | ||||
21105390 | 89 days ago | 0.0005123 ETH | ||||
21105390 | 89 days ago | 0.02097932 ETH | ||||
21105390 | 89 days ago | 0.02097932 ETH | ||||
21079661 | 93 days ago | 0.00055133 ETH | ||||
21079661 | 93 days ago | 0.00055133 ETH | ||||
21079661 | 93 days ago | 0.01924201 ETH | ||||
21079661 | 93 days ago | 0.01924201 ETH | ||||
21079656 | 93 days ago | 0.01924201 ETH | ||||
21079652 | 93 days ago | 0.00055196 ETH | ||||
21079652 | 93 days ago | 0.00055196 ETH | ||||
21079652 | 93 days ago | 0.01924201 ETH | ||||
21079652 | 93 days ago | 0.01924201 ETH | ||||
21079644 | 93 days ago | 0.00055445 ETH | ||||
21079644 | 93 days ago | 0.00055445 ETH | ||||
21079644 | 93 days ago | 0.01924201 ETH | ||||
21079644 | 93 days ago | 0.01924201 ETH | ||||
21079635 | 93 days ago | 0.00055448 ETH | ||||
21079635 | 93 days ago | 0.00055448 ETH | ||||
21079635 | 93 days ago | 0.01924201 ETH | ||||
21079635 | 93 days ago | 0.01924201 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
PaymentModuleV1
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.4; import { AccessControlEnumerable } from "@openzeppelin/contracts/access/AccessControlEnumerable.sol"; import { IERC1155 } from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import { IERC721Receiver } from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import { IUniswapV2Pair } from "@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol"; import { IUniswapV2Router02 } from "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol"; import { IDepositHandler } from "../interfaces/IDepositHandler.sol"; import { ILPTokenProcessorV2 } from "../interfaces/ILPTokenProcessorV2.sol"; import { IPaymentModule } from "../interfaces/IPaymentModule.sol"; import { IPricingModule } from "../interfaces/IPricingModule.sol"; import { INonfungiblePositionManager } from "../../common/interfaces/INonfungiblePositionManager.sol"; import { IPriceOracleManager } from "../../common/interfaces/IPriceOracleManager.sol"; import { ISwapRouterV3 } from "../../common/interfaces/ISwapRouterV3.sol"; import { IUniswapPair } from "../../common/interfaces/IUniswapPair.sol"; contract PaymentModuleV1 is IDepositHandler, IPaymentModule, AccessControlEnumerable, IERC721Receiver { using SafeERC20 for IERC20Metadata; address public constant burnAddress = 0x000000000000000000000000000000000000dEaD; bytes32 public constant PAYMENT_ADMIN_ROLE = keccak256("PAYMENT_ADMIN_ROLE"); address public FLOKI; IERC20Metadata public USDT; ILPTokenProcessorV2 public lpTokenProcessor; IPricingModule public pricingModule; IPriceOracleManager public priceOracle; address public mainRouter; bool public isV2Router; address public nativeWrappedToken; uint24 public v3PoolFeeForUsdNative = 3000; uint24 public v3PoolFeeForFlokiNative = 3000; address public treasury; bool public convertNativeFeeToUsd = true; uint256 public constant BASIS_POINTS = 10000; uint256 public constant referrerBasisPoints = 2500; // 25% uint256 public constant burnBasisPoints = 2500; // 25% uint256 public feeCollectedLastBlock; uint256 public flokiBurnedLastBlock; uint256 public referrerShareLastBlock; event LPTokenProcessorUpdated(address indexed oldProcessor, address indexed newProcessor); event PriceOracleManagerUpdated(address indexed oldOracle, address indexed newOracle); event PricingModuleUpdated(address indexed oldModule, address indexed newModule); event TreasuryAddressUpdated(address indexed oldTreasury, address indexed newTreasury); event FeeCollected(uint256 indexed previousBlock, address indexed vault, uint256 usdAmount); event ReferrerSharePaid(uint256 indexed previousBlock, address indexed vault, address referrer, uint256 usdAmount); event FlokiBurned(uint256 indexed previousBlock, address indexed vault, uint256 usdAmount, uint256 flokiAmount); event V3PoolFeeForUsdUpdated(uint24 indexed oldFee, uint24 indexed newFee); event V3PoolFeeForFlokiUpdated(uint24 indexed oldFee, uint24 indexed newFee); event RouterUpdated(address indexed oldRouter, address indexed newRouter, bool isV3Router); event UsdTokenUpdated(address indexed oldUsd, address indexed newUsd); event SlippageUpdated(uint256 indexed oldSlippage, uint256 indexed newSlippage); constructor( address flokiAddress, address lpTokenProcessorAddress, address pricingModuleAddress, address treasuryAddress, address routerAddress, bool v2Router, address priceOracleAddress, address usdAddress ) { require(pricingModuleAddress != address(0), "PaymentModuleV1::constructor::ZERO: Pricing module cannot be zero address."); require(routerAddress != address(0), "PaymentModuleV1::constructor::ZERO: Router cannot be zero address."); FLOKI = flokiAddress; pricingModule = IPricingModule(pricingModuleAddress); lpTokenProcessor = ILPTokenProcessorV2(lpTokenProcessorAddress); priceOracle = IPriceOracleManager(priceOracleAddress); mainRouter = routerAddress; isV2Router = v2Router; treasury = treasuryAddress; USDT = IERC20Metadata(usdAddress); nativeWrappedToken = _getNativeWrappedToken(); _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); } /** Deprecated. Kept for compatibility with existing clients. */ function routerForFloki() external view returns (address) { return mainRouter; } function processPayment(ProcessPaymentParams memory params) external payable override onlyRole(PAYMENT_ADMIN_ROLE) { IPricingModule.PriceInfo memory price = pricingModule.getPrice( params.user, params.fungibleTokenDeposits, params.nonFungibleTokenDeposits, params.multiTokenDeposits, params.isVesting ); // Process ERC20 token payments first. _processErc20(params, price); // Process NFT _processNfts(params, price); // Process Multi Token _processMultiToken(params); // Process fees. uint256 weiToBeRefunded = 0; if (convertNativeFeeToUsd || msg.value == 0) { weiToBeRefunded = _processFee(price.usdtAmount, params.user, params.referrer, params.vault); } else { weiToBeRefunded = _processNativeFees(price.usdtAmount, params.referrer, params.vault); } (bool success, ) = payable(params.user).call{ value: weiToBeRefunded }(""); require(success, "Failed to refund leftover ETH"); } function _getNativeWrappedToken() private view returns (address) { if (isV2Router) { return IUniswapV2Router02(mainRouter).WETH(); } else { return ISwapRouterV3(mainRouter).WETH9(); } } function _processErc20(ProcessPaymentParams memory params, IPricingModule.PriceInfo memory price) private { for (uint256 i = 0; i < params.fungibleTokenDeposits.length; i++) { // First transfer the full sum of the tokens to the payment processor. uint256 initialBalance = IERC20Metadata(params.fungibleTokenDeposits[i].tokenAddress).balanceOf(address(this)); IERC20Metadata(params.fungibleTokenDeposits[i].tokenAddress).safeTransferFrom(params.user, address(this), params.fungibleTokenDeposits[i].amount); uint256 receivedAmount = IERC20Metadata(params.fungibleTokenDeposits[i].tokenAddress).balanceOf(address(this)) - initialBalance; // Then transfer tokens that are to be locked to the vault (lpV2Tokens[i] is zero for non-LP tokens). IERC20Metadata(params.fungibleTokenDeposits[i].tokenAddress).safeTransfer(params.vault, receivedAmount - price.v2LpAmounts[i]); if (params.fungibleTokenDeposits[i].tokenAddress == price.v2LpTokens[i]) { // It's important to know that these subtractions never // cause an underflow. The number in `lpV2Amounts[i]` is // non-zero after the transfer to the vault. IERC20Metadata(params.fungibleTokenDeposits[i].tokenAddress).safeApprove(address(lpTokenProcessor), price.v2LpAmounts[i]); // Send LP tokens to the Keepers-powered LP token processor. // The LP token processor will take care of liquidating, swapping for USD token and paying referrers. lpTokenProcessor.addTokenForSwapping( ILPTokenProcessorV2.TokenSwapInfo({ tokenAddress: params.fungibleTokenDeposits[i].tokenAddress, routerFactory: _factory(params.fungibleTokenDeposits[i].tokenAddress), isV2: true, referrer: params.referrer, vault: params.vault, amount: price.v2LpAmounts[i], v3PoolFee: 0 }) ); } } } function _processNfts(ProcessPaymentParams memory params, IPricingModule.PriceInfo memory price) private { for (uint256 i = 0; i < params.nonFungibleTokenDeposits.length; i++) { // First, transfer the tokens to the payment processor. IERC721(params.nonFungibleTokenDeposits[i].tokenAddress).safeTransferFrom(params.user, address(this), params.nonFungibleTokenDeposits[i].tokenId); if (params.nonFungibleTokenDeposits[i].tokenAddress == price.v3LpTokens[i].tokenAddress) { // For V3 LP positions, we need to remove our share of the liquidity // amount0Min and amount1Min are price slippage checks // if the amount received after burning is not greater than these minimums, transaction will fail require(price.v3LpTokens[i].liquidityToRemove > 0, "PaymentModuleV1::processPayment::ZERO: Liquidity to remove cannot be zero."); uint256 initialBalance0 = IERC20Metadata(price.v3LpTokens[i].token0).balanceOf(address(this)); uint256 initialBalance1 = IERC20Metadata(price.v3LpTokens[i].token1).balanceOf(address(this)); INonfungiblePositionManager(price.v3LpTokens[i].tokenAddress).decreaseLiquidity( INonfungiblePositionManager.DecreaseLiquidityParams({ tokenId: params.nonFungibleTokenDeposits[i].tokenId, liquidity: price.v3LpTokens[i].liquidityToRemove, amount0Min: 0, amount1Min: 0, deadline: block.timestamp }) ); INonfungiblePositionManager(price.v3LpTokens[i].tokenAddress).collect( INonfungiblePositionManager.CollectParams({ tokenId: params.nonFungibleTokenDeposits[i].tokenId, recipient: address(this), amount0Max: type(uint128).max, amount1Max: type(uint128).max }) ); // Send unpaired tokens to the Keepers-powered LP token processor. // The LP token processor will take care of liquidating, swapping for USD token and paying referrers. uint256 amount0Received = IERC20Metadata(price.v3LpTokens[i].token0).balanceOf(address(this)) - initialBalance0; uint256 amount1Received = IERC20Metadata(price.v3LpTokens[i].token1).balanceOf(address(this)) - initialBalance1; address factory = INonfungiblePositionManager(price.v3LpTokens[i].tokenAddress).factory(); // Approve tokens to LP Token Processor IERC20Metadata(price.v3LpTokens[i].token0).safeApprove(address(lpTokenProcessor), amount0Received); IERC20Metadata(price.v3LpTokens[i].token1).safeApprove(address(lpTokenProcessor), amount1Received); lpTokenProcessor.addTokenForSwapping( ILPTokenProcessorV2.TokenSwapInfo({ tokenAddress: price.v3LpTokens[i].token0, routerFactory: factory, isV2: false, referrer: params.referrer, vault: params.vault, amount: amount0Received, v3PoolFee: price.v3LpTokens[i].fee }) ); lpTokenProcessor.addTokenForSwapping( ILPTokenProcessorV2.TokenSwapInfo({ tokenAddress: price.v3LpTokens[i].token1, routerFactory: factory, isV2: false, referrer: params.referrer, vault: params.vault, amount: amount1Received, v3PoolFee: price.v3LpTokens[i].fee }) ); } IERC721(params.nonFungibleTokenDeposits[i].tokenAddress).safeTransferFrom(address(this), params.vault, params.nonFungibleTokenDeposits[i].tokenId); } } function _processMultiToken(ProcessPaymentParams memory params) private { for (uint256 i = 0; i < params.multiTokenDeposits.length; i++) { IERC1155(params.multiTokenDeposits[i].tokenAddress).safeTransferFrom( params.user, params.vault, params.multiTokenDeposits[i].tokenId, params.multiTokenDeposits[i].amount, "" ); } } function _factory(address lpTokenAddress) private view returns (address) { try IUniswapPair(lpTokenAddress).factory() returns (address factory) { return factory; } catch { return address(0); } } function _processFee( uint256 usdAmount, address user, address referrer, address vault ) private returns (uint256 weiToBeRefunded) { require(address(USDT) != address(0), "PaymentModuleV1::processPayment::ZERO: USD payments not enabled."); if (usdAmount > 0) { uint256 initialUsdBalance = USDT.balanceOf(address(this)); if (msg.value > 0) { // if user is paying with native token, we swap it by USDT weiToBeRefunded = _swapNativeToUsd(usdAmount); } else { USDT.safeTransferFrom(user, address(this), usdAmount); } uint256 newUsdBalance = USDT.balanceOf(address(this)); uint256 usdEarned = newUsdBalance - initialUsdBalance; require(usdEarned >= usdAmount, "Not enough USD received to cover fees. USD token must not have transfer fees."); uint256 treasuryUsdShare = usdAmount; if (referrer != address(0)) { uint256 referrerUSDTShare = (usdAmount * referrerBasisPoints) / BASIS_POINTS; USDT.safeTransfer(referrer, referrerUSDTShare); treasuryUsdShare -= referrerUSDTShare; emit ReferrerSharePaid(referrerShareLastBlock, vault, referrer, referrerUSDTShare); referrerShareLastBlock = block.number; } if (FLOKI != address(0)) { uint256 burnShare = (usdAmount * burnBasisPoints) / BASIS_POINTS; uint256 flokiBalance = IERC20Metadata(FLOKI).balanceOf(burnAddress); USDT.safeApprove(address(lpTokenProcessor), burnShare); bool success = lpTokenProcessor.swapTokens(address(USDT), burnShare, FLOKI, burnAddress, mainRouter, _getV3PoolFees()); treasuryUsdShare -= burnShare; require(success, "Swap failed"); uint256 flokiBurned = IERC20Metadata(FLOKI).balanceOf(burnAddress) - flokiBalance; emit FlokiBurned(flokiBurnedLastBlock, vault, burnShare, flokiBurned); flokiBurnedLastBlock = block.number; } USDT.safeTransfer(treasury, treasuryUsdShare); emit FeeCollected(feeCollectedLastBlock, vault, treasuryUsdShare); feeCollectedLastBlock = block.number; } } function _getV3PoolFees() private view returns (uint24[] memory) { uint24[] memory fees = new uint24[](2); fees[0] = v3PoolFeeForUsdNative; fees[1] = v3PoolFeeForFlokiNative; return fees; } function _processNativeFees( uint256 usdAmount, address referrer, address vault ) private returns (uint256 weiToBeRefunded) { priceOracle.fetchPriceInUSD(nativeWrappedToken); uint256 price = priceOracle.getPriceInUSD(nativeWrappedToken, pricingModule.priceDecimals()); require(price > 0, "PaymentModuleV1::processPayment::INVALID: Price from oracle is unavailable."); uint256 expectedWei = (usdAmount * 1 ether) / price; require(msg.value >= expectedWei, "PaymentModuleV1::processPayment::INVALID: Not enough Native Tokens sent to cover fees."); weiToBeRefunded = msg.value - expectedWei; if (referrer != address(0)) { uint256 referrerWeiShare = (expectedWei * referrerBasisPoints) / BASIS_POINTS; (bool referrerSucceeded, ) = payable(referrer).call{ value: referrerWeiShare }(""); require(referrerSucceeded, "Failed to send native share to referrer."); expectedWei -= referrerWeiShare; uint256 usdReferrerShare = (usdAmount * referrerBasisPoints) / BASIS_POINTS; usdAmount -= usdReferrerShare; emit ReferrerSharePaid(referrerShareLastBlock, vault, referrer, usdReferrerShare); referrerShareLastBlock = block.number; } (bool success, ) = payable(treasury).call{ value: expectedWei }(""); require(success, "Failed to send native token to treasury."); emit FeeCollected(feeCollectedLastBlock, vault, usdAmount); feeCollectedLastBlock = block.number; return weiToBeRefunded; } function _swapNativeToUsd(uint256 usdAmount) private returns (uint256 weiToBeRefunded) { uint256 oldEthBalance = address(this).balance; if (isV2Router) { address[] memory path = new address[](2); path[0] = IUniswapV2Router02(mainRouter).WETH(); path[1] = address(USDT); IUniswapV2Router02(mainRouter).swapETHForExactTokens{ value: msg.value }(usdAmount, path, address(this), block.timestamp); } else { ISwapRouterV3.ExactOutputSingleParams memory params = ISwapRouterV3.ExactOutputSingleParams({ tokenIn: ISwapRouterV3(mainRouter).WETH9(), tokenOut: address(USDT), fee: v3PoolFeeForUsdNative, recipient: address(this), amountOut: usdAmount, amountInMaximum: msg.value, sqrtPriceLimitX96: 0 }); ISwapRouterV3(mainRouter).exactOutputSingle{ value: msg.value }(params); } // refund any extra ETH sent weiToBeRefunded = msg.value - (oldEthBalance - address(this).balance); } function setConvertNativeFeeToUsd(bool _convertNativeFeeToUsd) external onlyRole(DEFAULT_ADMIN_ROLE) { convertNativeFeeToUsd = _convertNativeFeeToUsd; } function setFloki(address _floki) external onlyRole(DEFAULT_ADMIN_ROLE) { FLOKI = _floki; } function setUsdToken(address newUsdToken) external onlyRole(DEFAULT_ADMIN_ROLE) { require(newUsdToken != address(0), "LPTokenProcessorV2::setUsdToken::ZERO: USDT cannot be zero address."); address oldUsdToken = address(USDT); USDT = IERC20Metadata(newUsdToken); emit UsdTokenUpdated(oldUsdToken, newUsdToken); } function setLPTokenProcessor(address newProcessor) external onlyRole(DEFAULT_ADMIN_ROLE) { address oldProcessor = address(lpTokenProcessor); lpTokenProcessor = ILPTokenProcessorV2(newProcessor); emit LPTokenProcessorUpdated(oldProcessor, newProcessor); } function setPriceOracleManager(address priceOracleAddress) external onlyRole(DEFAULT_ADMIN_ROLE) { address oldPriceOracle = address(priceOracle); priceOracle = IPriceOracleManager(priceOracleAddress); emit PriceOracleManagerUpdated(oldPriceOracle, priceOracleAddress); } function setPricingModule(address newModule) external onlyRole(DEFAULT_ADMIN_ROLE) { address oldModule = address(pricingModule); pricingModule = IPricingModule(newModule); emit PricingModuleUpdated(oldModule, newModule); } function setRouter(address newRouter, bool v2Router) external onlyRole(DEFAULT_ADMIN_ROLE) { address oldRouter = mainRouter; mainRouter = newRouter; isV2Router = v2Router; nativeWrappedToken = _getNativeWrappedToken(); emit RouterUpdated(oldRouter, newRouter, v2Router); } function setV3PoolFeeForUsd(uint24 newFee) external onlyRole(DEFAULT_ADMIN_ROLE) { uint24 oldFee = v3PoolFeeForUsdNative; v3PoolFeeForUsdNative = newFee; emit V3PoolFeeForUsdUpdated(oldFee, newFee); } function setV3PoolFeeForFloki(uint24 newFee) external onlyRole(DEFAULT_ADMIN_ROLE) { uint24 oldFee = v3PoolFeeForFlokiNative; v3PoolFeeForFlokiNative = newFee; emit V3PoolFeeForFlokiUpdated(oldFee, newFee); } function setTreasury(address newTreasury) external onlyRole(DEFAULT_ADMIN_ROLE) { address oldTreasury = treasury; treasury = newTreasury; emit TreasuryAddressUpdated(oldTreasury, newTreasury); } function adminWithdraw(address tokenAddress, uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE) { if (tokenAddress == address(0)) { // We specifically ignore this return value. (bool success, ) = payable(treasury).call{ value: amount }(""); require(success, "Failed to withdraw ETH"); } else { IERC20Metadata(tokenAddress).safeTransfer(treasury, amount); } } function notifyFeeCollected(address _vault, uint256 _amount) external onlyRole(DEFAULT_ADMIN_ROLE) { emit FeeCollected(feeCollectedLastBlock, _vault, _amount); feeCollectedLastBlock = block.number; } function notifyFlokiBurned( address _vault, uint256 _usdAmount, uint256 _flokiAmount ) external onlyRole(DEFAULT_ADMIN_ROLE) { emit FlokiBurned(flokiBurnedLastBlock, _vault, _usdAmount, _flokiAmount); flokiBurnedLastBlock = block.number; } function notifyReferrerSharePaid( address _vault, address _referrer, uint256 _amount ) external onlyRole(DEFAULT_ADMIN_ROLE) { emit ReferrerSharePaid(referrerShareLastBlock, _vault, _referrer, _amount); referrerShareLastBlock = block.number; } receive() external payable {} function onERC721Received( address, address, uint256, bytes calldata ) external pure override returns (bytes4) { return this.onERC721Received.selector; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol) pragma solidity ^0.8.0; import "./IAccessControlEnumerable.sol"; import "./AccessControl.sol"; import "../utils/structs/EnumerableSet.sol"; /** * @dev Extension of {AccessControl} that allows enumerating the members of each role. */ abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl { using EnumerableSet for EnumerableSet.AddressSet; mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) { return _roleMembers[role].at(index); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) { return _roleMembers[role].length(); } /** * @dev Overload {_grantRole} to track enumerable memberships */ function _grantRole(bytes32 role, address account) internal virtual override { super._grantRole(role, account); _roleMembers[role].add(account); } /** * @dev Overload {_revokeRole} to track enumerable memberships */ function _revokeRole(bytes32 role, address account) internal virtual override { super._revokeRole(role, account); _roleMembers[role].remove(account); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; /** * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. */ interface IAccessControlEnumerable is IAccessControl { /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) external view returns (address); /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } 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)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } 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"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } 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"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * ==== * * [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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(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) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
pragma solidity >=0.5.0; interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; }
pragma solidity >=0.6.2; interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); }
pragma solidity >=0.6.2; import './IUniswapV2Router01.sol'; interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.4; pragma abicoder v2; import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; /// @title Non-fungible token for positions /// @notice Wraps Uniswap V3 positions in a non-fungible token interface which allows for them to be transferred /// and authorized. interface INonfungiblePositionManager is IERC721Enumerable { /// @notice Returns the position information associated with a given token ID. /// @dev Throws if the token ID is not valid. /// @param tokenId The ID of the token that represents the position /// @return nonce The nonce for permits /// @return operator The address that is approved for spending /// @return token0 The address of the token0 for a specific pool /// @return token1 The address of the token1 for a specific pool /// @return fee The fee associated with the pool /// @return tickLower The lower end of the tick range for the position /// @return tickUpper The higher end of the tick range for the position /// @return liquidity The liquidity of the position /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation function positions(uint256 tokenId) external view returns ( uint96 nonce, address operator, address token0, address token1, uint24 fee, int24 tickLower, int24 tickUpper, uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, uint128 tokensOwed0, uint128 tokensOwed1 ); struct MintParams { address token0; address token1; uint24 fee; int24 tickLower; int24 tickUpper; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; address recipient; uint256 deadline; } /// @notice Creates a new position wrapped in a NFT /// @dev Call this when the pool does exist and is initialized. Note that if the pool is created but not initialized /// a method does not exist, i.e. the pool is assumed to be initialized. /// @param params The params necessary to mint a position, encoded as `MintParams` in calldata /// @return tokenId The ID of the token that represents the minted position /// @return liquidity The amount of liquidity for this position /// @return amount0 The amount of token0 /// @return amount1 The amount of token1 function mint(MintParams calldata params) external payable returns ( uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1 ); struct IncreaseLiquidityParams { uint256 tokenId; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; uint256 deadline; } /// @notice Increases the amount of liquidity in a position, with tokens paid by the `msg.sender` /// @param params tokenId The ID of the token for which liquidity is being increased, /// amount0Desired The desired amount of token0 to be spent, /// amount1Desired The desired amount of token1 to be spent, /// amount0Min The minimum amount of token0 to spend, which serves as a slippage check, /// amount1Min The minimum amount of token1 to spend, which serves as a slippage check, /// deadline The time by which the transaction must be included to effect the change /// @return liquidity The new liquidity amount as a result of the increase /// @return amount0 The amount of token0 to acheive resulting liquidity /// @return amount1 The amount of token1 to acheive resulting liquidity function increaseLiquidity(IncreaseLiquidityParams calldata params) external payable returns ( uint128 liquidity, uint256 amount0, uint256 amount1 ); struct DecreaseLiquidityParams { uint256 tokenId; uint128 liquidity; uint256 amount0Min; uint256 amount1Min; uint256 deadline; } /// @notice Decreases the amount of liquidity in a position and accounts it to the position /// @param params tokenId The ID of the token for which liquidity is being decreased, /// amount The amount by which liquidity will be decreased, /// amount0Min The minimum amount of token0 that should be accounted for the burned liquidity, /// amount1Min The minimum amount of token1 that should be accounted for the burned liquidity, /// deadline The time by which the transaction must be included to effect the change /// @return amount0 The amount of token0 accounted to the position's tokens owed /// @return amount1 The amount of token1 accounted to the position's tokens owed function decreaseLiquidity(DecreaseLiquidityParams calldata params) external payable returns (uint256 amount0, uint256 amount1); struct CollectParams { uint256 tokenId; address recipient; uint128 amount0Max; uint128 amount1Max; } /// @notice Collects up to a maximum amount of fees owed to a specific position to the recipient /// @param params tokenId The ID of the NFT for which tokens are being collected, /// recipient The account that should receive the tokens, /// amount0Max The maximum amount of token0 to collect, /// amount1Max The maximum amount of token1 to collect /// @return amount0 The amount of fees collected in token0 /// @return amount1 The amount of fees collected in token1 function collect(CollectParams calldata params) external payable returns (uint256 amount0, uint256 amount1); /// @notice Burns a token ID, which deletes it from the NFT contract. The token must have 0 liquidity and all tokens /// must be collected first. /// @param tokenId The ID of the token that is being burned function burn(uint256 tokenId) external payable; function factory() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.4; interface IPriceOracleManager { /** * Fetches the USD price for a token if required */ function fetchPriceInUSD(address sourceToken) external; /** * Returns the price of the token in USD, normalized to the expected decimals param. */ function getPriceInUSD(address token, uint256 expectedDecimals) external view returns (uint256 price); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.4; interface ISwapRouterV3 { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); struct ExactInputParams { bytes path; address recipient; uint256 amountIn; uint256 amountOutMinimum; } function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); function WETH9() external pure returns (address); function factory() external pure returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.4; interface IUniswapPair { function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.4; interface IDepositHandler { struct FungibleTokenDeposit { address tokenAddress; uint256 amount; bool isLP; } struct NonFungibleTokenDeposit { address tokenAddress; uint256 tokenId; } struct MultiTokenDeposit { address tokenAddress; uint256 tokenId; uint256 amount; } struct V3LPData { address tokenAddress; address token0; address token1; uint128 liquidityToRemove; uint24 fee; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.4; interface ILPTokenProcessorV2 { struct TokenSwapInfo { address tokenAddress; address routerFactory; bool isV2; address referrer; address vault; uint256 amount; uint24 v3PoolFee; } function addTokenForSwapping(TokenSwapInfo memory params) external; function getRouter(address lpTokenAddress) external view returns (address); function getV3Position(address tokenAddress, uint256 tokenId) external view returns ( address, address, uint128, uint24 ); function isV2LiquidityPoolToken(address tokenAddress) external view returns (bool); function isV3LiquidityPoolToken(address tokenAddress, uint256 tokenId) external view returns (bool); function swapTokens( address sourceToken, uint256 sourceAmount, address destinationToken, address receiver, address routerAddress, uint24[] memory poolFees ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.4; import { IDepositHandler } from "./IDepositHandler.sol"; interface IPaymentModule is IDepositHandler { struct PaymentHolder { address tokenAddress; uint256 amount; uint256 payment; } struct ProcessPaymentParams { address vault; address user; address referrer; FungibleTokenDeposit[] fungibleTokenDeposits; NonFungibleTokenDeposit[] nonFungibleTokenDeposits; MultiTokenDeposit[] multiTokenDeposits; bool isVesting; } function processPayment(ProcessPaymentParams memory params) external payable; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.4; import { IDepositHandler } from "../interfaces/IDepositHandler.sol"; interface IPricingModule is IDepositHandler { struct PriceInfo { address[] v2LpTokens; uint256[] v2LpAmounts; V3LPData[] v3LpTokens; uint256 usdtAmount; } /** * @notice Get price of vault creation. * @param user Address of vault creator. * @param fungibleTokenDeposits Array of fungible token deposits * consisting of addresses and amounts. * @param nonFungibleTokenDeposits Array of non-fungible token deposits * consisting of addresses and IDs. * @param multiTokenDeposits Array of multi token deposits consisting of * addresses, IDs and their corresponding amounts. * @return A four-item tuple consisting of an array of LP token addresses, * an array of the corresponding required payment amounts, an array of V3LPData, and the amount * of USDT required. */ function getPrice( address user, FungibleTokenDeposit[] memory fungibleTokenDeposits, NonFungibleTokenDeposit[] memory nonFungibleTokenDeposits, MultiTokenDeposit[] memory multiTokenDeposits, bool isVested ) external view returns (PriceInfo memory); function priceDecimals() external view returns (uint8); }
{ "evmVersion": "istanbul", "libraries": {}, "metadata": { "bytecodeHash": "none", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 800 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"flokiAddress","type":"address"},{"internalType":"address","name":"lpTokenProcessorAddress","type":"address"},{"internalType":"address","name":"pricingModuleAddress","type":"address"},{"internalType":"address","name":"treasuryAddress","type":"address"},{"internalType":"address","name":"routerAddress","type":"address"},{"internalType":"bool","name":"v2Router","type":"bool"},{"internalType":"address","name":"priceOracleAddress","type":"address"},{"internalType":"address","name":"usdAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"previousBlock","type":"uint256"},{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"uint256","name":"usdAmount","type":"uint256"}],"name":"FeeCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"previousBlock","type":"uint256"},{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"uint256","name":"usdAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"flokiAmount","type":"uint256"}],"name":"FlokiBurned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldProcessor","type":"address"},{"indexed":true,"internalType":"address","name":"newProcessor","type":"address"}],"name":"LPTokenProcessorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOracle","type":"address"},{"indexed":true,"internalType":"address","name":"newOracle","type":"address"}],"name":"PriceOracleManagerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldModule","type":"address"},{"indexed":true,"internalType":"address","name":"newModule","type":"address"}],"name":"PricingModuleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"previousBlock","type":"uint256"},{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"address","name":"referrer","type":"address"},{"indexed":false,"internalType":"uint256","name":"usdAmount","type":"uint256"}],"name":"ReferrerSharePaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldRouter","type":"address"},{"indexed":true,"internalType":"address","name":"newRouter","type":"address"},{"indexed":false,"internalType":"bool","name":"isV3Router","type":"bool"}],"name":"RouterUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldSlippage","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newSlippage","type":"uint256"}],"name":"SlippageUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldTreasury","type":"address"},{"indexed":true,"internalType":"address","name":"newTreasury","type":"address"}],"name":"TreasuryAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldUsd","type":"address"},{"indexed":true,"internalType":"address","name":"newUsd","type":"address"}],"name":"UsdTokenUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint24","name":"oldFee","type":"uint24"},{"indexed":true,"internalType":"uint24","name":"newFee","type":"uint24"}],"name":"V3PoolFeeForFlokiUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint24","name":"oldFee","type":"uint24"},{"indexed":true,"internalType":"uint24","name":"newFee","type":"uint24"}],"name":"V3PoolFeeForUsdUpdated","type":"event"},{"inputs":[],"name":"BASIS_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FLOKI","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAYMENT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDT","outputs":[{"internalType":"contract IERC20Metadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"adminWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"convertNativeFeeToUsd","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeCollectedLastBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flokiBurnedLastBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isV2Router","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpTokenProcessor","outputs":[{"internalType":"contract ILPTokenProcessorV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nativeWrappedToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"notifyFeeCollected","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"uint256","name":"_usdAmount","type":"uint256"},{"internalType":"uint256","name":"_flokiAmount","type":"uint256"}],"name":"notifyFlokiBurned","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_referrer","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"notifyReferrerSharePaid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"priceOracle","outputs":[{"internalType":"contract IPriceOracleManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pricingModule","outputs":[{"internalType":"contract IPricingModule","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"isLP","type":"bool"}],"internalType":"struct IDepositHandler.FungibleTokenDeposit[]","name":"fungibleTokenDeposits","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"internalType":"struct IDepositHandler.NonFungibleTokenDeposit[]","name":"nonFungibleTokenDeposits","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IDepositHandler.MultiTokenDeposit[]","name":"multiTokenDeposits","type":"tuple[]"},{"internalType":"bool","name":"isVesting","type":"bool"}],"internalType":"struct IPaymentModule.ProcessPaymentParams","name":"params","type":"tuple"}],"name":"processPayment","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"referrerBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referrerShareLastBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"routerForFloki","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_convertNativeFeeToUsd","type":"bool"}],"name":"setConvertNativeFeeToUsd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_floki","type":"address"}],"name":"setFloki","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newProcessor","type":"address"}],"name":"setLPTokenProcessor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"priceOracleAddress","type":"address"}],"name":"setPriceOracleManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newModule","type":"address"}],"name":"setPricingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRouter","type":"address"},{"internalType":"bool","name":"v2Router","type":"bool"}],"name":"setRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTreasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newUsdToken","type":"address"}],"name":"setUsdToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"newFee","type":"uint24"}],"name":"setV3PoolFeeForFloki","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"newFee","type":"uint24"}],"name":"setV3PoolFeeForUsd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"v3PoolFeeForFlokiNative","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"v3PoolFeeForUsdNative","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040526008805464017700017760a31b65ffffffffffff60a01b199091161790556009805460ff60a01b1916600160a01b1790553480156200004257600080fd5b50604051620054a5380380620054a58339810160408190526200006591620004ac565b6001600160a01b038616620000e95760405162461bcd60e51b815260206004820152604a60248201526000805160206200548583398151915260448201527f524f3a2050726963696e67206d6f64756c652063616e6e6f74206265207a6572606482015269379030b2323932b9b99760b11b608482015260a4015b60405180910390fd5b6001600160a01b038416620001615760405162461bcd60e51b815260206004820152604260248201526000805160206200548583398151915260448201527f524f3a20526f757465722063616e6e6f74206265207a65726f20616464726573606482015261399760f11b608482015260a401620000e0565b600280546001600160a01b03199081166001600160a01b038b8116919091179092556005805482168984161790556004805482168a8416179055600680548216858416179055600780548784166001600160a81b031990911617600160a01b8715150217905560098054821688841617905560038054909116918316919091179055620001ed62000228565b600880546001600160a01b0319166001600160a01b03929092169190911790556200021a6000336200031c565b505050505050505062000558565b600754600090600160a01b900460ff1615620002cd57600760009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b1580156200028d57600080fd5b505afa158015620002a2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002c891906200048f565b905090565b600760009054906101000a90046001600160a01b03166001600160a01b0316634aa4a4fc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200028d57600080fd5b6200033382826200035f60201b620012bf1760201c565b60008281526001602090815260409091206200035a9183906200135d62000400821b17901c565b505050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16620003fc576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620003bb3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600062000417836001600160a01b03841662000420565b90505b92915050565b600081815260018301602052604081205462000469575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200041a565b5060006200041a565b80516001600160a01b03811681146200048a57600080fd5b919050565b600060208284031215620004a1578081fd5b620004178262000472565b600080600080600080600080610100898b031215620004c9578384fd5b620004d48962000472565b9750620004e460208a0162000472565b9650620004f460408a0162000472565b95506200050460608a0162000472565b94506200051460808a0162000472565b935060a0890151801515811462000529578384fd5b92506200053960c08a0162000472565b91506200054960e08a0162000472565b90509295985092959890939650565b614f1d80620005686000396000f3fe6080604052600436106103005760003560e01c8063967737c91161018f578063c54e44eb116100e1578063e1f1c4a71161008a578063e4301ec511610064578063e4301ec5146108bc578063e9948e31146108dc578063f0f44260146108fc57600080fd5b8063e1f1c4a71461087a578063e23bfa5a14610890578063e39e927b146108a657600080fd5b8063cf188ad0116100bb578063cf188ad01461081a578063d547741f1461083a578063da8055901461085a57600080fd5b8063c54e44eb146107b7578063c9d7489f146107d7578063ca15c873146107fa57600080fd5b8063b24a67c411610143578063b567f6a61161011d578063b567f6a614610760578063c170364614610781578063c3c646741461079757600080fd5b8063b24a67c4146106ec578063b24b56b01461070c578063b41c5fda1461074057600080fd5b80639a5bce1e116101745780639a5bce1e14610696578063a217fddf146106b6578063a8998b73146106cb57600080fd5b8063967737c9146106835780639a436c9b1461053e57600080fd5b806336568abe1161025357806361d027b3116101fc5780638e33a9e6116101d65780638e33a9e6146105ff5780639010d07c1461061f57806391d148541461063f57600080fd5b806361d027b3146105a957806370d5ae05146105c95780637c169123146105df57600080fd5b8063470cc5f21161022d578063470cc5f21461053e578063539c07c714610554578063595a04451461057257600080fd5b806336568abe146104de5780633e07bd5f146104fe578063401d44821461051e57600080fd5b8063150b7a02116102b557806326352aca1161028f57806326352aca1461047e5780632f2ff15d1461049e5780632f9f8c13146104be57600080fd5b8063150b7a02146103c3578063248a9ca3146104085780632630c12f1461044657600080fd5b806305d719f1116102e657806305d719f1146103635780630c3244de146103835780630f395b77146103a357600080fd5b8062bbc2dc1461030c57806301ffc9a71461032e57600080fd5b3661030757005b600080fd5b34801561031857600080fd5b5061032c61032736600461451b565b61091c565b005b34801561033a57600080fd5b5061034e61034936600461478c565b61097a565b60405190151581526020015b60405180910390f35b34801561036f57600080fd5b5061032c61037e36600461451b565b6109a5565b34801561038f57600080fd5b5061032c61039e366004614963565b610a03565b3480156103af57600080fd5b5061032c6103be36600461451b565b610a7e565b3480156103cf57600080fd5b506103ef6103de366004614593565b630a85bd0160e11b95945050505050565b6040516001600160e01b0319909116815260200161035a565b34801561041457600080fd5b5061043861042336600461472f565b60009081526020819052604090206001015490565b60405190815260200161035a565b34801561045257600080fd5b50600654610466906001600160a01b031681565b6040516001600160a01b03909116815260200161035a565b34801561048a57600080fd5b5061032c610499366004614665565b610aac565b3480156104aa57600080fd5b5061032c6104b9366004614747565b610b06565b3480156104ca57600080fd5b50600254610466906001600160a01b031681565b3480156104ea57600080fd5b5061032c6104f9366004614747565b610b30565b34801561050a57600080fd5b5061032c610519366004614553565b610bc1565b34801561052a57600080fd5b5061032c610539366004614665565b610c20565b34801561054a57600080fd5b506104386109c481565b34801561056057600080fd5b506007546001600160a01b0316610466565b34801561057e57600080fd5b5060085461059590600160a01b900462ffffff1681565b60405162ffffff909116815260200161035a565b3480156105b557600080fd5b50600954610466906001600160a01b031681565b3480156105d557600080fd5b5061046661dead81565b3480156105eb57600080fd5b5061032c6105fa366004614963565b610cfc565b34801561060b57600080fd5b5061032c61061a36600461451b565b610d77565b34801561062b57600080fd5b5061046661063a36600461476b565b610dd5565b34801561064b57600080fd5b5061034e61065a366004614747565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b61032c610691366004614870565b610df4565b3480156106a257600080fd5b5061032c6106b1366004614690565b610feb565b3480156106c257600080fd5b50610438600081565b3480156106d757600080fd5b5060075461034e90600160a01b900460ff1681565b3480156106f857600080fd5b5061032c6107073660046146f7565b611048565b34801561071857600080fd5b506104387f4a76dea3a6231aa5446f85ecde36fb499385f0f3539e800a138fb9855200db6781565b34801561074c57600080fd5b50600454610466906001600160a01b031681565b34801561076c57600080fd5b5060095461034e90600160a01b900460ff1681565b34801561078d57600080fd5b50610438600c5481565b3480156107a357600080fd5b5061032c6107b236600461462d565b61108d565b3480156107c357600080fd5b50600354610466906001600160a01b031681565b3480156107e357600080fd5b5060085461059590600160b81b900462ffffff1681565b34801561080657600080fd5b5061043861081536600461472f565b61113f565b34801561082657600080fd5b50600754610466906001600160a01b031681565b34801561084657600080fd5b5061032c610855366004614747565b611156565b34801561086657600080fd5b5061032c61087536600461451b565b61117b565b34801561088657600080fd5b5061043861271081565b34801561089c57600080fd5b50610438600a5481565b3480156108b257600080fd5b50610438600b5481565b3480156108c857600080fd5b50600854610466906001600160a01b031681565b3480156108e857600080fd5b50600554610466906001600160a01b031681565b34801561090857600080fd5b5061032c61091736600461451b565b611261565b600061092781611372565b600480546001600160a01b038481166001600160a01b0319831681179093556040519116919082907fbe4d92296304c08899e8f09ed9f0a81a36aacbb92e06937db35b74c190386d3290600090a3505050565b60006001600160e01b03198216635a05180f60e01b148061099f575061099f8261137f565b92915050565b60006109b081611372565b600580546001600160a01b038481166001600160a01b0319831681179093556040519116919082907fa8cb7494a9dfd9a9217c6ae355438f169643a50bb6f7cd1046379e3a91b07efd90600090a3505050565b6000610a0e81611372565b6008805462ffffff848116600160a01b8181027fffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffff85161790945560405193909204169182907fdd1f92c0541e60b8bc0cd45489a4e214b5cab667a3e8f147a8677a4c8f87ebc590600090a3505050565b6000610a8981611372565b50600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000610ab781611372565b826001600160a01b0316600a547ff1d6c8ee14081f641e2073a1064d870f135f1001a301c6b14a7b9655672fec1184604051610af591815260200190565b60405180910390a3505043600a5550565b600082815260208190526040902060010154610b2181611372565b610b2b83836113b4565b505050565b6001600160a01b0381163314610bb35760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b610bbd82826113d6565b5050565b6000610bcc81611372565b600c54604080516001600160a01b03868116825260208201869052871692917fa1226f693825711d4115bffd17913b315dbf5a69dc7e9b963cde08921992b792910160405180910390a3505043600c555050565b6000610c2b81611372565b6001600160a01b038316610ce2576009546040516000916001600160a01b03169084908381818185875af1925050503d8060008114610c86576040519150601f19603f3d011682016040523d82523d6000602084013e610c8b565b606091505b5050905080610cdc5760405162461bcd60e51b815260206004820152601660248201527f4661696c656420746f20776974686472617720455448000000000000000000006044820152606401610baa565b50505050565b600954610b2b906001600160a01b038581169116846113f8565b6000610d0781611372565b6008805462ffffff848116600160b81b8181027fffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffff85161790945560405193909204169182907ffb035cdf0e93aa8f8469ceb9666561d4b90efbaed8a99bd4ad341ce175cf16e390600090a3505050565b6000610d8281611372565b600680546001600160a01b038481166001600160a01b0319831681179093556040519116919082907f94c475b625ea2cd275733bbd42692872062c157920702a9588e68c9a9410def890600090a3505050565b6000828152600160205260408120610ded9083611470565b9392505050565b7f4a76dea3a6231aa5446f85ecde36fb499385f0f3539e800a138fb9855200db67610e1e81611372565b60055460208301516060840151608085015160a086015160c0870151604051637f53bed960e01b81526000966001600160a01b031695637f53bed995610e6f95919490939192909190600401614b14565b60006040518083038186803b158015610e8757600080fd5b505afa158015610e9b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ec391908101906147b4565b9050610ecf838261147c565b610ed983826119c9565b610ee283612722565b600954600090600160a01b900460ff1680610efb575034155b15610f2357610f1c826060015185602001518660400151876000015161286b565b9050610f3d565b610f3a826060015185604001518660000151612e92565b90505b600084602001516001600160a01b03168260405160006040518083038185875af1925050503d8060008114610f8e576040519150601f19603f3d011682016040523d82523d6000602084013e610f93565b606091505b5050905080610fe45760405162461bcd60e51b815260206004820152601d60248201527f4661696c656420746f20726566756e64206c6566746f766572204554480000006044820152606401610baa565b5050505050565b6000610ff681611372565b600b5460408051858152602081018590526001600160a01b03871692917f4124ef036039a90351b9862218c2417806e83bc3ec8152a46a64b6dc33f12d1f910160405180910390a3505043600b555050565b600061105381611372565b5060098054911515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b600061109881611372565b600780546001600160a01b038581167fffffffffffffffffffffff000000000000000000000000000000000000000000831617600160a01b8615150217909255166110e161340b565b600880546001600160a01b0319166001600160a01b039283161790556040518415158152858216918316907f80fdee3512206975d63f674069eae3e0b0bbf7b91e1769587e8e3dfb272f991d9060200160405180910390a350505050565b600081815260016020526040812061099f906134f9565b60008281526020819052604090206001015461117181611372565b610b2b83836113d6565b600061118681611372565b6001600160a01b03821661120e5760405162461bcd60e51b815260206004820152604360248201527f4c50546f6b656e50726f636573736f7256323a3a736574557364546f6b656e3a60448201527f3a5a45524f3a20555344542063616e6e6f74206265207a65726f20616464726560648201526239b99760e91b608482015260a401610baa565b600380546001600160a01b038481166001600160a01b0319831681179093556040519116919082907f40f67e76635d70f4e4c56ec98d9668a3c2ad514af7829718b7d83c44b25d370390600090a3505050565b600061126c81611372565b600980546001600160a01b038481166001600160a01b0319831681179093556040519116919082907f430359a6d97ced2b6f93c77a91e7ce9dfd43252eb91e916adba170485cd8a6a490600090a3505050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610bbd576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556113193390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610ded836001600160a01b038416613503565b61137c8133613552565b50565b60006001600160e01b03198216637965db0b60e01b148061099f57506301ffc9a760e01b6001600160e01b031983161461099f565b6113be82826112bf565b6000828152600160205260409020610b2b908261135d565b6113e082826135d0565b6000828152600160205260409020610b2b908261364f565b6040516001600160a01b038316602482015260448101829052610b2b90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b031990931692909217909152613664565b6000610ded8383613749565b60005b826060015151811015610b2b576000836060015182815181106114b257634e487b7160e01b600052603260045260246000fd5b6020908102919091010151516040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156114fe57600080fd5b505afa158015611512573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611536919061497f565b90506115ba8460200151308660600151858151811061156557634e487b7160e01b600052603260045260246000fd5b6020026020010151602001518760600151868151811061159557634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b0316613781909392919063ffffffff16565b600081856060015184815181106115e157634e487b7160e01b600052603260045260246000fd5b6020908102919091010151516040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561162d57600080fd5b505afa158015611641573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611665919061497f565b61166f9190614e3b565b90506116f885600001518560200151858151811061169d57634e487b7160e01b600052603260045260246000fd5b6020026020010151836116b09190614e3b565b876060015186815181106116d457634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b03166113f89092919063ffffffff16565b835180518490811061171a57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03168560600151848151811061174f57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b031614156119b457600454602085015180516117f1926001600160a01b03169190869081106117a157634e487b7160e01b600052603260045260246000fd5b6020026020010151876060015186815181106117cd57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b03166137b99092919063ffffffff16565b600460009054906101000a90046001600160a01b03166001600160a01b0316639654a3096040518060e001604052808860600151878151811061184457634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b031681526020016118968960600151888151811061188557634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516138e4565b6001600160a01b0316815260200160011515815260200188604001516001600160a01b0316815260200188600001516001600160a01b03168152602001876020015187815181106118f757634e487b7160e01b600052603260045260246000fd5b6020908102919091018101518252600091810191909152604080516001600160e01b031960e086901b16815283516001600160a01b039081166004830152928401518316602482015290830151151560448201526060830151821660648201526080830151909116608482015260a082015160a482015260c09091015162ffffff1660c482015260e401600060405180830381600087803b15801561199b57600080fd5b505af11580156119af573d6000803e3d6000fd5b505050505b505080806119c190614e95565b91505061147f565b60005b826080015151811015610b2b57826080015181815181106119fd57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b03166342842e0e84602001513086608001518581518110611a4157634e487b7160e01b600052603260045260246000fd5b60209081029190910181015101516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b158015611a9e57600080fd5b505af1158015611ab2573d6000803e3d6000fd5b5050505081604001518181518110611ada57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b031683608001518281518110611b1357634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b0316141561263257600082604001518281518110611b5457634e487b7160e01b600052603260045260246000fd5b6020026020010151606001516fffffffffffffffffffffffffffffffff1611611c0b5760405162461bcd60e51b815260206004820152604a60248201527f5061796d656e744d6f64756c6556313a3a70726f636573735061796d656e743a60448201527f3a5a45524f3a204c697175696469747920746f2072656d6f76652063616e6e6f60648201527f74206265207a65726f2e00000000000000000000000000000000000000000000608482015260a401610baa565b600082604001518281518110611c3157634e487b7160e01b600052603260045260246000fd5b60209081029190910181015101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015611c7f57600080fd5b505afa158015611c93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb7919061497f565b9050600083604001518381518110611cdf57634e487b7160e01b600052603260045260246000fd5b602090810291909101015160409081015190516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015611d2f57600080fd5b505afa158015611d43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d67919061497f565b905083604001518381518110611d8d57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b0316630c49ccbe6040518060a0016040528088608001518781518110611dd657634e487b7160e01b600052603260045260246000fd5b602002602001015160200151815260200187604001518781518110611e0b57634e487b7160e01b600052603260045260246000fd5b6020026020010151606001516fffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001428152506040518263ffffffff1660e01b8152600401611ea39190600060a082019050825182526fffffffffffffffffffffffffffffffff602084015116602083015260408301516040830152606083015160608301526080830151608083015292915050565b6040805180830381600087803b158015611ebc57600080fd5b505af1158015611ed0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef49190614997565b505083604001518381518110611f1a57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b031663fc6f7865604051806080016040528088608001518781518110611f6357634e487b7160e01b600052603260045260246000fd5b602090810291909101810151810151825230828201526fffffffffffffffffffffffffffffffff6040808401829052606093840182905280516001600160e01b031960e088901b16815285516004820152928501516001600160a01b0316602484015284015181166044830152929091015190911660648201526084016040805180830381600087803b158015611ff957600080fd5b505af115801561200d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120319190614997565b50506000828560400151858151811061205a57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156120a857600080fd5b505afa1580156120bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e0919061497f565b6120ea9190614e3b565b90506000828660400151868151811061211357634e487b7160e01b600052603260045260246000fd5b602090810291909101015160409081015190516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561216357600080fd5b505afa158015612177573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061219b919061497f565b6121a59190614e3b565b90506000866040015186815181106121cd57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b031663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b15801561221157600080fd5b505afa158015612225573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122499190614537565b90506122ad600460009054906101000a90046001600160a01b0316848960400151898151811061228957634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160a01b03166137b99092919063ffffffff16565b60045460408801518051612309926001600160a01b03169185918a9081106122e557634e487b7160e01b600052603260045260246000fd5b6020026020010151604001516001600160a01b03166137b99092919063ffffffff16565b6004546040805160e0810182529089015180516001600160a01b0390931692639654a309929182918b90811061234f57634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160a01b03168152602001846001600160a01b031681526020016000151581526020018b604001516001600160a01b031681526020018b600001516001600160a01b031681526020018681526020018a604001518a815181106123d157634e487b7160e01b600052603260045260246000fd5b60200260200101516080015162ffffff168152506040518263ffffffff1660e01b81526004016124629190600060e0820190506001600160a01b038084511683528060208501511660208401526040840151151560408401528060608501511660608401528060808501511660808401525060a083015160a083015262ffffff60c08401511660c083015292915050565b600060405180830381600087803b15801561247c57600080fd5b505af1158015612490573d6000803e3d6000fd5b50505050600460009054906101000a90046001600160a01b03166001600160a01b0316639654a3096040518060e001604052808a604001518a815181106124e757634e487b7160e01b600052603260045260246000fd5b6020026020010151604001516001600160a01b03168152602001846001600160a01b031681526020016000151581526020018b604001516001600160a01b031681526020018b600001516001600160a01b031681526020018581526020018a604001518a8151811061256957634e487b7160e01b600052603260045260246000fd5b60200260200101516080015162ffffff168152506040518263ffffffff1660e01b81526004016125fa9190600060e0820190506001600160a01b038084511683528060208501511660208401526040840151151560408401528060608501511660608401528060808501511660808401525060a083015160a083015262ffffff60c08401511660c083015292915050565b600060405180830381600087803b15801561261457600080fd5b505af1158015612628573d6000803e3d6000fd5b5050505050505050505b8260800151818151811061265657634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b03166342842e0e3085600001518660800151858151811061269a57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015101516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b1580156126f757600080fd5b505af115801561270b573d6000803e3d6000fd5b50505050808061271a90614e95565b9150506119cc565b60005b8160a0015151811015610bbd578160a00151818151811061275657634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b031663f242432a836020015184600001518560a00151858151811061279e57634e487b7160e01b600052603260045260246000fd5b6020026020010151602001518660a0015186815181106127ce57634e487b7160e01b600052603260045260246000fd5b602090810291909101015160409081015190516001600160e01b031960e087901b1681526001600160a01b0394851660048201529390921660248401526044830152606482015260a06084820152600060a482015260c401600060405180830381600087803b15801561284057600080fd5b505af1158015612854573d6000803e3d6000fd5b50505050808061286390614e95565b915050612725565b6003546000906001600160a01b03166128ee576040805162461bcd60e51b81526020600482015260248101919091527f5061796d656e744d6f64756c6556313a3a70726f636573735061796d656e743a60448201527f3a5a45524f3a20555344207061796d656e7473206e6f7420656e61626c65642e6064820152608401610baa565b8415612e8a576003546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561293857600080fd5b505afa15801561294c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612970919061497f565b905034156129885761298186613960565b91506129a0565b6003546129a0906001600160a01b0316863089613781565b6003546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b1580156129e457600080fd5b505afa1580156129f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1c919061497f565b90506000612a2a8383614e3b565b905087811015612ac85760405162461bcd60e51b815260206004820152604d60248201527f4e6f7420656e6f7567682055534420726563656976656420746f20636f76657260448201527f20666565732e2055534420746f6b656e206d757374206e6f742068617665207460648201527f72616e7366657220666565732e00000000000000000000000000000000000000608482015260a401610baa565b876001600160a01b03871615612b6a576000612710612ae96109c48c614e1c565b612af39190614dfc565b600354909150612b0d906001600160a01b031689836113f8565b612b178183614e3b565b600c54604080516001600160a01b038c8116825260208201869052939550928a16927fa1226f693825711d4115bffd17913b315dbf5a69dc7e9b963cde08921992b792910160405180910390a35043600c555b6002546001600160a01b031615612e1e576000612710612b8c6109c48c614e1c565b612b969190614dfc565b6002546040516370a0823160e01b815261dead60048201529192506000916001600160a01b03909116906370a082319060240160206040518083038186803b158015612be157600080fd5b505afa158015612bf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c19919061497f565b600454600354919250612c39916001600160a01b039081169116846137b9565b6004546003546002546007546000936001600160a01b0390811693636b27a811939082169288929182169161dead9116612c71613cc3565b6040518763ffffffff1660e01b8152600401612c9296959493929190614bbe565b602060405180830381600087803b158015612cac57600080fd5b505af1158015612cc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ce49190614713565b9050612cf08385614e3b565b935080612d3f5760405162461bcd60e51b815260206004820152600b60248201527f53776170206661696c65640000000000000000000000000000000000000000006044820152606401610baa565b6002546040516370a0823160e01b815261dead600482015260009184916001600160a01b03909116906370a082319060240160206040518083038186803b158015612d8957600080fd5b505afa158015612d9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dc1919061497f565b612dcb9190614e3b565b600b5460408051878152602081018490529293506001600160a01b038d16927f4124ef036039a90351b9862218c2417806e83bc3ec8152a46a64b6dc33f12d1f910160405180910390a3505043600b5550505b600954600354612e3b916001600160a01b039182169116836113f8565b856001600160a01b0316600a547ff1d6c8ee14081f641e2073a1064d870f135f1001a301c6b14a7b9655672fec1183604051612e7991815260200190565b60405180910390a3505043600a5550505b949350505050565b60065460085460405163800e38b760e01b81526001600160a01b039182166004820152600092919091169063800e38b790602401600060405180830381600087803b158015612ee057600080fd5b505af1158015612ef4573d6000803e3d6000fd5b50506006546008546005546040805162a6016560e31b81529051600096506001600160a01b039485169550637089f2bf9493841693909216916305300b2891600480820192602092909190829003018186803b158015612f5357600080fd5b505afa158015612f67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f8b91906149ba565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260ff16602482015260440160206040518083038186803b158015612fd257600080fd5b505afa158015612fe6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061300a919061497f565b9050600081116130a85760405162461bcd60e51b815260206004820152604b60248201527f5061796d656e744d6f64756c6556313a3a70726f636573735061796d656e743a60448201527f3a494e56414c49443a2050726963652066726f6d206f7261636c65206973207560648201527f6e617661696c61626c652e000000000000000000000000000000000000000000608482015260a401610baa565b6000816130bd87670de0b6b3a7640000614e1c565b6130c79190614dfc565b9050803410156131655760405162461bcd60e51b815260206004820152605660248201527f5061796d656e744d6f64756c6556313a3a70726f636573735061796d656e743a60448201527f3a494e56414c49443a204e6f7420656e6f756768204e617469766520546f6b6560648201527f6e732073656e7420746f20636f76657220666565732e00000000000000000000608482015260a401610baa565b61316f8134614e3b565b92506001600160a01b038516156132ee5760006127106131916109c484614e1c565b61319b9190614dfc565b90506000866001600160a01b03168260405160006040518083038185875af1925050503d80600081146131ea576040519150601f19603f3d011682016040523d82523d6000602084013e6131ef565b606091505b50509050806132665760405162461bcd60e51b815260206004820152602860248201527f4661696c656420746f2073656e64206e617469766520736861726520746f207260448201527f656665727265722e0000000000000000000000000000000000000000000000006064820152608401610baa565b6132708284614e3b565b925060006127106132836109c48b614e1c565b61328d9190614dfc565b9050613299818a614e3b565b600c54604080516001600160a01b038c8116825260208201869052939c50928a16927fa1226f693825711d4115bffd17913b315dbf5a69dc7e9b963cde08921992b792910160405180910390a3505043600c55505b6009546040516000916001600160a01b03169083908381818185875af1925050503d806000811461333b576040519150601f19603f3d011682016040523d82523d6000602084013e613340565b606091505b50509050806133b75760405162461bcd60e51b815260206004820152602860248201527f4661696c656420746f2073656e64206e617469766520746f6b656e20746f207460448201527f726561737572792e0000000000000000000000000000000000000000000000006064820152608401610baa565b846001600160a01b0316600a547ff1d6c8ee14081f641e2073a1064d870f135f1001a301c6b14a7b9655672fec11896040516133f591815260200190565b60405180910390a3505043600a55509392505050565b600754600090600160a01b900460ff16156134ab57600760009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b15801561346e57600080fd5b505afa158015613482573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134a69190614537565b905090565b600760009054906101000a90046001600160a01b03166001600160a01b0316634aa4a4fc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561346e57600080fd5b600061099f825490565b600081815260018301602052604081205461354a5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561099f565b50600061099f565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610bbd5761358e816001600160a01b03166014613d78565b613599836020613d78565b6040516020016135aa929190614a93565b60408051601f198184030181529082905262461bcd60e51b8252610baa91600401614c3e565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615610bbd576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610ded836001600160a01b038416613f67565b60006136b9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166140849092919063ffffffff16565b805190915015610b2b57808060200190518101906136d79190614713565b610b2b5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610baa565b600082600001828154811061376e57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b6040516001600160a01b0380851660248301528316604482015260648101829052610cdc9085906323b872dd60e01b90608401611424565b8015806138425750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b15801561380857600080fd5b505afa15801561381c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613840919061497f565b155b6138b45760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610baa565b6040516001600160a01b038316602482015260448101829052610b2b90849063095ea7b360e01b90606401611424565b6000816001600160a01b031663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b15801561391f57600080fd5b505afa92505050801561394f575060408051601f3d908101601f1916820190925261394c91810190614537565b60015b61099f57506000919050565b919050565b6007546000904790600160a01b900460ff1615613b16576040805160028082526060820183526000926020830190803683375050600754604080516315ab88c960e31b815290519394506001600160a01b039091169263ad5c464892506004808301926020929190829003018186803b1580156139dc57600080fd5b505afa1580156139f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a149190614537565b81600081518110613a3557634e487b7160e01b600052603260045260246000fd5b6001600160a01b039283166020918202929092010152600354825191169082906001908110613a7457634e487b7160e01b600052603260045260246000fd5b6001600160a01b03928316602091820292909201015260075460405163fb3bdb4160e01b815291169063fb3bdb41903490613ab9908890869030904290600401614c71565b6000604051808303818588803b158015613ad257600080fd5b505af1158015613ae6573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f19168201604052613b0f91908101906146c4565b5050613caf565b6040805160e081018083526007546312a9293f60e21b909152915160009282916001600160a01b0390911690634aa4a4fc9060e480850191602091818703018186803b158015613b6557600080fd5b505afa158015613b79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b9d9190614537565b6001600160a01b0390811682526003548116602080840191909152600854600160a01b900462ffffff9081166040808601919091523060608087019190915260808087018c90523460a0808901829052600060c0998a01526007548551635023b4df60e01b81528b518a166004820152978b015189166024890152948a01519095166044870152918801518616606486015287015160848501529186015160a484015293850151831660c4830152939450911691635023b4df9160e4016020604051808303818588803b158015613c7357600080fd5b505af1158015613c87573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190613cac919061497f565b50505b613cb94782614e3b565b610ded9034614e3b565b60408051600280825260608083018452926000929190602083019080368337019050509050600860149054906101000a900462ffffff1681600081518110613d1b57634e487b7160e01b600052603260045260246000fd5b62ffffff92831660209182029290920101526008548251600160b81b9091049091169082906001908110613d5f57634e487b7160e01b600052603260045260246000fd5b62ffffff90921660209283029190910190910152919050565b60606000613d87836002614e1c565b613d92906002614de4565b67ffffffffffffffff811115613db857634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613de2576020820181803683370190505b509050600360fc1b81600081518110613e0b57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613e4857634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506000613e6c846002614e1c565b613e77906001614de4565b90505b6001811115613f18577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110613ec657634e487b7160e01b600052603260045260246000fd5b1a60f81b828281518110613eea57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93613f1181614e7e565b9050613e7a565b508315610ded5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610baa565b6000818152600183016020526040812054801561407a576000613f8b600183614e3b565b8554909150600090613f9f90600190614e3b565b9050818114614020576000866000018281548110613fcd57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905080876000018481548110613ffe57634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255918252600188019052604090208390555b855486908061403f57634e487b7160e01b600052603160045260246000fd5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061099f565b600091505061099f565b6060612e8a8484600085856001600160a01b0385163b6140e65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610baa565b600080866001600160a01b031685876040516141029190614a77565b60006040518083038185875af1925050503d806000811461413f576040519150601f19603f3d011682016040523d82523d6000602084013e614144565b606091505b509150915061415482828661415f565b979650505050505050565b6060831561416e575081610ded565b82511561417e5782518084602001fd5b8160405162461bcd60e51b8152600401610baa9190614c3e565b803561395b81614edc565b600082601f8301126141b3578081fd5b815160206141c86141c383614dc0565b614d8f565b80838252828201915082860187848660051b89010111156141e7578586fd5b855b8581101561420e5781516141fc81614edc565b845292840192908401906001016141e9565b5090979650505050505050565b600082601f83011261422b578081fd5b8135602061423b6141c383614dc0565b82815281810190858301606080860288018501891015614259578687fd5b865b868110156142b35781838b031215614271578788fd5b614279614cda565b833561428481614edc565b8152838701358782015260408085013561429d81614ef1565b908201528552938501939181019160010161425b565b509198975050505050505050565b600082601f8301126142d1578081fd5b813560206142e16141c383614dc0565b828152818101908583016060808602880185018910156142ff578687fd5b865b868110156142b35781838b031215614317578788fd5b61431f614cda565b833561432a81614edc565b815283870135878201526040808501359082015285529385019391810191600101614301565b600082601f830112614360578081fd5b813560206143706141c383614dc0565b80838252828201915082860187848660061b890101111561438f578586fd5b855b8581101561420e57604080838b0312156143a9578788fd5b6143b1614d03565b83356143bc81614edc565b8152838701358782015285529385019390910190600101614391565b600082601f8301126143e8578081fd5b815160206143f86141c383614dc0565b8281528181019085830160a080860288018501891015614416578687fd5b865b868110156142b35781838b03121561442e578788fd5b614436614d26565b835161444181614edc565b81528387015161445081614edc565b8188015260408481015161446381614edc565b908201526060848101516fffffffffffffffffffffffffffffffff8116811461448a578a8bfd5b9082015260808481015161449d81614eff565b9082015285529385019391810191600101614418565b600082601f8301126144c3578081fd5b815160206144d36141c383614dc0565b80838252828201915082860187848660051b89010111156144f2578586fd5b855b8581101561420e578151845292840192908401906001016144f4565b803561395b81614ef1565b60006020828403121561452c578081fd5b8135610ded81614edc565b600060208284031215614548578081fd5b8151610ded81614edc565b600080600060608486031215614567578182fd5b833561457281614edc565b9250602084013561458281614edc565b929592945050506040919091013590565b6000806000806000608086880312156145aa578283fd5b85356145b581614edc565b945060208601356145c581614edc565b935060408601359250606086013567ffffffffffffffff808211156145e8578283fd5b818801915088601f8301126145fb578283fd5b813581811115614609578384fd5b89602082850101111561461a578384fd5b9699959850939650602001949392505050565b6000806040838503121561463f578182fd5b823561464a81614edc565b9150602083013561465a81614ef1565b809150509250929050565b60008060408385031215614677578182fd5b823561468281614edc565b946020939093013593505050565b6000806000606084860312156146a4578081fd5b83356146af81614edc565b95602085013595506040909401359392505050565b6000602082840312156146d5578081fd5b815167ffffffffffffffff8111156146eb578182fd5b612e8a848285016144b3565b600060208284031215614708578081fd5b8135610ded81614ef1565b600060208284031215614724578081fd5b8151610ded81614ef1565b600060208284031215614740578081fd5b5035919050565b60008060408385031215614759578182fd5b82359150602083013561465a81614edc565b6000806040838503121561477d578182fd5b50508035926020909101359150565b60006020828403121561479d578081fd5b81356001600160e01b031981168114610ded578182fd5b6000602082840312156147c5578081fd5b815167ffffffffffffffff808211156147dc578283fd5b90830190608082860312156147ef578283fd5b6147f7614d49565b825182811115614805578485fd5b614811878286016141a3565b825250602083015182811115614825578485fd5b614831878286016144b3565b602083015250604083015182811115614848578485fd5b614854878286016143d8565b6040830152506060830151606082015280935050505092915050565b600060208284031215614881578081fd5b813567ffffffffffffffff80821115614898578283fd5b9083019060e082860312156148ab578283fd5b6148b3614d6c565b6148bc83614198565b81526148ca60208401614198565b60208201526148db60408401614198565b60408201526060830135828111156148f1578485fd5b6148fd8782860161421b565b606083015250608083013582811115614914578485fd5b61492087828601614350565b60808301525060a083013582811115614937578485fd5b614943878286016142c1565b60a08301525061495560c08401614510565b60c082015295945050505050565b600060208284031215614974578081fd5b8135610ded81614eff565b600060208284031215614990578081fd5b5051919050565b600080604083850312156149a9578182fd5b505080516020909101519092909150565b6000602082840312156149cb578081fd5b815160ff81168114610ded578182fd5b6000815180845260208085019450808401835b83811015614a2957815180516001600160a01b03168852838101518489015260409081015190880152606090960195908201906001016149ee565b509495945050505050565b6000815180845260208085019450808401835b83811015614a2957815180516001600160a01b031688528301518388015260409096019590820190600101614a47565b60008251614a89818460208701614e52565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614acb816017850160208801614e52565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351614b08816028840160208801614e52565b01602801949350505050565b600060a082016001600160a01b038089168452602060a08186015282895180855260c087019150828b019450855b81811015614b78578551805186168452848101518585015260409081015115159084015294830194606090920191600101614b42565b50508581036040870152614b8c818a614a34565b93505050508281036060840152614ba381866149db565b915050614bb4608083018415159052565b9695505050505050565b600060c082016001600160a01b03808a1684526020898186015281891660408601528188166060860152818716608086015260c060a0860152829150855180845260e0860192508187019350845b81811015614c2d57845162ffffff1684529382019392820192600101614c0c565b50919b9a5050505050505050505050565b6020815260008251806020840152614c5d816040850160208701614e52565b601f01601f19169190910160400192915050565b600060808201868352602060808185015281875180845260a0860191508289019350845b81811015614cba5784516001600160a01b031683529383019391830191600101614c95565b50506001600160a01b039690961660408501525050506060015292915050565b6040516060810167ffffffffffffffff81118282101715614cfd57614cfd614ec6565b60405290565b6040805190810167ffffffffffffffff81118282101715614cfd57614cfd614ec6565b60405160a0810167ffffffffffffffff81118282101715614cfd57614cfd614ec6565b6040516080810167ffffffffffffffff81118282101715614cfd57614cfd614ec6565b60405160e0810167ffffffffffffffff81118282101715614cfd57614cfd614ec6565b604051601f8201601f1916810167ffffffffffffffff81118282101715614db857614db8614ec6565b604052919050565b600067ffffffffffffffff821115614dda57614dda614ec6565b5060051b60200190565b60008219821115614df757614df7614eb0565b500190565b600082614e1757634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615614e3657614e36614eb0565b500290565b600082821015614e4d57614e4d614eb0565b500390565b60005b83811015614e6d578181015183820152602001614e55565b83811115610cdc5750506000910152565b600081614e8d57614e8d614eb0565b506000190190565b6000600019821415614ea957614ea9614eb0565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461137c57600080fd5b801515811461137c57600080fd5b62ffffff8116811461137c57600080fdfea164736f6c6343000804000a5061796d656e744d6f64756c6556313a3a636f6e7374727563746f723a3a5a45000000000000000000000000cf0c122c6b73ff809c693db761e7baebe62b6a2e00000000000000000000000053b67d1172a3d90889d21c1351667ba8024abd9c000000000000000000000000fbfeef15c5a1d7415bdb48bcc2dd30e8bbb81834000000000000000000000000f5d492ffbec47db69333a6812bec227b6f670a860000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000004e8e826e6d64f711a383fa2e99e42f92a0a67d54000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
Deployed Bytecode
0x6080604052600436106103005760003560e01c8063967737c91161018f578063c54e44eb116100e1578063e1f1c4a71161008a578063e4301ec511610064578063e4301ec5146108bc578063e9948e31146108dc578063f0f44260146108fc57600080fd5b8063e1f1c4a71461087a578063e23bfa5a14610890578063e39e927b146108a657600080fd5b8063cf188ad0116100bb578063cf188ad01461081a578063d547741f1461083a578063da8055901461085a57600080fd5b8063c54e44eb146107b7578063c9d7489f146107d7578063ca15c873146107fa57600080fd5b8063b24a67c411610143578063b567f6a61161011d578063b567f6a614610760578063c170364614610781578063c3c646741461079757600080fd5b8063b24a67c4146106ec578063b24b56b01461070c578063b41c5fda1461074057600080fd5b80639a5bce1e116101745780639a5bce1e14610696578063a217fddf146106b6578063a8998b73146106cb57600080fd5b8063967737c9146106835780639a436c9b1461053e57600080fd5b806336568abe1161025357806361d027b3116101fc5780638e33a9e6116101d65780638e33a9e6146105ff5780639010d07c1461061f57806391d148541461063f57600080fd5b806361d027b3146105a957806370d5ae05146105c95780637c169123146105df57600080fd5b8063470cc5f21161022d578063470cc5f21461053e578063539c07c714610554578063595a04451461057257600080fd5b806336568abe146104de5780633e07bd5f146104fe578063401d44821461051e57600080fd5b8063150b7a02116102b557806326352aca1161028f57806326352aca1461047e5780632f2ff15d1461049e5780632f9f8c13146104be57600080fd5b8063150b7a02146103c3578063248a9ca3146104085780632630c12f1461044657600080fd5b806305d719f1116102e657806305d719f1146103635780630c3244de146103835780630f395b77146103a357600080fd5b8062bbc2dc1461030c57806301ffc9a71461032e57600080fd5b3661030757005b600080fd5b34801561031857600080fd5b5061032c61032736600461451b565b61091c565b005b34801561033a57600080fd5b5061034e61034936600461478c565b61097a565b60405190151581526020015b60405180910390f35b34801561036f57600080fd5b5061032c61037e36600461451b565b6109a5565b34801561038f57600080fd5b5061032c61039e366004614963565b610a03565b3480156103af57600080fd5b5061032c6103be36600461451b565b610a7e565b3480156103cf57600080fd5b506103ef6103de366004614593565b630a85bd0160e11b95945050505050565b6040516001600160e01b0319909116815260200161035a565b34801561041457600080fd5b5061043861042336600461472f565b60009081526020819052604090206001015490565b60405190815260200161035a565b34801561045257600080fd5b50600654610466906001600160a01b031681565b6040516001600160a01b03909116815260200161035a565b34801561048a57600080fd5b5061032c610499366004614665565b610aac565b3480156104aa57600080fd5b5061032c6104b9366004614747565b610b06565b3480156104ca57600080fd5b50600254610466906001600160a01b031681565b3480156104ea57600080fd5b5061032c6104f9366004614747565b610b30565b34801561050a57600080fd5b5061032c610519366004614553565b610bc1565b34801561052a57600080fd5b5061032c610539366004614665565b610c20565b34801561054a57600080fd5b506104386109c481565b34801561056057600080fd5b506007546001600160a01b0316610466565b34801561057e57600080fd5b5060085461059590600160a01b900462ffffff1681565b60405162ffffff909116815260200161035a565b3480156105b557600080fd5b50600954610466906001600160a01b031681565b3480156105d557600080fd5b5061046661dead81565b3480156105eb57600080fd5b5061032c6105fa366004614963565b610cfc565b34801561060b57600080fd5b5061032c61061a36600461451b565b610d77565b34801561062b57600080fd5b5061046661063a36600461476b565b610dd5565b34801561064b57600080fd5b5061034e61065a366004614747565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b61032c610691366004614870565b610df4565b3480156106a257600080fd5b5061032c6106b1366004614690565b610feb565b3480156106c257600080fd5b50610438600081565b3480156106d757600080fd5b5060075461034e90600160a01b900460ff1681565b3480156106f857600080fd5b5061032c6107073660046146f7565b611048565b34801561071857600080fd5b506104387f4a76dea3a6231aa5446f85ecde36fb499385f0f3539e800a138fb9855200db6781565b34801561074c57600080fd5b50600454610466906001600160a01b031681565b34801561076c57600080fd5b5060095461034e90600160a01b900460ff1681565b34801561078d57600080fd5b50610438600c5481565b3480156107a357600080fd5b5061032c6107b236600461462d565b61108d565b3480156107c357600080fd5b50600354610466906001600160a01b031681565b3480156107e357600080fd5b5060085461059590600160b81b900462ffffff1681565b34801561080657600080fd5b5061043861081536600461472f565b61113f565b34801561082657600080fd5b50600754610466906001600160a01b031681565b34801561084657600080fd5b5061032c610855366004614747565b611156565b34801561086657600080fd5b5061032c61087536600461451b565b61117b565b34801561088657600080fd5b5061043861271081565b34801561089c57600080fd5b50610438600a5481565b3480156108b257600080fd5b50610438600b5481565b3480156108c857600080fd5b50600854610466906001600160a01b031681565b3480156108e857600080fd5b50600554610466906001600160a01b031681565b34801561090857600080fd5b5061032c61091736600461451b565b611261565b600061092781611372565b600480546001600160a01b038481166001600160a01b0319831681179093556040519116919082907fbe4d92296304c08899e8f09ed9f0a81a36aacbb92e06937db35b74c190386d3290600090a3505050565b60006001600160e01b03198216635a05180f60e01b148061099f575061099f8261137f565b92915050565b60006109b081611372565b600580546001600160a01b038481166001600160a01b0319831681179093556040519116919082907fa8cb7494a9dfd9a9217c6ae355438f169643a50bb6f7cd1046379e3a91b07efd90600090a3505050565b6000610a0e81611372565b6008805462ffffff848116600160a01b8181027fffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffff85161790945560405193909204169182907fdd1f92c0541e60b8bc0cd45489a4e214b5cab667a3e8f147a8677a4c8f87ebc590600090a3505050565b6000610a8981611372565b50600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000610ab781611372565b826001600160a01b0316600a547ff1d6c8ee14081f641e2073a1064d870f135f1001a301c6b14a7b9655672fec1184604051610af591815260200190565b60405180910390a3505043600a5550565b600082815260208190526040902060010154610b2181611372565b610b2b83836113b4565b505050565b6001600160a01b0381163314610bb35760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b610bbd82826113d6565b5050565b6000610bcc81611372565b600c54604080516001600160a01b03868116825260208201869052871692917fa1226f693825711d4115bffd17913b315dbf5a69dc7e9b963cde08921992b792910160405180910390a3505043600c555050565b6000610c2b81611372565b6001600160a01b038316610ce2576009546040516000916001600160a01b03169084908381818185875af1925050503d8060008114610c86576040519150601f19603f3d011682016040523d82523d6000602084013e610c8b565b606091505b5050905080610cdc5760405162461bcd60e51b815260206004820152601660248201527f4661696c656420746f20776974686472617720455448000000000000000000006044820152606401610baa565b50505050565b600954610b2b906001600160a01b038581169116846113f8565b6000610d0781611372565b6008805462ffffff848116600160b81b8181027fffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffff85161790945560405193909204169182907ffb035cdf0e93aa8f8469ceb9666561d4b90efbaed8a99bd4ad341ce175cf16e390600090a3505050565b6000610d8281611372565b600680546001600160a01b038481166001600160a01b0319831681179093556040519116919082907f94c475b625ea2cd275733bbd42692872062c157920702a9588e68c9a9410def890600090a3505050565b6000828152600160205260408120610ded9083611470565b9392505050565b7f4a76dea3a6231aa5446f85ecde36fb499385f0f3539e800a138fb9855200db67610e1e81611372565b60055460208301516060840151608085015160a086015160c0870151604051637f53bed960e01b81526000966001600160a01b031695637f53bed995610e6f95919490939192909190600401614b14565b60006040518083038186803b158015610e8757600080fd5b505afa158015610e9b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ec391908101906147b4565b9050610ecf838261147c565b610ed983826119c9565b610ee283612722565b600954600090600160a01b900460ff1680610efb575034155b15610f2357610f1c826060015185602001518660400151876000015161286b565b9050610f3d565b610f3a826060015185604001518660000151612e92565b90505b600084602001516001600160a01b03168260405160006040518083038185875af1925050503d8060008114610f8e576040519150601f19603f3d011682016040523d82523d6000602084013e610f93565b606091505b5050905080610fe45760405162461bcd60e51b815260206004820152601d60248201527f4661696c656420746f20726566756e64206c6566746f766572204554480000006044820152606401610baa565b5050505050565b6000610ff681611372565b600b5460408051858152602081018590526001600160a01b03871692917f4124ef036039a90351b9862218c2417806e83bc3ec8152a46a64b6dc33f12d1f910160405180910390a3505043600b555050565b600061105381611372565b5060098054911515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b600061109881611372565b600780546001600160a01b038581167fffffffffffffffffffffff000000000000000000000000000000000000000000831617600160a01b8615150217909255166110e161340b565b600880546001600160a01b0319166001600160a01b039283161790556040518415158152858216918316907f80fdee3512206975d63f674069eae3e0b0bbf7b91e1769587e8e3dfb272f991d9060200160405180910390a350505050565b600081815260016020526040812061099f906134f9565b60008281526020819052604090206001015461117181611372565b610b2b83836113d6565b600061118681611372565b6001600160a01b03821661120e5760405162461bcd60e51b815260206004820152604360248201527f4c50546f6b656e50726f636573736f7256323a3a736574557364546f6b656e3a60448201527f3a5a45524f3a20555344542063616e6e6f74206265207a65726f20616464726560648201526239b99760e91b608482015260a401610baa565b600380546001600160a01b038481166001600160a01b0319831681179093556040519116919082907f40f67e76635d70f4e4c56ec98d9668a3c2ad514af7829718b7d83c44b25d370390600090a3505050565b600061126c81611372565b600980546001600160a01b038481166001600160a01b0319831681179093556040519116919082907f430359a6d97ced2b6f93c77a91e7ce9dfd43252eb91e916adba170485cd8a6a490600090a3505050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610bbd576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556113193390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610ded836001600160a01b038416613503565b61137c8133613552565b50565b60006001600160e01b03198216637965db0b60e01b148061099f57506301ffc9a760e01b6001600160e01b031983161461099f565b6113be82826112bf565b6000828152600160205260409020610b2b908261135d565b6113e082826135d0565b6000828152600160205260409020610b2b908261364f565b6040516001600160a01b038316602482015260448101829052610b2b90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b031990931692909217909152613664565b6000610ded8383613749565b60005b826060015151811015610b2b576000836060015182815181106114b257634e487b7160e01b600052603260045260246000fd5b6020908102919091010151516040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156114fe57600080fd5b505afa158015611512573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611536919061497f565b90506115ba8460200151308660600151858151811061156557634e487b7160e01b600052603260045260246000fd5b6020026020010151602001518760600151868151811061159557634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b0316613781909392919063ffffffff16565b600081856060015184815181106115e157634e487b7160e01b600052603260045260246000fd5b6020908102919091010151516040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561162d57600080fd5b505afa158015611641573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611665919061497f565b61166f9190614e3b565b90506116f885600001518560200151858151811061169d57634e487b7160e01b600052603260045260246000fd5b6020026020010151836116b09190614e3b565b876060015186815181106116d457634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b03166113f89092919063ffffffff16565b835180518490811061171a57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03168560600151848151811061174f57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b031614156119b457600454602085015180516117f1926001600160a01b03169190869081106117a157634e487b7160e01b600052603260045260246000fd5b6020026020010151876060015186815181106117cd57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b03166137b99092919063ffffffff16565b600460009054906101000a90046001600160a01b03166001600160a01b0316639654a3096040518060e001604052808860600151878151811061184457634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b031681526020016118968960600151888151811061188557634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516138e4565b6001600160a01b0316815260200160011515815260200188604001516001600160a01b0316815260200188600001516001600160a01b03168152602001876020015187815181106118f757634e487b7160e01b600052603260045260246000fd5b6020908102919091018101518252600091810191909152604080516001600160e01b031960e086901b16815283516001600160a01b039081166004830152928401518316602482015290830151151560448201526060830151821660648201526080830151909116608482015260a082015160a482015260c09091015162ffffff1660c482015260e401600060405180830381600087803b15801561199b57600080fd5b505af11580156119af573d6000803e3d6000fd5b505050505b505080806119c190614e95565b91505061147f565b60005b826080015151811015610b2b57826080015181815181106119fd57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b03166342842e0e84602001513086608001518581518110611a4157634e487b7160e01b600052603260045260246000fd5b60209081029190910181015101516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b158015611a9e57600080fd5b505af1158015611ab2573d6000803e3d6000fd5b5050505081604001518181518110611ada57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b031683608001518281518110611b1357634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b0316141561263257600082604001518281518110611b5457634e487b7160e01b600052603260045260246000fd5b6020026020010151606001516fffffffffffffffffffffffffffffffff1611611c0b5760405162461bcd60e51b815260206004820152604a60248201527f5061796d656e744d6f64756c6556313a3a70726f636573735061796d656e743a60448201527f3a5a45524f3a204c697175696469747920746f2072656d6f76652063616e6e6f60648201527f74206265207a65726f2e00000000000000000000000000000000000000000000608482015260a401610baa565b600082604001518281518110611c3157634e487b7160e01b600052603260045260246000fd5b60209081029190910181015101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015611c7f57600080fd5b505afa158015611c93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb7919061497f565b9050600083604001518381518110611cdf57634e487b7160e01b600052603260045260246000fd5b602090810291909101015160409081015190516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015611d2f57600080fd5b505afa158015611d43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d67919061497f565b905083604001518381518110611d8d57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b0316630c49ccbe6040518060a0016040528088608001518781518110611dd657634e487b7160e01b600052603260045260246000fd5b602002602001015160200151815260200187604001518781518110611e0b57634e487b7160e01b600052603260045260246000fd5b6020026020010151606001516fffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001428152506040518263ffffffff1660e01b8152600401611ea39190600060a082019050825182526fffffffffffffffffffffffffffffffff602084015116602083015260408301516040830152606083015160608301526080830151608083015292915050565b6040805180830381600087803b158015611ebc57600080fd5b505af1158015611ed0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef49190614997565b505083604001518381518110611f1a57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b031663fc6f7865604051806080016040528088608001518781518110611f6357634e487b7160e01b600052603260045260246000fd5b602090810291909101810151810151825230828201526fffffffffffffffffffffffffffffffff6040808401829052606093840182905280516001600160e01b031960e088901b16815285516004820152928501516001600160a01b0316602484015284015181166044830152929091015190911660648201526084016040805180830381600087803b158015611ff957600080fd5b505af115801561200d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120319190614997565b50506000828560400151858151811061205a57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156120a857600080fd5b505afa1580156120bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e0919061497f565b6120ea9190614e3b565b90506000828660400151868151811061211357634e487b7160e01b600052603260045260246000fd5b602090810291909101015160409081015190516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561216357600080fd5b505afa158015612177573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061219b919061497f565b6121a59190614e3b565b90506000866040015186815181106121cd57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b031663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b15801561221157600080fd5b505afa158015612225573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122499190614537565b90506122ad600460009054906101000a90046001600160a01b0316848960400151898151811061228957634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160a01b03166137b99092919063ffffffff16565b60045460408801518051612309926001600160a01b03169185918a9081106122e557634e487b7160e01b600052603260045260246000fd5b6020026020010151604001516001600160a01b03166137b99092919063ffffffff16565b6004546040805160e0810182529089015180516001600160a01b0390931692639654a309929182918b90811061234f57634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160a01b03168152602001846001600160a01b031681526020016000151581526020018b604001516001600160a01b031681526020018b600001516001600160a01b031681526020018681526020018a604001518a815181106123d157634e487b7160e01b600052603260045260246000fd5b60200260200101516080015162ffffff168152506040518263ffffffff1660e01b81526004016124629190600060e0820190506001600160a01b038084511683528060208501511660208401526040840151151560408401528060608501511660608401528060808501511660808401525060a083015160a083015262ffffff60c08401511660c083015292915050565b600060405180830381600087803b15801561247c57600080fd5b505af1158015612490573d6000803e3d6000fd5b50505050600460009054906101000a90046001600160a01b03166001600160a01b0316639654a3096040518060e001604052808a604001518a815181106124e757634e487b7160e01b600052603260045260246000fd5b6020026020010151604001516001600160a01b03168152602001846001600160a01b031681526020016000151581526020018b604001516001600160a01b031681526020018b600001516001600160a01b031681526020018581526020018a604001518a8151811061256957634e487b7160e01b600052603260045260246000fd5b60200260200101516080015162ffffff168152506040518263ffffffff1660e01b81526004016125fa9190600060e0820190506001600160a01b038084511683528060208501511660208401526040840151151560408401528060608501511660608401528060808501511660808401525060a083015160a083015262ffffff60c08401511660c083015292915050565b600060405180830381600087803b15801561261457600080fd5b505af1158015612628573d6000803e3d6000fd5b5050505050505050505b8260800151818151811061265657634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b03166342842e0e3085600001518660800151858151811061269a57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015101516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b1580156126f757600080fd5b505af115801561270b573d6000803e3d6000fd5b50505050808061271a90614e95565b9150506119cc565b60005b8160a0015151811015610bbd578160a00151818151811061275657634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b031663f242432a836020015184600001518560a00151858151811061279e57634e487b7160e01b600052603260045260246000fd5b6020026020010151602001518660a0015186815181106127ce57634e487b7160e01b600052603260045260246000fd5b602090810291909101015160409081015190516001600160e01b031960e087901b1681526001600160a01b0394851660048201529390921660248401526044830152606482015260a06084820152600060a482015260c401600060405180830381600087803b15801561284057600080fd5b505af1158015612854573d6000803e3d6000fd5b50505050808061286390614e95565b915050612725565b6003546000906001600160a01b03166128ee576040805162461bcd60e51b81526020600482015260248101919091527f5061796d656e744d6f64756c6556313a3a70726f636573735061796d656e743a60448201527f3a5a45524f3a20555344207061796d656e7473206e6f7420656e61626c65642e6064820152608401610baa565b8415612e8a576003546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561293857600080fd5b505afa15801561294c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612970919061497f565b905034156129885761298186613960565b91506129a0565b6003546129a0906001600160a01b0316863089613781565b6003546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b1580156129e457600080fd5b505afa1580156129f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1c919061497f565b90506000612a2a8383614e3b565b905087811015612ac85760405162461bcd60e51b815260206004820152604d60248201527f4e6f7420656e6f7567682055534420726563656976656420746f20636f76657260448201527f20666565732e2055534420746f6b656e206d757374206e6f742068617665207460648201527f72616e7366657220666565732e00000000000000000000000000000000000000608482015260a401610baa565b876001600160a01b03871615612b6a576000612710612ae96109c48c614e1c565b612af39190614dfc565b600354909150612b0d906001600160a01b031689836113f8565b612b178183614e3b565b600c54604080516001600160a01b038c8116825260208201869052939550928a16927fa1226f693825711d4115bffd17913b315dbf5a69dc7e9b963cde08921992b792910160405180910390a35043600c555b6002546001600160a01b031615612e1e576000612710612b8c6109c48c614e1c565b612b969190614dfc565b6002546040516370a0823160e01b815261dead60048201529192506000916001600160a01b03909116906370a082319060240160206040518083038186803b158015612be157600080fd5b505afa158015612bf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c19919061497f565b600454600354919250612c39916001600160a01b039081169116846137b9565b6004546003546002546007546000936001600160a01b0390811693636b27a811939082169288929182169161dead9116612c71613cc3565b6040518763ffffffff1660e01b8152600401612c9296959493929190614bbe565b602060405180830381600087803b158015612cac57600080fd5b505af1158015612cc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ce49190614713565b9050612cf08385614e3b565b935080612d3f5760405162461bcd60e51b815260206004820152600b60248201527f53776170206661696c65640000000000000000000000000000000000000000006044820152606401610baa565b6002546040516370a0823160e01b815261dead600482015260009184916001600160a01b03909116906370a082319060240160206040518083038186803b158015612d8957600080fd5b505afa158015612d9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dc1919061497f565b612dcb9190614e3b565b600b5460408051878152602081018490529293506001600160a01b038d16927f4124ef036039a90351b9862218c2417806e83bc3ec8152a46a64b6dc33f12d1f910160405180910390a3505043600b5550505b600954600354612e3b916001600160a01b039182169116836113f8565b856001600160a01b0316600a547ff1d6c8ee14081f641e2073a1064d870f135f1001a301c6b14a7b9655672fec1183604051612e7991815260200190565b60405180910390a3505043600a5550505b949350505050565b60065460085460405163800e38b760e01b81526001600160a01b039182166004820152600092919091169063800e38b790602401600060405180830381600087803b158015612ee057600080fd5b505af1158015612ef4573d6000803e3d6000fd5b50506006546008546005546040805162a6016560e31b81529051600096506001600160a01b039485169550637089f2bf9493841693909216916305300b2891600480820192602092909190829003018186803b158015612f5357600080fd5b505afa158015612f67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f8b91906149ba565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260ff16602482015260440160206040518083038186803b158015612fd257600080fd5b505afa158015612fe6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061300a919061497f565b9050600081116130a85760405162461bcd60e51b815260206004820152604b60248201527f5061796d656e744d6f64756c6556313a3a70726f636573735061796d656e743a60448201527f3a494e56414c49443a2050726963652066726f6d206f7261636c65206973207560648201527f6e617661696c61626c652e000000000000000000000000000000000000000000608482015260a401610baa565b6000816130bd87670de0b6b3a7640000614e1c565b6130c79190614dfc565b9050803410156131655760405162461bcd60e51b815260206004820152605660248201527f5061796d656e744d6f64756c6556313a3a70726f636573735061796d656e743a60448201527f3a494e56414c49443a204e6f7420656e6f756768204e617469766520546f6b6560648201527f6e732073656e7420746f20636f76657220666565732e00000000000000000000608482015260a401610baa565b61316f8134614e3b565b92506001600160a01b038516156132ee5760006127106131916109c484614e1c565b61319b9190614dfc565b90506000866001600160a01b03168260405160006040518083038185875af1925050503d80600081146131ea576040519150601f19603f3d011682016040523d82523d6000602084013e6131ef565b606091505b50509050806132665760405162461bcd60e51b815260206004820152602860248201527f4661696c656420746f2073656e64206e617469766520736861726520746f207260448201527f656665727265722e0000000000000000000000000000000000000000000000006064820152608401610baa565b6132708284614e3b565b925060006127106132836109c48b614e1c565b61328d9190614dfc565b9050613299818a614e3b565b600c54604080516001600160a01b038c8116825260208201869052939c50928a16927fa1226f693825711d4115bffd17913b315dbf5a69dc7e9b963cde08921992b792910160405180910390a3505043600c55505b6009546040516000916001600160a01b03169083908381818185875af1925050503d806000811461333b576040519150601f19603f3d011682016040523d82523d6000602084013e613340565b606091505b50509050806133b75760405162461bcd60e51b815260206004820152602860248201527f4661696c656420746f2073656e64206e617469766520746f6b656e20746f207460448201527f726561737572792e0000000000000000000000000000000000000000000000006064820152608401610baa565b846001600160a01b0316600a547ff1d6c8ee14081f641e2073a1064d870f135f1001a301c6b14a7b9655672fec11896040516133f591815260200190565b60405180910390a3505043600a55509392505050565b600754600090600160a01b900460ff16156134ab57600760009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b15801561346e57600080fd5b505afa158015613482573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134a69190614537565b905090565b600760009054906101000a90046001600160a01b03166001600160a01b0316634aa4a4fc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561346e57600080fd5b600061099f825490565b600081815260018301602052604081205461354a5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561099f565b50600061099f565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610bbd5761358e816001600160a01b03166014613d78565b613599836020613d78565b6040516020016135aa929190614a93565b60408051601f198184030181529082905262461bcd60e51b8252610baa91600401614c3e565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615610bbd576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610ded836001600160a01b038416613f67565b60006136b9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166140849092919063ffffffff16565b805190915015610b2b57808060200190518101906136d79190614713565b610b2b5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610baa565b600082600001828154811061376e57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b6040516001600160a01b0380851660248301528316604482015260648101829052610cdc9085906323b872dd60e01b90608401611424565b8015806138425750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b15801561380857600080fd5b505afa15801561381c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613840919061497f565b155b6138b45760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610baa565b6040516001600160a01b038316602482015260448101829052610b2b90849063095ea7b360e01b90606401611424565b6000816001600160a01b031663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b15801561391f57600080fd5b505afa92505050801561394f575060408051601f3d908101601f1916820190925261394c91810190614537565b60015b61099f57506000919050565b919050565b6007546000904790600160a01b900460ff1615613b16576040805160028082526060820183526000926020830190803683375050600754604080516315ab88c960e31b815290519394506001600160a01b039091169263ad5c464892506004808301926020929190829003018186803b1580156139dc57600080fd5b505afa1580156139f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a149190614537565b81600081518110613a3557634e487b7160e01b600052603260045260246000fd5b6001600160a01b039283166020918202929092010152600354825191169082906001908110613a7457634e487b7160e01b600052603260045260246000fd5b6001600160a01b03928316602091820292909201015260075460405163fb3bdb4160e01b815291169063fb3bdb41903490613ab9908890869030904290600401614c71565b6000604051808303818588803b158015613ad257600080fd5b505af1158015613ae6573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f19168201604052613b0f91908101906146c4565b5050613caf565b6040805160e081018083526007546312a9293f60e21b909152915160009282916001600160a01b0390911690634aa4a4fc9060e480850191602091818703018186803b158015613b6557600080fd5b505afa158015613b79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b9d9190614537565b6001600160a01b0390811682526003548116602080840191909152600854600160a01b900462ffffff9081166040808601919091523060608087019190915260808087018c90523460a0808901829052600060c0998a01526007548551635023b4df60e01b81528b518a166004820152978b015189166024890152948a01519095166044870152918801518616606486015287015160848501529186015160a484015293850151831660c4830152939450911691635023b4df9160e4016020604051808303818588803b158015613c7357600080fd5b505af1158015613c87573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190613cac919061497f565b50505b613cb94782614e3b565b610ded9034614e3b565b60408051600280825260608083018452926000929190602083019080368337019050509050600860149054906101000a900462ffffff1681600081518110613d1b57634e487b7160e01b600052603260045260246000fd5b62ffffff92831660209182029290920101526008548251600160b81b9091049091169082906001908110613d5f57634e487b7160e01b600052603260045260246000fd5b62ffffff90921660209283029190910190910152919050565b60606000613d87836002614e1c565b613d92906002614de4565b67ffffffffffffffff811115613db857634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613de2576020820181803683370190505b509050600360fc1b81600081518110613e0b57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613e4857634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506000613e6c846002614e1c565b613e77906001614de4565b90505b6001811115613f18577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110613ec657634e487b7160e01b600052603260045260246000fd5b1a60f81b828281518110613eea57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93613f1181614e7e565b9050613e7a565b508315610ded5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610baa565b6000818152600183016020526040812054801561407a576000613f8b600183614e3b565b8554909150600090613f9f90600190614e3b565b9050818114614020576000866000018281548110613fcd57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905080876000018481548110613ffe57634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255918252600188019052604090208390555b855486908061403f57634e487b7160e01b600052603160045260246000fd5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061099f565b600091505061099f565b6060612e8a8484600085856001600160a01b0385163b6140e65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610baa565b600080866001600160a01b031685876040516141029190614a77565b60006040518083038185875af1925050503d806000811461413f576040519150601f19603f3d011682016040523d82523d6000602084013e614144565b606091505b509150915061415482828661415f565b979650505050505050565b6060831561416e575081610ded565b82511561417e5782518084602001fd5b8160405162461bcd60e51b8152600401610baa9190614c3e565b803561395b81614edc565b600082601f8301126141b3578081fd5b815160206141c86141c383614dc0565b614d8f565b80838252828201915082860187848660051b89010111156141e7578586fd5b855b8581101561420e5781516141fc81614edc565b845292840192908401906001016141e9565b5090979650505050505050565b600082601f83011261422b578081fd5b8135602061423b6141c383614dc0565b82815281810190858301606080860288018501891015614259578687fd5b865b868110156142b35781838b031215614271578788fd5b614279614cda565b833561428481614edc565b8152838701358782015260408085013561429d81614ef1565b908201528552938501939181019160010161425b565b509198975050505050505050565b600082601f8301126142d1578081fd5b813560206142e16141c383614dc0565b828152818101908583016060808602880185018910156142ff578687fd5b865b868110156142b35781838b031215614317578788fd5b61431f614cda565b833561432a81614edc565b815283870135878201526040808501359082015285529385019391810191600101614301565b600082601f830112614360578081fd5b813560206143706141c383614dc0565b80838252828201915082860187848660061b890101111561438f578586fd5b855b8581101561420e57604080838b0312156143a9578788fd5b6143b1614d03565b83356143bc81614edc565b8152838701358782015285529385019390910190600101614391565b600082601f8301126143e8578081fd5b815160206143f86141c383614dc0565b8281528181019085830160a080860288018501891015614416578687fd5b865b868110156142b35781838b03121561442e578788fd5b614436614d26565b835161444181614edc565b81528387015161445081614edc565b8188015260408481015161446381614edc565b908201526060848101516fffffffffffffffffffffffffffffffff8116811461448a578a8bfd5b9082015260808481015161449d81614eff565b9082015285529385019391810191600101614418565b600082601f8301126144c3578081fd5b815160206144d36141c383614dc0565b80838252828201915082860187848660051b89010111156144f2578586fd5b855b8581101561420e578151845292840192908401906001016144f4565b803561395b81614ef1565b60006020828403121561452c578081fd5b8135610ded81614edc565b600060208284031215614548578081fd5b8151610ded81614edc565b600080600060608486031215614567578182fd5b833561457281614edc565b9250602084013561458281614edc565b929592945050506040919091013590565b6000806000806000608086880312156145aa578283fd5b85356145b581614edc565b945060208601356145c581614edc565b935060408601359250606086013567ffffffffffffffff808211156145e8578283fd5b818801915088601f8301126145fb578283fd5b813581811115614609578384fd5b89602082850101111561461a578384fd5b9699959850939650602001949392505050565b6000806040838503121561463f578182fd5b823561464a81614edc565b9150602083013561465a81614ef1565b809150509250929050565b60008060408385031215614677578182fd5b823561468281614edc565b946020939093013593505050565b6000806000606084860312156146a4578081fd5b83356146af81614edc565b95602085013595506040909401359392505050565b6000602082840312156146d5578081fd5b815167ffffffffffffffff8111156146eb578182fd5b612e8a848285016144b3565b600060208284031215614708578081fd5b8135610ded81614ef1565b600060208284031215614724578081fd5b8151610ded81614ef1565b600060208284031215614740578081fd5b5035919050565b60008060408385031215614759578182fd5b82359150602083013561465a81614edc565b6000806040838503121561477d578182fd5b50508035926020909101359150565b60006020828403121561479d578081fd5b81356001600160e01b031981168114610ded578182fd5b6000602082840312156147c5578081fd5b815167ffffffffffffffff808211156147dc578283fd5b90830190608082860312156147ef578283fd5b6147f7614d49565b825182811115614805578485fd5b614811878286016141a3565b825250602083015182811115614825578485fd5b614831878286016144b3565b602083015250604083015182811115614848578485fd5b614854878286016143d8565b6040830152506060830151606082015280935050505092915050565b600060208284031215614881578081fd5b813567ffffffffffffffff80821115614898578283fd5b9083019060e082860312156148ab578283fd5b6148b3614d6c565b6148bc83614198565b81526148ca60208401614198565b60208201526148db60408401614198565b60408201526060830135828111156148f1578485fd5b6148fd8782860161421b565b606083015250608083013582811115614914578485fd5b61492087828601614350565b60808301525060a083013582811115614937578485fd5b614943878286016142c1565b60a08301525061495560c08401614510565b60c082015295945050505050565b600060208284031215614974578081fd5b8135610ded81614eff565b600060208284031215614990578081fd5b5051919050565b600080604083850312156149a9578182fd5b505080516020909101519092909150565b6000602082840312156149cb578081fd5b815160ff81168114610ded578182fd5b6000815180845260208085019450808401835b83811015614a2957815180516001600160a01b03168852838101518489015260409081015190880152606090960195908201906001016149ee565b509495945050505050565b6000815180845260208085019450808401835b83811015614a2957815180516001600160a01b031688528301518388015260409096019590820190600101614a47565b60008251614a89818460208701614e52565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614acb816017850160208801614e52565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351614b08816028840160208801614e52565b01602801949350505050565b600060a082016001600160a01b038089168452602060a08186015282895180855260c087019150828b019450855b81811015614b78578551805186168452848101518585015260409081015115159084015294830194606090920191600101614b42565b50508581036040870152614b8c818a614a34565b93505050508281036060840152614ba381866149db565b915050614bb4608083018415159052565b9695505050505050565b600060c082016001600160a01b03808a1684526020898186015281891660408601528188166060860152818716608086015260c060a0860152829150855180845260e0860192508187019350845b81811015614c2d57845162ffffff1684529382019392820192600101614c0c565b50919b9a5050505050505050505050565b6020815260008251806020840152614c5d816040850160208701614e52565b601f01601f19169190910160400192915050565b600060808201868352602060808185015281875180845260a0860191508289019350845b81811015614cba5784516001600160a01b031683529383019391830191600101614c95565b50506001600160a01b039690961660408501525050506060015292915050565b6040516060810167ffffffffffffffff81118282101715614cfd57614cfd614ec6565b60405290565b6040805190810167ffffffffffffffff81118282101715614cfd57614cfd614ec6565b60405160a0810167ffffffffffffffff81118282101715614cfd57614cfd614ec6565b6040516080810167ffffffffffffffff81118282101715614cfd57614cfd614ec6565b60405160e0810167ffffffffffffffff81118282101715614cfd57614cfd614ec6565b604051601f8201601f1916810167ffffffffffffffff81118282101715614db857614db8614ec6565b604052919050565b600067ffffffffffffffff821115614dda57614dda614ec6565b5060051b60200190565b60008219821115614df757614df7614eb0565b500190565b600082614e1757634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615614e3657614e36614eb0565b500290565b600082821015614e4d57614e4d614eb0565b500390565b60005b83811015614e6d578181015183820152602001614e55565b83811115610cdc5750506000910152565b600081614e8d57614e8d614eb0565b506000190190565b6000600019821415614ea957614ea9614eb0565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461137c57600080fd5b801515811461137c57600080fd5b62ffffff8116811461137c57600080fdfea164736f6c6343000804000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000cf0c122c6b73ff809c693db761e7baebe62b6a2e00000000000000000000000053b67d1172a3d90889d21c1351667ba8024abd9c000000000000000000000000fbfeef15c5a1d7415bdb48bcc2dd30e8bbb81834000000000000000000000000f5d492ffbec47db69333a6812bec227b6f670a860000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000004e8e826e6d64f711a383fa2e99e42f92a0a67d54000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
-----Decoded View---------------
Arg [0] : flokiAddress (address): 0xcf0C122c6b73ff809C693DB761e7BaeBe62b6a2E
Arg [1] : lpTokenProcessorAddress (address): 0x53B67D1172a3d90889d21c1351667ba8024abd9C
Arg [2] : pricingModuleAddress (address): 0xfBFeef15c5A1D7415Bdb48Bcc2DD30e8bBb81834
Arg [3] : treasuryAddress (address): 0xf5d492fFBeC47DB69333A6812bEc227B6f670A86
Arg [4] : routerAddress (address): 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
Arg [5] : v2Router (bool): True
Arg [6] : priceOracleAddress (address): 0x4e8E826E6d64f711A383fA2e99e42F92a0A67d54
Arg [7] : usdAddress (address): 0xdAC17F958D2ee523a2206206994597C13D831ec7
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 000000000000000000000000cf0c122c6b73ff809c693db761e7baebe62b6a2e
Arg [1] : 00000000000000000000000053b67d1172a3d90889d21c1351667ba8024abd9c
Arg [2] : 000000000000000000000000fbfeef15c5a1d7415bdb48bcc2dd30e8bbb81834
Arg [3] : 000000000000000000000000f5d492ffbec47db69333a6812bec227b6f670a86
Arg [4] : 0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [6] : 0000000000000000000000004e8e826e6d64f711a383fa2e99e42f92a0a67d54
Arg [7] : 000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.