Overview
ETH Balance
0 ETH
Eth Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 476 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Cross Swap | 19693121 | 78 days ago | IN | 0.0046546 ETH | 0.00275726 | ||||
Cross Swap | 19671911 | 81 days ago | IN | 0.00972377 ETH | 0.00293351 | ||||
Cross Swap | 19108616 | 160 days ago | IN | 0.01885192 ETH | 0.00400824 | ||||
In Case Token Go... | 19025070 | 172 days ago | IN | 0 ETH | 0.00192879 | ||||
In Case Token Go... | 19025069 | 172 days ago | IN | 0 ETH | 0.00168032 | ||||
Cross Swap | 18986310 | 177 days ago | IN | 0.0149541 ETH | 0.01120268 | ||||
Cross Swap | 18966570 | 180 days ago | IN | 0.01244238 ETH | 0.00772377 | ||||
Cross Swap | 18954158 | 182 days ago | IN | 0.0749541 ETH | 0.01415341 | ||||
Cross Swap | 18948548 | 183 days ago | IN | 0.1549541 ETH | 0.00693685 | ||||
Cross Swap | 18915532 | 187 days ago | IN | 0.03153903 ETH | 0.00538819 | ||||
Cross Swap | 18866019 | 194 days ago | IN | 0.10398943 ETH | 0.00577455 | ||||
Cross Swap | 18843707 | 197 days ago | IN | 0.01398943 ETH | 0.01291842 | ||||
Cross Swap | 18843562 | 197 days ago | IN | 0.12898943 ETH | 0.01306654 | ||||
Cross Swap | 18842289 | 198 days ago | IN | 0.11398943 ETH | 0.02227591 | ||||
Cross Swap | 18825540 | 200 days ago | IN | 0.02498943 ETH | 0.01733124 | ||||
Cross Swap | 18825188 | 200 days ago | IN | 0.00798943 ETH | 0.01514124 | ||||
Cross Swap | 18825135 | 200 days ago | IN | 0.00822943 ETH | 0.01491404 | ||||
Cross Swap | 18802937 | 203 days ago | IN | 0.00548943 ETH | 0.01629362 | ||||
Cross Swap | 18781657 | 206 days ago | IN | 2.00398943 ETH | 0.02163855 | ||||
Cross Swap | 18781025 | 206 days ago | IN | 3.00398943 ETH | 0.02188543 | ||||
Cross Swap | 18780897 | 206 days ago | IN | 1.80398943 ETH | 0.02313213 | ||||
Cross Swap | 18772161 | 207 days ago | IN | 0.01298943 ETH | 0.02214167 | ||||
Cross Swap | 18751157 | 210 days ago | IN | 0.09398943 ETH | 0.01349866 | ||||
Cross Swap | 18729655 | 213 days ago | IN | 0.15398943 ETH | 0.02808453 | ||||
Cross Swap | 18729493 | 213 days ago | IN | 0.10398943 ETH | 0.0306645 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
19693121 | 78 days ago | 0.0046546 ETH | ||||
19693121 | 78 days ago | 0.004 ETH | ||||
19693121 | 78 days ago | 0.004 ETH | ||||
19671911 | 81 days ago | 0.00972377 ETH | ||||
19671911 | 81 days ago | 0.00899999 ETH | ||||
19671911 | 81 days ago | 0.00899999 ETH | ||||
19108616 | 160 days ago | 0.01885192 ETH | ||||
19108616 | 160 days ago | 0.017 ETH | ||||
19108616 | 160 days ago | 0.017 ETH | ||||
18992233 | 176 days ago | 0.04997 ETH | ||||
18992233 | 176 days ago | 0.04997 ETH | ||||
18986310 | 177 days ago | 0.0149541 ETH | ||||
18986310 | 177 days ago | 0.01 ETH | ||||
18986310 | 177 days ago | 0.01 ETH | ||||
18974903 | 179 days ago | 0.79933854 ETH | ||||
18974903 | 179 days ago | 0.79933854 ETH | ||||
18968349 | 180 days ago | 0.95313939 ETH | ||||
18968349 | 180 days ago | 0.95313939 ETH | ||||
18968203 | 180 days ago | 0.19981993 ETH | ||||
18968203 | 180 days ago | 0.19981993 ETH | ||||
18968191 | 180 days ago | 2.49775894 ETH | ||||
18968191 | 180 days ago | 2.49775894 ETH | ||||
18966570 | 180 days ago | 0.01244238 ETH | ||||
18966570 | 180 days ago | 0.012 ETH | ||||
18966570 | 180 days ago | 0.012 ETH |
Loading...
Loading
Contract Name:
WooCrossChainRouterV3
Compiler Version
v0.8.14+commit.80d49f37
Optimization Enabled:
Yes with 20000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity =0.8.14; // OpenZeppelin Contracts import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; // Local Contracts import {IWETH} from "./interfaces/IWETH.sol"; import {IWooCrossChainRouterV3} from "./interfaces/IWooCrossChainRouterV3.sol"; import {IWooRouterV2} from "./interfaces/IWooRouterV2.sol"; import {IStargateEthVault} from "./interfaces/Stargate/IStargateEthVault.sol"; import {IStargateRouter} from "./interfaces/Stargate/IStargateRouter.sol"; import {ILzApp} from "./interfaces/LayerZero/ILzApp.sol"; import {TransferHelper} from "./libraries/TransferHelper.sol"; /// @title cross chain router implementation, version 3. /// @notice Router for stateless execution of cross chain swap against WOOFi or 1inch swap. /// @custom:stargate-contracts https://stargateprotocol.gitbook.io/stargate/developers/contract-addresses/mainnet contract WooCrossChainRouterV3 is IWooCrossChainRouterV3, Ownable, Pausable, ReentrancyGuard { using EnumerableSet for EnumerableSet.AddressSet; /* ----- Constants ----- */ address public constant ETH_PLACEHOLDER_ADDR = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; /* ----- Variables ----- */ IWooRouterV2 public wooRouter; IStargateRouter public stargateRouter; address public immutable weth; address public feeAddr; uint256 public bridgeSlippage; // 1 in 10000th: default 1% uint256 public dstGasForSwapCall; uint256 public dstGasForNoSwapCall; uint16 public sgChainIdLocal; // Stargate chainId on local chain uint16 public srcExternalFeeRate; // unit: 0.1 bps (1e6 = 100%, 25 = 2.5 bps) uint16 public dstExternalFeeRate; // unit: 0.1 bps (1e6 = 100%, 25 = 2.5 bps) uint256 public constant FEE_BASE = 1e5; mapping(uint16 => address) public wooCrossRouters; // chainId => WooCrossChainRouterV3 address mapping(uint16 => address) public sgETHs; // chainId => SGETH token address mapping(uint16 => mapping(address => uint256)) public sgPoolIds; // chainId => token address => Stargate poolId receive() external payable {} constructor( address _weth, address _wooRouter, address _stargateRouter, uint16 _sgChainIdLocal ) { weth = _weth; wooRouter = IWooRouterV2(_wooRouter); stargateRouter = IStargateRouter(_stargateRouter); sgChainIdLocal = _sgChainIdLocal; bridgeSlippage = 100; dstGasForSwapCall = 660000; dstGasForNoSwapCall = 80000; srcExternalFeeRate = 25; dstExternalFeeRate = 25; _initSgETHs(); _initSgPoolIds(); } function _initSgETHs() internal { // Ethereum sgETHs[101] = 0x72E2F4830b9E45d52F80aC08CB2bEC0FeF72eD9c; // Arbitrum sgETHs[110] = 0x82CbeCF39bEe528B5476FE6d1550af59a9dB6Fc0; // Optimism sgETHs[111] = 0xb69c8CBCD90A39D8D3d3ccf0a3E968511C3856A0; // Linea sgETHs[183] = 0x224D8Fd7aB6AD4c6eb4611Ce56EF35Dec2277F03; // Base sgETHs[184] = 0x224D8Fd7aB6AD4c6eb4611Ce56EF35Dec2277F03; } function _initSgPoolIds() internal { // poolId > 0 means able to be bridge token // Ethereum sgPoolIds[101][0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48] = 1; // USDC sgPoolIds[101][0xdAC17F958D2ee523a2206206994597C13D831ec7] = 2; // USDT sgPoolIds[101][0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2] = 13; // WETH sgPoolIds[101][0x4691937a7508860F876c9c0a2a617E7d9E945D4B] = 20; // WOO // BNB Chain sgPoolIds[102][0x55d398326f99059fF775485246999027B3197955] = 2; // USDT sgPoolIds[102][0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56] = 5; // BUSD sgPoolIds[102][0x4691937a7508860F876c9c0a2a617E7d9E945D4B] = 20; // WOO // Avalanche sgPoolIds[106][0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E] = 1; // USDC sgPoolIds[106][0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7] = 2; // USDT sgPoolIds[106][0xaBC9547B534519fF73921b1FBA6E672b5f58D083] = 20; // WOO // Polygon sgPoolIds[109][0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174] = 1; // USDC sgPoolIds[109][0xc2132D05D31c914a87C6611C10748AEb04B58e8F] = 2; // USDT sgPoolIds[109][0x1B815d120B3eF02039Ee11dC2d33DE7aA4a8C603] = 20; // WOO // Arbitrum sgPoolIds[110][0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8] = 1; // USDC sgPoolIds[110][0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9] = 2; // USDT sgPoolIds[110][0x82aF49447D8a07e3bd95BD0d56f35241523fBab1] = 13; // WETH sgPoolIds[110][0xcAFcD85D8ca7Ad1e1C6F82F651fA15E33AEfD07b] = 20; // WOO // Optimism sgPoolIds[111][0x7F5c764cBc14f9669B88837ca1490cCa17c31607] = 1; // USDC sgPoolIds[111][0x4200000000000000000000000000000000000006] = 13; // WETH sgPoolIds[111][0x871f2F2ff935FD1eD867842FF2a7bfD051A5E527] = 20; // WOO // Fantom sgPoolIds[112][0x04068DA6C83AFCFA0e13ba15A6696662335D5B75] = 1; // USDC sgPoolIds[112][0x6626c47c00F1D87902fc13EECfaC3ed06D5E8D8a] = 20; // WOO // Linea sgPoolIds[183][0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f] = 13; // WETH // Base sgPoolIds[184][0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA] = 1; // USDC sgPoolIds[184][0x4200000000000000000000000000000000000006] = 13; // WETH } /* ----- Functions ----- */ function crossSwap( uint256 refId, address payable to, SrcInfos memory srcInfos, DstInfos calldata dstInfos, Src1inch calldata src1inch, Dst1inch calldata dst1inch ) external payable whenNotPaused nonReentrant { require(srcInfos.fromToken != address(0), "WooCrossChainRouterV3: !srcInfos.fromToken"); require( dstInfos.toToken != address(0) && dstInfos.toToken != sgETHs[dstInfos.chainId], "WooCrossChainRouterV3: !dstInfos.toToken" ); require(to != address(0), "WooCrossChainRouterV3: !to"); uint256 msgValue = msg.value; uint256 bridgeAmount; uint256 fee = 0; { // Step 1: transfer if (srcInfos.fromToken == ETH_PLACEHOLDER_ADDR) { require(srcInfos.fromAmount <= msgValue, "WooCrossChainRouterV3: !srcInfos.fromAmount"); srcInfos.fromToken = weth; IWETH(weth).deposit{value: srcInfos.fromAmount}(); msgValue -= srcInfos.fromAmount; } else { TransferHelper.safeTransferFrom(srcInfos.fromToken, msg.sender, address(this), srcInfos.fromAmount); } // Step 2: local swap by 1inch router if (srcInfos.fromToken != srcInfos.bridgeToken) { TransferHelper.safeApprove(srcInfos.fromToken, address(wooRouter), srcInfos.fromAmount); if (src1inch.swapRouter != address(0)) { // external swap via 1inch bridgeAmount = wooRouter.externalSwap( src1inch.swapRouter, src1inch.swapRouter, srcInfos.fromToken, srcInfos.bridgeToken, srcInfos.fromAmount, srcInfos.minBridgeAmount, payable(address(this)), src1inch.data ); fee = (bridgeAmount * srcExternalFeeRate) / FEE_BASE; } else { // swap via WOOFi bridgeAmount = wooRouter.swap( srcInfos.fromToken, srcInfos.bridgeToken, srcInfos.fromAmount, srcInfos.minBridgeAmount, payable(address(this)), to ); } } else { require( srcInfos.fromAmount == srcInfos.minBridgeAmount, "WooCrossChainRouterV3: !srcInfos.minBridgeAmount" ); bridgeAmount = srcInfos.fromAmount; } require( bridgeAmount <= IERC20(srcInfos.bridgeToken).balanceOf(address(this)), "WooCrossChainRouterV3: !bridgeAmount" ); } // Step 3: deduct the swap fee bridgeAmount -= fee; // Step 4: cross chain swap by StargateRouter _bridgeByStargate(refId, to, msgValue, bridgeAmount, srcInfos, dstInfos, dst1inch); emit WooCrossSwapOnSrcChain( refId, _msgSender(), to, srcInfos.fromToken, srcInfos.fromAmount, srcInfos.bridgeToken, srcInfos.minBridgeAmount, bridgeAmount, src1inch.swapRouter == address(0) ? 0 : 1, fee ); } function sgReceive( uint16, // srcChainId bytes memory, // srcAddress uint256, // nonce address bridgedToken, uint256 amountLD, bytes memory payload ) external { require(msg.sender == address(stargateRouter), "WooCrossChainRouterV3: INVALID_CALLER"); // make sure the same order to abi.encode when decode payload (uint256 refId, address to, address toToken, uint256 minToAmount, Dst1inch memory dst1inch) = abi.decode( payload, (uint256, address, address, uint256, Dst1inch) ); // toToken won't be SGETH, and bridgedToken won't be ETH_PLACEHOLDER_ADDR if (bridgedToken == sgETHs[sgChainIdLocal]) { // bridgedToken is SGETH, received native token _handleNativeReceived(refId, to, toToken, amountLD, minToAmount, dst1inch); } else { // bridgedToken is not SGETH, received ERC20 token _handleERC20Received(refId, to, toToken, bridgedToken, amountLD, minToAmount, dst1inch); } } function quoteLayerZeroFee( uint256 refId, address to, DstInfos calldata dstInfos, Dst1inch calldata dst1inch ) external view returns (uint256, uint256) { bytes memory payload = abi.encode(refId, to, dstInfos.toToken, dstInfos.minToAmount, dst1inch); IStargateRouter.lzTxObj memory obj = _getLzTxObj(to, dstInfos); return stargateRouter.quoteLayerZeroFee( dstInfos.chainId, 1, // https://stargateprotocol.gitbook.io/stargate/developers/function-types obj.dstNativeAddr, payload, obj ); } /// @dev OKAY to be public method function claimFee(address token) external nonReentrant { require(feeAddr != address(0), "WooCrossChainRouterV3: !feeAddr"); uint256 amount = _generalBalanceOf(token, address(this)); if (amount > 0) { if (token == ETH_PLACEHOLDER_ADDR) { TransferHelper.safeTransferETH(feeAddr, amount); } else { TransferHelper.safeTransfer(token, feeAddr, amount); } } } function _getDstGasForCall(DstInfos memory dstInfos) internal view returns (uint256) { return (dstInfos.toToken == dstInfos.bridgeToken) ? dstGasForNoSwapCall : dstGasForSwapCall; } function _getAdapterParams( address to, address oft, uint256 dstGasForCall, DstInfos memory dstInfos ) internal view returns (bytes memory) { // OFT src logic: require(providedGasLimit >= minGasLimit) // uint256 minGasLimit = minDstGasLookup[_dstChainId][_type] + dstGasForCall; // _type: 0(send), 1(send_and_call) uint256 providedGasLimit = ILzApp(oft).minDstGasLookup(dstInfos.chainId, 1) + dstGasForCall; // https://layerzero.gitbook.io/docs/evm-guides/advanced/relayer-adapter-parameters#airdrop return abi.encodePacked( uint16(2), // version: 2 is able to airdrop native token on destination but 1 is not providedGasLimit, // gasAmount: destination transaction gas for LayerZero to delivers dstInfos.airdropNativeAmount, // nativeForDst: airdrop native token amount to // addressOnDst: address to receive airdrop native token on destination ); } function _getLzTxObj(address to, DstInfos memory dstInfos) internal view returns (IStargateRouter.lzTxObj memory) { uint256 dstGasForCall = _getDstGasForCall(dstInfos); return IStargateRouter.lzTxObj(dstGasForCall, dstInfos.airdropNativeAmount, abi.encodePacked(to)); } function _bridgeByStargate( uint256 refId, address payable to, uint256 msgValue, uint256 bridgeAmount, SrcInfos memory srcInfos, DstInfos calldata dstInfos, Dst1inch calldata dst1inch ) internal { require(sgPoolIds[sgChainIdLocal][srcInfos.bridgeToken] > 0, "WooCrossChainRouterV3: !srcInfos.bridgeToken"); require(sgPoolIds[dstInfos.chainId][dstInfos.bridgeToken] > 0, "WooCrossChainRouterV3: !dstInfos.bridgeToken"); bytes memory payload = abi.encode(refId, to, dstInfos.toToken, dstInfos.minToAmount, dst1inch); uint256 dstMinBridgeAmount = (bridgeAmount * (10000 - bridgeSlippage)) / 10000; bytes memory dstWooCrossChainRouter = abi.encodePacked(wooCrossRouters[dstInfos.chainId]); IStargateRouter.lzTxObj memory obj = _getLzTxObj(to, dstInfos); if (srcInfos.bridgeToken == weth) { IWETH(weth).withdraw(bridgeAmount); msgValue += bridgeAmount; } else { TransferHelper.safeApprove(srcInfos.bridgeToken, address(stargateRouter), bridgeAmount); } stargateRouter.swap{value: msgValue}( dstInfos.chainId, // dst chain id sgPoolIds[sgChainIdLocal][srcInfos.bridgeToken], // bridge token's pool id on src chain sgPoolIds[dstInfos.chainId][dstInfos.bridgeToken], // bridge token's pool id on dst chain payable(_msgSender()), // rebate address bridgeAmount, // swap amount on src chain dstMinBridgeAmount, // min received amount on dst chain obj, // config: dstGasForCall, dstAirdropNativeAmount, dstReceiveAirdropNativeTokenAddr dstWooCrossChainRouter, // smart contract to call on dst chain payload // payload to piggyback ); } function _handleNativeReceived( uint256 refId, address to, address toToken, uint256 bridgedAmount, uint256 minToAmount, Dst1inch memory dst1inch ) internal { address msgSender = _msgSender(); if (toToken == ETH_PLACEHOLDER_ADDR) { // Directly transfer ETH TransferHelper.safeTransferETH(to, bridgedAmount); emit WooCrossSwapOnDstChain( refId, msgSender, to, weth, bridgedAmount, toToken, ETH_PLACEHOLDER_ADDR, minToAmount, bridgedAmount, dst1inch.swapRouter == address(0) ? 0 : 1, 0 ); return; } // Swap required! IWETH(weth).deposit{value: bridgedAmount}(); if (dst1inch.swapRouter != address(0)) { uint256 fee = (bridgedAmount * dstExternalFeeRate) / FEE_BASE; uint256 swapAmount = bridgedAmount - fee; TransferHelper.safeApprove(weth, address(wooRouter), swapAmount); try wooRouter.externalSwap( dst1inch.swapRouter, dst1inch.swapRouter, weth, toToken, swapAmount, minToAmount, payable(to), dst1inch.data ) returns (uint256 realToAmount) { emit WooCrossSwapOnDstChain( refId, msgSender, to, weth, swapAmount, toToken, toToken, minToAmount, realToAmount, dst1inch.swapRouter == address(0) ? 0 : 1, fee ); } catch { TransferHelper.safeApprove(weth, address(wooRouter), 0); TransferHelper.safeTransfer(weth, to, bridgedAmount); emit WooCrossSwapOnDstChain( refId, msgSender, to, weth, bridgedAmount, toToken, weth, minToAmount, bridgedAmount, dst1inch.swapRouter == address(0) ? 0 : 1, 0 ); } } else { TransferHelper.safeApprove(weth, address(wooRouter), bridgedAmount); try wooRouter.swap( weth, toToken, bridgedAmount, minToAmount, payable(to), to ) returns (uint256 realToAmount) { emit WooCrossSwapOnDstChain( refId, msgSender, to, weth, bridgedAmount, toToken, toToken, minToAmount, realToAmount, dst1inch.swapRouter == address(0) ? 0 : 1, 0 ); } catch { TransferHelper.safeApprove(weth, address(wooRouter), 0); TransferHelper.safeTransfer(weth, to, bridgedAmount); emit WooCrossSwapOnDstChain( refId, msgSender, to, weth, bridgedAmount, toToken, weth, minToAmount, bridgedAmount, dst1inch.swapRouter == address(0) ? 0 : 1, 0 ); } } } function _handleERC20Received( uint256 refId, address to, address toToken, address bridgedToken, uint256 bridgedAmount, uint256 minToAmount, Dst1inch memory dst1inch ) internal { address msgSender = _msgSender(); if (toToken == bridgedToken) { TransferHelper.safeTransfer(bridgedToken, to, bridgedAmount); emit WooCrossSwapOnDstChain( refId, msgSender, to, bridgedToken, bridgedAmount, toToken, toToken, minToAmount, bridgedAmount, dst1inch.swapRouter == address(0) ? 0 : 1, 0 ); } else { // Deduct the external swap fee uint256 fee = (bridgedAmount * dstExternalFeeRate) / FEE_BASE; bridgedAmount -= fee; TransferHelper.safeApprove(bridgedToken, address(wooRouter), bridgedAmount); if (dst1inch.swapRouter != address(0)) { try wooRouter.externalSwap( dst1inch.swapRouter, dst1inch.swapRouter, bridgedToken, toToken, bridgedAmount, minToAmount, payable(to), dst1inch.data ) returns (uint256 realToAmount) { emit WooCrossSwapOnDstChain( refId, msgSender, to, bridgedToken, bridgedAmount, toToken, toToken, minToAmount, realToAmount, dst1inch.swapRouter == address(0) ? 0 : 1, fee ); } catch { bridgedAmount += fee; TransferHelper.safeTransfer(bridgedToken, to, bridgedAmount); emit WooCrossSwapOnDstChain( refId, msgSender, to, bridgedToken, bridgedAmount, toToken, bridgedToken, minToAmount, bridgedAmount, dst1inch.swapRouter == address(0) ? 0 : 1, 0 ); } } else { try wooRouter.swap(bridgedToken, toToken, bridgedAmount, minToAmount, payable(to), to) returns ( uint256 realToAmount ) { emit WooCrossSwapOnDstChain( refId, msgSender, to, bridgedToken, bridgedAmount, toToken, toToken, minToAmount, realToAmount, dst1inch.swapRouter == address(0) ? 0 : 1, 0 ); } catch { TransferHelper.safeTransfer(bridgedToken, to, bridgedAmount); emit WooCrossSwapOnDstChain( refId, msgSender, to, bridgedToken, bridgedAmount, toToken, bridgedToken, minToAmount, bridgedAmount, dst1inch.swapRouter == address(0) ? 0 : 1, 0 ); } } } } function _generalBalanceOf(address token, address who) internal view returns (uint256) { return token == ETH_PLACEHOLDER_ADDR ? who.balance : IERC20(token).balanceOf(who); } /* ----- Owner & Admin Functions ----- */ function setFeeAddr(address _feeAddr) external onlyOwner { feeAddr = _feeAddr; } function setWooRouter(address _wooRouter) external onlyOwner { require(_wooRouter != address(0), "WooCrossChainRouterV3: !_wooRouter"); wooRouter = IWooRouterV2(_wooRouter); } function setStargateRouter(address _stargateRouter) external onlyOwner { require(_stargateRouter != address(0), "WooCrossChainRouterV3: !_stargateRouter"); stargateRouter = IStargateRouter(_stargateRouter); } function setBridgeSlippage(uint256 _bridgeSlippage) external onlyOwner { require(_bridgeSlippage <= 10000, "WooCrossChainRouterV3: !_bridgeSlippage"); bridgeSlippage = _bridgeSlippage; } function setDstGasForSwapCall(uint256 _dstGasForSwapCall) external onlyOwner { dstGasForSwapCall = _dstGasForSwapCall; } function setDstGasForNoSwapCall(uint256 _dstGasForNoSwapCall) external onlyOwner { dstGasForNoSwapCall = _dstGasForNoSwapCall; } function setSgChainIdLocal(uint16 _sgChainIdLocal) external onlyOwner { sgChainIdLocal = _sgChainIdLocal; } function setWooCrossRouter(uint16 _chainId, address _crossRouter) external onlyOwner { require(_crossRouter != address(0), "WooCrossChainRouterV3: !_crossRouter"); wooCrossRouters[_chainId] = _crossRouter; } function pause() external onlyOwner { _pause(); } function unpause() external onlyOwner { _unpause(); } function inCaseTokenGotStuck(address stuckToken) external onlyOwner { if (stuckToken == ETH_PLACEHOLDER_ADDR) { TransferHelper.safeTransferETH(msg.sender, address(this).balance); } else { uint256 amount = IERC20(stuckToken).balanceOf(address(this)); TransferHelper.safeTransfer(stuckToken, msg.sender, amount); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.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 (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.9.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. 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. * * ```solidity * 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) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // 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 in 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; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title Wrapped ETH. interface IWETH { /// @dev Deposit ETH into WETH function deposit() external payable; /// @dev Transfer WETH to receiver /// @param to address of WETH receiver /// @param value amount of WETH to transfer /// @return get true when succeed, else false function transfer(address to, uint256 value) external returns (bool); /// @dev Withdraw WETH to ETH function withdraw(uint256) external; }
// SPDX-License-Identifier: MIT pragma solidity =0.8.14; /* ░██╗░░░░░░░██╗░█████╗░░█████╗░░░░░░░███████╗██╗ ░██║░░██╗░░██║██╔══██╗██╔══██╗░░░░░░██╔════╝██║ ░╚██╗████╗██╔╝██║░░██║██║░░██║█████╗█████╗░░██║ ░░████╔═████║░██║░░██║██║░░██║╚════╝██╔══╝░░██║ ░░╚██╔╝░╚██╔╝░╚█████╔╝╚█████╔╝░░░░░░██║░░░░░██║ ░░░╚═╝░░░╚═╝░░░╚════╝░░╚════╝░░░░░░░╚═╝░░░░░╚═╝ * * MIT License * =========== * * Copyright (c) 2020 WooTrade * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /// @title WOOFi cross chain router interface (version 3, supporting WOOFi and 1inch). /// @notice functions to interface with WOOFi cross chain swap, and 1inch for local swap interface IWooCrossChainRouterV3 { /* ----- Structs ----- */ struct SrcInfos { address fromToken; address bridgeToken; uint256 fromAmount; uint256 minBridgeAmount; } struct Src1inch { address swapRouter; bytes data; } struct DstInfos { uint16 chainId; address toToken; address bridgeToken; uint256 minToAmount; uint256 airdropNativeAmount; } struct Dst1inch { address swapRouter; bytes data; } /* ----- Events ----- */ event WooCrossSwapOnSrcChain( uint256 indexed refId, address indexed sender, address indexed to, address fromToken, uint256 fromAmount, address bridgeToken, uint256 minBridgeAmount, uint256 realBridgeAmount, uint8 swapType, uint256 fee ); event WooCrossSwapOnDstChain( uint256 indexed refId, address indexed sender, address indexed to, address bridgedToken, uint256 bridgedAmount, address toToken, address realToToken, uint256 minToAmount, uint256 realToAmount, uint8 swapType, uint256 fee ); /* ----- State Variables ----- */ function bridgeSlippage() external view returns (uint256); function dstGasForSwapCall() external view returns (uint256); function dstGasForNoSwapCall() external view returns (uint256); function wooCrossRouters(uint16 chainId) external view returns (address wooCrossRouter); /* ----- Functions ----- */ function crossSwap( uint256 refId, address payable to, SrcInfos memory srcInfos, DstInfos calldata dstInfos, Src1inch calldata src1inch, Dst1inch calldata dst1inch ) external payable; function sgReceive( uint16 srcChainId, bytes memory srcAddress, uint256 nonce, address bridgedToken, uint256 amountLD, bytes memory payload ) external; function quoteLayerZeroFee( uint256 refId, address to, DstInfos calldata dstInfos, Dst1inch calldata dst1inch ) external view returns (uint256 nativeAmount, uint256 zroAmount); }
// SPDX-License-Identifier: MIT pragma solidity =0.8.14; /* ░██╗░░░░░░░██╗░█████╗░░█████╗░░░░░░░███████╗██╗ ░██║░░██╗░░██║██╔══██╗██╔══██╗░░░░░░██╔════╝██║ ░╚██╗████╗██╔╝██║░░██║██║░░██║█████╗█████╗░░██║ ░░████╔═████║░██║░░██║██║░░██║╚════╝██╔══╝░░██║ ░░╚██╔╝░╚██╔╝░╚█████╔╝╚█████╔╝░░░░░░██║░░░░░██║ ░░░╚═╝░░░╚═╝░░░╚════╝░░╚════╝░░░░░░░╚═╝░░░░░╚═╝ * * MIT License * =========== * * Copyright (c) 2020 WooTrade * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /// @title Woo private pool for swap. /// @notice Use this contract to directly interfact with woo's synthetic proactive /// marketing making pool. /// @author woo.network interface IWooPPV2 { /* ----- Events ----- */ event Deposit(address indexed token, address indexed sender, uint256 amount); event Withdraw(address indexed token, address indexed receiver, uint256 amount); event Migrate(address indexed token, address indexed receiver, uint256 amount); event AdminUpdated(address indexed addr, bool flag); event FeeAddrUpdated(address indexed newFeeAddr); event WooracleUpdated(address indexed newWooracle); event WooSwap( address indexed fromToken, address indexed toToken, uint256 fromAmount, uint256 toAmount, address from, address indexed to, address rebateTo, uint256 swapVol, uint256 swapFee ); /* ----- External Functions ----- */ /// @notice The quote token address (immutable). /// @return address of quote token function quoteToken() external view returns (address); /// @notice Gets the pool size of the specified token (swap liquidity). /// @param token the token address /// @return the pool size function poolSize(address token) external view returns (uint256); /// @notice Query the amount to swap `fromToken` to `toToken`, without checking the pool reserve balance. /// @param fromToken the from token /// @param toToken the to token /// @param fromAmount the amount of `fromToken` to swap /// @return toAmount the swapped amount of `toToken` function tryQuery( address fromToken, address toToken, uint256 fromAmount ) external view returns (uint256 toAmount); /// @notice Query the amount to swap `fromToken` to `toToken`, with checking the pool reserve balance. /// @dev tx reverts when 'toToken' balance is insufficient. /// @param fromToken the from token /// @param toToken the to token /// @param fromAmount the amount of `fromToken` to swap /// @return toAmount the swapped amount of `toToken` function query( address fromToken, address toToken, uint256 fromAmount ) external view returns (uint256 toAmount); /// @notice Swap `fromToken` to `toToken`. /// @param fromToken the from token /// @param toToken the to token /// @param fromAmount the amount of `fromToken` to swap /// @param minToAmount the minimum amount of `toToken` to receive /// @param to the destination address /// @param rebateTo the rebate address (optional, can be address ZERO) /// @return realToAmount the amount of toToken to receive function swap( address fromToken, address toToken, uint256 fromAmount, uint256 minToAmount, address to, address rebateTo ) external returns (uint256 realToAmount); /// @notice Deposit the specified token into the liquidity pool of WooPPV2. /// @param token the token to deposit /// @param amount the deposit amount function deposit(address token, uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity =0.8.14; /* ░██╗░░░░░░░██╗░█████╗░░█████╗░░░░░░░███████╗██╗ ░██║░░██╗░░██║██╔══██╗██╔══██╗░░░░░░██╔════╝██║ ░╚██╗████╗██╔╝██║░░██║██║░░██║█████╗█████╗░░██║ ░░████╔═████║░██║░░██║██║░░██║╚════╝██╔══╝░░██║ ░░╚██╔╝░╚██╔╝░╚█████╔╝╚█████╔╝░░░░░░██║░░░░░██║ ░░░╚═╝░░░╚═╝░░░╚════╝░░╚════╝░░░░░░░╚═╝░░░░░╚═╝ * * MIT License * =========== * * Copyright (c) 2020 WooTrade * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import "../interfaces/IWooPPV2.sol"; /// @title Woo router interface (version 2) /// @notice functions to interface with WooFi swap interface IWooRouterV2 { /* ----- Type declarations ----- */ enum SwapType { WooSwap, DodoSwap } /* ----- Events ----- */ event WooRouterSwap( SwapType swapType, address indexed fromToken, address indexed toToken, uint256 fromAmount, uint256 toAmount, address from, address indexed to, address rebateTo ); event WooPoolChanged(address newPool); /* ----- Router properties ----- */ function WETH() external view returns (address); function wooPool() external view returns (IWooPPV2); /* ----- Main query & swap APIs ----- */ /// @notice query the amount to swap fromToken -> toToken /// @param fromToken the from token /// @param toToken the to token /// @param fromAmount the amount of fromToken to swap /// @return toAmount the predicted amount to receive function querySwap( address fromToken, address toToken, uint256 fromAmount ) external view returns (uint256 toAmount); /// @notice query the amount to swap fromToken -> toToken, /// WITHOUT checking the reserve balance; so it /// always returns the quoted amount (for reference). /// @param fromToken the from token /// @param toToken the to token /// @param fromAmount the amount of fromToken to swap /// @return toAmount the predicted amount to receive function tryQuerySwap( address fromToken, address toToken, uint256 fromAmount ) external view returns (uint256 toAmount); /// @notice Swap `fromToken` to `toToken`. /// @param fromToken the from token /// @param toToken the to token /// @param fromAmount the amount of `fromToken` to swap /// @param minToAmount the minimum amount of `toToken` to receive /// @param to the destination address /// @param rebateTo the rebate address (optional, can be 0) /// @return realToAmount the amount of toToken to receive function swap( address fromToken, address toToken, uint256 fromAmount, uint256 minToAmount, address payable to, address rebateTo ) external payable returns (uint256 realToAmount); /* ----- 3rd party DEX swap ----- */ /// @notice swap fromToken -> toToken via an external 3rd swap /// @param approveTarget the contract address for token transfer approval /// @param swapTarget the contract address for swap /// @param fromToken the from token /// @param toToken the to token /// @param fromAmount the amount of fromToken to swap /// @param minToAmount the min amount of swapped toToken /// @param to the destination address /// @param data call data for external call function externalSwap( address approveTarget, address swapTarget, address fromToken, address toToken, uint256 fromAmount, uint256 minToAmount, address payable to, bytes calldata data ) external payable returns (uint256 realToAmount); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the LzApp that functions not exist in the @layerzerolabs package */ interface ILzApp { function minDstGasLookup(uint16 _dstChainId, uint16 _type) external view returns (uint256 _minGasLimit); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IStargateEthVault { function deposit() external payable; function transfer(address to, uint256 value) external returns (bool); function withdraw(uint256) external; function approve(address guy, uint256 wad) external returns (bool); function transferFrom( address src, address dst, uint256 wad ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IStargateRouter { struct lzTxObj { uint256 dstGasForCall; uint256 dstNativeAmount; bytes dstNativeAddr; } function addLiquidity( uint256 _poolId, uint256 _amountLD, address _to ) external; function swap( uint16 _dstChainId, uint256 _srcPoolId, uint256 _dstPoolId, address payable _refundAddress, uint256 _amountLD, uint256 _minAmountLD, lzTxObj memory _lzTxParams, bytes calldata _to, bytes calldata _payload ) external payable; function redeemRemote( uint16 _dstChainId, uint256 _srcPoolId, uint256 _dstPoolId, address payable _refundAddress, uint256 _amountLP, uint256 _minAmountLD, bytes calldata _to, lzTxObj memory _lzTxParams ) external payable; function instantRedeemLocal( uint16 _srcPoolId, uint256 _amountLP, address _to ) external returns (uint256); function redeemLocal( uint16 _dstChainId, uint256 _srcPoolId, uint256 _dstPoolId, address payable _refundAddress, uint256 _amountLP, bytes calldata _to, lzTxObj memory _lzTxParams ) external payable; function sendCredits( uint16 _dstChainId, uint256 _srcPoolId, uint256 _dstPoolId, address payable _refundAddress ) external payable; function quoteLayerZeroFee( uint16 _dstChainId, uint8 _functionType, bytes calldata _toAddress, bytes calldata _transferAndCallPayload, lzTxObj memory _lzTxParams ) external view returns (uint256, uint256); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library TransferHelper { function safeApprove( address token, address to, uint256 value ) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require( success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper::safeApprove: approve failed" ); } function safeTransfer( address token, address to, uint256 value ) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); require( success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper::safeTransfer: transfer failed" ); } function safeTransferFrom( address token, address from, address to, uint256 value ) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require( success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper::transferFrom: transferFrom failed" ); } function safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call{value: value}(new bytes(0)); require(success, "TransferHelper::safeTransferETH: ETH transfer failed"); } }
{ "optimizer": { "enabled": true, "runs": 20000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_weth","type":"address"},{"internalType":"address","name":"_wooRouter","type":"address"},{"internalType":"address","name":"_stargateRouter","type":"address"},{"internalType":"uint16","name":"_sgChainIdLocal","type":"uint16"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"bridgedToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"bridgedAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"toToken","type":"address"},{"indexed":false,"internalType":"address","name":"realToToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"minToAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"realToAmount","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"swapType","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"WooCrossSwapOnDstChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"fromToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"fromAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"bridgeToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"minBridgeAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"realBridgeAmount","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"swapType","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"WooCrossSwapOnSrcChain","type":"event"},{"inputs":[],"name":"ETH_PLACEHOLDER_ADDR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bridgeSlippage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"claimFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"refId","type":"uint256"},{"internalType":"address payable","name":"to","type":"address"},{"components":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"address","name":"bridgeToken","type":"address"},{"internalType":"uint256","name":"fromAmount","type":"uint256"},{"internalType":"uint256","name":"minBridgeAmount","type":"uint256"}],"internalType":"struct IWooCrossChainRouterV3.SrcInfos","name":"srcInfos","type":"tuple"},{"components":[{"internalType":"uint16","name":"chainId","type":"uint16"},{"internalType":"address","name":"toToken","type":"address"},{"internalType":"address","name":"bridgeToken","type":"address"},{"internalType":"uint256","name":"minToAmount","type":"uint256"},{"internalType":"uint256","name":"airdropNativeAmount","type":"uint256"}],"internalType":"struct IWooCrossChainRouterV3.DstInfos","name":"dstInfos","type":"tuple"},{"components":[{"internalType":"address","name":"swapRouter","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IWooCrossChainRouterV3.Src1inch","name":"src1inch","type":"tuple"},{"components":[{"internalType":"address","name":"swapRouter","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IWooCrossChainRouterV3.Dst1inch","name":"dst1inch","type":"tuple"}],"name":"crossSwap","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"dstExternalFeeRate","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dstGasForNoSwapCall","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dstGasForSwapCall","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stuckToken","type":"address"}],"name":"inCaseTokenGotStuck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"refId","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"components":[{"internalType":"uint16","name":"chainId","type":"uint16"},{"internalType":"address","name":"toToken","type":"address"},{"internalType":"address","name":"bridgeToken","type":"address"},{"internalType":"uint256","name":"minToAmount","type":"uint256"},{"internalType":"uint256","name":"airdropNativeAmount","type":"uint256"}],"internalType":"struct IWooCrossChainRouterV3.DstInfos","name":"dstInfos","type":"tuple"},{"components":[{"internalType":"address","name":"swapRouter","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IWooCrossChainRouterV3.Dst1inch","name":"dst1inch","type":"tuple"}],"name":"quoteLayerZeroFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bridgeSlippage","type":"uint256"}],"name":"setBridgeSlippage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_dstGasForNoSwapCall","type":"uint256"}],"name":"setDstGasForNoSwapCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_dstGasForSwapCall","type":"uint256"}],"name":"setDstGasForSwapCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeAddr","type":"address"}],"name":"setFeeAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_sgChainIdLocal","type":"uint16"}],"name":"setSgChainIdLocal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stargateRouter","type":"address"}],"name":"setStargateRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"address","name":"_crossRouter","type":"address"}],"name":"setWooCrossRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wooRouter","type":"address"}],"name":"setWooRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sgChainIdLocal","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"sgETHs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"address","name":"","type":"address"}],"name":"sgPoolIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"bridgedToken","type":"address"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"sgReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"srcExternalFeeRate","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stargateRouter","outputs":[{"internalType":"contract IStargateRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"wooCrossRouters","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wooRouter","outputs":[{"internalType":"contract IWooRouterV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a06040523480156200001157600080fd5b506040516200460338038062004603833981016040819052620000349162000642565b6200003f33620005d5565b6000805460ff60a01b19169055600180556001600160a01b03848116608052600280546001600160a01b03199081168684161790915560038054909116918416919091179055600880546064600555620a12206006556201388060075561ffff831663ffffffff1990911617621900001761ffff60201b1916641900000000179055620001fc600a6020527ff9e1f7b0901346d296812178087abe22e5f073e1bdcdc4cbd5ca8e85ae0cd95b80546001600160a01b03199081167372e2f4830b9e45d52f80ac08cb2bec0fef72ed9c179091557f1bd1223d801633f6ab136f4d0374e6bf2cd24907ab2a621c791fdda7c6052df2805482167382cbecf39bee528b5476fe6d1550af59a9db6fc01790557f2e4315ab10cff3525f24869303cec5e46284ffd52efb61b7911dce72657bc2568054821673b69c8cbcd90a39d8d3d3ccf0a3e968511c3856a01790557fe741581f7b0c2019c89a7bc292158f8c5da3a6ee82a31c6c7978f2e845541e738054821673224d8fd7ab6ad4c6eb4611ce56ef35dec2277f0390811790915560b86000527ff3802049da67ba2f7722226d23ed15e33e2364e3176c48534159ba2e3794f6b98054909216179055565b620005cb60017f632a9c1ec8e4a92201d179df5a8440e74d1cdf633fcfc2b7315c58a3d6340bc281905560027f84e5d75099bd6c4cbdc2c8a489e7622876eff2882cd6670316e042732ad185e6819055600d7f6d637fd6e6fe43b9efe36f0f7c5600b5263c0ad79c9bfe1b42479bebaeb04eba81905560147f4a1dc47329e1e68a784d39a7245b904aede124e39716f760d2c23addcdbc7b5d8190557f7850f4367384fff995daf65b4d829a8b6961229c3a724dbbf42f2af9a0a048b583905560057f1dfdaa64fb68e413a0a0a0e4626a03d164109fb43da5574a6d90dee62feeaa1b557fc78e0e3cebbfd8d0ffd668235bda0d2e1556a0091f45dd955e05911f41c2c2cb8190557fc30e82c70a7cf18d7587adda5b58f8e66472fb7f71a0fe420bca19ac714870b18490557f862581a5cab8aa6d24a2af61f7b1650b15b6f38b5f5f643c741341698ce2c20d8390557fb89152c83731bacf211775d334152db8668afceedb774d96fd0d187dd6a1b5348190557fbf5b413feb446f720d8baa3e0a529c172775abddacc530ccd1df3cffa70b05dd8490557f1c8a6a2a61020ece78094d5a1b5d8e13d3be0006ee621d9f759c4b72f1983c398390557ff20469bb8ac314988e242299d838e97014f7b0b6d38c0900f72e80a1b73e94a18190557f81a99cfd41c8e456a24aed9a401d293b4f15787de85654774fa3dca9154c29d08490557f0815e22cea931a265a039577937770f4768c87e371b60442772c18ec922fec4c929092557fc58119b2689fcd210942cfeb33b9aebe9b9992f72243d5b16a6c6a59dbcf3a978190557f89cc462099dbd8d02a2cab45236029ccd1ccd79989daf7618ed2058e68714b7c8290557f483c72bf6e45cfc619f3c0f5aeca4ac1f91b4174c2d5d260ed1b91ede0453e4b8390557fe4702b55de7a864ef4acd15e35e19c780879565681591b26033f65d8d0e3d0ff8190557f4f882cfd18abefe6ca553c66e01a6050f4120df464e191eba65052213c21909c8290557f59649153242ca9d3750532e714c82fe378bfd8e4c2675382078c15ff140cfdaf8390557fca9b3ee9ada86c988cc357d0793f5d6472dd06d3b65f8e0a31dd13d9ebb85bf0919091557f97cdedb2d4e9030b36409afb68d0966e3bf3a705c501f4af45ab5e7d4b5a1fa98190557f0c630275afbb6b9b34d872a0177ec932d36ad3fd1eeac1f1b81b353b7cb06364919091557342000000000000000000000000000000000000066000527f8229f161923d5e158fa9ed5fed4aad517f16b3d3a5596c926be4fc191fc75cb36020527f9a7f16bb0f9a581a8278bcfeff83df0d725793f41b08fef869cdf73db9ece60955565b50505050620006a7565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200063d57600080fd5b919050565b600080600080608085870312156200065957600080fd5b620006648562000625565b9350620006746020860162000625565b9250620006846040860162000625565b9150606085015161ffff811681146200069c57600080fd5b939692955090935050565b608051613ebb62000748600039600081816102cf01528181610c8801528181611f6201528181611fcc015281816125f5015281816126b001528181612779015281816127d80152818161286b015281816128a0015281816128fe01528181612921015281816129fa01528181612aab01528181612b0d01528181612bad01528181612be201528181612c4001528181612c630152612d3c0152613ebb6000f3fe60806040526004361061021d5760003560e01c806388c4cb361161011d578063b9292141116100b0578063ecefc7051161007f578063f6af695711610064578063f6af695714610656578063f87b368a1461068c578063fdeba4e5146106c157600080fd5b8063ecefc7051461061f578063f2fde38b1461063657600080fd5b8063b9292141146105a5578063c22b7419146105c8578063e1a4e72a146105de578063ecb911de146105fe57600080fd5b8063a9e56f3c116100ec578063a9e56f3c14610517578063ab8236f314610537578063b2855b4f14610557578063b88dafcb1461057757600080fd5b806388c4cb361461047b5780638da5cb5b146104a357806397ebb452146104c1578063a4cd49ba146104e157600080fd5b80634dba39a2116101b0578063616d29641161017f578063715018a611610164578063715018a61461043b57806383af5550146104505780638456cb591461046657600080fd5b8063616d2964146104055780636ebc51e11461041b57600080fd5b80634dba39a21461037757806351b78b471461039757806359b80cf9146103b75780635c975abb146103ca57600080fd5b80633fc8cef3116101ec5780633fc8cef3146102bd578063403a01e5146102f1578063498f3097146103115780634d8650d71461035757600080fd5b806301d122d614610229578063091a76c61461024b57806339e7fddc1461026b5780633f4ba83a146102a857600080fd5b3661022457005b600080fd5b34801561023557600080fd5b50610249610244366004613439565b6106e1565b005b34801561025757600080fd5b50610249610266366004613454565b61071e565b34801561027757600080fd5b5060045461028b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102b457600080fd5b5061024961072b565b3480156102c957600080fd5b5061028b7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102fd57600080fd5b5061024961030c366004613454565b61073d565b34801561031d57600080fd5b5061034961032c366004613482565b600b60209081526000928352604080842090915290825290205481565b60405190815260200161029f565b34801561036357600080fd5b50610249610372366004613454565b6107e1565b34801561038357600080fd5b506102496103923660046134b9565b6107ee565b3480156103a357600080fd5b506102496103b23660046134b9565b6108c6565b6102496103c53660046135ac565b61099e565b3480156103d657600080fd5b5060005474010000000000000000000000000000000000000000900460ff16604051901515815260200161029f565b34801561041157600080fd5b5061034960075481565b34801561042757600080fd5b506102496104363660046134b9565b6111f4565b34801561044757600080fd5b506102496112f2565b34801561045c57600080fd5b5061034960055481565b34801561047257600080fd5b50610249611304565b34801561048757600080fd5b5061028b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b3480156104af57600080fd5b506000546001600160a01b031661028b565b3480156104cd57600080fd5b506102496104dc366004613482565b611314565b3480156104ed57600080fd5b5061028b6104fc366004613439565b600a602052600090815260409020546001600160a01b031681565b34801561052357600080fd5b5060035461028b906001600160a01b031681565b34801561054357600080fd5b50610249610552366004613733565b6113fd565b34801561056357600080fd5b506102496105723660046134b9565b611518565b34801561058357600080fd5b506008546105929061ffff1681565b60405161ffff909116815260200161029f565b3480156105b157600080fd5b5060085461059290640100000000900461ffff1681565b3480156105d457600080fd5b5061034960065481565b3480156105ea57600080fd5b506102496105f93660046134b9565b61155a565b34801561060a57600080fd5b506008546105929062010000900461ffff1681565b34801561062b57600080fd5b50610349620186a081565b34801561064257600080fd5b506102496106513660046134b9565b611631565b34801561066257600080fd5b5061028b610671366004613439565b6009602052600090815260409020546001600160a01b031681565b34801561069857600080fd5b506106ac6106a73660046137c1565b6116d8565b6040805192835260208301919091520161029f565b3480156106cd57600080fd5b5060025461028b906001600160a01b031681565b6106e96117cd565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff92909216919091179055565b6107266117cd565b600755565b6107336117cd565b61073b611841565b565b6107456117cd565b6127108111156107dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f576f6f43726f7373436861696e526f7574657256333a20215f6272696467655360448201527f6c6970706167650000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b600555565b6107e96117cd565b600655565b6107f66117cd565b6001600160a01b03811661088c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f576f6f43726f7373436861696e526f7574657256333a20215f776f6f526f757460448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084016107d3565b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6108ce6117cd565b6001600160a01b038116610964576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f576f6f43726f7373436861696e526f7574657256333a20215f7374617267617460448201527f65526f757465720000000000000000000000000000000000000000000000000060648201526084016107d3565b600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6109a66118b1565b6109ae611936565b83516001600160a01b0316610a45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f576f6f43726f7373436861696e526f7574657256333a2021737263496e666f7360448201527f2e66726f6d546f6b656e0000000000000000000000000000000000000000000060648201526084016107d3565b6000610a5760408501602086016134b9565b6001600160a01b031614158015610ab65750600a6000610a7a6020860186613439565b61ffff1681526020808201929092526040908101600020546001600160a01b031691610aaa9186019086016134b9565b6001600160a01b031614155b610b42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f576f6f43726f7373436861696e526f7574657256333a2021647374496e666f7360448201527f2e746f546f6b656e00000000000000000000000000000000000000000000000060648201526084016107d3565b6001600160a01b038516610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f576f6f43726f7373436861696e526f7574657256333a2021746f00000000000060448201526064016107d3565b8351349060009081906001600160a01b03167fffffffffffffffffffffffff111111111111111111111111111111111111111201610d2f578287604001511115610c7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f576f6f43726f7373436861696e526f7574657256333a2021737263496e666f7360448201527f2e66726f6d416d6f756e7400000000000000000000000000000000000000000060648201526084016107d3565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001680885260408089015181517fd0e30db0000000000000000000000000000000000000000000000000000000008152915163d0e30db09260048082019260009290919082900301818588803b158015610cff57600080fd5b505af1158015610d13573d6000803e3d6000fd5b5050505050866040015183610d28919061385c565b9250610d43565b610d43876000015133308a604001516119a9565b86602001516001600160a01b031687600001516001600160a01b031614610f465786516002546040890151610d8292916001600160a01b031690611b33565b6000610d9160208701876134b9565b6001600160a01b031614610e86576002546001600160a01b031663199b83fa610dbd60208801886134b9565b610dca60208901896134b9565b8a600001518b602001518c604001518d60600151308d8060200190610def9190613873565b6040518a63ffffffff1660e01b8152600401610e139998979695949392919061390a565b6020604051808303816000875af1158015610e32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e56919061396c565b600854909250620186a090610e759062010000900461ffff1684613985565b610e7f91906139c2565b9050610fe5565b600254875160208901516040808b015160608c015191517f7dc203820000000000000000000000000000000000000000000000000000000081526001600160a01b0394851660048201529284166024840152604483015260648201523060848201528a821660a4820152911690637dc203829060c4016020604051808303816000875af1158015610f1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3f919061396c565b9150610fe5565b8660600151876040015114610fdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f576f6f43726f7373436861696e526f7574657256333a2021737263496e666f7360448201527f2e6d696e427269646765416d6f756e740000000000000000000000000000000060648201526084016107d3565b866040015191505b60208701516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611048573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106c919061396c565b8211156110fa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f576f6f43726f7373436861696e526f7574657256333a2021627269646765416d60448201527f6f756e740000000000000000000000000000000000000000000000000000000060648201526084016107d3565b611104818361385c565b9150611115898985858b8b8a611cbc565b6001600160a01b038816336001600160a01b03168a7f546dc08c5438b68796e5047ad2ac863ab74300bdf49457917d47021f090c45c48a600001518b604001518c602001518d606001518960006001600160a01b03168e600001602081019061117e91906134b9565b6001600160a01b031614611193576001611196565b60005b604080516001600160a01b039788168152602081019690965293909516928401929092526060830152608082015260ff90911660a082015260c0810186905260e00160405180910390a45050506111ec60018055565b505050505050565b6111fc611936565b6004546001600160a01b031661126e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f576f6f43726f7373436861696e526f7574657256333a2021666565416464720060448201526064016107d3565b600061127a8230612166565b905080156112e5577fffffffffffffffffffffffff11111111111111111111111111111111111111126001600160a01b038316016112cd576004546112c8906001600160a01b031682612227565b6112e5565b6004546112e59083906001600160a01b031683612329565b506112ef60018055565b50565b6112fa6117cd565b61073b60006124ab565b61130c6117cd565b61073b612513565b61131c6117cd565b6001600160a01b0381166113b1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f576f6f43726f7373436861696e526f7574657256333a20215f63726f7373526f60448201527f757465720000000000000000000000000000000000000000000000000000000060648201526084016107d3565b61ffff91909116600090815260096020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909216919091179055565b6003546001600160a01b03163314611497576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f576f6f43726f7373436861696e526f7574657256333a20494e56414c49445f4360448201527f414c4c455200000000000000000000000000000000000000000000000000000060648201526084016107d3565b6000806000806000858060200190518101906114b39190613a2d565b60085461ffff166000908152600a6020526040902054949950929750909550935091506001600160a01b03908116908916036114fc576114f78585858a8686612582565b61150b565b61150b8585858b8b8787612de6565b5050505050505050505050565b6115206117cd565b600480547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6115626117cd565b7fffffffffffffffffffffffff11111111111111111111111111111111111111126001600160a01b0382160161159c576112ef3347612227565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156115fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611620919061396c565b905061162d823383612329565b5050565b6116396117cd565b6001600160a01b0381166116cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107d3565b6112ef816124ab565b6000808086866116ee60408801602089016134b9565b876060013587604051602001611708959493929190613bbf565b60408051601f19818403018152919052905060006117348761172f36899003890189613c02565b6132c7565b6003549091506001600160a01b0316630a5123696117556020890189613439565b6001846040015186866040518663ffffffff1660e01b815260040161177e959493929190613ce5565b6040805180830381865afa15801561179a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117be9190613d3d565b93509350505094509492505050565b6000546001600160a01b0316331461073b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107d3565b611849613369565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60005474010000000000000000000000000000000000000000900460ff161561073b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016107d3565b6002600154036119a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107d3565b6002600155565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790529151600092839290881691611a3b9190613d61565b6000604051808303816000865af19150503d8060008114611a78576040519150601f19603f3d011682016040523d82523d6000602084013e611a7d565b606091505b5091509150818015611aa7575080511580611aa7575080806020019051810190611aa79190613d7d565b6111ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a20747260448201527f616e7366657246726f6d206661696c656400000000000000000000000000000060648201526084016107d3565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151600092839290871691611bbd9190613d61565b6000604051808303816000865af19150503d8060008114611bfa576040519150601f19603f3d011682016040523d82523d6000602084013e611bff565b606091505b5091509150818015611c29575080511580611c29575080806020019051810190611c299190613d7d565b611cb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f5472616e7366657248656c7065723a3a73616665417070726f76653a2061707060448201527f726f7665206661696c656400000000000000000000000000000000000000000060648201526084016107d3565b5050505050565b60085461ffff166000908152600b60209081526040808320868301516001600160a01b03168452909152902054611d75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f576f6f43726f7373436861696e526f7574657256333a2021737263496e666f7360448201527f2e627269646765546f6b656e000000000000000000000000000000000000000060648201526084016107d3565b6000600b81611d876020860186613439565b61ffff1661ffff1681526020019081526020016000206000846040016020810190611db291906134b9565b6001600160a01b03166001600160a01b031681526020019081526020016000205411611e60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f576f6f43726f7373436861696e526f7574657256333a2021647374496e666f7360448201527f2e627269646765546f6b656e000000000000000000000000000000000000000060648201526084016107d3565b60008787611e7460408601602087016134b9565b856060013585604051602001611e8e959493929190613bbf565b60405160208183030381529060405290506000612710600554612710611eb4919061385c565b611ebe9088613985565b611ec891906139c2565b90506000600981611edc6020880188613439565b61ffff1681526020808201929092526040908101600020549051611f37926001600160a01b03909216910160609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b60408051601f1981840301815291905290506000611f5e8a61172f36899003890189613c02565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031687602001516001600160a01b031603612043576040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018990527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561201857600080fd5b505af115801561202c573d6000803e3d6000fd5b50505050878961203c9190613d9f565b985061205f565b602087015160035461205f91906001600160a01b03168a611b33565b6003546001600160a01b0316639fbf10fc8a61207e60208a018a613439565b60085461ffff166000908152600b602081815260408084208f8301516001600160a01b03168552825283205492906120b8908e018e613439565b61ffff1661ffff16815260200190815260200160002060008c60400160208101906120e391906134b9565b6001600160a01b03168152602081019190915260400160002054338e8a898b8e6040518b63ffffffff1660e01b815260040161212799989796959493929190613db7565b6000604051808303818588803b15801561214057600080fd5b505af1158015612154573d6000803e3d6000fd5b50505050505050505050505050505050565b60006001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14612214576040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301528416906370a0823190602401602060405180830381865afa1580156121eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220f919061396c565b612220565b816001600160a01b0316315b9392505050565b604080516000808252602082019092526001600160a01b0384169083906040516122519190613d61565b60006040518083038185875af1925050503d806000811461228e576040519150601f19603f3d011682016040523d82523d6000602084013e612293565b606091505b5050905080612324576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527f20455448207472616e73666572206661696c656400000000000000000000000060648201526084016107d3565b505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916123b39190613d61565b6000604051808303816000865af19150503d80600081146123f0576040519150601f19603f3d011682016040523d82523d6000602084013e6123f5565b606091505b509150915081801561241f57508051158061241f57508080602001905181019061241f9190613d7d565b611cb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c65640000000000000000000000000000000000000060648201526084016107d3565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61251b6118b1565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586118943390565b336001600160a01b0385167fffffffffffffffffffffffff1111111111111111111111111111111111111112016126ae576125bd8685612227565b856001600160a01b0316816001600160a01b0316887fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c7f0000000000000000000000000000000000000000000000000000000000000000888a73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8a8c60006001600160a01b03168c600001516001600160a01b031614612652576001612655565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c0820152600060e08201529051908190036101000190a4506111ec565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b15801561270957600080fd5b505af115801561271d573d6000803e3d6000fd5b505084516001600160a01b0316159250612aa291505057600854600090620186a09061275590640100000000900461ffff1687613985565b61275f91906139c2565b9050600061276d828761385c565b6002549091506127a8907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b031683611b33565b600260009054906101000a90046001600160a01b03166001600160a01b031663199b83fa856000015186600001517f00000000000000000000000000000000000000000000000000000000000000008b868b8f8c602001516040518963ffffffff1660e01b8152600401612823989796959493929190613e25565b6020604051808303816000875af192505050801561285e575060408051601f3d908101601f1916820190925261285b9181019061396c565b60015b6129c25760025461289b907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b03166000611b33565b6128c67f00000000000000000000000000000000000000000000000000000000000000008988612329565b876001600160a01b0316836001600160a01b03168a7fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c7f00000000000000000000000000000000000000000000000000000000000000008a8c7f00000000000000000000000000000000000000000000000000000000000000008c8e60006001600160a01b03168e600001516001600160a01b03161461296757600161296a565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c0820152600060e08201529051908190036101000190a4612a9b565b886001600160a01b0316846001600160a01b03168b7fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c7f0000000000000000000000000000000000000000000000000000000000000000868d8e8d8960006001600160a01b03168f600001516001600160a01b031614612a43576001612a46565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c082015260e081018990529051908190036101000190a4505b5050612ddd565b600254612ada907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b031686611b33565b6002546040517f7dc203820000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152878116602483015260448201879052606482018690528881166084830181905260a483015290911690637dc203829060c4016020604051808303816000875af1925050508015612ba0575060408051601f3d908101601f19168201909252612b9d9181019061396c565b60015b612d0457600254612bdd907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b03166000611b33565b612c087f00000000000000000000000000000000000000000000000000000000000000008786612329565b856001600160a01b0316816001600160a01b0316887fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c7f0000000000000000000000000000000000000000000000000000000000000000888a7f00000000000000000000000000000000000000000000000000000000000000008a8c60006001600160a01b03168c600001516001600160a01b031614612ca9576001612cac565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c0820152600060e08201529051908190036101000190a4612ddd565b866001600160a01b0316826001600160a01b0316897fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c7f0000000000000000000000000000000000000000000000000000000000000000898b8c8b8960006001600160a01b03168d600001516001600160a01b031614612d85576001612d88565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c0820152600060e08201529051908190036101000190a4505b50505050505050565b336001600160a01b0380861690871603612ec157612e05858886612329565b866001600160a01b0316816001600160a01b0316897fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c88888b8c8a8c60006001600160a01b03168c600001516001600160a01b031614612e66576001612e69565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c0820152600060e08201529051908190036101000190a46132bd565b600854600090620186a090612ee290640100000000900461ffff1687613985565b612eec91906139c2565b9050612ef8818661385c565b600254909550612f139087906001600160a01b031687611b33565b82516001600160a01b03161561314d57600260009054906101000a90046001600160a01b03166001600160a01b031663199b83fa84600001518560000151898b8a8a8f8b602001516040518963ffffffff1660e01b8152600401612f7e989796959493929190613e25565b6020604051808303816000875af1925050508015612fb9575060408051601f3d908101601f19168201909252612fb69181019061396c565b60015b61309057612fc78186613d9f565b9450612fd4868987612329565b876001600160a01b0316826001600160a01b03168a7fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c89898c8c8b8d60006001600160a01b03168d600001516001600160a01b031614613035576001613038565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c0820152600060e08201529051908190036101000190a46132bb565b886001600160a01b0316836001600160a01b03168b7fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c8a8a8d8e8c8960006001600160a01b03168e600001516001600160a01b0316146130f15760016130f4565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c082015260e081018890529051908190036101000190a4506132bb565b6002546040517f7dc203820000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152898116602483015260448201889052606482018790528a81166084830181905260a483015290911690637dc203829060c4016020604051808303816000875af19250505080156131f3575060408051601f3d908101601f191682019092526131f09181019061396c565b60015b61320257612fd4868987612329565b886001600160a01b0316836001600160a01b03168b7fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c8a8a8d8e8c8960006001600160a01b03168e600001516001600160a01b031614613263576001613266565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c0820152600060e08201529051908190036101000190a4505b505b5050505050505050565b6132eb60405180606001604052806000815260200160008152602001606081525090565b60006132f6836133ed565b90506040518060600160405280828152602001846080015181526020018560405160200161334f919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b60408051601f198184030181529190529052949350505050565b60005474010000000000000000000000000000000000000000900460ff1661073b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016107d3565b600081604001516001600160a01b031682602001516001600160a01b0316146134185760065461341c565b6007545b92915050565b803561ffff8116811461343457600080fd5b919050565b60006020828403121561344b57600080fd5b61222082613422565b60006020828403121561346657600080fd5b5035919050565b6001600160a01b03811681146112ef57600080fd5b6000806040838503121561349557600080fd5b61349e83613422565b915060208301356134ae8161346d565b809150509250929050565b6000602082840312156134cb57600080fd5b81356122208161346d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613528576135286134d6565b60405290565b6040805190810167ffffffffffffffff81118282101715613528576135286134d6565b604051601f8201601f1916810167ffffffffffffffff8111828210171561357a5761357a6134d6565b604052919050565b600060a0828403121561359457600080fd5b50919050565b60006040828403121561359457600080fd5b6000806000806000808688036101a08112156135c757600080fd5b8735965060208801356135d98161346d565b955060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08201121561360b57600080fd5b50613614613505565b60408801356136228161346d565b815260608801356136328161346d565b60208201526080880135604082015260a08801356060820152935061365a8860c08901613582565b925061016087013567ffffffffffffffff8082111561367857600080fd5b6136848a838b0161359a565b935061018089013591508082111561369b57600080fd5b506136a889828a0161359a565b9150509295509295509295565b600067ffffffffffffffff8211156136cf576136cf6134d6565b50601f01601f191660200190565b600082601f8301126136ee57600080fd5b81356137016136fc826136b5565b613551565b81815284602083860101111561371657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561374c57600080fd5b61375587613422565b9550602087013567ffffffffffffffff8082111561377257600080fd5b61377e8a838b016136dd565b965060408901359550606089013591506137978261346d565b9093506080880135925060a088013590808211156137b457600080fd5b506136a889828a016136dd565b60008060008061010085870312156137d857600080fd5b8435935060208501356137ea8161346d565b92506137f98660408701613582565b915060e085013567ffffffffffffffff81111561381557600080fd5b6138218782880161359a565b91505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561386e5761386e61382d565b500390565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126138a857600080fd5b83018035915067ffffffffffffffff8211156138c357600080fd5b6020019150368190038213156138d857600080fd5b9250929050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b60006101006001600160a01b03808d168452808c166020850152808b166040850152808a1660608501528860808501528760a085015280871660c0850152508060e084015261395c81840185876138df565b9c9b505050505050505050505050565b60006020828403121561397e57600080fd5b5051919050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156139bd576139bd61382d565b500290565b6000826139f8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b83811015613a18578181015183820152602001613a00565b83811115613a27576000848401525b50505050565b600080600080600060a08688031215613a4557600080fd5b85519450602080870151613a588161346d565b6040880151909550613a698161346d565b60608801516080890151919550935067ffffffffffffffff80821115613a8e57600080fd5b908801906040828b031215613aa257600080fd5b613aaa61352e565b8251613ab58161346d565b81528284015182811115613ac857600080fd5b8084019350508a601f840112613add57600080fd5b82519150613aed6136fc836136b5565b8281528b85848601011115613b0157600080fd5b613b10838683018787016139fd565b808583015250809450505050509295509295909350565b60008135613b348161346d565b6001600160a01b031683526020820135368390037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1018112613b7557600080fd5b820160208101903567ffffffffffffffff811115613b9257600080fd5b803603821315613ba157600080fd5b60406020860152613bb66040860182846138df565b95945050505050565b85815260006001600160a01b03808716602084015280861660408401525083606083015260a06080830152613bf760a0830184613b27565b979650505050505050565b600060a08284031215613c1457600080fd5b60405160a0810181811067ffffffffffffffff82111715613c3757613c376134d6565b604052613c4383613422565b81526020830135613c538161346d565b60208201526040830135613c668161346d565b6040820152606083810135908201526080928301359281019290925250919050565b60008151808452613ca08160208601602086016139fd565b601f01601f19169290920160200192915050565b80518252602081015160208301526000604082015160606040850152613cdd6060850182613c88565b949350505050565b61ffff8616815260ff8516602082015260a060408201526000613d0b60a0830186613c88565b8281036060840152613d1d8186613c88565b90508281036080840152613d318185613cb4565b98975050505050505050565b60008060408385031215613d5057600080fd5b505080516020909101519092909150565b60008251613d738184602087016139fd565b9190910192915050565b600060208284031215613d8f57600080fd5b8151801515811461222057600080fd5b60008219821115613db257613db261382d565b500190565b600061012061ffff8c1683528a60208401528960408401526001600160a01b03891660608401528760808401528660a08401528060c0840152613dfc81840187613cb4565b905082810360e0840152613e108186613c88565b905082810361010084015261395c8185613c88565b60006101006001600160a01b03808c168452808b166020850152808a16604085015280891660608501528760808501528660a085015280861660c0850152508060e0840152613e7681840185613c88565b9b9a505050505050505050505056fea2646970667358221220bc30f46519786380a48bcfad50acc990718c7071fb26ad71f571c65b030ffb1e64736f6c634300080e0033000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000044c08639bd59beb4f6ec52c0da6cd47283534e80000000000000000000000003b83d454a50abe06d94cb0d5d367825e190bda8f0000000000000000000000000000000000000000000000000000000000000065
Deployed Bytecode
0x60806040526004361061021d5760003560e01c806388c4cb361161011d578063b9292141116100b0578063ecefc7051161007f578063f6af695711610064578063f6af695714610656578063f87b368a1461068c578063fdeba4e5146106c157600080fd5b8063ecefc7051461061f578063f2fde38b1461063657600080fd5b8063b9292141146105a5578063c22b7419146105c8578063e1a4e72a146105de578063ecb911de146105fe57600080fd5b8063a9e56f3c116100ec578063a9e56f3c14610517578063ab8236f314610537578063b2855b4f14610557578063b88dafcb1461057757600080fd5b806388c4cb361461047b5780638da5cb5b146104a357806397ebb452146104c1578063a4cd49ba146104e157600080fd5b80634dba39a2116101b0578063616d29641161017f578063715018a611610164578063715018a61461043b57806383af5550146104505780638456cb591461046657600080fd5b8063616d2964146104055780636ebc51e11461041b57600080fd5b80634dba39a21461037757806351b78b471461039757806359b80cf9146103b75780635c975abb146103ca57600080fd5b80633fc8cef3116101ec5780633fc8cef3146102bd578063403a01e5146102f1578063498f3097146103115780634d8650d71461035757600080fd5b806301d122d614610229578063091a76c61461024b57806339e7fddc1461026b5780633f4ba83a146102a857600080fd5b3661022457005b600080fd5b34801561023557600080fd5b50610249610244366004613439565b6106e1565b005b34801561025757600080fd5b50610249610266366004613454565b61071e565b34801561027757600080fd5b5060045461028b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102b457600080fd5b5061024961072b565b3480156102c957600080fd5b5061028b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b3480156102fd57600080fd5b5061024961030c366004613454565b61073d565b34801561031d57600080fd5b5061034961032c366004613482565b600b60209081526000928352604080842090915290825290205481565b60405190815260200161029f565b34801561036357600080fd5b50610249610372366004613454565b6107e1565b34801561038357600080fd5b506102496103923660046134b9565b6107ee565b3480156103a357600080fd5b506102496103b23660046134b9565b6108c6565b6102496103c53660046135ac565b61099e565b3480156103d657600080fd5b5060005474010000000000000000000000000000000000000000900460ff16604051901515815260200161029f565b34801561041157600080fd5b5061034960075481565b34801561042757600080fd5b506102496104363660046134b9565b6111f4565b34801561044757600080fd5b506102496112f2565b34801561045c57600080fd5b5061034960055481565b34801561047257600080fd5b50610249611304565b34801561048757600080fd5b5061028b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b3480156104af57600080fd5b506000546001600160a01b031661028b565b3480156104cd57600080fd5b506102496104dc366004613482565b611314565b3480156104ed57600080fd5b5061028b6104fc366004613439565b600a602052600090815260409020546001600160a01b031681565b34801561052357600080fd5b5060035461028b906001600160a01b031681565b34801561054357600080fd5b50610249610552366004613733565b6113fd565b34801561056357600080fd5b506102496105723660046134b9565b611518565b34801561058357600080fd5b506008546105929061ffff1681565b60405161ffff909116815260200161029f565b3480156105b157600080fd5b5060085461059290640100000000900461ffff1681565b3480156105d457600080fd5b5061034960065481565b3480156105ea57600080fd5b506102496105f93660046134b9565b61155a565b34801561060a57600080fd5b506008546105929062010000900461ffff1681565b34801561062b57600080fd5b50610349620186a081565b34801561064257600080fd5b506102496106513660046134b9565b611631565b34801561066257600080fd5b5061028b610671366004613439565b6009602052600090815260409020546001600160a01b031681565b34801561069857600080fd5b506106ac6106a73660046137c1565b6116d8565b6040805192835260208301919091520161029f565b3480156106cd57600080fd5b5060025461028b906001600160a01b031681565b6106e96117cd565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff92909216919091179055565b6107266117cd565b600755565b6107336117cd565b61073b611841565b565b6107456117cd565b6127108111156107dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f576f6f43726f7373436861696e526f7574657256333a20215f6272696467655360448201527f6c6970706167650000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b600555565b6107e96117cd565b600655565b6107f66117cd565b6001600160a01b03811661088c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f576f6f43726f7373436861696e526f7574657256333a20215f776f6f526f757460448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084016107d3565b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6108ce6117cd565b6001600160a01b038116610964576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f576f6f43726f7373436861696e526f7574657256333a20215f7374617267617460448201527f65526f757465720000000000000000000000000000000000000000000000000060648201526084016107d3565b600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6109a66118b1565b6109ae611936565b83516001600160a01b0316610a45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f576f6f43726f7373436861696e526f7574657256333a2021737263496e666f7360448201527f2e66726f6d546f6b656e0000000000000000000000000000000000000000000060648201526084016107d3565b6000610a5760408501602086016134b9565b6001600160a01b031614158015610ab65750600a6000610a7a6020860186613439565b61ffff1681526020808201929092526040908101600020546001600160a01b031691610aaa9186019086016134b9565b6001600160a01b031614155b610b42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f576f6f43726f7373436861696e526f7574657256333a2021647374496e666f7360448201527f2e746f546f6b656e00000000000000000000000000000000000000000000000060648201526084016107d3565b6001600160a01b038516610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f576f6f43726f7373436861696e526f7574657256333a2021746f00000000000060448201526064016107d3565b8351349060009081906001600160a01b03167fffffffffffffffffffffffff111111111111111111111111111111111111111201610d2f578287604001511115610c7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f576f6f43726f7373436861696e526f7574657256333a2021737263496e666f7360448201527f2e66726f6d416d6f756e7400000000000000000000000000000000000000000060648201526084016107d3565b6001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21680885260408089015181517fd0e30db0000000000000000000000000000000000000000000000000000000008152915163d0e30db09260048082019260009290919082900301818588803b158015610cff57600080fd5b505af1158015610d13573d6000803e3d6000fd5b5050505050866040015183610d28919061385c565b9250610d43565b610d43876000015133308a604001516119a9565b86602001516001600160a01b031687600001516001600160a01b031614610f465786516002546040890151610d8292916001600160a01b031690611b33565b6000610d9160208701876134b9565b6001600160a01b031614610e86576002546001600160a01b031663199b83fa610dbd60208801886134b9565b610dca60208901896134b9565b8a600001518b602001518c604001518d60600151308d8060200190610def9190613873565b6040518a63ffffffff1660e01b8152600401610e139998979695949392919061390a565b6020604051808303816000875af1158015610e32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e56919061396c565b600854909250620186a090610e759062010000900461ffff1684613985565b610e7f91906139c2565b9050610fe5565b600254875160208901516040808b015160608c015191517f7dc203820000000000000000000000000000000000000000000000000000000081526001600160a01b0394851660048201529284166024840152604483015260648201523060848201528a821660a4820152911690637dc203829060c4016020604051808303816000875af1158015610f1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3f919061396c565b9150610fe5565b8660600151876040015114610fdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f576f6f43726f7373436861696e526f7574657256333a2021737263496e666f7360448201527f2e6d696e427269646765416d6f756e740000000000000000000000000000000060648201526084016107d3565b866040015191505b60208701516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611048573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106c919061396c565b8211156110fa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f576f6f43726f7373436861696e526f7574657256333a2021627269646765416d60448201527f6f756e740000000000000000000000000000000000000000000000000000000060648201526084016107d3565b611104818361385c565b9150611115898985858b8b8a611cbc565b6001600160a01b038816336001600160a01b03168a7f546dc08c5438b68796e5047ad2ac863ab74300bdf49457917d47021f090c45c48a600001518b604001518c602001518d606001518960006001600160a01b03168e600001602081019061117e91906134b9565b6001600160a01b031614611193576001611196565b60005b604080516001600160a01b039788168152602081019690965293909516928401929092526060830152608082015260ff90911660a082015260c0810186905260e00160405180910390a45050506111ec60018055565b505050505050565b6111fc611936565b6004546001600160a01b031661126e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f576f6f43726f7373436861696e526f7574657256333a2021666565416464720060448201526064016107d3565b600061127a8230612166565b905080156112e5577fffffffffffffffffffffffff11111111111111111111111111111111111111126001600160a01b038316016112cd576004546112c8906001600160a01b031682612227565b6112e5565b6004546112e59083906001600160a01b031683612329565b506112ef60018055565b50565b6112fa6117cd565b61073b60006124ab565b61130c6117cd565b61073b612513565b61131c6117cd565b6001600160a01b0381166113b1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f576f6f43726f7373436861696e526f7574657256333a20215f63726f7373526f60448201527f757465720000000000000000000000000000000000000000000000000000000060648201526084016107d3565b61ffff91909116600090815260096020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909216919091179055565b6003546001600160a01b03163314611497576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f576f6f43726f7373436861696e526f7574657256333a20494e56414c49445f4360448201527f414c4c455200000000000000000000000000000000000000000000000000000060648201526084016107d3565b6000806000806000858060200190518101906114b39190613a2d565b60085461ffff166000908152600a6020526040902054949950929750909550935091506001600160a01b03908116908916036114fc576114f78585858a8686612582565b61150b565b61150b8585858b8b8787612de6565b5050505050505050505050565b6115206117cd565b600480547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6115626117cd565b7fffffffffffffffffffffffff11111111111111111111111111111111111111126001600160a01b0382160161159c576112ef3347612227565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156115fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611620919061396c565b905061162d823383612329565b5050565b6116396117cd565b6001600160a01b0381166116cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107d3565b6112ef816124ab565b6000808086866116ee60408801602089016134b9565b876060013587604051602001611708959493929190613bbf565b60408051601f19818403018152919052905060006117348761172f36899003890189613c02565b6132c7565b6003549091506001600160a01b0316630a5123696117556020890189613439565b6001846040015186866040518663ffffffff1660e01b815260040161177e959493929190613ce5565b6040805180830381865afa15801561179a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117be9190613d3d565b93509350505094509492505050565b6000546001600160a01b0316331461073b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107d3565b611849613369565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60005474010000000000000000000000000000000000000000900460ff161561073b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016107d3565b6002600154036119a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107d3565b6002600155565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790529151600092839290881691611a3b9190613d61565b6000604051808303816000865af19150503d8060008114611a78576040519150601f19603f3d011682016040523d82523d6000602084013e611a7d565b606091505b5091509150818015611aa7575080511580611aa7575080806020019051810190611aa79190613d7d565b6111ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a20747260448201527f616e7366657246726f6d206661696c656400000000000000000000000000000060648201526084016107d3565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151600092839290871691611bbd9190613d61565b6000604051808303816000865af19150503d8060008114611bfa576040519150601f19603f3d011682016040523d82523d6000602084013e611bff565b606091505b5091509150818015611c29575080511580611c29575080806020019051810190611c299190613d7d565b611cb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f5472616e7366657248656c7065723a3a73616665417070726f76653a2061707060448201527f726f7665206661696c656400000000000000000000000000000000000000000060648201526084016107d3565b5050505050565b60085461ffff166000908152600b60209081526040808320868301516001600160a01b03168452909152902054611d75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f576f6f43726f7373436861696e526f7574657256333a2021737263496e666f7360448201527f2e627269646765546f6b656e000000000000000000000000000000000000000060648201526084016107d3565b6000600b81611d876020860186613439565b61ffff1661ffff1681526020019081526020016000206000846040016020810190611db291906134b9565b6001600160a01b03166001600160a01b031681526020019081526020016000205411611e60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f576f6f43726f7373436861696e526f7574657256333a2021647374496e666f7360448201527f2e627269646765546f6b656e000000000000000000000000000000000000000060648201526084016107d3565b60008787611e7460408601602087016134b9565b856060013585604051602001611e8e959493929190613bbf565b60405160208183030381529060405290506000612710600554612710611eb4919061385c565b611ebe9088613985565b611ec891906139c2565b90506000600981611edc6020880188613439565b61ffff1681526020808201929092526040908101600020549051611f37926001600160a01b03909216910160609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b60408051601f1981840301815291905290506000611f5e8a61172f36899003890189613c02565b90507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031687602001516001600160a01b031603612043576040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018990527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561201857600080fd5b505af115801561202c573d6000803e3d6000fd5b50505050878961203c9190613d9f565b985061205f565b602087015160035461205f91906001600160a01b03168a611b33565b6003546001600160a01b0316639fbf10fc8a61207e60208a018a613439565b60085461ffff166000908152600b602081815260408084208f8301516001600160a01b03168552825283205492906120b8908e018e613439565b61ffff1661ffff16815260200190815260200160002060008c60400160208101906120e391906134b9565b6001600160a01b03168152602081019190915260400160002054338e8a898b8e6040518b63ffffffff1660e01b815260040161212799989796959493929190613db7565b6000604051808303818588803b15801561214057600080fd5b505af1158015612154573d6000803e3d6000fd5b50505050505050505050505050505050565b60006001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14612214576040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301528416906370a0823190602401602060405180830381865afa1580156121eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220f919061396c565b612220565b816001600160a01b0316315b9392505050565b604080516000808252602082019092526001600160a01b0384169083906040516122519190613d61565b60006040518083038185875af1925050503d806000811461228e576040519150601f19603f3d011682016040523d82523d6000602084013e612293565b606091505b5050905080612324576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527f20455448207472616e73666572206661696c656400000000000000000000000060648201526084016107d3565b505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916123b39190613d61565b6000604051808303816000865af19150503d80600081146123f0576040519150601f19603f3d011682016040523d82523d6000602084013e6123f5565b606091505b509150915081801561241f57508051158061241f57508080602001905181019061241f9190613d7d565b611cb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c65640000000000000000000000000000000000000060648201526084016107d3565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61251b6118b1565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586118943390565b336001600160a01b0385167fffffffffffffffffffffffff1111111111111111111111111111111111111112016126ae576125bd8685612227565b856001600160a01b0316816001600160a01b0316887fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2888a73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8a8c60006001600160a01b03168c600001516001600160a01b031614612652576001612655565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c0820152600060e08201529051908190036101000190a4506111ec565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b15801561270957600080fd5b505af115801561271d573d6000803e3d6000fd5b505084516001600160a01b0316159250612aa291505057600854600090620186a09061275590640100000000900461ffff1687613985565b61275f91906139c2565b9050600061276d828761385c565b6002549091506127a8907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2906001600160a01b031683611b33565b600260009054906101000a90046001600160a01b03166001600160a01b031663199b83fa856000015186600001517f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28b868b8f8c602001516040518963ffffffff1660e01b8152600401612823989796959493929190613e25565b6020604051808303816000875af192505050801561285e575060408051601f3d908101601f1916820190925261285b9181019061396c565b60015b6129c25760025461289b907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2906001600160a01b03166000611b33565b6128c67f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28988612329565b876001600160a01b0316836001600160a01b03168a7fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28a8c7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28c8e60006001600160a01b03168e600001516001600160a01b03161461296757600161296a565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c0820152600060e08201529051908190036101000190a4612a9b565b886001600160a01b0316846001600160a01b03168b7fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2868d8e8d8960006001600160a01b03168f600001516001600160a01b031614612a43576001612a46565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c082015260e081018990529051908190036101000190a4505b5050612ddd565b600254612ada907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2906001600160a01b031686611b33565b6002546040517f7dc203820000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281166004830152878116602483015260448201879052606482018690528881166084830181905260a483015290911690637dc203829060c4016020604051808303816000875af1925050508015612ba0575060408051601f3d908101601f19168201909252612b9d9181019061396c565b60015b612d0457600254612bdd907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2906001600160a01b03166000611b33565b612c087f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28786612329565b856001600160a01b0316816001600160a01b0316887fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2888a7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28a8c60006001600160a01b03168c600001516001600160a01b031614612ca9576001612cac565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c0820152600060e08201529051908190036101000190a4612ddd565b866001600160a01b0316826001600160a01b0316897fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2898b8c8b8960006001600160a01b03168d600001516001600160a01b031614612d85576001612d88565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c0820152600060e08201529051908190036101000190a4505b50505050505050565b336001600160a01b0380861690871603612ec157612e05858886612329565b866001600160a01b0316816001600160a01b0316897fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c88888b8c8a8c60006001600160a01b03168c600001516001600160a01b031614612e66576001612e69565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c0820152600060e08201529051908190036101000190a46132bd565b600854600090620186a090612ee290640100000000900461ffff1687613985565b612eec91906139c2565b9050612ef8818661385c565b600254909550612f139087906001600160a01b031687611b33565b82516001600160a01b03161561314d57600260009054906101000a90046001600160a01b03166001600160a01b031663199b83fa84600001518560000151898b8a8a8f8b602001516040518963ffffffff1660e01b8152600401612f7e989796959493929190613e25565b6020604051808303816000875af1925050508015612fb9575060408051601f3d908101601f19168201909252612fb69181019061396c565b60015b61309057612fc78186613d9f565b9450612fd4868987612329565b876001600160a01b0316826001600160a01b03168a7fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c89898c8c8b8d60006001600160a01b03168d600001516001600160a01b031614613035576001613038565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c0820152600060e08201529051908190036101000190a46132bb565b886001600160a01b0316836001600160a01b03168b7fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c8a8a8d8e8c8960006001600160a01b03168e600001516001600160a01b0316146130f15760016130f4565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c082015260e081018890529051908190036101000190a4506132bb565b6002546040517f7dc203820000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152898116602483015260448201889052606482018790528a81166084830181905260a483015290911690637dc203829060c4016020604051808303816000875af19250505080156131f3575060408051601f3d908101601f191682019092526131f09181019061396c565b60015b61320257612fd4868987612329565b886001600160a01b0316836001600160a01b03168b7fe025e234368c681f94aa603de304cf6708c5638fe7454d6ed22a55430776a71c8a8a8d8e8c8960006001600160a01b03168e600001516001600160a01b031614613263576001613266565b60005b604080516001600160a01b039889168152602081019790975294871686860152929095166060850152608084015260a083019390935260ff90921660c0820152600060e08201529051908190036101000190a4505b505b5050505050505050565b6132eb60405180606001604052806000815260200160008152602001606081525090565b60006132f6836133ed565b90506040518060600160405280828152602001846080015181526020018560405160200161334f919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b60408051601f198184030181529190529052949350505050565b60005474010000000000000000000000000000000000000000900460ff1661073b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016107d3565b600081604001516001600160a01b031682602001516001600160a01b0316146134185760065461341c565b6007545b92915050565b803561ffff8116811461343457600080fd5b919050565b60006020828403121561344b57600080fd5b61222082613422565b60006020828403121561346657600080fd5b5035919050565b6001600160a01b03811681146112ef57600080fd5b6000806040838503121561349557600080fd5b61349e83613422565b915060208301356134ae8161346d565b809150509250929050565b6000602082840312156134cb57600080fd5b81356122208161346d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715613528576135286134d6565b60405290565b6040805190810167ffffffffffffffff81118282101715613528576135286134d6565b604051601f8201601f1916810167ffffffffffffffff8111828210171561357a5761357a6134d6565b604052919050565b600060a0828403121561359457600080fd5b50919050565b60006040828403121561359457600080fd5b6000806000806000808688036101a08112156135c757600080fd5b8735965060208801356135d98161346d565b955060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08201121561360b57600080fd5b50613614613505565b60408801356136228161346d565b815260608801356136328161346d565b60208201526080880135604082015260a08801356060820152935061365a8860c08901613582565b925061016087013567ffffffffffffffff8082111561367857600080fd5b6136848a838b0161359a565b935061018089013591508082111561369b57600080fd5b506136a889828a0161359a565b9150509295509295509295565b600067ffffffffffffffff8211156136cf576136cf6134d6565b50601f01601f191660200190565b600082601f8301126136ee57600080fd5b81356137016136fc826136b5565b613551565b81815284602083860101111561371657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561374c57600080fd5b61375587613422565b9550602087013567ffffffffffffffff8082111561377257600080fd5b61377e8a838b016136dd565b965060408901359550606089013591506137978261346d565b9093506080880135925060a088013590808211156137b457600080fd5b506136a889828a016136dd565b60008060008061010085870312156137d857600080fd5b8435935060208501356137ea8161346d565b92506137f98660408701613582565b915060e085013567ffffffffffffffff81111561381557600080fd5b6138218782880161359a565b91505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561386e5761386e61382d565b500390565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126138a857600080fd5b83018035915067ffffffffffffffff8211156138c357600080fd5b6020019150368190038213156138d857600080fd5b9250929050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b60006101006001600160a01b03808d168452808c166020850152808b166040850152808a1660608501528860808501528760a085015280871660c0850152508060e084015261395c81840185876138df565b9c9b505050505050505050505050565b60006020828403121561397e57600080fd5b5051919050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156139bd576139bd61382d565b500290565b6000826139f8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b83811015613a18578181015183820152602001613a00565b83811115613a27576000848401525b50505050565b600080600080600060a08688031215613a4557600080fd5b85519450602080870151613a588161346d565b6040880151909550613a698161346d565b60608801516080890151919550935067ffffffffffffffff80821115613a8e57600080fd5b908801906040828b031215613aa257600080fd5b613aaa61352e565b8251613ab58161346d565b81528284015182811115613ac857600080fd5b8084019350508a601f840112613add57600080fd5b82519150613aed6136fc836136b5565b8281528b85848601011115613b0157600080fd5b613b10838683018787016139fd565b808583015250809450505050509295509295909350565b60008135613b348161346d565b6001600160a01b031683526020820135368390037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1018112613b7557600080fd5b820160208101903567ffffffffffffffff811115613b9257600080fd5b803603821315613ba157600080fd5b60406020860152613bb66040860182846138df565b95945050505050565b85815260006001600160a01b03808716602084015280861660408401525083606083015260a06080830152613bf760a0830184613b27565b979650505050505050565b600060a08284031215613c1457600080fd5b60405160a0810181811067ffffffffffffffff82111715613c3757613c376134d6565b604052613c4383613422565b81526020830135613c538161346d565b60208201526040830135613c668161346d565b6040820152606083810135908201526080928301359281019290925250919050565b60008151808452613ca08160208601602086016139fd565b601f01601f19169290920160200192915050565b80518252602081015160208301526000604082015160606040850152613cdd6060850182613c88565b949350505050565b61ffff8616815260ff8516602082015260a060408201526000613d0b60a0830186613c88565b8281036060840152613d1d8186613c88565b90508281036080840152613d318185613cb4565b98975050505050505050565b60008060408385031215613d5057600080fd5b505080516020909101519092909150565b60008251613d738184602087016139fd565b9190910192915050565b600060208284031215613d8f57600080fd5b8151801515811461222057600080fd5b60008219821115613db257613db261382d565b500190565b600061012061ffff8c1683528a60208401528960408401526001600160a01b03891660608401528760808401528660a08401528060c0840152613dfc81840187613cb4565b905082810360e0840152613e108186613c88565b905082810361010084015261395c8185613c88565b60006101006001600160a01b03808c168452808b166020850152808a16604085015280891660608501528760808501528660a085015280861660c0850152508060e0840152613e7681840185613c88565b9b9a505050505050505050505056fea2646970667358221220bc30f46519786380a48bcfad50acc990718c7071fb26ad71f571c65b030ffb1e64736f6c634300080e0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000044c08639bd59beb4f6ec52c0da6cd47283534e80000000000000000000000003b83d454a50abe06d94cb0d5d367825e190bda8f0000000000000000000000000000000000000000000000000000000000000065
-----Decoded View---------------
Arg [0] : _weth (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [1] : _wooRouter (address): 0x044c08639bD59BEB4F6ec52c0da6CD47283534E8
Arg [2] : _stargateRouter (address): 0x3b83D454A50aBe06d94cb0d5d367825e190bDA8F
Arg [3] : _sgChainIdLocal (uint16): 101
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [1] : 000000000000000000000000044c08639bd59beb4f6ec52c0da6cd47283534e8
Arg [2] : 0000000000000000000000003b83d454a50abe06d94cb0d5d367825e190bda8f
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000065
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
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.