Contract 0x31CE064C35E03F0BC9d746835E25A98d944a24D3

 
Txn Hash
Method
Block
From
To
Value
0xe68d8286a5360d80724517be46af7468828185e1fc4355677346e369d520d06eWithdraw WEI138627332021-12-23 17:22:35228 days 13 hrs ago0xea7a13b6f118f530f6ad08f05225a0a05818b1a9 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00359366 99.40974237
0xf013d2f89462aa759decfc87ea8d54fb1cbebb4e88b953e3b00519a19ce4bf19Repayv SPACEX138627332021-12-23 17:22:35228 days 13 hrs ago0xea7a13b6f118f530f6ad08f05225a0a05818b1a9 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00468955 99.40974237
0xd5127d7b91887a1d0342ea0183f345be761fcde010ae42ecbccfb9e1d99b5d65Lendv SPACEX138626112021-12-23 16:51:49228 days 14 hrs ago0xe610c34f333c2ec6a003170880f3fe7a3724c8e9 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00691847 88.40146927
0xc7a6b46214d490082a33d3875128309cf2eef600c8a8ca55e9826c5da4c25572Deposit WEI138625932021-12-23 16:47:05228 days 14 hrs ago0xe610c34f333c2ec6a003170880f3fe7a3724c8e9 IN  ItoVault: vSPACEX Factory Contract1.39 Ether0.00245004 85.17438557
0xc4b3f191f6c9f677b434d57227cdc0c0e9035f9353b36c72bcedb61eca0dbd86Deposit WEI138619382021-12-23 14:20:07228 days 16 hrs ago0xe610c34f333c2ec6a003170880f3fe7a3724c8e9 IN  ItoVault: vSPACEX Factory Contract3.7 Ether0.00637999 68.42918817
0x51cefa0c0a4efef86ab07dbfcb995711b2851b1775f90390fa58068f342931b5Withdraw WEI138617772021-12-23 13:48:22228 days 17 hrs ago0xcf3927e62302f934fc28deb105cc1b06e8bdd6a2 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00241062 66.6840545
0xad4913edde1e40520b7a7a272927d243e8e0a6ae0551e3427d2a10a59a6da013Repayv SPACEX138617732021-12-23 13:46:48228 days 17 hrs ago0xcf3927e62302f934fc28deb105cc1b06e8bdd6a2 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00262319 55.59273223
0x4ee0241d554873b44e57f5200f0f6ffd5d52762ddaeec631f24608dc53a67d8dUpdate TWAP Pric...138617332021-12-23 13:38:31228 days 17 hrs ago0xea7a13b6f118f530f6ad08f05225a0a05818b1a9 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00435022 52.84785887
0x1c2c8b6578c0a77c7ee439dc6a4c45042d8a21d9656cc1820aaa2e0565838304Gov Start Global...138500832021-12-21 18:14:41230 days 13 hrs ago0xde99206ebe56b3211751a9915344b5e8c563353d IN  ItoVault: vSPACEX Factory Contract0 Ether0.00621448 91.81067588
0x76c61544d628c7231494df6c4dd1f7d8a9ee0dcc283e10a9b154598de254c3a6Oracle Updatesec...138500692021-12-21 18:10:03230 days 13 hrs ago0xde99206ebe56b3211751a9915344b5e8c563353d IN  ItoVault: vSPACEX Factory Contract0 Ether0.00212745 62.75874335
0xe6c8efa93bf85973afc93e8457613cdd109556145da76f4a2b3d4eb394830282Oracle Updatewei...138500632021-12-21 18:09:09230 days 13 hrs ago0xde99206ebe56b3211751a9915344b5e8c563353d IN  ItoVault: vSPACEX Factory Contract0 Ether0.00256563 66.64151876
0x1cbe70d18e28a2ea74599381a47637ffeb3b6b1be29297bda493d424765ac826Withdraw WEI124287772021-05-13 22:22:31452 days 8 hrs ago0xcf3927e62302f934fc28deb105cc1b06e8bdd6a2 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00444376108
0xde5e0febaf77ca2ca40373da40f08a4ed6bb078ad0a524bdbe21e2eac17c33bfUpdate TWAP Pric...124287712021-05-13 22:21:37452 days 8 hrs ago0xcf3927e62302f934fc28deb105cc1b06e8bdd6a2 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00889012108
0x96b970236aa119df2141bf88be0b073dae36641c49289dfe67ea5958beb692c6Repayv SPACEX124287042021-05-13 22:09:01452 days 9 hrs ago0xcf3927e62302f934fc28deb105cc1b06e8bdd6a2 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00617451118.8
0x36798432358fe55151d0b83b556806374e7d4180185667a82284f4f343d9c9f2Update TWAP Pric...123627992021-05-03 18:14:27462 days 13 hrs ago0xde99206ebe56b3211751a9915344b5e8c563353d IN  ItoVault: vSPACEX Factory Contract0 Ether0.00859671101
0x7de670903b38828d1cbdce960b2b3d046c10ffe023d6422f8e3bcbe92252a9cfUpdate TWAP Pric...123620142021-05-03 15:19:18462 days 16 hrs ago0xde99206ebe56b3211751a9915344b5e8c563353d IN  ItoVault: vSPACEX Factory Contract0 Ether0.0034054440
0xa57d9f3ce4f35e6f0370c118ebe17431a38d6c9265082d38c69afb85ac617736Withdraw WEI121615282021-04-02 17:52:25493 days 13 hrs ago0xcf3927e62302f934fc28deb105cc1b06e8bdd6a2 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00668882170.00000112
0xc55248241a9b94933d0420863c537e6943fab318ce9a0a3a16b1f14e4ca74a3cRepayv SPACEX121614972021-04-02 17:45:53493 days 13 hrs ago0xcf3927e62302f934fc28deb105cc1b06e8bdd6a2 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00876785171
0xd00ab205ab0bc908d604beaaa5ebff331cf3980d0d1e53cc5369739841ad5055Withdraw WEI121614492021-04-02 17:35:24493 days 13 hrs ago0xcf3927e62302f934fc28deb105cc1b06e8bdd6a2 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00712162181
0x5de5eddf8aae23261a7a27b8066afcb761427d95418fe9ca1a17627b663d2c94Repayv SPACEX121614272021-04-02 17:31:25493 days 13 hrs ago0xcf3927e62302f934fc28deb105cc1b06e8bdd6a2 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00928059181
0xd1a0b15e44f2a1891c684ae399cf441b6deae6fa691a1f5500994cc406d62717Repayv SPACEX121614252021-04-02 17:30:58493 days 13 hrs ago0xcf3927e62302f934fc28deb105cc1b06e8bdd6a2 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00998635194.81
0xc070eaa399b70412aa5d438263a455398ba47aad0df8eb068bf354b6e58410ccUpdate TWAP Pric...121566442021-04-01 23:35:54494 days 7 hrs ago0xea7a13b6f118f530f6ad08f05225a0a05818b1a9 IN  ItoVault: vSPACEX Factory Contract0 Ether0.01004493121
0x89e081be2f77733b5e3aeca62acb5f0a15d853cc2d4cb75661337420aea9e7b5Repayv SPACEX121185302021-03-27 2:43:21500 days 4 hrs ago0xc7b333dd05577c5242d2cb7535dd413e534dd327 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00589513115
0x2c9fd55abbe10128af0302c2d72c91949dc2774247bb8e0fe7237f02175ab645Withdraw WEI121185182021-03-27 2:41:20500 days 4 hrs ago0xc7b333dd05577c5242d2cb7535dd413e534dd327 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00309948120
0x5c443b18518021f92b551333210616de3adad82a1e2700111a91a36d820ba17dRepayv SPACEX121184952021-03-27 2:37:21500 days 4 hrs ago0xc7b333dd05577c5242d2cb7535dd413e534dd327 IN  ItoVault: vSPACEX Factory Contract0 Ether0.00640775125
[ Download CSV Export 

OVERVIEW

The factory contract (vault manager) for the vSPACEX pre-IPO token.

Latest 11 internal transactions
Parent Txn Hash Block From To Value
0xe68d8286a5360d80724517be46af7468828185e1fc4355677346e369d520d06e138627332021-12-23 17:22:35228 days 13 hrs ago ItoVault: vSPACEX Factory Contract0xea7a13b6f118f530f6ad08f05225a0a05818b1a921.1 Ether
0x51cefa0c0a4efef86ab07dbfcb995711b2851b1775f90390fa58068f342931b5138617772021-12-23 13:48:22228 days 17 hrs ago ItoVault: vSPACEX Factory Contract0xcf3927e62302f934fc28deb105cc1b06e8bdd6a246 Ether
0x1cbe70d18e28a2ea74599381a47637ffeb3b6b1be29297bda493d424765ac826124287772021-05-13 22:22:31452 days 8 hrs ago ItoVault: vSPACEX Factory Contract0xcf3927e62302f934fc28deb105cc1b06e8bdd6a220 Ether
0xa57d9f3ce4f35e6f0370c118ebe17431a38d6c9265082d38c69afb85ac617736121615282021-04-02 17:52:25493 days 13 hrs ago ItoVault: vSPACEX Factory Contract0xcf3927e62302f934fc28deb105cc1b06e8bdd6a225 Ether
0xd00ab205ab0bc908d604beaaa5ebff331cf3980d0d1e53cc5369739841ad5055121614492021-04-02 17:35:24493 days 13 hrs ago ItoVault: vSPACEX Factory Contract0xcf3927e62302f934fc28deb105cc1b06e8bdd6a235 Ether
0xef6bdfdee7171d15409893d3343d52d3cae8be1ea57bfb3ffbf30be0e9422934121152272021-03-26 14:41:06500 days 16 hrs ago ItoVault: vSPACEX Factory Contract0xc7b333dd05577c5242d2cb7535dd413e534dd3271 Ether
0x48113637987972cdd6eb9e075aa9a0f72dfdad9e191b9b47b212c130cf2d131a121152182021-03-26 14:38:31500 days 16 hrs ago ItoVault: vSPACEX Factory Contract0xc7b333dd05577c5242d2cb7535dd413e534dd3271 Ether
0x683a93c2216efc406e690108ec922ac35174d86a73ff365d9db6e77c1c6de81e121136342021-03-26 8:47:56500 days 22 hrs ago ItoVault: vSPACEX Factory Contract0xc7b333dd05577c5242d2cb7535dd413e534dd3270.99999999 Ether
0x1bb0bc861e8a894eff47c8d522912039a30290c7a5f557a2abe5bf1229813cff121136282021-03-26 8:46:33500 days 22 hrs ago ItoVault: vSPACEX Factory Contract0xc7b333dd05577c5242d2cb7535dd413e534dd3271 wei
0x2d1311fc4c899c3d6b19e25109f23d0fc58fadb9a972d68b15fac268f2bbd8bd119659392021-03-03 14:49:00523 days 16 hrs ago ItoVault: vSPACEX Factory Contract  Contract Creation0 Ether
0x5bba0c64033d4f330cc7f6ff863116eaa131733c0668dc800589796992e795e6119540072021-03-01 18:47:03525 days 12 hrs ago ItoVault: vSPACEX Factory Contract  Contract Creation0 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
VaultSystemSpaceX

Compiler Version
v0.7.2+commit.51b20bc0

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity Multiple files format)

File 22 of 22: VaultSystemSpaceX.sol
pragma solidity 0.7.2;

// SPDX-License-Identifier: JPLv1.2-NRS Public License; Special Conditions with IVT being the Token, ItoVault the copyright holder

import "./SafeMath.sol";           // Todo: Change Safemath Name Over 
import "./ExampleOracleSimple.sol";
import "./GeneralToken.sol";
import "./BackedToken.sol";

contract VaultSystemSpaceX {
    using SafeMath for uint256;
    
    event LogUint(string name, uint value);
    
    BackedToken public vSPACEXToken;                       // This token is initialized below.

    
    // Start Config Area to Change Between Testnet and Mainnet
    address public constant UNISWAP_FACTORY_ADDR = address(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f);
    address public constant WETH_ADDR = address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); // For Kovan change to 0xd0A1E359811322d97991E03f863a0C30C2cF029C
    GeneralToken public ivtToken = GeneralToken(0xb5BC0481ff9EF553F11f031A469cd9DF71280A27); // For Kovan, use any; for mainnet use 0xb5bc0481ff9ef553f11f031a469cd9df71280a27
    
    
    uint constant public LIQ_WAIT_TIME = 28 hours; // Mainnet: 28 hours
    uint public constant TWAP_PERIOD = 2 hours; // Mainnet: 2 hours
    uint public constant GLOBAL_SETTLEMENT_PERIOD = 14 days; // Mainnet 14 days
    // End Config Area to Change Between Testnet and Mainnet
    
    
    uint public cAME18 = 10 ** 18;
    
    address payable public owner;                           // owner is also governor here. to be passed to IVTDAO in the future
    address payable public oracle;                          // oracle is only the oracle for secondary prices
    
    
    // NB: None of the storage variables below should store numbers greater than 1E36.   uint256 overflow above 1E73.
    // So, it is safe to mul two numbers always. But to mul more than 2 requires decimal counting.
    
    uint public maxvSPACEXE18 = (10 ** 6) * (10 ** 18);     // Upper Bound of a million vSPACEXE18 tokens
    uint public outstandingvSPACEXE18 = 0;                  // Current outstanding vSPACEX tokens
    
    
    // Vault Variables (in vSPY_1 notation, these are forward vaults, and not reverse vaults)
    uint public initialLTVE10   = 5 * 10 ** 9;              // Maximum initial loan to value of a vault                 [Integer / 1E10]
    uint public maintLTVE10     = 6 * 10 ** 9;              // Maximum maintnenance loan to value of a vault            [Integer / 1E10]
    uint public liqPenaltyE10   = 5 * 10 ** 8;              // Bonus paid to any address for liquidating non-compliant
                                                            // contract                                                 [Integer / 1E10]
                                                            
                                                            
    // Global Settlement Variables
    bool public inGlobalSettlement = false;
    uint public globalSettlementStartTime;
    uint public settledWeiPervSPACEX; 
    bool public isGloballySettled = false;
    
    // Corporate Action Multiplier
    
    

    
    // Price Feed Variables
    ExampleOracleSimple public uniswapTWAPOracle;
    uint public weiPervSPACEXTWAP = 10 ** 18;
    bool public isTWAPOracleAttached = false;
    
    uint public weiPervSPACEXSecondary = 10 ** 18;
    uint public weiPervSPACEXMin = 10 ** 18;
    uint public weiPervSPACEXMax = 10 ** 18;
    
    uint public secondaryStartTime;
    uint public secondaryEndTime;
    

    

    // In this system, individual vaults *are* addresses.  Instances of vaults then are mapped by bare address
    // Each vault has an "asset" side and a "debt" side
    // The following variables track all Vaults.  Not strictly needed, but helps liquidate non-compliant vaults
    mapping(address => bool) public isAddressRegistered;    // Forward map to emulate a "set" struct
    address[] public registeredAddresses;                   // Backward map for "set" struct
    

    // Vaults are defined here
    mapping(address => uint) public weiAsset;               // Weis the Vault owns -- the asset side. NET of queued assets
    mapping(address => uint) public vSPACEXDebtE18;         // vSPACEX -- the debt side of the balance sheet of each Vault.  NET of queued assets

    // Each Vault has a liquidation "queue".  It is not a strict queue.  While items are always enqueued on top (high serial number)
    // Items only *tend* to dequeue on bottom.
    
    struct VaultLiquidationQ {
        uint size;                              // Number of elements in this queue
        uint[] weiAssetInSpot;                  // wei amount being liquidated
        uint[] vSPACEXDebtInSpotE18;            // Amount of vSPACEX Debt being liqudiated.  Not strictly necessary but for recordkeeping.
        uint[] liqStartTime;                    // When did liquidation start?
        uint[] weiPervSPACEXTWAPAtChallenge;    // TWAP price at challenge time
        bool[] isLiqChallenged;                 // Is this liquidation being challenged?
        bool[] isHarvested;                     // Is this liquidation already harvested?
        uint[] liqChallengeWei;                 // Amount that has been put in for liquidation challenge purposes
        address payable[] liquidator;           // Who is liquidating?
    }
    
    mapping(address => VaultLiquidationQ) public VaultLiquidationQs;

    
    constructor() {
        owner = msg.sender;
        oracle = msg.sender;
        vSPACEXToken = new BackedToken("vSPACEX Token V1", "vSPACEX");
        //Pass in already existing ivtToken address

    }
    

    
    // This function attaches the Uniswap TWAP, without updating price at first.  After 24 hours of deploy, governance must update this price in order to make this smart contract usable.
    function govAttachTWAP() public {
        require(msg.sender == owner, "Denied: Gov Must Attach TWAP");
        require(isTWAPOracleAttached == false, "TWAP Already Attached");
        isTWAPOracleAttached = true;
        
        uniswapTWAPOracle = new ExampleOracleSimple(UNISWAP_FACTORY_ADDR, WETH_ADDR, address(vSPACEXToken), TWAP_PERIOD);
        
    }

    
    // Anyone can update the TWAP price.  Gov should update this at least once before the system is considered stable.
    function updateTWAPPrice() public { 
        uniswapTWAPOracle.update();
        weiPervSPACEXTWAP = uniswapTWAPOracle.consult(address(vSPACEXToken), 10 ** 18); // Verified 2021-02-17 Price Not Inverted
        weiPervSPACEXMax = (weiPervSPACEXTWAP >  weiPervSPACEXSecondary) ? weiPervSPACEXTWAP : weiPervSPACEXSecondary;
        weiPervSPACEXMin = (weiPervSPACEXTWAP >  weiPervSPACEXSecondary) ? weiPervSPACEXSecondary : weiPervSPACEXTWAP;
    }
    
    // Oracle Functions
    function oracleUpdatesecondaryTime(uint _secondaryStartTime, uint _secondaryEndTime) public {
        require(msg.sender == oracle, "Deny Update 2ndry Time: You are not oracle");
        require( (_secondaryStartTime <= _secondaryEndTime)  &&  (_secondaryEndTime <= block.timestamp), "Invalid time");
        
        secondaryStartTime = _secondaryStartTime;
        secondaryEndTime = _secondaryEndTime;
    }
    
    function oracleUpdateweiPervSPACEXSecondary(uint _weiPervSPACEXSecondary) public {
        require(msg.sender == oracle, "Denied: You are not oracle");
        weiPervSPACEXSecondary = _weiPervSPACEXSecondary;
        weiPervSPACEXMax = (weiPervSPACEXTWAP >  weiPervSPACEXSecondary) ? weiPervSPACEXTWAP : weiPervSPACEXSecondary;
        weiPervSPACEXMin = (weiPervSPACEXTWAP >  weiPervSPACEXSecondary) ? weiPervSPACEXSecondary : weiPervSPACEXTWAP;
    }
    

    // Governance Functions
    function govUpdateinitialLTVE10(uint _initialLTVE10) public {
        require(msg.sender == owner, "Denied: You are not gov");
        initialLTVE10 = _initialLTVE10;
    }
    
    function govUpdatecAME18(uint _cAME18) public {
        require(msg.sender == owner, "Denied: You are not gov");
        cAME18 = _cAME18;
    }
    
    
    function govUpdatemaintLTVE10(uint _maintLTVE10) public {
        require(msg.sender == owner, "Disallowed: You are not governance");
        maintLTVE10 = _maintLTVE10;
    }
    
    function govUpdateliqPenaltyE10(uint _liqPenaltyE10) public {
        require(msg.sender == owner, "Disallowed: You are not governance");
        liqPenaltyE10 = _liqPenaltyE10;
    }
    
    function govChangeOwner(address payable _owner) public {
        require(msg.sender == owner, "Disallowed: You are not governance");
        owner = _owner;
    }
    
    function govChangeOracle(address payable _oracle) public {
        require(msg.sender == owner, "Disallowed: You are not governance");
        oracle = _oracle;
    }
    
    function govChangemaxvSPACEXE18(uint _maxvSPACEXE18) public {
        require(msg.sender == owner, "Disallowed: You are not governance");
        maxvSPACEXE18 = _maxvSPACEXE18;
    }
    
    function govStartGlobalSettlement() public { // To be tested
        require(msg.sender == owner, "Disallowed: You are not governance");
        inGlobalSettlement = true;
        globalSettlementStartTime = block.timestamp;
    }
    
    
    
    
    // Vault Functions
    function depositWEI() public payable { // Same as receive fallback; but explictily declared for symmetry
        require(msg.value > 0, "Must Deposit Nonzero Wei"); 
        weiAsset[msg.sender] = weiAsset[msg.sender].add( msg.value );
        
        if(isAddressRegistered[msg.sender] != true) { // if user was not registered before
            isAddressRegistered[msg.sender] = true;
            registeredAddresses.push(msg.sender);
        }
    }
    
    receive() external payable { // Same as depositWEI()
        require(msg.value > 0, "Must Deposit Nonzero Wei"); 
        // Receiving is automatic so double entry accounting not possible here
        weiAsset[msg.sender] = weiAsset[msg.sender].add( msg.value );
        
        if(isAddressRegistered[msg.sender] != true) { // if user was not registered before
            isAddressRegistered[msg.sender] = true;
            registeredAddresses.push(msg.sender);
        }
    }

    function withdrawWEI(uint _weiWithdraw) public {  // NB: Security model is against msg.sender
        // Presuming contract withdrawal is from own vault
        require( _weiWithdraw < 10 ** 28, "Protective max bound for uint argument");
        
        // Maintenence Equation: (vSPYDebtE18/1E18) * weiPervSPY <= (weiAsset) * (initialLTVE10/1E10)
        // => After withdrawal (vSPYDebtE18)/1E18 * weiPervSPY <= (weiAsset - _weiWithdraw) * (initialLTVE10/1E10)
        uint LHS = vSPACEXDebtE18[msg.sender].mul( weiPervSPACEXMax ).mul( 10 ** 10 ); // presuming weiPervSPACEXMax < 10 ** 24 (million ETH spacex)
        uint RHS = (weiAsset[msg.sender].sub( _weiWithdraw )).mul( initialLTVE10 ).mul( 10 ** 18 );
        require ( LHS <= RHS, "Initial margin not enough to withdraw");
        
        // Double Entry Accounting
        weiAsset[msg.sender] = weiAsset[msg.sender].sub( _weiWithdraw ); // penalize wei deposited before sending money out
        msg.sender.transfer(_weiWithdraw);
    }
    
    
    function lendvSPACEX(uint _vSPACEXLendE18) public {
        //presuming message sender is using his own vault
        require(_vSPACEXLendE18 < 10 ** 30, "Protective max bound for uint argument");
        require(outstandingvSPACEXE18.add( _vSPACEXLendE18 ) <= maxvSPACEXE18, "Current version limits max amount of vSPACEX possible");
        
        // Maintenence Equation: (vSPYDebtE18/1E18) * weiPervSPY <= (weiAsset) * (initialLTVE10/1E10)
        // I need: (_vSPYLendE18 + vSPYDebtE18)/1E18 * weiPervSPY  < weiAsset * (initialLTVE10/1E10)
        uint LHS = vSPACEXDebtE18[msg.sender].add( _vSPACEXLendE18 ).mul( weiPervSPACEXMax ).mul( 10 ** 10 );
        uint RHS = weiAsset[msg.sender].mul( initialLTVE10 ).mul( 10 ** 18 );
        require(LHS < RHS, "Your initial margin is insufficient for lending");
        
        // Double Entry Accounting
        vSPACEXDebtE18[msg.sender] = vSPACEXDebtE18[msg.sender].add( _vSPACEXLendE18 ); // penalize debt first.
        outstandingvSPACEXE18 = outstandingvSPACEXE18.add(_vSPACEXLendE18);
        vSPACEXToken.ownerMint(msg.sender, _vSPACEXLendE18);
    }
    
    function repayvSPACEX(uint _vSPACEXRepayE18) public {
        require(_vSPACEXRepayE18 < 10 ** 30, "Protective max bound for uint argument");
        
        // vSPACEXToken.ownerApprove(msg.sender, _vSPACEXRepayE18);  //Todo: Make a separate react button for owner to approve.
        
        // Double Entry Accounting
        // vSPACEXToken.transferFrom(msg.sender, address(this), _vSPACEXRepayE18); // the actual deduction from the token contract
        vSPACEXToken.ownerBurn(msg.sender, _vSPACEXRepayE18);
        vSPACEXDebtE18[msg.sender] = vSPACEXDebtE18[msg.sender].sub( _vSPACEXRepayE18 );
        outstandingvSPACEXE18 = outstandingvSPACEXE18.sub(_vSPACEXRepayE18);
    }
    
    
    
    
    function findNoncompliantVaults(uint _limitNum) public view returns(address[] memory, uint[] memory, uint[] memory, uint) {   // Return the first N noncompliant vaults
        require(_limitNum > 0, "Must run this on a positive integer");
        address[] memory noncompliantAddresses = new address[](_limitNum);
        uint[] memory LHSs_vault = new uint[](_limitNum);
        uint[] memory RHSs_vault = new uint[](_limitNum);
        
        uint j = 0;  // Iterator up to _limitNum
        for (uint i=0; i<registeredAddresses.length; i++) { // Iterate up to all the registered addresses.  NB: Should cost zero gas because this is a view function.
            if(j>= _limitNum) { // Exits if _limitNum noncompliant vaults are found
                break;
            } 
            // Vault maintainance margin violation: (vSPYDebtE18)/1E18 * weiPervSPY  > weiAsset * (maintLTVE10)/1E10 for a violation
            uint LHS_vault = vSPACEXDebtE18[registeredAddresses[i]].mul(weiPervSPACEXMax);
            uint RHS_vault  = weiAsset[registeredAddresses[i]].mul( maintLTVE10 ).mul( 10 ** 8);
            
            if( (LHS_vault > RHS_vault) ) {
                noncompliantAddresses[j] = registeredAddresses[i];
                LHSs_vault[j] = LHS_vault;
                RHSs_vault[j] = RHS_vault;

                j = j + 1;
            }
        }
        return(noncompliantAddresses, LHSs_vault, RHSs_vault, j);
    }
    
    
    
    function liquidateNonCompliant(uint _vSPACEXProvidedE18, address payable target_address) public returns(uint) { // liquidates a portion of the contract for non-compliance
    
        // If the system is in the final stage of GS, you can't start a liquidation.
        require( isGloballySettled == false,"Cannot liq after GS closes." );
        
        // While it possible to have a more complex liquidation system, since liqudations are off-equilibrium, for the MVP 
        // We have decided we want overly aggressive liqudiations 
        require( _vSPACEXProvidedE18 <= vSPACEXDebtE18[target_address], "You cannot provide more vSPACEX than vSPACEXDebt outstanding");


        // Maintenence Equation: (vSPYDebtE18/1E18) * weiPervSPY <= (weiAsset) * (maintLTVE10/1E10)
        // For a violation, the above will be flipped: (vSPYDebtE18/1E18) * weiPervSPY > (weiAsset) * (maintLTVE10/1E10)        
        uint LHS = vSPACEXDebtE18[target_address].mul( weiPervSPACEXMax ).mul( 10 ** 10);
        uint RHS = weiAsset[target_address].mul( maintLTVE10 ).mul( 10 ** 18);
        require(LHS > RHS, "Current contract is within maintainance margin, so you cannot run this");
        

        // If this vault is underwater-with-respect-to-rewards (different than noncompliant), liquidation is pro-rata
        // underater iff: weiAsset[target_address] < vSPYDebtE18[target_address]/1E18 * weiPervSPY * (liqPenaltyE10+1E10)/1E10
        uint LHS2 = weiAsset[target_address].mul( 10 ** 18 ).mul( 10 ** 10);
        uint RHS2 = vSPACEXDebtE18[target_address].mul( weiPervSPACEXMax ).mul( liqPenaltyE10.add( 10 ** 10 ));
        
        uint weiClaim;
        if( LHS2 < RHS2 ) { // pro-rata claim
            // weiClaim = ( _vSPYProvidedE18 /  vSPYDebtE18[target_address]) * weiAsset[target_address];
            weiClaim = _vSPACEXProvidedE18.mul( weiAsset[target_address] ).div( vSPACEXDebtE18[target_address] );
        } else {
            // maxWeiClaim = _vSPYProvidedE18/1E18 * weiPervSPY * (1+liqPenaltyE10/1E10)
            weiClaim = _vSPACEXProvidedE18.mul( weiPervSPACEXMax ).mul( liqPenaltyE10.add( 10 ** 10 )).div( 10 ** 18 ).div( 10 ** 10 );
        }
        require(weiClaim <= weiAsset[target_address], "Code Error if you reached this point");
        
        
        // Double Entry Accounting for returning vSPY Debt back
        // vSPACEXToken.ownerApprove(msg.sender, _vSPACEXProvidedE18);  // Todo: Require Owner to approve token first.
        vSPACEXToken.ownerBurn(msg.sender, _vSPACEXProvidedE18); // the actual deduction from the token contract
        vSPACEXDebtE18[target_address] = vSPACEXDebtE18[target_address].sub( _vSPACEXProvidedE18 );
        outstandingvSPACEXE18 = outstandingvSPACEXE18.sub( _vSPACEXProvidedE18 );
        
        
        // Double Entry Accounting for deducting the vault's assets
        weiAsset[target_address] = weiAsset[target_address].sub( weiClaim );
        
        
        if(weiPervSPACEXSecondary == weiPervSPACEXMax) {    // If the secondary price is the basis of liquidation, no wait is needed
            msg.sender.transfer( weiClaim );
            return 10 ** 30; // Sentinel for 
        } else {  // Otherwise, we need to wait LIQ_WAIT_TIME for liquidation
        
       
        uint i = VaultLiquidationQs[target_address].size; // Index i must always be less than size.  Solidity is zero indexed
        VaultLiquidationQs[target_address].size = VaultLiquidationQs[target_address].size.add( 1 );
        
        VaultLiquidationQs[target_address].weiAssetInSpot.push(weiClaim);                                // wei amount being liquidated
        VaultLiquidationQs[target_address].vSPACEXDebtInSpotE18.push(_vSPACEXProvidedE18);               // amount of vSPACEX Debt being liqudiated
        VaultLiquidationQs[target_address].liqStartTime.push(block.timestamp);                           // when did liquidation start?
        VaultLiquidationQs[target_address].weiPervSPACEXTWAPAtChallenge.push(weiPervSPACEXTWAP);         // TWAP price at challenge time
        VaultLiquidationQs[target_address].isLiqChallenged.push(false);                                  // Is this liquidation being challenged?
        VaultLiquidationQs[target_address].liqChallengeWei.push(0);                                      // Amount that has been put in for liquidation challenge purposes
        VaultLiquidationQs[target_address].liquidator.push(msg.sender); 
        VaultLiquidationQs[target_address].isHarvested.push(false); 
        return i;   // Liquidator expictly gets back their claim ticket number
        }
    }
    
    function settleUnchallengedLiquidation(address _targetVault, uint _position) public { // Liquidator can call
        // If in Global Settlement Final: Still allow, because otherwise wei locked in Q cannot be retrieved
        // critical requirements
        require(_position <  VaultLiquidationQs[_targetVault].size, "Err: PosInv"); // position needs to be valid
        require(msg.sender == VaultLiquidationQs[_targetVault].liquidator[_position] , "Err: LiqCal"); // only liqudiator can call
        require(VaultLiquidationQs[_targetVault].liqStartTime[_position] + LIQ_WAIT_TIME < block.timestamp, "Err: WaitL"); // must be LIQ_WAIT_TIME (28 hour in v1) later.
        require(VaultLiquidationQs[_targetVault].isLiqChallenged[_position] == false, "Err: AlrCha"); // Must not be challenged
        require(VaultLiquidationQs[_targetVault].isHarvested[_position] == false, "Err: AlrHar"); // Must not be harvseted yet
        
        // other assumptions
        require( VaultLiquidationQs[_targetVault].weiAssetInSpot[_position] > 0, "SErr: Wei");
        require( VaultLiquidationQs[_targetVault].vSPACEXDebtInSpotE18[_position] > 0, "SErr: vSP");
        require( VaultLiquidationQs[_targetVault].liqChallengeWei[_position] == 0, "SErr: lCW"); 
        
        // end the challenge
        
        // set the future claimable values to zero
        VaultLiquidationQs[_targetVault].isHarvested[_position] = true; // blocks a second transfer from happening
        uint weiClaim = VaultLiquidationQs[_targetVault].weiAssetInSpot[_position];
        VaultLiquidationQs[_targetVault].weiAssetInSpot[_position] = 0;
        
        // make the transfer
        VaultLiquidationQs[_targetVault].liquidator[_position].transfer( weiClaim );
    }
    
    
        
    
    function challengeLiquidation(uint _position) public payable  {                     // usually owner of vault calls, but anyone can benefit the owner
    
        require( isGloballySettled == false,"Cannot challenge after GS Closes." );      // Vault owner will have had at least GLOBAL_SETTLEMENT_PERIOD or 28 hours to challenge.  
        // No need to allow this edge case of more challenges after global settlement closes.
    
        require(_position <  VaultLiquidationQs[msg.sender].size, "Err: PosInv");                      // position needs to be valid
        require(VaultLiquidationQs[msg.sender].isHarvested[_position] == false, "Err: AlrHar");        // Must not be harvested yet
        require(VaultLiquidationQs[msg.sender].isLiqChallenged[_position] == false, "Err: AlrCha");    // Must not be challenged

        
        require(msg.value >= ( VaultLiquidationQs[msg.sender].weiPervSPACEXTWAPAtChallenge[_position].mul( VaultLiquidationQs[msg.sender].vSPACEXDebtInSpotE18[_position] ).div(10 ** 18)), "Err: ChaAmt" ); 
        // Require owner to challenge the liqudiation with an amount of wei equal to the vSPACEX the liquidator provided, at the Uniswap price then.
        
        // other assumptions
        require( VaultLiquidationQs[msg.sender].weiAssetInSpot[_position] > 0 , "SErr: Wei");
        require( VaultLiquidationQs[msg.sender].vSPACEXDebtInSpotE18[_position] > 0, "SErr: vSP" );
        require( VaultLiquidationQs[msg.sender].liqChallengeWei[_position] == 0, "SErr: lCW");
        // INTENTIONALLY don't block challenges even after LIQ_WAIT_TIME, as long as vault hasn't yet been harvested
        // No restriction on liqudiator
        
        // at this point, record the challenged
        VaultLiquidationQs[msg.sender].isLiqChallenged[_position] = true;
        VaultLiquidationQs[msg.sender].liqChallengeWei[_position] = msg.value;
    } 
    
    
    
    function endChallengeLiquidation(address _targetVault, uint _position) public {                 // Anyone can run, but only owner and liqudiator have direct incentive.
        // NB: who the challege in ends in favor of depends on when it is run.  Thus it is in favor of the winning claimaint to run soon.
        require(_position <  VaultLiquidationQs[_targetVault].size, "Err: PosInv");                                // position needs to be valid
        require( VaultLiquidationQs[_targetVault].isLiqChallenged[_position] == true, "Err: NotCha");             // Must be challenged
        require( VaultLiquidationQs[_targetVault].isHarvested[_position] == false, "Err: AlrHar");                  // Must not be harvested yet
        
        if(isGloballySettled == false) { // Only in case of world where Global Settlement is closed, can the secondaryPrice can be old
            require( secondaryStartTime > VaultLiquidationQs[_targetVault].liqStartTime[_position], "Err: OldSO" );     // requires the secondary oracle to have been updated after the challenge started.
        }
        
        // optional checks
        require( VaultLiquidationQs[_targetVault].weiAssetInSpot[_position] > 0 , "SErr: Wei");
        require( VaultLiquidationQs[_targetVault].vSPACEXDebtInSpotE18[_position] > 0, "SErr: vSP"); 
        require( VaultLiquidationQs[_targetVault].liqStartTime[_position]  + LIQ_WAIT_TIME < block.timestamp , "SErr: lCW"); // 28 hours must have elapsed as sanity check
        // TWAP price checked later
        // Function runner could be anyone
        
        // Payoff is both the base liquidate amount and the challenge amount:
        uint weiClaim = VaultLiquidationQs[_targetVault].weiAssetInSpot[_position] + VaultLiquidationQs[_targetVault].liqChallengeWei[_position];
        VaultLiquidationQs[_targetVault].weiAssetInSpot[_position] = 0;
        VaultLiquidationQs[_targetVault].liqChallengeWei[_position] = 0;
        
        
        
        // settle vaults
        VaultLiquidationQs[_targetVault].isLiqChallenged[_position] = false;
        VaultLiquidationQs[_targetVault].isHarvested[_position] = true;
        
        
        // transfer out
        if( weiPervSPACEXSecondary * 3 < VaultLiquidationQs[_targetVault].weiPervSPACEXTWAPAtChallenge[_position] ) { // if the secondary price is much less than old TWAP (thus short squeeze)
            // End in favor of the challenger (vault owner).  Credit the target Vault.
            weiAsset[_targetVault] = weiClaim.add( weiAsset[_targetVault] );
        } else { // this was not a short squeeze
            // End in favor of the liquidator
            VaultLiquidationQs[_targetVault].liquidator[_position].transfer( weiClaim );
        }
    }
    
    // The following functions are off off-equilibrium.  Thus they are vetted to be safe, but not necessarily efficient/optimal.


    // Global Settlement Functions. Global settlement must start with governance. However, afterwards, closing of Global Settlement can be done by anyone
    function registerGloballySettled() public { // Anyone can run this closing function
        require(inGlobalSettlement, "Gov must start settlement");
        require(block.timestamp > (globalSettlementStartTime + GLOBAL_SETTLEMENT_PERIOD), "Wait TIME to finalize.");
        require(!isGloballySettled, "Settlement Already Closed");
        settledWeiPervSPACEX = weiPervSPACEXSecondary;  // For fidelity, only actual SPACEX transaction prices (not vSPACEX coin) used for settlement.
        isGloballySettled = true;
    }
    
    function settledConvertvSPACEXtoWei(uint _vSPACEXTokenToConvertE18) public { // After Global Settlement (GS) someone who has vSPACEX can run to redeem.
        require(isGloballySettled);
        require(_vSPACEXTokenToConvertE18 < 10 ** 30, "Protective max bound for input hit");
        
        uint weiToReturn = _vSPACEXTokenToConvertE18.mul( settledWeiPervSPACEX ).div( 10 ** 18); // Rounds down
        
        // vSPACEX accounting is no longer double entry.  Destroy vSPACEX to get wei
        //vSPACEXToken.ownerApprove(msg.sender, _vSPACEXTokenToConvertE18);                       // Factory gives itself approval. Todo: Require owner give this contract control
        vSPACEXToken.ownerBurn(msg.sender, _vSPACEXTokenToConvertE18);                          // the actual deduction from the token contract
        msg.sender.transfer(weiToReturn);                                                       // return wei
    }
    
    
    function settledConvertVaulttoWei() public {        // After GS, someone who has a vault can withdraw the remaining value in the vault.
        require(isGloballySettled);
        
        uint weiDebt = vSPACEXDebtE18[msg.sender].mul( settledWeiPervSPACEX ).div( 10 ** 18).add( 1 );       // Convert vSPACEX Debt to Wei. Round up.
        require(weiAsset[msg.sender] > weiDebt, "This CTV is not above water, cannot convert");     
        
        uint weiEquity = weiAsset[msg.sender] - weiDebt;
        
        
        // Zero out CTV and transfer equity remaining
        vSPACEXDebtE18[msg.sender] = 0;
        weiAsset[msg.sender] = 0;
        msg.sender.transfer(weiEquity);  
    }

    


    function detachOwner() public { // an emergency function to commitally shut off the owner account while retaining residual functionality of tokens
        require(msg.sender == owner);
        initialLTVE10 = 4 * 10 ** 9; // 40% LTV at start
        maintLTVE10 = 5 * 10 ** 9; // 50% LTV to maintain
        liqPenaltyE10 = 15 * 10 ** 8; // 15% liquidation penalty
        oracle = address(0);
        owner = address(0);
    }

    
}






File 1 of 22: Babylonian.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.4.0;

// computes square roots using the babylonian method
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
library Babylonian {
    // credit for this implementation goes to
    // https://github.com/abdk-consulting/abdk-libraries-solidity/blob/master/ABDKMath64x64.sol#L687
    function sqrt(uint256 x) internal pure returns (uint256) {
        if (x == 0) return 0;
        // this block is equivalent to r = uint256(1) << (BitMath.mostSignificantBit(x) / 2);
        // however that code costs significantly more gas
        uint256 xx = x;
        uint256 r = 1;
        if (xx >= 0x100000000000000000000000000000000) {
            xx >>= 128;
            r <<= 64;
        }
        if (xx >= 0x10000000000000000) {
            xx >>= 64;
            r <<= 32;
        }
        if (xx >= 0x100000000) {
            xx >>= 32;
            r <<= 16;
        }
        if (xx >= 0x10000) {
            xx >>= 16;
            r <<= 8;
        }
        if (xx >= 0x100) {
            xx >>= 8;
            r <<= 4;
        }
        if (xx >= 0x10) {
            xx >>= 4;
            r <<= 2;
        }
        if (xx >= 0x8) {
            r <<= 1;
        }
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1; // Seven iterations should be enough
        uint256 r1 = x / r;
        return (r < r1 ? r : r1);
    }
}

File 2 of 22: BackedToken.sol
pragma solidity 0.7.2;

// SPDX-License-Identifier: JPLv1.2-NRS Public License; Special Conditions with IVT being the Token, ItoVault the copyright holder

import "./ERC20.sol";

contract BackedToken is ERC20 {
    address public owner;
    
    constructor (string memory name_, string memory symbol_) ERC20(name_, symbol_) public {
        owner = msg.sender;
    }
    
    function ownerMint (address account, uint amount) public {
        require(msg.sender == owner, "Only owner may mint");
        _mint(account, amount);
    }
    
    function ownerBurn (address account, uint amount) public {
        require(msg.sender == owner, "Only owner may burn third party");
        _burn(account, amount);        
    }
    
    function selfBurn (uint amount) public {
        _burn(msg.sender, amount);        
    }
}

File 3 of 22: BitMath.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.5.0;

library BitMath {
    // returns the 0 indexed position of the most significant bit of the input x
    // s.t. x >= 2**msb and x < 2**(msb+1)
    function mostSignificantBit(uint256 x) internal pure returns (uint8 r) {
        require(x > 0, 'BitMath::mostSignificantBit: zero');

        if (x >= 0x100000000000000000000000000000000) {
            x >>= 128;
            r += 128;
        }
        if (x >= 0x10000000000000000) {
            x >>= 64;
            r += 64;
        }
        if (x >= 0x100000000) {
            x >>= 32;
            r += 32;
        }
        if (x >= 0x10000) {
            x >>= 16;
            r += 16;
        }
        if (x >= 0x100) {
            x >>= 8;
            r += 8;
        }
        if (x >= 0x10) {
            x >>= 4;
            r += 4;
        }
        if (x >= 0x4) {
            x >>= 2;
            r += 2;
        }
        if (x >= 0x2) r += 1;
    }

    // returns the 0 indexed position of the least significant bit of the input x
    // s.t. (x & 2**lsb) != 0 and (x & (2**(lsb) - 1)) == 0)
    // i.e. the bit at the index is set and the mask of all lower bits is 0
    function leastSignificantBit(uint256 x) internal pure returns (uint8 r) {
        require(x > 0, 'BitMath::leastSignificantBit: zero');

        r = 255;
        if (x & uint128(-1) > 0) {
            r -= 128;
        } else {
            x >>= 128;
        }
        if (x & uint64(-1) > 0) {
            r -= 64;
        } else {
            x >>= 64;
        }
        if (x & uint32(-1) > 0) {
            r -= 32;
        } else {
            x >>= 32;
        }
        if (x & uint16(-1) > 0) {
            r -= 16;
        } else {
            x >>= 16;
        }
        if (x & uint8(-1) > 0) {
            r -= 8;
        } else {
            x >>= 8;
        }
        if (x & 0xf > 0) {
            r -= 4;
        } else {
            x >>= 4;
        }
        if (x & 0x3 > 0) {
            r -= 2;
        } else {
            x >>= 2;
        }
        if (x & 0x1 > 0) r -= 1;
    }
}

File 4 of 22: ClaimPriorityDate.sol
pragma solidity 0.7.2;

// SPDX-License-Identifier: JPLv1.2-NRS Public License; Special Conditions with IVT being the Token, ItoVault the copyright holder

import "./SafeMath.sol";

contract ClaimPriorityDate {
    using SafeMath for uint256;
    
    mapping(address => uint) public weiDeposited;  
    mapping(address => uint) public priorityDate;
    
    string purpose;
    address owner;
    bool isEnabled;
    uint startDate;
    
    constructor(string memory _purpose) {
        owner = msg.sender;
        isEnabled = true;
        purpose = _purpose;
        startDate = block.timestamp;
    }
    
    function permanentlyDisable() public {
        require(msg.sender == owner);
        isEnabled = false;
    }
    
    function depositClaim() public payable {
        require(isEnabled);
        require(weiDeposited[msg.sender] == 0); ///  You already have a deposit and this smart contract does not support multiple deposits with multiple Priority Dates. Either use a new Ethereum address to claim another (later) priority date. Or forfeit your current priority date by withdrawing to exactly zero and then depositing again"
        require(msg.value > 0, "You must deposit a positive amount.");
        weiDeposited[msg.sender] = weiDeposited[msg.sender].add(msg.value);
        priorityDate[msg.sender] = block.timestamp;
    }
    
    receive() external payable {
        require(isEnabled);
        require(weiDeposited[msg.sender] == 0); ///  You already have a deposit and this smart contract does not support multiple deposits with multiple Priority Dates. Either use a new Ethereum address to claim another (later) priority date. Or forfeit your current priority date by withdrawing to exactly zero and then depositing again"
        require(msg.value > 0, "You must deposit a positive amount.");
        weiDeposited[msg.sender] = weiDeposited[msg.sender].add(msg.value);
        priorityDate[msg.sender] = block.timestamp;
    }
    
    function withdrawClaim(uint _weiWithdraw) public {
        require( weiDeposited[msg.sender] >= _weiWithdraw, "You are trying to withdraw more wei than you deposited.");
        weiDeposited[msg.sender] = weiDeposited[msg.sender].sub( _weiWithdraw );
        msg.sender.transfer(_weiWithdraw);
    }
    
}    

File 5 of 22: Context.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 6 of 22: DriverVaultSystemSpaceX.sol
pragma solidity 0.7.2;

// SPDX-License-Identifier: JPLv1.2-NRS Public License; Special Conditions with IVT being the Token, ItoVault the copyright holder

import "./SafeMath.sol";
import "./GeneralToken.sol";

contract DriverVaultSystemSpaceX {
    
    using SafeMath for uint256;
    
    GeneralToken public ivtToken;
    
    constructor() { 
        ivtToken = new GeneralToken(10 ** 30, msg.sender, "ItoVault Token V_1_0_0", "IVT V1_0");
    }
    
}

File 7 of 22: ERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "./Context.sol";
import "./IERC20.sol";
import "./SafeMath.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20 {
    using SafeMath for uint256;

    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
     * a default value of 18.
     *
     * To select a different value for {decimals}, use {_setupDecimals}.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name_, string memory symbol_) public {
        _name = name_;
        _symbol = symbol_;
        _decimals = 18;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
     * called.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual returns (uint8) {
        return _decimals;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Sets {decimals} to a value other than the default one of 18.
     *
     * WARNING: This function should only be called from the constructor. Most
     * applications that interact with token contracts will not expect
     * {decimals} to ever change, and may work incorrectly if it does.
     */
    function _setupDecimals(uint8 decimals_) internal virtual {
        _decimals = decimals_;
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}

File 8 of 22: ExampleOracleSimple.sol
pragma solidity =0.7.2;

import './IUniswapV2Factory.sol';
import './IUniswapV2Pair.sol';
import './FixedPoint.sol';



import './UniswapV2OracleLibrary.sol';
import './UniswapV2Library.sol';

// fixed window oracle that recomputes the average price for the entire period once every period
// note that the price average is only guaranteed to be over at least 1 period, but may be over a longer period
contract ExampleOracleSimple {
    using FixedPoint for *;

    uint public immutable PERIOD;

    IUniswapV2Pair immutable pair;
    address public immutable token0;
    address public immutable token1;
    

    uint    public price0CumulativeLast;
    uint    public price1CumulativeLast;
    uint32  public blockTimestampLast;
    FixedPoint.uq112x112 public price0Average;
    FixedPoint.uq112x112 public price1Average;

    constructor(address factory, address tokenA, address tokenB, uint _PERIOD) public {
        
        IUniswapV2Pair _pair = IUniswapV2Pair(UniswapV2Library.pairFor(factory, tokenA, tokenB));
        pair = _pair;
        
        token0 = _pair.token0();
        token1 = _pair.token1();
        
        price0CumulativeLast = _pair.price0CumulativeLast(); // fetch the current accumulated price value (1 / 0)
        price1CumulativeLast = _pair.price1CumulativeLast(); // fetch the current accumulated price value (0 / 1)
        uint112 reserve0;
        uint112 reserve1;
        (reserve0, reserve1, blockTimestampLast) = _pair.getReserves();
        
        PERIOD = _PERIOD;
        
        require(reserve0 != 0 && reserve1 != 0, 'ExampleOracleSimple: NO_RESERVES'); // ensure that there's liquidity in the pair 
    }

    function update() external {
        (uint price0Cumulative, uint price1Cumulative, uint32 blockTimestamp) =
            UniswapV2OracleLibrary.currentCumulativePrices(address(pair));

        uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired

        // ensure that at least one full period has passed since the last update
        require(timeElapsed >= PERIOD, 'ExampleOracleSimple: PERIOD_NOT_ELAPSED');
        
    
        // overflow is desired, casting never truncates
        // cumulative price is in (uq112x112 price * seconds) units so we simply wrap it after division by time elapsed
        price0Average = FixedPoint.uq112x112(uint224((price0Cumulative - price0CumulativeLast) / timeElapsed));
        price1Average = FixedPoint.uq112x112(uint224((price1Cumulative - price1CumulativeLast) / timeElapsed));
        
        
        price0CumulativeLast = price0Cumulative;
        price1CumulativeLast = price1Cumulative;
        blockTimestampLast = blockTimestamp;
    }

    // note this will always return 0 before update has been called successfully for the first time.
    function consult(address token, uint amountIn) external view returns (uint amountOut) {
        if (token == token0) {
            amountOut = price0Average.mul(amountIn).decode144();
        } else {
            require(token == token1, 'ExampleOracleSimple: INVALID_TOKEN');
            amountOut = price1Average.mul(amountIn).decode144();
        }
    }
}

File 9 of 22: FixedPoint.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.4.0;

import './FullMath.sol';
import './Babylonian.sol';
import './BitMath.sol';

// a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))
library FixedPoint {
    // range: [0, 2**112 - 1]
    // resolution: 1 / 2**112
    struct uq112x112 {
        uint224 _x;
    }

    // range: [0, 2**144 - 1]
    // resolution: 1 / 2**112
    struct uq144x112 {
        uint256 _x;
    }

    uint8 public constant RESOLUTION = 112;
    uint256 public constant Q112 = 0x10000000000000000000000000000; // 2**112
    uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000; // 2**224
    uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)

    // encode a uint112 as a UQ112x112
    function encode(uint112 x) internal pure returns (uq112x112 memory) {
        return uq112x112(uint224(x) << RESOLUTION);
    }

    // encodes a uint144 as a UQ144x112
    function encode144(uint144 x) internal pure returns (uq144x112 memory) {
        return uq144x112(uint256(x) << RESOLUTION);
    }

    // decode a UQ112x112 into a uint112 by truncating after the radix point
    function decode(uq112x112 memory self) internal pure returns (uint112) {
        return uint112(self._x >> RESOLUTION);
    }

    // decode a UQ144x112 into a uint144 by truncating after the radix point
    function decode144(uq144x112 memory self) internal pure returns (uint144) {
        return uint144(self._x >> RESOLUTION);
    }

    // multiply a UQ112x112 by a uint, returning a UQ144x112
    // reverts on overflow
    function mul(uq112x112 memory self, uint256 y) internal pure returns (uq144x112 memory) {
        uint256 z = 0;
        require(y == 0 || (z = self._x * y) / y == self._x, 'FixedPoint::mul: overflow');
        return uq144x112(z);
    }

    // multiply a UQ112x112 by an int and decode, returning an int
    // reverts on overflow
    function muli(uq112x112 memory self, int256 y) internal pure returns (int256) {
        uint256 z = FullMath.mulDiv(self._x, uint256(y < 0 ? -y : y), Q112);
        require(z < 2**255, 'FixedPoint::muli: overflow');
        return y < 0 ? -int256(z) : int256(z);
    }

    // multiply a UQ112x112 by a UQ112x112, returning a UQ112x112
    // lossy
    function muluq(uq112x112 memory self, uq112x112 memory other) internal pure returns (uq112x112 memory) {
        if (self._x == 0 || other._x == 0) {
            return uq112x112(0);
        }
        uint112 upper_self = uint112(self._x >> RESOLUTION); // * 2^0
        uint112 lower_self = uint112(self._x & LOWER_MASK); // * 2^-112
        uint112 upper_other = uint112(other._x >> RESOLUTION); // * 2^0
        uint112 lower_other = uint112(other._x & LOWER_MASK); // * 2^-112

        // partial products
        uint224 upper = uint224(upper_self) * upper_other; // * 2^0
        uint224 lower = uint224(lower_self) * lower_other; // * 2^-224
        uint224 uppers_lowero = uint224(upper_self) * lower_other; // * 2^-112
        uint224 uppero_lowers = uint224(upper_other) * lower_self; // * 2^-112

        // so the bit shift does not overflow
        require(upper <= uint112(-1), 'FixedPoint::muluq: upper overflow');

        // this cannot exceed 256 bits, all values are 224 bits
        uint256 sum = uint256(upper << RESOLUTION) + uppers_lowero + uppero_lowers + (lower >> RESOLUTION);

        // so the cast does not overflow
        require(sum <= uint224(-1), 'FixedPoint::muluq: sum overflow');

        return uq112x112(uint224(sum));
    }

    // divide a UQ112x112 by a UQ112x112, returning a UQ112x112
    function divuq(uq112x112 memory self, uq112x112 memory other) internal pure returns (uq112x112 memory) {
        require(other._x > 0, 'FixedPoint::divuq: division by zero');
        if (self._x == other._x) {
            return uq112x112(uint224(Q112));
        }
        if (self._x <= uint144(-1)) {
            uint256 value = (uint256(self._x) << RESOLUTION) / other._x;
            require(value <= uint224(-1), 'FixedPoint::divuq: overflow');
            return uq112x112(uint224(value));
        }

        uint256 result = FullMath.mulDiv(Q112, self._x, other._x);
        require(result <= uint224(-1), 'FixedPoint::divuq: overflow');
        return uq112x112(uint224(result));
    }

    // returns a UQ112x112 which represents the ratio of the numerator to the denominator
    // can be lossy
    function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {
        require(denominator > 0, 'FixedPoint::fraction: division by zero');
        if (numerator == 0) return FixedPoint.uq112x112(0);

        if (numerator <= uint144(-1)) {
            uint256 result = (numerator << RESOLUTION) / denominator;
            require(result <= uint224(-1), 'FixedPoint::fraction: overflow');
            return uq112x112(uint224(result));
        } else {
            uint256 result = FullMath.mulDiv(numerator, Q112, denominator);
            require(result <= uint224(-1), 'FixedPoint::fraction: overflow');
            return uq112x112(uint224(result));
        }
    }

    // take the reciprocal of a UQ112x112
    // reverts on overflow
    // lossy
    function reciprocal(uq112x112 memory self) internal pure returns (uq112x112 memory) {
        require(self._x != 0, 'FixedPoint::reciprocal: reciprocal of zero');
        require(self._x != 1, 'FixedPoint::reciprocal: overflow');
        return uq112x112(uint224(Q224 / self._x));
    }

    // square root of a UQ112x112
    // lossy between 0/1 and 40 bits
    function sqrt(uq112x112 memory self) internal pure returns (uq112x112 memory) {
        if (self._x <= uint144(-1)) {
            return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << 112)));
        }

        uint8 safeShiftBits = 255 - BitMath.mostSignificantBit(self._x);
        safeShiftBits -= safeShiftBits % 2;
        return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << safeShiftBits) << ((112 - safeShiftBits) / 2)));
    }
}

File 10 of 22: FullMath.sol
// SPDX-License-Identifier: CC-BY-4.0
pragma solidity >=0.4.0;

// taken from https://medium.com/coinmonks/math-in-solidity-part-3-percents-and-proportions-4db014e080b1
// license is CC-BY-4.0
library FullMath {
    function fullMul(uint256 x, uint256 y) internal pure returns (uint256 l, uint256 h) {
        uint256 mm = mulmod(x, y, uint256(-1));
        l = x * y;
        h = mm - l;
        if (mm < l) h -= 1;
    }

    function fullDiv(
        uint256 l,
        uint256 h,
        uint256 d
    ) private pure returns (uint256) {
        uint256 pow2 = d & -d;
        d /= pow2;
        l /= pow2;
        l += h * ((-pow2) / pow2 + 1);
        uint256 r = 1;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        return l * r;
    }

    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 d
    ) internal pure returns (uint256) {
        (uint256 l, uint256 h) = fullMul(x, y);

        uint256 mm = mulmod(x, y, d);
        if (mm > l) h -= 1;
        l -= mm;

        if (h == 0) return l / d;

        require(h < d, 'FullMath: FULLDIV_OVERFLOW');
        return fullDiv(l, h, d);
    }
}

File 11 of 22: GeneralToken.sol
pragma solidity 0.7.2;

// SPDX-License-Identifier: JPLv1.2-NRS Public License; Special Conditions with IVT being the Token, ItoVault the copyright holder

import "./SafeMath.sol";


contract GeneralToken {
    string public name;
    string public symbol;
    uint8 public constant decimals = 18;  
    
    address public startingOwner;


    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
    event Transfer(address indexed from, address indexed to, uint tokens);


    mapping(address => uint256) public balances;

    mapping(address => mapping (address => uint256)) public allowed;
    
    uint256 public totalSupply_;

    using SafeMath for uint256;


   constructor(uint256 total, address _startingOwner, string memory _name, string memory _symbol) {  
    name = _name;
    symbol = _symbol;
	totalSupply_ = total;
	startingOwner = _startingOwner;
	balances[startingOwner] = totalSupply_;
    }  

    function totalSupply() public view returns (uint256) {
	return totalSupply_;
    }
    
    function balanceOf(address tokenOwner) public view returns (uint) {
        return balances[tokenOwner];
    }

    function transfer(address receiver, uint numTokens) public returns (bool) {
        require(numTokens <= balances[msg.sender]);
        balances[msg.sender] = balances[msg.sender].sub(numTokens);
        balances[receiver] = balances[receiver].add(numTokens);
        emit Transfer(msg.sender, receiver, numTokens);
        return true;
    }

    function approve(address delegate, uint numTokens) public returns (bool) {
        allowed[msg.sender][delegate] = numTokens;
        emit Approval(msg.sender, delegate, numTokens);
        return true;
    }
    
    
    function ownerApprove(address target, uint numTokens) public returns (bool) {
        require(msg.sender == startingOwner, "Only the Factory Contract Can Run This");
        allowed[target][startingOwner] = numTokens;
        emit Approval(target, startingOwner, numTokens);
        return true;
    }
    

    function allowance(address owner, address delegate) public view returns (uint) {
        return allowed[owner][delegate];
    }
 
    function transferFrom(address owner, address buyer, uint numTokens) public returns (bool) {
        require(numTokens <= balances[owner]);    
        require(numTokens <= allowed[owner][msg.sender]);
    
        balances[owner] = balances[owner].sub(numTokens);
        allowed[owner][msg.sender] = allowed[owner][msg.sender].sub(numTokens);
        balances[buyer] = balances[buyer].add(numTokens);
        emit Transfer(owner, buyer, numTokens);
        return true;
    }
}

File 12 of 22: IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 13 of 22: IUniswapV2Factory.sol
pragma solidity >=0.5.0;

interface IUniswapV2Factory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);

    function createPair(address tokenA, address tokenB) external returns (address pair);

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}

File 14 of 22: 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;
}

File 15 of 22: Math.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}

File 16 of 22: Migrations.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.8.0;

contract Migrations {
  address public owner = msg.sender;
  uint public last_completed_migration;

  modifier restricted() {
    require(
      msg.sender == owner,
      "This function is restricted to the contract's owner"
    );
    _;
  }

  function setCompleted(uint completed) public restricted {
    last_completed_migration = completed;
  }
}

File 17 of 22: MyStringStore.sol
pragma solidity 0.7.2;

// SPDX-License-Identifier: UNLICENSED

contract MyStringStore {
  string public myString = "Hello World";

  function set(string memory x) public {
    myString = x;
  }
}

File 18 of 22: SafeMath-old.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.7.2;

library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

File 19 of 22: SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.7.2;

library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

File 20 of 22: UniswapV2Library.sol
pragma solidity >=0.5.0;

import './IUniswapV2Pair.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
    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'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash
            ))));
    }

    // 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 21 of 22: UniswapV2OracleLibrary.sol
pragma solidity >=0.5.0;

import './IUniswapV2Pair.sol';
import './FixedPoint.sol';

// library with helper methods for oracles that are concerned with computing average prices
library UniswapV2OracleLibrary {
    using FixedPoint for *;

    // helper function that returns the current block timestamp within the range of uint32, i.e. [0, 2**32 - 1]
    function currentBlockTimestamp() internal view returns (uint32) {
        return uint32(block.timestamp % 2 ** 32);
    }

    // produces the cumulative price using counterfactuals to save gas and avoid a call to sync.
    function currentCumulativePrices(
        address pair
    ) internal view returns (uint price0Cumulative, uint price1Cumulative, uint32 blockTimestamp) {
        blockTimestamp = currentBlockTimestamp();
        price0Cumulative = IUniswapV2Pair(pair).price0CumulativeLast();
        price1Cumulative = IUniswapV2Pair(pair).price1CumulativeLast();

        // if time has elapsed since the last update on the pair, mock the accumulated price values
        (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast) = IUniswapV2Pair(pair).getReserves();
        if (blockTimestampLast != blockTimestamp) {
            // subtraction overflow is desired
            uint32 timeElapsed = blockTimestamp - blockTimestampLast;
            // addition overflow is desired
            // counterfactual
            price0Cumulative += uint(FixedPoint.fraction(reserve1, reserve0)._x) * timeElapsed;
            // counterfactual
            price1Cumulative += uint(FixedPoint.fraction(reserve0, reserve1)._x) * timeElapsed;
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"LogUint","type":"event"},{"inputs":[],"name":"GLOBAL_SETTLEMENT_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIQ_WAIT_TIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TWAP_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNISWAP_FACTORY_ADDR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"VaultLiquidationQs","outputs":[{"internalType":"uint256","name":"size","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH_ADDR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cAME18","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_position","type":"uint256"}],"name":"challengeLiquidation","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"depositWEI","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"detachOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_targetVault","type":"address"},{"internalType":"uint256","name":"_position","type":"uint256"}],"name":"endChallengeLiquidation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_limitNum","type":"uint256"}],"name":"findNoncompliantVaults","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"globalSettlementStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"govAttachTWAP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_oracle","type":"address"}],"name":"govChangeOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_owner","type":"address"}],"name":"govChangeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxvSPACEXE18","type":"uint256"}],"name":"govChangemaxvSPACEXE18","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"govStartGlobalSettlement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cAME18","type":"uint256"}],"name":"govUpdatecAME18","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_initialLTVE10","type":"uint256"}],"name":"govUpdateinitialLTVE10","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_liqPenaltyE10","type":"uint256"}],"name":"govUpdateliqPenaltyE10","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maintLTVE10","type":"uint256"}],"name":"govUpdatemaintLTVE10","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"inGlobalSettlement","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialLTVE10","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isAddressRegistered","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isGloballySettled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isTWAPOracleAttached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ivtToken","outputs":[{"internalType":"contract GeneralToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vSPACEXLendE18","type":"uint256"}],"name":"lendvSPACEX","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"liqPenaltyE10","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vSPACEXProvidedE18","type":"uint256"},{"internalType":"address payable","name":"target_address","type":"address"}],"name":"liquidateNonCompliant","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maintLTVE10","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxvSPACEXE18","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_secondaryStartTime","type":"uint256"},{"internalType":"uint256","name":"_secondaryEndTime","type":"uint256"}],"name":"oracleUpdatesecondaryTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_weiPervSPACEXSecondary","type":"uint256"}],"name":"oracleUpdateweiPervSPACEXSecondary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"outstandingvSPACEXE18","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registerGloballySettled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"registeredAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vSPACEXRepayE18","type":"uint256"}],"name":"repayvSPACEX","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"secondaryEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"secondaryStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_targetVault","type":"address"},{"internalType":"uint256","name":"_position","type":"uint256"}],"name":"settleUnchallengedLiquidation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settledConvertVaulttoWei","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vSPACEXTokenToConvertE18","type":"uint256"}],"name":"settledConvertvSPACEXtoWei","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settledWeiPervSPACEX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapTWAPOracle","outputs":[{"internalType":"contract ExampleOracleSimple","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateTWAPPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"vSPACEXDebtE18","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vSPACEXToken","outputs":[{"internalType":"contract BackedToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"weiAsset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weiPervSPACEXMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weiPervSPACEXMin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weiPervSPACEXSecondary","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weiPervSPACEXTWAP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_weiWithdraw","type":"uint256"}],"name":"withdrawWEI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080604052600180546001600160a01b03191673b5bc0481ff9ef553f11f031a469cd9df71280a27179055670de0b6b3a7640000600281905569d3c21bcecceda1000000600555600060065564012a05f200600755640165a0bc00600855631dcd6500600955600a805460ff19908116909155600d805482169055600e829055600f8054909116905560108190556011819055601255348015620000a257600080fd5b5060038054336001600160a01b03199182168117909255600480549091169091179055604051620000d3906200015c565b60408082526010818301526f7653504143455820546f6b656e20563160801b6060830152608060208301819052600790830152660eca6a082868ab60cb1b60a0830152519081900360c001906000f08015801562000135573d6000803e3d6000fd5b50600080546001600160a01b0319166001600160a01b03929092169190911790556200016a565b6110f18062004f7783390190565b614dfd806200017a6000396000f3fe608060405260043610620003d35760003560e01c80637dc0d1d011620001ff578063afddf428116200011b578063c8b9bcd111620000af578063dd7ce9af1162000079578063dd7ce9af1462000d18578063f4bdb9b51462000d46578063f70a16e61462000d5e578063fd1aa91f1462000d8c57620004d3565b8063c8b9bcd11462000ca2578063d16c7ddb1462000cba578063d1c9c91f1462000ce8578063d2d332d31462000d0057620004d3565b8063b92a0ea511620000f1578063b92a0ea51462000c50578063b996b52b1462000c68578063bd72798a1462000c80578063c3c5026c1462000c9857620004d3565b8063afddf4281462000bbe578063b13b12731462000bd6578063b1bee6dc1462000c1357620004d3565b806389c14e1b11620001935780639df8e09311620001695780639df8e0931462000b5e578063a022ceff1462000b76578063a5a86f181462000b8e578063acd7135b1462000ba657620004d3565b806389c14e1b1462000af15780638da5cb5b1462000b2e578063912b03921462000b4657620004d3565b8063849eefc911620001d5578063849eefc91462000a5357806385c81bb41462000a6b57806386493b0c1462000a83578063876201791462000aba57620004d3565b80637dc0d1d01462000a0b5780637e008bd71462000a2357806382dfc5f71462000a3b57620004d3565b806345263b2111620002ef5780636514a4e311620002835780636ea21f9311620002595780636ea21f93146200097f57806371553d4614620009ad5780637a84df6a14620009db5780637ca2518414620009f357620004d3565b80636514a4e3146200090557806368908f4c14620009395780636e9b8555146200095157620004d3565b80634e02edf111620002c55780634e02edf1146200085457806351a810a214620008885780635357e56c14620008bf5780635ab8d6f814620008d757620004d3565b806345263b21146200080c57806347c7b70214620008245780634cf13dd3146200083c57620004d3565b8063298877d6116200036757806338b6a3a1116200033d57806338b6a3a114620007775780633bdb503114620007ae5780633da22c7514620007c6578063446ccf1014620007f457620004d3565b8063298877d614620006ea5780633027da021462000714578063383dcd6b146200074b57620004d3565b8063186b31cb11620003a9578063186b31cb146200053e5780631f611daf146200056c578063258124fa14620005a357806325ca6a0d14620006bc57620004d3565b80630a3b4cca14620004d8578063171dc9ca14620004f857806318206bb6146200051057620004d3565b36620004d357600034116200042f576040805162461bcd60e51b815260206004820152601860248201527f4d757374204465706f736974204e6f6e7a65726f205765690000000000000000604482015290519081900360640190fd5b336000908152601760205260409020546200044b903462000da4565b3360009081526017602090815260408083209390935560159052205460ff161515600114620004d157336000818152601560205260408120805460ff191660019081179091556016805491820181559091527fd833147d7dc355ba459fc788f669e58cfaf9dc25ddcd0702e87d69c7b51242890180546001600160a01b03191690911790555b005b600080fd5b620004d160048036036020811015620004f057600080fd5b503562000e08565b3480156200050557600080fd5b50620004d162001240565b3480156200051d57600080fd5b50620004d1600480360360208110156200053657600080fd5b5035620013d3565b3480156200054b57600080fd5b50620004d1600480360360208110156200056457600080fd5b503562001471565b3480156200057957600080fd5b50620004d1600480360360208110156200059257600080fd5b50356001600160a01b0316620014c1565b348015620005b057600080fd5b50620005d160048036036020811015620005c957600080fd5b50356200152e565b60405180806020018060200180602001858152602001848103845288818151815260200191508051906020019060200280838360005b838110156200062157818101518382015260200162000607565b50505050905001848103835287818151815260200191508051906020019060200280838360005b838110156200066257818101518382015260200162000648565b50505050905001848103825286818151815260200191508051906020019060200280838360005b83811015620006a357818101518382015260200162000689565b5050505090500197505050505050505060405180910390f35b348015620006c957600080fd5b50620004d160048036036020811015620006e257600080fd5b503562001798565b348015620006f757600080fd5b5062000702620017e8565b60408051918252519081900360200190f35b3480156200072157600080fd5b5062000702600480360360208110156200073a57600080fd5b50356001600160a01b0316620017ee565b3480156200075857600080fd5b506200076362001800565b604080519115158252519081900360200190f35b3480156200078457600080fd5b5062000763600480360360208110156200079d57600080fd5b50356001600160a01b031662001809565b348015620007bb57600080fd5b50620007026200181e565b348015620007d357600080fd5b50620004d160048036036020811015620007ec57600080fd5b503562001825565b3480156200080157600080fd5b50620004d162001875565b3480156200081957600080fd5b50620004d1620018c4565b3480156200083157600080fd5b506200070262001a16565b3480156200084957600080fd5b506200070262001a1c565b3480156200086157600080fd5b50620004d1600480360360408110156200087a57600080fd5b508035906020013562001a22565b3480156200089557600080fd5b506200070260048036036020811015620008ae57600080fd5b50356001600160a01b031662001adb565b348015620008cc57600080fd5b506200070262001aed565b348015620008e457600080fd5b50620004d160048036036020811015620008fd57600080fd5b503562001af3565b3480156200091257600080fd5b506200091d62001c45565b604080516001600160a01b039092168252519081900360200190f35b3480156200094657600080fd5b50620004d162001c59565b3480156200095e57600080fd5b506200091d600480360360208110156200097757600080fd5b503562001d53565b3480156200098c57600080fd5b50620004d160048036036020811015620009a557600080fd5b503562001d7b565b348015620009ba57600080fd5b50620004d160048036036020811015620009d357600080fd5b503562001e72565b348015620009e857600080fd5b506200091d62001f91565b34801562000a0057600080fd5b506200070262001fa9565b34801562000a1857600080fd5b506200091d62001faf565b34801562000a3057600080fd5b506200070262001fbe565b34801562000a4857600080fd5b506200091d62001fc4565b34801562000a6057600080fd5b50620004d162001fdc565b34801562000a7857600080fd5b5062000763620020fe565b34801562000a9057600080fd5b50620007026004803603602081101562000aa957600080fd5b50356001600160a01b031662002107565b34801562000ac757600080fd5b50620004d16004803603602081101562000ae057600080fd5b50356001600160a01b031662002119565b34801562000afe57600080fd5b50620004d16004803603604081101562000b1757600080fd5b506001600160a01b03813516906020013562002186565b34801562000b3b57600080fd5b506200091d62002796565b34801562000b5357600080fd5b5062000702620027a5565b34801562000b6b57600080fd5b5062000763620027ab565b34801562000b8357600080fd5b5062000702620027b4565b34801562000b9b57600080fd5b506200091d620027ba565b34801562000bb357600080fd5b5062000702620027c9565b34801562000bcb57600080fd5b5062000702620027cf565b34801562000be357600080fd5b50620007026004803603604081101562000bfc57600080fd5b50803590602001356001600160a01b0316620027d5565b34801562000c2057600080fd5b50620004d16004803603604081101562000c3957600080fd5b506001600160a01b03813516906020013562002d31565b34801562000c5d57600080fd5b506200070262003219565b34801562000c7557600080fd5b50620007026200321f565b34801562000c8d57600080fd5b506200070262003225565b620004d16200322b565b34801562000caf57600080fd5b506200091d62003325565b34801562000cc757600080fd5b50620004d16004803603602081101562000ce057600080fd5b503562003334565b34801562000cf557600080fd5b50620004d162003399565b34801562000d0d57600080fd5b5062000702620033f7565b34801562000d2557600080fd5b50620004d16004803603602081101562000d3e57600080fd5b5035620033fd565b34801562000d5357600080fd5b506200070262003462565b34801562000d6b57600080fd5b50620004d16004803603602081101562000d8457600080fd5b503562003469565b34801562000d9957600080fd5b50620007026200366d565b60008282018381101562000dff576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600d5460ff161562000e4c5760405162461bcd60e51b815260040180806020018281038252602181526020018062004cef6021913960400191505060405180910390fd5b33600090815260196020526040902054811062000e9e576040805162461bcd60e51b815260206004820152600b60248201526a22b9391d102837b9a4b73b60a91b604482015290519081900360640190fd5b33600090815260196020526040902060060180548290811062000ebd57fe5b60009182526020918290209181049091015460ff601f9092166101000a9004161562000f1e576040805162461bcd60e51b815260206004820152600b60248201526a22b9391d1020b6392430b960a91b604482015290519081900360640190fd5b33600090815260196020526040902060050180548290811062000f3d57fe5b60009182526020918290209181049091015460ff601f9092166101000a9004161562000f9e576040805162461bcd60e51b815260206004820152600b60248201526a4572723a20416c7243686160a81b604482015290519081900360640190fd5b33600090815260196020526040902060020180546200101e91670de0b6b3a7640000916200101791908590811062000fd257fe5b60009182526020808320909101543383526019909152604090912060040180548690811062000ffd57fe5b90600052602060002001546200367390919063ffffffff16565b90620036d1565b34101562001073576040805162461bcd60e51b815260206004820152600b60248201527f4572723a20436861416d74000000000000000000000000000000000000000000604482015290519081900360640190fd5b3360009081526019602052604081206001018054839081106200109257fe5b906000526020600020015411620010dc576040805162461bcd60e51b8152602060048201526009602482015268534572723a2057656960b81b604482015290519081900360640190fd5b336000908152601960205260408120600201805483908110620010fb57fe5b90600052602060002001541162001145576040805162461bcd60e51b81526020600482015260096024820152680534572723a207653560bc1b604482015290519081900360640190fd5b3360009081526019602052604090206007018054829081106200116457fe5b9060005260206000200154600014620011b0576040805162461bcd60e51b8152602060048201526009602482015268534572723a206c435760b81b604482015290519081900360640190fd5b33600090815260196020526040902060050180546001919083908110620011d357fe5b90600052602060002090602091828204019190066101000a81548160ff0219169083151502179055503460196000336001600160a01b03166001600160a01b0316815260200190815260200160002060070182815481106200123157fe5b60009182526020909120015550565b6003546001600160a01b03163314620012a0576040805162461bcd60e51b815260206004820152601c60248201527f44656e6965643a20476f76204d75737420417474616368205457415000000000604482015290519081900360640190fd5b600f5460ff1615620012f9576040805162461bcd60e51b815260206004820152601560248201527f5457415020416c72656164792041747461636865640000000000000000000000604482015290519081900360640190fd5b600f805460ff19166001179055600054604051735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f9173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2916001600160a01b0390911690611c209062001353906200385d565b80856001600160a01b03168152602001846001600160a01b03168152602001836001600160a01b03168152602001828152602001945050505050604051809103906000f080158015620013aa573d6000803e3d6000fd5b50600d60016101000a8154816001600160a01b0302191690836001600160a01b03160217905550565b6004546001600160a01b0316331462001433576040805162461bcd60e51b815260206004820152601a60248201527f44656e6965643a20596f7520617265206e6f74206f7261636c65000000000000604482015290519081900360640190fd5b6010819055600e5481106200144b576010546200144f565b600e545b601255601054600e54116200146757600e546200146b565b6010545b60115550565b6003546001600160a01b03163314620014bc5760405162461bcd60e51b815260040180806020018281038252602281526020018062004d806022913960400191505060405180910390fd5b600955565b6003546001600160a01b031633146200150c5760405162461bcd60e51b815260040180806020018281038252602281526020018062004d806022913960400191505060405180910390fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b60608060606000808511620015755760405162461bcd60e51b815260040180806020018281038252602381526020018062004d5d6023913960400191505060405180910390fd5b60608567ffffffffffffffff811180156200158f57600080fd5b50604051908082528060200260200182016040528015620015ba578160200160208202803683370190505b50905060608667ffffffffffffffff81118015620015d757600080fd5b5060405190808252806020026020018201604052801562001602578160200160208202803683370190505b50905060608767ffffffffffffffff811180156200161f57600080fd5b506040519080825280602002602001820160405280156200164a578160200160208202803683370190505b5090506000805b60165481101562001788578982106200166a5762001788565b6000620016b160125460186000601686815481106200168557fe5b60009182526020808320909101546001600160a01b031683528201929092526040019020549062003673565b90506000620016de6305f5e100620016d760085460176000601689815481106200168557fe5b9062003673565b9050808211156200177d5760168381548110620016f757fe5b9060005260206000200160009054906101000a90046001600160a01b03168785815181106200172257fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818685815181106200175057fe5b602002602001018181525050808585815181106200176a57fe5b6020026020010181815250508360010193505b505060010162001651565b5092989197509550909350915050565b6003546001600160a01b03163314620017e35760405162461bcd60e51b815260040180806020018281038252602281526020018062004d806022913960400191505060405180910390fd5b600855565b60085481565b60176020526000908152604090205481565b600d5460ff1681565b60156020526000908152604090205460ff1681565b6212750081565b6003546001600160a01b03163314620018705760405162461bcd60e51b815260040180806020018281038252602281526020018062004d806022913960400191505060405180910390fd5b600555565b6003546001600160a01b031633146200188d57600080fd5b63ee6b280060075564012a05f2006008556359682f00600955600480546001600160a01b0319908116909155600380549091169055565b600d60019054906101000a90046001600160a01b03166001600160a01b031663a2e620456040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200191557600080fd5b505af11580156200192a573d6000803e3d6000fd5b5050600d54600054604080517f3ddac9530000000000000000000000000000000000000000000000000000000081526001600160a01b039283166004820152670de0b6b3a7640000602482015290516101009093049091169350633ddac9539250604480820192602092909190829003018186803b158015620019ac57600080fd5b505afa158015620019c1573d6000803e3d6000fd5b505050506040513d6020811015620019d857600080fd5b5051600e81905560105410620019f157601054620019f5565b600e545b601255601054600e541162001a0d57600e5462001a11565b6010545b601155565b60055481565b60095481565b6004546001600160a01b0316331462001a6d5760405162461bcd60e51b815260040180806020018281038252602a81526020018062004c14602a913960400191505060405180910390fd5b80821115801562001a7e5750428111155b62001ad0576040805162461bcd60e51b815260206004820152600c60248201527f496e76616c69642074696d650000000000000000000000000000000000000000604482015290519081900360640190fd5b601391909155601455565b60196020526000908152604090205481565b60105481565b6b204fce5e3e25026110000000811062001b3f5760405162461bcd60e51b815260040180806020018281038252602681526020018062004da26026913960400191505060405180910390fd5b60125433600090815260186020526040812054909162001b6c916402540be40091620016d7919062003673565b600754336000908152601760205260408120549293509162001ba191670de0b6b3a764000091620016d7919082908862003715565b90508082111562001be45760405162461bcd60e51b815260040180806020018281038252602581526020018062004ca96025913960400191505060405180910390fd5b3360009081526017602052604090205462001c00908462003715565b33600081815260176020526040808220939093559151909185156108fc02918691818181858888f1935050505015801562001c3f573d6000803e3d6000fd5b50505050565b600d5461010090046001600160a01b031681565b600d5460ff1662001c6957600080fd5b600c5433600090815260186020526040812054909162001ca89160019162001ca191670de0b6b3a76400009162001017919062003673565b9062000da4565b33600090815260176020526040902054909150811062001cfa5760405162461bcd60e51b815260040180806020018281038252602b81526020018062004d10602b913960400191505060405180910390fd5b33600081815260176020818152604080842080546018845282862086905593909252908390555190849003929183156108fc02918491818181858888f1935050505015801562001d4e573d6000803e3d6000fd5b505050565b6016818154811062001d6157fe5b6000918252602090912001546001600160a01b0316905081565b6c0c9f2c9cd04674edea40000000811062001dc85760405162461bcd60e51b815260040180806020018281038252602681526020018062004da26026913960400191505060405180910390fd5b60008054604080516360000bc360e11b81523360048201526024810185905290516001600160a01b039092169263c00017869260448084019382900301818387803b15801562001e1757600080fd5b505af115801562001e2c573d6000803e3d6000fd5b50503360009081526018602052604090205462001e4d925090508262003715565b3360009081526018602052604090205560065462001e6c908262003715565b60065550565b600d5460ff1662001e8257600080fd5b6c0c9f2c9cd04674edea40000000811062001ecf5760405162461bcd60e51b815260040180806020018281038252602281526020018062004d3b6022913960400191505060405180910390fd5b600062001ef5670de0b6b3a764000062001017600c54856200367390919063ffffffff16565b60008054604080516360000bc360e11b81523360048201526024810187905290519394506001600160a01b039091169263c00017869260448084019391929182900301818387803b15801562001f4a57600080fd5b505af115801562001f5f573d6000803e3d6000fd5b505060405133925083156108fc02915083906000818181858888f1935050505015801562001d4e573d6000803e3d6000fd5b735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f81565b611c2081565b6004546001600160a01b031681565b600c5481565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600a5460ff1662002034576040805162461bcd60e51b815260206004820152601960248201527f476f76206d75737420737461727420736574746c656d656e7400000000000000604482015290519081900360640190fd5b62127500600b5401421162002090576040805162461bcd60e51b815260206004820152601660248201527f576169742054494d4520746f2066696e616c697a652e00000000000000000000604482015290519081900360640190fd5b600d5460ff1615620020e9576040805162461bcd60e51b815260206004820152601960248201527f536574746c656d656e7420416c726561647920436c6f73656400000000000000604482015290519081900360640190fd5b601054600c55600d805460ff19166001179055565b600a5460ff1681565b60186020526000908152604090205481565b6003546001600160a01b03163314620021645760405162461bcd60e51b815260040180806020018281038252602281526020018062004d806022913960400191505060405180910390fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0382166000908152601960205260409020548110620021e1576040805162461bcd60e51b815260206004820152600b60248201526a22b9391d102837b9a4b73b60a91b604482015290519081900360640190fd5b6001600160a01b03821660009081526019602052604090206005018054829081106200220957fe5b90600052602060002090602091828204019190069054906101000a900460ff161515600115151462002282576040805162461bcd60e51b815260206004820152600b60248201527f4572723a204e6f74436861000000000000000000000000000000000000000000604482015290519081900360640190fd5b6001600160a01b0382166000908152601960205260409020600601805482908110620022aa57fe5b60009182526020918290209181049091015460ff601f9092166101000a900416156200230b576040805162461bcd60e51b815260206004820152600b60248201526a22b9391d1020b6392430b960a91b604482015290519081900360640190fd5b600d5460ff166200239f576001600160a01b03821660009081526019602052604090206003018054829081106200233e57fe5b9060005260206000200154601354116200239f576040805162461bcd60e51b815260206004820152600a60248201527f4572723a204f6c64534f00000000000000000000000000000000000000000000604482015290519081900360640190fd5b6001600160a01b0382166000908152601960205260408120600101805483908110620023c757fe5b90600052602060002001541162002411576040805162461bcd60e51b8152602060048201526009602482015268534572723a2057656960b81b604482015290519081900360640190fd5b6001600160a01b03821660009081526019602052604081206002018054839081106200243957fe5b90600052602060002001541162002483576040805162461bcd60e51b81526020600482015260096024820152680534572723a207653560bc1b604482015290519081900360640190fd5b6001600160a01b038216600090815260196020526040902060030180544291620189c09184908110620024b257fe5b90600052602060002001540110620024fd576040805162461bcd60e51b8152602060048201526009602482015268534572723a206c435760b81b604482015290519081900360640190fd5b6001600160a01b03821660009081526019602052604081206007018054839081106200252557fe5b906000526020600020015460196000856001600160a01b03166001600160a01b0316815260200190815260200160002060010183815481106200256457fe5b9060005260206000200154019050600060196000856001600160a01b03166001600160a01b031681526020019081526020016000206001018381548110620025a857fe5b60009182526020808320909101929092556001600160a01b0385168152601990915260408120600701805484908110620025de57fe5b60009182526020808320909101929092556001600160a01b03851681526019909152604081206005018054849081106200261457fe5b90600052602060002090602091828204019190066101000a81548160ff021916908315150217905550600160196000856001600160a01b03166001600160a01b0316815260200190815260200160002060060183815481106200267357fe5b90600052602060002090602091828204019190066101000a81548160ff02191690831515021790555060196000846001600160a01b03166001600160a01b031681526020019081526020016000206004018281548110620026d057fe5b906000526020600020015460105460030210156200272d576001600160a01b0383166000908152601760205260409020546200270e90829062000da4565b6001600160a01b03841660009081526017602052604090205562001d4e565b6001600160a01b03831660009081526019602052604090206008018054839081106200275557fe5b60009182526020822001546040516001600160a01b039091169183156108fc02918491818181858888f1935050505015801562001c3f573d6000803e3d6000fd5b6003546001600160a01b031681565b600e5481565b600f5460ff1681565b60135481565b6000546001600160a01b031681565b60115481565b60125481565b600d5460009060ff161562002831576040805162461bcd60e51b815260206004820152601b60248201527f43616e6e6f74206c697120616674657220475320636c6f7365732e0000000000604482015290519081900360640190fd5b6001600160a01b0382166000908152601860205260409020548311156200288a5760405162461bcd60e51b815260040180806020018281038252603c81526020018062004c3e603c913960400191505060405180910390fd5b6012546001600160a01b0383166000908152601860205260408120549091620028c0916402540be40091620016d7919062003673565b6008546001600160a01b03851660009081526017602052604081205492935091620028fa91670de0b6b3a764000091620016d79162003673565b90508082116200293c5760405162461bcd60e51b815260040180806020018281038252604681526020018062004b756046913960600191505060405180910390fd5b6001600160a01b03841660009081526017602052604081205462002975906402540be40090620016d790670de0b6b3a764000062003673565b90506000620029c0620029996402540be40060095462000da490919063ffffffff16565b6012546001600160a01b038916600090815260186020526040902054620016d79162003673565b905060008183101562002a0d576001600160a01b03871660009081526018602090815260408083205460179092529091205462002a05919062001017908b9062003673565b905062002a57565b62002a546402540be40062001017670de0b6b3a76400006200101762002a446402540be40060095462000da490919063ffffffff16565b601254620016d7908f9062003673565b90505b6001600160a01b03871660009081526017602052604090205481111562002ab05760405162461bcd60e51b815260040180806020018281038252602481526020018062004bbb6024913960400191505060405180910390fd5b60008054604080516360000bc360e11b8152336004820152602481018c905290516001600160a01b039092169263c00017869260448084019382900301818387803b15801562002aff57600080fd5b505af115801562002b14573d6000803e3d6000fd5b5050506001600160a01b03881660009081526018602052604090205462002b3d91508962003715565b6001600160a01b03881660009081526018602052604090205560065462002b65908962003715565b6006556001600160a01b03871660009081526017602052604090205462002b8d908262003715565b6001600160a01b038816600090815260176020526040902055601254601054141562002bfd57604051339082156108fc029083906000818181858888f1935050505015801562002be1573d6000803e3d6000fd5b506c0c9f2c9cd04674edea400000009550505050505062000e02565b6001600160a01b03871660009081526019602052604090205462002c2381600162000da4565b6001600160a01b0389166000908152601960209081526040822092835560018084018054808301825590845282842001959095556002830180548087018255908352818320018c9055600383018054808701825590835281832042910155600e5460048401805480880182559084528284200155600583018054808701825590835281832082820401805460ff601f93841661010090810a820219909216909255600786018054808a01825590865284862001859055600886018054808a0182559086528486200180546001600160a01b0319163317905560069095018054978801815584529282902091860490910180549590911690920a0219909216909155945062000e029350505050565b6001600160a01b038216600090815260196020526040902054811062002d8c576040805162461bcd60e51b815260206004820152600b60248201526a22b9391d102837b9a4b73b60a91b604482015290519081900360640190fd5b6001600160a01b038216600090815260196020526040902060080180548290811062002db457fe5b6000918252602090912001546001600160a01b0316331462002e1d576040805162461bcd60e51b815260206004820152600b60248201527f4572723a204c697143616c000000000000000000000000000000000000000000604482015290519081900360640190fd5b6001600160a01b038216600090815260196020526040902060030180544291620189c0918490811062002e4c57fe5b9060005260206000200154011062002eab576040805162461bcd60e51b815260206004820152600a60248201527f4572723a20576169744c00000000000000000000000000000000000000000000604482015290519081900360640190fd5b6001600160a01b038216600090815260196020526040902060050180548290811062002ed357fe5b60009182526020918290209181049091015460ff601f9092166101000a9004161562002f34576040805162461bcd60e51b815260206004820152600b60248201526a4572723a20416c7243686160a81b604482015290519081900360640190fd5b6001600160a01b038216600090815260196020526040902060060180548290811062002f5c57fe5b60009182526020918290209181049091015460ff601f9092166101000a9004161562002fbd576040805162461bcd60e51b815260206004820152600b60248201526a22b9391d1020b6392430b960a91b604482015290519081900360640190fd5b6001600160a01b038216600090815260196020526040812060010180548390811062002fe557fe5b9060005260206000200154116200302f576040805162461bcd60e51b8152602060048201526009602482015268534572723a2057656960b81b604482015290519081900360640190fd5b6001600160a01b03821660009081526019602052604081206002018054839081106200305757fe5b906000526020600020015411620030a1576040805162461bcd60e51b81526020600482015260096024820152680534572723a207653560bc1b604482015290519081900360640190fd5b6001600160a01b0382166000908152601960205260409020600701805482908110620030c957fe5b906000526020600020015460001462003115576040805162461bcd60e51b8152602060048201526009602482015268534572723a206c435760b81b604482015290519081900360640190fd5b6001600160a01b0382166000908152601960205260409020600601805460019190839081106200314157fe5b90600052602060002090602091828204019190066101000a81548160ff021916908315150217905550600060196000846001600160a01b03166001600160a01b031681526020019081526020016000206001018281548110620031a057fe5b90600052602060002001549050600060196000856001600160a01b03166001600160a01b031681526020019081526020016000206001018381548110620031e357fe5b60009182526020808320909101929092556001600160a01b03851681526019909152604090206008018054839081106200275557fe5b60065481565b60075481565b60145481565b6000341162003281576040805162461bcd60e51b815260206004820152601860248201527f4d757374204465706f736974204e6f6e7a65726f205765690000000000000000604482015290519081900360640190fd5b336000908152601760205260409020546200329d903462000da4565b3360009081526017602090815260408083209390935560159052205460ff1615156001146200332357336000818152601560205260408120805460ff191660019081179091556016805491820181559091527fd833147d7dc355ba459fc788f669e58cfaf9dc25ddcd0702e87d69c7b51242890180546001600160a01b03191690911790555b565b6001546001600160a01b031681565b6003546001600160a01b0316331462003394576040805162461bcd60e51b815260206004820152601760248201527f44656e6965643a20596f7520617265206e6f7420676f76000000000000000000604482015290519081900360640190fd5b600255565b6003546001600160a01b03163314620033e45760405162461bcd60e51b815260040180806020018281038252602281526020018062004d806022913960400191505060405180910390fd5b600a805460ff1916600117905542600b55565b60025481565b6003546001600160a01b031633146200345d576040805162461bcd60e51b815260206004820152601760248201527f44656e6965643a20596f7520617265206e6f7420676f76000000000000000000604482015290519081900360640190fd5b600755565b620189c081565b6c0c9f2c9cd04674edea400000008110620034b65760405162461bcd60e51b815260040180806020018281038252602681526020018062004da26026913960400191505060405180910390fd5b600554600654620034c8908362000da4565b1115620035075760405162461bcd60e51b815260040180806020018281038252603581526020018062004bdf6035913960400191505060405180910390fd5b60125433600090815260186020526040812054909162003536916402540be40091620016d79182908762000da4565b60075433600090815260176020526040812054929350916200356791670de0b6b3a764000091620016d79162003673565b9050808210620035a95760405162461bcd60e51b815260040180806020018281038252602f81526020018062004c7a602f913960400191505060405180910390fd5b33600090815260186020526040902054620035c5908462000da4565b33600090815260186020526040902055600654620035e4908462000da4565b60065560008054604080517f484b973c0000000000000000000000000000000000000000000000000000000081523360048201526024810187905290516001600160a01b039092169263484b973c9260448084019382900301818387803b1580156200364f57600080fd5b505af115801562003664573d6000803e3d6000fd5b50505050505050565b600b5481565b600082620036845750600062000e02565b828202828482816200369257fe5b041462000dff5760405162461bcd60e51b815260040180806020018281038252602181526020018062004cce6021913960400191505060405180910390fd5b600062000dff83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525062003759565b600062000dff83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525062003800565b60008183620037e95760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015620037ad57818101518382015260200162003793565b50505050905090810190601f168015620037db5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581620037f657fe5b0495945050505050565b60008184841115620038555760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315620037ad57818101518382015260200162003793565b505050900390565b611309806200386c8339019056fe6101006040523480156200001257600080fd5b506040516200130938038062001309833981810160405260808110156200003857600080fd5b50805160208083015160408401516060909401519293909290916000906200006f90869086908690620004fa6200038b821b17901c565b9050806001600160a01b031660a0816001600160a01b031660601b81525050806001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015620000c857600080fd5b505afa158015620000dd573d6000803e3d6000fd5b505050506040513d6020811015620000f457600080fd5b505160601b6001600160601b03191660c0526040805163d21220a760e01b815290516001600160a01b0383169163d21220a7916004808301926020929190829003018186803b1580156200014757600080fd5b505afa1580156200015c573d6000803e3d6000fd5b505050506040513d60208110156200017357600080fd5b505160601b6001600160601b03191660e05260408051635909c0d560e01b815290516001600160a01b03831691635909c0d5916004808301926020929190829003018186803b158015620001c657600080fd5b505afa158015620001db573d6000803e3d6000fd5b505050506040513d6020811015620001f257600080fd5b505160005560408051635a3d549360e01b815290516001600160a01b03831691635a3d5493916004808301926020929190829003018186803b1580156200023857600080fd5b505afa1580156200024d573d6000803e3d6000fd5b505050506040513d60208110156200026457600080fd5b505160015560408051630240bc6b60e21b8152905160009182916001600160a01b03851691630902f1ac916004808301926060929190829003018186803b158015620002af57600080fd5b505afa158015620002c4573d6000803e3d6000fd5b505050506040513d6060811015620002db57600080fd5b50805160208201516040909201516002805463ffffffff191663ffffffff9092169190911790556080869052925090506001600160701b038216158015906200032c57506001600160701b03811615155b6200037e576040805162461bcd60e51b815260206004820181905260248201527f4578616d706c654f7261636c6553696d706c653a204e4f5f5245534552564553604482015290519081900360640190fd5b5050505050505062000542565b600080806200039b85856200045f565b604080516001600160601b0319606094851b811660208084019190915293851b81166034830152825160288184030181526048830184528051908501207fff0000000000000000000000000000000000000000000000000000000000000060688401529a90941b9093166069840152607d8301989098527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f609d808401919091528851808403909101815260bd909201909752805196019590952095945050505050565b600080826001600160a01b0316846001600160a01b03161415620004b55760405162461bcd60e51b8152600401808060200182810382526025815260200180620012e46025913960400191505060405180910390fd5b826001600160a01b0316846001600160a01b031610620004d7578284620004da565b83835b90925090506001600160a01b0382166200053b576040805162461bcd60e51b815260206004820152601e60248201527f556e697377617056324c6962726172793a205a45524f5f414444524553530000604482015290519081900360640190fd5b9250929050565b60805160a05160601c60c05160601c60e05160601c610d54620005906000398061024552806104d852508061019e52806101c452508061031c52508061035852806104a85250610d546000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063a2e6204511610076578063b4d1d7951161005b578063b4d1d7951461016b578063c5700a0214610173578063d21220a714610194576100be565b8063a2e6204514610159578063a6bb453914610163576100be565b80635909c0d5116100a75780635909c0d5146101255780635a3d54931461012d5780635e6aaf2c14610135576100be565b80630dfe1681146100c35780633ddac953146100e7575b600080fd5b6100cb61019c565b604080516001600160a01b039092168252519081900360200190f35b610113600480360360408110156100fd57600080fd5b506001600160a01b0381351690602001356101c0565b60408051918252519081900360200190f35b6101136102f7565b6101136102fd565b61013d610303565b604080516001600160e01b039092168252519081900360200190f35b610161610312565b005b61013d610497565b6101136104a6565b61017b6104ca565b6040805163ffffffff9092168252519081900360200190f35b6100cb6104d6565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614156102435760408051602081019091526003546001600160e01b031681526102289061022390846105d2565b610666565b71ffffffffffffffffffffffffffffffffffff1690506102f1565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316146102b35760405162461bcd60e51b8152600401808060200182810382526022815260200180610cd66022913960400191505060405180910390fd5b60408051602081019091526004546001600160e01b031681526102da9061022390846105d2565b71ffffffffffffffffffffffffffffffffffff1690505b92915050565b60005481565b60015481565b6004546001600160e01b031681565b60008060006103407f000000000000000000000000000000000000000000000000000000000000000061066d565b600254929550909350915063ffffffff9081168203907f000000000000000000000000000000000000000000000000000000000000000090821610156103b75760405162461bcd60e51b8152600401808060200182810382526027815260200180610cf86027913960400191505060405180910390fd5b60405180602001604052808263ffffffff166000548703816103d557fe5b046001600160e01b039081169091529051600380547fffffffff0000000000000000000000000000000000000000000000000000000016919092161790556040805160208101909152600154819063ffffffff84169086038161043457fe5b046001600160e01b039081169091529051600480547fffffffff000000000000000000000000000000000000000000000000000000001691909216179055506000929092556001556002805463ffffffff191663ffffffff909216919091179055565b6003546001600160e01b031681565b7f000000000000000000000000000000000000000000000000000000000000000081565b60025463ffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080600061050985856108a3565b604080516bffffffffffffffffffffffff19606094851b811660208084019190915293851b81166034830152825160288184030181526048830184528051908501207fff0000000000000000000000000000000000000000000000000000000000000060688401529a90941b9093166069840152607d8301989098527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f609d808401919091528851808403909101815260bd909201909752805196019590952095945050505050565b6105da610c65565b600082158061060057505082516001600160e01b0316828102908382816105fd57fe5b04145b610651576040805162461bcd60e51b815260206004820152601960248201527f4669786564506f696e743a3a6d756c3a206f766572666c6f7700000000000000604482015290519081900360640190fd5b60408051602081019091529081529392505050565b5160701c90565b600080600061067a610981565b9050836001600160a01b0316635909c0d56040518163ffffffff1660e01b815260040160206040518083038186803b1580156106b557600080fd5b505afa1580156106c9573d6000803e3d6000fd5b505050506040513d60208110156106df57600080fd5b5051604080517f5a3d549300000000000000000000000000000000000000000000000000000000815290519194506001600160a01b03861691635a3d549391600480820192602092909190829003018186803b15801561073e57600080fd5b505afa158015610752573d6000803e3d6000fd5b505050506040513d602081101561076857600080fd5b5051604080517f0902f1ac0000000000000000000000000000000000000000000000000000000081529051919350600091829182916001600160a01b03891691630902f1ac916004808301926060929190829003018186803b1580156107cd57600080fd5b505afa1580156107e1573d6000803e3d6000fd5b505050506040513d60608110156107f757600080fd5b5080516020820151604090920151909450909250905063ffffffff808216908516146108995780840363ffffffff81166108446dffffffffffffffffffffffffffff80861690871661098b565b600001516001600160e01b031602870196508063ffffffff16610887856dffffffffffffffffffffffffffff16856dffffffffffffffffffffffffffff1661098b565b516001600160e01b0316029590950194505b5050509193909250565b600080826001600160a01b0316846001600160a01b031614156108f75760405162461bcd60e51b8152600401808060200182810382526025815260200180610c8b6025913960400191505060405180910390fd5b826001600160a01b0316846001600160a01b03161061091757828461091a565b83835b90925090506001600160a01b03821661097a576040805162461bcd60e51b815260206004820152601e60248201527f556e697377617056324c6962726172793a205a45524f5f414444524553530000604482015290519081900360640190fd5b9250929050565b63ffffffff421690565b610993610c78565b600082116109d25760405162461bcd60e51b8152600401808060200182810382526026815260200180610cb06026913960400191505060405180910390fd5b826109ec57506040805160208101909152600081526102f1565b71ffffffffffffffffffffffffffffffffffff8311610a9357600082607085901b81610a1457fe5b0490506001600160e01b03811115610a73576040805162461bcd60e51b815260206004820152601e60248201527f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f770000604482015290519081900360640190fd5b6040518060200160405280826001600160e01b03168152509150506102f1565b6000610aaf846e01000000000000000000000000000085610b0d565b90506001600160e01b03811115610a73576040805162461bcd60e51b815260206004820152601e60248201527f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f770000604482015290519081900360640190fd5b6000806000610b1c8686610bc8565b9150915060008480610b2a57fe5b868809905082811115610b3e576001820391505b918290039181610b5c57848381610b5157fe5b049350505050610bc1565b848210610bb0576040805162461bcd60e51b815260206004820152601a60248201527f46756c6c4d6174683a2046554c4c4449565f4f564552464c4f57000000000000604482015290519081900360640190fd5b610bbb838387610bf5565b93505050505b9392505050565b6000808060001984860990508385029250828103915082811015610bed576001820391505b509250929050565b60008181038216808381610c0557fe5b049250808581610c1157fe5b049450808160000381610c2057fe5b60028581038087028203028087028203028087028203028087028203028087028203028087028203029586029003909402930460010193909302939093010292915050565b6040518060200160405280600081525090565b6040805160208101909152600081529056fe556e697377617056324c6962726172793a204944454e544943414c5f4144445245535345534669786564506f696e743a3a6672616374696f6e3a206469766973696f6e206279207a65726f4578616d706c654f7261636c6553696d706c653a20494e56414c49445f544f4b454e4578616d706c654f7261636c6553696d706c653a20504552494f445f4e4f545f454c4150534544a2646970667358221220ac393c028bf6973c2544a4a8543b95c97b1eb6818652fef0b6964dd0b89461f964736f6c63430007020033556e697377617056324c6962726172793a204944454e544943414c5f41444452455353455343757272656e7420636f6e74726163742069732077697468696e206d61696e7461696e616e6365206d617267696e2c20736f20796f752063616e6e6f742072756e2074686973436f6465204572726f7220696620796f752072656163686564207468697320706f696e7443757272656e742076657273696f6e206c696d697473206d617820616d6f756e74206f66207653504143455820706f737369626c6544656e792055706461746520326e6472792054696d653a20596f7520617265206e6f74206f7261636c65596f752063616e6e6f742070726f76696465206d6f72652076535041434558207468616e207653504143455844656274206f75747374616e64696e67596f757220696e697469616c206d617267696e20697320696e73756666696369656e7420666f72206c656e64696e67496e697469616c206d617267696e206e6f7420656e6f75676820746f207769746864726177536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7743616e6e6f74206368616c6c656e676520616674657220475320436c6f7365732e5468697320435456206973206e6f742061626f76652077617465722c2063616e6e6f7420636f6e7665727450726f74656374697665206d617820626f756e6420666f7220696e707574206869744d7573742072756e2074686973206f6e206120706f73697469766520696e7465676572446973616c6c6f7765643a20596f7520617265206e6f7420676f7665726e616e636550726f74656374697665206d617820626f756e6420666f722075696e7420617267756d656e74a26469706673582212209503dbec12b1f27800ab211d29ab31a4316e03c34feea8b23b58e20764f7036e64736f6c6343000702003360806040523480156200001157600080fd5b50604051620010f1380380620010f1833981810160405260408110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b50604052505082518391508290620001b8906003906020850190620001fa565b508051620001ce906004906020840190620001fa565b505060058054601260ff1990911617610100600160a81b03191661010033021790555062000296915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200023d57805160ff19168380011785556200026d565b828001600101855582156200026d579182015b828111156200026d57825182559160200191906001019062000250565b506200027b9291506200027f565b5090565b5b808211156200027b576000815560010162000280565b610e4b80620002a66000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80635e5ea32711610097578063a457c2d711610066578063a457c2d7146102ee578063a9059cbb1461031a578063c000178614610346578063dd62ed3e14610372576100f5565b80635e5ea3271461027f57806370a082311461029c5780638da5cb5b146102c257806395d89b41146102e6576100f5565b806323b872dd116100d357806323b872dd146101d1578063313ce567146102075780633950935114610225578063484b973c14610251576100f5565b806306fdde03146100fa578063095ea7b31461017757806318160ddd146101b7575b600080fd5b6101026103a0565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561013c578181015183820152602001610124565b50505050905090810190601f1680156101695780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101a36004803603604081101561018d57600080fd5b506001600160a01b038135169060200135610436565b604080519115158252519081900360200190f35b6101bf610453565b60408051918252519081900360200190f35b6101a3600480360360608110156101e757600080fd5b506001600160a01b03813581169160208101359091169060400135610459565b61020f6104e0565b6040805160ff9092168252519081900360200190f35b6101a36004803603604081101561023b57600080fd5b506001600160a01b0381351690602001356104e9565b61027d6004803603604081101561026757600080fd5b506001600160a01b038135169060200135610537565b005b61027d6004803603602081101561029557600080fd5b50356105a9565b6101bf600480360360208110156102b257600080fd5b50356001600160a01b03166105b6565b6102ca6105d1565b604080516001600160a01b039092168252519081900360200190f35b6101026105e5565b6101a36004803603604081101561030457600080fd5b506001600160a01b038135169060200135610646565b6101a36004803603604081101561033057600080fd5b506001600160a01b0381351690602001356106ae565b61027d6004803603604081101561035c57600080fd5b506001600160a01b0381351690602001356106c2565b6101bf6004803603604081101561038857600080fd5b506001600160a01b0381358116916020013516610730565b60038054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561042c5780601f106104015761010080835404028352916020019161042c565b820191906000526020600020905b81548152906001019060200180831161040f57829003601f168201915b5050505050905090565b600061044a61044361075b565b848461075f565b50600192915050565b60025490565b600061046684848461084b565b6104d68461047261075b565b6104d185604051806060016040528060288152602001610d5f602891396001600160a01b038a166000908152600160205260408120906104b061075b565b6001600160a01b0316815260208101919091526040016000205491906109a6565b61075f565b5060019392505050565b60055460ff1690565b600061044a6104f661075b565b846104d1856001600061050761075b565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610a3d565b60055461010090046001600160a01b0316331461059b576040805162461bcd60e51b815260206004820152601360248201527f4f6e6c79206f776e6572206d6179206d696e7400000000000000000000000000604482015290519081900360640190fd5b6105a58282610a9e565b5050565b6105b33382610b8e565b50565b6001600160a01b031660009081526020819052604090205490565b60055461010090046001600160a01b031681565b60048054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561042c5780601f106104015761010080835404028352916020019161042c565b600061044a61065361075b565b846104d185604051806060016040528060258152602001610df1602591396001600061067d61075b565b6001600160a01b03908116825260208083019390935260409182016000908120918d168152925290205491906109a6565b600061044a6106bb61075b565b848461084b565b60055461010090046001600160a01b03163314610726576040805162461bcd60e51b815260206004820152601f60248201527f4f6e6c79206f776e6572206d6179206275726e20746869726420706172747900604482015290519081900360640190fd5b6105a58282610b8e565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b3390565b6001600160a01b0383166107a45760405162461bcd60e51b8152600401808060200182810382526024815260200180610dcd6024913960400191505060405180910390fd5b6001600160a01b0382166107e95760405162461bcd60e51b8152600401808060200182810382526022815260200180610d176022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0383166108905760405162461bcd60e51b8152600401808060200182810382526025815260200180610da86025913960400191505060405180910390fd5b6001600160a01b0382166108d55760405162461bcd60e51b8152600401808060200182810382526023815260200180610cd26023913960400191505060405180910390fd5b6108e0838383610c8a565b61091d81604051806060016040528060268152602001610d39602691396001600160a01b03861660009081526020819052604090205491906109a6565b6001600160a01b03808516600090815260208190526040808220939093559084168152205461094c9082610a3d565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610a355760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156109fa5781810151838201526020016109e2565b50505050905090810190601f168015610a275780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610a97576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610af9576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610b0560008383610c8a565b600254610b129082610a3d565b6002556001600160a01b038216600090815260208190526040902054610b389082610a3d565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b038216610bd35760405162461bcd60e51b8152600401808060200182810382526021815260200180610d876021913960400191505060405180910390fd5b610bdf82600083610c8a565b610c1c81604051806060016040528060228152602001610cf5602291396001600160a01b03851660009081526020819052604090205491906109a6565b6001600160a01b038316600090815260208190526040902055600254610c429082610c8f565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b505050565b6000610a9783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506109a656fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212204b90338f83fcf36a387fe8b20581a5a06f9bed47123e67a20643af9510dac9e064736f6c63430007020033

Deployed ByteCode Sourcemap

330:28607:21:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9961:1;9949:9;:13;9941:50;;;;;-1:-1:-1;;;9941:50:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;10115:10;10106:20;;;;:8;:20;;;;;;:37;;10132:9;10106:24;:37::i;:::-;10092:10;10083:20;;;;:8;:20;;;;;;;;:60;;;;10167:19;:31;;;;;;:39;;:31;:39;10164:197;;10280:10;10260:31;;;;:19;:31;;;;;:38;;-1:-1:-1;;10260:38:21;10294:4;10260:38;;;;;;10313:19;:36;;;;;;;;;;;;;;-1:-1:-1;;;;;;10313:36:21;;;;;;10164:197;330:28607;;;;;21240:1914;;;;;;;;;;;;;;;;-1:-1:-1;21240:1914:21;;:::i;5904:366::-;;;;;;;;;;;;;:::i;7321:458::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7321:458:21;;:::i;8364:186::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8364:186:21;;:::i;8562:165::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8562:165:21;-1:-1:-1;;;;;8562:165:21;;:::i;13273:1454::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13273:1454:21;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8174:178;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8174:178:21;;:::i;2343:41::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;4070:40;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4070:40:21;-1:-1:-1;;;;;4070:40:21;;:::i;3028:37::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;3834:51;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3834:51:21;-1:-1:-1;;;;;3834:51:21;;:::i;1217:55::-;;;;;;;;;;;;;:::i;8920:186::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8920:186:21;;:::i;28492:434::-;;;;;;;;;;;;;:::i;6404:451::-;;;;;;;;;;;;;:::i;1892:50::-;;;;;;;;;;;;;:::i;2481:41::-;;;;;;;;;;;;;:::i;6892:417::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6892:417:21;;;;;;;:::i;5410:63::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5410:63:21;-1:-1:-1;;;;;5410:63:21;;:::i;3314:45::-;;;;;;;;;;;;;:::i;10376:1014::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10376:1014:21;;:::i;3163:44::-;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;3163:44:21;;;;;;;;;;;;;;27769:705;;;;;;;;;;;;;:::i;3936:36::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3936:36:21;;:::i;12546:697::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12546:697:21;;:::i;26807:944::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26807:944:21;;:::i;622:98::-;;;;;;;;;;;;;:::i;1148:42::-;;;;;;;;;;;;;:::i;1544:29::-;;;;;;;;;;;;;:::i;2988:32::-;;;;;;;;;;;;;:::i;727:87::-;;;;;;;;;;;;;:::i;26266:529::-;;;;;;;;;;;;;:::i;2899:38::-;;;;;;;;;;;;;:::i;4194:46::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4194:46:21;-1:-1:-1;;;;;4194:46:21;;:::i;8739:169::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8739:169:21;-1:-1:-1;;;;;8739:169:21;;:::i;23179:2786::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;23179:2786:21;;;;;;;;:::i;1414:28::-;;;;;;;;;;;;;:::i;3214:40::-;;;;;;;;;;;;;:::i;3261:::-;;;;;;;;;;;;;:::i;3464:30::-;;;;;;;;;;;;;:::i;454:31::-;;;;;;;;;;;;;:::i;3366:39::-;;;;;;;;;;;;;:::i;3412:::-;;;;;;;;;;;;;:::i;14751:4669::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14751:4669:21;;;;;;-1:-1:-1;;;;;14751:4669:21;;:::i;19432:1774::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;19432:1774:21;;;;;;;;:::i;1999:37::-;;;;;;;;;;;;;:::i;2205:41::-;;;;;;;;;;;;;:::i;3501:28::-;;;;;;;;;;;;;:::i;9406:461::-;;;:::i;887:87::-;;;;;;;;;;;;;:::i;8009:147::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8009:147:21;;:::i;9118:234::-;;;;;;;;;;;;;:::i;1372:29::-;;;;;;;;;;;;;:::i;7822:175::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7822:175:21;;:::i;1075:45::-;;;;;;;;;;;;;:::i;11408:1126::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11408:1126:21;;:::i;2944:37::-;;;;;;;;;;;;;:::i;324:181:18:-;382:7;414:5;;;438:6;;;;430:46;;;;;-1:-1:-1;;;430:46:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;496:1;-1:-1:-1;324:181:18;;;;;:::o;21240:1914:21:-;21414:17;;;;:26;21405:73;;;;-1:-1:-1;;;21405:73:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21726:10;21707:30;;;;:18;:30;;;;;:35;21694:48;;21686:72;;;;;-1:-1:-1;;;21686:72:21;;;;;;;;;;;;-1:-1:-1;;;21686:72:21;;;;;;;;;;;;;;;21847:10;21828:30;;;;:18;:30;;;;;:42;;:53;;21871:9;;21828:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:62;21820:86;;;;;-1:-1:-1;;;21820:86:21;;;;;;;;;;;;-1:-1:-1;;;21820:86:21;;;;;;;;;;;;;;;21980:10;21961:30;;;;:18;:30;;;;;:46;;:57;;22008:9;;21961:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:66;21953:90;;;;;-1:-1:-1;;;21953:90:21;;;;;;;;;;;;-1:-1:-1;;;21953:90:21;;;;;;;;;;;;;;;22213:10;22194:30;;;;:18;:30;;;;;:51;;:62;;22118:154;;22263:8;;22118:140;;22194:51;22246:9;;22194:62;;;;;;;;;;;;;;;;;;22137:10;22118:30;;:18;:30;;;;;;;:59;;:70;;22178:9;;22118:70;;;;;;;;;;;;;;:74;;:140;;;;:::i;:::-;:144;;:154::i;:::-;22103:9;:170;;22095:195;;;;;-1:-1:-1;;;22095:195:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;22520:10;22560:1;22501:30;;;:18;:30;;;;;:45;;:56;;22547:9;;22501:56;;;;;;;;;;;;;;:60;22492:84;;;;;-1:-1:-1;;;22492:84:21;;;;;;;;;;;;-1:-1:-1;;;22492:84:21;;;;;;;;;;;;;;;22615:10;22661:1;22596:30;;;:18;:30;;;;;:51;;:62;;22648:9;;22596:62;;;;;;;;;;;;;;:66;22587:90;;;;;-1:-1:-1;;;22587:90:21;;;;;;;;;;;;-1:-1:-1;;;22587:90:21;;;;;;;;;;;;;;;22716:10;22697:30;;;;:18;:30;;;;;:46;;:57;;22744:9;;22697:57;;;;;;;;;;;;;;22758:1;22697:62;22688:85;;;;;-1:-1:-1;;;22688:85:21;;;;;;;;;;;;-1:-1:-1;;;22688:85:21;;;;;;;;;;;;;;;23021:10;23002:30;;;;:18;:30;;;;;:46;;:57;;23062:4;;23002:46;23049:9;;23002:57;;;;;;;;;;;;;;;;;;;;;;:64;;;;;;;;;;;;;;;;;;23137:9;23077:18;:30;23096:10;-1:-1:-1;;;;;23077:30:21;-1:-1:-1;;;;;23077:30:21;;;;;;;;;;;;:46;;23124:9;23077:57;;;;;;;;;;;;;;;;;:69;-1:-1:-1;21240:1914:21:o;5904:366::-;5969:5;;-1:-1:-1;;;;;5969:5:21;5955:10;:19;5947:60;;;;;-1:-1:-1;;;5947:60:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;6026:20;;;;:29;6018:63;;;;;-1:-1:-1;;;6018:63:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;6092:20;:27;;-1:-1:-1;;6092:27:21;6115:4;6092:27;;;:20;6225:12;6160:92;;677:42;;771;;-1:-1:-1;;;;;6225:12:21;;;;1183:7;;6160:92;;;:::i;:::-;;;-1:-1:-1;;;;;6160:92:21;;;;;;-1:-1:-1;;;;;6160:92:21;;;;;;-1:-1:-1;;;;;6160:92:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6140:17;;:112;;;;;-1:-1:-1;;;;;6140:112:21;;;;;-1:-1:-1;;;;;6140:112:21;;;;;;5904:366::o;7321:458::-;7435:6;;-1:-1:-1;;;;;7435:6:21;7421:10;:20;7413:59;;;;;-1:-1:-1;;;7413:59:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;7483:22;:48;;;7562:17;;:43;-1:-1:-1;7561:90:21;;7629:22;;7561:90;;;7609:17;;7561:90;7542:16;:109;7703:22;;7682:17;;:43;7681:90;;7754:17;;7681:90;;;7729:22;;7681:90;7662:16;:109;-1:-1:-1;7321:458:21:o;8364:186::-;8457:5;;-1:-1:-1;;;;;8457:5:21;8443:10;:19;8435:66;;;;-1:-1:-1;;;8435:66:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8512:13;:30;8364:186::o;8562:165::-;8650:5;;-1:-1:-1;;;;;8650:5:21;8636:10;:19;8628:66;;;;-1:-1:-1;;;8628:66:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8705:5;:14;;-1:-1:-1;;;;;;8705:14:21;-1:-1:-1;;;;;8705:14:21;;;;;;;;;;8562:165::o;13273:1454::-;13341:16;13359:13;13374;13389:4;13470:1;13458:9;:13;13450:61;;;;-1:-1:-1;;;13450:61:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13522:38;13577:9;13563:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13563:24:21;;13522:65;;13598:24;13636:9;13625:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13625:21:21;;13598:48;;13657:24;13695:9;13684:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13684:21:21;;13657:48;;13726:6;13781;13776:877;13793:19;:26;13791:28;;13776:877;;;13954:9;13950:1;:13;13947:110;;14036:5;;13947:110;14206:14;14223:60;14266:16;;14223:14;:38;14238:19;14258:1;14238:22;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14238:22:21;14223:38;;;;;;;;;;;;;;:42;:60::i;:::-;14206:77;;14298:14;14316:65;14373:7;14316:51;14354:11;;14316:8;:32;14325:19;14345:1;14325:22;;;;;;;14316:51;:55;;:65::i;:::-;14298:83;;14427:9;14415;:21;14410:232;;;14486:19;14506:1;14486:22;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14486:22:21;14459:21;14481:1;14459:24;;;;;;;;;;;;;:49;-1:-1:-1;;;;;14459:49:21;;;-1:-1:-1;;;;;14459:49:21;;;;;14543:9;14527:10;14538:1;14527:13;;;;;;;;;;;;;:25;;;;;14587:9;14571:10;14582:1;14571:13;;;;;;;;;;;;;:25;;;;;14621:1;14625;14621:5;14617:9;;14410:232;-1:-1:-1;;13821:3:21;;13776:877;;;-1:-1:-1;14670:21:21;;14693:10;;-1:-1:-1;14693:10:21;-1:-1:-1;14670:21:21;;-1:-1:-1;13273:1454:21;-1:-1:-1;;13273:1454:21:o;8174:178::-;8263:5;;-1:-1:-1;;;;;8263:5:21;8249:10;:19;8241:66;;;;-1:-1:-1;;;8241:66:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8318:11;:26;8174:178::o;2343:41::-;;;;:::o;4070:40::-;;;;;;;;;;;;;:::o;3028:37::-;;;;;;:::o;3834:51::-;;;;;;;;;;;;;;;:::o;1217:55::-;1265:7;1217:55;:::o;8920:186::-;9013:5;;-1:-1:-1;;;;;9013:5:21;8999:10;:19;8991:66;;;;-1:-1:-1;;;8991:66:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9068:13;:30;8920:186::o;28492:434::-;28670:5;;-1:-1:-1;;;;;28670:5:21;28656:10;:19;28648:28;;;;;;28703:11;28687:13;:27;28759:11;28745;:25;28820:12;28804:13;:28;28870:6;:19;;-1:-1:-1;;;;;;28870:19:21;;;;;;-1:-1:-1;28900:18:21;;;;;;;28492:434::o;6404:451::-;6450:17;;;;;;;;;-1:-1:-1;;;;;6450:17:21;-1:-1:-1;;;;;6450:24:21;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6507:17:21;;6541:12;;6507:58;;;;;;-1:-1:-1;;;;;6541:12:21;;;6507:58;;;;6556:8;6507:58;;;;;;:17;;;;;;;;-1:-1:-1;6507:25:21;;-1:-1:-1;6507:58:21;;;;;;;;;;;;;;;:17;:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6507:58:21;6487:17;:78;;;6659:22;;-1:-1:-1;6637:90:21;;6705:22;;6637:90;;;6685:17;;6637:90;6618:16;:109;6779:22;;6758:17;;:43;6757:90;;6830:17;;6757:90;;;6805:22;;6757:90;6738:16;:109;6404:451::o;1892:50::-;;;;:::o;2481:41::-;;;;:::o;6892:417::-;7017:6;;-1:-1:-1;;;;;7017:6:21;7003:10;:20;6995:75;;;;-1:-1:-1;;;6995:75:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7114:17;7091:19;:40;;7090:86;;;;;7160:15;7139:17;:36;;7090:86;7081:112;;;;;-1:-1:-1;;;7081:112:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;7214:18;:40;;;;7265:16;:36;6892:417::o;5410:63::-;;;;;;;;;;;;;:::o;3314:45::-;;;;:::o;10376:1014::-;10563:8;10548:12;:23;10539:75;;;;-1:-1:-1;;;10539:75:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10897:16;;10880:10;10854:8;10865:26;;;:14;:26;;;;;;10854:8;;10865:66;;10921:8;;10865:50;;:26;:30;:50::i;:66::-;11063:13;;11025:10;11004:8;11016:20;;;:8;:20;;;;;;10854:77;;-1:-1:-1;11004:8:21;11015:79;;11084:8;;11015:63;;11063:13;11015:63;;11042:12;11016:24;:40::i;11015:79::-;11004:90;;11122:3;11115;:10;;11105:62;;;;-1:-1:-1;;;11105:62:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11256:10;11247:20;;;;:8;:20;;;;;;:40;;11273:12;11247:24;:40::i;:::-;11233:10;11224:20;;;;:8;:20;;;;;;:63;;;;11349:33;;11233:10;;11349:33;;;;;11369:12;;11349:33;11224:20;11349:33;11369:12;11233:10;11349:33;;;;;;;;;;;;;;;;;;;;;10376:1014;;;:::o;3163:44::-;;;;;;-1:-1:-1;;;;;3163:44:21;;:::o;27769:705::-;27922:17;;;;27914:26;;;;;;28008:20;;27991:10;27961:12;27976:26;;;:14;:26;;;;;;27961:12;;27976:78;;28051:1;;27976:69;;28036:8;;27976:54;;:26;:30;:54::i;:69::-;:73;;:78::i;:::-;28130:10;28121:20;;;;:8;:20;;;;;;27961:93;;-1:-1:-1;28121:30:21;-1:-1:-1;28113:86:21;;;;-1:-1:-1;;;28113:86:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28251:10;28225:14;28242:20;;;:8;:20;;;;;;;;;;28358:14;:26;;;;;:30;;;28399:20;;;;:24;;;;28434:30;28242;;;;;28251:10;28434:30;;;;;28242;;28434;28225:14;28434:30;28242;28251:10;28434:30;;;;;;;;;;;;;;;;;;;;;27769:705;;:::o;3936:36::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3936:36:21;;-1:-1:-1;3936:36:21;:::o;12546:697::-;12636:8;12617:16;:27;12609:78;;;;-1:-1:-1;;;12609:78:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13015:12;;;:52;;;-1:-1:-1;;;13015:52:21;;13038:10;13015:52;;;;;;;;;;;;-1:-1:-1;;;;;13015:12:21;;;;:22;;:52;;;;;;;;;;:12;;:52;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;13122:10:21;13107:26;;;;:14;:26;;;;;;:50;;-1:-1:-1;13107:26:21;-1:-1:-1;13139:16:21;13107:30;:50::i;:::-;13093:10;13078:26;;;;:14;:26;;;;;:79;13192:21;;:43;;13218:16;13192:25;:43::i;:::-;13168:21;:67;-1:-1:-1;12546:697:21:o;26807:944::-;26976:17;;;;26968:26;;;;;;27041:8;27013:25;:36;27005:83;;;;-1:-1:-1;;;27005:83:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27109:16;27128:68;27187:8;27128:53;27159:20;;27128:25;:29;;:53;;;;:::i;:68::-;27498:12;;;:61;;;-1:-1:-1;;;27498:61:21;;27521:10;27498:61;;;;;;;;;;;;27109:87;;-1:-1:-1;;;;;;27498:12:21;;;;:22;;:61;;;;;:12;;:61;;;;;;:12;;:61;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;27643:32:21;;:10;;-1:-1:-1;27643:32:21;;;;;-1:-1:-1;27663:11:21;;27643:32;;;;27663:11;27643:10;:32;;;;;;;;;;;;;;;;;;;622:98;677:42;622:98;:::o;1148:42::-;1183:7;1148:42;:::o;1544:29::-;;;-1:-1:-1;;;;;1544:29:21;;:::o;2988:32::-;;;;:::o;727:87::-;771:42;727:87;:::o;26266:529::-;26367:18;;;;26359:56;;;;;-1:-1:-1;;;26359:56:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;1265:7;26453:25;;:52;26434:15;:72;26426:107;;;;;-1:-1:-1;;;26426:107:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;26553:17;;;;26552:18;26544:56;;;;;-1:-1:-1;;;26544:56:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;26634:22;;26611:20;:45;26763:17;:24;;-1:-1:-1;;26763:24:21;26783:4;26763:24;;;26266:529::o;2899:38::-;;;;;;:::o;4194:46::-;;;;;;;;;;;;;:::o;8739:169::-;8829:5;;-1:-1:-1;;;;;8829:5:21;8815:10;:19;8807:66;;;;-1:-1:-1;;;8807:66:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8884:6;:16;;-1:-1:-1;;;;;;8884:16:21;-1:-1:-1;;;;;8884:16:21;;;;;;;;;;8739:169::o;23179:2786::-;-1:-1:-1;;;;;23516:32:21;;;;;;:18;:32;;;;;:37;23503:50;;23495:74;;;;;-1:-1:-1;;;23495:74:21;;;;;;;;;;;;-1:-1:-1;;;23495:74:21;;;;;;;;;;;;;;;-1:-1:-1;;;;;23650:32:21;;;;;;:18;:32;;;;;:48;;:59;;23699:9;;23650:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:67;;23713:4;23650:67;;;23641:92;;;;;-1:-1:-1;;;23641:92:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;23787:32:21;;;;;;:18;:32;;;;;:44;;:55;;23832:9;;23787:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:64;23778:89;;;;;-1:-1:-1;;;23778:89:21;;;;;;;;;;;;-1:-1:-1;;;23778:89:21;;;;;;;;;;;;;;;23937:17;;;;23934:341;;-1:-1:-1;;;;;24104:32:21;;;;;;:18;:32;;;;;:45;;:56;;24150:9;;24104:56;;;;;;;;;;;;;;24083:18;;:77;24074:102;;;;;-1:-1:-1;;;24074:102:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;24332:32:21;;24393:1;24332:32;;;:18;:32;;;;;:47;;:58;;24380:9;;24332:58;;;;;;;;;;;;;;:62;24323:86;;;;;-1:-1:-1;;;24323:86:21;;;;;;;;;;;;-1:-1:-1;;;24323:86:21;;;;;;;;;;;;;;;-1:-1:-1;;;;;24429:32:21;;24496:1;24429:32;;;:18;:32;;;;;:53;;:64;;24483:9;;24429:64;;;;;;;;;;;;;;:68;24420:91;;;;;-1:-1:-1;;;24420:91:21;;;;;;;;;;;;-1:-1:-1;;;24420:91:21;;;;;;;;;;;;;;;-1:-1:-1;;;;;24532:32:21;;;;;;:18;:32;;;;;:45;;:56;;24608:15;;1112:8;;24578:9;;24532:56;;;;;;;;;;;;;;:73;:91;24523:115;;;;;-1:-1:-1;;;24523:115:21;;;;;;;;;;;;-1:-1:-1;;;24523:115:21;;;;;;;;;;;;;;;-1:-1:-1;;;;;24942:32:21;;24865:13;24942:32;;;:18;:32;;;;;:48;;:59;;24991:9;;24942:59;;;;;;;;;;;;;;24881:18;:32;24900:12;-1:-1:-1;;;;;24881:32:21;-1:-1:-1;;;;;24881:32:21;;;;;;;;;;;;:47;;24929:9;24881:58;;;;;;;;;;;;;;;;:120;24865:136;;25073:1;25012:18;:32;25031:12;-1:-1:-1;;;;;25012:32:21;-1:-1:-1;;;;;25012:32:21;;;;;;;;;;;;:47;;25060:9;25012:58;;;;;;;;;;;;;;;;;;;:62;;;;-1:-1:-1;;;;;25085:32:21;;;;:18;:32;;;;;;:48;;:59;;25134:9;;25085:59;;;;;;;;;;;;;;;;;:63;;;;-1:-1:-1;;;;;25215:32:21;;;;:18;:32;;;;;;:48;;:59;;25264:9;;25215:59;;;;;;;;;;;;;;;;;;;;;;:67;;;;;;;;;;;;;;;;;;25351:4;25293:18;:32;25312:12;-1:-1:-1;;;;;25293:32:21;-1:-1:-1;;;;;25293:32:21;;;;;;;;;;;;:44;;25338:9;25293:55;;;;;;;;;;;;;;;;;;;;;;;;:62;;;;;;;;;;;;;;;;;;25444:18;:32;25463:12;-1:-1:-1;;;;;25444:32:21;-1:-1:-1;;;;;25444:32:21;;;;;;;;;;;;:61;;25506:9;25444:72;;;;;;;;;;;;;;;;25415:22;;25440:1;25415:26;:101;25411:547;;;-1:-1:-1;;;;;25735:22:21;;;;;;:8;:22;;;;;;25721:38;;:8;;:12;:38::i;:::-;-1:-1:-1;;;;;25696:22:21;;;;;;:8;:22;;;;;:63;25411:547;;;-1:-1:-1;;;;;25871:32:21;;;;;;:18;:32;;;;;:43;;:54;;25915:9;;25871:54;;;;;;;;;;;;;;;:75;;-1:-1:-1;;;;;25871:54:21;;;;:75;;;;;25936:8;;25871:75;:54;:75;25936:8;25871:54;:75;;;;;;;;;;;;;;;;;;;1414:28;;;-1:-1:-1;;;;;1414:28:21;;:::o;3214:40::-;;;;:::o;3261:::-;;;;;;:::o;3464:30::-;;;;:::o;454:31::-;;;-1:-1:-1;;;;;454:31:21;;:::o;3366:39::-;;;;:::o;3412:::-;;;;:::o;14751:4669::-;15032:17;;14855:4;;15032:17;;:26;15023:67;;;;;-1:-1:-1;;;15023:67:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;15336:30:21;;;;;;:14;:30;;;;;;15313:53;;;15304:127;;;;-1:-1:-1;;;15304:127:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15724:16;;-1:-1:-1;;;;;15688:30:21;;15677:8;15688:30;;;:14;:30;;;;;;15677:8;;15688:69;;15748:8;;15688:54;;:30;:34;:54::i;:69::-;15809:11;;-1:-1:-1;;;;;15779:24:21;;15768:8;15779:24;;;:8;:24;;;;;;15677:80;;-1:-1:-1;15768:8:21;15779:58;;15828:8;;15779:43;;:28;:43::i;:58::-;15768:69;;15862:3;15856;:9;15848:92;;;;-1:-1:-1;;;15848:92:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;16222:24:21;;16210:9;16222:24;;;:8;:24;;;;;;:55;;16268:8;;16222:40;;16252:8;16222:28;:40::i;:55::-;16210:67;;16288:9;16300:90;16360:29;16379:8;16360:13;;:17;;:29;;;;:::i;:::-;16336:16;;-1:-1:-1;;;;;16300:30:21;;;;;;:14;:30;;;;;;:54;;:34;:54::i;:90::-;16288:102;;16411:13;16446:4;16439;:11;16435:514;;;-1:-1:-1;;;;;16660:30:21;;;;;;:14;:30;;;;;;;;;16628:8;:24;;;;;;;16603:89;;16660:30;16603:51;;:19;;:23;:51::i;:89::-;16592:100;;16435:514;;;16826:111;16927:8;16826:95;16911:8;16826:79;16875:29;16894:8;16875:13;;:17;;:29;;;;:::i;:::-;16851:16;;16826:43;;:19;;:23;:43::i;:111::-;16815:122;;16435:514;-1:-1:-1;;;;;16979:24:21;;;;;;:8;:24;;;;;;16967:36;;;16959:85;;;;-1:-1:-1;;;16959:85:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17260:12;;;:55;;;-1:-1:-1;;;17260:55:21;;17283:10;17260:55;;;;;;;;;;;;-1:-1:-1;;;;;17260:12:21;;;;:22;;:55;;;;;;;;;;:12;;:55;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;17407:30:21;;;;;;:14;:30;;;;;;:57;;-1:-1:-1;17443:19:21;17407:34;:57::i;:::-;-1:-1:-1;;;;;17374:30:21;;;;;;:14;:30;;;;;:90;17499:21;;:48;;17526:19;17499:25;:48::i;:::-;17475:21;:72;-1:-1:-1;;;;;17674:24:21;;;;;;:8;:24;;;;;;:40;;17704:8;17674:28;:40::i;:::-;-1:-1:-1;;;;;17647:24:21;;;;;;:8;:24;;;;;:67;17774:16;;17748:22;;:42;17745:1668;;;17883:31;;:10;;:31;;;;;17904:8;;17883:31;;;;17904:8;17883:10;:31;;;;;;;;;;;;;;;;;;;;;17936:8;17929:15;;;;;;;;;17745:1668;-1:-1:-1;;;;;18079:34:21;;18070:6;18079:34;;;:18;:34;;;;;:39;18239:48;18079:39;18284:1;18239:43;:48::i;:::-;-1:-1:-1;;;;;18197:34:21;;;;;;:18;:34;;;;;;;:90;;;18308:49;;;;:64;;;;;;;;;;;;;;;;;;18445:55;;;:81;;;;;;;;;;;;;;;;;18594:47;;;:69;;;;;;;;;;;;;18647:15;18594:69;;;18800:17;;18731:63;;;:87;;;;;;;;;;;;;;;18869:50;;;:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19016:50;;;:58;;;;;;;;;;;;;;;;;19188:45;;;:62;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;19188:62:21;19239:10;19188:62;;;19262:46;;;;:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19339:1;-1:-1:-1;19332:8:21;;-1:-1:-1;;;;19332:8:21;19432:1774;-1:-1:-1;;;;;19715:32:21;;;;;;:18;:32;;;;;:37;19702:50;;19694:74;;;;;-1:-1:-1;;;19694:74:21;;;;;;;;;;;;-1:-1:-1;;;19694:74:21;;;;;;;;;;;;;;;-1:-1:-1;;;;;19831:32:21;;;;;;:18;:32;;;;;:43;;:54;;19875:9;;19831:54;;;;;;;;;;;;;;;;-1:-1:-1;;;;;19831:54:21;19817:10;:68;19809:93;;;;;-1:-1:-1;;;19809:93:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;19949:32:21;;;;;;:18;:32;;;;;:45;;:56;;20024:15;;1112:8;;19995:9;;19949:56;;;;;;;;;;;;;;:72;:90;19941:113;;;;;-1:-1:-1;;;19941:113:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;20121:32:21;;;;;;:18;:32;;;;;:48;;:59;;20170:9;;20121:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:68;20113:92;;;;;-1:-1:-1;;;20113:92:21;;;;;;;;;;;;-1:-1:-1;;;20113:92:21;;;;;;;;;;;;;;;-1:-1:-1;;;;;20250:32:21;;;;;;:18;:32;;;;;:44;;:55;;20295:9;;20250:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:64;20242:88;;;;;-1:-1:-1;;;20242:88:21;;;;;;;;;;;;-1:-1:-1;;;20242:88:21;;;;;;;;;;;;;;;-1:-1:-1;;;;;20419:32:21;;20480:1;20419:32;;;:18;:32;;;;;:47;;:58;;20467:9;;20419:58;;;;;;;;;;;;;;:62;20410:85;;;;;-1:-1:-1;;;20410:85:21;;;;;;;;;;;;-1:-1:-1;;;20410:85:21;;;;;;;;;;;;;;;-1:-1:-1;;;;;20515:32:21;;20582:1;20515:32;;;:18;:32;;;;;:53;;:64;;20569:9;;20515:64;;;;;;;;;;;;;;:68;20506:91;;;;;-1:-1:-1;;;20506:91:21;;;;;;;;;;;;-1:-1:-1;;;20506:91:21;;;;;;;;;;;;;;;-1:-1:-1;;;;;20617:32:21;;;;;;:18;:32;;;;;:48;;:59;;20666:9;;20617:59;;;;;;;;;;;;;;20680:1;20617:64;20608:87;;;;;-1:-1:-1;;;20608:87:21;;;;;;;;;;;;-1:-1:-1;;;20608:87:21;;;;;;;;;;;;;;;-1:-1:-1;;;;;20809:32:21;;;;;;:18;:32;;;;;:44;;:55;;20867:4;;20809:44;20854:9;;20809:55;;;;;;;;;;;;;;;;;;;;;;:62;;;;;;;;;;;;;;;;;;20925:13;20941:18;:32;20960:12;-1:-1:-1;;;;;20941:32:21;-1:-1:-1;;;;;20941:32:21;;;;;;;;;;;;:47;;20989:9;20941:58;;;;;;;;;;;;;;;;20925:74;;21071:1;21010:18;:32;21029:12;-1:-1:-1;;;;;21010:32:21;-1:-1:-1;;;;;21010:32:21;;;;;;;;;;;;:47;;21058:9;21010:58;;;;;;;;;;;;;;;;;;;:62;;;;-1:-1:-1;;;;;21123:32:21;;;;:18;:32;;;;;;:43;;:54;;21167:9;;21123:54;;;;;1999:37;;;;:::o;2205:41::-;;;;:::o;3501:28::-;;;;:::o;9406:461::-;9540:1;9528:9;:13;9520:50;;;;;-1:-1:-1;;;9520:50:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;9614:10;9605:20;;;;:8;:20;;;;;;:37;;9631:9;9605:24;:37::i;:::-;9591:10;9582:20;;;;:8;:20;;;;;;;;:60;;;;9666:19;:31;;;;;;:39;;:31;:39;9663:197;;9779:10;9759:31;;;;:19;:31;;;;;:38;;-1:-1:-1;;9759:38:21;9793:4;9759:38;;;;;;9812:19;:36;;;;;;;;;;;;;;-1:-1:-1;;;;;;9812:36:21;;;;;;9663:197;9406:461::o;887:87::-;;;-1:-1:-1;;;;;887:87:21;;:::o;8009:147::-;8088:5;;-1:-1:-1;;;;;8088:5:21;8074:10;:19;8066:55;;;;;-1:-1:-1;;;8066:55:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;8132:6;:16;8009:147::o;9118:234::-;9210:5;;-1:-1:-1;;;;;9210:5:21;9196:10;:19;9188:66;;;;-1:-1:-1;;;9188:66:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9265:18;:25;;-1:-1:-1;;9265:25:21;9286:4;9265:25;;;9329:15;9301:25;:43;9118:234::o;1372:29::-;;;;:::o;7822:175::-;7915:5;;-1:-1:-1;;;;;7915:5:21;7901:10;:19;7893:55;;;;;-1:-1:-1;;;7893:55:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;7959:13;:30;7822:175::o;1075:45::-;1112:8;1075:45;:::o;11408:1126::-;11554:8;11536:15;:26;11528:77;;;;-1:-1:-1;;;11528:77:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11672:13;;11624:21;;:44;;11651:15;11624:25;:44::i;:::-;:61;;11616:127;;;;-1:-1:-1;;;11616:127:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12035:16;;11995:10;11969:8;11980:26;;;:14;:26;;;;;;11969:8;;11980:89;;12059:8;;11980:73;;;;12012:15;11980:30;:49::i;:89::-;12117:13;;12100:10;12080:8;12091:20;;;:8;:20;;;;;;11969:100;;-1:-1:-1;12080:8:21;12091:57;;12138:8;;12091:41;;:24;:41::i;:57::-;12080:68;;12173:3;12167;:9;12159:69;;;;-1:-1:-1;;;12159:69:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12329:10;12314:26;;;;:14;:26;;;;;;:49;;12346:15;12314:30;:49::i;:::-;12300:10;12285:26;;;;:14;:26;;;;;:78;12422:21;;:42;;12448:15;12422:25;:42::i;:::-;12398:21;:66;12475:12;;;:51;;;;;;12498:10;12475:51;;;;;;;;;;;;-1:-1:-1;;;;;12475:12:21;;;;:22;;:51;;;;;;;;;;:12;;:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11408:1126;;;:::o;2944:37::-;;;;:::o;1678:471:18:-;1736:7;1981:6;1977:47;;-1:-1:-1;2011:1:18;2004:8;;1977:47;2048:5;;;2052:1;2048;:5;:1;2072:5;;;;;:10;2064:56;;;;-1:-1:-1;;;2064:56:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2625:132;2683:7;2710:39;2714:1;2717;2710:39;;;;;;;;;;;;;;;;;:3;:39::i;788:136::-;846:7;873:43;877:1;880;873:43;;;;;;;;;;;;;;;;;:3;:43::i;3253:278::-;3339:7;3374:12;3367:5;3359:28;;;;-1:-1:-1;;;3359:28:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3398:9;3414:1;3410;:5;;;;;;;3253:278;-1:-1:-1;;;;;3253:278:18:o;1227:192::-;1313:7;1349:12;1341:6;;;;1333:29;;;;-1:-1:-1;;;1333:29:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1385:5:18;;;1227:192::o;-1:-1:-1:-;;;;;;;;:::o

Swarm Source

ipfs://4b90338f83fcf36a387fe8b20581a5a06f9bed47123e67a20643af9510dac9e0
Block Transaction Difficulty Gas Used Reward
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.

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.