Contract 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d

Txn Hash Method
Block
From
To
Value [Txn Fee]
0x0820afc812c26e80e1257b17cd137a4cb2d02ea13e1f3f9dacf7c947b663770fRemove Liquidity...38258122023-03-15 18:11:1213 days 15 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.001358325
0xa95d481481c67009471672f8d312162eae70fca0a883e90375ca5b98996d090aAdd Sync Liquidi...38255282023-03-15 17:13:4813 days 16 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.00122086
0x01abd7c4b71196ee4bfe3a33fa392fed443854e2a74360282125545ae1e90979Add Sync Liquidi...38255272023-03-15 17:13:3613 days 16 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.0001206125
0xa6e1ced3f376b7e5ba19b0aba409916b5af44ef04ab718b6ab273b7752be4d1bRemove Liquidity...38255272023-03-15 17:13:3613 days 16 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.00138364
0xa0f697e2ca65a042bb5b5ef1ec91ff80cd0b8924af1dad0e1a39f165dbe7ef8bRemove Liquidity...38255272023-03-15 17:13:3613 days 16 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.00111602
0x2924d65c3629c365464750cd91cde13037186d6cebb74704a845106103a85040Remove Liquidity...38255272023-03-15 17:13:3613 days 16 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.00121342
0x935efa60d48cfc615582b6346d4deadc36a12cffd210643e07cb92ba0a24e5dcRemove Liquidity...38255262023-03-15 17:13:2413 days 16 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.0011289875
0x7caaf6b591b66ece5d38f3d0916dd963dd50f658ea6c1ea034bdebfd9a867a64Add Sync Liquidi...38255262023-03-15 17:13:2413 days 16 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.001102305
0xd06bc7636e5017c03177f4ffd55d4e01470e5263c365b23a2c5bdcb03dc83739Add Sync Liquidi...38255262023-03-15 17:13:2413 days 16 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.001466455
0x479be4b2992ad0b9c4f2cd28b94bd14279ac19998d01225e608a85acce538bc1Remove Liquidity...38255242023-03-15 17:13:0013 days 16 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.0012816775
0x708f25c6067e4f633793f3cd34d635181682d6d3998c955f158333fcb652ca5eAdd Sync Liquidi...38255212023-03-15 17:12:2413 days 16 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.000127625
0xe98f1aa42a34cb69bd6b5fde9ed22031f3dc815b51641471a8539b83366ac28cAdd Sync Liquidi...38255212023-03-15 17:12:2413 days 16 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.0014466725
0x865fb09ecf86fa2ed844d13311986e6babd02c434a3d774a6c52ac4d93f875a5Add Sync Liquidi...38255212023-03-15 17:12:2413 days 16 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.0012122025
0xab45a2494ec82a53d8c96f2beb86b9a5855eb56602038f9618c72464a0843fd0Add Sync Liquidi...38255192023-03-15 17:12:0013 days 16 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.00133086
0xbcd3efd3730de3a0ec14ec4d824f4f2db9f4f8d425bfa7ba219de711f844c43dAdd Sync Liquidi...38255172023-03-15 17:11:3613 days 16 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.001203635
0x86d9d8263e99219c683a71a936e63f03d0b40ab8f68df955e2a5cd1d17aa92f0Add Sync Liquidi...38255172023-03-15 17:11:3613 days 16 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.001348535
0x84c053384386a3351e06ca5830e87dd839991015b027b4a00c2b2f98c992e737Add Sync Liquidi...38252262023-03-15 16:12:2413 days 17 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.00012762
0xb02826ed8a33cf83b9023a0cade378780430d7d2285c3fea6336631bcad14235Add Sync Liquidi...38252262023-03-15 16:12:2413 days 17 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.0010509925
0xde098c9a1e07258388bf9550c9036f674ff3fbe81dd65a8fa5194ea2f9116c46Remove Liquidity...38252252023-03-15 16:12:0613 days 17 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.0012202475
0xe571119739ee8736b16433c32db025675565bab4930b226ce3f23473d610fe45Remove Liquidity...38252252023-03-15 16:12:0613 days 17 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.0013235675
0x59053cb979e6fddac64300d07fd80fa28e0a2050d299b09a8d1692cbfd097d18Add Sync Liquidi...38252252023-03-15 16:12:0613 days 17 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.0011793775
0x210a0104ef7f33f1551fc08b911f4390457b37a738beb1b461d0e37549e35629Remove Liquidity...38252232023-03-15 16:11:4213 days 17 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.0009991775
0xc9c45fb61462680fd43c453c1d643b67e303cefa7ce292bdc9aaf7ba376ca014Remove Liquidity...38252232023-03-15 16:11:4213 days 17 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.0013431075
0x7966769022b351320f4685385e4cbb128b91c6b3b5a20f1edccb3098c0352aa8Add Sync Liquidi...38252222023-03-15 16:11:3013 days 17 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.0013442725
0x239417057cc61d3738121bea22d5fbc83bb3b106c74a410f1fe9c48562da0b6cRemove Liquidity...38252222023-03-15 16:11:3013 days 17 hrs ago0x75fa4420d221d5a956ad9a2192a72ce640492ced IN  0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0 MOVR0.0011284725
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x3374261908afa6082204b319b07dfe4040e96e03bfb8df43c96138ef4b0480e038441712023-03-18 8:17:3611 days 1 hr ago 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d Moonbeam Foundation: WMOVR Token13.478139836897214363 MOVR
0x3374261908afa6082204b319b07dfe4040e96e03bfb8df43c96138ef4b0480e038441712023-03-18 8:17:3611 days 1 hr ago 0x0000000000000000000000000000000000000808 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d13.478139836897214363 MOVR
0xf8797c095aa34a695cd9ab7f9b0a2880f660556b66004730b295a519013344b338441582023-03-18 8:14:5411 days 1 hr ago 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0x2ad2264a0755936137ac256fd9d742feee7ab5ff13.482881631897214363 MOVR
0xf8797c095aa34a695cd9ab7f9b0a2880f660556b66004730b295a519013344b338441582023-03-18 8:14:5411 days 1 hr ago Moonbeam Foundation: WMOVR Token 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d13.482881631897214363 MOVR
0x4bd342518127df27a5e8d51ac5df3341ae9c2c88f5b825c1fbbb59f72700144138441532023-03-18 8:13:5411 days 1 hr ago 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d Moonbeam Foundation: WMOVR Token13.452749524397214362 MOVR
0x4bd342518127df27a5e8d51ac5df3341ae9c2c88f5b825c1fbbb59f72700144138441532023-03-18 8:13:5411 days 1 hr ago 0x0000000000000000000000000000000000000808 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d13.452749524397214362 MOVR
0x823caaba639be7d5fe52fa5f0e05d085580cc615d218d8ba635cc0559974544b38441472023-03-18 8:12:3611 days 1 hr ago 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0x2ad2264a0755936137ac256fd9d742feee7ab5ff13.482881631897214362 MOVR
0x823caaba639be7d5fe52fa5f0e05d085580cc615d218d8ba635cc0559974544b38441472023-03-18 8:12:3611 days 1 hr ago Moonbeam Foundation: WMOVR Token 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d13.482881631897214362 MOVR
0x8f0495bf6df67d4387671b342d2df5fb7dc885902597438a7b30b0bbd36f9d3a38419012023-03-18 0:36:1211 days 9 hrs ago 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d Moonbeam Foundation: WMOVR Token8.513201177277672295 MOVR
0x8f0495bf6df67d4387671b342d2df5fb7dc885902597438a7b30b0bbd36f9d3a38419012023-03-18 0:36:1211 days 9 hrs ago 0x0000000000000000000000000000000000000808 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d8.513201177277672295 MOVR
0x0b118a68b0c3c0b973ecf2bdef411521e2d2a385dae1bf5a83499cc32ab8800f38418702023-03-18 0:29:5411 days 9 hrs ago 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0x7c6d932fb73aa2468093b39d563ebeaea22445558.510419920998815073 MOVR
0x0b118a68b0c3c0b973ecf2bdef411521e2d2a385dae1bf5a83499cc32ab8800f38418702023-03-18 0:29:5411 days 9 hrs ago Moonbeam Foundation: WMOVR Token 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d8.510419920998815073 MOVR
0x9436dc10388bb15ff52be46af0349254edcc29db80dd530cdbba7cfc32e5cccf38407732023-03-17 20:47:5411 days 12 hrs ago 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0x780f6e15712490de5dd353e9646717922e7530339.596997252913362476 MOVR
0x9436dc10388bb15ff52be46af0349254edcc29db80dd530cdbba7cfc32e5cccf38407732023-03-17 20:47:5411 days 12 hrs ago Moonbeam Foundation: WMOVR Token 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d9.596997252913362476 MOVR
0x76ed1d6d5cf988bbf6d9ce274e2f705055bc950e59cd25b78dc61b3153bed4de38370552023-03-17 8:12:3012 days 1 hr ago 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0x6020b55e2bf6746e513a1e99561cb50843fb6f2858.641372763872658821 MOVR
0x76ed1d6d5cf988bbf6d9ce274e2f705055bc950e59cd25b78dc61b3153bed4de38370552023-03-17 8:12:3012 days 1 hr ago Moonbeam Foundation: WMOVR Token 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d58.641372763872658821 MOVR
0xdc79d69ea08c483ba2df059eb9a495c9d018655923dd82583e05a47d7bc851f038369722023-03-17 7:55:2412 days 1 hr ago 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0x83a110727d39159a65c835d0c6c162ebc01acaea41.001408617858849443 MOVR
0xdc79d69ea08c483ba2df059eb9a495c9d018655923dd82583e05a47d7bc851f038369722023-03-17 7:55:2412 days 1 hr ago Moonbeam Foundation: WMOVR Token 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d41.001408617858849443 MOVR
0xf4ebcda5f850d2403b3de0530aa3a3841998c25a56cb795b4858062aedc6df3038366442023-03-17 6:48:2412 days 2 hrs ago 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d Moonbeam Foundation: WMOVR Token50 MOVR
0xf4ebcda5f850d2403b3de0530aa3a3841998c25a56cb795b4858062aedc6df3038366442023-03-17 6:48:2412 days 2 hrs ago 0x0000000000000000000000000000000000000808 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d50 MOVR
0x0dc13f7c9e28e42c9d79ce1cfccf120c325ed84c6de690248afb7dd74f6a41e238366142023-03-17 6:42:2412 days 2 hrs ago 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0x52fcaed1f886aa5a2f02ebad8365afd2ca722b0443.754783288373734008 MOVR
0x0dc13f7c9e28e42c9d79ce1cfccf120c325ed84c6de690248afb7dd74f6a41e238366142023-03-17 6:42:2412 days 2 hrs ago Moonbeam Foundation: WMOVR Token 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d43.754783288373734008 MOVR
0xd832450264508a024920f9575ec7b41e5c024bd7ce0b4f12154c4a7d0636945d38337692023-03-16 21:07:4212 days 12 hrs ago 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0xb6932ae987775fc317737d35e9df3cb7ccc9cfec17.342886959474630316 MOVR
0xd832450264508a024920f9575ec7b41e5c024bd7ce0b4f12154c4a7d0636945d38337692023-03-16 21:07:4212 days 12 hrs ago Moonbeam Foundation: WMOVR Token 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d17.342886959474630316 MOVR
0x1e4a6f8b40fa1f2b8475a9553b0311e9fd89a98ce4fbd09ac478b8be2f87aec238337212023-03-16 20:58:0612 days 12 hrs ago 0x78bc5d98bc4df08fd14889f682b13bf824bc3b0d0xb6932ae987775fc317737d35e9df3cb7ccc9cfec15.663707078601520924 MOVR
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ZirconPylonRouter

Compiler Version
v0.6.6+commit.6c089d02

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 14 : ZirconPylonRouter.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity =0.6.6;

import "./interfaces/IZirconPylonRouter.sol";
import "@zircon/core/contracts/interfaces/IZirconPair.sol";
import "@zircon/core/contracts/interfaces/IZirconPylonFactory.sol";
import "@zircon/core/contracts/interfaces/IZirconFactory.sol";
import "@zircon/core/contracts/interfaces/IZirconPoolToken.sol";
import "@zircon/core/contracts/interfaces/IZirconPTFactory.sol";
import "./libraries/ZirconPeripheralLibrary.sol";
import "./libraries/UniswapV2Library.sol";
//import "hardhat/console.sol";
import "@uniswap/lib/contracts/libraries/TransferHelper.sol";
import "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol";

contract ZirconPylonRouter is IZirconPylonRouter {

    address public immutable override factory;
    address public immutable override pylonFactory;
    address public immutable override ptFactory;
    address public immutable override WETH;
    bytes4 private constant DEPOSIT = bytes4(keccak256(bytes('routerDeposit(uint256)')));

    modifier ensure(uint deadline) {
        require(deadline >= block.timestamp, 'UniswapV2Router: EXPIRED');
        _;
    }

    // **** Constructor ****
    constructor(address _factory, address _pylonFactory, address _ptFactory, address _WETH) public {
        factory = _factory;
        WETH = _WETH;
        pylonFactory = _pylonFactory;
        ptFactory = _ptFactory;
    }

    receive() external payable {
        assert(msg.sender == WETH); // only accept ETH via fallback from the WETH contract
    }

    // *** HELPER FUNCTIONS *****
    function _getPylon(address tokenA, address tokenB) internal view returns (address pylon){
        pylon = ZirconPeripheralLibrary.pylonFor(pylonFactory, tokenA, tokenB, UniswapV2Library.pairFor(factory, tokenA, tokenB));
    }

    // Transfers token or utility
    function _transfer(uint amountDesired, address token, address pylon) private {
        if (token == WETH) {
            IWETH(WETH).deposit{value: amountDesired}();
            assert(IWETH(WETH).transfer(pylon, amountDesired));
        }else{
            TransferHelper.safeTransferFrom(token, msg.sender, pylon, amountDesired);
        }
    }



    function _getAmounts(uint amountDesiredToken, uint amountDesiredETH, bool isAnchor, address tokenA, address tokenB) internal view returns (uint amountA, uint amountB){
        uint atA =  !isAnchor ? amountDesiredToken : amountDesiredETH;
        uint atB = !isAnchor ?  amountDesiredETH : amountDesiredToken;
        //        uint aminA = !isAnchor ? amountTokenMin : amountETHMin;
        //        uint aminB = !isAnchor ?  amountETHMin : amountTokenMin;
        (amountA, amountB) = _addAsyncLiquidity(tokenA, tokenB, atA, atB);
    }

    // Transfers both tokens to pylon
    function _transferAsync(address tokenA, address tokenB, uint amountA, uint amountB) internal returns (address pylon){
        pylon = _getPylon(tokenA, tokenB);
        TransferHelper.safeTransferFrom(tokenA, msg.sender, pylon, amountA);
        TransferHelper.safeTransferFrom(tokenB, msg.sender, pylon, amountB);
    }

    // Modifier to check that pylon & pair are initialized
    modifier _addLiquidityChecks(address tokenA, address tokenB) {
        address pair = IZirconFactory(factory).getPair(tokenA, tokenB);
        require(pair != address(0), "ZPR: Pair Not Created");
        require(IZirconPylonFactory(pylonFactory).getPylon(tokenA, tokenB) != address(0), "ZPR: Pylon not created");
        // Checking if pylon is initialized
        require(ZirconPeripheralLibrary.isInitialized(pylonFactory, tokenA, tokenB, pair), "ZPR: Pylon Not Initialized");
        _;
    }
    // function called only to use the modifier to restrict the usage
    function restricted(address tokenA, address tokenB) internal _addLiquidityChecks(tokenA, tokenB){}

    // **** INIT PYLON *****
    function _initializePylon(address tokenA, address tokenB) internal virtual returns (address pair, address pylon) {
        // If Pair is not initialized
        pair = IZirconFactory(factory).getPair(tokenA, tokenB);

        if (pair == address(0)) {
            // Let's create it...
            pair = IZirconFactory(factory).createPair(tokenA, tokenB, pylonFactory);
        }

        //Let's see if pylon is initialized
        pylon = IZirconPylonFactory(pylonFactory).getPylon(tokenA, tokenB);
        if (pylon == address(0)) {
            // adds pylon
            pylon = IZirconPylonFactory(pylonFactory).addPylon(pair, tokenA, tokenB);
        }
    }

    // Init Function with two tokens
    function init(
        address tokenA,
        address tokenB,
        uint amountDesiredA,
        uint amountDesiredB,
        address to,
        uint deadline
    ) external virtual override ensure(deadline) returns (uint amountA, uint amountB){
        // Initializes the pylon
        (, address pylon) = _initializePylon(tokenA, tokenB);
        // Desired amounts
        amountA = amountDesiredA;
        amountB = amountDesiredB;
        // Let's transfer to pylon
        TransferHelper.safeTransferFrom(tokenA, msg.sender, pylon, amountA);
        TransferHelper.safeTransferFrom(tokenB, msg.sender, pylon, amountB);
        // init Pylon
        IZirconPylon(pylon).initPylon(to);
    }

    // Init Function with one token and utility token
    function initETH(
        address token,
        uint amountDesiredToken,
        bool isAnchor,
        address to,
        uint deadline
    ) virtual override ensure(deadline)  external payable  returns (uint amountA, uint amountB){

        // Initialize Pylon & Pair
        address tokenA = isAnchor ? WETH : token;
        address tokenB = isAnchor ? token : WETH;
        (, address pylon) = _initializePylon(tokenA, tokenB);


        amountA = isAnchor ? msg.value : amountDesiredToken;
        amountB = isAnchor ? amountDesiredToken : msg.value;

        // Transfering tokens to Pylon
        TransferHelper.safeTransferFrom(token, msg.sender, pylon, amountDesiredToken);
        IWETH(WETH).deposit{value: msg.value}();
        assert(IWETH(WETH).transfer(pylon, msg.value));

        // Calling init Pylon
        IZirconPylon(pylon).initPylon(to);
    }

    // **** ADD SYNC LIQUIDITY ****
    function stake(address farm, uint liquidity) internal {
        (bool success, bytes memory data) = farm.call(abi.encodeWithSelector(DEPOSIT, uint256(liquidity)));
        if (!success) {
            if(data.length > 0){
                assembly {
                    let returndata_size := mload(data)
                    revert(add(32, data), returndata_size)
                }
            }else{
                require(success, 'ZP: FARM_FAILED');
            }
        }
    }

    function addSyncLiquidity(
        address tokenA,
        address tokenB,
        uint amountDesired,
        uint minLiquidity,
        bool isAnchor,
        address to,
        address farm,
        uint deadline
    ) virtual override ensure(deadline)  external returns (uint amount, uint liquidity) {
        // Checking Pylon and pair are initialized
        restricted(tokenA, tokenB);
        amount = amountDesired;
        // Getting pylon address
        address pylon = _getPylon(tokenA, tokenB);
        // Transferring tokens
        TransferHelper.safeTransferFrom(isAnchor ? tokenB : tokenA, msg.sender, pylon, amount);
        liquidity = IZirconPylon(pylon).mintPoolTokens(to, isAnchor);
        require(liquidity >= minLiquidity, "ZPR: Not enough liquidity");
        // Adding liquidity
        if (farm != address(0)) {
            stake(farm, liquidity);
        }
    }

    // @isAnchor indicates if the token should be the anchor or float
    // it mints the ETH token, so the opposite of isAnchor
    // In case where we want to mint the token we should use the classic addSyncLiquidity
    // TODO: removing shouldMintAnchor change on FE
    function addSyncLiquidityETH(
        address token,
        bool isAnchor,
        uint minLiquidity,
        address to,
        address farm,
        uint deadline
    ) virtual override ensure(deadline) external payable returns (uint liquidity) {
        require(msg.value > 0, "ZPR: ZERO-VALUE");
        address tokenA = isAnchor ? WETH : token;
        address tokenB = isAnchor ? token : WETH;
        // Checking Pylon and pair are initialized
        restricted(tokenA, tokenB);
        // Getting Pylon Address
        address pylon = _getPylon(tokenA, tokenB);
        // transferring token or utility token
        IWETH(WETH).deposit{value: msg.value}();
        assert(IWETH(WETH).transfer(pylon, msg.value));
        // minting tokens
        liquidity = IZirconPylon(pylon).mintPoolTokens(to, !isAnchor);
        require(liquidity >= minLiquidity, "ZPR: Not enough liquidity");
        // Adding liquidity
        if (farm != address(0)) {
            stake(farm, liquidity);
        }
    }

    // **** ASYNC-100 LIQUIDITY ******
    //    function addAsyncLiquidity100(
    //        address tokenA,
    //        address tokenB,
    //        uint amountDesired,
    //        bool isAnchor,
    //        address to,
    //        address farm,
    //        uint deadline
    //    ) virtual override ensure(deadline) _addLiquidityChecks(tokenA, tokenB) external returns (uint liquidity){
    //        // Getting Pylon Address
    //        address pylon = _getPylon(tokenA, tokenB);
    //        // sending tokens to pylon
    //        TransferHelper.safeTransferFrom(isAnchor ? tokenB : tokenA, msg.sender, pylon, amountDesired);
    //        // minting async-100
    //        liquidity = IZirconPylon(pylon).mintAsync100(to, isAnchor);
    //        // Adding liquidity
    //        if (farm != address(0)) {
    //            stake(farm, liquidity);
    //        }
    //    }

    // @isAnchor indicates if the token should be the anchor or float
    // This Function mints tokens for WETH in the contrary of @isAnchor
    //    function addAsyncLiquidity100ETH(
    //        address token,
    //        bool isAnchor,
    //        address to,
    //        address farm,
    //        uint deadline
    //    ) virtual override ensure(deadline)  external payable returns (uint liquidity){
    //        require(msg.value > 0, "ZPR: ZERO-VALUE");
    //        address tokenA = isAnchor ? WETH : token;
    //        address tokenB = isAnchor ? token : WETH;
    //
    //        restricted(tokenA, tokenB);
    //        // getting pylon
    //        address pylon = _getPylon(tokenA, tokenB);
    //        // Transfering tokens
    //        IWETH(WETH).deposit{value: msg.value}();
    //        assert(IWETH(WETH).transfer(pylon,  msg.value));
    //
    //        // Miting Async-100
    //        liquidity = IZirconPylon(pylon).mintAsync100(to, !isAnchor);
    //        // Adding liquidity
    //        if (farm != address(0)) {
    //            stake(farm, liquidity);
    //        }
    //    }

    // **** ADD ASYNC LIQUIDITY **** //

    function _addAsyncLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired
    ) internal virtual _addLiquidityChecks(tokenA, tokenB) view returns (uint amountA, uint amountB) {
        // create the pair if it doesn't exist yet
        (uint reserveA, uint reserveB) = UniswapV2Library.getReserves(factory, tokenA, tokenB);
        if (reserveA == 0 && reserveB == 0) {
            (amountA, amountB) = (amountADesired, amountBDesired);
        } else {
            uint amountBOptimal = UniswapV2Library.quote(amountADesired, reserveA, reserveB);
            if (amountBOptimal <= amountBDesired) {
                (amountA, amountB) = (amountADesired, amountBOptimal);
            } else {
                uint amountAOptimal = UniswapV2Library.quote(amountBDesired, reserveB, reserveA);
                assert(amountAOptimal <= amountADesired);
                (amountA, amountB) = (amountAOptimal, amountBDesired);
            }
        }

    }

    function addAsyncLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint minLiquidity,
        bool isAnchor,
        address to,
        address farm,
        uint deadline
    ) virtual override ensure(deadline)  external returns (uint liquidity){
        (uint amountA, uint amountB) = _addAsyncLiquidity(tokenA, tokenB, amountADesired, amountBDesired);
        address pylon = _transferAsync(tokenA, tokenB, amountA, amountB);
        liquidity = IZirconPylon(pylon).mintAsync(to, isAnchor);

        require(liquidity >= minLiquidity,string(abi.encodePacked("MIN_LIQUIDITY: ", uint2str(liquidity), " ", uint2str(minLiquidity))));
        // Adding liquidity
        if (farm != address(0)) {
            stake(farm, liquidity);
        }
    }


    function uint2str(uint _i) internal pure returns (string memory _uintAsString) {
        if (_i == 0) {
            return "0";
        }
        uint j = _i;
        uint len;
        while (j != 0) {
            len++;
            j /= 10;
        }
        bytes memory bstr = new bytes(len);
        uint k = len;
        while (_i != 0) {
            k = k-1;
            uint8 temp = (48 + uint8(_i - _i / 10 * 10));
            bytes1 b1 = bytes1(temp);
            bstr[k] = b1;
            _i /= 10;
        }
        return string(bstr);
    }

    function addAsyncLiquidityETH(
        address token,
        uint amountDesiredToken,
        uint minLiquidity,
        bool isAnchor,
        bool shouldReceiveAnchor,
        address to,
        address farm,
        uint deadline
    ) virtual override ensure(deadline)  external payable returns (uint amountA, uint amountB, uint liquidity){
        {
            address _token = token;
            bool _isAnchor = isAnchor;
            (amountA, amountB) = _getAmounts(amountDesiredToken, msg.value, _isAnchor, _isAnchor ? WETH : _token, _isAnchor ?  _token : WETH);
        }
        {
            address _token = token;
            bool _isAnchor = isAnchor;

            address pylon = _getPylon(_isAnchor ? WETH : _token, _isAnchor ?  _token : WETH);
            TransferHelper.safeTransferFrom(_token, msg.sender, pylon, _isAnchor ? amountB : amountA);
            IWETH(WETH).deposit{value: _isAnchor ? amountA : amountB}();
            assert(IWETH(WETH).transfer(pylon, _isAnchor ? amountA : amountB));
            liquidity = IZirconPylon(pylon).mintAsync(to, shouldReceiveAnchor);
            require(liquidity >= minLiquidity, uint2str(liquidity));
        }
        // refund dust eth, if any
        if (msg.value > (isAnchor ? amountA : amountB)) TransferHelper.safeTransferETH(msg.sender, msg.value - (isAnchor ? amountA : amountB));
        // Adding liquidity
        if (farm != address(0)) {
            stake(farm, liquidity);
        }
    }

    // *** remove Sync

    function removeLiquiditySync(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountMin,
        bool shouldReceiveAnchor,
        address to,
        uint deadline
    ) virtual override ensure(deadline)  public returns (uint amount){
        address pylon = _getPylon(tokenA, tokenB);
        address poolToken = IZirconPTFactory(ptFactory).getPoolToken(pylon, shouldReceiveAnchor ? tokenB : tokenA);

        IZirconPoolToken(poolToken).transferFrom(msg.sender, pylon, liquidity); // send liquidity to pylon
        (amount) = IZirconPylon(pylon).burn(to, shouldReceiveAnchor);
        require(amount >= amountMin, 'UniswapV2Router: INSUFFICIENT_AMOUNT');
    }

    function removeLiquiditySyncETH(
        address token,
        uint liquidity,
        uint amountMin,
        bool isAnchor,
        bool shouldRemoveAnchor,
        address to,
        uint deadline
    ) virtual override ensure(deadline)  external returns (uint amount){
        address tokenA = isAnchor ? WETH : token;
        address tokenB = isAnchor ? token : WETH;
        (amount) = removeLiquiditySync(
            tokenA,
            tokenB,
            liquidity,
            amountMin,
            shouldRemoveAnchor,
            (isAnchor && shouldRemoveAnchor) || (!shouldRemoveAnchor && !isAnchor) ? to : address(this),
            deadline
        );
        if ((isAnchor && !shouldRemoveAnchor) || (shouldRemoveAnchor && !isAnchor)) {
            IWETH(WETH).withdraw(amount);
            TransferHelper.safeTransferETH(to, amount);
        }
    }
    function removeLiquidityAsync(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        bool isAnchor,
        address to,
        uint deadline
    ) virtual override ensure(deadline)  public returns (uint amountA, uint amountB){
        address pylon = _getPylon(tokenA, tokenB);
        address poolToken = IZirconPTFactory(ptFactory).getPoolToken(pylon, isAnchor ? tokenB : tokenA);

        IZirconPoolToken(poolToken).transferFrom(msg.sender, pylon, liquidity); // send liquidity to pair
        (amountA, amountB) = IZirconPylon(pylon).burnAsync(to, isAnchor);


        require(amountA >= amountAMin, string(abi.encodePacked("A_AMOUNT: ", uint2str(amountA), " ", uint2str(amountAMin))));
        require(amountB >= amountBMin,  string(abi.encodePacked("B_AMOUNT: ", uint2str(amountB), " ", uint2str(amountBMin))));

    }
    function removeLiquidityAsyncETH(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        bool isAnchor,
        bool shouldBurnAnchor,
        address to,
        uint deadline
    ) virtual override ensure(deadline)  external returns (uint amountToken, uint amountETH){
        {
            (uint amountA, uint amountB) = removeLiquidityAsync(
                !isAnchor ? token : WETH,
                !isAnchor ? WETH : token,
                liquidity,
                !isAnchor ? amountTokenMin : amountETHMin,
                !isAnchor ? amountETHMin : amountTokenMin,
                shouldBurnAnchor,
                address(this),
                deadline
            );
            amountToken = !isAnchor ? amountA : amountB;
            amountETH = !isAnchor ?  amountB : amountA;
        }
        TransferHelper.safeTransfer(token, to, amountToken);
        IWETH(WETH).withdraw(amountETH);
        TransferHelper.safeTransferETH(to, amountETH);
    }

    //    function removeLiquiditySyncWithPermit(
    //        address tokenA,
    //        address tokenB,
    //        uint liquidity,
    //        uint amountMin,
    //        bool isAnchor,
    //        address to,
    //        uint deadline,
    //        bool approveMax, uint8 v, bytes32 r, bytes32 s
    //    ) virtual override ensure(deadline)  external returns (uint amount){
    //        address pylon = _getPylon(tokenA, tokenB);
    //        uint value = approveMax ? uint(-1) : liquidity;
    //        IZirconPoolToken(isAnchor ? IZirconPylon(pylon).anchorPoolTokenAddress() : IZirconPylon(pylon).floatPoolTokenAddress()).permit(msg.sender, address(this), value, deadline, v, r, s);
    //        (amount) = removeLiquiditySync(tokenA, tokenB, liquidity, amountMin, isAnchor, to, deadline);
    //    }
    //
    //    function removeLiquidityETHWithPermit(
    //        address token,
    //        uint liquidity,
    //        uint amountMin,
    //        bool isAnchor,
    //        bool shouldRemoveAnchor,
    //        address to,
    //        uint deadline,
    //        bool approveMax, uint8 v, bytes32 r, bytes32 s
    //    ) virtual override ensure(deadline) external returns (uint amount){
    //        address pylon = UniswapV2Library.pairFor(factory, token, WETH);
    //        uint value = approveMax ? uint(-1) : liquidity;
    //        IZirconPoolToken(shouldRemoveAnchor ? IZirconPylon(pylon).anchorPoolTokenAddress() : IZirconPylon(pylon).floatPoolTokenAddress())
    //        .permit(msg.sender, address(this), value, deadline, v, r, s);
    //        (amount) = removeLiquiditySyncETH(
    //            token,
    //            liquidity,
    //            amountMin,
    //            isAnchor,
    //            shouldRemoveAnchor,
    //            to,
    //            deadline);
    //    }
    //
    //    function removeLiquidityAsyncWithPermit(
    //        address token,
    //        uint liquidity,
    //        uint amountTokenMin,
    //        uint amountETHMin,
    //        bool isAnchor,
    //        bool shouldBurnAnchor,
    //        address to,
    //        uint deadline,
    //        bool approveMax, uint8 v, bytes32 r, bytes32 s
    //    ) virtual override ensure(deadline)  external returns (uint amountA, uint amountB){
    //        address tokenA = !isAnchor ? token : WETH;
    //        address tokenB = !isAnchor ?  WETH : token;
    //
    //        address pylon = _getPylon(tokenA, tokenB);
    //        uint value = approveMax ? uint(-1) : liquidity;
    //        IZirconPoolToken(shouldRemoveAnchor ? IZirconPylon(pylon).anchorPoolTokenAddress() : IZirconPylon(pylon).floatPoolTokenAddress())
    //        .permit(msg.sender, address(this), value, deadline, v, r, s);
    //        (amountA, amountB) = removeLiquidityAsyncETH(token, liquidity, amountAMin, amountBMin, isAnchor, to, deadline);
    //
    //    }

    //    function removeLiquidityAsyncETHWithPermit(
    //        address token,
    //        uint liquidity,
    //        uint amountTokenMin,
    //        uint amountETHMin,
    //    bool isAnchor,
    //        bool shouldBurnAnchor,
    //        address to,
    //        uint deadline,
    //        bool approveMax, uint8 v, bytes32 r, bytes32 s
    //    ) virtual override ensure(deadline) external returns (uint amountA, uint amountB){
    //        address pylon = _getPylon(tokenA, tokenB);
    //        uint value = approveMax ? uint(-1) : liquidity;
    //        IZirconPoolToken(shouldRemoveAnchor ? IZirconPylon(pylon).anchorPoolTokenAddress() : IZirconPylon(pylon).floatPoolToken())
    //        .permit(msg.sender, address(this), value, deadline, v, r, s);
    //        (amountA, amountB) = removeLiquidityAsync(token, liquidity, amountTokenMin, amountETHMin, isAnchor, shouldBurnAnchor, to, deadline);
    //
    //    }
}

File 2 of 14 : IZirconPylonRouter.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.2;

interface IZirconPylonRouter {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);
    function pylonFactory() external pure returns (address);
    function ptFactory() external pure returns (address);

    function init(
        address tokenA,
        address tokenB,
        uint amountDesiredA,
        uint amountDesiredB,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB);

    function initETH(
        address token,
        uint amountDesiredToken,
        bool isAnchor,
        address to,
        uint deadline
    ) external payable returns (uint amountA, uint amountB);

    function addSyncLiquidity(
        address tokenA,
        address tokenB,
        uint amountDesired,
        uint minLiquidity,
        bool isAnchor,
        address to,
        address farm,
        uint deadline
    ) external returns (uint amount, uint liquidity);

    function addSyncLiquidityETH(
        address token,
        bool isAnchor,
        uint minLiquidity,
        address to,
        address pool,
        uint deadline
    ) external payable returns (uint liquidity);

    //    function addAsyncLiquidity100(
    //        address tokenA,
    //        address tokenB,
    //        uint amountDesired,
    //        uint minLiquidity,
    //    bool isAnchor,
    //        address to,
    //        address pool,
    //        uint deadline
    //    ) external returns (uint liquidity);
    //
    //    function addAsyncLiquidity100ETH(
    //        address token,
    //        bool isAnchor,
    //        uint minLiquidity,
    //
    //    address to,
    //        address pool,
    //        uint deadline
    //    ) external payable returns (uint liquidity);

    function addAsyncLiquidity(
        address tokenA,
        address tokenB,
        uint amountA,
        uint amountB,
        uint minLiquidity,
        bool isAnchor,
        address to,
        address farm,
        uint deadline
    ) external returns (uint liquidity);

    function addAsyncLiquidityETH(
        address token,
        uint amountDesiredToken,
        uint minLiquidity,
        bool isAnchor,
        bool shouldReceiveAnchor,
        address to,
        address farm,
        uint deadline
    ) external payable returns (uint amountA, uint amountB, uint liquidity);

    function removeLiquiditySync(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountMin,
        bool shouldReceiveAnchor,
        address to,
        uint deadline
    ) external returns (uint amount);
    function removeLiquiditySyncETH(
        address token,
        uint liquidity,
        uint amountMin,
        bool isAnchor,
        bool shouldRemoveAnchor,
        address to,
        uint deadline
    ) external returns (uint amount);
    function removeLiquidityAsync(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        bool isAnchor,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityAsyncETH(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        bool isAnchor,
        bool shouldBurnAnchor,
        address to,
        uint deadline
    ) external returns (uint amountToken, uint amountETH);
    //    function removeLiquidityWithPermit(
    //        address tokenA,
    //        address tokenB,
    //        uint liquidity,
    //        uint amountAMin,
    //        uint amountBMin,
    //        address to,
    //        uint deadline,
    //        bool approveMax, uint8 v, bytes32 r, bytes32 s
    //    ) external returns (uint amountA, uint amountB);
    //    function removeLiquidityETHWithPermit(
    //        address token,
    //        uint liquidity,
    //        uint amountTokenMin,
    //        uint amountETHMin,
    //        address to,
    //        uint deadline,
    //        bool approveMax, uint8 v, bytes32 r, bytes32 s
    //    ) external returns (uint amountToken, uint amountETH);
}

File 3 of 14 : IZirconPair.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.5.16;

interface IZirconPair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function energyRevenueAddress() external pure returns (address);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    //again only for test
    function mintTest(address to, uint amount) external;

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function burnOneSide(address to, bool isReserve0) external returns (uint amount);
    function mintOneSide(address to, bool isReserve0) external returns (uint liquidity, uint amount0, uint amount1);
    function publicMintFee() external;
    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
//    function skim(address to) external;
    function sync() external;

    function tryLock() external;

    function initialize(address, address, address) external;
    function changeEnergyRevAddress(address _revAddress) external;

}

File 4 of 14 : IZirconPylonFactory.sol
pragma solidity >=0.5.16;

interface IZirconPylonFactory {
    function maximumPercentageSync() external view returns (uint);

    function deltaGammaThreshold() external view returns (uint);
    function deltaGammaMinFee() external view returns (uint);
    function muUpdatePeriod() external view returns (uint);
    function muChangeFactor() external view returns (uint);
//    function liquidityFee() external view returns (uint);
    function EMASamples() external view returns (uint);
    function oracleUpdateSecs() external view returns (uint);

    function allPylons(uint p) external view returns (address);
    function getPylon(address tokenA, address tokenB) external view returns (address pair);
    function factory() external view returns (address);
    function energyFactory() external view returns (address);
    event PylonCreated(address indexed token0, address indexed token1, address poolToken0, address poolToken1, address pylon, address pair);
    function allPylonsLength() external view returns (uint);
    function paused() external view returns (bool);
    // function setLiquidityFee(uint _liquidityFee) external;
    // Adding Pylon
    // First Token is always the Float and the second one is the Anchor
    function addPylon(address _pairAddress, address _tokenA, address _tokenB) external returns (address pylonAddress);
    function addPylonCustomPT(address _pairAddress, address _tokenA, address _tokenB, address floatPTAddress, address anchorPTAddress) external returns (address pylonAddress);
    function setMigrator(address _migrator) external;
    function setFeeToSetter(address _feeToSetter) external;
    function setFees(uint _maximumPercentageSync, uint _deltaGammaThreshold, uint _deltaGammaMinFee, uint _muUpdatePeriod, uint _muChangeFactor, uint _EMASamples, uint _oracleUpdate) external;
    function setPaused(bool _paused) external;

    function changeEnergyAddress(address _newEnergyRev, address _pylonAddress, address _pairAddress, address _tokenA, address _tokenB) external returns (address energy);
    function migrateLiquidity(address _oldPylon, address _newPylon) external;
    function startPylon(address _pylon, uint _gamma, uint _vab, bool _formulaSwitch) external;
    function changeEnergyFactoryAddress(address _newEnergyFactory) external;

}

File 5 of 14 : IZirconFactory.sol
pragma solidity >=0.5.16;

interface IZirconFactory {
    //    function feeTo() external view returns (address);
    //    function feeToSetter() external view returns (address);
    //    function migrator() external view returns (address);
    function energyFactory() external view returns (address);

    function getPair(address, address) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);
    function dynamicRatio() external view returns (uint);
    function liquidityFee() external view returns (uint);
    function setLiquidityFee(uint _liquidityFee) external;

    function pairCodeHash() external pure returns (bytes32);
    function createPair(address tokenA, address tokenB, address _pylonFactory) external returns (address pair);

    function setMigrator(address _migrator) external;
    function setFeeToSetter(address _feeToSetter) external;
    function changeEnergyRevAddress(address _pairAddress, address _tokenA, address _tokenB, address _pylonFactory) external returns (address newEnergy);

    function changeEnergyFactoryAddress(address _newEnergyFactory) external;
    function setDynamicRatio(uint _dynamicRatio) external;

}

File 6 of 14 : IZirconPoolToken.sol
pragma solidity >=0.5.16;

interface IZirconPoolToken {
    function factory() external view returns (address);
    function isAnchor() external view returns (bool);
    function token() external view returns (address);
    function pair() external view returns (address);
    function pylonFactory() external view returns (address);
    function pylon() external view returns (address);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);

    function mint(address account, uint256 amount) external;
    function burn(address account, uint256 amount) external;
    function initialize(address _token0, address _pair, address _pylon, bool _isAnchor) external;
    function transferFrom(address from, address to, uint value) external returns (bool);
}

File 7 of 14 : IZirconPTFactory.sol
pragma solidity >=0.5.16;

interface IZirconPTFactory {
    function getPoolToken(address pylon, address token) external view returns (address pt);
    function createPTAddress(address _token, address pylonAddress) external returns (address poolToken);
    function changePylonAddress(address oldPylon, address tokenA, address tokenB, address newPylon, address pylonFactory) external;
    function setMigrator(address _migrator) external;
    function setFeeToSetter(address _feeToSetter) external;
}

File 8 of 14 : ZirconPeripheralLibrary.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.6;

import "./SafeMath.sol";
import "@zircon/core/contracts/interfaces/IZirconPylon.sol";

library ZirconPeripheralLibrary {
    using SafeMath for uint256;
    // calculates the CREATE2 address for a pair without making any external calls
    //TODO: Update init code hash with Zircon Pylon code hash


    // DO NOT CHANGE THIS FUNCTION WILL BE UPDATED BY 'yarn bytecode' inside zircon-core
    function pylonFor(address pylonFactory, address tokenA, address tokenB, address pair) pure internal returns (address pylon){pylon=address(uint(keccak256(abi.encodePacked(hex'ff',pylonFactory,keccak256(abi.encodePacked(tokenA, tokenB,pair)),hex'bdcd981759969595cbaa18dbe5182f383ceab96981adab30631555fdec2ba5ad'))));}


    function isInitialized(address factory, address tokenA, address tokenB, address pair) view internal returns (bool initialized){
        initialized = IZirconPylon(pylonFor(factory, tokenA, tokenB, pair)).initialized() == 1;
    }

    function translate(uint toConvert, uint ptt, uint ptb) pure public  returns (uint amount){
        amount =  (ptt == 0 || ptb == 0) ? toConvert : toConvert.mul(ptb)/ptt;
    }

    // fetches and gets Reserves
    function getSyncReserves(address factory, address tokenA, address tokenB, address pair) internal view returns (uint112 reserveF, uint112 reserveA) {
        (reserveF, reserveA) = IZirconPylon(pylonFor(factory, tokenA, tokenB, pair)).getSyncReserves();
    }


    // fetches and sorts the reserves for a pair
    function maximumSync(uint reserve, uint reservePylon, uint syncPercentage, uint maxBase, uint ptt, uint ptb) internal pure returns (uint maximum) {
        uint pairReserveTranslated = translate(reserve, ptt, ptb);
        maximum = (pairReserveTranslated == 0 || reservePylon > pairReserveTranslated) ? maxBase :
        (pairReserveTranslated.mul(syncPercentage)/100).sub(reservePylon);
    }

}

File 9 of 14 : UniswapV2Library.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0;

import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol';
//import "hardhat/console.sol";

import "./SafeMath.sol";

library UniswapV2Library {
    using SafeMath for uint;

    // returns sorted token addresses, used to handle return values from pairs sorted in this order
    function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
        require(tokenA != tokenB, 'UniswapV2Library: IDENTICAL_ADDRESSES');
        (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
        require(token0 != address(0), 'UniswapV2Library: ZERO_ADDRESS');
    }

    // calculates the CREATE2 address for a pair without making any external calls
    // DO NOT CHANGE THIS FUNCTION WILL BE UPDATED BY 'yarn bytecode' inside zircon-core
    function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) {(address token0, address token1) = sortTokens(tokenA, tokenB); pair = address(uint(keccak256(abi.encodePacked(hex'ff', factory, keccak256(abi.encodePacked(token0, token1)), hex'0ec3a964af2d4288dcee11cf85135843bcfc1e8e4f8a107d634a0818cc792ee7'))));}

    // fetches and sorts the reserves for a pair
    function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) {
        (address token0,) = sortTokens(tokenA, tokenB);
        (uint reserve0, uint reserve1,) = IUniswapV2Pair(pairFor(factory, tokenA, tokenB)).getReserves();
        (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
    }

    // given some amount of an asset and pair reserves, returns an equivalent amount of the other asset
    function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) {
        require(amountA > 0, 'UniswapV2Library: INSUFFICIENT_AMOUNT');
        require(reserveA > 0 && reserveB > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
        amountB = amountA.mul(reserveB) / reserveA;
    }

    // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) {
        require(amountIn > 0, 'UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT');
        require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
        uint amountInWithFee = amountIn.mul(997);
        uint numerator = amountInWithFee.mul(reserveOut);
        uint denominator = reserveIn.mul(1000).add(amountInWithFee);
        amountOut = numerator / denominator;
    }

    // given an output amount of an asset and pair reserves, returns a required input amount of the other asset
    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) {
        require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT');
        require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
        uint numerator = reserveIn.mul(amountOut).mul(1000);
        uint denominator = reserveOut.sub(amountOut).mul(997);
        amountIn = (numerator / denominator).add(1);
    }

    // performs chained getAmountOut calculations on any number of pairs
    function getAmountsOut(address factory, uint amountIn, address[] memory path) internal view returns (uint[] memory amounts) {
        require(path.length >= 2, 'UniswapV2Library: INVALID_PATH');
        amounts = new uint[](path.length);
        amounts[0] = amountIn;
        for (uint i; i < path.length - 1; i++) {
            (uint reserveIn, uint reserveOut) = getReserves(factory, path[i], path[i + 1]);
            amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut);
        }
    }

    // performs chained getAmountIn calculations on any number of pairs
    function getAmountsIn(address factory, uint amountOut, address[] memory path) internal view returns (uint[] memory amounts) {
        require(path.length >= 2, 'UniswapV2Library: INVALID_PATH');
        amounts = new uint[](path.length);
        amounts[amounts.length - 1] = amountOut;
        for (uint i = path.length - 1; i > 0; i--) {
            (uint reserveIn, uint reserveOut) = getReserves(factory, path[i - 1], path[i]);
            amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut);
        }
    }
}

File 10 of 14 : TransferHelper.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.6.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');
    }
}

File 11 of 14 : IWETH.sol
pragma solidity >=0.5.0;

interface IWETH {
    function deposit() external payable;
    function transfer(address to, uint value) external returns (bool);
    function withdraw(uint) external;
}

File 12 of 14 : SafeMath.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity =0.6.6;

// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)

library SafeMath {
    function add(uint x, uint y) internal pure returns (uint z) {
        require((z = x + y) >= x, 'ds-math-add-overflow');
    }

    function sub(uint x, uint y) internal pure returns (uint z) {
        require((z = x - y) <= x, 'ds-math-sub-underflow');
    }

    function mul(uint x, uint y) internal pure returns (uint z) {
        require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow');
    }
}

File 13 of 14 : IZirconPylon.sol
pragma solidity >=0.5.16;
interface IZirconPylon {
    function initialized() external view returns (uint);
//    function anchorPoolTokenAddress() external view returns (address);
//    function floatPoolTokenAddress() external view returns (address);
//    function energyAddress() external view returns (address);
    function gammaMulDecimals() external view returns (uint);
    function isFloatReserve0() external view returns (bool);
    function virtualAnchorBalance() external view returns (uint);
    function virtualFloatBalance() external view returns (uint);
    function p2x() external view returns (uint);
    function p2y() external view returns (uint);
    function lastRootKTranslated() external view returns (uint);
    function formulaSwitch() external view returns (bool);
    function lastPrice() external view returns (uint);
    function EMABlockNumber() external view returns (bool);
    function getSyncReserves() external view returns  (uint112 _reserve0, uint112 _reserve1);
    // Called once by the factory at time of deployment
    // @_floatPoolToken -> Contains Address Of Float PT
    // @_anchorPoolToken -> Contains Address Of Anchor PT
    // @token0 -> Float token
    // @token1 -> Anchor token
    function initMigratedPylon(uint _gamma, uint _vab, bool _formulaSwitch) external;
    function initialize(address _floatPoolTokenAddress, address _anchorPoolTokenAddress, address _floatToken, address _anchorToken, address _pairAddress, address _pairFactoryAddress, address _energy, address _energyRev) external;
    // On init pylon we have to handle two cases
    // The first case is when we initialize the pair through the pylon
    // And the second one is when initialize the pylon with a pair al ready existing
    function initPylon(address _to) external returns (uint floatLiquidity, uint anchorLiquidity);
    // External Function called to mint pool Token
    // Liquidity have to be sent before
    function mintPoolTokens(address to, bool isAnchor) external returns (uint liquidity);
//    function mintAsync100(address to, bool isAnchor) external returns (uint liquidity);
    function mintAsync(address to, bool shouldMintAnchor) external returns (uint liquidity);
    // Burn Async send both tokens 50-50
    // Liquidity has to be sent before
    function burnAsync(address _to, bool _isAnchor) external returns (uint amount0, uint amount1);
    // Burn send liquidity back to user burning Pool tokens
    // The function first uses the reserves of the Pylon
    // If not enough reserves it burns The Pool Tokens of the pylon
    function burn(address _to, bool _isAnchor) external returns (uint amount);
    function changeEnergyAddress(address _energyAddress, address _energyRevAddress) external;
    function migrateLiquidity(address newPylon) external;

    }

File 14 of 14 : IUniswapV2Pair.sol
pragma solidity >=0.5.0;

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_pylonFactory","type":"address"},{"internalType":"address","name":"_ptFactory","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"minLiquidity","type":"uint256"},{"internalType":"bool","name":"isAnchor","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"farm","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addAsyncLiquidity","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountDesiredToken","type":"uint256"},{"internalType":"uint256","name":"minLiquidity","type":"uint256"},{"internalType":"bool","name":"isAnchor","type":"bool"},{"internalType":"bool","name":"shouldReceiveAnchor","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"farm","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addAsyncLiquidityETH","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountDesired","type":"uint256"},{"internalType":"uint256","name":"minLiquidity","type":"uint256"},{"internalType":"bool","name":"isAnchor","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"farm","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addSyncLiquidity","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"isAnchor","type":"bool"},{"internalType":"uint256","name":"minLiquidity","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"farm","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addSyncLiquidityETH","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountDesiredA","type":"uint256"},{"internalType":"uint256","name":"amountDesiredB","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"init","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountDesiredToken","type":"uint256"},{"internalType":"bool","name":"isAnchor","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"initETH","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"ptFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pylonFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"bool","name":"isAnchor","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityAsync","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"bool","name":"isAnchor","type":"bool"},{"internalType":"bool","name":"shouldBurnAnchor","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityAsyncETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountMin","type":"uint256"},{"internalType":"bool","name":"shouldReceiveAnchor","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquiditySync","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountMin","type":"uint256"},{"internalType":"bool","name":"isAnchor","type":"bool"},{"internalType":"bool","name":"shouldRemoveAnchor","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquiditySyncETH","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

61010060405234801561001157600080fd5b506040516137453803806137458339818101604052608081101561003457600080fd5b508051602082015160408301516060938401516001600160601b031993851b8416608052841b831660e05290831b821660a05290911b1660c05260805160601c60a05160601c60c05160601c60e05160601c6135de6101676000398060f15280610875528061089c52806108e4528061090b528061095252806109d25280610c615280610c8c5280610cef5280610d8652806116e75280611712528061175452806117eb52806119685280611c7e5280611cb25280611d2a5280611e205280611e4b5280611ece5250806105d45280610e8a5280611016525080611f565280611f7f528061262f52806126fd52806127cd52806129985280612a6b5280612c375280612d0a52508061198c5280611fa55280612524528061265952806128545280612af35280612d8a52506135de6000f3fe6080604052600436106100e15760003560e01c80638a96e2471161007f578063cdccaca011610059578063cdccaca014610428578063ed1d080f14610497578063ef68f27f146104fb578063ef8863b41461055a5761011a565b80638a96e247146103b4578063ad5c4648146103fe578063c45a0155146104135761011a565b80632b34f135116100bb5780632b34f1351461026457806359b11df71461029557806359b9a98b146102ea578063769635bd1461034e5761011a565b8063119438711461011f5780631e3990bd14610190578063230e9bca146102075761011a565b3661011a57336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461011857fe5b005b600080fd5b34801561012b57600080fd5b5061017e600480360360e081101561014257600080fd5b506001600160a01b0381358116916020810135821691604082013591606081013591608082013515159160a08101359091169060c0013561056f565b60408051918252519081900360200190f35b6101e960048036036101008110156101a757600080fd5b506001600160a01b0381358116916020810135916040820135916060810135151591608082013515159160a081013582169160c0820135169060e0013561080a565b60408051938452602084019290925282820152519081900360600190f35b61024b600480360360a081101561021d57600080fd5b506001600160a01b038135811691602081013591604082013515159160608101359091169060800135610bfe565b6040805192835260208301919091528051918290030190f35b34801561027057600080fd5b50610279610e88565b604080516001600160a01b039092168252519081900360200190f35b3480156102a157600080fd5b5061024b600480360360c08110156102b857600080fd5b506001600160a01b03813581169160208101358216916040820135916060810135916080820135169060a00135610eac565b3480156102f657600080fd5b5061024b600480360361010081101561030e57600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a081013515159160c0820135169060e00135610fb0565b34801561035a57600080fd5b5061024b600480360361010081101561037257600080fd5b506001600160a01b0381358116916020810135821691604082013591606081013591608082013515159160a081013582169160c0820135169060e001356114aa565b61017e600480360360c08110156103ca57600080fd5b506001600160a01b038135811691602081013515159160408201359160608101358216916080820135169060a00135611630565b34801561040a57600080fd5b50610279611966565b34801561041f57600080fd5b5061027961198a565b34801561043457600080fd5b5061017e600480360361012081101561044c57600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a081013515159160c082013581169160e08101359091169061010001356119ae565b3480156104a357600080fd5b5061024b60048036036101008110156104bb57600080fd5b506001600160a01b038135811691602081013591604082013591606081013591608082013515159160a081013515159160c0820135169060e00135611c1c565b34801561050757600080fd5b5061017e600480360360e081101561051e57600080fd5b506001600160a01b0381358116916020810135916040820135916060810135151591608082013515159160a08101359091169060c00135611dbe565b34801561056657600080fd5b50610279611f54565b600081428110156105c2576040805162461bcd60e51b8152602060048201526018602482015277155b9a5cddd85c158c949bdd5d195c8e881156141254915160421b604482015290519081900360640190fd5b60006105ce8a8a611f78565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663fad51a9a838961060d578d61060f565b8c5b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b15801561066e57600080fd5b505afa158015610682573d6000803e3d6000fd5b505050506040513d602081101561069857600080fd5b5051604080516323b872dd60e01b81523360048201526001600160a01b038581166024830152604482018d90529151929350908316916323b872dd916064808201926020929091908290030181600087803b1580156106f657600080fd5b505af115801561070a573d6000803e3d6000fd5b505050506040513d602081101561072057600080fd5b5050604080517fba7b3dea0000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152891515602483015291519184169163ba7b3dea916044808201926020929091908290030181600087803b15801561078f57600080fd5b505af11580156107a3573d6000803e3d6000fd5b505050506040513d60208110156107b957600080fd5b50519350878410156107fc5760405162461bcd60e51b815260040180806020018281038252602481526020018061350b6024913960400191505060405180910390fd5b505050979650505050505050565b60008060008342811015610860576040805162461bcd60e51b8152602060048201526018602482015277155b9a5cddd85c158c949bdd5d195c8e881156141254915160421b604482015290519081900360640190fd5b8b896108c78d3483806108735785610895565b7f00000000000000000000000000000000000000000000000000000000000000005b856108c0577f00000000000000000000000000000000000000000000000000000000000000006108c2565b865b611fd7565b90965094508d91508a90506000610936826108e25783610904565b7f00000000000000000000000000000000000000000000000000000000000000005b8361092f577f0000000000000000000000000000000000000000000000000000000000000000610931565b845b611f78565b905061095083338385610949578a61094b565b895b61201a565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db08361098a578761098c565b885b6040518263ffffffff1660e01b81526004016000604051808303818588803b1580156109b757600080fd5b505af11580156109cb573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb8284610a0b5788610a0d565b895b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015610a5c57600080fd5b505af1158015610a70573d6000803e3d6000fd5b505050506040513d6020811015610a8657600080fd5b5051610a8e57fe5b604080516319e6ef2760e11b81526001600160a01b038c811660048301528d151560248301529151918316916333cdde4e916044808201926020929091908290030181600087803b158015610ae257600080fd5b505af1158015610af6573d6000803e3d6000fd5b505050506040513d6020811015610b0c57600080fd5b505194508c851015610b1d86612177565b90610ba65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b6b578181015183820152602001610b53565b50505050905090810190601f168015610b985780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5050505088610bb55782610bb7565b835b341115610bd657610bd6338a610bcd5784610bcf565b855b340361228f565b6001600160a01b03861615610bef57610bef8683612387565b50985098509895505050505050565b6000808242811015610c52576040805162461bcd60e51b8152602060048201526018602482015277155b9a5cddd85c158c949bdd5d195c8e881156141254915160421b604482015290519081900360640190fd5b600086610c5f5788610c81565b7f00000000000000000000000000000000000000000000000000000000000000005b9050600087610cb0577f0000000000000000000000000000000000000000000000000000000000000000610cb2565b895b90506000610cc0838361251f565b91505088610cce5789610cd0565b345b955088610cdd5734610cdf565b895b9450610ced8b33838d61201a565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610d4857600080fd5b505af1158015610d5c573d6000803e3d6000fd5b50506040805163a9059cbb60e01b81526001600160a01b03868116600483015234602483015291517f0000000000000000000000000000000000000000000000000000000000000000909216945063a9059cbb935060448082019350602092918290030181600087803b158015610dd257600080fd5b505af1158015610de6573d6000803e3d6000fd5b505050506040513d6020811015610dfc57600080fd5b5051610e0457fe5b60408051633ca5007160e21b81526001600160a01b038a8116600483015282519084169263f29401c492602480820193918290030181600087803b158015610e4b57600080fd5b505af1158015610e5f573d6000803e3d6000fd5b505050506040513d6040811015610e7557600080fd5b50959b949a509398505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000808242811015610f00576040805162461bcd60e51b8152602060048201526018602482015277155b9a5cddd85c158c949bdd5d195c8e881156141254915160421b604482015290519081900360640190fd5b6000610f0c8a8a61251f565b915050879350869250610f218a33838761201a565b610f2d8933838661201a565b60408051633ca5007160e21b81526001600160a01b03888116600483015282519084169263f29401c492602480820193918290030181600087803b158015610f7457600080fd5b505af1158015610f88573d6000803e3d6000fd5b505050506040513d6040811015610f9e57600080fd5b50939a92995091975050505050505050565b6000808242811015611004576040805162461bcd60e51b8152602060048201526018602482015277155b9a5cddd85c158c949bdd5d195c8e881156141254915160421b604482015290519081900360640190fd5b60006110108c8c611f78565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663fad51a9a838a61104f578f611051565b8e5b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b1580156110b057600080fd5b505afa1580156110c4573d6000803e3d6000fd5b505050506040513d60208110156110da57600080fd5b5051604080516323b872dd60e01b81523360048201526001600160a01b038581166024830152604482018f90529151929350908316916323b872dd916064808201926020929091908290030181600087803b15801561113857600080fd5b505af115801561114c573d6000803e3d6000fd5b505050506040513d602081101561116257600080fd5b5050604080517fc561cf4f0000000000000000000000000000000000000000000000000000000081526001600160a01b0389811660048301528a1515602483015282519085169263c561cf4f92604480820193918290030181600087803b1580156111cc57600080fd5b505af11580156111e0573d6000803e3d6000fd5b505050506040513d60408110156111f657600080fd5b50805160209091015190955093508985101561121186612177565b61121a8c612177565b60405160200180807f415f414d4f554e543a2000000000000000000000000000000000000000000000815250600a0183805190602001908083835b602083106112745780518252601f199092019160209182019101611255565b6001836020036101000a03801982511681845116808217855250505050505090500180600160fd1b81525060010182805190602001908083835b602083106112cd5780518252601f1990920191602091820191016112ae565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529061134e5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b6b578181015183820152602001610b53565b508884101561135c85612177565b6113658b612177565b60405160200180807f425f414d4f554e543a2000000000000000000000000000000000000000000000815250600a0183805190602001908083835b602083106113bf5780518252601f1990920191602091820191016113a0565b6001836020036101000a03801982511681845116808217855250505050505090500180600160fd1b81525060010182805190602001908083835b602083106114185780518252601f1990920191602091820191016113f9565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052906114995760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b6b578181015183820152602001610b53565b505050509850989650505050505050565b60008082428110156114fe576040805162461bcd60e51b8152602060048201526018602482015277155b9a5cddd85c158c949bdd5d195c8e881156141254915160421b604482015290519081900360640190fd5b6115088b8b61284e565b88925060006115178c8c611f78565b905061153188611527578c611529565b8b5b33838761201a565b604080516346a3871160e11b81526001600160a01b0389811660048301528a15156024830152915191831691638d470e22916044808201926020929091908290030181600087803b15801561158557600080fd5b505af1158015611599573d6000803e3d6000fd5b505050506040513d60208110156115af57600080fd5b5051925088831015611608576040805162461bcd60e51b815260206004820152601960248201527f5a50523a204e6f7420656e6f756768206c697175696469747900000000000000604482015290519081900360640190fd5b6001600160a01b03861615611621576116218684612387565b50509850989650505050505050565b60008142811015611683576040805162461bcd60e51b8152602060048201526018602482015277155b9a5cddd85c158c949bdd5d195c8e881156141254915160421b604482015290519081900360640190fd5b600034116116d8576040805162461bcd60e51b815260206004820152600f60248201527f5a50523a205a45524f2d56414c55450000000000000000000000000000000000604482015290519081900360640190fd5b6000876116e55788611707565b7f00000000000000000000000000000000000000000000000000000000000000005b9050600088611736577f0000000000000000000000000000000000000000000000000000000000000000611738565b895b9050611744828261284e565b60006117508383611f78565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156117ad57600080fd5b505af11580156117c1573d6000803e3d6000fd5b50506040805163a9059cbb60e01b81526001600160a01b03868116600483015234602483015291517f0000000000000000000000000000000000000000000000000000000000000000909216945063a9059cbb935060448082019350602092918290030181600087803b15801561183757600080fd5b505af115801561184b573d6000803e3d6000fd5b505050506040513d602081101561186157600080fd5b505161186957fe5b604080516346a3871160e11b81526001600160a01b038a811660048301528c156024830152915191831691638d470e22916044808201926020929091908290030181600087803b1580156118bc57600080fd5b505af11580156118d0573d6000803e3d6000fd5b505050506040513d60208110156118e657600080fd5b505194508885101561193f576040805162461bcd60e51b815260206004820152601960248201527f5a50523a204e6f7420656e6f756768206c697175696469747900000000000000604482015290519081900360640190fd5b6001600160a01b03871615611958576119588786612387565b505050509695505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008142811015611a01576040805162461bcd60e51b8152602060048201526018602482015277155b9a5cddd85c158c949bdd5d195c8e881156141254915160421b604482015290519081900360640190fd5b600080611a108d8d8d8d612aea565b915091506000611a228e8e8585612e22565b604080516319e6ef2760e11b81526001600160a01b038b811660048301528c151560248301529151929350908316916333cdde4e916044808201926020929091908290030181600087803b158015611a7957600080fd5b505af1158015611a8d573d6000803e3d6000fd5b505050506040513d6020811015611aa357600080fd5b5051945089851015611ab486612177565b611abd8c612177565b60405160200180807f4d494e5f4c49515549444954593a200000000000000000000000000000000000815250600f0183805190602001908083835b60208310611b175780518252601f199092019160209182019101611af8565b6001836020036101000a03801982511681845116808217855250505050505090500180600160fd1b81525060010182805190602001908083835b60208310611b705780518252601f199092019160209182019101611b51565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405290611bf15760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b6b578181015183820152602001610b53565b506001600160a01b03871615611c0b57611c0b8786612387565b505050509998505050505050505050565b6000808242811015611c70576040805162461bcd60e51b8152602060048201526018602482015277155b9a5cddd85c158c949bdd5d195c8e881156141254915160421b604482015290519081900360640190fd5b600080611cf78915611ca2577f0000000000000000000000000000000000000000000000000000000000000000611ca4565b8d5b8a15611cb0578e611cd2565b7f00000000000000000000000000000000000000000000000000000000000000005b8e8c15611cdf578d611ce1565b8e5b8d15611ced578f611cef565b8e5b8d308d610fb0565b915091508815611d075780611d09565b815b94508815611d175781611d19565b805b93505050611d288b8685612e50565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611d8e57600080fd5b505af1158015611da2573d6000803e3d6000fd5b50505050611db0858361228f565b509850989650505050505050565b60008142811015611e11576040805162461bcd60e51b8152602060048201526018602482015277155b9a5cddd85c158c949bdd5d195c8e881156141254915160421b604482015290519081900360640190fd5b600086611e1e5789611e40565b7f00000000000000000000000000000000000000000000000000000000000000005b9050600087611e6f577f0000000000000000000000000000000000000000000000000000000000000000611e71565b8a5b9050611ea982828c8c8b8d8015611e8557508c5b80611e9757508c158015611e9757508d155b611ea15730611ea3565b8b5b8b61056f565b9350878015611eb6575086155b80611ec75750868015611ec7575087155b156107fc577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611f3257600080fd5b505af1158015611f46573d6000803e3d6000fd5b505050506107fc868561228f565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000611fd07f00000000000000000000000000000000000000000000000000000000000000008484611fcb7f00000000000000000000000000000000000000000000000000000000000000008888612f9d565b613075565b9392505050565b60008060008515611fe85786611fea565b875b905060008615611ffa5788611ffc565b875b905061200a86868484612aea565b909a909950975050505050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17815292518251600094606094938a169392918291908083835b6020831061209f5780518252601f199092019160209182019101612080565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612101576040519150601f19603f3d011682016040523d82523d6000602084013e612106565b606091505b5091509150818015612134575080511580612134575080806020019051602081101561213157600080fd5b50515b61216f5760405162461bcd60e51b81526004018080602001828103825260318152602001806134816031913960400191505060405180910390fd5b505050505050565b6060816121b8575060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015261228a565b8160005b81156121d057600101600a820491506121bc565b60608167ffffffffffffffff811180156121e957600080fd5b506040519080825280601f01601f191660200182016040528015612214576020820181803683370190505b509050815b851561228457600019016000600a8704600a028703603001905060008160f81b90508084848151811061224857fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a880497505050612219565b50925050505b919050565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b602083106122db5780518252601f1990920191602091820191016122bc565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d806000811461233d576040519150601f19603f3d011682016040523d82523d6000602084013e612342565b606091505b50509050806123825760405162461bcd60e51b81526004018080602001828103825260348152602001806134b26034913960400191505060405180910390fd5b505050565b604080518082018252601681527f726f757465724465706f7369742875696e74323536290000000000000000000060209182015281516024808201859052835180830390910181526044909101835290810180516001600160e01b03167f462293a300000000000000000000000000000000000000000000000000000000178152915181516000936060936001600160a01b038816939092909182918083835b602083106124465780518252601f199092019160209182019101612427565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146124a8576040519150601f19603f3d011682016040523d82523d6000602084013e6124ad565b606091505b509150915081612519578051156124c75780518082602001fd5b81612519576040805162461bcd60e51b815260206004820152600f60248201527f5a503a204641524d5f4641494c45440000000000000000000000000000000000604482015290519081900360640190fd5b50505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390585856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b1580156125b257600080fd5b505afa1580156125c6573d6000803e3d6000fd5b505050506040513d60208110156125dc57600080fd5b505191506001600160a01b0382166126d357604080517f76f797380000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015285811660248301527f00000000000000000000000000000000000000000000000000000000000000008116604483015291517f0000000000000000000000000000000000000000000000000000000000000000909216916376f79738916064808201926020929091908290030181600087803b1580156126a457600080fd5b505af11580156126b8573d6000803e3d6000fd5b505050506040513d60208110156126ce57600080fd5b505191505b60408051630e0f297360e01b81526001600160a01b038681166004830152858116602483015291517f000000000000000000000000000000000000000000000000000000000000000090921691630e0f297391604480820192602092909190829003018186803b15801561274657600080fd5b505afa15801561275a573d6000803e3d6000fd5b505050506040513d602081101561277057600080fd5b505190506001600160a01b03811661284757604080517f79281abe0000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301528681166024830152858116604483015291517f0000000000000000000000000000000000000000000000000000000000000000909216916379281abe916064808201926020929091908290030181600087803b15801561281857600080fd5b505af115801561282c573d6000803e3d6000fd5b505050506040513d602081101561284257600080fd5b505190505b9250929050565b818160007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390584846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b1580156128e257600080fd5b505afa1580156128f6573d6000803e3d6000fd5b505050506040513d602081101561290c57600080fd5b505190506001600160a01b03811661296b576040805162461bcd60e51b815260206004820152601560248201527f5a50523a2050616972204e6f7420437265617465640000000000000000000000604482015290519081900360640190fd5b60408051630e0f297360e01b81526001600160a01b038581166004830152848116602483015291516000927f00000000000000000000000000000000000000000000000000000000000000001691630e0f2973916044808301926020929190829003018186803b1580156129de57600080fd5b505afa1580156129f2573d6000803e3d6000fd5b505050506040513d6020811015612a0857600080fd5b50516001600160a01b03161415612a66576040805162461bcd60e51b815260206004820152601660248201527f5a50523a2050796c6f6e206e6f74206372656174656400000000000000000000604482015290519081900360640190fd5b612a927f000000000000000000000000000000000000000000000000000000000000000084848461313f565b612ae3576040805162461bcd60e51b815260206004820152601a60248201527f5a50523a2050796c6f6e204e6f7420496e697469616c697a6564000000000000604482015290519081900360640190fd5b5050505050565b600080858560007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390584846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b158015612b8157600080fd5b505afa158015612b95573d6000803e3d6000fd5b505050506040513d6020811015612bab57600080fd5b505190506001600160a01b038116612c0a576040805162461bcd60e51b815260206004820152601560248201527f5a50523a2050616972204e6f7420437265617465640000000000000000000000604482015290519081900360640190fd5b60408051630e0f297360e01b81526001600160a01b038581166004830152848116602483015291516000927f00000000000000000000000000000000000000000000000000000000000000001691630e0f2973916044808301926020929190829003018186803b158015612c7d57600080fd5b505afa158015612c91573d6000803e3d6000fd5b505050506040513d6020811015612ca757600080fd5b50516001600160a01b03161415612d05576040805162461bcd60e51b815260206004820152601660248201527f5a50523a2050796c6f6e206e6f74206372656174656400000000000000000000604482015290519081900360640190fd5b612d317f000000000000000000000000000000000000000000000000000000000000000084848461313f565b612d82576040805162461bcd60e51b815260206004820152601a60248201527f5a50523a2050796c6f6e204e6f7420496e697469616c697a6564000000000000604482015290519081900360640190fd5b600080612db07f00000000000000000000000000000000000000000000000000000000000000008c8c6131bd565b91509150816000148015612dc2575080155b15612dd257889650879550612e14565b6000612ddf8a848461328b565b9050888111612df357899750955085612e12565b6000612e008a848661328b565b90508a811115612e0c57fe5b97508896505b505b505050505094509492505050565b6000612e2e8585611f78565b9050612e3c8533838661201a565b612e488433838561201a565b949350505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b178152925182516000946060949389169392918291908083835b60208310612ecd5780518252601f199092019160209182019101612eae565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612f2f576040519150601f19603f3d011682016040523d82523d6000602084013e612f34565b606091505b5091509150818015612f62575080511580612f625750808060200190516020811015612f5f57600080fd5b50515b612ae35760405162461bcd60e51b815260040180806020018281038252602d81526020018061357c602d913960400191505060405180910390fd5b6000806000612fac8585613337565b604080516bffffffffffffffffffffffff19606094851b811660208084019190915293851b81166034830152825160288184030181526048830184528051908501207fff0000000000000000000000000000000000000000000000000000000000000060688401529a90941b9093166069840152607d8301989098527f0ec3a964af2d4288dcee11cf85135843bcfc1e8e4f8a107d634a0818cc792ee7609d808401919091528851808403909101815260bd909201909752805196019590952095945050505050565b604080516bffffffffffffffffffffffff19606095861b811660208084019190915294861b8116603483015292851b831660488201528151603c818303018152605c820183528051908501207fff00000000000000000000000000000000000000000000000000000000000000607c8301529590941b909116607d84015260918301939093527fbdcd981759969595cbaa18dbe5182f383ceab96981adab30631555fdec2ba5ad60b1808401919091528351808403909101815260d1909201909252805191012090565b600061314d85858585613075565b6001600160a01b031663158ef93e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561318557600080fd5b505afa158015613199573d6000803e3d6000fd5b505050506040513d60208110156131af57600080fd5b505160011495945050505050565b60008060006131cc8585613337565b5090506000806131dd888888612f9d565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561321557600080fd5b505afa158015613229573d6000803e3d6000fd5b505050506040513d606081101561323f57600080fd5b5080516020909101516dffffffffffffffffffffffffffff91821693501690506001600160a01b038781169084161461327957808261327c565b81815b90999098509650505050505050565b60008084116132cb5760405162461bcd60e51b81526004018080602001828103825260258152602001806135576025913960400191505060405180910390fd5b6000831180156132db5750600082115b6133165760405162461bcd60e51b815260040180806020018281038252602881526020018061352f6028913960400191505060405180910390fd5b82613327858463ffffffff61340e16565b8161332e57fe5b04949350505050565b600080826001600160a01b0316846001600160a01b0316141561338b5760405162461bcd60e51b81526004018080602001828103825260258152602001806134e66025913960400191505060405180910390fd5b826001600160a01b0316846001600160a01b0316106133ab5782846133ae565b83835b90925090506001600160a01b038216612847576040805162461bcd60e51b815260206004820152601e60248201527f556e697377617056324c6962726172793a205a45524f5f414444524553530000604482015290519081900360640190fd5b60008115806134295750508082028282828161342657fe5b04145b61347a576040805162461bcd60e51b815260206004820152601460248201527f64732d6d6174682d6d756c2d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b9291505056fe5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a207472616e7366657246726f6d206661696c65645472616e7366657248656c7065723a3a736166655472616e736665724554483a20455448207472616e73666572206661696c6564556e697377617056324c6962726172793a204944454e544943414c5f414444524553534553556e69737761705632526f757465723a20494e53554646494349454e545f414d4f554e54556e697377617056324c6962726172793a20494e53554646494349454e545f4c4951554944495459556e697377617056324c6962726172793a20494e53554646494349454e545f414d4f554e545472616e7366657248656c7065723a3a736166655472616e736665723a207472616e73666572206661696c6564a2646970667358221220cb3d1f7c79955a4e6841c84d1d297256b1f1af7cd0f8f0c28932f0b6af1af0fe64736f6c634300060600330000000000000000000000006b6071ccc534fcee7b699aab87929faf8806d5bd00000000000000000000000009f8e0aea93bcb511276a166e6e57e02e5cc1e0a0000000000000000000000002d4ddeb8b183413e9d88a98fa3dd844e34d41c5400000000000000000000000098878b06940ae243284ca214f92bb71a2b032b8a

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000006b6071ccc534fcee7b699aab87929faf8806d5bd00000000000000000000000009f8e0aea93bcb511276a166e6e57e02e5cc1e0a0000000000000000000000002d4ddeb8b183413e9d88a98fa3dd844e34d41c5400000000000000000000000098878b06940ae243284ca214f92bb71a2b032b8a

-----Decoded View---------------
Arg [0] : _factory (address): 0x6b6071ccc534fcee7b699aab87929faf8806d5bd
Arg [1] : _pylonFactory (address): 0x09f8e0aea93bcb511276a166e6e57e02e5cc1e0a
Arg [2] : _ptFactory (address): 0x2d4ddeb8b183413e9d88a98fa3dd844e34d41c54
Arg [3] : _WETH (address): 0x98878b06940ae243284ca214f92bb71a2b032b8a

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000006b6071ccc534fcee7b699aab87929faf8806d5bd
Arg [1] : 00000000000000000000000009f8e0aea93bcb511276a166e6e57e02e5cc1e0a
Arg [2] : 0000000000000000000000002d4ddeb8b183413e9d88a98fa3dd844e34d41c54
Arg [3] : 00000000000000000000000098878b06940ae243284ca214f92bb71a2b032b8a


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.