Contract 0x2D46292cbB3C601c6e2c74C32df3A4FCe99b59C7 1

 
Txn Hash Method
Index
From
To
Value
0xc0814feba6aafa396d475e649dbe3998f5933ff014377b689f0c116c5a803e73Initiate Deposit261033342022-09-28 22:21:4322 mins ago0xf9d6e17f019c4d719c46a8a8832ecc25ea096aa2 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000370216690.00100155
0xe7d9e79dfcbe328587bcee4a8b9b161a160376db1545911f1b4519d40cda2c73Initiate Deposit261020392022-09-28 22:10:4133 mins ago0x0be7b271ba03874ad78d712246066c20c81693d3 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000404673790.00100155
0x9779db029bc9479aa9a4f880c64f0db65076e3ec61e5a2900d5ef794443cf3d4Process Withdraw...261006902022-09-28 22:00:1544 mins ago0x9f76043b23125024ce5f0fb4ae707482107dd2a8 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000689136640.00100155
0xc7af3549fc43b49ad487feccaf9ce6cf8d44c0ee2d2694c28644204747675166Process Deposit ...261006622022-09-28 22:00:0044 mins ago0x9f76043b23125024ce5f0fb4ae707482107dd2a8 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000688920840.00100155
0x705c74b510a3a5ea9cce31f66d08eba08dd539c4a0f5b6bda934d22e0ecda31aInitiate Withdra...261003382022-09-28 21:56:5847 mins ago0xe7911fd11b0d6a6ed3a8aaf2815801be57a05702 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0001364652440.001002785
0x6b10260d6decf4f54473cea4494d966f3abf1b84aba8dbf1d49d4471a684e2e4Initiate Withdra...261000262022-09-28 21:53:3950 mins ago0xf10b4845ad2b68e0e4e2951b72f0a0cbfcfb9933 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.000072264070.00100155
0x6c645c7af4c86aa5e53fc5c6f1743bd5520f524a30e8d95871d80ab566f2149bInitiate Withdra...260999752022-09-28 21:52:5451 mins ago0xef677e6f8b6730db905188f3f06bf58701d12a76 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000649077990.001002785
0xb02ffbac92420aba126325f1f6d4e40737894c0aaf56cbbef0bf6b15a53f6a02Initiate Deposit260997062022-09-28 21:50:2254 mins ago0x96ad6be504d153a25d41a476d5202425e85135fb IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000394811560.00100155
0x1e5b9ccfe02245acc1bc116b4b923c2f4e51392697638a7a963e6037fc73165eInitiate Withdra...260973762022-09-28 21:32:331 hr 11 mins ago0x65771f8edf797d2b98241010ac67cc8ea2f88b33 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000413087020.00100155
0xe5d27fbab20ac96c8e730d2b2536511cd60be63ef45a42d91a129218704c797cInitiate Deposit260971112022-09-28 21:30:471 hr 13 mins ago0x7bfb6030e9ab4f418e19950365c81cd82d115c78 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000478826130.00100155
0xfd2e098751d35b633c9f93d4d78991d026740f880db074af9a72442f2c46d510Process Withdraw...260933312022-09-28 21:00:241 hr 44 mins ago0x9f76043b23125024ce5f0fb4ae707482107dd2a8 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000520632780.00100155
0x9656052b399f2727dbb94647c51fe33b3cad1cc0376c0bf2e09e6fcac62bda08Process Deposit ...260932762022-09-28 20:59:531 hr 44 mins ago0x9f76043b23125024ce5f0fb4ae707482107dd2a8 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.000051025170.00100155
0xe49795d1d437ab37d125668225d033b9c572a946b00c28f84c3136a2bd26b92cInitiate Withdra...260896142022-09-28 20:37:002 hrs 7 mins ago0x9b2d76f2e5e92b2c78c6e2ce07c6f86b95091964 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000459202470.001101705
0xbc97c140058d16f6192b51f587721d5a857723401b7cf6b0fcbc1712e86788deInitiate Deposit260866572022-09-28 20:14:352 hrs 29 mins ago0x037720b43b114fd7cf0e51362b8ab8091348c377 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000752709010.00100155
0xf7f78db76cf204cf391229f71d51d7cfb3a126bd9aff4843c33aacfc91d14f1fInitiate Deposit260853992022-09-28 20:09:022 hrs 35 mins ago 0x31270214b9cea11f1a07e3a55b4f6643a64f94ff IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000587486810.00100155
0x86ddb7e9717567770c4efd385dfc575d3971b9d4822830f94d33584700261212Process Withdraw...260843532022-09-28 20:00:062 hrs 44 mins ago0x9f76043b23125024ce5f0fb4ae707482107dd2a8 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000625299230.00100155
0x4dba0405d11fb32fb0cb279e70d4526447ca0598b7b9e7c9afb499ef42abe014Process Deposit ...260843252022-09-28 19:59:512 hrs 44 mins ago0x9f76043b23125024ce5f0fb4ae707482107dd2a8 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000541907160.00100155
0xdf3e46c6af571a39af031092af2831de9559b107b009b13fc9b0d91732c05015Initiate Withdra...260798552022-09-28 19:31:023 hrs 13 mins ago0x0a4cc212591b3fa27a33a34d598ecb5aad35c2fb IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000704087030.00100155
0x9229f955e8e5b6137724705cf85e596ab5d207245cbef4b2d0f0e7c1439ca897Initiate Deposit260794102022-09-28 19:27:133 hrs 17 mins ago0x4d999f16ec6fd46a84e3c2cd4a9a64dd314ae829 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000789087570.00100155
0x0df10c2d5bf2a51b74149f21606d789b39f98d25ef00ab2447e095a58d32c76cProcess Withdraw...260759862022-09-28 19:00:193 hrs 44 mins ago0x9f76043b23125024ce5f0fb4ae707482107dd2a8 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000920800470.00100155
0xaad02b3d0ae4ec5cee806557bcae10febc3fae74a593c131c34b33ce33d956aeProcess Deposit ...260759532022-09-28 19:00:043 hrs 44 mins ago0x9f76043b23125024ce5f0fb4ae707482107dd2a8 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000916592160.00100155
0x59714c367bf7f27ec4ef15650ccecbca295edb41eafafbbdf99ff9c332f8d76bInitiate Withdra...260757272022-09-28 18:58:183 hrs 46 mins ago0xa408cb2c8faa0c7d18f451033898fc3c8361939a IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0001018914930.00100155
0x09d03db3350b7c6c77f885c59b5f660aa35cd2f847ad4a1d2692effa779f9f4cInitiate Withdra...260750852022-09-28 18:53:143 hrs 51 mins ago0xb5f4af1a4b5021ae10207e1c2e119ce8249b3007 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0000994047320.00100155
0x4ce6af6280f9132e86cc0db8bdfa98e9dc4d67ab57791508408b191e13759a03Initiate Deposit260743812022-09-28 18:48:123 hrs 56 mins ago0xd16b2a7d65807114eec78a734a55a95de0cabcb2 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0001116066370.00100155
0x5ddb0d9157f4c5c4058c1a15afe9b94beeb650b3edd3b3958d3bbe01b43f46a0Initiate Deposit260696062022-09-28 18:16:554 hrs 27 mins ago0x86b49b8fd824a462a0ccff07e0af218c075057d2 IN  0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c70 Ether0.0001007211340.00100155
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0x0052a341bea99c4b452816235fc2216143c5f21c0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0xbb3e8eac35e649ed1071a9ec42223d474e67b19a0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0xbb3e8eac35e649ed1071a9ec42223d474e67b19a0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0xbb3e8eac35e649ed1071a9ec42223d474e67b19a0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0x22602469d704bffb0936c7a7cfcd18f7aa2693750 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0x1d42a98848e022908069c2c545ae44cc78509bc80 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0x0052a341bea99c4b452816235fc2216143c5f21c0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0xbb3e8eac35e649ed1071a9ec42223d474e67b19a0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0xbb3e8eac35e649ed1071a9ec42223d474e67b19a0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0xbb3e8eac35e649ed1071a9ec42223d474e67b19a0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0x22602469d704bffb0936c7a7cfcd18f7aa2693750 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0x1d42a98848e022908069c2c545ae44cc78509bc80 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0x22602469d704bffb0936c7a7cfcd18f7aa2693750 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0x2901f5f1d4c99f9eee36ccd9a264729c5dd35c110 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 Synthetix: sETH Token0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 Synthetix: sETH Token0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0x0052a341bea99c4b452816235fc2216143c5f21c0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0xbb3e8eac35e649ed1071a9ec42223d474e67b19a0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0xbb3e8eac35e649ed1071a9ec42223d474e67b19a0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0xbb3e8eac35e649ed1071a9ec42223d474e67b19a0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0x22602469d704bffb0936c7a7cfcd18f7aa2693750 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0x1d42a98848e022908069c2c545ae44cc78509bc80 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0x0052a341bea99c4b452816235fc2216143c5f21c0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0xbb3e8eac35e649ed1071a9ec42223d474e67b19a0 Ether
0xa9eccd57db7b6e8faf765c596c60b37f30cee58ec675c0e91fc5b029fbb4070b260175662022-09-28 14:00:118 hrs 44 mins ago 0x2d46292cbb3c601c6e2c74c32df3a4fce99b59c7 0xbb3e8eac35e649ed1071a9ec42223d474e67b19a0 Ether
[ Download CSV Export 
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
CallSellingVault

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 10000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Optimistic.Etherscan.io on 2022-08-20
*/

// Sources flattened with hardhat v2.9.6 https://hardhat.org

// File @rari-capital/solmate/src/auth/[email protected]

// -License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Provides a flexible and updatable auth pattern which is completely separate from application logic.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
abstract contract Auth {
    event OwnerUpdated(address indexed user, address indexed newOwner);

    event AuthorityUpdated(address indexed user, Authority indexed newAuthority);

    address public owner;

    Authority public authority;

    constructor(address _owner, Authority _authority) {
        owner = _owner;
        authority = _authority;

        emit OwnerUpdated(msg.sender, _owner);
        emit AuthorityUpdated(msg.sender, _authority);
    }

    modifier requiresAuth() virtual {
        require(isAuthorized(msg.sender, msg.sig), "UNAUTHORIZED");

        _;
    }

    function isAuthorized(address user, bytes4 functionSig) internal view virtual returns (bool) {
        Authority auth = authority; // Memoizing authority saves us a warm SLOAD, around 100 gas.

        // Checking if the caller is the owner only after calling the authority saves gas in most cases, but be
        // aware that this makes protected functions uncallable even to the owner if the authority is out of order.
        return (address(auth) != address(0) && auth.canCall(user, address(this), functionSig)) || user == owner;
    }

    function setAuthority(Authority newAuthority) public virtual {
        // We check if the caller is the owner first because we want to ensure they can
        // always swap out the authority even if it's reverting or using up a lot of gas.
        require(msg.sender == owner || authority.canCall(msg.sender, address(this), msg.sig));

        authority = newAuthority;

        emit AuthorityUpdated(msg.sender, newAuthority);
    }

    function setOwner(address newOwner) public virtual requiresAuth {
        owner = newOwner;

        emit OwnerUpdated(msg.sender, newOwner);
    }
}

/// @notice A generic interface for a contract which provides authorization data to an Auth instance.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
interface Authority {
    function canCall(
        address user,
        address target,
        bytes4 functionSig
    ) external view returns (bool);
}


// File @rari-capital/solmate/src/tokens/[email protected]

// -License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}


// File @rari-capital/solmate/src/utils/[email protected]

// -License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
    /*//////////////////////////////////////////////////////////////
                    SIMPLIFIED FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.

    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
    }

    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
    }

    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
    }

    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
    }

    /*//////////////////////////////////////////////////////////////
                    LOW LEVEL FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function mulDivDown(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        assembly {
            // Store x * y in z for now.
            z := mul(x, y)

            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
                revert(0, 0)
            }

            // Divide z by the denominator.
            z := div(z, denominator)
        }
    }

    function mulDivUp(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        assembly {
            // Store x * y in z for now.
            z := mul(x, y)

            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
                revert(0, 0)
            }

            // First, divide z - 1 by the denominator and add 1.
            // We allow z - 1 to underflow if z is 0, because we multiply the
            // end result by 0 if z is zero, ensuring we return 0 if z is zero.
            z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))
        }
    }

    function rpow(
        uint256 x,
        uint256 n,
        uint256 scalar
    ) internal pure returns (uint256 z) {
        assembly {
            switch x
            case 0 {
                switch n
                case 0 {
                    // 0 ** 0 = 1
                    z := scalar
                }
                default {
                    // 0 ** n = 0
                    z := 0
                }
            }
            default {
                switch mod(n, 2)
                case 0 {
                    // If n is even, store scalar in z for now.
                    z := scalar
                }
                default {
                    // If n is odd, store x in z for now.
                    z := x
                }

                // Shifting right by 1 is like dividing by 2.
                let half := shr(1, scalar)

                for {
                    // Shift n right by 1 before looping to halve it.
                    n := shr(1, n)
                } n {
                    // Shift n right by 1 each iteration to halve it.
                    n := shr(1, n)
                } {
                    // Revert immediately if x ** 2 would overflow.
                    // Equivalent to iszero(eq(div(xx, x), x)) here.
                    if shr(128, x) {
                        revert(0, 0)
                    }

                    // Store x squared.
                    let xx := mul(x, x)

                    // Round to the nearest number.
                    let xxRound := add(xx, half)

                    // Revert if xx + half overflowed.
                    if lt(xxRound, xx) {
                        revert(0, 0)
                    }

                    // Set x to scaled xxRound.
                    x := div(xxRound, scalar)

                    // If n is even:
                    if mod(n, 2) {
                        // Compute z * x.
                        let zx := mul(z, x)

                        // If z * x overflowed:
                        if iszero(eq(div(zx, x), z)) {
                            // Revert if x is non-zero.
                            if iszero(iszero(x)) {
                                revert(0, 0)
                            }
                        }

                        // Round to the nearest number.
                        let zxRound := add(zx, half)

                        // Revert if zx + half overflowed.
                        if lt(zxRound, zx) {
                            revert(0, 0)
                        }

                        // Return properly scaled zxRound.
                        z := div(zxRound, scalar)
                    }
                }
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                        GENERAL NUMBER UTILITIES
    //////////////////////////////////////////////////////////////*/

    function sqrt(uint256 x) internal pure returns (uint256 z) {
        assembly {
            // Start off with z at 1.
            z := 1

            // Used below to help find a nearby power of 2.
            let y := x

            // Find the lowest power of 2 that is at least sqrt(x).
            if iszero(lt(y, 0x100000000000000000000000000000000)) {
                y := shr(128, y) // Like dividing by 2 ** 128.
                z := shl(64, z) // Like multiplying by 2 ** 64.
            }
            if iszero(lt(y, 0x10000000000000000)) {
                y := shr(64, y) // Like dividing by 2 ** 64.
                z := shl(32, z) // Like multiplying by 2 ** 32.
            }
            if iszero(lt(y, 0x100000000)) {
                y := shr(32, y) // Like dividing by 2 ** 32.
                z := shl(16, z) // Like multiplying by 2 ** 16.
            }
            if iszero(lt(y, 0x10000)) {
                y := shr(16, y) // Like dividing by 2 ** 16.
                z := shl(8, z) // Like multiplying by 2 ** 8.
            }
            if iszero(lt(y, 0x100)) {
                y := shr(8, y) // Like dividing by 2 ** 8.
                z := shl(4, z) // Like multiplying by 2 ** 4.
            }
            if iszero(lt(y, 0x10)) {
                y := shr(4, y) // Like dividing by 2 ** 4.
                z := shl(2, z) // Like multiplying by 2 ** 2.
            }
            if iszero(lt(y, 0x8)) {
                // Equivalent to 2 ** z.
                z := shl(1, z)
            }

            // Shifting right by 1 is like dividing by 2.
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))

            // Compute a rounded down version of z.
            let zRoundDown := div(x, z)

            // If zRoundDown is smaller, use it.
            if lt(zRoundDown, z) {
                z := zRoundDown
            }
        }
    }
}


// File @rari-capital/solmate/src/utils/[email protected]

// -License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Gas optimized reentrancy protection for smart contracts.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/ReentrancyGuard.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
    uint256 private locked = 1;

    modifier nonReentrant() virtual {
        require(locked == 1, "REENTRANCY");

        locked = 2;

        _;

        locked = 1;
    }
}


// File @rari-capital/solmate/src/utils/[email protected]

// -License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument.
            mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
            )
        }

        require(success, "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "APPROVE_FAILED");
    }
}


// File contracts/utils/Pausable.sol

// -License-Identifier: MIT
pragma solidity 0.8.9;

abstract contract Pausable {

    bool private _paused;
    bool private _depositsPaused;

    constructor() {
        _paused = false;
        _depositsPaused = false;
    }

    function paused() public view virtual returns (bool) {
        return _paused;
    }

    function depositsPaused() public view virtual returns (bool) {
        return _depositsPaused;
    }

    modifier whenNotPaused() {
        if (paused()) {
            revert Paused();
        }
        _;
    }

    modifier whenPaused() {
        if (!paused()) {
            revert NotPaused();
        }
        _;
    }

    modifier whenDepositsNotPaused() {
        if(depositsPaused()) {
            revert DepositsPaused();
        }
        _;
    }

    modifier whenDepositsPaused() {
        if (!depositsPaused()) {
            revert DepositsNotPaused();
        }
        _;
    }

    function _pause() internal virtual whenNotPaused {
        _paused = true;
        _depositsPaused = true;
        emit SetPaused(msg.sender);
    }

    function _pauseDeposits() internal virtual whenDepositsNotPaused {
        _depositsPaused = true;
        emit SetDepositsPaused(msg.sender);
    }

    function _unpause() internal virtual whenPaused {
        _paused = false;
        _depositsPaused = false;
        emit SetUnpaused(msg.sender);
    }

    function _unpauseDeposits() internal virtual whenDepositsPaused {
        _depositsPaused = false;
        emit SetDepositsUnpaused(msg.sender);
    }

    error Paused();
    error DepositsPaused();
    error NotPaused();
    error DepositsNotPaused();

    event SetPaused(address account);
    event SetDepositsPaused(address account);
    event SetUnpaused(address account);
    event SetDepositsUnpaused(address account);
}


// File contracts/interfaces/synthetix/ISynthetix.sol

// -License-Identifier: MIT
pragma solidity 0.8.9;

interface ISynthetix {

    function exchange(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey
    ) external returns (uint amountReceived);
  
    function exchangeOnBehalf(
        address exchangeForAddress,
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey
    ) external returns (uint amountReceived);

    function exchangeWithTracking(
        bytes32 sourceCurrencyKey,
        uint sourceAmount,
        bytes32 destinationCurrencyKey,
        address rewardAddress,
        bytes32 trackingCode
    ) external returns (uint256 amountReceived);

}


// File contracts/interfaces/synthetix/IExchangeRates.sol

// -License-Identifier: MIT
pragma solidity 0.8.9;

interface IExchangeRates {
    function rateAndInvalid(
        bytes32 currencyKey
    ) external view returns (uint rate, bool isInvalid);
}


// File contracts/interfaces/IPolynomialVaultToken.sol

// -License-Identifier: MIT
pragma solidity 0.8.9;

interface IPolynomialVaultToken {
    function mint(address _user, uint256 _amt) external;
    function burn(address _user, uint256 _amt) external;

    function totalSupply() external view returns (uint256 totalSupply);
}


// File contracts/interfaces/IPolynomialVault.sol

// -License-Identifier: MIT
pragma solidity 0.8.9;

interface IPolynomialVault {}


// File contracts/interfaces/lyra/IOptionMarket.sol

// -License-Identifier: MIT
pragma solidity 0.8.9;

interface IOptionMarket {
    enum OptionType {
        LONG_CALL,
        LONG_PUT,
        SHORT_CALL_BASE,
        SHORT_CALL_QUOTE,
        SHORT_PUT_QUOTE
    }

    struct Strike {
        // strike listing identifier
        uint id;
        // strike price
        uint strikePrice;
        // volatility component specific to the strike listing (boardIv * skew = vol of strike)
        uint skew;
        // total user long call exposure
        uint longCall;
        // total user short call (base collateral) exposure
        uint shortCallBase;
        // total user short call (quote collateral) exposure
        uint shortCallQuote;
        // total user long put exposure
        uint longPut;
        // total user short put (quote collateral) exposure
        uint shortPut;
        // id of board to which strike belongs
        uint boardId;
    }
    
    struct OptionBoard {
        // board identifier
        uint id;
        // expiry of all strikes belonging to board
        uint expiry;
        // volatility component specific to board (boardIv * skew = vol of strike)
        uint iv;
        // admin settable flag blocking all trading on this board
        bool frozen;
        // list of all strikes belonging to this board
        uint[] strikeIds;
    }

    function getStrikeAndBoard(uint strikeId) external view returns (Strike memory, OptionBoard memory);

    function getStrikeAndExpiry(uint strikeId) external view returns (uint strikePrice, uint expiry);

    function getSettlementParameters(uint strikeId) external view returns (
        uint strikePrice,
        uint priceAtExpiry,
        uint strikeToBaseReturned
    );

    function addCollateral(uint positionId, uint amountCollateral) external;
}


// File contracts/interfaces/lyra/IOptionMarketWrapperWithSwaps.sol

// -License-Identifier: MIT
pragma solidity 0.8.9;

interface IOptionMarketWrapperWithSwaps {
    struct ReturnDetails {
        address market;
        uint positionId;
        address owner;
        uint amount;
        uint totalCost;
        uint totalFee;
        int swapFee;
        address token;
    }

    struct OptionPositionParams {
        IOptionMarket optionMarket;
        uint strikeId; // The id of the relevant OptionListing
        uint positionId;
        uint iterations;
        uint setCollateralTo;
        uint currentCollateral;
        IOptionMarket.OptionType optionType; // Is the trade a long/short & call/put?
        uint amount; // The amount the user has requested to close
        uint minCost; // Min amount for the cost of the trade
        uint maxCost; // Max amount for the cost of the trade
        uint inputAmount; // Amount of stable coins the user can use
        ERC20 inputAsset; // Address of coin user wants to open with
    }

    function openPosition(OptionPositionParams memory params) external returns (ReturnDetails memory returnDetails);

    function closePosition(OptionPositionParams memory params) external returns (ReturnDetails memory returnDetails);
}


// File contracts/interfaces/lyra/IOptionToken.sol

// -License-Identifier: MIT
pragma solidity 0.8.9;

interface IOptionToken {
    enum PositionState {
        EMPTY,
        ACTIVE,
        CLOSED,
        LIQUIDATED,
        SETTLED,
        MERGED
    }

    function getPositionState(uint positionId) external view returns (PositionState);

    function getApproved(uint256 tokenId) external view returns (address operator);

    function approve(address to, uint256 tokenId) external;
}


// File contracts/interfaces/lyra/IOptionGreekCache.sol

// -License-Identifier: MIT
pragma solidity 0.8.9;

interface IOptionGreekCache {
    struct GreekCacheParameters {
        // Cap the number of strikes per board to avoid hitting gasLimit constraints
        uint maxStrikesPerBoard;
        // How much spot price can move since last update before deposits/withdrawals are blocked
        uint acceptableSpotPricePercentMove;
        // How much time has passed since last update before deposits/withdrawals are blocked
        uint staleUpdateDuration;
        // Length of the GWAV for the baseline volatility used to fire the vol circuit breaker
        uint varianceIvGWAVPeriod;
        // Length of the GWAV for the skew ratios used to fire the vol circuit breaker
        uint varianceSkewGWAVPeriod;
        // Length of the GWAV for the baseline used to determine the NAV of the pool
        uint optionValueIvGWAVPeriod;
        // Length of the GWAV for the skews used to determine the NAV of the pool
        uint optionValueSkewGWAVPeriod;
        // Minimum skew that will be fed into the GWAV calculation
        // Prevents near 0 values being used to heavily manipulate the GWAV
        uint gwavSkewFloor;
        // Maximum skew that will be fed into the GWAV calculation
        uint gwavSkewCap;
        // Interest/risk free rate
        int rateAndCarry;
    }

    function getGreekCacheParams() external view returns (GreekCacheParameters memory);

    function getIvGWAV(uint boardId, uint secondsAgo) external view returns (uint ivGWAV);

    function getSkewGWAV(uint strikeId, uint secondsAgo) external view returns (uint skewGWAV);
}


// File contracts/libraries/DecimalMath.sol

//-License-Identifier: MIT
//
//Copyright (c) 2019 Synthetix
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.

pragma solidity ^0.8.9;

/**
 * @title DecimalMath
 * @author Lyra
 * @dev Modified synthetix SafeDecimalMath to include internal arithmetic underflow/overflow.
 * @dev https://docs.synthetix.io/contracts/source/libraries/SafeDecimalMath/
 */

library DecimalMath {
  /* Number of decimal places in the representations. */
  uint8 public constant decimals = 18;
  uint8 public constant highPrecisionDecimals = 27;

  /* The number representing 1.0. */
  uint public constant UNIT = 10**uint(decimals);

  /* The number representing 1.0 for higher fidelity numbers. */
  uint public constant PRECISE_UNIT = 10**uint(highPrecisionDecimals);
  uint private constant UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR = 10**uint(highPrecisionDecimals - decimals);

  /**
   * @return Provides an interface to UNIT.
   */
  function unit() external pure returns (uint) {
    return UNIT;
  }

  /**
   * @return Provides an interface to PRECISE_UNIT.
   */
  function preciseUnit() external pure returns (uint) {
    return PRECISE_UNIT;
  }

  /**
   * @return The result of multiplying x and y, interpreting the operands as fixed-point
   * decimals.
   *
   * @dev A unit factor is divided out after the product of x and y is evaluated,
   * so that product must be less than 2**256. As this is an integer division,
   * the internal division always rounds down. This helps save on gas. Rounding
   * is more expensive on gas.
   */
  function multiplyDecimal(uint x, uint y) internal pure returns (uint) {
    /* Divide by UNIT to remove the extra factor introduced by the product. */
    return (x * y) / UNIT;
  }

  /**
   * @return The result of safely multiplying x and y, interpreting the operands
   * as fixed-point decimals of the specified precision unit.
   *
   * @dev The operands should be in the form of a the specified unit factor which will be
   * divided out after the product of x and y is evaluated, so that product must be
   * less than 2**256.
   *
   * Unlike multiplyDecimal, this function rounds the result to the nearest increment.
   * Rounding is useful when you need to retain fidelity for small decimal numbers
   * (eg. small fractions or percentages).
   */
  function _multiplyDecimalRound(
    uint x,
    uint y,
    uint precisionUnit
  ) private pure returns (uint) {
    /* Divide by UNIT to remove the extra factor introduced by the product. */
    uint quotientTimesTen = (x * y) / (precisionUnit / 10);

    if (quotientTimesTen % 10 >= 5) {
      quotientTimesTen += 10;
    }

    return quotientTimesTen / 10;
  }

  /**
   * @return The result of safely multiplying x and y, interpreting the operands
   * as fixed-point decimals of a precise unit.
   *
   * @dev The operands should be in the precise unit factor which will be
   * divided out after the product of x and y is evaluated, so that product must be
   * less than 2**256.
   *
   * Unlike multiplyDecimal, this function rounds the result to the nearest increment.
   * Rounding is useful when you need to retain fidelity for small decimal numbers
   * (eg. small fractions or percentages).
   */
  function multiplyDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) {
    return _multiplyDecimalRound(x, y, PRECISE_UNIT);
  }

  /**
   * @return The result of safely multiplying x and y, interpreting the operands
   * as fixed-point decimals of a standard unit.
   *
   * @dev The operands should be in the standard unit factor which will be
   * divided out after the product of x and y is evaluated, so that product must be
   * less than 2**256.
   *
   * Unlike multiplyDecimal, this function rounds the result to the nearest increment.
   * Rounding is useful when you need to retain fidelity for small decimal numbers
   * (eg. small fractions or percentages).
   */
  function multiplyDecimalRound(uint x, uint y) internal pure returns (uint) {
    return _multiplyDecimalRound(x, y, UNIT);
  }

  /**
   * @return The result of safely dividing x and y. The return value is a high
   * precision decimal.
   *
   * @dev y is divided after the product of x and the standard precision unit
   * is evaluated, so the product of x and UNIT must be less than 2**256. As
   * this is an integer division, the result is always rounded down.
   * This helps save on gas. Rounding is more expensive on gas.
   */
  function divideDecimal(uint x, uint y) internal pure returns (uint) {
    /* Reintroduce the UNIT factor that will be divided out by y. */
    return (x * UNIT) / y;
  }

  /**
   * @return The result of safely dividing x and y. The return value is as a rounded
   * decimal in the precision unit specified in the parameter.
   *
   * @dev y is divided after the product of x and the specified precision unit
   * is evaluated, so the product of x and the specified precision unit must
   * be less than 2**256. The result is rounded to the nearest increment.
   */
  function _divideDecimalRound(
    uint x,
    uint y,
    uint precisionUnit
  ) private pure returns (uint) {
    uint resultTimesTen = (x * (precisionUnit * 10)) / y;

    if (resultTimesTen % 10 >= 5) {
      resultTimesTen += 10;
    }

    return resultTimesTen / 10;
  }

  /**
   * @return The result of safely dividing x and y. The return value is as a rounded
   * standard precision decimal.
   *
   * @dev y is divided after the product of x and the standard precision unit
   * is evaluated, so the product of x and the standard precision unit must
   * be less than 2**256. The result is rounded to the nearest increment.
   */
  function divideDecimalRound(uint x, uint y) internal pure returns (uint) {
    return _divideDecimalRound(x, y, UNIT);
  }

  /**
   * @return The result of safely dividing x and y. The return value is as a rounded
   * high precision decimal.
   *
   * @dev y is divided after the product of x and the high precision unit
   * is evaluated, so the product of x and the high precision unit must
   * be less than 2**256. The result is rounded to the nearest increment.
   */
  function divideDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) {
    return _divideDecimalRound(x, y, PRECISE_UNIT);
  }

  /**
   * @dev Convert a standard decimal representation to a high precision one.
   */
  function decimalToPreciseDecimal(uint i) internal pure returns (uint) {
    return i * UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR;
  }

  /**
   * @dev Convert a high precision decimal to a standard decimal representation.
   */
  function preciseDecimalToDecimal(uint i) internal pure returns (uint) {
    uint quotientTimesTen = i / (UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR / 10);

    if (quotientTimesTen % 10 >= 5) {
      quotientTimesTen += 10;
    }

    return quotientTimesTen / 10;
  }
}


// File contracts/libraries/SignedDecimalMath.sol

//-License-Identifier: MIT
//
//Copyright (c) 2019 Synthetix
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.

pragma solidity ^0.8.9;

/**
 * @title SignedDecimalMath
 * @author Lyra
 * @dev Modified synthetix SafeSignedDecimalMath to include internal arithmetic underflow/overflow.
 * @dev https://docs.synthetix.io/contracts/source/libraries/safedecimalmath
 */
library SignedDecimalMath {
  /* Number of decimal places in the representations. */
  uint8 public constant decimals = 18;
  uint8 public constant highPrecisionDecimals = 27;

  /* The number representing 1.0. */
  int public constant UNIT = int(10**uint(decimals));

  /* The number representing 1.0 for higher fidelity numbers. */
  int public constant PRECISE_UNIT = int(10**uint(highPrecisionDecimals));
  int private constant UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR = int(10**uint(highPrecisionDecimals - decimals));

  /**
   * @return Provides an interface to UNIT.
   */
  function unit() external pure returns (int) {
    return UNIT;
  }

  /**
   * @return Provides an interface to PRECISE_UNIT.
   */
  function preciseUnit() external pure returns (int) {
    return PRECISE_UNIT;
  }

  /**
   * @dev Rounds an input with an extra zero of precision, returning the result without the extra zero.
   * Half increments round away from zero; positive numbers at a half increment are rounded up,
   * while negative such numbers are rounded down. This behaviour is designed to be consistent with the
   * unsigned version of this library (SafeDecimalMath).
   */
  function _roundDividingByTen(int valueTimesTen) private pure returns (int) {
    int increment;
    if (valueTimesTen % 10 >= 5) {
      increment = 10;
    } else if (valueTimesTen % 10 <= -5) {
      increment = -10;
    }
    return (valueTimesTen + increment) / 10;
  }

  /**
   * @return The result of multiplying x and y, interpreting the operands as fixed-point
   * decimals.
   *
   * @dev A unit factor is divided out after the product of x and y is evaluated,
   * so that product must be less than 2**256. As this is an integer division,
   * the internal division always rounds down. This helps save on gas. Rounding
   * is more expensive on gas.
   */
  function multiplyDecimal(int x, int y) internal pure returns (int) {
    /* Divide by UNIT to remove the extra factor introduced by the product. */
    return (x * y) / UNIT;
  }

  /**
   * @return The result of safely multiplying x and y, interpreting the operands
   * as fixed-point decimals of the specified precision unit.
   *
   * @dev The operands should be in the form of a the specified unit factor which will be
   * divided out after the product of x and y is evaluated, so that product must be
   * less than 2**256.
   *
   * Unlike multiplyDecimal, this function rounds the result to the nearest increment.
   * Rounding is useful when you need to retain fidelity for small decimal numbers
   * (eg. small fractions or percentages).
   */
  function _multiplyDecimalRound(
    int x,
    int y,
    int precisionUnit
  ) private pure returns (int) {
    /* Divide by UNIT to remove the extra factor introduced by the product. */
    int quotientTimesTen = (x * y) / (precisionUnit / 10);
    return _roundDividingByTen(quotientTimesTen);
  }

  /**
   * @return The result of safely multiplying x and y, interpreting the operands
   * as fixed-point decimals of a precise unit.
   *
   * @dev The operands should be in the precise unit factor which will be
   * divided out after the product of x and y is evaluated, so that product must be
   * less than 2**256.
   *
   * Unlike multiplyDecimal, this function rounds the result to the nearest increment.
   * Rounding is useful when you need to retain fidelity for small decimal numbers
   * (eg. small fractions or percentages).
   */
  function multiplyDecimalRoundPrecise(int x, int y) internal pure returns (int) {
    return _multiplyDecimalRound(x, y, PRECISE_UNIT);
  }

  /**
   * @return The result of safely multiplying x and y, interpreting the operands
   * as fixed-point decimals of a standard unit.
   *
   * @dev The operands should be in the standard unit factor which will be
   * divided out after the product of x and y is evaluated, so that product must be
   * less than 2**256.
   *
   * Unlike multiplyDecimal, this function rounds the result to the nearest increment.
   * Rounding is useful when you need to retain fidelity for small decimal numbers
   * (eg. small fractions or percentages).
   */
  function multiplyDecimalRound(int x, int y) internal pure returns (int) {
    return _multiplyDecimalRound(x, y, UNIT);
  }

  /**
   * @return The result of safely dividing x and y. The return value is a high
   * precision decimal.
   *
   * @dev y is divided after the product of x and the standard precision unit
   * is evaluated, so the product of x and UNIT must be less than 2**256. As
   * this is an integer division, the result is always rounded down.
   * This helps save on gas. Rounding is more expensive on gas.
   */
  function divideDecimal(int x, int y) internal pure returns (int) {
    /* Reintroduce the UNIT factor that will be divided out by y. */
    return (x * UNIT) / y;
  }

  /**
   * @return The result of safely dividing x and y. The return value is as a rounded
   * decimal in the precision unit specified in the parameter.
   *
   * @dev y is divided after the product of x and the specified precision unit
   * is evaluated, so the product of x and the specified precision unit must
   * be less than 2**256. The result is rounded to the nearest increment.
   */
  function _divideDecimalRound(
    int x,
    int y,
    int precisionUnit
  ) private pure returns (int) {
    int resultTimesTen = (x * (precisionUnit * 10)) / y;
    return _roundDividingByTen(resultTimesTen);
  }

  /**
   * @return The result of safely dividing x and y. The return value is as a rounded
   * standard precision decimal.
   *
   * @dev y is divided after the product of x and the standard precision unit
   * is evaluated, so the product of x and the standard precision unit must
   * be less than 2**256. The result is rounded to the nearest increment.
   */
  function divideDecimalRound(int x, int y) internal pure returns (int) {
    return _divideDecimalRound(x, y, UNIT);
  }

  /**
   * @return The result of safely dividing x and y. The return value is as a rounded
   * high precision decimal.
   *
   * @dev y is divided after the product of x and the high precision unit
   * is evaluated, so the product of x and the high precision unit must
   * be less than 2**256. The result is rounded to the nearest increment.
   */
  function divideDecimalRoundPrecise(int x, int y) internal pure returns (int) {
    return _divideDecimalRound(x, y, PRECISE_UNIT);
  }

  /**
   * @dev Convert a standard decimal representation to a high precision one.
   */
  function decimalToPreciseDecimal(int i) internal pure returns (int) {
    return i * UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR;
  }

  /**
   * @dev Convert a high precision decimal to a standard decimal representation.
   */
  function preciseDecimalToDecimal(int i) internal pure returns (int) {
    int quotientTimesTen = i / (UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR / 10);
    return _roundDividingByTen(quotientTimesTen);
  }
}


// File contracts/libraries/HigherMath.sol

// -License-Identifier: UNLICENSED
pragma solidity 0.8.9;

// Slightly modified version of:
// - https://github.com/recmo/experiment-solexp/blob/605738f3ed72d6c67a414e992be58262fbc9bb80/src/FixedPointMathLib.sol
library HigherMath {
  /// @dev Computes ln(x) for a 1e27 fixed point. Loses 9 last significant digits of precision.
  function lnPrecise(int x) internal pure returns (int r) {
    return ln(x / 1e9) * 1e9;
  }

  /// @dev Computes e ^ x for a 1e27 fixed point. Loses 9 last significant digits of precision.
  function expPrecise(int x) internal pure returns (uint r) {
    return exp(x / 1e9) * 1e9;
  }

  // Computes ln(x) in 1e18 fixed point.
  // Reverts if x is negative or zero.
  // Consumes 670 gas.
  function ln(int x) internal pure returns (int r) {
    unchecked {
      if (x < 1) {
        if (x < 0) revert LnNegativeUndefined();
        revert Overflow();
      }

      // We want to convert x from 10**18 fixed point to 2**96 fixed point.
      // We do this by multiplying by 2**96 / 10**18.
      // But since ln(x * C) = ln(x) + ln(C), we can simply do nothing here
      // and add ln(2**96 / 10**18) at the end.

      // Reduce range of x to (1, 2) * 2**96
      // ln(2^k * x) = k * ln(2) + ln(x)
      // Note: inlining ilog2 saves 8 gas.
      int k = int(ilog2(uint(x))) - 96;
      x <<= uint(159 - k);
      x = int(uint(x) >> 159);

      // Evaluate using a (8, 8)-term rational approximation
      // p is made monic, we will multiply by a scale factor later
      int p = x + 3273285459638523848632254066296;
      p = ((p * x) >> 96) + 24828157081833163892658089445524;
      p = ((p * x) >> 96) + 43456485725739037958740375743393;
      p = ((p * x) >> 96) - 11111509109440967052023855526967;
      p = ((p * x) >> 96) - 45023709667254063763336534515857;
      p = ((p * x) >> 96) - 14706773417378608786704636184526;
      p = p * x - (795164235651350426258249787498 << 96);
      //emit log_named_int("p", p);
      // We leave p in 2**192 basis so we don't need to scale it back up for the division.
      // q is monic by convention
      int q = x + 5573035233440673466300451813936;
      q = ((q * x) >> 96) + 71694874799317883764090561454958;
      q = ((q * x) >> 96) + 283447036172924575727196451306956;
      q = ((q * x) >> 96) + 401686690394027663651624208769553;
      q = ((q * x) >> 96) + 204048457590392012362485061816622;
      q = ((q * x) >> 96) + 31853899698501571402653359427138;
      q = ((q * x) >> 96) + 909429971244387300277376558375;
      assembly {
        // Div in assembly because solidity adds a zero check despite the `unchecked`.
        // The q polynomial is known not to have zeros in the domain. (All roots are complex)
        // No scaling required because p is already 2**96 too large.
        r := sdiv(p, q)
      }
      // r is in the range (0, 0.125) * 2**96

      // Finalization, we need to
      // * multiply by the scale factor s = 5.549…
      // * add ln(2**96 / 10**18)
      // * add k * ln(2)
      // * multiply by 10**18 / 2**96 = 5**18 >> 78
      // mul s * 5e18 * 2**96, base is now 5**18 * 2**192
      r *= 1677202110996718588342820967067443963516166;
      // add ln(2) * k * 5e18 * 2**192
      r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;
      // add ln(2**96 / 10**18) * 5e18 * 2**192
      r += 600920179829731861736702779321621459595472258049074101567377883020018308;
      // base conversion: mul 2**18 / 2**192
      r >>= 174;
    }
  }

  // Integer log2
  // @returns floor(log2(x)) if x is nonzero, otherwise 0. This is the same
  //          as the location of the highest set bit.
  // Consumes 232 gas. This could have been an 3 gas EVM opcode though.
  function ilog2(uint x) internal pure returns (uint r) {
    assembly {
      r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
      r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
      r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
      r := or(r, shl(4, lt(0xffff, shr(r, x))))
      r := or(r, shl(3, lt(0xff, shr(r, x))))
      r := or(r, shl(2, lt(0xf, shr(r, x))))
      r := or(r, shl(1, lt(0x3, shr(r, x))))
      r := or(r, lt(0x1, shr(r, x)))
    }
  }

  // Computes e^x in 1e18 fixed point.
  function exp(int x) internal pure returns (uint r) {
    unchecked {
      // Input x is in fixed point format, with scale factor 1/1e18.

      // When the result is < 0.5 we return zero. This happens when
      // x <= floor(log(0.5e18) * 1e18) ~ -42e18
      if (x <= -42139678854452767551) {
        return 0;
      }

      // When the result is > (2**255 - 1) / 1e18 we can not represent it
      // as an int256. This happens when x >= floor(log((2**255 -1) / 1e18) * 1e18) ~ 135.
      if (x >= 135305999368893231589) revert ExpOverflow();

      // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96
      // for more intermediate precision and a binary basis. This base conversion
      // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.
      x = (x << 78) / 5**18;

      // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers of two
      // such that exp(x) = exp(x') * 2**k, where k is an integer.
      // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).
      int k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96;
      x = x - k * 54916777467707473351141471128;
      // k is in the range [-61, 195].

      // Evaluate using a (6, 7)-term rational approximation
      // p is made monic, we will multiply by a scale factor later
      int p = x + 2772001395605857295435445496992;
      p = ((p * x) >> 96) + 44335888930127919016834873520032;
      p = ((p * x) >> 96) + 398888492587501845352592340339721;
      p = ((p * x) >> 96) + 1993839819670624470859228494792842;
      p = p * x + (4385272521454847904632057985693276 << 96);
      // We leave p in 2**192 basis so we don't need to scale it back up for the division.
      // Evaluate using using Knuth's scheme from p. 491.
      int z = x + 750530180792738023273180420736;
      z = ((z * x) >> 96) + 32788456221302202726307501949080;
      int w = x - 2218138959503481824038194425854;
      w = ((w * z) >> 96) + 892943633302991980437332862907700;
      int q = z + w - 78174809823045304726920794422040;
      q = ((q * w) >> 96) + 4203224763890128580604056984195872;
      assembly {
        // Div in assembly because solidity adds a zero check despite the `unchecked`.
        // The q polynomial is known not to have zeros in the domain. (All roots are complex)
        // No scaling required because p is already 2**96 too large.
        r := sdiv(p, q)
      }
      // r should be in the range (0.09, 0.25) * 2**96.

      // We now need to multiply r by
      //  * the scale factor s = ~6.031367120...,
      //  * the 2**k factor from the range reduction, and
      //  * the 1e18 / 2**96 factor for base converison.
      // We do all of this at once, with an intermediate result in 2**213 basis
      // so the final right shift is always by a positive amount.
      r = (uint(r) * 3822833074963236453042738258902158003155416615667) >> uint(195 - k);
    }
  }

  error Overflow();
  error ExpOverflow();
  error LnNegativeUndefined();
}


// File contracts/libraries/BlackScholes.sol

// -License-Identifier: ISC

//ISC License
//
//Copyright (c) 2021 Lyra Finance
//
//Permission to use, copy, modify, and/or distribute this software for any
//purpose with or without fee is hereby granted, provided that the above
//copyright notice and this permission notice appear in all copies.
//
//THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
//REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
//AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
//INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
//LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
//OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
//PERFORMANCE OF THIS SOFTWARE.

pragma solidity 0.8.9;



/**
* @title BlackScholes
* @author Lyra
* @dev Contract to compute the black scholes price of options. Where the unit is unspecified, it should be treated as a
* PRECISE_DECIMAL, which has 1e27 units of precision. The default decimal matches the ethereum standard of 1e18 units
* of precision.
*/
library BlackScholesLib {
    using DecimalMath for uint;
    using SignedDecimalMath for int;
    
    struct PricesDeltaStdVega {
        uint callPrice;
        uint putPrice;
        int callDelta;
        int putDelta;
        uint vega;
        uint stdVega;
    }
    
    /**
    * @param timeToExpirySec Number of seconds to the expiry of the option
    * @param volatilityDecimal Implied volatility over the period til expiry as a percentage
    * @param spotDecimal The current price of the base asset
    * @param strikePriceDecimal The strikePrice price of the option
    * @param rateDecimal The percentage risk free rate + carry cost
    */
    struct BlackScholesInputs {
        uint timeToExpirySec;
        uint volatilityDecimal;
        uint spotDecimal;
        uint strikePriceDecimal;
        int rateDecimal;
    }
    
    uint private constant SECONDS_PER_YEAR = 31536000;
    /// @dev Internally this library uses 27 decimals of precision
    uint private constant PRECISE_UNIT = 1e27;
    uint private constant SQRT_TWOPI = 2506628274631000502415765285;
    /// @dev Below this value, return 0
    int private constant MIN_CDF_STD_DIST_INPUT = (int(PRECISE_UNIT) * -45) / 10; // -4.5
    /// @dev Above this value, return 1
    int private constant MAX_CDF_STD_DIST_INPUT = int(PRECISE_UNIT) * 10;
    /// @dev Value to use to avoid any division by 0 or values near 0
    uint private constant MIN_T_ANNUALISED = PRECISE_UNIT / SECONDS_PER_YEAR; // 1 second
    uint private constant MIN_VOLATILITY = PRECISE_UNIT / 10000; // 0.001%
    uint private constant VEGA_STANDARDISATION_MIN_DAYS = 7 days;
    /// @dev Magic numbers for normal CDF
    uint private constant SPLIT = 7071067811865470000000000000;
    uint private constant N0 = 220206867912376000000000000000;
    uint private constant N1 = 221213596169931000000000000000;
    uint private constant N2 = 112079291497871000000000000000;
    uint private constant N3 = 33912866078383000000000000000;
    uint private constant N4 = 6373962203531650000000000000;
    uint private constant N5 = 700383064443688000000000000;
    uint private constant N6 = 35262496599891100000000000;
    uint private constant M0 = 440413735824752000000000000000;
    uint private constant M1 = 793826512519948000000000000000;
    uint private constant M2 = 637333633378831000000000000000;
    uint private constant M3 = 296564248779674000000000000000;
    uint private constant M4 = 86780732202946100000000000000;
    uint private constant M5 = 16064177579207000000000000000;
    uint private constant M6 = 1755667163182640000000000000;
    uint private constant M7 = 88388347648318400000000000;
    
    /////////////////////////////////////
    // Option Pricing public functions //
    /////////////////////////////////////
    
    /**
    * @dev Returns call and put prices for options with given parameters.
    */
    function optionPrices(BlackScholesInputs memory bsInput) public pure returns (uint call, uint put) {
        uint tAnnualised = _annualise(bsInput.timeToExpirySec);
        uint spotPrecise = bsInput.spotDecimal.decimalToPreciseDecimal();
        uint strikePricePrecise = bsInput.strikePriceDecimal.decimalToPreciseDecimal();
        int ratePrecise = bsInput.rateDecimal.decimalToPreciseDecimal();
        (int d1, int d2) = _d1d2(
            tAnnualised,
            bsInput.volatilityDecimal.decimalToPreciseDecimal(),
            spotPrecise,
            strikePricePrecise,
            ratePrecise
        );
        (call, put) = _optionPrices(tAnnualised, spotPrecise, strikePricePrecise, ratePrecise, d1, d2);
        return (call.preciseDecimalToDecimal(), put.preciseDecimalToDecimal());
    }
    
    /**
    * @dev Returns call/put prices and delta/stdVega for options with given parameters.
    */
    function pricesDeltaStdVega(BlackScholesInputs memory bsInput) public pure returns (PricesDeltaStdVega memory) {
        uint tAnnualised = _annualise(bsInput.timeToExpirySec);
        uint spotPrecise = bsInput.spotDecimal.decimalToPreciseDecimal();
        
        (int d1, int d2) = _d1d2(
            tAnnualised,
            bsInput.volatilityDecimal.decimalToPreciseDecimal(),
            spotPrecise,
            bsInput.strikePriceDecimal.decimalToPreciseDecimal(),
            bsInput.rateDecimal.decimalToPreciseDecimal()
        );
        (uint callPrice, uint putPrice) = _optionPrices(
            tAnnualised,
            spotPrecise,
            bsInput.strikePriceDecimal.decimalToPreciseDecimal(),
            bsInput.rateDecimal.decimalToPreciseDecimal(),
            d1,
            d2
        );
        (uint vegaPrecise, uint stdVegaPrecise) = _standardVega(d1, spotPrecise, bsInput.timeToExpirySec);
        (int callDelta, int putDelta) = _delta(d1);
        
        return
        PricesDeltaStdVega(
            callPrice.preciseDecimalToDecimal(),
            putPrice.preciseDecimalToDecimal(),
            callDelta.preciseDecimalToDecimal(),
            putDelta.preciseDecimalToDecimal(),
            vegaPrecise.preciseDecimalToDecimal(),
            stdVegaPrecise.preciseDecimalToDecimal()
        );
    }
    
    /**
    * @dev Returns call delta given parameters.
    */
    
    function delta(BlackScholesInputs memory bsInput) public pure returns (int callDeltaDecimal, int putDeltaDecimal) {
        uint tAnnualised = _annualise(bsInput.timeToExpirySec);
        uint spotPrecise = bsInput.spotDecimal.decimalToPreciseDecimal();
        
        (int d1, ) = _d1d2(
            tAnnualised,
            bsInput.volatilityDecimal.decimalToPreciseDecimal(),
            spotPrecise,
            bsInput.strikePriceDecimal.decimalToPreciseDecimal(),
            bsInput.rateDecimal.decimalToPreciseDecimal()
        );
        
        (int callDelta, int putDelta) = _delta(d1);
        return (callDelta.preciseDecimalToDecimal(), putDelta.preciseDecimalToDecimal());
    }
    
    /**
    * @dev Returns non-normalized vega given parameters. Quoted in cents.
    */
    function vega(BlackScholesInputs memory bsInput) public pure returns (uint vegaDecimal) {
        uint tAnnualised = _annualise(bsInput.timeToExpirySec);
        uint spotPrecise = bsInput.spotDecimal.decimalToPreciseDecimal();
        
        (int d1, ) = _d1d2(
            tAnnualised,
            bsInput.volatilityDecimal.decimalToPreciseDecimal(),
            spotPrecise,
            bsInput.strikePriceDecimal.decimalToPreciseDecimal(),
            bsInput.rateDecimal.decimalToPreciseDecimal()
        );
        return _vega(tAnnualised, spotPrecise, d1).preciseDecimalToDecimal();
    }
    
    //////////////////////
    // Computing Greeks //
    //////////////////////
    
    /**
    * @dev Returns internal coefficients of the Black-Scholes call price formula, d1 and d2.
    * @param tAnnualised Number of years to expiry
    * @param volatility Implied volatility over the period til expiry as a percentage
    * @param spot The current price of the base asset
    * @param strikePrice The strikePrice price of the option
    * @param rate The percentage risk free rate + carry cost
    */
    function _d1d2(
        uint tAnnualised,
        uint volatility,
        uint spot,
        uint strikePrice,
        int rate
    ) internal pure returns (int d1, int d2) {
        // Set minimum values for tAnnualised and volatility to not break computation in extreme scenarios
        // These values will result in option prices reflecting only the difference in stock/strikePrice, which is expected.
        // This should be caught before calling this function, however the function shouldn't break if the values are 0.
        tAnnualised = tAnnualised < MIN_T_ANNUALISED ? MIN_T_ANNUALISED : tAnnualised;
        volatility = volatility < MIN_VOLATILITY ? MIN_VOLATILITY : volatility;
        
        int vtSqrt = int(volatility.multiplyDecimalRoundPrecise(_sqrtPrecise(tAnnualised)));
        int log = HigherMath.lnPrecise(int(spot.divideDecimalRoundPrecise(strikePrice)));
        int v2t = (int(volatility.multiplyDecimalRoundPrecise(volatility) / 2) + rate).multiplyDecimalRoundPrecise(
            int(tAnnualised)
        );
        d1 = (log + v2t).divideDecimalRoundPrecise(vtSqrt);
        d2 = d1 - vtSqrt;
    }
    
    /**
    * @dev Internal coefficients of the Black-Scholes call price formula.
    * @param tAnnualised Number of years to expiry
    * @param spot The current price of the base asset
    * @param strikePrice The strikePrice price of the option
    * @param rate The percentage risk free rate + carry cost
    * @param d1 Internal coefficient of Black-Scholes
    * @param d2 Internal coefficient of Black-Scholes
    */
    function _optionPrices(
        uint tAnnualised,
        uint spot,
        uint strikePrice,
        int rate,
        int d1,
        int d2
    ) internal pure returns (uint call, uint put) {
        uint strikePricePV = strikePrice.multiplyDecimalRoundPrecise(
            HigherMath.expPrecise(int(-rate.multiplyDecimalRoundPrecise(int(tAnnualised))))
        );
        uint spotNd1 = spot.multiplyDecimalRoundPrecise(_stdNormalCDF(d1));
        uint strikePriceNd2 = strikePricePV.multiplyDecimalRoundPrecise(_stdNormalCDF(d2));
        
        // We clamp to zero if the minuend is less than the subtrahend
        // In some scenarios it may be better to compute put price instead and derive call from it depending on which way
        // around is more precise.
        call = strikePriceNd2 <= spotNd1 ? spotNd1 - strikePriceNd2 : 0;
        put = call + strikePricePV;
        put = spot <= put ? put - spot : 0;
    }
    
    /*
    * Greeks
    */
    
    /**
    * @dev Returns the option's delta value
    * @param d1 Internal coefficient of Black-Scholes
    */
    function _delta(int d1) internal pure returns (int callDelta, int putDelta) {
        callDelta = int(_stdNormalCDF(d1));
        putDelta = callDelta - int(PRECISE_UNIT);
    }
    
    /**
    * @dev Returns the option's vega value based on d1. Quoted in cents.
    *
    * @param d1 Internal coefficient of Black-Scholes
    * @param tAnnualised Number of years to expiry
    * @param spot The current price of the base asset
    */
    function _vega(
        uint tAnnualised,
        uint spot,
        int d1
    ) internal pure returns (uint) {
        return _sqrtPrecise(tAnnualised).multiplyDecimalRoundPrecise(_stdNormal(d1).multiplyDecimalRoundPrecise(spot));
    }
    
    /**
    * @dev Returns the option's vega value with expiry modified to be at least VEGA_STANDARDISATION_MIN_DAYS
    * @param d1 Internal coefficient of Black-Scholes
    * @param spot The current price of the base asset
    * @param timeToExpirySec Number of seconds to expiry
    */
    function _standardVega(
        int d1,
        uint spot,
        uint timeToExpirySec
    ) internal pure returns (uint, uint) {
        uint tAnnualised = _annualise(timeToExpirySec);
        uint normalisationFactor = _getVegaNormalisationFactorPrecise(timeToExpirySec);
        uint vegaPrecise = _vega(tAnnualised, spot, d1);
        return (vegaPrecise, vegaPrecise.multiplyDecimalRoundPrecise(normalisationFactor));
    }
    
    function _getVegaNormalisationFactorPrecise(uint timeToExpirySec) internal pure returns (uint) {
        timeToExpirySec = timeToExpirySec < VEGA_STANDARDISATION_MIN_DAYS ? VEGA_STANDARDISATION_MIN_DAYS : timeToExpirySec;
        uint daysToExpiry = timeToExpirySec / 1 days;
        uint thirty = 30 * PRECISE_UNIT;
        return _sqrtPrecise(thirty / daysToExpiry) / 100;
    }
    
    /////////////////////
    // Math Operations //
    /////////////////////
    
    /**
    * @dev Compute the absolute value of `val`.
    *
    * @param val The number to absolute value.
    */
    function _abs(int val) internal pure returns (uint) {
        return uint(val < 0 ? -val : val);
    }
    
    /// @notice Calculates the square root of x, rounding down (borrowed from https://github.com/paulrberg/prb-math)
    /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.
    /// @param x The uint256 number for which to calculate the square root.
    /// @return result The result as an uint256.
    function _sqrt(uint x) internal pure returns (uint result) {
        if (x == 0) {
            return 0;
        }
        
        // Calculate the square root of the perfect square of a power of two that is the closest to x.
        uint xAux = uint(x);
        result = 1;
        if (xAux >= 0x100000000000000000000000000000000) {
            xAux >>= 128;
            result <<= 64;
        }
        if (xAux >= 0x10000000000000000) {
            xAux >>= 64;
            result <<= 32;
        }
        if (xAux >= 0x100000000) {
            xAux >>= 32;
            result <<= 16;
        }
        if (xAux >= 0x10000) {
            xAux >>= 16;
            result <<= 8;
        }
        if (xAux >= 0x100) {
            xAux >>= 8;
            result <<= 4;
        }
        if (xAux >= 0x10) {
            xAux >>= 4;
            result <<= 2;
        }
        if (xAux >= 0x8) {
            result <<= 1;
        }
        
        // The operations can never overflow because the result is max 2^127 when it enters this block.
        unchecked {
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1; // Seven iterations should be enough
            uint roundedDownResult = x / result;
            return result >= roundedDownResult ? roundedDownResult : result;
        }
    }
    
    /**
    * @dev Returns the square root of the value using Newton's method.
    */
    function _sqrtPrecise(uint x) internal pure returns (uint) {
        // Add in an extra unit factor for the square root to gobble;
        // otherwise, sqrt(x * UNIT) = sqrt(x) * sqrt(UNIT)
        return _sqrt(x * PRECISE_UNIT);
    }
    
    /**
    * @dev The standard normal distribution of the value.
    */
    function _stdNormal(int x) internal pure returns (uint) {
        return
        HigherMath.expPrecise(int(-x.multiplyDecimalRoundPrecise(x / 2))).divideDecimalRoundPrecise(SQRT_TWOPI);
    }
    
    /**
    * @dev The standard normal cumulative distribution of the value.
    * borrowed from a C++ implementation https://stackoverflow.com/a/23119456
    */
    function _stdNormalCDF(int x) public pure returns (uint) {
        uint z = _abs(x);
        int c;
        
        if (z <= 37 * PRECISE_UNIT) {
            uint e = HigherMath.expPrecise(-int(z.multiplyDecimalRoundPrecise(z / 2)));
            if (z < SPLIT) {
                c = int(
                    (_stdNormalCDFNumerator(z).divideDecimalRoundPrecise(_stdNormalCDFDenom(z)).multiplyDecimalRoundPrecise(e))
                );
            } else {
                uint f = (z +
                    PRECISE_UNIT.divideDecimalRoundPrecise(
                        z +
                        (2 * PRECISE_UNIT).divideDecimalRoundPrecise(
                            z +
                            (3 * PRECISE_UNIT).divideDecimalRoundPrecise(
                                z + (4 * PRECISE_UNIT).divideDecimalRoundPrecise(z + ((PRECISE_UNIT * 13) / 20))
                            )
                        )
                    ));
                    c = int(e.divideDecimalRoundPrecise(f.multiplyDecimalRoundPrecise(SQRT_TWOPI)));
                }
            }
        return uint((x <= 0 ? c : (int(PRECISE_UNIT) - c)));
    }
        
    /**
    * @dev Helper for _stdNormalCDF
    */
    function _stdNormalCDFNumerator(uint z) internal pure returns (uint) {
        uint numeratorInner = ((((((N6 * z) / PRECISE_UNIT + N5) * z) / PRECISE_UNIT + N4) * z) / PRECISE_UNIT + N3);
        return (((((numeratorInner * z) / PRECISE_UNIT + N2) * z) / PRECISE_UNIT + N1) * z) / PRECISE_UNIT + N0;
    }
    
    /**
    * @dev Helper for _stdNormalCDF
    */
    function _stdNormalCDFDenom(uint z) internal pure returns (uint) {
        uint denominatorInner = ((((((M7 * z) / PRECISE_UNIT + M6) * z) / PRECISE_UNIT + M5) * z) / PRECISE_UNIT + M4);
        return
        (((((((denominatorInner * z) / PRECISE_UNIT + M3) * z) / PRECISE_UNIT + M2) * z) / PRECISE_UNIT + M1) * z) /
        PRECISE_UNIT +
        M0;
    }
    
    /**
    * @dev Converts an integer number of seconds to a fractional number of years.
    */
    function _annualise(uint secs) internal pure returns (uint yearFraction) {
        return secs.divideDecimalRoundPrecise(SECONDS_PER_YEAR);
    }
}


// File contracts/core/CallSellingVault.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;












contract CallSellingVault is IPolynomialVault, Auth, ReentrancyGuard, Pausable {
    /// -----------------------------------------------------------------------
    /// Library usage
    /// -----------------------------------------------------------------------
    using FixedPointMathLib for uint256;
    using SafeTransferLib for ERC20;

    /// -----------------------------------------------------------------------
    /// Data Structures
    /// -----------------------------------------------------------------------

    struct PositionData {
        uint256 positionId;
        uint256 amount;
        uint256 collateral;
        int256 premiumCollected;
    }

    struct QueuedDeposit {
        uint256 id;
        address user;
        uint256 depositedAmount;
        uint256 mintedTokens;
        uint256 requestedTime;
    }

    struct QueuedWithdraw {
        uint256 id;
        address user;
        uint256 withdrawnTokens;
        uint256 returnedAmount;
        uint256 requestedTime;
    }

    /// -----------------------------------------------------------------------
    /// Constants
    /// -----------------------------------------------------------------------

    IOptionMarket.OptionType private constant OPTION_TYPE = IOptionMarket.OptionType.SHORT_CALL_BASE;

    /// -----------------------------------------------------------------------
    /// Immutable parameters
    /// -----------------------------------------------------------------------

    /// @notice Human Readable Name of the Vault
    bytes32 public immutable name;

    /// @notice Synthetix Synth key of the underlying token
    bytes32 public immutable UNDERLYING_SYNTH_KEY;

    /// @notice Underlying Asset
    ERC20 public immutable UNDERLYING;

    /// @notice sUSD
    ERC20 public immutable SUSD;

    /// @notice Corresponding vault token
    IPolynomialVaultToken public immutable VAULT_TOKEN;

    /// @notice Lyra Option Market
    IOptionMarket public immutable MARKET;

    /// @notice Lyra Option Market Wrapper
    IOptionMarketWrapperWithSwaps public immutable MARKET_WRAPPER;

    /// @notice Lyra Option Token
    IOptionToken public immutable OPTION_TOKEN;

    /// @notice Lyra Options Greek Cache
    IOptionGreekCache public immutable GREEKS;

    /// @notice Synthetix Exchange
    ISynthetix public immutable SYNTHETIX;

    /// @notice Synthetix Exchange Rates
    IExchangeRates public immutable RATES;

    /// -----------------------------------------------------------------------
    /// Storage variables
    /// -----------------------------------------------------------------------

    /// @notice Collateralization ratio
    uint256 public collateralization;

    /// @notice Minimum deposit amount
    uint256 public minDepositAmount;

    /// @notice Minimum deposit delay
    uint256 public minDepositDelay;

    /// @notice Minimum withdrawal delay
    uint256 public minWithdrawDelay;

    /// @notice GWAV Length
    uint256 public gwavLength;

    /// @notice Trade Iterations
    uint256 public tradeIterations;

    /// @notice Delta cutoff for trades
    int256 public deltaCutoff;

    /// @notice Fee Receipient
    address public feeReceipient;

    /// @notice Performance Fee 
    uint256 public performanceFee;

    /// @notice Withdrawal Fee
    uint256 public withdrawalFee;

    /// @notice Synthetix Tracking Code
    bytes32 public synthetixTrackingCode;

    /// @notice Total queued deposits
    uint256 public totalQueuedDeposits;

    /// @notice Total queued withdrawals
    uint256 public totalQueuedWithdrawals;

    /// @notice Next deposit queue item that needs to be processed
    uint256 public queuedDepositHead = 1;

    /// @notice Next deposit queue ID that needs to be processed
    uint256 public nextQueuedDepositId = 1;

    /// @notice Next withdrawal queue item that needs to be processed
    uint256 public queuedWithdrawalHead = 1;

    /// @notice Next withdrawal queue ID that needs to be processed
    uint256 public nextQueuedWithdrawalId = 1;

    /// @notice Total funds
    uint256 public totalFunds;

    /// @notice Used funds
    uint256 public usedFunds;

    /// @notice Total premium collected
    int256 public totalPremiumCollected;

    /// @notice An array of active strike IDs
    uint256[] public liveStrikes;

    /// @notice Strike ID => Position Data
    mapping (uint256 => PositionData) public positionDatas;

    /// @notice Deposit Queue
    mapping (uint256 => QueuedDeposit) public depositQueue;

    /// @notice Withdrawal Queue
    mapping (uint256 => QueuedWithdraw) public withdrawalQueue;

    constructor(
        ERC20 _underlying,
        ERC20 _susd,
        IPolynomialVaultToken _vaultToken,
        IOptionMarket _market,
        IOptionMarketWrapperWithSwaps _marketWrapper,
        IOptionToken _optionToken,
        IOptionGreekCache _greeks,
        ISynthetix _synthetix,
        IExchangeRates _exchangeRates,
        bytes32 _underlyingKey,
        bytes32 _name
    ) Auth(msg.sender, Authority(address(0x0))) {
        UNDERLYING = _underlying;
        VAULT_TOKEN = _vaultToken;
        MARKET = _market;
        MARKET_WRAPPER = _marketWrapper;
        OPTION_TOKEN = _optionToken;
        GREEKS = _greeks;
        SYNTHETIX = _synthetix;
        RATES = _exchangeRates;
        UNDERLYING_SYNTH_KEY = _underlyingKey;
        SUSD = _susd;
        name = _name;
    }

    /// -----------------------------------------------------------------------
    /// User actions
    /// -----------------------------------------------------------------------

    /// @notice Initiate deposit to the vault
    /// @notice If there are no active positions, deposits are processed immediately
    /// @notice Otherwise it is added to the deposit queue
    /// @param user Address of the user to receive the VAULT_TOKENs upon processing
    /// @param amount Amount of UNDERLYING being depositted
    function initiateDeposit(address user, uint256 amount) external nonReentrant whenDepositsNotPaused {
        if (user == address(0x0)) {
            revert ExpectedNonZero();
        }

        if (amount < minDepositAmount) {
            revert MinimumDepositRequired(minDepositAmount, amount);
        }

        // Instant processing
        if (liveStrikes.length == 0) {
            uint256 tokenPrice =  getTokenPrice();
            uint256 tokensToMint = amount.divWadDown(tokenPrice);

            VAULT_TOKEN.mint(user, tokensToMint);
    
            totalFunds += amount;
            emit ProcessDeposit(0, user, amount, tokensToMint, block.timestamp);
        } else {
            // Queueing the deposit request 
            QueuedDeposit storage newDeposit = depositQueue[nextQueuedDepositId];

            newDeposit.id = nextQueuedDepositId++;
            newDeposit.user = user;
            newDeposit.depositedAmount = amount;
            newDeposit.requestedTime = block.timestamp;

            totalQueuedDeposits += amount;
            emit InitiateDeposit(newDeposit.id, msg.sender, user, amount);
        }

        UNDERLYING.safeTransferFrom(msg.sender, address(this), amount);
      
    }

    /// @notice Initiate withdrawal from the vault
    /// @notice If there are no active positions, withdrawals are processed instantly
    /// @notice Otherwise the request is added to the withdrawal queue
    /// @param user Address of the user to receive the UNDERLYING upon processing
    /// @param tokens Amounts of VAULT_TOKENs being requested to burn / withdraw
    function initiateWithdrawal(address user, uint256 tokens) external nonReentrant {
        if (user == address(0x0)) {
            revert ExpectedNonZero();
        }

        // Instant withdrawal
        if (liveStrikes.length == 0) {
            uint256 tokenPrice = getTokenPrice();
            uint256 underlyingToReturn = tokens.mulWadDown(tokenPrice);
            UNDERLYING.safeTransfer(user, underlyingToReturn);
            totalFunds -= underlyingToReturn;
            emit ProcessWithdrawal(0, user, tokens, underlyingToReturn, block.timestamp);
        } else {
            // Queueing the withdrawal request
            QueuedWithdraw storage newWithdraw = withdrawalQueue[nextQueuedWithdrawalId];

            newWithdraw.id = nextQueuedWithdrawalId++;
            newWithdraw.user = user;
            newWithdraw.withdrawnTokens = tokens;
            newWithdraw.requestedTime = block.timestamp;

            totalQueuedWithdrawals += tokens;
            emit InitiateWithdrawal(newWithdraw.id, msg.sender, user, tokens);
        }

        VAULT_TOKEN.burn(msg.sender, tokens);
    }

    /// @notice Process queued deposit requests
    /// @param idCount Number of deposit queue items to process
    function processDepositQueue(uint256 idCount) external nonReentrant {
        uint256 tokenPrice = getTokenPrice();

        for (uint256 i = 0; i < idCount; i++) {
            QueuedDeposit storage current = depositQueue[queuedDepositHead];

            if (current.requestedTime == 0 || block.timestamp < current.requestedTime + minDepositDelay) {
                return;
            }

            uint256 tokensToMint = current.depositedAmount.divWadDown(tokenPrice);

            current.mintedTokens = tokensToMint;
            totalQueuedDeposits -= current.depositedAmount;
            totalFunds += current.depositedAmount;
            VAULT_TOKEN.mint(current.user, tokensToMint);

            emit ProcessDeposit(
                current.id, current.user, current.depositedAmount, current.mintedTokens, current.requestedTime
            );

            current.depositedAmount = 0;
            queuedDepositHead++;
        }
    }

    /// @notice Process queued withdrawal requests
    /// @param idCount Number of withdrawal queue items to process
    function processWithdrawalQueue(uint256 idCount) external nonReentrant {
        for (uint256 i = 0; i < idCount; i++) {
            uint256 tokenPrice = getTokenPrice();

            QueuedWithdraw storage current = withdrawalQueue[queuedWithdrawalHead];

            if (current.requestedTime == 0 || block.timestamp < current.requestedTime + minWithdrawDelay) {
                return;
            }

            uint256 availableFunds = totalFunds - usedFunds;

            if (availableFunds == 0) {
                return;
            }

            uint256 underlyingToReturn = current.withdrawnTokens.mulWadDown(tokenPrice);

            // Partial withdrawals if not enough available funds in the vault
            // Queue head is not increased
            if (underlyingToReturn > availableFunds) {
                current.returnedAmount = availableFunds;
                uint256 tokensBurned = availableFunds.divWadUp(tokenPrice);

                totalQueuedWithdrawals -= tokensBurned;
                current.withdrawnTokens -= tokensBurned;

                totalFunds -= availableFunds;

                if (withdrawalFee > 0) {
                    uint256 withdrawFees = availableFunds.mulWadDown(withdrawalFee);
                    UNDERLYING.safeTransfer(feeReceipient, withdrawFees);
                    availableFunds -= withdrawFees;
                }

                UNDERLYING.safeTransfer(current.user, availableFunds);

                emit ProcessWithdrawalPartially(
                    current.id, current.user, tokensBurned, availableFunds, current.requestedTime
                );
                return;
            } else {
                // Complete full withdrawal
                current.returnedAmount = underlyingToReturn;
                totalQueuedWithdrawals -= current.withdrawnTokens;
                current.withdrawnTokens = 0;

                totalFunds -= underlyingToReturn;

                if (withdrawalFee > 0) {
                    uint256 withdrawFees = underlyingToReturn.mulWadDown(withdrawalFee);
                    UNDERLYING.safeTransfer(feeReceipient, withdrawFees);
                    underlyingToReturn -= withdrawFees;
                }

                UNDERLYING.safeTransfer(current.user, underlyingToReturn);

                emit ProcessWithdrawal(
                    current.id, current.user, current.withdrawnTokens, underlyingToReturn, current.requestedTime
                );
            }

            queuedWithdrawalHead++;
        }
    }

    /// -----------------------------------------------------------------------    
    /// View methods
    /// -----------------------------------------------------------------------

    /// @notice Get VAULT_TOKEN price
    /// @notice Calculated using the Black-Scholes price of active option positions
    function getTokenPrice() public view returns (uint256) {
        if (totalFunds == 0) {
            return 1e18;
        }

        uint256 totalSupply = getTotalSupply();
        if (liveStrikes.length == 0) {
            return totalFunds.divWadDown(totalSupply);
        }

        uint256 totalValue = totalFunds + uint256(totalPremiumCollected);

        (uint256 spotPrice, bool isInvalid) = RATES.rateAndInvalid(UNDERLYING_SYNTH_KEY);

        if (spotPrice == 0 || isInvalid) {
            revert InvalidPrice(spotPrice, isInvalid);
        }

        for (uint256 i = 0; i < liveStrikes.length; i++) {
            uint256 strikeId = liveStrikes[i];

            PositionData memory position = positionDatas[strikeId];
            
            (uint256 callPremiumInUsd, ) = getPremiumForStrike(strikeId);
            uint256 callPremium = callPremiumInUsd.divWadDown(spotPrice);
            totalValue -= callPremium.mulWadDown(position.amount);
        }
        return totalValue.divWadDown(totalSupply);
    }

    /// @notice Returns the total supply of the VAULT_TOKEN
    function getTotalSupply() public view returns (uint256) {
        return VAULT_TOKEN.totalSupply() + totalQueuedWithdrawals;
    }

    /// @notice Returns liveStrikes array
    function getLiveStrikes() public view returns (uint256[] memory) {
        return liveStrikes;
    }

    /// -----------------------------------------------------------------------    
    /// Internal View methods
    /// -----------------------------------------------------------------------

    /// @notice Returns the Black-Scholes premium of call and put options
    /// @param _strikeId Lyra Strike ID
    function getPremiumForStrike(uint256 _strikeId) internal view returns (uint256 callPremium, uint256 putPremium) {
        (
            IOptionMarket.Strike memory strike,
            IOptionMarket.OptionBoard memory board
        ) = MARKET.getStrikeAndBoard(_strikeId);

        (uint256 spotPrice, bool isInvalid) = RATES.rateAndInvalid(UNDERLYING_SYNTH_KEY);

        if (spotPrice == 0 || isInvalid) {
            revert InvalidPrice(spotPrice, isInvalid);
        }

        if (block.timestamp > board.expiry) {
            (
                ,
                uint priceAtExpiry,
                uint ammShortCallBaseProfitRatio
            ) = MARKET.getSettlementParameters(_strikeId);

            if (priceAtExpiry == 0) {
                revert InvalidExpiryPrice();
            }

            callPremium = ammShortCallBaseProfitRatio.mulWadDown(spotPrice);
        } else {
            uint256 boardIv = GREEKS.getIvGWAV(board.id, gwavLength);
            uint256 strikeSkew = GREEKS.getSkewGWAV(_strikeId, gwavLength);
            BlackScholesLib.BlackScholesInputs memory bsInput = BlackScholesLib.BlackScholesInputs({
                timeToExpirySec: board.expiry - block.timestamp,
                volatilityDecimal: boardIv.mulWadDown(strikeSkew),
                spotDecimal: spotPrice,
                strikePriceDecimal: strike.strikePrice,
                rateDecimal: GREEKS.getGreekCacheParams().rateAndCarry
            });
    
            (callPremium, putPremium) = BlackScholesLib.optionPrices(bsInput);
        }
    }

    /// @notice Returns the delta of the call option given its strike ID
    /// @param _strikeId Lyra Strike ID
    function getCallDelta(uint256 _strikeId) internal view returns (int256 callDelta) {
        (
            IOptionMarket.Strike memory strike,
            IOptionMarket.OptionBoard memory board
        ) = MARKET.getStrikeAndBoard(_strikeId);

        (uint256 spotPrice, bool isInvalid) = RATES.rateAndInvalid(UNDERLYING_SYNTH_KEY);

        if (spotPrice == 0 || isInvalid) {
            revert InvalidPrice(spotPrice, isInvalid);
        }

        BlackScholesLib.BlackScholesInputs memory bsInput = BlackScholesLib.BlackScholesInputs({
            timeToExpirySec: board.expiry - block.timestamp,
            volatilityDecimal: board.iv.mulWadDown(strike.skew),
            spotDecimal: spotPrice,
            strikePriceDecimal: strike.strikePrice,
            rateDecimal: GREEKS.getGreekCacheParams().rateAndCarry
        });

        (callDelta, ) = BlackScholesLib.delta(bsInput);
    }

    /// -----------------------------------------------------------------------
    /// Keeper actions
    /// -----------------------------------------------------------------------

    /// @notice Open a short call position
    /// @param strikeId Lyra strike ID of the call option
    /// @param amount Amount of options to short
    function openPosition(uint256 strikeId, uint256 amount) external requiresAuth nonReentrant whenNotPaused {
        _openShortPosition(strikeId, amount);
    }

    /// @notice Close an active short call position
    /// @param strikeId Lyra strike ID of the call option
    /// @param amount Amount of options to close
    /// @param premiumAmount Amount of UNDERLYING to convert to sUSD to pay back the premium
    function closePosition(uint256 strikeId, uint256 amount, uint256 premiumAmount) external requiresAuth nonReentrant whenNotPaused {
        _closeShortPosition(strikeId, amount, premiumAmount);
    }

    /// @notice Add additional collateral to an active short position
    /// @param strikeId Lyra strike ID of the call option
    /// @param amount Amount of additional UNDERLYING to add
    function addCollateral(uint256 strikeId, uint256 amount) external requiresAuth nonReentrant whenNotPaused {
        _addCollateral(strikeId, amount);
    }

    /// @notice Calculat the accounting of settled options
    /// @param strikeIds Array of strike IDs
    function settleOptions(uint256[] memory strikeIds) external requiresAuth nonReentrant whenNotPaused {
        _settleOptions(strikeIds);
    }

    /// -----------------------------------------------------------------------
    /// Owner actions
    /// -----------------------------------------------------------------------

    /// @notice Pause contracts
    function pause() external requiresAuth {
        _pause();
    }

    /// @notice Pause deposits
    function pauseDeposits() external requiresAuth {
        _pauseDeposits();
    }

    /// @notice Unpause contracts
    function unpause() external requiresAuth {
        _unpause();
    }

    /// @notice Unpause deposits
    function unpauseDeposits() external requiresAuth {
        _unpauseDeposits();
    }

    /// @notice Set collateralization ratio for selling option
    /// @param _ratio Collateralization ratio in 18 decimals
    function setCollateralization(uint256 _ratio) external requiresAuth {
        if (_ratio > 1e18 || _ratio < 5e17) {
            revert InvalidCollateralization(collateralization, _ratio);
        }

        emit UpdateCollateralization(collateralization, _ratio);

        collateralization = _ratio;
    }

    /// @notice Set fee receipient address
    /// @param _feeReceipient Address of the new fee receipient
    function setFeeReceipient(address _feeReceipient) external requiresAuth {
        if (_feeReceipient == address(0x0)) {
            revert ExpectedNonZero();
        }

        emit UpdateFeeReceipient(feeReceipient, _feeReceipient);

        feeReceipient = _feeReceipient;
    }

    /// @notice Set Fees
    /// @param _performanceFee New Performance Fee
    /// @param _withdrawalFee New Withdrawal Fee
    function setFees(uint256 _performanceFee, uint256 _withdrawalFee) external requiresAuth {
        if (_performanceFee > 1e17 || _withdrawalFee > 1e16) {
            revert FeesTooHigh(performanceFee, withdrawalFee, _performanceFee, _withdrawalFee);
        }

        emit UpdateFees(
            performanceFee, withdrawalFee, _performanceFee, _withdrawalFee
        );

        performanceFee = _performanceFee;
        withdrawalFee = _withdrawalFee;
    }

    /// @notice Set Synthetix Volume Program Tracking Code
    /// @param _code New tracking code
    function setSynthetixTracking(bytes32 _code) external requiresAuth {
        emit UpdateSynthetixTrackingCode(synthetixTrackingCode, _code);
        synthetixTrackingCode = _code;
    }

    /// @notice Set Minimum deposit amount
    /// @param _minAmt Minimum deposit amount
    function setMinDepositAmount(uint256 _minAmt) external requiresAuth {
        emit UpdateMinDeposit(minDepositAmount, _minAmt);
        minDepositAmount = _minAmt;
    }

    /// @notice Set Deposit and Withdrawal delays
    /// @param _depositDelay New Deposit Delay
    /// @param _withdrawDelay New Withdrawal Delay
    function setDelays(uint256 _depositDelay, uint256 _withdrawDelay) external requiresAuth {
        emit UpdateDelays(minDepositDelay, _depositDelay, minWithdrawDelay, _withdrawDelay);
        minDepositDelay = _depositDelay;
        minWithdrawDelay = _withdrawDelay;
    }

    /// @notice Set GWAV Length
    /// @param length Length in seconds
    function setGWAVLength(uint256 length) external requiresAuth {
        emit UpdateGWAVLength(gwavLength, length);
        gwavLength = length;
    }

    /// @notice Set Trade iterations
    /// @param _iterations Trade iterations
    function setIterations(uint256 _iterations) external requiresAuth {
        emit UpdateTradeIterations(tradeIterations, _iterations);
        tradeIterations = _iterations;
    }

    /// @notice Set Delta Cutoff
    /// @param _deltaCutoff Delta cutoff value
    function setDeltaCutoff(int256 _deltaCutoff) external requiresAuth {
        if (_deltaCutoff < 5e17) {
            emit UpdateDeltaCutoff(deltaCutoff, _deltaCutoff);
            deltaCutoff = _deltaCutoff;
        }
    }

    /// @notice Save ERC20 token from the vault (not SUSD or UNDERLYING)
    /// @param token Address of the token
    /// @param receiver Address of the receiver
    /// @param amt Amount to save
    function saveToken(address token, address receiver, uint256 amt) external requiresAuth {
        require(token != address(UNDERLYING) || token != address(SUSD));
        ERC20(token).transfer(receiver, amt);
    }

    /// -----------------------------------------------------------------------
    /// Internal Methods
    /// -----------------------------------------------------------------------

    function _openShortPosition(uint256 _strikeId, uint256 _amt) internal {
        int256 callDelta = getCallDelta(_strikeId);

        // Options with delta higher than 0.25 should not be traded by the vault
        if (callDelta > deltaCutoff) {
            revert OptionTooRisky(_strikeId, uint256(callDelta));
        }

        PositionData storage positionData = positionDatas[_strikeId];

        if (
            positionData.positionId != 0 &&
            OPTION_TOKEN.getApproved(positionData.positionId) != address(MARKET_WRAPPER)
        ) {
            OPTION_TOKEN.approve(address(MARKET_WRAPPER), positionData.positionId);
        }

        uint256 collateralReq = _amt.mulWadDown(collateralization);
        usedFunds += collateralReq;

        if (usedFunds > totalFunds) {
            revert InsufficientFunds(totalFunds, usedFunds - collateralReq, collateralReq);
        }

        uint256 totalCollateral = positionData.collateral + collateralReq;

        UNDERLYING.safeApprove(address(MARKET_WRAPPER), collateralReq);

        IOptionMarketWrapperWithSwaps.OptionPositionParams memory params;

        params.optionMarket = MARKET;
        params.strikeId = _strikeId;
        params.positionId = positionData.positionId;
        params.iterations = tradeIterations;
        params.setCollateralTo = totalCollateral;
        params.currentCollateral = positionData.collateral;
        params.optionType = OPTION_TYPE;
        params.amount = _amt;
        params.minCost = 0;
        params.maxCost = type(uint256).max;
        params.inputAmount = 0;
        params.inputAsset = SUSD;

        // Open position
        IOptionMarketWrapperWithSwaps.ReturnDetails memory returnDetails = MARKET_WRAPPER.openPosition(params);

        // Converted collected premium (in sUSD) to UNDERLYING
        uint256 underlyingReceived = SYNTHETIX.exchangeWithTracking(
            "sUSD",
            returnDetails.totalCost,
            UNDERLYING_SYNTH_KEY,
            feeReceipient,
            synthetixTrackingCode
        );

        positionData.collateral = totalCollateral;
        positionData.amount += _amt;
        positionData.premiumCollected += int256(underlyingReceived);
        totalPremiumCollected += int256(underlyingReceived);

        if (positionData.positionId == 0) {
            positionData.positionId = returnDetails.positionId;
            liveStrikes.push(_strikeId);
        }

        emit OpenPosition(_strikeId, positionData.positionId, _amt, collateralReq, underlyingReceived, uint256(callDelta));
    }

    function _closeShortPosition(uint256 _strikeId, uint256 _amt, uint256 _premiumAmt) internal {
        PositionData storage positionData = positionDatas[_strikeId];

        if (positionData.positionId == 0 || positionData.amount < _amt || _premiumAmt > uint256(totalPremiumCollected)) {
            revert InvalidCloseRequest(_strikeId, positionData.positionId);
        }

        if (OPTION_TOKEN.getApproved(positionData.positionId) != address(MARKET_WRAPPER)) {
            OPTION_TOKEN.approve(address(MARKET_WRAPPER), positionData.positionId);
        }

        // Convert UNDERLYING to sUSD to pay back in order to close the position
        uint256 susdReceived = SYNTHETIX.exchangeWithTracking(
            UNDERLYING_SYNTH_KEY,
            _premiumAmt,
            "sUSD",
            feeReceipient,
            synthetixTrackingCode
        );

        uint256 collateralToRemove;
        uint256 totalCollateral;

        if (_amt == positionData.amount) {
            collateralToRemove = positionData.collateral;
        } else {
            collateralToRemove = _amt.mulWadUp(collateralization);
            totalCollateral = positionData.collateral - collateralToRemove;
        }

        SUSD.safeApprove(address(MARKET_WRAPPER), susdReceived);

        IOptionMarketWrapperWithSwaps.OptionPositionParams memory params;

        params.optionMarket = MARKET;
        params.strikeId = _strikeId;
        params.positionId = positionData.positionId;
        params.iterations = tradeIterations;
        params.setCollateralTo = totalCollateral;
        params.currentCollateral = positionData.collateral;
        params.optionType = OPTION_TYPE;
        params.amount = _amt;
        params.minCost = 0;
        params.maxCost = type(uint256).max;
        params.inputAmount = susdReceived;
        params.inputAsset = SUSD;

        // Close the position
        IOptionMarketWrapperWithSwaps.ReturnDetails memory returnDetails = MARKET_WRAPPER.closePosition(params);

        // Convert the remaining sUSD to UNDERLYING
        uint256 underlyingReceived = SYNTHETIX.exchangeWithTracking(
            "sUSD",
            susdReceived - returnDetails.totalCost,
            UNDERLYING_SYNTH_KEY,
            feeReceipient,
            synthetixTrackingCode
        );

        uint256 premiumUsed = _premiumAmt - underlyingReceived;

        positionData.collateral = totalCollateral;
        positionData.amount -= _amt;
        positionData.premiumCollected -= int256(premiumUsed);

        if (positionData.amount == 0) {
            if (positionData.premiumCollected > 0) {
                uint256 profit = uint256(positionData.premiumCollected);
                uint256 perfFees = profit.mulWadDown(performanceFee);
                UNDERLYING.safeTransfer(feeReceipient, perfFees);
                totalFunds += (profit - perfFees);
            } else {
                totalFunds -= uint256(-positionData.premiumCollected);
            }
            positionData.positionId = 0;
            positionData.premiumCollected = 0;
            _removeStrikeId(_strikeId);
        }

        totalPremiumCollected -= int256(premiumUsed);
        usedFunds -= collateralToRemove;

        emit ClosePosition(_strikeId, positionData.positionId, _amt, collateralToRemove, premiumUsed);
    }

    function _addCollateral(uint256 _strikeId, uint256 _amt) internal {
        usedFunds += _amt;

        if (usedFunds > totalFunds) {
            revert InsufficientFunds(totalFunds, usedFunds - _amt, _amt);
        }

        PositionData storage positionData = positionDatas[_strikeId];

        UNDERLYING.safeApprove(address(MARKET), _amt);
        MARKET.addCollateral(positionData.positionId, _amt);
        positionData.collateral += _amt;

        emit AddCollateral(_strikeId, positionData.positionId, _amt);
    }

    /// @notice This doesn't actually settle the options, instead it only does the accounting for the settlement
    /// @notice Actual settlement can be done by anyone and doesn't return any data
    /// @notice Because of the above reason, relevant strike ids should be settled separately before calling this method
    function _settleOptions(uint256[] memory _strikeIds) internal {
        for (uint256 i = 0; i < _strikeIds.length; i++) {
            PositionData storage positionData = positionDatas[_strikeIds[i]];

            if (positionData.amount == 0) {
                revert ExpectedNonZero();
            }

            IOptionToken.PositionState optionState = OPTION_TOKEN.getPositionState(positionData.positionId);
            if (optionState != IOptionToken.PositionState.SETTLED) {
                revert OptionNotSettled(_strikeIds[i], positionData.positionId, optionState);
            }

            (
                ,
                uint priceAtExpiry,
                uint ammShortCallBaseProfitRatio
            ) = MARKET.getSettlementParameters(_strikeIds[i]);

            if (priceAtExpiry == 0) {
                revert InvalidExpiryPrice();
            }

            // Calculate the losses if any
            uint256 ammProfit = ammShortCallBaseProfitRatio.mulWadDown(positionData.amount);

            if (ammProfit > 0) {
                totalFunds -= ammProfit;
            }

            usedFunds -= positionData.collateral;

            if (positionData.premiumCollected > 0) {
                uint256 profit = uint256(positionData.premiumCollected);
                uint256 perfFees;
                if (ammProfit == 0) {
                    perfFees = profit.mulWadDown(performanceFee);
                    UNDERLYING.safeTransfer(feeReceipient, perfFees);
                }
                totalFunds += (profit - perfFees);
                totalPremiumCollected -= int256(profit);
                if (totalPremiumCollected < 0) {
                    totalFunds -= uint256(-totalPremiumCollected);
                    totalPremiumCollected = 0;
                }
            } else {
                totalFunds -= uint256(-positionData.premiumCollected);
            }

            emit SettleOption(
                _strikeIds[i],
                positionData.positionId,
                positionData.amount,
                positionData.collateral,
                positionData.premiumCollected,
                ammProfit
            );

            positionData.positionId = 0;
            positionData.premiumCollected = 0;
            positionData.amount = 0;
            positionData.collateral = 0;

            _removeStrikeId(_strikeIds[i]);
        }
    }

    function _removeStrikeId(uint256 _strikeId) internal {
        uint256 i;
        uint256 n = liveStrikes.length;
        for (i = 0; i < n; i++) {
            if (_strikeId == liveStrikes[i]) {
                break;
            }
        }

        if (i < n) {
            liveStrikes[i] = liveStrikes[n - 1];
            liveStrikes.pop();
        }
    }

    /// -----------------------------------------------------------------------
    /// Errors
    /// -----------------------------------------------------------------------

    /// General
    error InsufficientFunds(uint256 totalFunds, uint256 usedFunds, uint256 requiredFunds);
    error ExpectedNonZero();

    /// Trading errors
    error InvalidPrice(uint256 spotPrice, bool isInvalid);
    error InvalidExpiryPrice();
    error InvalidCloseRequest(uint256 strikeId, uint256 positionId);
    error OptionNotSettled(uint256 strikeId, uint256 positionId, IOptionToken.PositionState optionState);
    error OptionTooRisky(uint256 strikeId, uint256 delta);

    /// Deposit and Withdrawals
    error MinimumDepositRequired(uint256 minDeposit, uint256 requestedAmount);

    /// Owner actions
    error InvalidCollateralization(uint256 currentCollateralization, uint256 requestedCollateralization);
    error FeesTooHigh(uint256 currentPerf, uint256 currentWithdraw, uint256 newPerf, uint256 newWithdraw);

    /// -----------------------------------------------------------------------
    /// Events
    /// -----------------------------------------------------------------------

    /// @notice Initiate Deposit Event
    /// @param depositId Deposit ID
    /// @param depositor Address of the fund depositor (msg.sender)
    /// @param user Address of the user who'll be getting the VAULT_TOKENs
    /// @param amount Amount depositted (in UNDERLYING)
    event InitiateDeposit(
        uint256 depositId,
        address depositor,
        address user,
        uint256 amount
    );

    /// @notice Process Deposit Event
    /// @param depositId Deposit ID
    /// @param user Address of the user who'll be getting the VAULT_TOKENs
    /// @param amount Amount depositted (in UNDERLYING)
    /// @param tokens Amount of VAULT_TOKENs minted
    /// @param requestedTime Timestamp of the initiateDeposit call
    event ProcessDeposit(
        uint256 depositId,
        address user,
        uint256 amount,
        uint256 tokens,
        uint256 requestedTime
    );

    /// @notice Initiate Withdrawal Event
    /// @param withdrawalId Withdrawal ID
    /// @param withdrawer Address of the user who requested withdraw (msg.sender)
    /// @param user Address of the user who'll be getting UNDERLYING tokens upon processing
    /// @param tokens Amount of VAULT_TOKENs to burn / withdraw
    event InitiateWithdrawal(
        uint256 withdrawalId,
        address withdrawer,
        address user,
        uint256 tokens
    );

    /// @notice Process Withdrawal Event
    /// @param withdrawalId Withdrawal ID
    /// @param user Address of the user who's getting the funds
    /// @param tokens Amount of VAULT_TOKENs burned
    /// @param amount Amount of UNDERLYING returned
    /// @param requestedTime Timestamp of the initiateWithdraw call
    event ProcessWithdrawal(
        uint256 withdrawalId,
        address user,
        uint256 tokens,
        uint256 amount,
        uint256 requestedTime
    );

    /// @notice Process Withdrawal Partially Event
    /// @param withdrawalId Withdrawal ID
    /// @param user Address of the user who's getting the funds
    /// @param tokens Amount of VAULT_TOKENs burned
    /// @param amount Amount of UNDERLYING returned
    /// @param requestedTime Timestamp of the initiateWithdraw call
    event ProcessWithdrawalPartially(
        uint256 withdrawalId,
        address user,
        uint256 tokens,
        uint256 amount,
        uint256 requestedTime
    );

    /// @notice Update Collateralization Event
    /// @param oldCollateralization Old Collateralization
    /// @param newCollateralization New Collateralization
    event UpdateCollateralization(uint256 oldCollateralization, uint256 newCollateralization);

    /// @notice Update Fee Receipient Event
    /// @param oldFeeReceipient Address of the old fee receipient
    /// @param newFeeReceipient Address of the new fee receipient
    event UpdateFeeReceipient(address oldFeeReceipient, address newFeeReceipient);

    /// @notice Update Fees Event
    /// @param oldPerf Old Perfomance Fee
    /// @param oldWithdraw Old Withdrawal Fee
    /// @param newPerf New Performance Fee
    /// @param newWithdraw New Withdrawal Fee
    event UpdateFees(uint256 oldPerf, uint256 oldWithdraw, uint256 newPerf, uint256 newWithdraw);

    /// @notice Update Synthetix Tracking Code Event
    /// @param oldCode Existing code
    /// @param newCode New code
    event UpdateSynthetixTrackingCode(bytes32 oldCode, bytes32 newCode);

    /// @notice Update Minimum Deposit Amount Event
    /// @param oldMinimum Previous minimum deposit amount
    /// @param newMinimum New minimum deposit amount
    event UpdateMinDeposit(uint256 oldMinimum, uint256 newMinimum);

    /// @notice Update Deposit and Withdraw delays Event
    /// @param oldDepositDelay Old Deposit Delay
    /// @param newDepositDelay New Deposit Delay
    /// @param oldWithdrawDelay Old Withdraw Delay
    /// @param newWithdrawDelay New Withdraw Delay
    event UpdateDelays(
        uint256 oldDepositDelay,
        uint256 newDepositDelay,
        uint256 oldWithdrawDelay,
        uint256 newWithdrawDelay
    );

    /// @notice Update GWAV Length
    /// @param oldLength Old Length
    /// @param newLength New Length
    event UpdateGWAVLength(
        uint256 oldLength,
        uint256 newLength
    );

    /// @notice Update Trade Iterations
    /// @param oldIterations Old Iterations
    /// @param newIterations New Iterations
    event UpdateTradeIterations(
        uint256 oldIterations,
        uint256 newIterations
    );

    /// @notice Update Delta Cutoff
    /// @param oldCutoff Old delta cutoff
    /// @param newCutoff New delta cutoff
    event UpdateDeltaCutoff(
        int256 oldCutoff,
        int256 newCutoff
    );

    /// @notice Open Position Event
    /// @param strikeId Lyra Strike ID
    /// @param positionId Corresponding Position ID
    /// @param amount Amount of additional short position
    /// @param collateral Collateral used
    /// @param premiumCollected Premium collected from opening the short position
    /// @param callDelta Call Delta of the option
    event OpenPosition(
        uint256 strikeId,
        uint256 positionId,
        uint256 amount,
        uint256 collateral,
        uint256 premiumCollected,
        uint256 callDelta
    );

    /// @notice Close Position Event
    /// @param strikeId Lyra Strike ID
    /// @param positionId Corresponding Position ID
    /// @param amount Amount of short position closed
    /// @param collateralWithdrawn Amount of collateral withdrawn
    /// @param premiumPaid Amount of premium paid to close the position
    event ClosePosition(
        uint256 strikeId,
        uint256 positionId,
        uint256 amount,
        uint256 collateralWithdrawn,
        uint256 premiumPaid
    );

    /// @notice Add Collateral Event
    /// @param strikeId Lyra Strike ID
    /// @param positionId Corresponding Position ID
    /// @param amount Amount of additional collateral added
    event AddCollateral(uint256 strikeId, uint256 positionId, uint256 amount);

    /// @notice Settle Option Event
    /// @param strikeId Lyra Strike ID
    /// @param positionId Corresponding Position ID
    /// @param amount Total amount of options
    /// @param totalCollateral Total collateral
    /// @param totalPremium Total premium collected
    /// @param loss Total loss from the position
    event SettleOption(
        uint256 strikeId,
        uint256 positionId,
        uint256 amount,
        uint256 totalCollateral,
        int256 totalPremium,
        uint256 loss
    );
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract ERC20","name":"_underlying","type":"address"},{"internalType":"contract ERC20","name":"_susd","type":"address"},{"internalType":"contract IPolynomialVaultToken","name":"_vaultToken","type":"address"},{"internalType":"contract IOptionMarket","name":"_market","type":"address"},{"internalType":"contract IOptionMarketWrapperWithSwaps","name":"_marketWrapper","type":"address"},{"internalType":"contract IOptionToken","name":"_optionToken","type":"address"},{"internalType":"contract IOptionGreekCache","name":"_greeks","type":"address"},{"internalType":"contract ISynthetix","name":"_synthetix","type":"address"},{"internalType":"contract IExchangeRates","name":"_exchangeRates","type":"address"},{"internalType":"bytes32","name":"_underlyingKey","type":"bytes32"},{"internalType":"bytes32","name":"_name","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DepositsNotPaused","type":"error"},{"inputs":[],"name":"DepositsPaused","type":"error"},{"inputs":[],"name":"ExpectedNonZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentPerf","type":"uint256"},{"internalType":"uint256","name":"currentWithdraw","type":"uint256"},{"internalType":"uint256","name":"newPerf","type":"uint256"},{"internalType":"uint256","name":"newWithdraw","type":"uint256"}],"name":"FeesTooHigh","type":"error"},{"inputs":[{"internalType":"uint256","name":"totalFunds","type":"uint256"},{"internalType":"uint256","name":"usedFunds","type":"uint256"},{"internalType":"uint256","name":"requiredFunds","type":"uint256"}],"name":"InsufficientFunds","type":"error"},{"inputs":[{"internalType":"uint256","name":"strikeId","type":"uint256"},{"internalType":"uint256","name":"positionId","type":"uint256"}],"name":"InvalidCloseRequest","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentCollateralization","type":"uint256"},{"internalType":"uint256","name":"requestedCollateralization","type":"uint256"}],"name":"InvalidCollateralization","type":"error"},{"inputs":[],"name":"InvalidExpiryPrice","type":"error"},{"inputs":[{"internalType":"uint256","name":"spotPrice","type":"uint256"},{"internalType":"bool","name":"isInvalid","type":"bool"}],"name":"InvalidPrice","type":"error"},{"inputs":[{"internalType":"uint256","name":"minDeposit","type":"uint256"},{"internalType":"uint256","name":"requestedAmount","type":"uint256"}],"name":"MinimumDepositRequired","type":"error"},{"inputs":[],"name":"NotPaused","type":"error"},{"inputs":[{"internalType":"uint256","name":"strikeId","type":"uint256"},{"internalType":"uint256","name":"positionId","type":"uint256"},{"internalType":"enum IOptionToken.PositionState","name":"optionState","type":"uint8"}],"name":"OptionNotSettled","type":"error"},{"inputs":[{"internalType":"uint256","name":"strikeId","type":"uint256"},{"internalType":"uint256","name":"delta","type":"uint256"}],"name":"OptionTooRisky","type":"error"},{"inputs":[],"name":"Paused","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"strikeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"positionId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AddCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"AuthorityUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"strikeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"positionId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateralWithdrawn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"premiumPaid","type":"uint256"}],"name":"ClosePosition","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"depositId","type":"uint256"},{"indexed":false,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"InitiateDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"withdrawalId","type":"uint256"},{"indexed":false,"internalType":"address","name":"withdrawer","type":"address"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"InitiateWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"strikeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"positionId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateral","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"premiumCollected","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"callDelta","type":"uint256"}],"name":"OpenPosition","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"depositId","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestedTime","type":"uint256"}],"name":"ProcessDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"withdrawalId","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestedTime","type":"uint256"}],"name":"ProcessWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"withdrawalId","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestedTime","type":"uint256"}],"name":"ProcessWithdrawalPartially","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"SetDepositsPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"SetDepositsUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"SetPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"SetUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"strikeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"positionId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalCollateral","type":"uint256"},{"indexed":false,"internalType":"int256","name":"totalPremium","type":"int256"},{"indexed":false,"internalType":"uint256","name":"loss","type":"uint256"}],"name":"SettleOption","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldCollateralization","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCollateralization","type":"uint256"}],"name":"UpdateCollateralization","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldDepositDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDepositDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldWithdrawDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newWithdrawDelay","type":"uint256"}],"name":"UpdateDelays","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"int256","name":"oldCutoff","type":"int256"},{"indexed":false,"internalType":"int256","name":"newCutoff","type":"int256"}],"name":"UpdateDeltaCutoff","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldFeeReceipient","type":"address"},{"indexed":false,"internalType":"address","name":"newFeeReceipient","type":"address"}],"name":"UpdateFeeReceipient","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldPerf","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldWithdraw","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPerf","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newWithdraw","type":"uint256"}],"name":"UpdateFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldLength","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLength","type":"uint256"}],"name":"UpdateGWAVLength","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMinimum","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMinimum","type":"uint256"}],"name":"UpdateMinDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"oldCode","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"newCode","type":"bytes32"}],"name":"UpdateSynthetixTrackingCode","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldIterations","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newIterations","type":"uint256"}],"name":"UpdateTradeIterations","type":"event"},{"inputs":[],"name":"GREEKS","outputs":[{"internalType":"contract IOptionGreekCache","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MARKET","outputs":[{"internalType":"contract IOptionMarket","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MARKET_WRAPPER","outputs":[{"internalType":"contract IOptionMarketWrapperWithSwaps","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPTION_TOKEN","outputs":[{"internalType":"contract IOptionToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RATES","outputs":[{"internalType":"contract IExchangeRates","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUSD","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SYNTHETIX","outputs":[{"internalType":"contract ISynthetix","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNDERLYING","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNDERLYING_SYNTH_KEY","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VAULT_TOKEN","outputs":[{"internalType":"contract IPolynomialVaultToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"strikeId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"addCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"authority","outputs":[{"internalType":"contract Authority","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"strikeId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"premiumAmount","type":"uint256"}],"name":"closePosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collateralization","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deltaCutoff","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"depositQueue","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"depositedAmount","type":"uint256"},{"internalType":"uint256","name":"mintedTokens","type":"uint256"},{"internalType":"uint256","name":"requestedTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositsPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeReceipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLiveStrikes","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gwavLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"initiateDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"initiateWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"liveStrikes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minDepositAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minDepositDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minWithdrawDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextQueuedDepositId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextQueuedWithdrawalId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"strikeId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"openPosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"performanceFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"positionDatas","outputs":[{"internalType":"uint256","name":"positionId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"collateral","type":"uint256"},{"internalType":"int256","name":"premiumCollected","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"idCount","type":"uint256"}],"name":"processDepositQueue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"idCount","type":"uint256"}],"name":"processWithdrawalQueue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"queuedDepositHead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"queuedWithdrawalHead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"saveToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"setAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ratio","type":"uint256"}],"name":"setCollateralization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositDelay","type":"uint256"},{"internalType":"uint256","name":"_withdrawDelay","type":"uint256"}],"name":"setDelays","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int256","name":"_deltaCutoff","type":"int256"}],"name":"setDeltaCutoff","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeReceipient","type":"address"}],"name":"setFeeReceipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_performanceFee","type":"uint256"},{"internalType":"uint256","name":"_withdrawalFee","type":"uint256"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"setGWAVLength","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_iterations","type":"uint256"}],"name":"setIterations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minAmt","type":"uint256"}],"name":"setMinDepositAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_code","type":"bytes32"}],"name":"setSynthetixTracking","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"strikeIds","type":"uint256[]"}],"name":"settleOptions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"synthetixTrackingCode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFunds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalPremiumCollected","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalQueuedDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalQueuedWithdrawals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeIterations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"usedFunds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"withdrawalQueue","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"withdrawnTokens","type":"uint256"},{"internalType":"uint256","name":"returnedAmount","type":"uint256"},{"internalType":"uint256","name":"requestedTime","type":"uint256"}],"stateMutability":"view","type":"function"}]

6101e0604052600160025560016011556001601255600160135560016014553480156200002b57600080fd5b5060405162005f8e38038062005f8e8339810160408190526200004e9162000145565b60008054336001600160a01b03199182168117835560018054909216909155604051909190829081907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76908490a36040516001600160a01b0382169033907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350506003805461ffff191690556001600160a01b039a8b1660c052978a166101005295891661012052938816610140529187166101605286166101805285166101a05284166101c05260a052911660e05260805262000232565b6001600160a01b03811681146200014257600080fd5b50565b60008060008060008060008060008060006101608c8e0312156200016857600080fd5b8b5162000175816200012c565b60208d0151909b5062000188816200012c565b60408d0151909a506200019b816200012c565b60608d0151909950620001ae816200012c565b60808d0151909850620001c1816200012c565b60a08d0151909750620001d4816200012c565b60c08d0151909650620001e7816200012c565b60e08d0151909550620001fa816200012c565b6101008d01519094506200020e816200012c565b809350506101208c015191506101408c015190509295989b509295989b9093969950565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c051615b4d6200044160003960008181610670015281816114db015281816135af0152614c6b0152600081816106aa015281816131960152818161405501526142f2015260008181610957015281816137cc015281816138870152818161395a0152614d8a01526000818161093001528181612d0e01528181612dda01528181613e5401528181613f1d01526146730152600081816108f701528181612cea01528181612e0701528181612f480152818161306a01528181613e3001528181613f4a01528181614140015261426201526000818161099101528181612f7701528181613491015281816136c201528181613c6c01528181613cca0152818161416f0152818161476f0152614b4d015260008181610544015281816117be015281816122310152818161253401526128d701526000818161048c01528181611d2d0152818161301b0152818161411e01526142130152600081816108500152818161102f0152818161107901528181611183015281816111cd01528181611cf10152818161239301528181612a8701528181612f2601528181613c4a015281816144ac01526148f301526000818161077e015281816114a5015281816131550152818161357701528181613fe7015281816143910152614c330152600061041a0152615b4d6000f3fe608060405234801561001057600080fd5b50600436106104065760003560e01c80637f54b4131161021a578063c4e41b2211610135578063deccdf63116100c8578063f46f16c211610097578063f7164fc71161007c578063f7164fc7146109bc578063fc2da41f146109c5578063fd9d4077146109ce57600080fd5b8063f46f16c21461098c578063f6011230146109b357600080fd5b8063deccdf6314610922578063e3d51ddd1461092b578063e55d1a5214610952578063ec5523461461097957600080fd5b8063caca00f411610104578063caca00f4146108cc578063ccf3aed2146108df578063d2450c76146108f2578063d91d2f601461091957600080fd5b8063c4e41b2214610843578063c5d664c61461084b578063c822adda14610872578063c8393ba9146108b957600080fd5b8063968ed600116101ad578063b35648d71161017c578063b35648d7146107f7578063b41e20d41461080a578063bc0d6c571461081d578063bf7e214f1461083057600080fd5b8063968ed600146107b35780639afdb2c2146107bc5780639cc621df146107cf578063a8f35adf146107e457600080fd5b8063892df74f116101e9578063892df74f146107675780638bc7e8c4146107705780638da4e2f9146107795780638da5cb5b146107a057600080fd5b80637f54b413146106cc57806383290a3c146106df5780638456cb5914610756578063877887821461075e57600080fd5b8063481bf0b81161032557806360da3e83116102b8578063771126af1161028757806379f67c441161026c57806379f67c441461066b5780637a9e5e4b146106925780637d1c3071146106a557600080fd5b8063771126af146106035780637772ba071461065857600080fd5b806360da3e83146105cf57806363d8882a146105df578063645006ca146105e757806370f52081146105f057600080fd5b80634d8737cb116102f45780634d8737cb146105935780634ffaa736146105a657806358f67c0b146105af5780635c975abb146105b857600080fd5b8063481bf0b814610566578063499d75d81461056f5780634b48f20d146105785780634b94f50e1461058b57600080fd5b80632a80cda31161039d57806335f748c21161036c57806335f748c21461051b5780633740ebb3146105245780633f4ba83a146105375780634499d14b1461053f57600080fd5b80632a80cda3146104cf5780632b6fcf2e146104e25780633012b05c146104f5578063342c00b31461050857600080fd5b806313af4035116103d957806313af40351461046b57806315a01bc11461047e57806315d8eeba14610487578063208e7e93146104c657600080fd5b8063021919801461040b57806306fdde03146104155780630b2ad0881461044f5780630b78f9c014610458575b600080fd5b6104136109d7565b005b61043c7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61043c60145481565b61041361046636600461513f565b610a4f565b610413610479366004615176565b610b81565b61043c60165481565b6104ae7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610446565b61043c60115481565b6104136104dd366004615193565b610c4d565b6104136104f0366004615193565b610cf7565b61041361050336600461513f565b610da1565b610413610516366004615193565b610eb0565b61043c60065481565b600b546104ae906001600160a01b031681565b61041361128f565b6104ae7f000000000000000000000000000000000000000000000000000000000000000081565b61043c60105481565b61043c600a5481565b610413610586366004615176565b611300565b61043c61142a565b6104136105a1366004615193565b61167a565b61043c60095481565b61043c600f5481565b60035460ff165b6040519015158152602001610446565b600354610100900460ff166105bf565b6104136118c1565b61043c60055481565b6104136105fe366004615193565b611932565b610638610611366004615193565b60196020526000908152604090208054600182015460028301546003909301549192909184565b604080519485526020850193909352918301526060820152608001610446565b61041361066636600461513f565b6119f0565b6104ae7f000000000000000000000000000000000000000000000000000000000000000081565b6104136106a0366004615176565b611aaf565b6104ae7f000000000000000000000000000000000000000000000000000000000000000081565b61043c6106da366004615193565b611bf4565b6107266106ed366004615193565b601a602052600090815260409020805460018201546002830154600384015460049094015492936001600160a01b039092169290919085565b604080519586526001600160a01b039094166020860152928401919091526060830152608082015260a001610446565b610413611c15565b61043c600c5481565b61043c60135481565b61043c600d5481565b61043c7f000000000000000000000000000000000000000000000000000000000000000081565b6000546104ae906001600160a01b031681565b61043c60155481565b6104136107ca3660046151ac565b611c86565b6107d7611e0c565b60405161044691906151ed565b6104136107f236600461513f565b611e64565b610413610805366004615231565b611f6a565b610413610818366004615193565b61207b565b61041361082b366004615370565b612125565b6001546104ae906001600160a01b031681565b61043c61222a565b6104ae7f000000000000000000000000000000000000000000000000000000000000000081565b610726610880366004615193565b601b602052600090815260409020805460018201546002830154600384015460049094015492936001600160a01b039092169290919085565b6104136108c7366004615406565b6122cf565b6104136108da366004615193565b6125a1565b6104136108ed366004615193565b6126aa565b6104ae7f000000000000000000000000000000000000000000000000000000000000000081565b61043c60045481565b61043c60085481565b6104ae7f000000000000000000000000000000000000000000000000000000000000000081565b6104ae7f000000000000000000000000000000000000000000000000000000000000000081565b610413610987366004615406565b612754565b6104ae7f000000000000000000000000000000000000000000000000000000000000000081565b61043c600e5481565b61043c60175481565b61043c60125481565b61043c60075481565b610a05336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b610a455760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b60448201526064015b60405180910390fd5b610a4d612ba8565b565b610a7d336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b610ab85760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b67016345785d8a0000821180610ad45750662386f26fc1000081115b15610b2857600c54600d546040517f0995039e000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044810183905260648101829052608401610a3c565b600c54600d546040805192835260208301919091528101839052606081018290527f5c3aee3d65f7eb02cded951435d06b06ef307bc7f57b98975c4a41dc116e711c9060800160405180910390a1600c91909155600d55565b610baf336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b610bea5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b610c7b336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b610cb65760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b60055460408051918252602082018390527f915e1f57375bebe5483299c788956d167e46a28a143974dc29bba5a420aa4354910160405180910390a1600555565b610d25336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b610d605760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b60085460408051918252602082018390527f40777929ad14ec610067fc9c075e20805fe1c57e1879cf2b583355109971c546910160405180910390a1600855565b610dcf336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b610e0a5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b600254600114610e5c5760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e4359000000000000000000000000000000000000000000006044820152606401610a3c565b6002805560035460ff1615610e9d576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea78282612c4c565b50506001600255565b600254600114610f025760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e4359000000000000000000000000000000000000000000006044820152606401610a3c565b6002805560005b81811015610ea7576000610f1b61142a565b6013546000908152601b602052604090206004810154919250901580610f5157506007548160040154610f4e9190615461565b42105b15610f5e57505050611287565b6000601654601554610f709190615479565b905080610f805750505050611287565b6002820154600090610f929085613310565b90508181111561110d57600383018290556000610faf838661332c565b90508060106000828254610fc39190615479565b9250508190555080846002016000828254610fde9190615479565b925050819055508260156000828254610ff79190615479565b9091555050600d541561106657600061101b600d548561331090919063ffffffff16565b600b54909150611058906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911683613341565b6110628185615479565b9350505b60018401546110a2906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911685613341565b835460018501546004860154604080519384526001600160a01b039092166020840152828201849052606083018690526080830152517f36a40db5d5631acd8e2764bd196c60dd82faed72aea6647297ab6af63309b58e9181900360a00190a1505050505050611287565b6003830181905560028301546010805460009061112b908490615479565b90915550506000600284018190556015805483929061114b908490615479565b9091555050600d54156111ba57600061116f600d548361331090919063ffffffff16565b600b549091506111ac906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911683613341565b6111b68183615479565b9150505b60018301546111f6906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911683613341565b8254600184015460028501546004860154604080519485526001600160a01b039093166020850152918301526060820183905260808201527f86dc3fd2a6c267674f2f2ef1b4b7283dcca31e1e2517a55358795c65eca1fe039060a00160405180910390a16013805490600061126b83615490565b919050555050505050808061127f90615490565b915050610f09565b506001600255565b6112bd336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b6112f85760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b610a4d6133e0565b61132e336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b6113695760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b6001600160a01b0381166113a9576040517f54db0c8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b54604080516001600160a01b03928316815291831660208301527fc8bc890a52e17e373db7ac75d8f97911a18bffc2ef18bd8047ed55770ee6ba8b910160405180910390a1600b80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6000601554600014156114445750670de0b6b3a764000090565b600061144e61222a565b60185490915061146b576015546114659082613474565b91505090565b600060175460155461147d9190615461565b6040517f0c71cd230000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015290915060009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630c71cd2390602401604080518083038186803b15801561151c57600080fd5b505afa158015611530573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155491906154de565b9150915081600014806115645750805b156115a6576040517f7ba84727000000000000000000000000000000000000000000000000000000008152600481018390528115156024820152604401610a3c565b60005b601854811015611666576000601882815481106115c8576115c861550a565b600091825260208083209091015480835260198252604080842081516080810183528154815260018201549481019490945260028101549184019190915260030154606083015292509061161b83613489565b509050600061162a8288613474565b905061164383602001518261331090919063ffffffff16565b61164d9089615479565b975050505050808061165e90615490565b9150506115a9565b506116718385613474565b94505050505090565b6002546001146116cc5760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e4359000000000000000000000000000000000000000000006044820152606401610a3c565b6002805560006116da61142a565b905060005b828110156118b7576011546000908152601a6020526040902060048101541580611719575060065481600401546117169190615461565b42105b1561172657505050611287565b60028101546000906117389085613474565b90508082600301819055508160020154600f60008282546117599190615479565b9091555050600282015460158054600090611775908490615461565b909155505060018201546040517f40c10f190000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152602481018390527f0000000000000000000000000000000000000000000000000000000000000000909116906340c10f1990604401600060405180830381600087803b15801561180457600080fd5b505af1158015611818573d6000803e3d6000fd5b505083546001850154600286015460038701546004880154604080519586526001600160a01b0390941660208601528484019290925260608401526080830152517f4d356a2d534287c80daa3bb725dcc09c0ad1049e50c1e328646c49e5a0b2c6cb93509081900360a0019150a1600060028301819055601180549161189d83615490565b9190505550505080806118af90615490565b9150506116df565b5050506001600255565b6118ef336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b61192a5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b610a4d613ac9565b611960336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b61199b5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b6706f05b59d3b200008112156119ed57600a5460408051918252602082018390527fbfc81c1ba7d829304f63f4bffe5910955b03f6951f1177ba93883cff15a40567910160405180910390a1600a8190555b50565b611a1e336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b611a595760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b6006546007546040805192835260208301859052820152606081018290527fc8f5f7dffddfef257dee57a6cd0384a4900f2ab48c3e69766faa5577e6a7cbcb9060800160405180910390a1600691909155600755565b6000546001600160a01b0316331480611b8757506001546040517fb70096130000000000000000000000000000000000000000000000000000000081523360048201523060248201526000357fffffffff000000000000000000000000000000000000000000000000000000001660448201526001600160a01b039091169063b70096139060640160206040518083038186803b158015611b4f57600080fd5b505afa158015611b63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b879190615539565b611b9057600080fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350565b60188181548110611c0457600080fd5b600091825260209091200154905081565b611c43336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b611c7e5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b610a4d613b62565b611cb4336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b611cef5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316141580611d6257507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614155b611d6b57600080fd5b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301526024820183905284169063a9059cbb90604401602060405180830381600087803b158015611dce57600080fd5b505af1158015611de2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e069190615539565b50505050565b60606018805480602002602001604051908101604052809291908181526020018280548015611e5a57602002820191906000526020600020905b815481526020019060010190808311611e46575b5050505050905090565b611e92336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b611ecd5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b600254600114611f1f5760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e4359000000000000000000000000000000000000000000006044820152606401610a3c565b6002805560035460ff1615611f60576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea78282613bfb565b611f98336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b611fd35760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b6002546001146120255760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e4359000000000000000000000000000000000000000000006044820152606401610a3c565b6002805560035460ff1615612066576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612071838383613d8f565b5050600160025550565b6120a9336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b6120e45760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b60095460408051918252602082018390527ff53b0be70f27baabf334832258c8da935a270674357a3d0e51ad87896efbc654910160405180910390a1600955565b612153336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b61218e5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b6002546001146121e05760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e4359000000000000000000000000000000000000000000006044820152606401610a3c565b6002805560035460ff1615612221576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611287816145c3565b60006010547f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561228857600080fd5b505afa15801561229c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c09190615554565b6122ca9190615461565b905090565b6002546001146123215760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e4359000000000000000000000000000000000000000000006044820152606401610a3c565b600280556001600160a01b038216612365576040517f54db0c8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60185461242f57600061237661142a565b905060006123848383613310565b90506123ba6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168583613341565b80601560008282546123cc9190615479565b909155505060408051600081526001600160a01b0386166020820152908101849052606081018290524260808201527f86dc3fd2a6c267674f2f2ef1b4b7283dcca31e1e2517a55358795c65eca1fe039060a00160405180910390a150506124ff565b601480546000818152601b60205260408120929061244c83615490565b9091555081556001810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03851617905560028101829055426004820155601080548391906000906124a9908490615461565b90915550508054604080519182523360208301526001600160a01b0385168282015260608201849052517f6af4b9a67fcdcb6bdd58b7b26c00492d52c66372d350d228ec6a5420bb13fe329181900360800190a1505b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639dc29fac90604401600060405180830381600087803b15801561258057600080fd5b505af1158015612594573d6000803e3d6000fd5b5050600160025550505050565b6125cf336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b61260a5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b670de0b6b3a764000081118061262757506706f05b59d3b2000081105b1561266957600480546040517f618e3d2d0000000000000000000000000000000000000000000000000000000081529182015260248101829052604401610a3c565b60045460408051918252602082018390527f7cbf954c53f0cfe32163baacd57a397c9a307b23673e8dbb6e84fe0ea1f5e59d910160405180910390a1600455565b6126d8336000357fffffffff0000000000000000000000000000000000000000000000000000000016612aaf565b6127135760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610a3c565b600e5460408051918252602082018390527fe6a80d2c46fa6481cec16136a0a5b4f293bf679480d7790883589d7f54ce91d1910160405180910390a1600e55565b6002546001146127a65760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e4359000000000000000000000000000000000000000000006044820152606401610a3c565b60028055600354610100900460ff16156127ec576040517fdeeb694300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03821661282c576040517f54db0c8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600554811015612876576005546040517f54443ec4000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610a3c565b6018546129aa57600061288761142a565b905060006128958383613474565b6040517f40c10f190000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152602482018390529192507f0000000000000000000000000000000000000000000000000000000000000000909116906340c10f1990604401600060405180830381600087803b15801561291d57600080fd5b505af1158015612931573d6000803e3d6000fd5b5050505082601560008282546129479190615461565b909155505060408051600081526001600160a01b0386166020820152908101849052606081018290524260808201527f4d356a2d534287c80daa3bb725dcc09c0ad1049e50c1e328646c49e5a0b2c6cb9060a00160405180910390a15050612a7a565b601280546000818152601a6020526040812092906129c783615490565b9091555081556001810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03851617905560028101829055426004820155600f8054839190600090612a24908490615461565b90915550508054604080519182523360208301526001600160a01b0385168282015260608201849052517f1ccb85c4426dacaaa67edc2ae6421283328736c96dd21b82026889d72414832c9181900360800190a1505b610ea76001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333084614a9a565b6001546000906001600160a01b03168015801590612b8857506040517fb70096130000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301523060248301527fffffffff000000000000000000000000000000000000000000000000000000008516604483015282169063b70096139060640160206040518083038186803b158015612b5057600080fd5b505afa158015612b64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b889190615539565b80612ba057506000546001600160a01b038581169116145b949350505050565b600354610100900460ff1615612bea576040517fdeeb694300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790556040513381527fcb92ca4a4d7ab7e82e1f35164d09a91663f3393b45f06fcac5a73f63ae6bf23f906020015b60405180910390a1565b6000612c5783614b46565b9050600a54811315612c9f576040517fc8a6b25a0000000000000000000000000000000000000000000000000000000081526004810184905260248101829052604401610a3c565b6000838152601960205260409020805415801590612da3575080546040517f081812fc0000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116927f00000000000000000000000000000000000000000000000000000000000000009091169163081812fc91612d479160040190815260200190565b60206040518083038186803b158015612d5f57600080fd5b505afa158015612d73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d979190615578565b6001600160a01b031614155b15612e765780546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163095ea7b391612e43917f0000000000000000000000000000000000000000000000000000000000000000916004016001600160a01b03929092168252602082015260400190565b600060405180830381600087803b158015612e5d57600080fd5b505af1158015612e71573d6000803e3d6000fd5b505050505b6000612e8d6004548561331090919063ffffffff16565b90508060166000828254612ea19190615461565b90915550506015546016541115612f055760155481601654612ec39190615479565b6040517ff5623b720000000000000000000000000000000000000000000000000000000081526004810192909252602482015260448101829052606401610a3c565b6000818360020154612f179190615461565b9050612f6d6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000084614ef3565b612f756150bb565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602081018790528354604082015260095460608201526080810182905260028085015460a083015260c082018190525060e08101869052600061010082018190527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61012083015261014082018190526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166101608401526040517f8bc369690000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000090911690638bc36969906130a19085906004016155d8565b61010060405180830381600087803b1580156130bc57600080fd5b505af11580156130d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130f49190615675565b6080810151600b54600e546040517f30ead7600000000000000000000000000000000000000000000000000000000081527f7355534400000000000000000000000000000000000000000000000000000000600482015260248101939093527f000000000000000000000000000000000000000000000000000000000000000060448401526001600160a01b03918216606484015260848301529192506000917f000000000000000000000000000000000000000000000000000000000000000016906330ead7609060a401602060405180830381600087803b1580156131da57600080fd5b505af11580156131ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132129190615554565b9050838660020181905550878660010160008282546132319190615461565b925050819055508086600301600082825461324c919061571c565b925050819055508060176000828254613265919061571c565b909155505085546132ad5760208201518655601880546001810182556000919091527fb13d2d76d1f4b7be834882e410b3e3a8afaf69f83600ae24db354391d2378d2e018990555b8554604080518b815260208101929092528101899052606081018690526080810182905260a081018890527f2dd3dfdb73dc08e6c8de113eab384a64762cac5fff65e48df7758edc264e84959060c00160405180910390a1505050505050505050565b60006133258383670de0b6b3a7640000614f92565b9392505050565b600061332583670de0b6b3a764000084614fb1565b60006040517fa9059cbb000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080611e065760405162461bcd60e51b815260206004820152600f60248201527f5452414e534645525f4641494c454400000000000000000000000000000000006044820152606401610a3c565b60035460ff1661341c576040517f6cd6020100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556040513381527f3bd4fb9a28883a4c90034f2cd214c1f94fc09854604f38dee6a87e5455e2123b90602001612c42565b600061332583670de0b6b3a764000084614f92565b6000806000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c4c4a0d0866040518263ffffffff1660e01b81526004016134dd91815260200190565b60006040518083038186803b1580156134f557600080fd5b505afa158015613509573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261354f919081019061585b565b6040517f0c71cd230000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152919350915060009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630c71cd2390602401604080518083038186803b1580156135f057600080fd5b505afa158015613604573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061362891906154de565b9150915081600014806136385750805b1561367a576040517f7ba84727000000000000000000000000000000000000000000000000000000008152600481018390528115156024820152604401610a3c565b826020015142111561378f576040517f1fdb6cbd0000000000000000000000000000000000000000000000000000000081526004810188905260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631fdb6cbd9060240160606040518083038186803b15801561370457600080fd5b505afa158015613718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061373c9190615915565b9250925050816000141561377c576040517f30c7646e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6137868185613310565b97505050613ac0565b82516008546040517ff3fd9b3d000000000000000000000000000000000000000000000000000000008152600481019290925260248201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f3fd9b3d9060440160206040518083038186803b15801561381657600080fd5b505afa15801561382a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061384e9190615554565b6008546040517f7df712680000000000000000000000000000000000000000000000000000000081529192506000916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691637df71268916138c5918d91600401918252602082015260400190565b60206040518083038186803b1580156138dd57600080fd5b505afa1580156138f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139159190615554565b905060006040518060a001604052804288602001516139349190615479565b81526020016139438585613310565b8152602001868152602001886020015181526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f369f2ac6040518163ffffffff1660e01b81526004016101406040518083038186803b1580156139b257600080fd5b505afa1580156139c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139ea9190615943565b61012001519052604080517fbcf1e77900000000000000000000000000000000000000000000000000000000815282516004820152602083015160248201529082015160448201526060820151606482015260808201516084820152909150730052a341bea99c4b452816235fc2216143c5f21c9063bcf1e7799060a401604080518083038186803b158015613a7f57600080fd5b505af4158015613a93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ab791906159ca565b90995097505050505b50505050915091565b600354610100900460ff16613b0a576040517fa4d3098c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690556040513381527fd9b17f88c19eed029496a647acd647444182c708871dadb0b13c8db2bbcdff3690602001612c42565b60035460ff1615613b9f576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790556040513381527ff87d42f34d6dc854596ee7e10d09f6ef97f38e4ab22330c4fcb384c7e7f81d1990602001612c42565b8060166000828254613c0d9190615461565b90915550506015546016541115613c2f5760155481601654612ec39190615479565b6000828152601960205260409020613c916001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000084614ef3565b80546040517fa8f35adf0000000000000000000000000000000000000000000000000000000081526004810191909152602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a8f35adf90604401600060405180830381600087803b158015613d1657600080fd5b505af1158015613d2a573d6000803e3d6000fd5b5050505081816002016000828254613d429190615461565b9091555050805460408051858152602081019290925281018390527f8dedd193eae1d427fb5f6ae4dcd87fa15d38eabb7ecf00bf9c85a8f692d709dc9060600160405180910390a1505050565b600083815260196020526040902080541580613dae5750828160010154105b80613dba575060175482115b15613dfe5780546040517f1e61e6a7000000000000000000000000000000000000000000000000000000008152610a3c918691600401918252602082015260400190565b80546040517f081812fc0000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116927f00000000000000000000000000000000000000000000000000000000000000009091169163081812fc91613e8d9160040190815260200190565b60206040518083038186803b158015613ea557600080fd5b505afa158015613eb9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613edd9190615578565b6001600160a01b031614613fb95780546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163095ea7b391613f86917f0000000000000000000000000000000000000000000000000000000000000000916004016001600160a01b03929092168252602082015260400190565b600060405180830381600087803b158015613fa057600080fd5b505af1158015613fb4573d6000803e3d6000fd5b505050505b600b54600e546040517f30ead7600000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018590527f735553440000000000000000000000000000000000000000000000000000000060448201526001600160a01b03928316606482015260848101919091526000917f000000000000000000000000000000000000000000000000000000000000000016906330ead7609060a401602060405180830381600087803b15801561409957600080fd5b505af11580156140ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140d19190615554565b905060008083600101548614156140ee5783600201549150614111565b6004546140fc908790614fdf565b915081846002015461410e9190615479565b90505b6141656001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000085614ef3565b61416d6150bb565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602081018890528454604082015260095460608201526080810182905260028086015460a083015260c082018190525060e08101879052600061010082018190527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61012083015261014082018590526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166101608401526040517fb738a96b0000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000009091169063b738a96b906142999085906004016155d8565b61010060405180830381600087803b1580156142b457600080fd5b505af11580156142c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142ec9190615675565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166330ead76083608001518861432f9190615479565b600b54600e5460405160e085901b7fffffffff000000000000000000000000000000000000000000000000000000001681527f7355534400000000000000000000000000000000000000000000000000000000600482015260248101939093527f000000000000000000000000000000000000000000000000000000000000000060448401526001600160a01b039091166064830152608482015260a401602060405180830381600087803b1580156143e757600080fd5b505af11580156143fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061441f9190615554565b9050600061442d828a615479565b90508488600201819055508988600101600082825461444c9190615479565b925050819055508088600301600082825461446791906159ee565b90915550506001880154614535576000886003015413156144fd576003880154600c54600090614498908390613310565b600b549091506144d5906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911683613341565b6144df8183615479565b601560008282546144f09190615461565b9091555061452292505050565b876003015461450b90615a62565b6015600082825461451c9190615479565b90915550505b600080895560038901556145358b614ff4565b806017600082825461454791906159ee565b9250508190555085601660008282546145609190615479565b90915550508754604080518d8152602081019290925281018b905260608101879052608081018290527fee19d4dcc15e899950ecf28027eee5796688964dc923320a7eedcfc95abfc7a29060a00160405180910390a15050505050505050505050565b60005b8151811015614a96576000601960008484815181106145e7576145e761550a565b60200260200101518152602001908152602001600020905080600101546000141561463e576040517f54db0c8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80546040517feb29dc5e0000000000000000000000000000000000000000000000000000000081526000916001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163eb29dc5e916146aa9160040190815260200190565b60206040518083038186803b1580156146c257600080fd5b505afa1580156146d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146fa9190615a9b565b9050600481600581111561471057614710615595565b1461476a578383815181106147275761472761550a565b60200260200101518260000154826040517f25c1b4cf000000000000000000000000000000000000000000000000000000008152600401610a3c93929190615abc565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631fdb6cbd8787815181106147ae576147ae61550a565b60200260200101516040518263ffffffff1660e01b81526004016147d491815260200190565b60606040518083038186803b1580156147ec57600080fd5b505afa158015614800573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148249190615915565b92509250508160001415614864576040517f30c7646e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061487d85600101548361331090919063ffffffff16565b9050801561489d5780601560008282546148979190615479565b90915550505b8460020154601660008282546148b39190615479565b909155505060038501546000121561498f57600385015460008261491c57600c546148df908390613310565b600b5490915061491c906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911683613341565b6149268183615479565b601560008282546149379190615461565b92505081905550816017600082825461495091906159ee565b9091555050601754600013156149885760175461496c90615a62565b6015600082825461497d9190615479565b909155505060006017555b50506149b4565b846003015461499d90615a62565b601560008282546149ae9190615479565b90915550505b7f5c7fe62083bc914e5249c3b877823e54536d036c26578aa386223d00f9db704c8787815181106149e7576149e761550a565b6020026020010151866000015487600101548860020154896003015486604051614a3996959493929190958652602086019490945260408501929092526060840152608083015260a082015260c00190565b60405180910390a16000808655600386018190556001860181905560028601558651614a7e90889088908110614a7157614a7161550a565b6020026020010151614ff4565b50505050508080614a8e90615490565b9150506145c6565b5050565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081528460048201528360248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080614b3f5760405162461bcd60e51b815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152606401610a3c565b5050505050565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c4c4a0d0856040518263ffffffff1660e01b8152600401614b9991815260200190565b60006040518083038186803b158015614bb157600080fd5b505afa158015614bc5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052614c0b919081019061585b565b6040517f0c71cd230000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152919350915060009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630c71cd2390602401604080518083038186803b158015614cac57600080fd5b505afa158015614cc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614ce491906154de565b915091508160001480614cf45750805b15614d36576040517f7ba84727000000000000000000000000000000000000000000000000000000008152600481018390528115156024820152604401610a3c565b60006040518060a00160405280428660200151614d539190615479565b8152602001614d738760400151876040015161331090919063ffffffff16565b8152602001848152602001866020015181526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f369f2ac6040518163ffffffff1660e01b81526004016101406040518083038186803b158015614de257600080fd5b505afa158015614df6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614e1a9190615943565b61012001519052604080517fdc1f2cd800000000000000000000000000000000000000000000000000000000815282516004820152602083015160248201529082015160448201526060820151606482015260808201516084820152909150730052a341bea99c4b452816235fc2216143c5f21c9063dc1f2cd89060a401604080518083038186803b158015614eaf57600080fd5b505af4158015614ec3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614ee791906159ca565b50979650505050505050565b60006040517f095ea7b3000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080611e065760405162461bcd60e51b815260206004820152600e60248201527f415050524f56455f4641494c45440000000000000000000000000000000000006044820152606401610a3c565b828202811515841585830485141716614faa57600080fd5b0492915050565b828202811515841585830485141716614fc957600080fd5b6001826001830304018115150290509392505050565b60006133258383670de0b6b3a7640000614fb1565b6018546000905b8082101561503f57601882815481106150165761501661550a565b906000526020600020015483141561502d5761503f565b8161503781615490565b925050614ffb565b808210156150b6576018615054600183615479565b815481106150645761506461550a565b9060005260206000200154601883815481106150825761508261550a565b600091825260209091200155601880548061509f5761509f615ae8565b600190038181906000526020600020016000905590555b505050565b60405180610180016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081526020016000600481111561510d5761510d615595565b81526020016000815260200160008152602001600081526020016000815260200160006001600160a01b031681525090565b6000806040838503121561515257600080fd5b50508035926020909101359150565b6001600160a01b03811681146119ed57600080fd5b60006020828403121561518857600080fd5b813561332581615161565b6000602082840312156151a557600080fd5b5035919050565b6000806000606084860312156151c157600080fd5b83356151cc81615161565b925060208401356151dc81615161565b929592945050506040919091013590565b6020808252825182820181905260009190848201906040850190845b8181101561522557835183529284019291840191600101615209565b50909695505050505050565b60008060006060848603121561524657600080fd5b505081359360208301359350604090920135919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156152af576152af61525d565b60405290565b604051610120810167ffffffffffffffff811182821017156152af576152af61525d565b604051610140810167ffffffffffffffff811182821017156152af576152af61525d565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156153445761534461525d565b604052919050565b600067ffffffffffffffff8211156153665761536661525d565b5060051b60200190565b6000602080838503121561538357600080fd5b823567ffffffffffffffff81111561539a57600080fd5b8301601f810185136153ab57600080fd5b80356153be6153b98261534c565b6152fd565b81815260059190911b820183019083810190878311156153dd57600080fd5b928401925b828410156153fb578335825292840192908401906153e2565b979650505050505050565b6000806040838503121561541957600080fd5b823561542481615161565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561547457615474615432565b500190565b60008282101561548b5761548b615432565b500390565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156154c2576154c2615432565b5060010190565b805180151581146154d957600080fd5b919050565b600080604083850312156154f157600080fd5b82519150615501602084016154c9565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561554b57600080fd5b613325826154c9565b60006020828403121561556657600080fd5b5051919050565b80516154d981615161565b60006020828403121561558a57600080fd5b815161332581615161565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600581106155d4576155d4615595565b9052565b81516001600160a01b0316815261018081016020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015161562e60c08401826155c4565b5060e08381015190830152610100808401519083015261012080840151908301526101408084015190830152610160928301516001600160a01b0316929091019190915290565b600061010080838503121561568957600080fd5b6040519081019067ffffffffffffffff821181831017156156ac576156ac61525d565b81604052835191506156bd82615161565b818152602084015160208201526156d66040850161556d565b6040820152606084015160608201526080840151608082015260a084015160a082015260c084015160c082015261570f60e0850161556d565b60e0820152949350505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561575657615756615432565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561578a5761578a615432565b50500190565b600060a082840312156157a257600080fd5b6157aa61528c565b90508151815260208083015181830152604083015160408301526157d0606084016154c9565b6060830152608083015167ffffffffffffffff8111156157ef57600080fd5b8301601f8101851361580057600080fd5b805161580e6153b98261534c565b81815260059190911b8201830190838101908783111561582d57600080fd5b928401925b8284101561584b57835182529284019290840190615832565b6080860152509295945050505050565b60008082840361014081121561587057600080fd5b6101208082121561588057600080fd5b6158886152b5565b9150845182526020850151602083015260408501516040830152606085015160608301526080850151608083015260a085015160a083015260c085015160c083015260e085015160e08301526101008086015181840152508193508085015191505067ffffffffffffffff8111156158ff57600080fd5b61590b85828601615790565b9150509250929050565b60008060006060848603121561592a57600080fd5b8351925060208401519150604084015190509250925092565b6000610140828403121561595657600080fd5b61595e6152d9565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152506101208084015181830152508091505092915050565b600080604083850312156159dd57600080fd5b505080516020909101519092909150565b6000808312837f800000000000000000000000000000000000000000000000000000000000000001831281151615615a2857615a28615432565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018313811615615a5c57615a5c615432565b50500390565b60007f8000000000000000000000000000000000000000000000000000000000000000821415615a9457615a94615432565b5060000390565b600060208284031215615aad57600080fd5b81516006811061332557600080fd5b838152602081018390526060810160068310615ada57615ada615595565b826040830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220fe8a9eac0a5149f64c9df9d3ab950c9aed3dcc58e633fa22bf618a7b7fe1de3d64736f6c63430008090033000000000000000000000000e405de8f52ba7559f9df3c368500b6e6ae6cee490000000000000000000000008c6f28f2f1a3c87f0f938b96d27520d9751ec8d90000000000000000000000002901f5f1d4c99f9eee36ccd9a264729c5dd35c110000000000000000000000001d42a98848e022908069c2c545ae44cc78509bc8000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b000000000000000000000000cfdff4e171133d55de2e45c66a0e144a135d93f2000000000000000000000000bb3e8eac35e649ed1071a9ec42223d474e67b19a0000000000000000000000008700daec35af8ff88c16bdf0418774cb3d7599b400000000000000000000000022602469d704bffb0936c7a7cfcd18f7aa2693757345544800000000000000000000000000000000000000000000000000000000734554482043616c6c2053656c6c696e67000000000000000000000000000000

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

000000000000000000000000e405de8f52ba7559f9df3c368500b6e6ae6cee490000000000000000000000008c6f28f2f1a3c87f0f938b96d27520d9751ec8d90000000000000000000000002901f5f1d4c99f9eee36ccd9a264729c5dd35c110000000000000000000000001d42a98848e022908069c2c545ae44cc78509bc8000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b000000000000000000000000cfdff4e171133d55de2e45c66a0e144a135d93f2000000000000000000000000bb3e8eac35e649ed1071a9ec42223d474e67b19a0000000000000000000000008700daec35af8ff88c16bdf0418774cb3d7599b400000000000000000000000022602469d704bffb0936c7a7cfcd18f7aa2693757345544800000000000000000000000000000000000000000000000000000000734554482043616c6c2053656c6c696e67000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _underlying (address): 0xe405de8f52ba7559f9df3c368500b6e6ae6cee49
Arg [1] : _susd (address): 0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9
Arg [2] : _vaultToken (address): 0x2901f5f1d4c99f9eee36ccd9a264729c5dd35c11
Arg [3] : _market (address): 0x1d42a98848e022908069c2c545ae44cc78509bc8
Arg [4] : _marketWrapper (address): 0xcce7819d65f348c64b7beb205ba367b3fe33763b
Arg [5] : _optionToken (address): 0xcfdff4e171133d55de2e45c66a0e144a135d93f2
Arg [6] : _greeks (address): 0xbb3e8eac35e649ed1071a9ec42223d474e67b19a
Arg [7] : _synthetix (address): 0x8700daec35af8ff88c16bdf0418774cb3d7599b4
Arg [8] : _exchangeRates (address): 0x22602469d704bffb0936c7a7cfcd18f7aa269375
Arg [9] : _underlyingKey (bytes32): 0x7345544800000000000000000000000000000000000000000000000000000000
Arg [10] : _name (bytes32): 0x734554482043616c6c2053656c6c696e67000000000000000000000000000000

-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 000000000000000000000000e405de8f52ba7559f9df3c368500b6e6ae6cee49
Arg [1] : 0000000000000000000000008c6f28f2f1a3c87f0f938b96d27520d9751ec8d9
Arg [2] : 0000000000000000000000002901f5f1d4c99f9eee36ccd9a264729c5dd35c11
Arg [3] : 0000000000000000000000001d42a98848e022908069c2c545ae44cc78509bc8
Arg [4] : 000000000000000000000000cce7819d65f348c64b7beb205ba367b3fe33763b
Arg [5] : 000000000000000000000000cfdff4e171133d55de2e45c66a0e144a135d93f2
Arg [6] : 000000000000000000000000bb3e8eac35e649ed1071a9ec42223d474e67b19a
Arg [7] : 0000000000000000000000008700daec35af8ff88c16bdf0418774cb3d7599b4
Arg [8] : 00000000000000000000000022602469d704bffb0936c7a7cfcd18f7aa269375
Arg [9] : 7345544800000000000000000000000000000000000000000000000000000000
Arg [10] : 734554482043616c6c2053656c6c696e67000000000000000000000000000000


Library Used

BlackScholesLib : 0x0052a341bea99c4b452816235fc2216143c5f21c

Deployed ByteCode Sourcemap

76299:41112:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95568:82;;;:::i;:::-;;77885:29;;;;;;;;160:25:1;;;148:2;133:18;77885:29:0;;;;;;;;80422:41;;;;;;96880:470;;;;;;:::i;:::-;;:::i;2109:151::-;;;;;;:::i;:::-;;:::i;80563:24::-;;;;;;78136:27;;;;;;;;-1:-1:-1;;;;;1358:55:1;;;1340:74;;1328:2;1313:18;78136:27:0;1181:239:1;80076:36:0;;;;;;97745:172;;;;;;:::i;:::-;;:::i;98434:151::-;;;;;;:::i;:::-;;:::i;93995:160::-;;;;;;:::i;:::-;;:::i;86388:2585::-;;;;;;:::i;:::-;;:::i;79210:30::-;;;;;;79574:28;;;;;-1:-1:-1;;;;;79574:28:0;;;95693:70;;;:::i;78215:50::-;;;;;79962:37;;;;;;79508:25;;;;;;96456:288;;;;;;:::i;:::-;;:::i;89295:1049::-;;;:::i;85295:965::-;;;;;;:::i;:::-;;:::i;79428:30::-;;;;;;79877:34;;;;;;24846:86;24917:7;;;;24846:86;;;2447:14:1;;2440:22;2422:41;;2410:2;2395:18;24846:86:0;2282:187:1;24940:102:0;25019:15;;;;;;;24940:102;;95805:86;;;:::i;79131:31::-;;;;;;98947:227;;;;;;:::i;:::-;;:::i;80809:54::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2887:25:1;;;2943:2;2928:18;;2921:34;;;;2971:18;;;2964:34;3029:2;3014:18;;3007:34;2874:3;2859:19;80809:54:0;2658:389:1;98076:276:0;;;;;;:::i;:::-;;:::i;78772:37::-;;;;;1659:442;;;;;;:::i;:::-;;:::i;78684:37::-;;;;;80728:28;;;;;;:::i;:::-;;:::i;80903:54::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;80903:54:0;;;;;;;;;;;;;4083:25:1;;;-1:-1:-1;;;;;4144:55:1;;;4139:2;4124:18;;4117:83;4216:18;;;4209:34;;;;4274:2;4259:18;;4252:34;4317:3;4302:19;;4295:35;4070:3;4055:19;80903:54:0;3824:512:1;95462:66:0;;;:::i;79645:29::-;;;;;;80305:39;;;;;;79715:28;;;;;;77984:45;;;;;680:20;;;;;-1:-1:-1;;;;;680:20:0;;;80501:25;;;;;;99383:216;;;;;;:::i;:::-;;:::i;90596:102::-;;;:::i;:::-;;;;;;;:::i;94819:157::-;;;;;;:::i;:::-;;:::i;94419:200::-;;;;;;:::i;:::-;;:::i;98676:181::-;;;;;;:::i;:::-;;:::i;95090:144::-;;;;;;:::i;:::-;;:::i;709:26::-;;;;;-1:-1:-1;;;;;709:26:0;;;90413:132;;;:::i;78072:33::-;;;;;81000:58;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;81000:58:0;;;;;;;;;84048:1125;;;;;;:::i;:::-;;:::i;96025:314::-;;;;;;:::i;:::-;;:::i;97458:188::-;;;;;;:::i;:::-;;:::i;78400:61::-;;;;;79050:32;;;;;;79360:25;;;;;;78505:42;;;;;78598:41;;;;;82416:1248;;;;;;:::i;:::-;;:::i;78310:37::-;;;;;79793:36;;;;;;80637:35;;;;;;80187:38;;;;;;79291:31;;;;;;95568:82;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;;;;;;;;;95626:16:::1;:14;:16::i;:::-;95568:82::o:0;96880:470::-;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;97001:4:::1;96983:15;:22;:47;;;;97026:4;97009:14;:21;96983:47;96979:162;;;97066:14;::::0;97082:13:::1;::::0;97054:75:::1;::::0;::::1;::::0;;::::1;::::0;::::1;2887:25:1::0;;;;2928:18;;;2921:34;2971:18;;;2964:34;;;3014:18;;;3007:34;;;2859:19;;97054:75:0::1;2658:389:1::0;96979:162:0::1;97183:14;::::0;97199:13:::1;::::0;97158:98:::1;::::0;;2887:25:1;;;2943:2;2928:18;;2921:34;;;;2971:18;;2964:34;;;3029:2;3014:18;;3007:34;;;97158:98:0::1;::::0;2874:3:1;2859:19;97158:98:0::1;;;;;;;97269:14;:32:::0;;;;97312:13:::1;:30:::0;96880:470::o;2109:151::-;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;2184:5:::1;:16:::0;;;::::1;-1:-1:-1::0;;;;;2184:16:0;::::1;::::0;;::::1;::::0;;2218:34:::1;::::0;2184:16;;2231:10:::1;::::0;2218:34:::1;::::0;2184:5;2218:34:::1;2109:151:::0;:::o;97745:172::-;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;97846:16:::1;::::0;97829:43:::1;::::0;;10842:25:1;;;10898:2;10883:18;;10876:34;;;97829:43:0::1;::::0;10815:18:1;97829:43:0::1;;;;;;;97883:16;:26:::0;97745:172::o;98434:151::-;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;98528:10:::1;::::0;98511:36:::1;::::0;;10842:25:1;;;10898:2;10883:18;;10876:34;;;98511:36:0::1;::::0;10815:18:1;98511:36:0::1;;;;;;;98558:10;:19:::0;98434:151::o;93995:160::-;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;18530:6:::1;;18540:1;18530:11;18522:34;;;::::0;-1:-1:-1;;;18522:34:0;;11123:2:1;18522:34:0::1;::::0;::::1;11105:21:1::0;11162:2;11142:18;;;11135:30;11201:12;11181:18;;;11174:40;11231:18;;18522:34:0::1;10921:334:1::0;18522:34:0::1;18578:1;18569:10:::0;;24917:7;;;;25086:56:::2;;;25122:8;;;;;;;;;;;;;;25086:56;94111:36:::3;94130:8;94140:6;94111:18;:36::i;:::-;-1:-1:-1::0;;18615:1:0::1;18606:6;:10:::0;93995:160::o;86388:2585::-;18530:6;;18540:1;18530:11;18522:34;;;;-1:-1:-1;;;18522:34:0;;11123:2:1;18522:34:0;;;11105:21:1;11162:2;11142:18;;;11135:30;11201:12;11181:18;;;11174:40;11231:18;;18522:34:0;10921:334:1;18522:34:0;18578:1;18569:10;;86475:9:::1;86470:2496;86494:7;86490:1;:11;86470:2496;;;86523:18;86544:15;:13;:15::i;:::-;86625:20;::::0;86576:30:::1;86609:37:::0;;;:15:::1;:37;::::0;;;;86667:21:::1;::::0;::::1;::::0;86523:36;;-1:-1:-1;86609:37:0;86667:26;;:88:::1;;;86739:16;;86715:7;:21;;;:40;;;;:::i;:::-;86697:15;:58;86667:88;86663:135;;;86776:7;;;;;86663:135;86814:22;86852:9;;86839:10;;:22;;;;:::i;:::-;86814:47:::0;-1:-1:-1;86882:19:0;86878:66:::1;;86922:7;;;;;;86878:66;86989:23;::::0;::::1;::::0;86960:26:::1;::::0;86989:46:::1;::::0;87024:10;86989:34:::1;:46::i;:::-;86960:75;;87200:14;87179:18;:35;87175:1741;;;87235:22;::::0;::::1;:39:::0;;;87293:20:::1;87316:35;87260:14:::0;87340:10;87316:23:::1;:35::i;:::-;87293:58;;87398:12;87372:22;;:38;;;;;;;:::i;:::-;;;;;;;;87456:12;87429:7;:23;;;:39;;;;;;;:::i;:::-;;;;;;;;87503:14;87489:10;;:28;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;87542:13:0::1;::::0;:17;87538:257:::1;;87584:20;87607:40;87633:13;;87607:14;:25;;:40;;;;:::i;:::-;87694:13;::::0;87584:63;;-1:-1:-1;87670:52:0::1;::::0;-1:-1:-1;;;;;87670:10:0::1;:23:::0;::::1;::::0;87694:13:::1;87584:63:::0;87670:23:::1;:52::i;:::-;87745:30;87763:12:::0;87745:30;::::1;:::i;:::-;;;87561:234;87538:257;87839:12;::::0;::::1;::::0;87815:53:::1;::::0;-1:-1:-1;;;;;87815:10:0::1;:23:::0;::::1;::::0;87839:12:::1;87853:14:::0;87815:23:::1;:53::i;:::-;87943:10:::0;;87955:12:::1;::::0;::::1;::::0;87999:21:::1;::::0;::::1;::::0;87894:145:::1;::::0;;4083:25:1;;;-1:-1:-1;;;;;87955:12:0;;::::1;4139:2:1::0;4124:18;;4117:83;4216:18;;;4209:34;;;4274:2;4259:18;;4252:34;;;4317:3;4302:19;;4295:35;87894:145:0;::::1;::::0;;;;4070:3:1;87894:145:0;;::::1;88058:7;;;;;;;;87175:1741;88150:22;::::0;::::1;:43:::0;;;88238:23:::1;::::0;::::1;::::0;88212:22:::1;:49:::0;;:22:::1;::::0;:49:::1;::::0;88238:23;;88212:49:::1;:::i;:::-;::::0;;;-1:-1:-1;;88306:1:0::1;88280:23;::::0;::::1;:27:::0;;;88328:10:::1;:32:::0;;88342:18;;88306:1;88328:32:::1;::::0;88342:18;;88328:32:::1;:::i;:::-;::::0;;;-1:-1:-1;;88385:13:0::1;::::0;:17;88381:265:::1;;88427:20;88450:44;88480:13;;88450:18;:29;;:44;;;;:::i;:::-;88541:13;::::0;88427:67;;-1:-1:-1;88517:52:0::1;::::0;-1:-1:-1;;;;;88517:10:0::1;:23:::0;::::1;::::0;88541:13:::1;88427:67:::0;88517:23:::1;:52::i;:::-;88592:34;88614:12:::0;88592:34;::::1;:::i;:::-;;;88404:242;88381:265;88690:12;::::0;::::1;::::0;88666:57:::1;::::0;-1:-1:-1;;;;;88666:10:0::1;:23:::0;::::1;::::0;88690:12:::1;88704:18:::0;88666:23:::1;:57::i;:::-;88789:10:::0;;88801:12:::1;::::0;::::1;::::0;88815:23:::1;::::0;::::1;::::0;88860:21:::1;::::0;::::1;::::0;88749:151:::1;::::0;;4083:25:1;;;-1:-1:-1;;;;;88801:12:0;;::::1;4139:2:1::0;4124:18;;4117:83;4216:18;;;4209:34;4274:2;4259:18;;4252:34;;;4317:3;4302:19;;4295:35;88749:151:0::1;::::0;4070:3:1;4055:19;88749:151:0::1;;;;;;;88932:20;:22:::0;;;:20:::1;:22;::::0;::::1;:::i;:::-;;;;;;86508:2458;;;;86503:3;;;;;:::i;:::-;;;;86470:2496;;18592:1;-1:-1:-1::0;18615:1:0;18606:6;:10;86388:2585::o;95693:70::-;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;95745:10:::1;:8;:10::i;96456:288::-:0;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;-1:-1:-1;;;;;96543:30:0;::::1;96539:87;;96597:17;;;;;;;;;;;;;;96539:87;96663:13;::::0;96643:50:::1;::::0;;-1:-1:-1;;;;;96663:13:0;;::::1;12147:34:1::0;;12217:15;;;12212:2;12197:18;;12190:43;96643:50:0::1;::::0;12059:18:1;96643:50:0::1;;;;;;;96706:13;:30:::0;;;::::1;-1:-1:-1::0;;;;;96706:30:0;;;::::1;::::0;;;::::1;::::0;;96456:288::o;89295:1049::-;89341:7;89365:10;;89379:1;89365:15;89361:59;;;-1:-1:-1;89404:4:0;;89295:1049::o;89361:59::-;89432:19;89454:16;:14;:16::i;:::-;89485:11;:18;89432:38;;-1:-1:-1;89481:97:0;;89532:10;;:34;;89554:11;89532:21;:34::i;:::-;89525:41;;;89295:1049;:::o;89481:97::-;89590:18;89632:21;;89611:10;;:43;;;;:::i;:::-;89705:42;;;;;89726:20;89705:42;;;160:25:1;89590:64:0;;-1:-1:-1;89668:17:0;;;;-1:-1:-1;;;;;89705:5:0;:20;;;;133:18:1;;89705:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89667:80;;;;89764:9;89777:1;89764:14;:27;;;;89782:9;89764:27;89760:101;;;89815:34;;;;;;;;12849:25:1;;;12917:14;;12910:22;12890:18;;;12883:50;12822:18;;89815:34:0;12681:258:1;89760:101:0;89878:9;89873:412;89897:11;:18;89893:22;;89873:412;;;89937:16;89956:11;89968:1;89956:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;90018:23;;;:13;:23;;;;;;89987:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89956:14;-1:-1:-1;89987:54:0;90101:29;89956:14;90101:19;:29::i;:::-;-1:-1:-1;90070:60:0;-1:-1:-1;90145:19:0;90167:38;90070:60;90195:9;90167:27;:38::i;:::-;90145:60;;90234:39;90257:8;:15;;;90234:11;:22;;:39;;;;:::i;:::-;90220:53;;;;:::i;:::-;;;89922:363;;;;89917:3;;;;;:::i;:::-;;;;89873:412;;;-1:-1:-1;90302:34:0;:10;90324:11;90302:21;:34::i;:::-;90295:41;;;;;;89295:1049;:::o;85295:965::-;18530:6;;18540:1;18530:11;18522:34;;;;-1:-1:-1;;;18522:34:0;;11123:2:1;18522:34:0;;;11105:21:1;11162:2;11142:18;;;11135:30;11201:12;11181:18;;;11174:40;11231:18;;18522:34:0;10921:334:1;18522:34:0;18578:1;18569:10;;85374:18:::1;85395:15;:13;:15::i;:::-;85374:36;;85428:9;85423:830;85447:7;85443:1;:11;85423:830;;;85521:17;::::0;85476:29:::1;85508:31:::0;;;:12:::1;:31;::::0;;;;85560:21:::1;::::0;::::1;::::0;:26;;:87:::1;;;85632:15;;85608:7;:21;;;:39;;;;:::i;:::-;85590:15;:57;85560:87;85556:134;;;85668:7;;;;;85556:134;85729:23;::::0;::::1;::::0;85706:20:::1;::::0;85729:46:::1;::::0;85764:10;85729:34:::1;:46::i;:::-;85706:69;;85815:12;85792:7;:20;;:35;;;;85865:7;:23;;;85842:19;;:46;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;85917:23:0::1;::::0;::::1;::::0;85903:10:::1;:37:::0;;:10:::1;::::0;:37:::1;::::0;85917:23;;85903:37:::1;:::i;:::-;::::0;;;-1:-1:-1;;85972:12:0::1;::::0;::::1;::::0;85955:44:::1;::::0;;;;-1:-1:-1;;;;;85972:12:0;;::::1;85955:44;::::0;::::1;13307:74:1::0;13397:18;;;13390:34;;;85955:11:0::1;:16:::0;;::::1;::::0;::::1;::::0;13280:18:1;;85955:44:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;86054:10:0;;86066:12:::1;::::0;::::1;::::0;86080:23:::1;::::0;::::1;::::0;86105:20:::1;::::0;::::1;::::0;86127:21:::1;::::0;::::1;::::0;86021:142:::1;::::0;;4083:25:1;;;-1:-1:-1;;;;;86066:12:0;;::::1;4139:2:1::0;4124:18;;4117:83;4216:18;;;4209:34;;;;4274:2;4259:18;;4252:34;4317:3;4302:19;;4295:35;86021:142:0;::::1;::::0;-1:-1:-1;86021:142:0;;;;4070:3:1;86021:142:0;;-1:-1:-1;86021:142:0::1;86206:1;86180:23;::::0;::::1;:27:::0;;;86222:17:::1;:19:::0;;;::::1;::::0;::::1;:::i;:::-;;;;;;85461:792;;85456:3;;;;;:::i;:::-;;;;85423:830;;;;85363:897;-1:-1:-1::0;18615:1:0;18606:6;:10;85295:965::o;95805:86::-;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;95865:18:::1;:16;:18::i;98947:227::-:0;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;99044:4:::1;99029:12;:19;99025:142;;;99088:11;::::0;99070:44:::1;::::0;;10842:25:1;;;10898:2;10883:18;;10876:34;;;99070:44:0::1;::::0;10815:18:1;99070:44:0::1;;;;;;;99129:11;:26:::0;;;99025:142:::1;98947:227:::0;:::o;98076:276::-;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;98193:15:::1;::::0;98225:16:::1;::::0;98180:78:::1;::::0;;2887:25:1;;;2943:2;2928:18;;2921:34;;;2971:18;;2964:34;3029:2;3014:18;;3007:34;;;98180:78:0::1;::::0;2874:3:1;2859:19;98180:78:0::1;;;;;;;98269:15;:31:::0;;;;98311:16:::1;:33:::0;98076:276::o;1659:442::-;1933:5;;-1:-1:-1;;;;;1933:5:0;1919:10;:19;;:76;;-1:-1:-1;1942:9:0;;:53;;;;;1960:10;1942:53;;;13945:34:1;1980:4:0;13995:18:1;;;13988:43;1942:9:0;1987:7;;;14047:18:1;;;14040:107;-1:-1:-1;;;;;1942:9:0;;;;:17;;13857:18:1;;1942:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1911:85;;;;;;2009:9;:24;;;;-1:-1:-1;;;;;2009:24:0;;;;;;;;2051:42;;2068:10;;2051:42;;-1:-1:-1;;2051:42:0;1659:442;:::o;80728:28::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;80728:28:0;:::o;95462:66::-;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;95512:8:::1;:6;:8::i;99383:216::-:0;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;99506:10:::1;-1:-1:-1::0;;;;;99489:28:0::1;:5;-1:-1:-1::0;;;;;99489:28:0::1;;;:54;;;;99538:4;-1:-1:-1::0;;;;;99521:22:0::1;:5;-1:-1:-1::0;;;;;99521:22:0::1;;;99489:54;99481:63;;;::::0;::::1;;99555:36;::::0;;;;-1:-1:-1;;;;;13325:55:1;;;99555:36:0::1;::::0;::::1;13307:74:1::0;13397:18;;;13390:34;;;99555:21:0;::::1;::::0;::::1;::::0;13280:18:1;;99555:36:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;99383:216:::0;;;:::o;90596:102::-;90643:16;90679:11;90672:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90596:102;:::o;94819:157::-;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;18530:6:::1;;18540:1;18530:11;18522:34;;;::::0;-1:-1:-1;;;18522:34:0;;11123:2:1;18522:34:0::1;::::0;::::1;11105:21:1::0;11162:2;11142:18;;;11135:30;11201:12;11181:18;;;11174:40;11231:18;;18522:34:0::1;10921:334:1::0;18522:34:0::1;18578:1;18569:10:::0;;24917:7;;;;25086:56:::2;;;25122:8;;;;;;;;;;;;;;25086:56;94936:32:::3;94951:8;94961:6;94936:14;:32::i;94419:200::-:0;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;18530:6:::1;;18540:1;18530:11;18522:34;;;::::0;-1:-1:-1;;;18522:34:0;;11123:2:1;18522:34:0::1;::::0;::::1;11105:21:1::0;11162:2;11142:18;;;11135:30;11201:12;11181:18;;;11174:40;11231:18;;18522:34:0::1;10921:334:1::0;18522:34:0::1;18578:1;18569:10:::0;;24917:7;;;;25086:56:::2;;;25122:8;;;;;;;;;;;;;;25086:56;94559:52:::3;94579:8;94589:6;94597:13;94559:19;:52::i;:::-;-1:-1:-1::0;;18615:1:0::1;18606:6;:10:::0;-1:-1:-1;94419:200:0:o;98676:181::-;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;98780:15:::1;::::0;98758:51:::1;::::0;;10842:25:1;;;10898:2;10883:18;;10876:34;;;98758:51:0::1;::::0;10815:18:1;98758:51:0::1;;;;;;;98820:15;:29:::0;98676:181::o;95090:144::-;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;18530:6:::1;;18540:1;18530:11;18522:34;;;::::0;-1:-1:-1;;;18522:34:0;;11123:2:1;18522:34:0::1;::::0;::::1;11105:21:1::0;11162:2;11142:18;;;11135:30;11201:12;11181:18;;;11174:40;11231:18;;18522:34:0::1;10921:334:1::0;18522:34:0::1;18578:1;18569:10:::0;;24917:7;;;;25086:56:::2;;;25122:8;;;;;;;;;;;;;;25086:56;95201:25:::3;95216:9;95201:14;:25::i;90413:132::-:0;90460:7;90515:22;;90487:11;-1:-1:-1;;;;;90487:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:50;;;;:::i;:::-;90480:57;;90413:132;:::o;84048:1125::-;18530:6;;18540:1;18530:11;18522:34;;;;-1:-1:-1;;;18522:34:0;;11123:2:1;18522:34:0;;;11105:21:1;11162:2;11142:18;;;11135:30;11201:12;11181:18;;;11174:40;11231:18;;18522:34:0;10921:334:1;18522:34:0;18578:1;18569:10;;-1:-1:-1;;;;;84143:20:0;::::1;84139:77;;84187:17;;;;;;;;;;;;;;84139:77;84263:11;:18:::0;84259:858:::1;;84303:18;84324:15;:13;:15::i;:::-;84303:36:::0;-1:-1:-1;84354:26:0::1;84383:29;:6:::0;84303:36;84383:17:::1;:29::i;:::-;84354:58:::0;-1:-1:-1;84427:49:0::1;-1:-1:-1::0;;;;;84427:10:0::1;:23;84451:4:::0;84354:58;84427:23:::1;:49::i;:::-;84505:18;84491:10;;:32;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;84543:71:0::1;::::0;;84561:1:::1;4083:25:1::0;;-1:-1:-1;;;;;4144:55:1;;4139:2;4124:18;;4117:83;4216:18;;;4209:34;;;4274:2;4259:18;;4252:34;;;84598:15:0::1;4317:3:1::0;4302:19;;4295:35;84543:71:0::1;::::0;4070:3:1;4055:19;84543:71:0::1;;;;;;;84288:338;;84259:858;;;84748:22;::::0;;84695:34:::1;84732:39:::0;;;:15:::1;:39;::::0;;;;;84748:22;84805:24:::1;84748:22:::0;84805:24:::1;:::i;:::-;::::0;;;-1:-1:-1;84788:41:0;;84844:16:::1;::::0;::::1;:23:::0;;;::::1;-1:-1:-1::0;;;;;84844:23:0;::::1;;::::0;;84882:27:::1;::::0;::::1;:36:::0;;;84961:15:::1;84933:25;::::0;::::1;:43:::0;84993:22:::1;:32:::0;;84882:36;;84993:22;-1:-1:-1;;84993:32:0::1;::::0;84882:36;;84993:32:::1;:::i;:::-;::::0;;;-1:-1:-1;;85064:14:0;;85045:60:::1;::::0;;15310:25:1;;;85080:10:0::1;15427:2:1::0;15412:18;;15405:43;-1:-1:-1;;;;;15484:15:1;;15464:18;;;15457:43;15531:2;15516:18;;15509:34;;;85045:60:0;::::1;::::0;;;;15297:3:1;85045:60:0;;::::1;84632:485;84259:858;85129:36;::::0;;;;85146:10:::1;85129:36;::::0;::::1;13307:74:1::0;13397:18;;;13390:34;;;85129:11:0::1;-1:-1:-1::0;;;;;85129:16:0::1;::::0;::::1;::::0;13280:18:1;;85129:36:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;18615:1:0;18606:6;:10;-1:-1:-1;;;;84048:1125:0:o;96025:314::-;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;96117:4:::1;96108:6;:13;:30;;;;96134:4;96125:6;:13;96108:30;96104:121;;;96187:17;::::0;;96162:51:::1;::::0;::::1;::::0;;;;::::1;10842:25:1::0;10883:18;;;10876:34;;;10815:18;;96162:51:0::1;10668:248:1::0;96104:121:0::1;96266:17;::::0;96242:50:::1;::::0;;10842:25:1;;;10898:2;10883:18;;10876:34;;;96242:50:0::1;::::0;10815:18:1;96242:50:0::1;;;;;;;96305:17;:26:::0;96025:314::o;97458:188::-;1025:33;1038:10;1050:7;;;;1025:12;:33::i;:::-;1017:58;;;;-1:-1:-1;;;1017:58:0;;10133:2:1;1017:58:0;;;10115:21:1;10172:2;10152:18;;;10145:30;-1:-1:-1;;;10191:18:1;;;10184:42;10243:18;;1017:58:0;9931:336:1;1017:58:0;97569:21:::1;::::0;97541:57:::1;::::0;;10842:25:1;;;10898:2;10883:18;;10876:34;;;97541:57:0::1;::::0;10815:18:1;97541:57:0::1;;;;;;;97609:21;:29:::0;97458:188::o;82416:1248::-;18530:6;;18540:1;18530:11;18522:34;;;;-1:-1:-1;;;18522:34:0;;11123:2:1;18522:34:0;;;11105:21:1;11162:2;11142:18;;;11135:30;11201:12;11181:18;;;11174:40;11231:18;;18522:34:0;10921:334:1;18522:34:0;18578:1;18569:10;;25019:15;;;;;;;25333:71:::1;;;25376:16;;;;;;;;;;;;;;25333:71;-1:-1:-1::0;;;;;82530:20:0;::::2;82526:77;;82574:17;;;;;;;;;;;;;;82526:77;82628:16;;82619:6;:25;82615:113;;;82691:16;::::0;82668:48:::2;::::0;::::2;::::0;;::::2;::::0;::::2;10842:25:1::0;;;;10883:18;;;10876:34;;;10815:18;;82668:48:0::2;10668:248:1::0;82615:113:0::2;82775:11;:18:::0;82771:803:::2;;82815:18;82837:15;:13;:15::i;:::-;82815:37:::0;-1:-1:-1;82867:20:0::2;82890:29;:6:::0;82815:37;82890:17:::2;:29::i;:::-;82936:36;::::0;;;;-1:-1:-1;;;;;13325:55:1;;;82936:36:0::2;::::0;::::2;13307:74:1::0;13397:18;;;13390:34;;;82867:52:0;;-1:-1:-1;82936:11:0::2;:16:::0;;::::2;::::0;::::2;::::0;13280:18:1;;82936:36:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;83007:6;82993:10;;:20;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;83033:62:0::2;::::0;;83048:1:::2;4083:25:1::0;;-1:-1:-1;;;;;4144:55:1;;4139:2;4124:18;;4117:83;4216:18;;;4209:34;;;4274:2;4259:18;;4252:34;;;83079:15:0::2;4317:3:1::0;4302:19;;4295:35;83033:62:0::2;::::0;4070:3:1;4055:19;83033:62:0::2;;;;;;;82800:307;;82771:803;;;83222:19;::::0;;83174:32:::2;83209:33:::0;;;:12:::2;:33;::::0;;;;;83222:19;83275:21:::2;83222:19:::0;83275:21:::2;:::i;:::-;::::0;;;-1:-1:-1;83259:37:0;;83311:15:::2;::::0;::::2;:22:::0;;;::::2;-1:-1:-1::0;;;;;83311:22:0;::::2;;::::0;;83348:26:::2;::::0;::::2;:35:::0;;;83425:15:::2;83398:24;::::0;::::2;:42:::0;83457:19:::2;:29:::0;;83348:35;;83457:19;-1:-1:-1;;83457:29:0::2;::::0;83348:35;;83457:29:::2;:::i;:::-;::::0;;;-1:-1:-1;;83522:13:0;;83506:56:::2;::::0;;15310:25:1;;;83537:10:0::2;15427:2:1::0;15412:18;;15405:43;-1:-1:-1;;;;;15484:15:1;;15464:18;;;15457:43;15531:2;15516:18;;15509:34;;;83506:56:0;::::2;::::0;;;;15297:3:1;83506:56:0;;::::2;83113:461;82771:803;83586:62;-1:-1:-1::0;;;;;83586:10:0::2;:27;83614:10;83634:4;83641:6:::0;83586:27:::2;:62::i;1105:546::-:0;1226:9;;1192:4;;-1:-1:-1;;;;;1226:9:0;1548:27;;;;;:77;;-1:-1:-1;1579:46:0;;;;;-1:-1:-1;;;;;13963:15:1;;;1579:46:0;;;13945:34:1;1606:4:0;13995:18:1;;;13988:43;14079:66;14067:79;;14047:18;;;14040:107;1579:12:0;;;;;13857:18:1;;1579:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1547:96;;;-1:-1:-1;1638:5:0;;-1:-1:-1;;;;;1630:13:0;;;1638:5;;1630:13;1547:96;1540:103;1105:546;-1:-1:-1;;;;1105:546:0:o;25735:151::-;25019:15;;;;;;;25333:71;;;25376:16;;;;;;;;;;;;;;25333:71;25811:15:::1;:22:::0;;;::::1;;;::::0;;25849:29:::1;::::0;25867:10:::1;1340:74:1::0;;25849:29:0::1;::::0;1328:2:1;1313:18;25849:29:0::1;;;;;;;;25735:151::o:0;99797:2617::-;99878:16;99897:23;99910:9;99897:12;:23::i;:::-;99878:42;;100031:11;;100019:9;:23;100015:108;;;100066:45;;;;;;;;10842:25:1;;;10883:18;;;10876:34;;;10815:18;;100066:45:0;10668:248:1;100015:108:0;100135:33;100171:24;;;:13;:24;;;;;100226:23;;:28;;;;:121;;-1:-1:-1;100296:23:0;;100271:49;;;;;-1:-1:-1;;;;;100332:14:0;100271:76;;;:12;:24;;;;;;:49;;;;160:25:1;;;148:2;133:18;;14:177;100271:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;100271:76:0;;;100226:121;100208:248;;;100420:23;;100374:70;;;;;-1:-1:-1;;;;;100374:12:0;:20;;;;:70;;100403:14;;100374:70;;-1:-1:-1;;;;;13325:55:1;;;;13307:74;;13412:2;13397:18;;13390:34;13295:2;13280:18;;13133:297;100374:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;100208:248;100468:21;100492:34;100508:17;;100492:4;:15;;:34;;;;:::i;:::-;100468:58;;100550:13;100537:9;;:26;;;;;;;:::i;:::-;;;;-1:-1:-1;;100592:10:0;;100580:9;;:22;100576:133;;;100644:10;;100668:13;100656:9;;:25;;;;:::i;:::-;100626:71;;;;;;;;16408:25:1;;;;16449:18;;;16442:34;16492:18;;;16485:34;;;16381:18;;100626:71:0;16206:319:1;100576:133:0;100721:23;100773:13;100747:12;:23;;;:39;;;;:::i;:::-;100721:65;-1:-1:-1;100799:62:0;-1:-1:-1;;;;;100799:10:0;:22;100830:14;100847:13;100799:22;:62::i;:::-;100874:64;;:::i;:::-;100973:6;-1:-1:-1;;;;;100951:28:0;;;100990:15;;;:27;;;101048:23;;101028:17;;;:43;101102:15;;101082:17;;;:35;101128:22;;;:40;;;101206:23;;;;;101179:24;;;:50;101240:17;;;101206:23;101240:31;;-1:-1:-1;101282:13:0;;;:20;;;101330:1;101313:14;;;:18;;;101359:17;101342:14;;;:34;101387:18;;;:22;;;-1:-1:-1;;;;;101440:4:0;101420:24;;:17;;;:24;101550:35;;;;;:14;:27;;;;;;:35;;101282:6;;101550:35;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;101757:23;;;;101830:13;;101858:21;;101691:199;;;;;19403:6:1;101691:199:0;;;19385:25:1;19426:18;;;19419:34;;;;101795:20:0;19469:18:1;;;19462:34;-1:-1:-1;;;;;101830:13:0;;;19512:18:1;;;19505:83;19604:19;;;19597:35;101757:23:0;;-1:-1:-1;101662:26:0;;101691:9;:30;;;;19357:19:1;;101691:199:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;101662:228;;101929:15;101903:12;:23;;:41;;;;101978:4;101955:12;:19;;;:27;;;;;;;:::i;:::-;;;;;;;;102033:18;101993:12;:29;;;:59;;;;;;;:::i;:::-;;;;;;;;102095:18;102063:21;;:51;;;;;;;:::i;:::-;;;;-1:-1:-1;;102131:23:0;;102127:153;;102202:24;;;;102176:50;;102241:11;:27;;;;;;;102176:23;102241:27;;;;;;;;;102127:153;102321:23;;102297:109;;;20302:25:1;;;20358:2;20343:18;;20336:34;;;;20386:18;;20379:34;;;20444:2;20429:18;;20422:34;;;20487:3;20472:19;;20465:35;;;20531:3;20516:19;;20509:35;;;102297:109:0;;20289:3:1;20274:19;102297:109:0;;;;;;;99867:2547;;;;;;;99797:2617;;:::o;10525:166::-;10590:7;10617:21;10628:1;10631;10474:4;10617:10;:21::i;:::-;10610:28;10525:166;-1:-1:-1;;;10525:166:0:o;11041:160::-;11104:7;11131:19;11140:1;10474:4;11148:1;11131:8;:19::i;21576:1485::-;21693:12;21824:4;21818:11;21969:66;21950:17;21943:93;22084:2;22080:1;22061:17;22057:25;22050:37;22165:6;22160:2;22141:17;22137:26;22130:42;22977:2;22974:1;22970:2;22951:17;22948:1;22941:5;22934;22929:51;22493:16;22486:24;22480:2;22462:16;22459:24;22455:1;22451;22445:8;22442:15;22438:46;22435:76;22232:763;22221:774;;;23026:7;23018:35;;;;-1:-1:-1;;;23018:35:0;;20757:2:1;23018:35:0;;;20739:21:1;20796:2;20776:18;;;20769:30;20835:17;20815:18;;;20808:45;20870:18;;23018:35:0;20555:339:1;25894:155:0;24917:7;;;;25202:60;;25239:11;;;;;;;;;;;;;;25202:60;25953:7:::1;:15:::0;;25979:23;;;;26018::::1;::::0;26030:10:::1;1340:74:1::0;;26018:23:0::1;::::0;1328:2:1;1313:18;26018:23:0::1;1181:239:1::0;10867:166:0;10932:7;10959:21;10970:1;10474:4;10978:1;10959:10;:21::i;91021:1586::-;91092:19;91113:18;91159:34;91208:38;91260:6;-1:-1:-1;;;;;91260:24:0;;91285:9;91260:35;;;;;;;;;;;;;160:25:1;;148:2;133:18;;14:177;91260:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91346:42;;;;;91367:20;91346:42;;;160:25:1;91144:151:0;;-1:-1:-1;91144:151:0;-1:-1:-1;91309:17:0;;;;-1:-1:-1;;;;;91346:5:0;:20;;;;133:18:1;;91346:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91308:80;;;;91405:9;91418:1;91405:14;:27;;;;91423:9;91405:27;91401:101;;;91456:34;;;;;;;;12849:25:1;;;12917:14;;12910:22;12890:18;;;12883:50;12822:18;;91456:34:0;12681:258:1;91401:101:0;91536:5;:12;;;91518:15;:30;91514:1086;;;91690:41;;;;;;;;160:25:1;;;91603:18:0;;;;-1:-1:-1;;;;;91690:6:0;:30;;;;133:18:1;;91690:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91565:166;;;;;91752:13;91769:1;91752:18;91748:86;;;91798:20;;;;;;;;;;;;;;91748:86;91864:49;:27;91903:9;91864:38;:49::i;:::-;91850:63;;91550:375;;91514:1086;;;91981:8;;91991:10;;91964:38;;;;;;;;10842:25:1;;;;10883:18;;;10876:34;91946:15:0;;91964:6;-1:-1:-1;;;;;91964:16:0;;;;10815:18:1;;91964:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;92068:10;;92038:41;;;;;91946:56;;-1:-1:-1;92017:18:0;;-1:-1:-1;;;;;92038:6:0;:18;;;;:41;;92057:9;;92038:41;;10842:25:1;;;10898:2;10883:18;;10876:34;10830:2;10815:18;;10668:248;92038:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;92017:62;;92094:49;92146:356;;;;;;;;92232:15;92217:5;:12;;;:30;;;;:::i;:::-;92146:356;;;;92285:30;:7;92304:10;92285:18;:30::i;:::-;92146:356;;;;92347:9;92146:356;;;;92395:6;:18;;;92146:356;;;;92445:6;-1:-1:-1;;;;;92445:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;92146:356;;92551:37;;;;;;24591:13:1;;92551:37:0;;;24573:32:1;24661:4;24649:17;;24643:24;24621:20;;;24614:54;24712:17;;;24706:24;24684:20;;;24677:54;24787:4;24775:17;;24769:24;24747:20;;;24740:54;24850:4;24838:17;;24832:24;24810:20;;;24803:54;92094:408:0;;-1:-1:-1;92551:15:0;;:28;;24545:19:1;;92551:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;92523:65;;-1:-1:-1;92523:65:0;-1:-1:-1;;;;91514:1086:0;91133:1474;;;;91021:1586;;;:::o;26057:153::-;25019:15;;;;;;;25472:76;;25517:19;;;;;;;;;;;;;;25472:76;26132:15:::1;:23:::0;;;::::1;::::0;;26171:31:::1;::::0;26191:10:::1;1340:74:1::0;;26171:31:0::1;::::0;1328:2:1;1313:18;26171:31:0::1;1181:239:1::0;25575:152:0;24917:7;;;;25086:56;;;25122:8;;;;;;;;;;;;;;25086:56;25635:7:::1;:14:::0;;25660:22;;;;;;25698:21:::1;::::0;25708:10:::1;1340:74:1::0;;25698:21:0::1;::::0;1328:2:1;1313:18;25698:21:0::1;1181:239:1::0;105819:537:0;105909:4;105896:9;;:17;;;;;;;:::i;:::-;;;;-1:-1:-1;;105942:10:0;;105930:9;;:22;105926:115;;;105994:10;;106018:4;106006:9;;:16;;;;:::i;105926:115::-;106053:33;106089:24;;;:13;:24;;;;;106126:45;-1:-1:-1;;;;;106126:10:0;:22;106157:6;106166:4;106126:22;:45::i;:::-;106203:23;;106182:51;;;;;;;;10842:25:1;;;;10883:18;;;10876:34;;;106182:6:0;-1:-1:-1;;;;;106182:20:0;;;;10815:18:1;;106182:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;106271:4;106244:12;:23;;;:31;;;;;;;:::i;:::-;;;;-1:-1:-1;;106318:23:0;;106293:55;;;16408:25:1;;;16464:2;16449:18;;16442:34;;;;16492:18;;16485:34;;;106293:55:0;;16396:2:1;16381:18;106293:55:0;;;;;;;105885:471;105819:537;;:::o;102422:3389::-;102525:33;102561:24;;;:13;:24;;;;;102602:23;;:28;;:58;;;102656:4;102634:12;:19;;;:26;102602:58;:106;;;;102686:21;;102664:11;:44;102602:106;102598:201;;;102763:23;;102732:55;;;;;;;102752:9;;102732:55;;10842:25:1;;;10898:2;10883:18;;10876:34;10830:2;10815:18;;10668:248;102598:201:0;102840:23;;102815:49;;;;;-1:-1:-1;;;;;102876:14:0;102815:76;;;:12;:24;;;;;;:49;;;;160:25:1;;;148:2;133:18;;14:177;102815:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;102815:76:0;;102811:179;;102954:23;;102908:70;;;;;-1:-1:-1;;;;;102908:12:0;:20;;;;:70;;102937:14;;102908:70;;-1:-1:-1;;;;;13325:55:1;;;;13307:74;;13412:2;13397:18;;13390:34;13295:2;13280:18;;13133:297;102908:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102811:179;103234:13;;103262:21;;103107:187;;;;;103152:20;103107:187;;;25440:25:1;25481:18;;;25474:34;;;25544:6;25524:18;;;25517:34;-1:-1:-1;;;;;103234:13:0;;;25567:18:1;;;25560:83;25659:19;;;25652:35;;;;103084:20:0;;103107:9;:30;;;;25412:19:1;;103107:187:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;103084:210;;103307:26;103344:23;103392:12;:19;;;103384:4;:27;103380:267;;;103449:12;:23;;;103428:44;;103380:267;;;103540:17;;103526:32;;:4;;:13;:32::i;:::-;103505:53;;103617:18;103591:12;:23;;;:44;;;;:::i;:::-;103573:62;;103380:267;103659:55;-1:-1:-1;;;;;103659:4:0;:16;103684:14;103701:12;103659:16;:55::i;:::-;103727:64;;:::i;:::-;103826:6;-1:-1:-1;;;;;103804:28:0;;;103843:15;;;:27;;;103901:23;;103881:17;;;:43;103955:15;;103935:17;;;:35;103981:22;;;:40;;;104059:23;;;;;104032:24;;;:50;104093:17;;;104059:23;104093:31;;-1:-1:-1;104135:13:0;;;:20;;;104183:1;104166:14;;;:18;;;104212:17;104195:14;;;:34;104240:18;;;:33;;;-1:-1:-1;;;;;104304:4:0;104284:24;;:17;;;:24;104419:36;;;;;:14;:28;;;;;;:36;;104135:6;;104419:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;104352:103;;104521:26;104550:9;-1:-1:-1;;;;;104550:30:0;;104631:13;:23;;;104616:12;:38;;;;:::i;:::-;104704:13;;104732:21;;104550:214;;;;;;;;;;19403:6:1;104550:214:0;;;19385:25:1;19426:18;;;19419:34;;;;104669:20:0;19469:18:1;;;19462:34;-1:-1:-1;;;;;104704:13:0;;;19512:18:1;;;19505:83;19604:19;;;19597:35;19357:19;;104550:214:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;104521:243;-1:-1:-1;104777:19:0;104799:32;104521:243;104799:11;:32;:::i;:::-;104777:54;;104870:15;104844:12;:23;;:41;;;;104919:4;104896:12;:19;;;:27;;;;;;;:::i;:::-;;;;;;;;104974:11;104934:12;:29;;;:52;;;;;;;:::i;:::-;;;;-1:-1:-1;;105003:19:0;;;;104999:600;;105080:1;105048:12;:29;;;:33;105044:413;;;105127:29;;;;105213:14;;105102;;105195:33;;105127:29;;105195:17;:33::i;:::-;105271:13;;105176:52;;-1:-1:-1;105247:48:0;;-1:-1:-1;;;;;105247:10:0;:23;;;105271:13;105176:52;105247:23;:48::i;:::-;105329:17;105338:8;105329:6;:17;:::i;:::-;105314:10;;:33;;;;;;;:::i;:::-;;;;-1:-1:-1;105044:413:0;;-1:-1:-1;;;105044:413:0;;105411:12;:29;;;105410:30;;;:::i;:::-;105388:10;;:53;;;;;;;:::i;:::-;;;;-1:-1:-1;;105044:413:0;105497:1;105471:27;;;105513:29;;;:33;105561:26;105577:9;105561:15;:26::i;:::-;105643:11;105611:21;;:44;;;;;;;:::i;:::-;;;;;;;;105679:18;105666:9;;:31;;;;;;;:::i;:::-;;;;-1:-1:-1;;105740:23:0;;105715:88;;;26527:25:1;;;26583:2;26568:18;;26561:34;;;;26611:18;;26604:34;;;26669:2;26654:18;;26647:34;;;26712:3;26697:19;;26690:35;;;105715:88:0;;26514:3:1;26499:19;105715:88:0;;;;;;;102514:3297;;;;;;;;102422:3389;;;:::o;106685:2454::-;106763:9;106758:2374;106782:10;:17;106778:1;:21;106758:2374;;;106821:33;106857:13;:28;106871:10;106882:1;106871:13;;;;;;;;:::i;:::-;;;;;;;106857:28;;;;;;;;;;;106821:64;;106906:12;:19;;;106929:1;106906:24;106902:89;;;106958:17;;;;;;;;;;;;;;106902:89;107078:23;;107048:54;;;;;107007:38;;-1:-1:-1;;;;;107048:12:0;:29;;;;:54;;;;160:25:1;;;148:2;133:18;;14:177;107048:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;107007:95;-1:-1:-1;107136:34:0;107121:11;:49;;;;;;;;:::i;:::-;;107117:166;;107215:10;107226:1;107215:13;;;;;;;;:::i;:::-;;;;;;;107230:12;:23;;;107255:11;107198:69;;;;;;;;;;;;;:::i;107117:166::-;107337:18;107374:32;107424:6;-1:-1:-1;;;;;107424:30:0;;107455:10;107466:1;107455:13;;;;;;;;:::i;:::-;;;;;;;107424:45;;;;;;;;;;;;;160:25:1;;148:2;133:18;;14:177;107424:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;107299:170;;;;;107490:13;107507:1;107490:18;107486:86;;;107536:20;;;;;;;;;;;;;;107486:86;107632:17;107652:59;107691:12;:19;;;107652:27;:38;;:59;;;;:::i;:::-;107632:79;-1:-1:-1;107732:13:0;;107728:77;;107780:9;107766:10;;:23;;;;;;;:::i;:::-;;;;-1:-1:-1;;107728:77:0;107834:12;:23;;;107821:9;;:36;;;;;;;:::i;:::-;;;;-1:-1:-1;;107878:29:0;;;;107910:1;-1:-1:-1;107874:749:0;;;107957:29;;;;107932:14;108045;108041:178;;108113:14;;108095:33;;:6;;:17;:33::i;:::-;108175:13;;108084:44;;-1:-1:-1;108151:48:0;;-1:-1:-1;;;;;108151:10:0;:23;;;108175:13;108084:44;108151:23;:48::i;:::-;108252:17;108261:8;108252:6;:17;:::i;:::-;108237:10;;:33;;;;;;;:::i;:::-;;;;;;;;108321:6;108289:21;;:39;;;;;;;:::i;:::-;;;;-1:-1:-1;;108351:21:0;;108375:1;-1:-1:-1;108347:167:0;;;108424:21;;108423:22;;;:::i;:::-;108401:10;;:45;;;;;;;:::i;:::-;;;;-1:-1:-1;;108493:1:0;108469:21;:25;108347:167;107913:616;;107874:749;;;108577:12;:29;;;108576:30;;;:::i;:::-;108554:10;;:53;;;;;;;:::i;:::-;;;;-1:-1:-1;;107874:749:0;108644:257;108675:10;108686:1;108675:13;;;;;;;;:::i;:::-;;;;;;;108707:12;:23;;;108749:12;:19;;;108787:12;:23;;;108829:12;:29;;;108877:9;108644:257;;;;;;;;;;20302:25:1;;;20358:2;20343:18;;20336:34;;;;20401:2;20386:18;;20379:34;;;;20444:2;20429:18;;20422:34;20487:3;20472:19;;20465:35;20531:3;20516:19;;20509:35;20289:3;20274:19;;20015:535;108644:257:0;;;;;;;;108944:1;108918:27;;;108960:29;;;:33;;;109008:19;;;:23;;;-1:-1:-1;109046:23:0;;:27;109106:13;;109090:30;;109106:10;;109117:1;;109106:13;;;;;;:::i;:::-;;;;;;;109090:15;:30::i;:::-;106806:2326;;;;;106801:3;;;;;:::i;:::-;;;;106758:2374;;;;106685:2454;:::o;19964:1604::-;20108:12;20239:4;20233:11;20384:66;20365:17;20358:93;20499:4;20495:1;20476:17;20472:25;20465:39;20584:2;20579;20560:17;20556:26;20549:38;20665:6;20660:2;20641:17;20637:26;20630:42;21479:2;21476:1;21471:3;21452:17;21449:1;21442:5;21435;21430:52;20993:16;20986:24;20980:2;20962:16;20959:24;20955:1;20951;20945:8;20942:15;20938:46;20935:76;20732:765;20721:776;;;21528:7;21520:40;;;;-1:-1:-1;;;21520:40:0;;28155:2:1;21520:40:0;;;28137:21:1;28194:2;28174:18;;;28167:30;28233:22;28213:18;;;28206:50;28273:18;;21520:40:0;27953:344:1;21520:40:0;20097:1471;19964:1604;;;;:::o;92730:916::-;92794:16;92838:34;92887:38;92939:6;-1:-1:-1;;;;;92939:24:0;;92964:9;92939:35;;;;;;;;;;;;;160:25:1;;148:2;133:18;;14:177;92939:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93025:42;;;;;93046:20;93025:42;;;160:25:1;92823:151:0;;-1:-1:-1;92823:151:0;-1:-1:-1;92988:17:0;;;;-1:-1:-1;;;;;93025:5:0;:20;;;;133:18:1;;93025:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;92987:80;;;;93084:9;93097:1;93084:14;:27;;;;93102:9;93084:27;93080:101;;;93135:34;;;;;;;;12849:25:1;;;12917:14;;12910:22;12890:18;;;12883:50;12822:18;;93135:34:0;12681:258:1;93080:101:0;93193:49;93245:334;;;;;;;;93327:15;93312:5;:12;;;:30;;;;:::i;:::-;93245:334;;;;93376:32;93396:6;:11;;;93376:5;:8;;;:19;;:32;;;;:::i;:::-;93245:334;;;;93436:9;93245:334;;;;93480:6;:18;;;93245:334;;;;93526:6;-1:-1:-1;;;;;93526:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;93245:334;;93608:30;;;;;;24591:13:1;;93608:30:0;;;24573:32:1;24661:4;24649:17;;24643:24;24621:20;;;24614:54;24712:17;;;24706:24;24684:20;;;24677:54;24787:4;24775:17;;24769:24;24747:20;;;24740:54;24850:4;24838:17;;24832:24;24810:20;;;24803:54;93193:386:0;;-1:-1:-1;93608:15:0;;:21;;24545:19:1;;93608:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;93592:46:0;92730:916;-1:-1:-1;;;;;;;92730:916:0:o;23069:1483::-;23185:12;23316:4;23310:11;23461:66;23442:17;23435:93;23576:2;23572:1;23553:17;23549:25;23542:37;23657:6;23652:2;23633:17;23629:26;23622:42;24469:2;24466:1;24462:2;24443:17;24440:1;24433:5;24426;24421:51;23985:16;23978:24;23972:2;23954:16;23951:24;23947:1;23943;23937:8;23934:15;23930:46;23927:76;23724:763;23713:774;;;24518:7;24510:34;;;;-1:-1:-1;;;24510:34:0;;28752:2:1;24510:34:0;;;28734:21:1;28791:2;28771:18;;;28764:30;28830:16;28810:18;;;28803:44;28864:18;;24510:34:0;28550:338:1;11405:552:0;11618:9;;;11752:19;;11745:27;11777:9;;11791;;;11788:16;;11774:31;11741:65;11731:123;;11837:1;11834;11827:12;11731:123;11920:19;;11405:552;-1:-1:-1;;11405:552:0:o;11965:771::-;12176:9;;;12310:19;;12303:27;12335:9;;12349;;;12346:16;;12332:31;12299:65;12289:123;;12395:1;12392;12385:12;12289:123;12715:1;12701:11;12697:1;12694;12690:9;12686:27;12682:35;12677:1;12670:9;12663:17;12659:59;12654:64;;11965:771;;;;;:::o;10699:160::-;10762:7;10789:19;10798:1;10801;10474:4;10789:8;:19::i;109147:372::-;109243:11;:18;109211:9;;109272:123;109288:1;109284;:5;109272:123;;;109328:11;109340:1;109328:14;;;;;;;;:::i;:::-;;;;;;;;;109315:9;:27;109311:73;;;109363:5;;109311:73;109291:3;;;;:::i;:::-;;;;109272:123;;;109415:1;109411;:5;109407:105;;;109450:11;109462:5;109466:1;109462;:5;:::i;:::-;109450:18;;;;;;;;:::i;:::-;;;;;;;;;109433:11;109445:1;109433:14;;;;;;;;:::i;:::-;;;;;;;;;;:35;109483:11;:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;109407:105;109200:319;;109147:372;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;378:248:1:-;446:6;454;507:2;495:9;486:7;482:23;478:32;475:52;;;523:1;520;513:12;475:52;-1:-1:-1;;546:23:1;;;616:2;601:18;;;588:32;;-1:-1:-1;378:248:1:o;631:154::-;-1:-1:-1;;;;;710:5:1;706:54;699:5;696:65;686:93;;775:1;772;765:12;790:247;849:6;902:2;890:9;881:7;877:23;873:32;870:52;;;918:1;915;908:12;870:52;957:9;944:23;976:31;1001:5;976:31;:::i;1425:180::-;1484:6;1537:2;1525:9;1516:7;1512:23;1508:32;1505:52;;;1553:1;1550;1543:12;1505:52;-1:-1:-1;1576:23:1;;1425:180;-1:-1:-1;1425:180:1:o;4341:456::-;4418:6;4426;4434;4487:2;4475:9;4466:7;4462:23;4458:32;4455:52;;;4503:1;4500;4493:12;4455:52;4542:9;4529:23;4561:31;4586:5;4561:31;:::i;:::-;4611:5;-1:-1:-1;4668:2:1;4653:18;;4640:32;4681:33;4640:32;4681:33;:::i;:::-;4341:456;;4733:7;;-1:-1:-1;;;4787:2:1;4772:18;;;;4759:32;;4341:456::o;4802:632::-;4973:2;5025:21;;;5095:13;;4998:18;;;5117:22;;;4944:4;;4973:2;5196:15;;;;5170:2;5155:18;;;4944:4;5239:169;5253:6;5250:1;5247:13;5239:169;;;5314:13;;5302:26;;5383:15;;;;5348:12;;;;5275:1;5268:9;5239:169;;;-1:-1:-1;5425:3:1;;4802:632;-1:-1:-1;;;;;;4802:632:1:o;5439:316::-;5516:6;5524;5532;5585:2;5573:9;5564:7;5560:23;5556:32;5553:52;;;5601:1;5598;5591:12;5553:52;-1:-1:-1;;5624:23:1;;;5694:2;5679:18;;5666:32;;-1:-1:-1;5745:2:1;5730:18;;;5717:32;;5439:316;-1:-1:-1;5439:316:1:o;5760:184::-;5812:77;5809:1;5802:88;5909:4;5906:1;5899:15;5933:4;5930:1;5923:15;5949:253;6021:2;6015:9;6063:4;6051:17;;6098:18;6083:34;;6119:22;;;6080:62;6077:88;;;6145:18;;:::i;:::-;6181:2;6174:22;5949:253;:::o;6207:255::-;6279:2;6273:9;6321:6;6309:19;;6358:18;6343:34;;6379:22;;;6340:62;6337:88;;;6405:18;;:::i;6467:252::-;6539:2;6533:9;6581:3;6569:16;;6615:18;6600:34;;6636:22;;;6597:62;6594:88;;;6662:18;;:::i;6724:334::-;6795:2;6789:9;6851:2;6841:13;;6856:66;6837:86;6825:99;;6954:18;6939:34;;6975:22;;;6936:62;6933:88;;;7001:18;;:::i;:::-;7037:2;7030:22;6724:334;;-1:-1:-1;6724:334:1:o;7063:183::-;7123:4;7156:18;7148:6;7145:30;7142:56;;;7178:18;;:::i;:::-;-1:-1:-1;7223:1:1;7219:14;7235:4;7215:25;;7063:183::o;7251:891::-;7335:6;7366:2;7409;7397:9;7388:7;7384:23;7380:32;7377:52;;;7425:1;7422;7415:12;7377:52;7465:9;7452:23;7498:18;7490:6;7487:30;7484:50;;;7530:1;7527;7520:12;7484:50;7553:22;;7606:4;7598:13;;7594:27;-1:-1:-1;7584:55:1;;7635:1;7632;7625:12;7584:55;7671:2;7658:16;7694:60;7710:43;7750:2;7710:43;:::i;:::-;7694:60;:::i;:::-;7788:15;;;7870:1;7866:10;;;;7858:19;;7854:28;;;7819:12;;;;7894:19;;;7891:39;;;7926:1;7923;7916:12;7891:39;7950:11;;;;7970:142;7986:6;7981:3;7978:15;7970:142;;;8052:17;;8040:30;;8003:12;;;;8090;;;;7970:142;;;8131:5;7251:891;-1:-1:-1;;;;;;;7251:891:1:o;8395:315::-;8463:6;8471;8524:2;8512:9;8503:7;8499:23;8495:32;8492:52;;;8540:1;8537;8530:12;8492:52;8579:9;8566:23;8598:31;8623:5;8598:31;:::i;:::-;8648:5;8700:2;8685:18;;;;8672:32;;-1:-1:-1;;;8395:315:1:o;11260:184::-;11312:77;11309:1;11302:88;11409:4;11406:1;11399:15;11433:4;11430:1;11423:15;11449:128;11489:3;11520:1;11516:6;11513:1;11510:13;11507:39;;;11526:18;;:::i;:::-;-1:-1:-1;11562:9:1;;11449:128::o;11582:125::-;11622:4;11650:1;11647;11644:8;11641:34;;;11655:18;;:::i;:::-;-1:-1:-1;11692:9:1;;11582:125::o;11712:195::-;11751:3;11782:66;11775:5;11772:77;11769:103;;;11852:18;;:::i;:::-;-1:-1:-1;11899:1:1;11888:13;;11712:195::o;12244:164::-;12320:13;;12369;;12362:21;12352:32;;12342:60;;12398:1;12395;12388:12;12342:60;12244:164;;;:::o;12413:263::-;12489:6;12497;12550:2;12538:9;12529:7;12525:23;12521:32;12518:52;;;12566:1;12563;12556:12;12518:52;12595:9;12589:16;12579:26;;12624:46;12666:2;12655:9;12651:18;12624:46;:::i;:::-;12614:56;;12413:263;;;;;:::o;12944:184::-;12996:77;12993:1;12986:88;13093:4;13090:1;13083:15;13117:4;13114:1;13107:15;14158:202;14225:6;14278:2;14266:9;14257:7;14253:23;14249:32;14246:52;;;14294:1;14291;14284:12;14246:52;14317:37;14344:9;14317:37;:::i;14365:184::-;14435:6;14488:2;14476:9;14467:7;14463:23;14459:32;14456:52;;;14504:1;14501;14494:12;14456:52;-1:-1:-1;14527:16:1;;14365:184;-1:-1:-1;14365:184:1:o;15807:138::-;15886:13;;15908:31;15886:13;15908:31;:::i;15950:251::-;16020:6;16073:2;16061:9;16052:7;16048:23;16044:32;16041:52;;;16089:1;16086;16079:12;16041:52;16121:9;16115:16;16140:31;16165:5;16140:31;:::i;16530:184::-;16582:77;16579:1;16572:88;16679:4;16676:1;16669:15;16703:4;16700:1;16693:15;16719:141;16801:1;16794:5;16791:12;16781:46;;16807:18;;:::i;:::-;16836;;16719:141::o;16865:1182::-;17114:13;;-1:-1:-1;;;;;1115:54:1;1103:67;;17075:3;17060:19;;17195:4;17187:6;17183:17;17177:24;17170:4;17159:9;17155:20;17148:54;17258:4;17250:6;17246:17;17240:24;17233:4;17222:9;17218:20;17211:54;17321:4;17313:6;17309:17;17303:24;17296:4;17285:9;17281:20;17274:54;17384:4;17376:6;17372:17;17366:24;17359:4;17348:9;17344:20;17337:54;17447:4;17439:6;17435:17;17429:24;17422:4;17411:9;17407:20;17400:54;17501:4;17493:6;17489:17;17483:24;17516:62;17572:4;17561:9;17557:20;17543:12;17516:62;:::i;:::-;-1:-1:-1;17634:4:1;17622:17;;;17616:24;17594:20;;;17587:54;17660:6;17708:15;;;17702:22;17682:18;;;17675:50;17744:6;17792:15;;;17786:22;17766:18;;;17759:50;17828:6;17876:15;;;17870:22;17850:18;;;17843:50;17912:6;17955:15;;;17949:22;-1:-1:-1;;;;;1115:54:1;18022:18;;;;1103:67;;;;16865:1182;:::o;18052:1006::-;18153:6;18184:3;18228:2;18216:9;18207:7;18203:23;18199:32;18196:52;;;18244:1;18241;18234:12;18196:52;18277:2;18271:9;18307:15;;;;18352:18;18337:34;;18373:22;;;18334:62;18331:88;;;18399:18;;:::i;:::-;18439:10;18435:2;18428:22;18478:9;18472:16;18459:29;;18497:31;18522:5;18497:31;:::i;:::-;18552:5;18544:6;18537:21;18612:2;18601:9;18597:18;18591:25;18586:2;18578:6;18574:15;18567:50;18650:49;18695:2;18684:9;18680:18;18650:49;:::i;:::-;18645:2;18637:6;18633:15;18626:74;18754:2;18743:9;18739:18;18733:25;18728:2;18720:6;18716:15;18709:50;18814:3;18803:9;18799:19;18793:26;18787:3;18779:6;18775:16;18768:52;18875:3;18864:9;18860:19;18854:26;18848:3;18840:6;18836:16;18829:52;18936:3;18925:9;18921:19;18915:26;18909:3;18901:6;18897:16;18890:52;18976:50;19021:3;19010:9;19006:19;18976:50;:::i;:::-;18970:3;18958:16;;18951:76;18962:6;18052:1006;-1:-1:-1;;;;18052:1006:1:o;19643:367::-;19682:3;19717:1;19714;19710:9;19826:1;19758:66;19754:74;19751:1;19747:82;19742:2;19735:10;19731:99;19728:125;;;19833:18;;:::i;:::-;19952:1;19884:66;19880:74;19877:1;19873:82;19869:2;19865:91;19862:117;;;19959:18;;:::i;:::-;-1:-1:-1;;19995:9:1;;19643:367::o;20899:1144::-;20968:5;21016:4;21004:9;20999:3;20995:19;20991:30;20988:50;;;21034:1;21031;21024:12;20988:50;21056:22;;:::i;:::-;21047:31;;21107:9;21101:16;21094:5;21087:31;21137:2;21192;21181:9;21177:18;21171:25;21166:2;21159:5;21155:14;21148:49;21250:2;21239:9;21235:18;21229:25;21224:2;21217:5;21213:14;21206:49;21287:46;21329:2;21318:9;21314:18;21287:46;:::i;:::-;21282:2;21275:5;21271:14;21264:70;21378:3;21367:9;21363:19;21357:26;21406:18;21398:6;21395:30;21392:50;;;21438:1;21435;21428:12;21392:50;21461:22;;21514:4;21506:13;;21502:23;-1:-1:-1;21492:51:1;;21539:1;21536;21529:12;21492:51;21568:2;21562:9;21591:60;21607:43;21647:2;21607:43;:::i;21591:60::-;21685:15;;;21767:1;21763:10;;;;21755:19;;21751:28;;;21716:12;;;;21791:15;;;21788:35;;;21819:1;21816;21809:12;21788:35;21843:11;;;;21863:135;21879:6;21874:3;21871:15;21863:135;;;21945:10;;21933:23;;21896:12;;;;21976;;;;21863:135;;;22025:3;22014:15;;22007:30;-1:-1:-1;22018:5:1;;20899:1144;-1:-1:-1;;;;;20899:1144:1:o;22048:1107::-;22180:6;22188;22232:9;22223:7;22219:23;22262:3;22258:2;22254:12;22251:32;;;22279:1;22276;22269:12;22251:32;22302:6;22328:2;22324;22320:11;22317:31;;;22344:1;22341;22334:12;22317:31;22370:22;;:::i;:::-;22357:35;;22421:9;22415:16;22408:5;22401:31;22485:2;22474:9;22470:18;22464:25;22459:2;22452:5;22448:14;22441:49;22543:2;22532:9;22528:18;22522:25;22517:2;22510:5;22506:14;22499:49;22601:2;22590:9;22586:18;22580:25;22575:2;22568:5;22564:14;22557:49;22660:3;22649:9;22645:19;22639:26;22633:3;22626:5;22622:15;22615:51;22720:3;22709:9;22705:19;22699:26;22693:3;22686:5;22682:15;22675:51;22780:3;22769:9;22765:19;22759:26;22753:3;22746:5;22742:15;22735:51;22840:3;22829:9;22825:19;22819:26;22813:3;22806:5;22802:15;22795:51;22865:3;22921:2;22910:9;22906:18;22900:25;22895:2;22888:5;22884:14;22877:49;;22945:5;22935:15;;22994:2;22983:9;22979:18;22973:25;22959:39;;;23021:18;23013:6;23010:30;23007:50;;;23053:1;23050;23043:12;23007:50;23076:73;23141:7;23132:6;23121:9;23117:22;23076:73;:::i;:::-;23066:83;;;22048:1107;;;;;:::o;23160:306::-;23248:6;23256;23264;23317:2;23305:9;23296:7;23292:23;23288:32;23285:52;;;23333:1;23330;23323:12;23285:52;23362:9;23356:16;23346:26;;23412:2;23401:9;23397:18;23391:25;23381:35;;23456:2;23445:9;23441:18;23435:25;23425:35;;23160:306;;;;;:::o;23471:870::-;23579:6;23632:3;23620:9;23611:7;23607:23;23603:33;23600:53;;;23649:1;23646;23639:12;23600:53;23675:22;;:::i;:::-;23726:9;23720:16;23713:5;23706:31;23790:2;23779:9;23775:18;23769:25;23764:2;23757:5;23753:14;23746:49;23848:2;23837:9;23833:18;23827:25;23822:2;23815:5;23811:14;23804:49;23906:2;23895:9;23891:18;23885:25;23880:2;23873:5;23869:14;23862:49;23965:3;23954:9;23950:19;23944:26;23938:3;23931:5;23927:15;23920:51;24025:3;24014:9;24010:19;24004:26;23998:3;23991:5;23987:15;23980:51;24085:3;24074:9;24070:19;24064:26;24058:3;24051:5;24047:15;24040:51;24145:3;24134:9;24130:19;24124:26;24118:3;24111:5;24107:15;24100:51;24170:3;24226:2;24215:9;24211:18;24205:25;24200:2;24193:5;24189:14;24182:49;;24250:3;24306:2;24295:9;24291:18;24285:25;24280:2;24273:5;24269:14;24262:49;;24330:5;24320:15;;;23471:870;;;;:::o;24868:245::-;24947:6;24955;25008:2;24996:9;24987:7;24983:23;24979:32;24976:52;;;25024:1;25021;25014:12;24976:52;-1:-1:-1;;25047:16:1;;25103:2;25088:18;;;25082:25;25047:16;;25082:25;;-1:-1:-1;24868:245:1:o;25698:369::-;25737:4;25773:1;25770;25766:9;25882:1;25814:66;25810:74;25807:1;25803:82;25798:2;25791:10;25787:99;25784:125;;;25889:18;;:::i;:::-;26008:1;25940:66;25936:74;25933:1;25929:82;25925:2;25921:91;25918:117;;;26015:18;;:::i;:::-;-1:-1:-1;;26052:9:1;;25698:369::o;26072:191::-;26107:3;26138:66;26131:5;26128:77;26125:103;;;26208:18;;:::i;:::-;-1:-1:-1;26248:1:1;26244:13;;26072:191::o;26736:278::-;26824:6;26877:2;26865:9;26856:7;26852:23;26848:32;26845:52;;;26893:1;26890;26883:12;26845:52;26925:9;26919:16;26964:1;26957:5;26954:12;26944:40;;26980:1;26977;26970:12;27019:391;27237:25;;;27293:2;27278:18;;27271:34;;;27225:2;27210:18;;27335:1;27324:13;;27314:47;;27341:18;;:::i;:::-;27397:6;27392:2;27381:9;27377:18;27370:34;27019:391;;;;;;:::o;28893:184::-;28945:77;28942:1;28935:88;29042:4;29039:1;29032:15;29066:4;29063:1;29056:15

Swarm Source

ipfs://fe8a9eac0a5149f64c9df9d3ab950c9aed3dcc58e633fa22bf618a7b7fe1de3d
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.