Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 12882248 | 1199 days ago | IN | 0 ETH | 0.05029728 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
13262496 | 1140 days ago | 21.89752595 ETH | ||||
13262496 | 1140 days ago | 21.89752595 ETH | ||||
13262496 | 1140 days ago | 48.85402532 ETH | ||||
13262496 | 1140 days ago | 26.97618941 ETH | ||||
13262496 | 1140 days ago | 21.8778359 ETH | ||||
13261749 | 1140 days ago | 1.06980285 ETH | ||||
13261749 | 1140 days ago | 1.06980285 ETH | ||||
13261749 | 1140 days ago | 3.25397999 ETH | ||||
13261749 | 1140 days ago | 2.18513908 ETH | ||||
13261749 | 1140 days ago | 1.0688409 ETH | ||||
13261747 | 1140 days ago | 0.46101919 ETH | ||||
13261747 | 1140 days ago | 0.46101919 ETH | ||||
13261747 | 1140 days ago | 4.09317527 ETH | ||||
13261747 | 1140 days ago | 3.63257062 ETH | ||||
13261747 | 1140 days ago | 0.46060464 ETH | ||||
13261739 | 1140 days ago | 4.2330013 ETH | ||||
13261739 | 1140 days ago | 4.2330013 ETH | ||||
13261739 | 1140 days ago | 7.50685022 ETH | ||||
13261739 | 1140 days ago | 3.27765518 ETH | ||||
13261739 | 1140 days ago | 4.22919503 ETH | ||||
13261725 | 1140 days ago | 2.11327762 ETH | ||||
13261725 | 1140 days ago | 2.11327762 ETH | ||||
13261725 | 1140 days ago | 4.15944512 ETH | ||||
13261725 | 1140 days ago | 2.04806773 ETH | ||||
13261725 | 1140 days ago | 2.11137738 ETH |
Loading...
Loading
Contract Name:
MCDSaverFlashLoan
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-07-23 */ // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; contract DefisaverLogger { event LogEvent( address indexed contractAddress, address indexed caller, string indexed logName, bytes data ); // solhint-disable-next-line func-name-mixedcase function Log(address _contract, address _caller, string memory _logName, bytes memory _data) public { emit LogEvent(_contract, _caller, _logName, _data); } } contract Discount { address public owner; mapping(address => CustomServiceFee) public serviceFees; uint256 constant MAX_SERVICE_FEE = 400; struct CustomServiceFee { bool active; uint256 amount; } constructor() public { owner = msg.sender; } function isCustomFeeSet(address _user) public view returns (bool) { return serviceFees[_user].active; } function getCustomServiceFee(address _user) public view returns (uint256) { return serviceFees[_user].amount; } function setServiceFee(address _user, uint256 _fee) public { require(msg.sender == owner, "Only owner"); require(_fee >= MAX_SERVICE_FEE || _fee == 0); serviceFees[_user] = CustomServiceFee({active: true, amount: _fee}); } function disableServiceFee(address _user) public { require(msg.sender == owner, "Only owner"); serviceFees[_user] = CustomServiceFee({active: false, amount: 0}); } } abstract contract PipInterface { function read() public virtual returns (bytes32); } abstract contract Spotter { struct Ilk { PipInterface pip; uint256 mat; } mapping (bytes32 => Ilk) public ilks; uint256 public par; } abstract contract Jug { struct Ilk { uint256 duty; uint256 rho; } mapping (bytes32 => Ilk) public ilks; function drip(bytes32) public virtual returns (uint); } abstract contract Vat { struct Urn { uint256 ink; // Locked Collateral [wad] uint256 art; // Normalised Debt [wad] } struct Ilk { uint256 Art; // Total Normalised Debt [wad] uint256 rate; // Accumulated Rates [ray] uint256 spot; // Price with Safety Margin [ray] uint256 line; // Debt Ceiling [rad] uint256 dust; // Urn Debt Floor [rad] } mapping (bytes32 => mapping (address => Urn )) public urns; mapping (bytes32 => Ilk) public ilks; mapping (bytes32 => mapping (address => uint)) public gem; // [wad] function can(address, address) virtual public view returns (uint); function dai(address) virtual public view returns (uint); function frob(bytes32, address, address, address, int, int) virtual public; function hope(address) virtual public; function move(address, address, uint) virtual public; function fork(bytes32, address, address, int, int) virtual public; } abstract contract Gem { function dec() virtual public returns (uint); function gem() virtual public returns (Gem); function join(address, uint) virtual public payable; function exit(address, uint) virtual public; function approve(address, uint) virtual public; function transfer(address, uint) virtual public returns (bool); function transferFrom(address, address, uint) virtual public returns (bool); function deposit() virtual public payable; function withdraw(uint) virtual public; function allowance(address, address) virtual public returns (uint); } abstract contract DaiJoin { function vat() public virtual returns (Vat); function dai() public virtual returns (Gem); function join(address, uint) public virtual payable; function exit(address, uint) public virtual; } abstract contract Join { bytes32 public ilk; function dec() virtual public view returns (uint); function gem() virtual public view returns (Gem); function join(address, uint) virtual public payable; function exit(address, uint) virtual public; } contract DSMath { function add(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x + y) >= x); } function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x - y) <= x); } function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { require(y == 0 || (z = x * y) / y == x); } function div(uint256 x, uint256 y) internal pure returns (uint256 z) { return x / y; } function min(uint256 x, uint256 y) internal pure returns (uint256 z) { return x <= y ? x : y; } function max(uint256 x, uint256 y) internal pure returns (uint256 z) { return x >= y ? x : y; } function imin(int256 x, int256 y) internal pure returns (int256 z) { return x <= y ? x : y; } function imax(int256 x, int256 y) internal pure returns (int256 z) { return x >= y ? x : y; } uint256 constant WAD = 10**18; uint256 constant RAY = 10**27; function wmul(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, y), WAD / 2) / WAD; } function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, y), RAY / 2) / RAY; } function wdiv(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, WAD), y / 2) / y; } function rdiv(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, RAY), y / 2) / y; } // This famous algorithm is called "exponentiation by squaring" // and calculates x^n with x as fixed-point and n as regular unsigned. // // It's O(log n), instead of O(n) for naive repeated multiplication. // // These facts are why it works: // // If n is even, then x^n = (x^2)^(n/2). // If n is odd, then x^n = x * x^(n-1), // and applying the equation for even x gives // x^n = x * (x^2)^((n-1) / 2). // // Also, EVM division is flooring and // floor[(n-1) / 2] = floor[n / 2]. // function rpow(uint256 x, uint256 n) internal pure returns (uint256 z) { z = n % 2 != 0 ? x : RAY; for (n /= 2; n != 0; n /= 2) { x = rmul(x, x); if (n % 2 != 0) { z = rmul(z, x); } } } } abstract contract DSAuthority { function canCall(address src, address dst, bytes4 sig) public virtual view returns (bool); } contract DSAuthEvents { event LogSetAuthority(address indexed authority); event LogSetOwner(address indexed owner); } contract DSAuth is DSAuthEvents { DSAuthority public authority; address public owner; constructor() public { owner = msg.sender; emit LogSetOwner(msg.sender); } function setOwner(address owner_) public auth { owner = owner_; emit LogSetOwner(owner); } function setAuthority(DSAuthority authority_) public auth { authority = authority_; emit LogSetAuthority(address(authority)); } modifier auth { require(isAuthorized(msg.sender, msg.sig)); _; } function isAuthorized(address src, bytes4 sig) internal view returns (bool) { if (src == address(this)) { return true; } else if (src == owner) { return true; } else if (authority == DSAuthority(0)) { return false; } else { return authority.canCall(src, address(this), sig); } } } contract DSNote { event LogNote( bytes4 indexed sig, address indexed guy, bytes32 indexed foo, bytes32 indexed bar, uint256 wad, bytes fax ) anonymous; modifier note { bytes32 foo; bytes32 bar; assembly { foo := calldataload(4) bar := calldataload(36) } emit LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data); _; } } abstract contract DSProxy is DSAuth, DSNote { DSProxyCache public cache; // global cache for contracts constructor(address _cacheAddr) public { require(setCache(_cacheAddr)); } // solhint-disable-next-line no-empty-blocks receive() external payable {} // use the proxy to execute calldata _data on contract _code // function execute(bytes memory _code, bytes memory _data) // public // payable // virtual // returns (address target, bytes32 response); function execute(address _target, bytes memory _data) public payable virtual returns (bytes32 response); //set new cache function setCache(address _cacheAddr) public virtual payable returns (bool); } contract DSProxyCache { mapping(bytes32 => address) cache; function read(bytes memory _code) public view returns (address) { bytes32 hash = keccak256(_code); return cache[hash]; } function write(bytes memory _code) public returns (address target) { assembly { target := create(0, add(_code, 0x20), mload(_code)) switch iszero(extcodesize(target)) case 1 { // throw if contract failed to deploy revert(0, 0) } } bytes32 hash = keccak256(_code); cache[hash] = target; } } abstract contract Manager { function last(address) virtual public returns (uint); function cdpCan(address, uint, address) virtual public view returns (uint); function ilks(uint) virtual public view returns (bytes32); function owns(uint) virtual public view returns (address); function urns(uint) virtual public view returns (address); function vat() virtual public view returns (address); function open(bytes32, address) virtual public returns (uint); function give(uint, address) virtual public; function cdpAllow(uint, address, uint) virtual public; function urnAllow(address, uint) virtual public; function frob(uint, int, int) virtual public; function flux(uint, address, uint) virtual public; function move(uint, address, uint) virtual public; function exit(address, uint, address, uint) virtual public; function quit(uint, address) virtual public; function enter(address, uint) virtual public; function shift(uint, uint) virtual public; } /// @title Helper methods for MCDSaverProxy contract MCDSaverProxyHelper is DSMath { enum ManagerType { MCD, BPROTOCOL } /// @notice Returns a normalized debt _amount based on the current rate /// @param _amount Amount of dai to be normalized /// @param _rate Current rate of the stability fee /// @param _daiVatBalance Balance od Dai in the Vat for that CDP function normalizeDrawAmount(uint _amount, uint _rate, uint _daiVatBalance) internal pure returns (int dart) { if (_daiVatBalance < mul(_amount, RAY)) { dart = toPositiveInt(sub(mul(_amount, RAY), _daiVatBalance) / _rate); dart = mul(uint(dart), _rate) < mul(_amount, RAY) ? dart + 1 : dart; } } /// @notice Converts a number to Rad percision /// @param _wad The input number in wad percision function toRad(uint _wad) internal pure returns (uint) { return mul(_wad, 10 ** 27); } /// @notice Converts a number to 18 decimal percision /// @param _joinAddr Join address of the collateral /// @param _amount Number to be converted function convertTo18(address _joinAddr, uint256 _amount) internal view returns (uint256) { return mul(_amount, 10 ** (18 - Join(_joinAddr).dec())); } /// @notice Converts a uint to int and checks if positive /// @param _x Number to be converted function toPositiveInt(uint _x) internal pure returns (int y) { y = int(_x); require(y >= 0, "int-overflow"); } /// @notice Gets Dai amount in Vat which can be added to Cdp /// @param _vat Address of Vat contract /// @param _urn Urn of the Cdp /// @param _ilk Ilk of the Cdp function normalizePaybackAmount(address _vat, address _urn, bytes32 _ilk) internal view returns (int amount) { uint dai = Vat(_vat).dai(_urn); (, uint rate,,,) = Vat(_vat).ilks(_ilk); (, uint art) = Vat(_vat).urns(_ilk, _urn); amount = toPositiveInt(dai / rate); amount = uint(amount) <= art ? - amount : - toPositiveInt(art); } /// @notice Gets the whole debt of the CDP /// @param _vat Address of Vat contract /// @param _usr Address of the Dai holder /// @param _urn Urn of the Cdp /// @param _ilk Ilk of the Cdp function getAllDebt(address _vat, address _usr, address _urn, bytes32 _ilk) internal view returns (uint daiAmount) { (, uint rate,,,) = Vat(_vat).ilks(_ilk); (, uint art) = Vat(_vat).urns(_ilk, _urn); uint dai = Vat(_vat).dai(_usr); uint rad = sub(mul(art, rate), dai); daiAmount = rad / RAY; daiAmount = mul(daiAmount, RAY) < rad ? daiAmount + 1 : daiAmount; } /// @notice Gets the token address from the Join contract /// @param _joinAddr Address of the Join contract function getCollateralAddr(address _joinAddr) internal view returns (address) { return address(Join(_joinAddr).gem()); } /// @notice Checks if the join address is one of the Ether coll. types /// @param _joinAddr Join address to check function isEthJoinAddr(address _joinAddr) internal view returns (bool) { // if it's dai_join_addr don't check gem() it will fail if (_joinAddr == 0x9759A6Ac90977b93B58547b4A71c78317f391A28) return false; // if coll is weth it's and eth type coll if (address(Join(_joinAddr).gem()) == 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2) { return true; } return false; } /// @notice Gets CDP info (collateral, debt) /// @param _manager Manager contract /// @param _cdpId Id of the CDP /// @param _ilk Ilk of the CDP function getCdpInfo(Manager _manager, uint _cdpId, bytes32 _ilk) public view returns (uint, uint) { address vat = _manager.vat(); address urn = _manager.urns(_cdpId); (uint collateral, uint debt) = Vat(vat).urns(_ilk, urn); (,uint rate,,,) = Vat(vat).ilks(_ilk); return (collateral, rmul(debt, rate)); } /// @notice Address that owns the DSProxy that owns the CDP /// @param _manager Manager contract /// @param _cdpId Id of the CDP function getOwner(Manager _manager, uint _cdpId) public view returns (address) { DSProxy proxy = DSProxy(uint160(_manager.owns(_cdpId))); return proxy.owner(); } /// @notice Based on the manager type returns the address /// @param _managerType Type of vault manager to use function getManagerAddr(ManagerType _managerType) public pure returns (address) { if (_managerType == ManagerType.MCD) { return 0x5ef30b9986345249bc32d8928B7ee64DE9435E39; } else if (_managerType == ManagerType.BPROTOCOL) { return 0x3f30c2381CD8B917Dd96EB2f1A4F96D91324BBed; } } } interface ERC20 { function totalSupply() external view returns (uint256 supply); function balanceOf(address _owner) external view returns (uint256 balance); function transfer(address _to, uint256 _value) external returns (bool success); function transferFrom(address _from, address _to, uint256 _value) external returns (bool success); function approve(address _spender, uint256 _value) external returns (bool success); function allowance(address _owner, address _spender) external view returns (uint256 remaining); function decimals() external view returns (uint256 digits); event Approval(address indexed _owner, address indexed _spender, uint256 _value); } library Address { function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(ERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(ERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. */ function safeApprove(ERC20 token, address spender, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(ERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(ERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function _callOptionalReturn(ERC20 token, bytes memory data) private { bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } contract AdminAuth { using SafeERC20 for ERC20; address public owner; address public admin; modifier onlyOwner() { require(owner == msg.sender); _; } modifier onlyAdmin() { require(admin == msg.sender); _; } constructor() public { owner = 0xBc841B0dE0b93205e912CFBBd1D0c160A1ec6F00; admin = 0x25eFA336886C74eA8E282ac466BdCd0199f85BB9; } /// @notice Admin is set by owner first time, after that admin is super role and has permission to change owner /// @param _admin Address of multisig that becomes admin function setAdminByOwner(address _admin) public { require(msg.sender == owner); require(admin == address(0)); admin = _admin; } /// @notice Admin is able to set new admin /// @param _admin Address of multisig that becomes new admin function setAdminByAdmin(address _admin) public { require(msg.sender == admin); admin = _admin; } /// @notice Admin is able to change owner /// @param _owner Address of new owner function setOwnerByAdmin(address _owner) public { require(msg.sender == admin); owner = _owner; } /// @notice Destroy the contract function kill() public onlyOwner { selfdestruct(payable(owner)); } /// @notice withdraw stuck funds function withdrawStuckFunds(address _token, uint _amount) public onlyOwner { if (_token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) { payable(owner).transfer(_amount); } else { ERC20(_token).safeTransfer(owner, _amount); } } } contract BotRegistry is AdminAuth { mapping (address => bool) public botList; constructor() public { botList[0x776B4a13093e30B05781F97F6A4565B6aa8BE330] = true; botList[0xAED662abcC4FA3314985E67Ea993CAD064a7F5cF] = true; botList[0xa5d330F6619d6bF892A5B87D80272e1607b3e34D] = true; botList[0x5feB4DeE5150B589a7f567EA7CADa2759794A90A] = true; botList[0x7ca06417c1d6f480d3bB195B80692F95A6B66158] = true; } function setBot(address _botAddr, bool _state) public onlyOwner { botList[_botAddr] = _state; } } abstract contract TokenInterface { address public constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; function allowance(address, address) public virtual returns (uint256); function balanceOf(address) public virtual returns (uint256); function approve(address, uint256) public virtual; function transfer(address, uint256) public virtual returns (bool); function transferFrom(address, address, uint256) public virtual returns (bool); function deposit() public virtual payable; function withdraw(uint256) public virtual; } interface ExchangeInterfaceV3 { function sell(address _srcAddr, address _destAddr, uint _srcAmount, bytes memory _additionalData) external payable returns (uint); function buy(address _srcAddr, address _destAddr, uint _destAmount, bytes memory _additionalData) external payable returns(uint); function getSellRate(address _srcAddr, address _destAddr, uint _srcAmount, bytes memory _additionalData) external view returns (uint); function getBuyRate(address _srcAddr, address _destAddr, uint _srcAmount, bytes memory _additionalData) external view returns (uint); } contract ZrxAllowlist is AdminAuth { mapping (address => bool) public zrxAllowlist; mapping(address => bool) private nonPayableAddrs; constructor() public { zrxAllowlist[0x6958F5e95332D93D21af0D7B9Ca85B8212fEE0A5] = true; zrxAllowlist[0x61935CbDd02287B511119DDb11Aeb42F1593b7Ef] = true; zrxAllowlist[0xDef1C0ded9bec7F1a1670819833240f027b25EfF] = true; zrxAllowlist[0x080bf510FCbF18b91105470639e9561022937712] = true; nonPayableAddrs[0x080bf510FCbF18b91105470639e9561022937712] = true; } function setAllowlistAddr(address _zrxAddr, bool _state) public onlyOwner { zrxAllowlist[_zrxAddr] = _state; } function isZrxAddr(address _zrxAddr) public view returns (bool) { return zrxAllowlist[_zrxAddr]; } function addNonPayableAddr(address _nonPayableAddr) public onlyOwner { nonPayableAddrs[_nonPayableAddr] = true; } function removeNonPayableAddr(address _nonPayableAddr) public onlyOwner { nonPayableAddrs[_nonPayableAddr] = false; } function isNonPayableAddr(address _addr) public view returns(bool) { return nonPayableAddrs[_addr]; } } contract DFSExchangeData { // first is empty to keep the legacy order in place enum ExchangeType { _, OASIS, KYBER, UNISWAP, ZEROX } enum ActionType { SELL, BUY } struct OffchainData { address wrapper; address exchangeAddr; address allowanceTarget; uint256 price; uint256 protocolFee; bytes callData; } struct ExchangeData { address srcAddr; address destAddr; uint256 srcAmount; uint256 destAmount; uint256 minPrice; uint256 dfsFeeDivider; // service fee divider address user; // user to check special fee address wrapper; bytes wrapperData; OffchainData offchainData; } function packExchangeData(ExchangeData memory _exData) public pure returns(bytes memory) { return abi.encode(_exData); } function unpackExchangeData(bytes memory _data) public pure returns(ExchangeData memory _exData) { _exData = abi.decode(_data, (ExchangeData)); } } abstract contract IFeeRecipient { function getFeeAddr() public view virtual returns (address); function changeWalletAddr(address _newWallet) public virtual; } contract DFSExchangeHelper { string public constant ERR_OFFCHAIN_DATA_INVALID = "Offchain data invalid"; using SafeERC20 for ERC20; address public constant KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address public constant EXCHANGE_WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; IFeeRecipient public constant _feeRecipient = IFeeRecipient(0x39C4a92Dc506300c3Ea4c67ca4CA611102ee6F2A); address public constant DISCOUNT_ADDRESS = 0x1b14E8D511c9A4395425314f849bD737BAF8208F; address public constant SAVER_EXCHANGE_REGISTRY = 0x25dd3F51e0C3c3Ff164DDC02A8E4D65Bb9cBB12D; address public constant ZRX_ALLOWLIST_ADDR = 0x4BA1f38427b33B8ab7Bb0490200dAE1F1C36823F; function getDecimals(address _token) internal view returns (uint256) { if (_token == KYBER_ETH_ADDRESS) return 18; return ERC20(_token).decimals(); } function getBalance(address _tokenAddr) internal view returns (uint balance) { if (_tokenAddr == KYBER_ETH_ADDRESS) { balance = address(this).balance; } else { balance = ERC20(_tokenAddr).balanceOf(address(this)); } } function sendLeftover(address _srcAddr, address _destAddr, address payable _to) internal { // send back any leftover ether or tokens if (address(this).balance > 0) { _to.transfer(address(this).balance); } if (getBalance(_srcAddr) > 0) { ERC20(_srcAddr).safeTransfer(_to, getBalance(_srcAddr)); } if (getBalance(_destAddr) > 0) { ERC20(_destAddr).safeTransfer(_to, getBalance(_destAddr)); } } /// @notice Takes a feePercentage and sends it to wallet /// @param _amount Dai amount of the whole trade /// @param _user Address of the user /// @param _token Address of the token /// @param _dfsFeeDivider Dfs fee divider /// @return feeAmount Amount in Dai owner earned on the fee function getFee(uint256 _amount, address _user, address _token, uint256 _dfsFeeDivider) internal returns (uint256 feeAmount) { if (_dfsFeeDivider != 0 && Discount(DISCOUNT_ADDRESS).isCustomFeeSet(_user)) { _dfsFeeDivider = Discount(DISCOUNT_ADDRESS).getCustomServiceFee(_user); } if (_dfsFeeDivider == 0) { feeAmount = 0; } else { feeAmount = _amount / _dfsFeeDivider; // fee can't go over 10% of the whole amount if (feeAmount > (_amount / 10)) { feeAmount = _amount / 10; } address walletAddr = _feeRecipient.getFeeAddr(); if (_token == KYBER_ETH_ADDRESS) { payable(walletAddr).transfer(feeAmount); } else { ERC20(_token).safeTransfer(walletAddr, feeAmount); } } } function sliceUint(bytes memory bs, uint256 start) internal pure returns (uint256) { require(bs.length >= start + 32, "slicing out of range"); uint256 x; assembly { x := mload(add(bs, add(0x20, start))) } return x; } function writeUint256(bytes memory _b, uint256 _index, uint _input) internal pure { if (_b.length < _index + 32) { revert(ERR_OFFCHAIN_DATA_INVALID); } bytes32 input = bytes32(_input); _index += 32; // Read the bytes32 from array memory assembly { mstore(add(_b, _index), input) } } /// @notice Converts Kybers Eth address -> Weth /// @param _src Input address function ethToWethAddr(address _src) internal pure returns (address) { return _src == KYBER_ETH_ADDRESS ? EXCHANGE_WETH_ADDRESS : _src; } } contract SaverExchangeRegistry is AdminAuth { mapping(address => bool) private wrappers; constructor() public { wrappers[0x880A845A85F843a5c67DB2061623c6Fc3bB4c511] = true; wrappers[0x4c9B55f2083629A1F7aDa257ae984E03096eCD25] = true; wrappers[0x42A9237b872368E1bec4Ca8D26A928D7d39d338C] = true; } function addWrapper(address _wrapper) public onlyOwner { wrappers[_wrapper] = true; } function removeWrapper(address _wrapper) public onlyOwner { wrappers[_wrapper] = false; } function isWrapper(address _wrapper) public view returns(bool) { return wrappers[_wrapper]; } } abstract contract OffchainWrapperInterface is DFSExchangeData { function takeOrder( ExchangeData memory _exData, ActionType _type ) virtual public payable returns (bool success, uint256); } contract DFSExchangeCore is DFSExchangeHelper, DSMath, DFSExchangeData { string public constant ERR_SLIPPAGE_HIT = "Slippage hit"; string public constant ERR_DEST_AMOUNT_MISSING = "Dest amount missing"; string public constant ERR_WRAPPER_INVALID = "Wrapper invalid"; string public constant ERR_NOT_ZEROX_EXCHANGE = "Zerox exchange invalid"; /// @notice Internal method that preforms a sell on 0x/on-chain /// @dev Usefull for other DFS contract to integrate for exchanging /// @param exData Exchange data struct /// @return (address, uint) Address of the wrapper used and destAmount function _sell(ExchangeData memory exData) internal returns (address, uint) { address wrapper; uint swapedTokens; bool success; // if selling eth, convert to weth if (exData.srcAddr == KYBER_ETH_ADDRESS) { exData.srcAddr = ethToWethAddr(exData.srcAddr); TokenInterface(EXCHANGE_WETH_ADDRESS).deposit{value: exData.srcAmount}(); } exData.srcAmount -= getFee(exData.srcAmount, exData.user, exData.srcAddr, exData.dfsFeeDivider); // Try 0x first and then fallback on specific wrapper if (exData.offchainData.price > 0) { (success, swapedTokens) = takeOrder(exData, ActionType.SELL); if (success) { wrapper = exData.offchainData.exchangeAddr; } } // fallback to desired wrapper if 0x failed if (!success) { swapedTokens = saverSwap(exData, ActionType.SELL); wrapper = exData.wrapper; } // if anything is left in weth, pull it to user as eth if (getBalance(EXCHANGE_WETH_ADDRESS) > 0) { TokenInterface(EXCHANGE_WETH_ADDRESS).withdraw( TokenInterface(EXCHANGE_WETH_ADDRESS).balanceOf(address(this)) ); } if (exData.destAddr == EXCHANGE_WETH_ADDRESS) { require(getBalance(KYBER_ETH_ADDRESS) >= wmul(exData.minPrice, exData.srcAmount), ERR_SLIPPAGE_HIT); } else { require(getBalance(exData.destAddr) >= wmul(exData.minPrice, exData.srcAmount), ERR_SLIPPAGE_HIT); } return (wrapper, swapedTokens); } /// @notice Internal method that preforms a buy on 0x/on-chain /// @dev Usefull for other DFS contract to integrate for exchanging /// @param exData Exchange data struct /// @return (address, uint) Address of the wrapper used and srcAmount function _buy(ExchangeData memory exData) internal returns (address, uint) { address wrapper; uint swapedTokens; bool success; require(exData.destAmount != 0, ERR_DEST_AMOUNT_MISSING); exData.srcAmount -= getFee(exData.srcAmount, exData.user, exData.srcAddr, exData.dfsFeeDivider); // if selling eth, convert to weth if (exData.srcAddr == KYBER_ETH_ADDRESS) { exData.srcAddr = ethToWethAddr(exData.srcAddr); TokenInterface(EXCHANGE_WETH_ADDRESS).deposit{value: exData.srcAmount}(); } if (exData.offchainData.price > 0) { (success, swapedTokens) = takeOrder(exData, ActionType.BUY); if (success) { wrapper = exData.offchainData.exchangeAddr; } } // fallback to desired wrapper if 0x failed if (!success) { swapedTokens = saverSwap(exData, ActionType.BUY); wrapper = exData.wrapper; } // if anything is left in weth, pull it to user as eth if (getBalance(EXCHANGE_WETH_ADDRESS) > 0) { TokenInterface(EXCHANGE_WETH_ADDRESS).withdraw( TokenInterface(EXCHANGE_WETH_ADDRESS).balanceOf(address(this)) ); } if (exData.destAddr == EXCHANGE_WETH_ADDRESS) { require(getBalance(KYBER_ETH_ADDRESS) >= exData.destAmount, ERR_SLIPPAGE_HIT); } else { require(getBalance(exData.destAddr) >= exData.destAmount, ERR_SLIPPAGE_HIT); } return (wrapper, getBalance(exData.destAddr)); } /// @notice Takes order from 0x and returns bool indicating if it is successful /// @param _exData Exchange data function takeOrder( ExchangeData memory _exData, ActionType _type ) private returns (bool success, uint256) { if (!ZrxAllowlist(ZRX_ALLOWLIST_ADDR).isZrxAddr(_exData.offchainData.exchangeAddr)) { return (false, 0); } if (!SaverExchangeRegistry(SAVER_EXCHANGE_REGISTRY).isWrapper(_exData.offchainData.wrapper)) { return (false, 0); } // send src amount ERC20(_exData.srcAddr).safeTransfer(_exData.offchainData.wrapper, _exData.srcAmount); return OffchainWrapperInterface(_exData.offchainData.wrapper).takeOrder{value: _exData.offchainData.protocolFee}(_exData, _type); } /// @notice Calls wraper contract for exchage to preform an on-chain swap /// @param _exData Exchange data struct /// @param _type Type of action SELL|BUY /// @return swapedTokens For Sell that the destAmount, for Buy thats the srcAmount function saverSwap(ExchangeData memory _exData, ActionType _type) internal returns (uint swapedTokens) { require(SaverExchangeRegistry(SAVER_EXCHANGE_REGISTRY).isWrapper(_exData.wrapper), ERR_WRAPPER_INVALID); ERC20(_exData.srcAddr).safeTransfer(_exData.wrapper, _exData.srcAmount); if (_type == ActionType.SELL) { swapedTokens = ExchangeInterfaceV3(_exData.wrapper). sell(_exData.srcAddr, _exData.destAddr, _exData.srcAmount, _exData.wrapperData); } else { swapedTokens = ExchangeInterfaceV3(_exData.wrapper). buy(_exData.srcAddr, _exData.destAddr, _exData.destAmount, _exData.wrapperData); } } // solhint-disable-next-line no-empty-blocks receive() external virtual payable {} } /// @title Implements Boost and Repay for MCD CDPs contract MCDSaverProxy is DFSExchangeCore, MCDSaverProxyHelper { uint public constant MANUAL_SERVICE_FEE = 400; // 0.25% Fee uint public constant AUTOMATIC_SERVICE_FEE = 333; // 0.3% Fee bytes32 public constant ETH_ILK = 0x4554482d41000000000000000000000000000000000000000000000000000000; address public constant VAT_ADDRESS = 0x35D1b3F3D7966A1DFe207aa4514C12a259A0492B; address public constant SPOTTER_ADDRESS = 0x65C79fcB50Ca1594B025960e539eD7A9a6D434A3; address public constant DAI_JOIN_ADDRESS = 0x9759A6Ac90977b93B58547b4A71c78317f391A28; address public constant JUG_ADDRESS = 0x19c0976f590D67707E62397C87829d896Dc0f1F1; address public constant DAI_ADDRESS = 0x6B175474E89094C44Da98b954EedeAC495271d0F; address public constant BOT_REGISTRY_ADDRESS = 0x637726f8b08a7ABE3aE3aCaB01A80E2d8ddeF77B; Vat public constant vat = Vat(VAT_ADDRESS); DaiJoin public constant daiJoin = DaiJoin(DAI_JOIN_ADDRESS); Spotter public constant spotter = Spotter(SPOTTER_ADDRESS); DefisaverLogger public constant logger = DefisaverLogger(0x5c55B921f590a89C1Ebe84dF170E655a82b62126); /// @notice Repay - draws collateral, converts to Dai and repays the debt /// @dev Must be called by the DSProxy contract that owns the CDP function repay( ExchangeData memory _exchangeData, uint _cdpId, uint _gasCost, address _joinAddr, ManagerType _managerType ) public payable { address managerAddr = getManagerAddr(_managerType); address user = getOwner(Manager(managerAddr), _cdpId); bytes32 ilk = Manager(managerAddr).ilks(_cdpId); drawCollateral(managerAddr, _cdpId, _joinAddr, _exchangeData.srcAmount); _exchangeData.user = user; _exchangeData.dfsFeeDivider = isAutomation() ? AUTOMATIC_SERVICE_FEE : MANUAL_SERVICE_FEE; (, uint daiAmount) = _sell(_exchangeData); daiAmount -= takeFee(_gasCost, daiAmount); paybackDebt(managerAddr, _cdpId, ilk, daiAmount, user); // if there is some eth left (0x fee), return it to user if (address(this).balance > 0) { tx.origin.transfer(address(this).balance); } logger.Log(address(this), msg.sender, "MCDRepay", abi.encode(_cdpId, user, _exchangeData.srcAmount, daiAmount)); } /// @notice Boost - draws Dai, converts to collateral and adds to CDP /// @dev Must be called by the DSProxy contract that owns the CDP function boost( ExchangeData memory _exchangeData, uint _cdpId, uint _gasCost, address _joinAddr, ManagerType _managerType ) public payable { address managerAddr = getManagerAddr(_managerType); address user = getOwner(Manager(managerAddr), _cdpId); bytes32 ilk = Manager(managerAddr).ilks(_cdpId); uint daiDrawn = drawDai(managerAddr, _cdpId, ilk, _exchangeData.srcAmount); _exchangeData.user = user; _exchangeData.dfsFeeDivider = isAutomation() ? AUTOMATIC_SERVICE_FEE : MANUAL_SERVICE_FEE; _exchangeData.srcAmount = daiDrawn - takeFee(_gasCost, daiDrawn); (, uint swapedColl) = _sell(_exchangeData); addCollateral(managerAddr, _cdpId, _joinAddr, swapedColl); // if there is some eth left (0x fee), return it to user if (address(this).balance > 0) { tx.origin.transfer(address(this).balance); } logger.Log(address(this), msg.sender, "MCDBoost", abi.encode(_cdpId, user, _exchangeData.srcAmount, swapedColl)); } /// @notice Draws Dai from the CDP /// @dev If _daiAmount is bigger than max available we'll draw max /// @param _managerAddr Address of the CDP Manager /// @param _cdpId Id of the CDP /// @param _ilk Ilk of the CDP /// @param _daiAmount Amount of Dai to draw function drawDai(address _managerAddr, uint _cdpId, bytes32 _ilk, uint _daiAmount) internal returns (uint) { uint rate = Jug(JUG_ADDRESS).drip(_ilk); uint daiVatBalance = vat.dai(Manager(_managerAddr).urns(_cdpId)); uint maxAmount = getMaxDebt(_managerAddr, _cdpId, _ilk); if (_daiAmount >= maxAmount) { _daiAmount = sub(maxAmount, 1); } Manager(_managerAddr).frob(_cdpId, int(0), normalizeDrawAmount(_daiAmount, rate, daiVatBalance)); Manager(_managerAddr).move(_cdpId, address(this), toRad(_daiAmount)); if (vat.can(address(this), address(DAI_JOIN_ADDRESS)) == 0) { vat.hope(DAI_JOIN_ADDRESS); } DaiJoin(DAI_JOIN_ADDRESS).exit(address(this), _daiAmount); return _daiAmount; } /// @notice Adds collateral to the CDP /// @param _managerAddr Address of the CDP Manager /// @param _cdpId Id of the CDP /// @param _joinAddr Address of the join contract for the CDP collateral /// @param _amount Amount of collateral to add function addCollateral(address _managerAddr, uint _cdpId, address _joinAddr, uint _amount) internal { int convertAmount = 0; if (isEthJoinAddr(_joinAddr)) { Join(_joinAddr).gem().deposit{value: _amount}(); convertAmount = toPositiveInt(_amount); } else { convertAmount = toPositiveInt(convertTo18(_joinAddr, _amount)); } ERC20(address(Join(_joinAddr).gem())).safeApprove(_joinAddr, _amount); Join(_joinAddr).join(address(this), _amount); vat.frob( Manager(_managerAddr).ilks(_cdpId), Manager(_managerAddr).urns(_cdpId), address(this), address(this), convertAmount, 0 ); } /// @notice Draws collateral and returns it to DSProxy /// @param _managerAddr Address of the CDP Manager /// @dev If _amount is bigger than max available we'll draw max /// @param _cdpId Id of the CDP /// @param _joinAddr Address of the join contract for the CDP collateral /// @param _amount Amount of collateral to draw function drawCollateral(address _managerAddr, uint _cdpId, address _joinAddr, uint _amount) internal returns (uint) { uint frobAmount = _amount; if (Join(_joinAddr).dec() != 18) { frobAmount = _amount * (10 ** (18 - Join(_joinAddr).dec())); } Manager(_managerAddr).frob(_cdpId, -toPositiveInt(frobAmount), 0); Manager(_managerAddr).flux(_cdpId, address(this), frobAmount); Join(_joinAddr).exit(address(this), _amount); if (isEthJoinAddr(_joinAddr)) { Join(_joinAddr).gem().withdraw(_amount); // Weth -> Eth } return _amount; } /// @notice Paybacks Dai debt /// @param _managerAddr Address of the CDP Manager /// @dev If the _daiAmount is bigger than the whole debt, returns extra Dai /// @param _cdpId Id of the CDP /// @param _ilk Ilk of the CDP /// @param _daiAmount Amount of Dai to payback /// @param _owner Address that owns the DSProxy that owns the CDP function paybackDebt(address _managerAddr, uint _cdpId, bytes32 _ilk, uint _daiAmount, address _owner) internal { address urn = Manager(_managerAddr).urns(_cdpId); uint wholeDebt = getAllDebt(VAT_ADDRESS, urn, urn, _ilk); if (_daiAmount > wholeDebt) { ERC20(DAI_ADDRESS).transfer(_owner, sub(_daiAmount, wholeDebt)); _daiAmount = wholeDebt; } if (ERC20(DAI_ADDRESS).allowance(address(this), DAI_JOIN_ADDRESS) == 0) { ERC20(DAI_ADDRESS).approve(DAI_JOIN_ADDRESS, uint(-1)); } daiJoin.join(urn, _daiAmount); Manager(_managerAddr).frob(_cdpId, 0, normalizePaybackAmount(VAT_ADDRESS, urn, _ilk)); } /// @notice Gets the maximum amount of collateral available to draw /// @param _managerAddr Address of the CDP Manager /// @param _cdpId Id of the CDP /// @param _ilk Ilk of the CDP /// @param _joinAddr Joind address of collateral /// @dev Substracts 10 wei to aviod rounding error later on function getMaxCollateral(address _managerAddr, uint _cdpId, bytes32 _ilk, address _joinAddr) public view returns (uint) { uint price = getPrice(_ilk); (uint collateral, uint debt) = getCdpInfo(Manager(_managerAddr), _cdpId, _ilk); (, uint mat) = Spotter(SPOTTER_ADDRESS).ilks(_ilk); uint maxCollateral = sub(collateral, (div(mul(mat, debt), price))); uint normalizeMaxCollateral = maxCollateral / (10 ** (18 - Join(_joinAddr).dec())); // take one percent due to precision issues return normalizeMaxCollateral * 99 / 100; } /// @notice Gets the maximum amount of debt available to generate /// @param _managerAddr Address of the CDP Manager /// @param _cdpId Id of the CDP /// @param _ilk Ilk of the CDP /// @dev Substracts 10 wei to aviod rounding error later on function getMaxDebt(address _managerAddr, uint _cdpId, bytes32 _ilk) public virtual view returns (uint) { uint price = getPrice(_ilk); (, uint mat) = spotter.ilks(_ilk); (uint collateral, uint debt) = getCdpInfo(Manager(_managerAddr), _cdpId, _ilk); return sub(sub(div(mul(collateral, price), mat), debt), 10); } /// @notice Gets a price of the asset /// @param _ilk Ilk of the CDP function getPrice(bytes32 _ilk) public view returns (uint) { (, uint mat) = spotter.ilks(_ilk); (,,uint spot,,) = vat.ilks(_ilk); return rmul(rmul(spot, spotter.par()), mat); } function isAutomation() internal view returns(bool) { return BotRegistry(BOT_REGISTRY_ADDRESS).botList(tx.origin); } function takeFee(uint256 _gasCost, uint _amount) internal returns(uint) { if (_gasCost > 0) { uint ethDaiPrice = getPrice(ETH_ILK); uint feeAmount = rmul(_gasCost, ethDaiPrice); if (feeAmount > _amount / 5) { feeAmount = _amount / 5; } address walletAddr = _feeRecipient.getFeeAddr(); ERC20(DAI_ADDRESS).transfer(walletAddr, feeAmount); return feeAmount; } return 0; } } interface IFlashLoanReceiver { function executeOperation(address _reserve, uint256 _amount, uint256 _fee, bytes calldata _params) external; } abstract contract ILendingPoolAddressesProvider { function getLendingPool() public view virtual returns (address); function setLendingPoolImpl(address _pool) public virtual; function getLendingPoolCore() public virtual view returns (address payable); function setLendingPoolCoreImpl(address _lendingPoolCore) public virtual; function getLendingPoolConfigurator() public virtual view returns (address); function setLendingPoolConfiguratorImpl(address _configurator) public virtual; function getLendingPoolDataProvider() public virtual view returns (address); function setLendingPoolDataProviderImpl(address _provider) public virtual; function getLendingPoolParametersProvider() public virtual view returns (address); function setLendingPoolParametersProviderImpl(address _parametersProvider) public virtual; function getTokenDistributor() public virtual view returns (address); function setTokenDistributor(address _tokenDistributor) public virtual; function getFeeProvider() public virtual view returns (address); function setFeeProviderImpl(address _feeProvider) public virtual; function getLendingPoolLiquidationManager() public virtual view returns (address); function setLendingPoolLiquidationManager(address _manager) public virtual; function getLendingPoolManager() public virtual view returns (address); function setLendingPoolManager(address _lendingPoolManager) public virtual; function getPriceOracle() public virtual view returns (address); function setPriceOracle(address _priceOracle) public virtual; function getLendingRateOracle() public view virtual returns (address); function setLendingRateOracle(address _lendingRateOracle) public virtual; } library EthAddressLib { function ethAddress() internal pure returns(address) { return 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; } } abstract contract FlashLoanReceiverBase is IFlashLoanReceiver { using SafeERC20 for ERC20; using SafeMath for uint256; ILendingPoolAddressesProvider public addressesProvider; constructor(ILendingPoolAddressesProvider _provider) public { addressesProvider = _provider; } receive () external virtual payable {} function transferFundsBackToPoolInternal(address _reserve, uint256 _amount) internal { address payable core = addressesProvider.getLendingPoolCore(); transferInternal(core,_reserve, _amount); } function transferInternal(address payable _destination, address _reserve, uint256 _amount) internal { if(_reserve == EthAddressLib.ethAddress()) { //solium-disable-next-line _destination.call{value: _amount}(""); return; } ERC20(_reserve).safeTransfer(_destination, _amount); } function getBalanceInternal(address _target, address _reserve) internal view returns(uint256) { if(_reserve == EthAddressLib.ethAddress()) { return _target.balance; } return ERC20(_reserve).balanceOf(_target); } } /// @title Receiver of Dydx flash loan and performs the fl repay/boost logic /// @notice Must have a dust amount of WETH on the contract for 2 wei dydx fee contract MCDSaverFlashLoan is MCDSaverProxy, AdminAuth, FlashLoanReceiverBase { ILendingPoolAddressesProvider public LENDING_POOL_ADDRESS_PROVIDER = ILendingPoolAddressesProvider(0x24a42fD28C976A61Df5D00D0599C34c4f90748c8); constructor() FlashLoanReceiverBase(LENDING_POOL_ADDRESS_PROVIDER) public {} struct SaverData { uint cdpId; uint gasCost; uint loanAmount; uint fee; address joinAddr; ManagerType managerType; } function executeOperation( address _reserve, uint256 _amount, uint256 _fee, bytes calldata _params) external override { ( bytes memory exDataBytes, uint cdpId, uint gasCost, address joinAddr, bool isRepay, uint8 managerType ) = abi.decode(_params, (bytes,uint256,uint256,address,bool,uint8)); ExchangeData memory exchangeData = unpackExchangeData(exDataBytes); SaverData memory saverData = SaverData({ cdpId: cdpId, gasCost: gasCost, loanAmount: _amount, fee: _fee, joinAddr: joinAddr, managerType: ManagerType(managerType) }); if (isRepay) { repayWithLoan(exchangeData, saverData); } else { boostWithLoan(exchangeData, saverData); } transferFundsBackToPoolInternal(_reserve, _amount.add(_fee)); // if there is some eth left (0x fee), return it to user if (address(this).balance > 0) { tx.origin.transfer(address(this).balance); } } function boostWithLoan( ExchangeData memory _exchangeData, SaverData memory _saverData ) internal { address managerAddr = getManagerAddr(_saverData.managerType); address user = getOwner(Manager(managerAddr), _saverData.cdpId); // Draw users Dai uint maxDebt = getMaxDebt(managerAddr, _saverData.cdpId, Manager(managerAddr).ilks(_saverData.cdpId)); uint daiDrawn = drawDai(managerAddr, _saverData.cdpId, Manager(managerAddr).ilks(_saverData.cdpId), maxDebt); // Swap _exchangeData.srcAmount = daiDrawn + _saverData.loanAmount - takeFee(_saverData.gasCost, daiDrawn + _saverData.loanAmount); _exchangeData.user = user; _exchangeData.dfsFeeDivider = isAutomation() ? AUTOMATIC_SERVICE_FEE : MANUAL_SERVICE_FEE; (, uint swapedAmount) = _sell(_exchangeData); // Return collateral addCollateral(managerAddr, _saverData.cdpId, _saverData.joinAddr, swapedAmount); // Draw Dai to repay the flash loan drawDai(managerAddr, _saverData.cdpId, Manager(managerAddr).ilks(_saverData.cdpId), (_saverData.loanAmount + _saverData.fee)); logger.Log(address(this), msg.sender, "MCDFlashBoost", abi.encode(_saverData.cdpId, user, _exchangeData.srcAmount, swapedAmount)); } function repayWithLoan( ExchangeData memory _exchangeData, SaverData memory _saverData ) internal { address managerAddr = getManagerAddr(_saverData.managerType); address user = getOwner(Manager(managerAddr), _saverData.cdpId); bytes32 ilk = Manager(managerAddr).ilks(_saverData.cdpId); // Draw collateral uint maxColl = getMaxCollateral(managerAddr, _saverData.cdpId, ilk, _saverData.joinAddr); uint collDrawn = drawCollateral(managerAddr, _saverData.cdpId, _saverData.joinAddr, maxColl); // Swap _exchangeData.srcAmount = (_saverData.loanAmount + collDrawn); _exchangeData.user = user; _exchangeData.dfsFeeDivider = isAutomation() ? AUTOMATIC_SERVICE_FEE : MANUAL_SERVICE_FEE; (, uint paybackAmount) = _sell(_exchangeData); paybackAmount -= takeFee(_saverData.gasCost, paybackAmount); // Payback the debt paybackDebt(managerAddr, _saverData.cdpId, ilk, paybackAmount, user); // Draw collateral to repay the flash loan drawCollateral(managerAddr, _saverData.cdpId, _saverData.joinAddr, (_saverData.loanAmount + _saverData.fee)); logger.Log(address(this), msg.sender, "MCDFlashRepay", abi.encode(_saverData.cdpId, user, _exchangeData.srcAmount, paybackAmount)); } receive() external override(FlashLoanReceiverBase, DFSExchangeCore) payable {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AUTOMATIC_SERVICE_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BOT_REGISTRY_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAI_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAI_JOIN_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DISCOUNT_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_DEST_AMOUNT_MISSING","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_NOT_ZEROX_EXCHANGE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_OFFCHAIN_DATA_INVALID","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_SLIPPAGE_HIT","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_WRAPPER_INVALID","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_ILK","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXCHANGE_WETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"JUG_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"KYBER_ETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LENDING_POOL_ADDRESS_PROVIDER","outputs":[{"internalType":"contract ILendingPoolAddressesProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANUAL_SERVICE_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SAVER_EXCHANGE_REGISTRY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SPOTTER_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VAT_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ZRX_ALLOWLIST_ADDR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_feeRecipient","outputs":[{"internalType":"contract IFeeRecipient","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"addressesProvider","outputs":[{"internalType":"contract ILendingPoolAddressesProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"srcAddr","type":"address"},{"internalType":"address","name":"destAddr","type":"address"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"dfsFeeDivider","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"bytes","name":"wrapperData","type":"bytes"},{"components":[{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"address","name":"exchangeAddr","type":"address"},{"internalType":"address","name":"allowanceTarget","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct DFSExchangeData.OffchainData","name":"offchainData","type":"tuple"}],"internalType":"struct DFSExchangeData.ExchangeData","name":"_exchangeData","type":"tuple"},{"internalType":"uint256","name":"_cdpId","type":"uint256"},{"internalType":"uint256","name":"_gasCost","type":"uint256"},{"internalType":"address","name":"_joinAddr","type":"address"},{"internalType":"enum MCDSaverProxyHelper.ManagerType","name":"_managerType","type":"uint8"}],"name":"boost","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"daiJoin","outputs":[{"internalType":"contract DaiJoin","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"bytes","name":"_params","type":"bytes"}],"name":"executeOperation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Manager","name":"_manager","type":"address"},{"internalType":"uint256","name":"_cdpId","type":"uint256"},{"internalType":"bytes32","name":"_ilk","type":"bytes32"}],"name":"getCdpInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum MCDSaverProxyHelper.ManagerType","name":"_managerType","type":"uint8"}],"name":"getManagerAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_managerAddr","type":"address"},{"internalType":"uint256","name":"_cdpId","type":"uint256"},{"internalType":"bytes32","name":"_ilk","type":"bytes32"},{"internalType":"address","name":"_joinAddr","type":"address"}],"name":"getMaxCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_managerAddr","type":"address"},{"internalType":"uint256","name":"_cdpId","type":"uint256"},{"internalType":"bytes32","name":"_ilk","type":"bytes32"}],"name":"getMaxDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract Manager","name":"_manager","type":"address"},{"internalType":"uint256","name":"_cdpId","type":"uint256"}],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_ilk","type":"bytes32"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kill","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"logger","outputs":[{"internalType":"contract DefisaverLogger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"srcAddr","type":"address"},{"internalType":"address","name":"destAddr","type":"address"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"dfsFeeDivider","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"bytes","name":"wrapperData","type":"bytes"},{"components":[{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"address","name":"exchangeAddr","type":"address"},{"internalType":"address","name":"allowanceTarget","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct DFSExchangeData.OffchainData","name":"offchainData","type":"tuple"}],"internalType":"struct DFSExchangeData.ExchangeData","name":"_exData","type":"tuple"}],"name":"packExchangeData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"srcAddr","type":"address"},{"internalType":"address","name":"destAddr","type":"address"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"dfsFeeDivider","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"bytes","name":"wrapperData","type":"bytes"},{"components":[{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"address","name":"exchangeAddr","type":"address"},{"internalType":"address","name":"allowanceTarget","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct DFSExchangeData.OffchainData","name":"offchainData","type":"tuple"}],"internalType":"struct DFSExchangeData.ExchangeData","name":"_exchangeData","type":"tuple"},{"internalType":"uint256","name":"_cdpId","type":"uint256"},{"internalType":"uint256","name":"_gasCost","type":"uint256"},{"internalType":"address","name":"_joinAddr","type":"address"},{"internalType":"enum MCDSaverProxyHelper.ManagerType","name":"_managerType","type":"uint8"}],"name":"repay","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setAdminByAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setAdminByOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwnerByAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"spotter","outputs":[{"internalType":"contract Spotter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"unpackExchangeData","outputs":[{"components":[{"internalType":"address","name":"srcAddr","type":"address"},{"internalType":"address","name":"destAddr","type":"address"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"dfsFeeDivider","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"bytes","name":"wrapperData","type":"bytes"},{"components":[{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"address","name":"exchangeAddr","type":"address"},{"internalType":"address","name":"allowanceTarget","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct DFSExchangeData.OffchainData","name":"offchainData","type":"tuple"}],"internalType":"struct DFSExchangeData.ExchangeData","name":"_exData","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"vat","outputs":[{"internalType":"contract Vat","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawStuckFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6080604052600380546001600160a01b0319167324a42fd28c976a61df5d00d0599c34c4f90748c817905534801561003657600080fd5b50600354600080546001600160a01b031990811673bc841b0de0b93205e912cfbbd1d0c160a1ec6f00179091556001805482167325efa336886c74ea8e282ac466bdcd0199f85bb9179055600280549091166001600160a01b03909216919091179055614f60806100a86000396000f3fe60806040526004361061026b5760003560e01c80638c8a795811610144578063c72c4d10116100b6578063dd6d903c1161007a578063dd6d903c1461060f578063deca5f881461062f578063e870b9cd1461064f578063ee87255814610662578063f24ccbfe14610682578063f851a4401461069757610272565b8063c72c4d10146105d2578063c7975824146105e7578063cc694d48146105fa578063cf786f8f146103bc578063cfac57c7146105a857610272565b8063a46a66c911610108578063a46a66c914610549578063a7304bf71461055e578063acbeba611461057e578063ae08fd1014610593578063c11645bc146105a8578063c50ebaf8146105bd57610272565b80638c8a7958146104c85780638da5cb5b146104dd57806398ab3d49146104f2578063a342f23814610507578063a3b8e5d11461051c57610272565b806336569e77116101dd5780634d2ab9dc116101a15780634d2ab9dc146104495780634d93667e1461045e578063526d64611461047e5780636738929f1461035257806381b94280146104935780638aa0fd0e146104a857610272565b806336569e77146103bc5780633a128322146103d15780634115fe6b146103f157806341c0e1b51461041f578063449b9ffa1461043457610272565b806329f7fc9e1161022f57806329f7fc9e1461031b5780632a4c0a1a1461033d5780632e77468d146103525780632f634a9014610367578063314b63321461038757806331d98b3f1461039c57610272565b806304c9805c1461027757806308d4f52a146102a2578063186cab76146102cf5780631e48907b146102e4578063278d58311461030657610272565b3661027257005b600080fd5b34801561028357600080fd5b5061028c6106ac565b6040516102999190614c9d565b60405180910390f35b3480156102ae57600080fd5b506102c26102bd366004614758565b6106b2565b6040516102999190614cf2565b3480156102db57600080fd5b5061028c6106dc565b3480156102f057600080fd5b506103046102ff366004614465565b6106e8565b005b34801561031257600080fd5b506102c2610721565b34801561032757600080fd5b50610330610749565b6040516102999190614ac4565b34801561034957600080fd5b50610330610761565b34801561035e57600080fd5b50610330610779565b34801561037357600080fd5b5061033061038236600461470e565b610791565b34801561039357600080fd5b5061033061088d565b3480156103a857600080fd5b5061028c6103b736600461461f565b6108a5565b3480156103c857600080fd5b50610330610a63565b3480156103dd57600080fd5b506103046103ec36600461449d565b610a7b565b3480156103fd57600080fd5b5061041161040c3660046144c8565b610b14565b604051610299929190614e7b565b34801561042b57600080fd5b50610304610d30565b34801561044057600080fd5b506102c2610d55565b34801561045557600080fd5b5061028c610d87565b34801561046a57600080fd5b5061033061047936600461473d565b610d8d565b34801561048a57600080fd5b50610330610dec565b34801561049f57600080fd5b50610330610e04565b3480156104b457600080fd5b5061028c6104c33660046144c8565b610e1c565b3480156104d457600080fd5b50610330610efd565b3480156104e957600080fd5b50610330610f15565b3480156104fe57600080fd5b50610330610f24565b34801561051357600080fd5b50610330610f33565b34801561052857600080fd5b5061053c61053736600461464f565b610f4b565b6040516102999190614de3565b34801561055557600080fd5b50610330610f67565b34801561056a57600080fd5b50610304610579366004614465565b610f7f565b34801561058a57600080fd5b50610330610fb8565b34801561059f57600080fd5b506102c2610fd0565b3480156105b457600080fd5b50610330611001565b3480156105c957600080fd5b506102c2611019565b3480156105de57600080fd5b50610330611048565b6103046105f5366004614893565b611057565b34801561060657600080fd5b506102c261123c565b34801561061b57600080fd5b5061028c61062a3660046144fc565b611267565b34801561063b57600080fd5b5061030461064a366004614465565b6113cf565b61030461065d366004614893565b6113fc565b34801561066e57600080fd5b5061030461067d366004614545565b6115d9565b34801561068e57600080fd5b506103306116c8565b3480156106a357600080fd5b506103306116e0565b61014d81565b6060816040516020016106c59190614de3565b60405160208183030381529060405290505b919050565b644554482d4160d81b81565b6001546001600160a01b031633146106ff57600080fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b81525081565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b736b175474e89094c44da98b954eedeac495271d0f81565b7365c79fcb50ca1594b025960e539ed7a9a6d434a381565b600080836001600160a01b0316638161b120846040518263ffffffff1660e01b81526004016107c09190614c9d565b60206040518083038186803b1580156107d857600080fd5b505afa1580156107ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108109190614481565b9050806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561084b57600080fd5b505afa15801561085f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108839190614481565b9150505b92915050565b7325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d81565b604051636cb1c69b60e11b815260009081907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906108e1908690600401614c9d565b604080518083038186803b1580156108f857600080fd5b505afa15801561090c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109309190614720565b604051636cb1c69b60e11b8152909250600091507335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063d9638d369061096e908790600401614c9d565b60a06040518083038186803b15801561098657600080fd5b505afa15801561099a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109be9190614929565b505092505050610a5b610a55827365c79fcb50ca1594b025960e539ed7a9a6d434a36001600160a01b031663495d32cb6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1857600080fd5b505afa158015610a2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a509190614637565b6116ef565b836116ef565b949350505050565b7335d1b3f3d7966a1dfe207aa4514c12a259a0492b81565b6000546001600160a01b03163314610a9257600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b0383161415610af657600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015610af0573d6000803e3d6000fd5b50610b10565b600054610b10906001600160a01b0384811691168361172e565b5050565b6000806000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5257600080fd5b505afa158015610b66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8a9190614481565b90506000866001600160a01b0316632726b073876040518263ffffffff1660e01b8152600401610bba9190614c9d565b60206040518083038186803b158015610bd257600080fd5b505afa158015610be6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0a9190614481565b9050600080836001600160a01b0316632424be5c88856040518363ffffffff1660e01b8152600401610c3d929190614ca6565b604080518083038186803b158015610c5457600080fd5b505afa158015610c68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8c9190614906565b915091506000846001600160a01b031663d9638d36896040518263ffffffff1660e01b8152600401610cbe9190614c9d565b60a06040518083038186803b158015610cd657600080fd5b505afa158015610cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0e9190614929565b50505091505082610d1f83836116ef565b965096505050505050935093915050565b6000546001600160a01b03163314610d4757600080fd5b6000546001600160a01b0316ff5b6040518060400160405280601681526020017516995c9bde08195e18da185b99d9481a5b9d985b1a5960521b81525081565b61019081565b600080826001811115610d9c57fe5b1415610dbd5750735ef30b9986345249bc32d8928b7ee64de9435e396106d7565b6001826001811115610dcb57fe5b14156106d75750733f30c2381cd8b917dd96eb2f1a4f96d91324bbed6106d7565b73637726f8b08a7abe3ae3acab01a80e2d8ddef77b81565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600080610e28836108a5565b604051636cb1c69b60e11b81529091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d3690610e65908790600401614c9d565b604080518083038186803b158015610e7c57600080fd5b505afa158015610e90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb49190614720565b915050600080610ec5888888610b14565b91509150610eef610ee8610ee2610edc8588611789565b866117ad565b836117b8565b600a6117b8565b9450505050505b9392505050565b734ba1f38427b33b8ab7bb0490200dae1f1c36823f81565b6000546001600160a01b031681565b6003546001600160a01b031681565b7339c4a92dc506300c3ea4c67ca4ca611102ee6f2a81565b610f53614084565b81806020019051810190610887919061478b565b731b14e8d511c9a4395425314f849bd737baf8208f81565b6001546001600160a01b03163314610f9657600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b7319c0976f590d67707e62397c87829d896dc0f1f181565b6040518060400160405280601581526020017413d99998da185a5b8819185d18481a5b9d985b1a59605a1b81525081565b739759a6ac90977b93b58547b4a71c78317f391a2881565b604051806040016040528060138152602001724465737420616d6f756e74206d697373696e6760681b81525081565b6002546001600160a01b031681565b600061106282610d8d565b905060006110708287610791565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016110a09190614c9d565b60206040518083038186803b1580156110b857600080fd5b505afa1580156110cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f09190614637565b905060006111048489848c604001516117c8565b6001600160a01b03841660c08b0152905061111d611bf8565b6111295761019061112d565b61014d5b60a08a015261113c8782611c87565b810360408a0152600061114e8a611ded565b91505061115d858a898461213d565b47156111915760405132904780156108fc02916000818181858888f1935050505015801561118f573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338c888f60400151876040516020016111d19493929190614e41565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016111fe93929190614b4c565b600060405180830381600087803b15801561121857600080fd5b505af115801561122c573d6000803e3d6000fd5b5050505050505050505050505050565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b81525081565b600080611273846108a5565b9050600080611283888888610b14565b604051636cb1c69b60e11b815291935091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906112c2908a90600401614c9d565b604080518083038186803b1580156112d957600080fd5b505afa1580156112ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113119190614720565b91505060006113328461132d6113278587611789565b886117ad565b6117b8565b90506000876001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561136f57600080fd5b505afa158015611383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a79190614637565b601203600a0a82816113b557fe5b049050606460638202049650505050505050949350505050565b6000546001600160a01b031633146113e657600080fd5b6001546001600160a01b031615610f9657600080fd5b600061140782610d8d565b905060006114158287610791565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016114459190614c9d565b60206040518083038186803b15801561145d57600080fd5b505afa158015611471573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114959190614637565b90506114a78388878b6040015161248f565b506001600160a01b03821660c08901526114bf611bf8565b6114cb576101906114cf565b61014d5b60a089015260006114df89611ded565b9150506114ec8782611c87565b90036114fb84898484876127a0565b471561152f5760405132904780156108fc02916000818181858888f1935050505015801561152d573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338b878e604001518760405160200161156f9493929190614e41565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161159c93929190614be9565b600060405180830381600087803b1580156115b657600080fd5b505af11580156115ca573d6000803e3d6000fd5b50505050505050505050505050565b60606000808080806115ed87890189614682565b955095509550955095509550611601614084565b61160a87610f4b565b9050611614614100565b6040518060c001604052808881526020018781526020018d81526020018c8152602001866001600160a01b031681526020018460ff16600181111561165557fe5b600181111561166057fe5b905290508315611679576116748282612b1f565b611683565b6116838282612d28565b6116968d6116918e8e612fdd565b613002565b47156115ca5760405132904780156108fc02916000818181858888f1935050505015801561122c573d6000803e3d6000fd5b735c55b921f590a89c1ebe84df170e655a82b6212681565b6001546001600160a01b031681565b6000676765c793fa10079d601b1b61171f61170a8585611789565b6002676765c793fa10079d601b1b5b0461308c565b8161172657fe5b049392505050565b6117848363a9059cbb60e01b848460405160240161174d929190614c35565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261309c565b505050565b60008115806117a4575050808202828282816117a157fe5b04145b61088757600080fd5b600081838161172657fe5b8082038281111561088757600080fd5b60405163089c54b560e31b815260009081907319c0976f590d67707e62397c87829d896dc0f1f1906344e2a5a890611804908790600401614c9d565b602060405180830381600087803b15801561181e57600080fd5b505af1158015611832573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118569190614637565b905060007335d1b3f3d7966a1dfe207aa4514c12a259a0492b6001600160a01b0316636c25b346886001600160a01b0316632726b073896040518263ffffffff1660e01b81526004016118a99190614c9d565b60206040518083038186803b1580156118c157600080fd5b505afa1580156118d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118f99190614481565b6040518263ffffffff1660e01b81526004016119159190614ac4565b60206040518083038186803b15801561192d57600080fd5b505afa158015611941573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119659190614637565b90506000611974888888610e1c565b905080851061198b576119888160016117b8565b94505b876001600160a01b03166345e6bdcd8860006119a889888861312b565b6040518463ffffffff1660e01b81526004016119c693929190614e65565b600060405180830381600087803b1580156119e057600080fd5b505af11580156119f4573d6000803e3d6000fd5b50505050876001600160a01b031663f9f30db68830611a12896131ae565b6040518463ffffffff1660e01b8152600401611a3093929190614e22565b600060405180830381600087803b158015611a4a57600080fd5b505af1158015611a5e573d6000803e3d6000fd5b5050604051634538c4eb60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250634538c4eb9150611aaf903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614ad8565b60206040518083038186803b158015611ac757600080fd5b505afa158015611adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aff9190614637565b611b81576040516328ec8bf160e21b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063a3b22fc490611b4e90739759a6ac90977b93b58547b4a71c78317f391a2890600401614ac4565b600060405180830381600087803b158015611b6857600080fd5b505af1158015611b7c573d6000803e3d6000fd5b505050505b60405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a289063ef693bed90611bba9030908990600401614c35565b600060405180830381600087803b158015611bd457600080fd5b505af1158015611be8573d6000803e3d6000fd5b50969a9950505050505050505050565b6040516320eb73ed60e11b815260009073637726f8b08a7abe3ae3acab01a80e2d8ddef77b906341d6e7da90611c32903290600401614ac4565b60206040518083038186803b158015611c4a57600080fd5b505afa158015611c5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c8291906145d6565b905090565b60008215611de4576000611ca2644554482d4160d81b6108a5565b90506000611cb085836116ef565b905060058404811115611cc35750600583045b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b158015611d1257600080fd5b505afa158015611d26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d4a9190614481565b60405163a9059cbb60e01b8152909150736b175474e89094c44da98b954eedeac495271d0f9063a9059cbb90611d869084908690600401614c35565b602060405180830381600087803b158015611da057600080fd5b505af1158015611db4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd891906145d6565b50819350505050610887565b50600092915050565b600080600080600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b031686600001516001600160a01b03161415611ea8578551611e32906131c5565b6001600160a01b031686526040808701518151630d0e30db60e41b8152915173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29263d0e30db09291600480830192600092919082900301818588803b158015611e8e57600080fd5b505af1158015611ea2573d6000803e3d6000fd5b50505050505b611ec486604001518760c0015188600001518960a0015161320c565b6040870180519190910390526101208601516060015115611f0157611eea86600061345f565b925090508015611f01578561012001516020015192505b80611f1b57611f1186600061365d565b91508560e0015192505b6000611f3a73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc261389f565b1115612020576040516370a0823160e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d9082906370a0823190611f7f903090600401614ac4565b602060405180830381600087803b158015611f9957600080fd5b505af1158015611fad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd19190614637565b6040518263ffffffff1660e01b8152600401611fed9190614c9d565b600060405180830381600087803b15801561200757600080fd5b505af115801561201b573d6000803e3d6000fd5b505050505b60208601516001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214156120cc5761205b86608001518760400151613949565b61207873eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee61389f565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906120c65760405162461bcd60e51b81526004016120bd9190614cf2565b60405180910390fd5b50612132565b6120de86608001518760400151613949565b6120eb876020015161389f565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906121305760405162461bcd60e51b81526004016120bd9190614cf2565b505b509092509050915091565b600061214883613971565b1561222157826001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561218657600080fd5b505afa15801561219a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121be9190614481565b6001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b1580156121f857600080fd5b505af115801561220c573d6000803e3d6000fd5b505050505061221a82613a4e565b9050612236565b61223361222e8484613a70565b613a4e565b90505b6122bc8383856001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561227457600080fd5b505afa158015612288573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122ac9190614481565b6001600160a01b03169190613af2565b604051633b4da69f60e01b81526001600160a01b03841690633b4da69f906122ea9030908690600401614c35565b600060405180830381600087803b15801561230457600080fd5b505af1158015612318573d6000803e3d6000fd5b5050604051632c2cb9fd60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250637608870391506001600160a01b03881690632c2cb9fd90612364908990600401614c9d565b60206040518083038186803b15801561237c57600080fd5b505afa158015612390573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b49190614637565b604051632726b07360e01b81526001600160a01b03891690632726b073906123e0908a90600401614c9d565b60206040518083038186803b1580156123f857600080fd5b505afa15801561240c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124309190614481565b30308660006040518763ffffffff1660e01b815260040161245696959493929190614cbd565b600060405180830381600087803b15801561247057600080fd5b505af1158015612484573d6000803e3d6000fd5b505050505050505050565b600080829050836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b1580156124ce57600080fd5b505afa1580156124e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125069190614637565b60121461258957836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561254657600080fd5b505afa15801561255a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257e9190614637565b601203600a0a830290505b856001600160a01b03166345e6bdcd866125a284613a4e565b60000360006040518463ffffffff1660e01b81526004016125c593929190614e65565b600060405180830381600087803b1580156125df57600080fd5b505af11580156125f3573d6000803e3d6000fd5b50506040516313771f0760e31b81526001600160a01b0389169250639bb8f838915061262790889030908690600401614e22565b600060405180830381600087803b15801561264157600080fd5b505af1158015612655573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038716925063ef693bed91506126879030908790600401614c35565b600060405180830381600087803b1580156126a157600080fd5b505af11580156126b5573d6000803e3d6000fd5b505050506126c284613971565b1561279657836001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561270057600080fd5b505afa158015612714573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127389190614481565b6001600160a01b0316632e1a7d4d846040518263ffffffff1660e01b81526004016127639190614c9d565b600060405180830381600087803b15801561277d57600080fd5b505af1158015612791573d6000803e3d6000fd5b505050505b5090949350505050565b604051632726b07360e01b81526000906001600160a01b03871690632726b073906127cf908890600401614c9d565b60206040518083038186803b1580156127e757600080fd5b505afa1580156127fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061281f9190614481565b905060006128437335d1b3f3d7966a1dfe207aa4514c12a259a0492b838488613b31565b9050808411156128e657736b175474e89094c44da98b954eedeac495271d0f63a9059cbb8461287287856117b8565b6040518363ffffffff1660e01b815260040161288f929190614c35565b602060405180830381600087803b1580156128a957600080fd5b505af11580156128bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e191906145d6565b508093505b604051636eb1769f60e11b8152736b175474e89094c44da98b954eedeac495271d0f9063dd62ed3e90612933903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614ad8565b60206040518083038186803b15801561294b57600080fd5b505afa15801561295f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129839190614637565b612a2a5760405163095ea7b360e01b8152736b175474e89094c44da98b954eedeac495271d0f9063095ea7b3906129d690739759a6ac90977b93b58547b4a71c78317f391a289060001990600401614c35565b602060405180830381600087803b1580156129f057600080fd5b505af1158015612a04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a2891906145d6565b505b604051633b4da69f60e01b8152739759a6ac90977b93b58547b4a71c78317f391a2890633b4da69f90612a639085908890600401614c35565b600060405180830381600087803b158015612a7d57600080fd5b505af1158015612a91573d6000803e3d6000fd5b50505050866001600160a01b03166345e6bdcd876000612ac67335d1b3f3d7966a1dfe207aa4514c12a259a0492b878b613d0c565b6040518463ffffffff1660e01b8152600401612ae493929190614e65565b600060405180830381600087803b158015612afe57600080fd5b505af1158015612b12573d6000803e3d6000fd5b5050505050505050505050565b6000612b2e8260a00151610d8d565b90506000612b40828460000151610791565b8351604051632c2cb9fd60e01b81529192506000916001600160a01b03851691632c2cb9fd91612b739190600401614c9d565b60206040518083038186803b158015612b8b57600080fd5b505afa158015612b9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc39190614637565b90506000612bdb848660000151848860800151611267565b90506000612bf385876000015188608001518561248f565b6040808801518201908901526001600160a01b03851660c08901529050612c18611bf8565b612c2457610190612c28565b61014d5b60a08801526000612c3888611ded565b915050612c49876020015182611c87565b8751910390612c5c9087908684896127a0565b612c7a86886000015189608001518a606001518b604001510161248f565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338a60000151898d6040015187604051602001612cbf9493929190614e41565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612cec93929190614b98565b600060405180830381600087803b158015612d0657600080fd5b505af1158015612d1a573d6000803e3d6000fd5b505050505050505050505050565b6000612d378260a00151610d8d565b90506000612d49828460000151610791565b8351604051632c2cb9fd60e01b8152919250600091612dd39185916001600160a01b03831690632c2cb9fd90612d83908490600401614c9d565b60206040518083038186803b158015612d9b57600080fd5b505afa158015612daf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c39190614637565b8451604051632c2cb9fd60e01b8152919250600091612e639186916001600160a01b03831690632c2cb9fd90612e0d908490600401614c9d565b60206040518083038186803b158015612e2557600080fd5b505afa158015612e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e5d9190614637565b856117c8565b9050612e79856020015186604001518301611c87565b604080870151830191909103908701526001600160a01b03831660c0870152612ea0611bf8565b612eac57610190612eb0565b61014d5b60a08701526000612ec087611ded565b915050612ed785876000015188608001518461213d565b8551604051632c2cb9fd60e01b8152612f6b9187916001600160a01b03831690632c2cb9fd90612f0b908490600401614c9d565b60206040518083038186803b158015612f2357600080fd5b505afa158015612f37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f5b9190614637565b89606001518a60400151016117c8565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338960000151888c6040015187604051602001612fb09493929190614e41565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612ae493929190614af2565b600082820183811015610ef65760405162461bcd60e51b81526004016120bd90614d05565b6002546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b15801561304757600080fd5b505afa15801561305b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061307f9190614481565b9050611784818484613eca565b8082018281101561088757600080fd5b60606130f1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613f609092919063ffffffff16565b805190915015611784578080602001905181019061310f91906145d6565b6117845760405162461bcd60e51b81526004016120bd90614d73565b600061314284676765c793fa10079d601b1b611789565b821015610ef6576131788361316b61316587676765c793fa10079d601b1b611789565b856117b8565b8161317257fe5b04613a4e565b905061318f84676765c793fa10079d601b1b611789565b6131998285611789565b106131a45780610a5b565b6001019392505050565b600061088782676765c793fa10079d601b1b611789565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146131f15781610887565b5073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2919050565b6000811580159061329f5750604051632cdc77ab60e21b8152731b14e8d511c9a4395425314f849bd737baf8208f9063b371deac9061324f908790600401614ac4565b60206040518083038186803b15801561326757600080fd5b505afa15801561327b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061329f91906145d6565b1561332e57604051636eeb543160e01b8152731b14e8d511c9a4395425314f849bd737baf8208f90636eeb5431906132db908790600401614ac4565b60206040518083038186803b1580156132f357600080fd5b505afa158015613307573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061332b9190614637565b91505b8161333b57506000610a5b565b81858161334457fe5b049050600a85048111156133585750600a84045b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b1580156133a757600080fd5b505afa1580156133bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133df9190614481565b90506001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415613442576040516001600160a01b0382169083156108fc029084906000818181858888f1935050505015801561343c573d6000803e3d6000fd5b50613456565b6134566001600160a01b038516828461172e565b50949350505050565b610120820151602001516040516302f5cc7960e11b81526000918291734ba1f38427b33b8ab7bb0490200dae1f1c36823f916305eb98f2916134a49190600401614ac4565b60206040518083038186803b1580156134bc57600080fd5b505afa1580156134d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134f491906145d6565b61350357506000905080613656565b6101208401515160405163e0aa279760e01b81527325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa2797916135409190600401614ac4565b60206040518083038186803b15801561355857600080fd5b505afa15801561356c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061359091906145d6565b61359f57506000905080613656565b61012084015151604085015185516135c2926001600160a01b039091169161172e565b610120840151805160809091015160405163097396a160e31b81526001600160a01b0390921691634b9cb50891906136009088908890600401614df6565b60408051808303818588803b15801561361857600080fd5b505af115801561362c573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061365191906145f2565b915091505b9250929050565b60e082015160405163e0aa279760e01b81526000917325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa27979161369a91600401614ac4565b60206040518083038186803b1580156136b257600080fd5b505afa1580156136c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136ea91906145d6565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b815250906137305760405162461bcd60e51b81526004016120bd9190614cf2565b5060e083015160408401518451613752926001600160a01b039091169161172e565b600082600181111561376057fe5b1415613806578260e001516001600160a01b0316635b6f36fc8460000151856020015186604001518761010001516040518563ffffffff1660e01b81526004016137ad9493929190614c4e565b602060405180830381600087803b1580156137c757600080fd5b505af11580156137db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137ff9190614637565b9050610887565b8260e001516001600160a01b0316633924db668460000151856020015186606001518761010001516040518563ffffffff1660e01b815260040161384d9493929190614c4e565b602060405180830381600087803b15801561386757600080fd5b505af115801561387b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef69190614637565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156138cd5750476106d7565b6040516370a0823160e01b81526001600160a01b038316906370a08231906138f9903090600401614ac4565b60206040518083038186803b15801561391157600080fd5b505afa158015613925573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108879190614637565b6000670de0b6b3a764000061171f6139618585611789565b6002670de0b6b3a7640000611719565b6000739759a6ac90977b93b58547b4a71c78317f391a286001600160a01b03831614156139a0575060006106d7565b816001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b1580156139d957600080fd5b505afa1580156139ed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a119190614481565b6001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03161415613a46575060016106d7565b506000919050565b8060008112156106d75760405162461bcd60e51b81526004016120bd90614dbd565b6000610ef682846001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b158015613aaf57600080fd5b505afa158015613ac3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae79190614637565b601203600a0a611789565b613b128363095ea7b360e01b84600060405160240161174d929190614c81565b6117848363095ea7b360e01b848460405160240161174d929190614c35565b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b8152600401613b609190614c9d565b60a06040518083038186803b158015613b7857600080fd5b505afa158015613b8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb09190614929565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b8152600401613be6929190614ca6565b604080518083038186803b158015613bfd57600080fd5b505afa158015613c11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c359190614906565b9150506000876001600160a01b0316636c25b346886040518263ffffffff1660e01b8152600401613c669190614ac4565b60206040518083038186803b158015613c7e57600080fd5b505afa158015613c92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cb69190614637565b90506000613cc7610ee28486611789565b9050676765c793fa10079d601b1b8104945080613cef86676765c793fa10079d601b1b611789565b10613cfa5784613cff565b846001015b9998505050505050505050565b600080846001600160a01b0316636c25b346856040518263ffffffff1660e01b8152600401613d3b9190614ac4565b60206040518083038186803b158015613d5357600080fd5b505afa158015613d67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d8b9190614637565b90506000856001600160a01b031663d9638d36856040518263ffffffff1660e01b8152600401613dbb9190614c9d565b60a06040518083038186803b158015613dd357600080fd5b505afa158015613de7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e0b9190614929565b5050509150506000866001600160a01b0316632424be5c86886040518363ffffffff1660e01b8152600401613e41929190614ca6565b604080518083038186803b158015613e5857600080fd5b505afa158015613e6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e909190614906565b915050613e9f82848161317257fe5b935080841115613eba57613eb281613a4e565b600003613ebf565b836000035b979650505050505050565b613ed2613f6f565b6001600160a01b0316826001600160a01b03161415613f4c57826001600160a01b031681604051613f0290614ac1565b60006040518083038185875af1925050503d8060008114613f3f576040519150601f19603f3d011682016040523d82523d6000602084013e613f44565b606091505b505050611784565b6117846001600160a01b038316848361172e565b6060610a5b8484600085613f87565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b6060613f928561404b565b613fae5760405162461bcd60e51b81526004016120bd90614d3c565b60006060866001600160a01b03168587604051613fcb9190614aa5565b60006040518083038185875af1925050503d8060008114614008576040519150601f19603f3d011682016040523d82523d6000602084013e61400d565b606091505b50915091508115614021579150610a5b9050565b8051156140315780518082602001fd5b8360405162461bcd60e51b81526004016120bd9190614cf2565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610a5b575050151592915050565b60405180610140016040528060006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016140fb614144565b905290565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b03168152602001600060018111156140fb57fe5b6040518060c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001606081525090565b803561088781614f04565b805161088781614f04565b600082601f8301126141bb578081fd5b81356141ce6141c982614eb0565b614e89565b91508082528360208285010111156141e557600080fd5b8060208401602084013760009082016020015292915050565b600082601f83011261420e578081fd5b815161421c6141c982614eb0565b915080825283602082850101111561423357600080fd5b614244816020840160208601614ed4565b5092915050565b80356002811061088757600080fd5b600061014080838503121561426d578182fd5b61427681614e89565b9150506142838383614195565b81526142928360208401614195565b602082015260408201356040820152606082013560608201526080820135608082015260a082013560a08201526142cc8360c08401614195565b60c08201526142de8360e08401614195565b60e08201526101008083013567ffffffffffffffff8082111561430057600080fd5b61430c868387016141ab565b8385015261012092508285013591508082111561432857600080fd5b5061433585828601614341565b82840152505092915050565b600060c08284031215614352578081fd5b61435c60c0614e89565b9050813561436981614f04565b8152602082013561437981614f04565b6020820152604082013561438c81614f04565b80604083015250606082013560608201526080820135608082015260a082013567ffffffffffffffff8111156143c157600080fd5b6143cd848285016141ab565b60a08301525092915050565b600060c082840312156143ea578081fd5b6143f460c0614e89565b9050815161440181614f04565b8152602082015161441181614f04565b6020820152604082015161442481614f04565b80604083015250606082015160608201526080820151608082015260a082015167ffffffffffffffff81111561445957600080fd5b6143cd848285016141fe565b600060208284031215614476578081fd5b8135610ef681614f04565b600060208284031215614492578081fd5b8151610ef681614f04565b600080604083850312156144af578081fd5b82356144ba81614f04565b946020939093013593505050565b6000806000606084860312156144dc578081fd5b83356144e781614f04565b95602085013595506040909401359392505050565b60008060008060808587031215614511578182fd5b843561451c81614f04565b93506020850135925060408501359150606085013561453a81614f04565b939692955090935050565b60008060008060006080868803121561455c578283fd5b853561456781614f04565b94506020860135935060408601359250606086013567ffffffffffffffff80821115614591578283fd5b818801915088601f8301126145a4578283fd5b8135818111156145b2578384fd5b8960208285010111156145c3578384fd5b9699959850939650602001949392505050565b6000602082840312156145e7578081fd5b8151610ef681614f1c565b60008060408385031215614604578182fd5b825161460f81614f1c565b6020939093015192949293505050565b600060208284031215614630578081fd5b5035919050565b600060208284031215614648578081fd5b5051919050565b600060208284031215614660578081fd5b813567ffffffffffffffff811115614676578182fd5b610883848285016141ab565b60008060008060008060c0878903121561469a578384fd5b863567ffffffffffffffff8111156146b0578485fd5b6146bc89828a016141ab565b965050602087013594506040870135935060608701356146db81614f04565b925060808701356146eb81614f1c565b915060a087013560ff81168114614700578182fd5b809150509295509295509295565b600080604083850312156144af578182fd5b60008060408385031215614732578182fd5b825161460f81614f04565b60006020828403121561474e578081fd5b610ef6838361424b565b600060208284031215614769578081fd5b813567ffffffffffffffff81111561477f578182fd5b6108838482850161425a565b60006020828403121561479c578081fd5b815167ffffffffffffffff808211156147b3578283fd5b81840191506101408083870312156147c9578384fd5b6147d281614e89565b90506147de86846141a0565b81526147ed86602085016141a0565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201526148278660c085016141a0565b60c08201526148398660e085016141a0565b60e08201526101008084015183811115614851578586fd5b61485d888287016141fe565b8284015250506101208084015183811115614876578586fd5b614882888287016143d9565b918301919091525095945050505050565b600080600080600060a086880312156148aa578283fd5b853567ffffffffffffffff8111156148c0578384fd5b6148cc8882890161425a565b955050602086013593506040860135925060608601356148eb81614f04565b91506148fa876080880161424b565b90509295509295909350565b60008060408385031215614918578182fd5b505080516020909101519092909150565b600080600080600060a08688031215614940578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b6001600160a01b03169052565b6000815180845261498d816020860160208601614ed4565b601f01601f19169290920160200192915050565b60006101406149b1848451614968565b60208301516149c36020860182614968565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c08301516149fe60c0860182614968565b5060e0830151614a1160e0860182614968565b50610100808401518282870152614a2a83870182614975565b925050506101208084015185830382870152614a468382614a50565b9695505050505050565b600060018060a01b0380835116845280602084015116602085015280604084015116604085015250606082015160608401526080820151608084015260a082015160c060a085015261088360c0850182614975565b60008251614ab7818460208701614ed4565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c1350d1119b185cda109bdbdcdd609a1b60a082015260c060608201819052600090614b4390830184614975565b95945050505050565b6001600160a01b03848116825283166020820152608060408201819052600890820152671350d1109bdbdcdd60c21b60a082015260c060608201819052600090614b4390830184614975565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c4d4344466c617368526570617960981b60a082015260c060608201819052600090614b4390830184614975565b6001600160a01b03848116825283166020820152608060408201819052600890820152674d4344526570617960c01b60a082015260c060608201819052600090614b4390830184614975565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614a4690830184614975565b6001600160a01b0392909216825260ff16602082015260400190565b90815260200190565b9182526001600160a01b0316602082015260400190565b9586526001600160a01b039485166020870152928416604086015292166060840152608083019190915260a082015260c00190565b600060208252610ef66020830184614975565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600c908201526b696e742d6f766572666c6f7760a01b604082015260600190565b600060208252610ef660208301846149a1565b600060408252614e0960408301856149a1565b905060028310614e1557fe5b8260208301529392505050565b9283526001600160a01b03919091166020830152604082015260600190565b9384526001600160a01b039290921660208401526040830152606082015260800190565b9283526020830191909152604082015260600190565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715614ea857600080fd5b604052919050565b600067ffffffffffffffff821115614ec6578081fd5b50601f01601f191660200190565b60005b83811015614eef578181015183820152602001614ed7565b83811115614efe576000848401525b50505050565b6001600160a01b0381168114614f1957600080fd5b50565b8015158114614f1957600080fdfea2646970667358221220a82338d1bbe4f0433c35fa0219f01fc6d69e0309bf732ee2e41e7e83efdb33b264736f6c634300060c0033
Deployed Bytecode
0x60806040526004361061026b5760003560e01c80638c8a795811610144578063c72c4d10116100b6578063dd6d903c1161007a578063dd6d903c1461060f578063deca5f881461062f578063e870b9cd1461064f578063ee87255814610662578063f24ccbfe14610682578063f851a4401461069757610272565b8063c72c4d10146105d2578063c7975824146105e7578063cc694d48146105fa578063cf786f8f146103bc578063cfac57c7146105a857610272565b8063a46a66c911610108578063a46a66c914610549578063a7304bf71461055e578063acbeba611461057e578063ae08fd1014610593578063c11645bc146105a8578063c50ebaf8146105bd57610272565b80638c8a7958146104c85780638da5cb5b146104dd57806398ab3d49146104f2578063a342f23814610507578063a3b8e5d11461051c57610272565b806336569e77116101dd5780634d2ab9dc116101a15780634d2ab9dc146104495780634d93667e1461045e578063526d64611461047e5780636738929f1461035257806381b94280146104935780638aa0fd0e146104a857610272565b806336569e77146103bc5780633a128322146103d15780634115fe6b146103f157806341c0e1b51461041f578063449b9ffa1461043457610272565b806329f7fc9e1161022f57806329f7fc9e1461031b5780632a4c0a1a1461033d5780632e77468d146103525780632f634a9014610367578063314b63321461038757806331d98b3f1461039c57610272565b806304c9805c1461027757806308d4f52a146102a2578063186cab76146102cf5780631e48907b146102e4578063278d58311461030657610272565b3661027257005b600080fd5b34801561028357600080fd5b5061028c6106ac565b6040516102999190614c9d565b60405180910390f35b3480156102ae57600080fd5b506102c26102bd366004614758565b6106b2565b6040516102999190614cf2565b3480156102db57600080fd5b5061028c6106dc565b3480156102f057600080fd5b506103046102ff366004614465565b6106e8565b005b34801561031257600080fd5b506102c2610721565b34801561032757600080fd5b50610330610749565b6040516102999190614ac4565b34801561034957600080fd5b50610330610761565b34801561035e57600080fd5b50610330610779565b34801561037357600080fd5b5061033061038236600461470e565b610791565b34801561039357600080fd5b5061033061088d565b3480156103a857600080fd5b5061028c6103b736600461461f565b6108a5565b3480156103c857600080fd5b50610330610a63565b3480156103dd57600080fd5b506103046103ec36600461449d565b610a7b565b3480156103fd57600080fd5b5061041161040c3660046144c8565b610b14565b604051610299929190614e7b565b34801561042b57600080fd5b50610304610d30565b34801561044057600080fd5b506102c2610d55565b34801561045557600080fd5b5061028c610d87565b34801561046a57600080fd5b5061033061047936600461473d565b610d8d565b34801561048a57600080fd5b50610330610dec565b34801561049f57600080fd5b50610330610e04565b3480156104b457600080fd5b5061028c6104c33660046144c8565b610e1c565b3480156104d457600080fd5b50610330610efd565b3480156104e957600080fd5b50610330610f15565b3480156104fe57600080fd5b50610330610f24565b34801561051357600080fd5b50610330610f33565b34801561052857600080fd5b5061053c61053736600461464f565b610f4b565b6040516102999190614de3565b34801561055557600080fd5b50610330610f67565b34801561056a57600080fd5b50610304610579366004614465565b610f7f565b34801561058a57600080fd5b50610330610fb8565b34801561059f57600080fd5b506102c2610fd0565b3480156105b457600080fd5b50610330611001565b3480156105c957600080fd5b506102c2611019565b3480156105de57600080fd5b50610330611048565b6103046105f5366004614893565b611057565b34801561060657600080fd5b506102c261123c565b34801561061b57600080fd5b5061028c61062a3660046144fc565b611267565b34801561063b57600080fd5b5061030461064a366004614465565b6113cf565b61030461065d366004614893565b6113fc565b34801561066e57600080fd5b5061030461067d366004614545565b6115d9565b34801561068e57600080fd5b506103306116c8565b3480156106a357600080fd5b506103306116e0565b61014d81565b6060816040516020016106c59190614de3565b60405160208183030381529060405290505b919050565b644554482d4160d81b81565b6001546001600160a01b031633146106ff57600080fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b81525081565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b736b175474e89094c44da98b954eedeac495271d0f81565b7365c79fcb50ca1594b025960e539ed7a9a6d434a381565b600080836001600160a01b0316638161b120846040518263ffffffff1660e01b81526004016107c09190614c9d565b60206040518083038186803b1580156107d857600080fd5b505afa1580156107ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108109190614481565b9050806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561084b57600080fd5b505afa15801561085f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108839190614481565b9150505b92915050565b7325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d81565b604051636cb1c69b60e11b815260009081907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906108e1908690600401614c9d565b604080518083038186803b1580156108f857600080fd5b505afa15801561090c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109309190614720565b604051636cb1c69b60e11b8152909250600091507335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063d9638d369061096e908790600401614c9d565b60a06040518083038186803b15801561098657600080fd5b505afa15801561099a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109be9190614929565b505092505050610a5b610a55827365c79fcb50ca1594b025960e539ed7a9a6d434a36001600160a01b031663495d32cb6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1857600080fd5b505afa158015610a2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a509190614637565b6116ef565b836116ef565b949350505050565b7335d1b3f3d7966a1dfe207aa4514c12a259a0492b81565b6000546001600160a01b03163314610a9257600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b0383161415610af657600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015610af0573d6000803e3d6000fd5b50610b10565b600054610b10906001600160a01b0384811691168361172e565b5050565b6000806000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5257600080fd5b505afa158015610b66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8a9190614481565b90506000866001600160a01b0316632726b073876040518263ffffffff1660e01b8152600401610bba9190614c9d565b60206040518083038186803b158015610bd257600080fd5b505afa158015610be6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0a9190614481565b9050600080836001600160a01b0316632424be5c88856040518363ffffffff1660e01b8152600401610c3d929190614ca6565b604080518083038186803b158015610c5457600080fd5b505afa158015610c68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8c9190614906565b915091506000846001600160a01b031663d9638d36896040518263ffffffff1660e01b8152600401610cbe9190614c9d565b60a06040518083038186803b158015610cd657600080fd5b505afa158015610cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0e9190614929565b50505091505082610d1f83836116ef565b965096505050505050935093915050565b6000546001600160a01b03163314610d4757600080fd5b6000546001600160a01b0316ff5b6040518060400160405280601681526020017516995c9bde08195e18da185b99d9481a5b9d985b1a5960521b81525081565b61019081565b600080826001811115610d9c57fe5b1415610dbd5750735ef30b9986345249bc32d8928b7ee64de9435e396106d7565b6001826001811115610dcb57fe5b14156106d75750733f30c2381cd8b917dd96eb2f1a4f96d91324bbed6106d7565b73637726f8b08a7abe3ae3acab01a80e2d8ddef77b81565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600080610e28836108a5565b604051636cb1c69b60e11b81529091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d3690610e65908790600401614c9d565b604080518083038186803b158015610e7c57600080fd5b505afa158015610e90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb49190614720565b915050600080610ec5888888610b14565b91509150610eef610ee8610ee2610edc8588611789565b866117ad565b836117b8565b600a6117b8565b9450505050505b9392505050565b734ba1f38427b33b8ab7bb0490200dae1f1c36823f81565b6000546001600160a01b031681565b6003546001600160a01b031681565b7339c4a92dc506300c3ea4c67ca4ca611102ee6f2a81565b610f53614084565b81806020019051810190610887919061478b565b731b14e8d511c9a4395425314f849bd737baf8208f81565b6001546001600160a01b03163314610f9657600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b7319c0976f590d67707e62397c87829d896dc0f1f181565b6040518060400160405280601581526020017413d99998da185a5b8819185d18481a5b9d985b1a59605a1b81525081565b739759a6ac90977b93b58547b4a71c78317f391a2881565b604051806040016040528060138152602001724465737420616d6f756e74206d697373696e6760681b81525081565b6002546001600160a01b031681565b600061106282610d8d565b905060006110708287610791565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016110a09190614c9d565b60206040518083038186803b1580156110b857600080fd5b505afa1580156110cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f09190614637565b905060006111048489848c604001516117c8565b6001600160a01b03841660c08b0152905061111d611bf8565b6111295761019061112d565b61014d5b60a08a015261113c8782611c87565b810360408a0152600061114e8a611ded565b91505061115d858a898461213d565b47156111915760405132904780156108fc02916000818181858888f1935050505015801561118f573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338c888f60400151876040516020016111d19493929190614e41565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016111fe93929190614b4c565b600060405180830381600087803b15801561121857600080fd5b505af115801561122c573d6000803e3d6000fd5b5050505050505050505050505050565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b81525081565b600080611273846108a5565b9050600080611283888888610b14565b604051636cb1c69b60e11b815291935091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906112c2908a90600401614c9d565b604080518083038186803b1580156112d957600080fd5b505afa1580156112ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113119190614720565b91505060006113328461132d6113278587611789565b886117ad565b6117b8565b90506000876001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561136f57600080fd5b505afa158015611383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a79190614637565b601203600a0a82816113b557fe5b049050606460638202049650505050505050949350505050565b6000546001600160a01b031633146113e657600080fd5b6001546001600160a01b031615610f9657600080fd5b600061140782610d8d565b905060006114158287610791565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016114459190614c9d565b60206040518083038186803b15801561145d57600080fd5b505afa158015611471573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114959190614637565b90506114a78388878b6040015161248f565b506001600160a01b03821660c08901526114bf611bf8565b6114cb576101906114cf565b61014d5b60a089015260006114df89611ded565b9150506114ec8782611c87565b90036114fb84898484876127a0565b471561152f5760405132904780156108fc02916000818181858888f1935050505015801561152d573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338b878e604001518760405160200161156f9493929190614e41565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161159c93929190614be9565b600060405180830381600087803b1580156115b657600080fd5b505af11580156115ca573d6000803e3d6000fd5b50505050505050505050505050565b60606000808080806115ed87890189614682565b955095509550955095509550611601614084565b61160a87610f4b565b9050611614614100565b6040518060c001604052808881526020018781526020018d81526020018c8152602001866001600160a01b031681526020018460ff16600181111561165557fe5b600181111561166057fe5b905290508315611679576116748282612b1f565b611683565b6116838282612d28565b6116968d6116918e8e612fdd565b613002565b47156115ca5760405132904780156108fc02916000818181858888f1935050505015801561122c573d6000803e3d6000fd5b735c55b921f590a89c1ebe84df170e655a82b6212681565b6001546001600160a01b031681565b6000676765c793fa10079d601b1b61171f61170a8585611789565b6002676765c793fa10079d601b1b5b0461308c565b8161172657fe5b049392505050565b6117848363a9059cbb60e01b848460405160240161174d929190614c35565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261309c565b505050565b60008115806117a4575050808202828282816117a157fe5b04145b61088757600080fd5b600081838161172657fe5b8082038281111561088757600080fd5b60405163089c54b560e31b815260009081907319c0976f590d67707e62397c87829d896dc0f1f1906344e2a5a890611804908790600401614c9d565b602060405180830381600087803b15801561181e57600080fd5b505af1158015611832573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118569190614637565b905060007335d1b3f3d7966a1dfe207aa4514c12a259a0492b6001600160a01b0316636c25b346886001600160a01b0316632726b073896040518263ffffffff1660e01b81526004016118a99190614c9d565b60206040518083038186803b1580156118c157600080fd5b505afa1580156118d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118f99190614481565b6040518263ffffffff1660e01b81526004016119159190614ac4565b60206040518083038186803b15801561192d57600080fd5b505afa158015611941573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119659190614637565b90506000611974888888610e1c565b905080851061198b576119888160016117b8565b94505b876001600160a01b03166345e6bdcd8860006119a889888861312b565b6040518463ffffffff1660e01b81526004016119c693929190614e65565b600060405180830381600087803b1580156119e057600080fd5b505af11580156119f4573d6000803e3d6000fd5b50505050876001600160a01b031663f9f30db68830611a12896131ae565b6040518463ffffffff1660e01b8152600401611a3093929190614e22565b600060405180830381600087803b158015611a4a57600080fd5b505af1158015611a5e573d6000803e3d6000fd5b5050604051634538c4eb60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250634538c4eb9150611aaf903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614ad8565b60206040518083038186803b158015611ac757600080fd5b505afa158015611adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aff9190614637565b611b81576040516328ec8bf160e21b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063a3b22fc490611b4e90739759a6ac90977b93b58547b4a71c78317f391a2890600401614ac4565b600060405180830381600087803b158015611b6857600080fd5b505af1158015611b7c573d6000803e3d6000fd5b505050505b60405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a289063ef693bed90611bba9030908990600401614c35565b600060405180830381600087803b158015611bd457600080fd5b505af1158015611be8573d6000803e3d6000fd5b50969a9950505050505050505050565b6040516320eb73ed60e11b815260009073637726f8b08a7abe3ae3acab01a80e2d8ddef77b906341d6e7da90611c32903290600401614ac4565b60206040518083038186803b158015611c4a57600080fd5b505afa158015611c5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c8291906145d6565b905090565b60008215611de4576000611ca2644554482d4160d81b6108a5565b90506000611cb085836116ef565b905060058404811115611cc35750600583045b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b158015611d1257600080fd5b505afa158015611d26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d4a9190614481565b60405163a9059cbb60e01b8152909150736b175474e89094c44da98b954eedeac495271d0f9063a9059cbb90611d869084908690600401614c35565b602060405180830381600087803b158015611da057600080fd5b505af1158015611db4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd891906145d6565b50819350505050610887565b50600092915050565b600080600080600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b031686600001516001600160a01b03161415611ea8578551611e32906131c5565b6001600160a01b031686526040808701518151630d0e30db60e41b8152915173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29263d0e30db09291600480830192600092919082900301818588803b158015611e8e57600080fd5b505af1158015611ea2573d6000803e3d6000fd5b50505050505b611ec486604001518760c0015188600001518960a0015161320c565b6040870180519190910390526101208601516060015115611f0157611eea86600061345f565b925090508015611f01578561012001516020015192505b80611f1b57611f1186600061365d565b91508560e0015192505b6000611f3a73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc261389f565b1115612020576040516370a0823160e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d9082906370a0823190611f7f903090600401614ac4565b602060405180830381600087803b158015611f9957600080fd5b505af1158015611fad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd19190614637565b6040518263ffffffff1660e01b8152600401611fed9190614c9d565b600060405180830381600087803b15801561200757600080fd5b505af115801561201b573d6000803e3d6000fd5b505050505b60208601516001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214156120cc5761205b86608001518760400151613949565b61207873eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee61389f565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906120c65760405162461bcd60e51b81526004016120bd9190614cf2565b60405180910390fd5b50612132565b6120de86608001518760400151613949565b6120eb876020015161389f565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906121305760405162461bcd60e51b81526004016120bd9190614cf2565b505b509092509050915091565b600061214883613971565b1561222157826001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561218657600080fd5b505afa15801561219a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121be9190614481565b6001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b1580156121f857600080fd5b505af115801561220c573d6000803e3d6000fd5b505050505061221a82613a4e565b9050612236565b61223361222e8484613a70565b613a4e565b90505b6122bc8383856001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561227457600080fd5b505afa158015612288573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122ac9190614481565b6001600160a01b03169190613af2565b604051633b4da69f60e01b81526001600160a01b03841690633b4da69f906122ea9030908690600401614c35565b600060405180830381600087803b15801561230457600080fd5b505af1158015612318573d6000803e3d6000fd5b5050604051632c2cb9fd60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250637608870391506001600160a01b03881690632c2cb9fd90612364908990600401614c9d565b60206040518083038186803b15801561237c57600080fd5b505afa158015612390573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b49190614637565b604051632726b07360e01b81526001600160a01b03891690632726b073906123e0908a90600401614c9d565b60206040518083038186803b1580156123f857600080fd5b505afa15801561240c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124309190614481565b30308660006040518763ffffffff1660e01b815260040161245696959493929190614cbd565b600060405180830381600087803b15801561247057600080fd5b505af1158015612484573d6000803e3d6000fd5b505050505050505050565b600080829050836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b1580156124ce57600080fd5b505afa1580156124e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125069190614637565b60121461258957836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561254657600080fd5b505afa15801561255a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257e9190614637565b601203600a0a830290505b856001600160a01b03166345e6bdcd866125a284613a4e565b60000360006040518463ffffffff1660e01b81526004016125c593929190614e65565b600060405180830381600087803b1580156125df57600080fd5b505af11580156125f3573d6000803e3d6000fd5b50506040516313771f0760e31b81526001600160a01b0389169250639bb8f838915061262790889030908690600401614e22565b600060405180830381600087803b15801561264157600080fd5b505af1158015612655573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038716925063ef693bed91506126879030908790600401614c35565b600060405180830381600087803b1580156126a157600080fd5b505af11580156126b5573d6000803e3d6000fd5b505050506126c284613971565b1561279657836001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561270057600080fd5b505afa158015612714573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127389190614481565b6001600160a01b0316632e1a7d4d846040518263ffffffff1660e01b81526004016127639190614c9d565b600060405180830381600087803b15801561277d57600080fd5b505af1158015612791573d6000803e3d6000fd5b505050505b5090949350505050565b604051632726b07360e01b81526000906001600160a01b03871690632726b073906127cf908890600401614c9d565b60206040518083038186803b1580156127e757600080fd5b505afa1580156127fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061281f9190614481565b905060006128437335d1b3f3d7966a1dfe207aa4514c12a259a0492b838488613b31565b9050808411156128e657736b175474e89094c44da98b954eedeac495271d0f63a9059cbb8461287287856117b8565b6040518363ffffffff1660e01b815260040161288f929190614c35565b602060405180830381600087803b1580156128a957600080fd5b505af11580156128bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e191906145d6565b508093505b604051636eb1769f60e11b8152736b175474e89094c44da98b954eedeac495271d0f9063dd62ed3e90612933903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614ad8565b60206040518083038186803b15801561294b57600080fd5b505afa15801561295f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129839190614637565b612a2a5760405163095ea7b360e01b8152736b175474e89094c44da98b954eedeac495271d0f9063095ea7b3906129d690739759a6ac90977b93b58547b4a71c78317f391a289060001990600401614c35565b602060405180830381600087803b1580156129f057600080fd5b505af1158015612a04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a2891906145d6565b505b604051633b4da69f60e01b8152739759a6ac90977b93b58547b4a71c78317f391a2890633b4da69f90612a639085908890600401614c35565b600060405180830381600087803b158015612a7d57600080fd5b505af1158015612a91573d6000803e3d6000fd5b50505050866001600160a01b03166345e6bdcd876000612ac67335d1b3f3d7966a1dfe207aa4514c12a259a0492b878b613d0c565b6040518463ffffffff1660e01b8152600401612ae493929190614e65565b600060405180830381600087803b158015612afe57600080fd5b505af1158015612b12573d6000803e3d6000fd5b5050505050505050505050565b6000612b2e8260a00151610d8d565b90506000612b40828460000151610791565b8351604051632c2cb9fd60e01b81529192506000916001600160a01b03851691632c2cb9fd91612b739190600401614c9d565b60206040518083038186803b158015612b8b57600080fd5b505afa158015612b9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc39190614637565b90506000612bdb848660000151848860800151611267565b90506000612bf385876000015188608001518561248f565b6040808801518201908901526001600160a01b03851660c08901529050612c18611bf8565b612c2457610190612c28565b61014d5b60a08801526000612c3888611ded565b915050612c49876020015182611c87565b8751910390612c5c9087908684896127a0565b612c7a86886000015189608001518a606001518b604001510161248f565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338a60000151898d6040015187604051602001612cbf9493929190614e41565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612cec93929190614b98565b600060405180830381600087803b158015612d0657600080fd5b505af1158015612d1a573d6000803e3d6000fd5b505050505050505050505050565b6000612d378260a00151610d8d565b90506000612d49828460000151610791565b8351604051632c2cb9fd60e01b8152919250600091612dd39185916001600160a01b03831690632c2cb9fd90612d83908490600401614c9d565b60206040518083038186803b158015612d9b57600080fd5b505afa158015612daf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c39190614637565b8451604051632c2cb9fd60e01b8152919250600091612e639186916001600160a01b03831690632c2cb9fd90612e0d908490600401614c9d565b60206040518083038186803b158015612e2557600080fd5b505afa158015612e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e5d9190614637565b856117c8565b9050612e79856020015186604001518301611c87565b604080870151830191909103908701526001600160a01b03831660c0870152612ea0611bf8565b612eac57610190612eb0565b61014d5b60a08701526000612ec087611ded565b915050612ed785876000015188608001518461213d565b8551604051632c2cb9fd60e01b8152612f6b9187916001600160a01b03831690632c2cb9fd90612f0b908490600401614c9d565b60206040518083038186803b158015612f2357600080fd5b505afa158015612f37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f5b9190614637565b89606001518a60400151016117c8565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338960000151888c6040015187604051602001612fb09493929190614e41565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612ae493929190614af2565b600082820183811015610ef65760405162461bcd60e51b81526004016120bd90614d05565b6002546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b15801561304757600080fd5b505afa15801561305b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061307f9190614481565b9050611784818484613eca565b8082018281101561088757600080fd5b60606130f1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613f609092919063ffffffff16565b805190915015611784578080602001905181019061310f91906145d6565b6117845760405162461bcd60e51b81526004016120bd90614d73565b600061314284676765c793fa10079d601b1b611789565b821015610ef6576131788361316b61316587676765c793fa10079d601b1b611789565b856117b8565b8161317257fe5b04613a4e565b905061318f84676765c793fa10079d601b1b611789565b6131998285611789565b106131a45780610a5b565b6001019392505050565b600061088782676765c793fa10079d601b1b611789565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146131f15781610887565b5073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2919050565b6000811580159061329f5750604051632cdc77ab60e21b8152731b14e8d511c9a4395425314f849bd737baf8208f9063b371deac9061324f908790600401614ac4565b60206040518083038186803b15801561326757600080fd5b505afa15801561327b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061329f91906145d6565b1561332e57604051636eeb543160e01b8152731b14e8d511c9a4395425314f849bd737baf8208f90636eeb5431906132db908790600401614ac4565b60206040518083038186803b1580156132f357600080fd5b505afa158015613307573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061332b9190614637565b91505b8161333b57506000610a5b565b81858161334457fe5b049050600a85048111156133585750600a84045b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b1580156133a757600080fd5b505afa1580156133bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133df9190614481565b90506001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415613442576040516001600160a01b0382169083156108fc029084906000818181858888f1935050505015801561343c573d6000803e3d6000fd5b50613456565b6134566001600160a01b038516828461172e565b50949350505050565b610120820151602001516040516302f5cc7960e11b81526000918291734ba1f38427b33b8ab7bb0490200dae1f1c36823f916305eb98f2916134a49190600401614ac4565b60206040518083038186803b1580156134bc57600080fd5b505afa1580156134d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134f491906145d6565b61350357506000905080613656565b6101208401515160405163e0aa279760e01b81527325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa2797916135409190600401614ac4565b60206040518083038186803b15801561355857600080fd5b505afa15801561356c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061359091906145d6565b61359f57506000905080613656565b61012084015151604085015185516135c2926001600160a01b039091169161172e565b610120840151805160809091015160405163097396a160e31b81526001600160a01b0390921691634b9cb50891906136009088908890600401614df6565b60408051808303818588803b15801561361857600080fd5b505af115801561362c573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061365191906145f2565b915091505b9250929050565b60e082015160405163e0aa279760e01b81526000917325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa27979161369a91600401614ac4565b60206040518083038186803b1580156136b257600080fd5b505afa1580156136c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136ea91906145d6565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b815250906137305760405162461bcd60e51b81526004016120bd9190614cf2565b5060e083015160408401518451613752926001600160a01b039091169161172e565b600082600181111561376057fe5b1415613806578260e001516001600160a01b0316635b6f36fc8460000151856020015186604001518761010001516040518563ffffffff1660e01b81526004016137ad9493929190614c4e565b602060405180830381600087803b1580156137c757600080fd5b505af11580156137db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137ff9190614637565b9050610887565b8260e001516001600160a01b0316633924db668460000151856020015186606001518761010001516040518563ffffffff1660e01b815260040161384d9493929190614c4e565b602060405180830381600087803b15801561386757600080fd5b505af115801561387b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef69190614637565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156138cd5750476106d7565b6040516370a0823160e01b81526001600160a01b038316906370a08231906138f9903090600401614ac4565b60206040518083038186803b15801561391157600080fd5b505afa158015613925573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108879190614637565b6000670de0b6b3a764000061171f6139618585611789565b6002670de0b6b3a7640000611719565b6000739759a6ac90977b93b58547b4a71c78317f391a286001600160a01b03831614156139a0575060006106d7565b816001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b1580156139d957600080fd5b505afa1580156139ed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a119190614481565b6001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03161415613a46575060016106d7565b506000919050565b8060008112156106d75760405162461bcd60e51b81526004016120bd90614dbd565b6000610ef682846001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b158015613aaf57600080fd5b505afa158015613ac3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae79190614637565b601203600a0a611789565b613b128363095ea7b360e01b84600060405160240161174d929190614c81565b6117848363095ea7b360e01b848460405160240161174d929190614c35565b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b8152600401613b609190614c9d565b60a06040518083038186803b158015613b7857600080fd5b505afa158015613b8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb09190614929565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b8152600401613be6929190614ca6565b604080518083038186803b158015613bfd57600080fd5b505afa158015613c11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c359190614906565b9150506000876001600160a01b0316636c25b346886040518263ffffffff1660e01b8152600401613c669190614ac4565b60206040518083038186803b158015613c7e57600080fd5b505afa158015613c92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cb69190614637565b90506000613cc7610ee28486611789565b9050676765c793fa10079d601b1b8104945080613cef86676765c793fa10079d601b1b611789565b10613cfa5784613cff565b846001015b9998505050505050505050565b600080846001600160a01b0316636c25b346856040518263ffffffff1660e01b8152600401613d3b9190614ac4565b60206040518083038186803b158015613d5357600080fd5b505afa158015613d67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d8b9190614637565b90506000856001600160a01b031663d9638d36856040518263ffffffff1660e01b8152600401613dbb9190614c9d565b60a06040518083038186803b158015613dd357600080fd5b505afa158015613de7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e0b9190614929565b5050509150506000866001600160a01b0316632424be5c86886040518363ffffffff1660e01b8152600401613e41929190614ca6565b604080518083038186803b158015613e5857600080fd5b505afa158015613e6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e909190614906565b915050613e9f82848161317257fe5b935080841115613eba57613eb281613a4e565b600003613ebf565b836000035b979650505050505050565b613ed2613f6f565b6001600160a01b0316826001600160a01b03161415613f4c57826001600160a01b031681604051613f0290614ac1565b60006040518083038185875af1925050503d8060008114613f3f576040519150601f19603f3d011682016040523d82523d6000602084013e613f44565b606091505b505050611784565b6117846001600160a01b038316848361172e565b6060610a5b8484600085613f87565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b6060613f928561404b565b613fae5760405162461bcd60e51b81526004016120bd90614d3c565b60006060866001600160a01b03168587604051613fcb9190614aa5565b60006040518083038185875af1925050503d8060008114614008576040519150601f19603f3d011682016040523d82523d6000602084013e61400d565b606091505b50915091508115614021579150610a5b9050565b8051156140315780518082602001fd5b8360405162461bcd60e51b81526004016120bd9190614cf2565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610a5b575050151592915050565b60405180610140016040528060006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016140fb614144565b905290565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b03168152602001600060018111156140fb57fe5b6040518060c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001606081525090565b803561088781614f04565b805161088781614f04565b600082601f8301126141bb578081fd5b81356141ce6141c982614eb0565b614e89565b91508082528360208285010111156141e557600080fd5b8060208401602084013760009082016020015292915050565b600082601f83011261420e578081fd5b815161421c6141c982614eb0565b915080825283602082850101111561423357600080fd5b614244816020840160208601614ed4565b5092915050565b80356002811061088757600080fd5b600061014080838503121561426d578182fd5b61427681614e89565b9150506142838383614195565b81526142928360208401614195565b602082015260408201356040820152606082013560608201526080820135608082015260a082013560a08201526142cc8360c08401614195565b60c08201526142de8360e08401614195565b60e08201526101008083013567ffffffffffffffff8082111561430057600080fd5b61430c868387016141ab565b8385015261012092508285013591508082111561432857600080fd5b5061433585828601614341565b82840152505092915050565b600060c08284031215614352578081fd5b61435c60c0614e89565b9050813561436981614f04565b8152602082013561437981614f04565b6020820152604082013561438c81614f04565b80604083015250606082013560608201526080820135608082015260a082013567ffffffffffffffff8111156143c157600080fd5b6143cd848285016141ab565b60a08301525092915050565b600060c082840312156143ea578081fd5b6143f460c0614e89565b9050815161440181614f04565b8152602082015161441181614f04565b6020820152604082015161442481614f04565b80604083015250606082015160608201526080820151608082015260a082015167ffffffffffffffff81111561445957600080fd5b6143cd848285016141fe565b600060208284031215614476578081fd5b8135610ef681614f04565b600060208284031215614492578081fd5b8151610ef681614f04565b600080604083850312156144af578081fd5b82356144ba81614f04565b946020939093013593505050565b6000806000606084860312156144dc578081fd5b83356144e781614f04565b95602085013595506040909401359392505050565b60008060008060808587031215614511578182fd5b843561451c81614f04565b93506020850135925060408501359150606085013561453a81614f04565b939692955090935050565b60008060008060006080868803121561455c578283fd5b853561456781614f04565b94506020860135935060408601359250606086013567ffffffffffffffff80821115614591578283fd5b818801915088601f8301126145a4578283fd5b8135818111156145b2578384fd5b8960208285010111156145c3578384fd5b9699959850939650602001949392505050565b6000602082840312156145e7578081fd5b8151610ef681614f1c565b60008060408385031215614604578182fd5b825161460f81614f1c565b6020939093015192949293505050565b600060208284031215614630578081fd5b5035919050565b600060208284031215614648578081fd5b5051919050565b600060208284031215614660578081fd5b813567ffffffffffffffff811115614676578182fd5b610883848285016141ab565b60008060008060008060c0878903121561469a578384fd5b863567ffffffffffffffff8111156146b0578485fd5b6146bc89828a016141ab565b965050602087013594506040870135935060608701356146db81614f04565b925060808701356146eb81614f1c565b915060a087013560ff81168114614700578182fd5b809150509295509295509295565b600080604083850312156144af578182fd5b60008060408385031215614732578182fd5b825161460f81614f04565b60006020828403121561474e578081fd5b610ef6838361424b565b600060208284031215614769578081fd5b813567ffffffffffffffff81111561477f578182fd5b6108838482850161425a565b60006020828403121561479c578081fd5b815167ffffffffffffffff808211156147b3578283fd5b81840191506101408083870312156147c9578384fd5b6147d281614e89565b90506147de86846141a0565b81526147ed86602085016141a0565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201526148278660c085016141a0565b60c08201526148398660e085016141a0565b60e08201526101008084015183811115614851578586fd5b61485d888287016141fe565b8284015250506101208084015183811115614876578586fd5b614882888287016143d9565b918301919091525095945050505050565b600080600080600060a086880312156148aa578283fd5b853567ffffffffffffffff8111156148c0578384fd5b6148cc8882890161425a565b955050602086013593506040860135925060608601356148eb81614f04565b91506148fa876080880161424b565b90509295509295909350565b60008060408385031215614918578182fd5b505080516020909101519092909150565b600080600080600060a08688031215614940578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b6001600160a01b03169052565b6000815180845261498d816020860160208601614ed4565b601f01601f19169290920160200192915050565b60006101406149b1848451614968565b60208301516149c36020860182614968565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c08301516149fe60c0860182614968565b5060e0830151614a1160e0860182614968565b50610100808401518282870152614a2a83870182614975565b925050506101208084015185830382870152614a468382614a50565b9695505050505050565b600060018060a01b0380835116845280602084015116602085015280604084015116604085015250606082015160608401526080820151608084015260a082015160c060a085015261088360c0850182614975565b60008251614ab7818460208701614ed4565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c1350d1119b185cda109bdbdcdd609a1b60a082015260c060608201819052600090614b4390830184614975565b95945050505050565b6001600160a01b03848116825283166020820152608060408201819052600890820152671350d1109bdbdcdd60c21b60a082015260c060608201819052600090614b4390830184614975565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c4d4344466c617368526570617960981b60a082015260c060608201819052600090614b4390830184614975565b6001600160a01b03848116825283166020820152608060408201819052600890820152674d4344526570617960c01b60a082015260c060608201819052600090614b4390830184614975565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614a4690830184614975565b6001600160a01b0392909216825260ff16602082015260400190565b90815260200190565b9182526001600160a01b0316602082015260400190565b9586526001600160a01b039485166020870152928416604086015292166060840152608083019190915260a082015260c00190565b600060208252610ef66020830184614975565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600c908201526b696e742d6f766572666c6f7760a01b604082015260600190565b600060208252610ef660208301846149a1565b600060408252614e0960408301856149a1565b905060028310614e1557fe5b8260208301529392505050565b9283526001600160a01b03919091166020830152604082015260600190565b9384526001600160a01b039290921660208401526040830152606082015260800190565b9283526020830191909152604082015260600190565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715614ea857600080fd5b604052919050565b600067ffffffffffffffff821115614ec6578081fd5b50601f01601f191660200190565b60005b83811015614eef578181015183820152602001614ed7565b83811115614efe576000848401525b50505050565b6001600160a01b0381168114614f1957600080fd5b50565b8015158114614f1957600080fdfea2646970667358221220a82338d1bbe4f0433c35fa0219f01fc6d69e0309bf732ee2e41e7e83efdb33b264736f6c634300060c0033
Deployed Bytecode Sourcemap
54051:4503:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40244:48;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28680:134;;;;;;;;;;-1:-1:-1;28680:134:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;40313:100::-;;;;;;;;;;;;;:::i;24375:122::-;;;;;;;;;;-1:-1:-1;24375:122:0;;;;;:::i;:::-;;:::i;:::-;;33987:56;;;;;;;;;;;;;:::i;29315:86::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;40779:80::-;;;;;;;;;;;;;:::i;41081:58::-;;;;;;;;;;;;;:::i;15116:186::-;;;;;;;;;;-1:-1:-1;15116:186:0;;;;;:::i;:::-;;:::i;29711:92::-;;;;;;;;;;;;;:::i;49673:210::-;;;;;;;;;;-1:-1:-1;49673:210:0;;;;;:::i;:::-;;:::i;40966:42::-;;;;;;;;;;;;;:::i;24670:285::-;;;;;;;;;;-1:-1:-1;24670:285:0;;;;;:::i;:::-;;:::i;14607:357::-;;;;;;;;;;-1:-1:-1;14607:357:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;24543:80::-;;;;;;;;;;;;;:::i;34196:72::-;;;;;;;;;;;;;:::i;40179:45::-;;;;;;;;;;;;;:::i;15431:336::-;;;;;;;;;;-1:-1:-1;15431:336:0;;;;;:::i;:::-;;:::i;40868:89::-;;;;;;;;;;;;;:::i;29408:90::-;;;;;;;;;;;;;:::i;49229:357::-;;;;;;;;;;-1:-1:-1;49229:357:0;;;;;:::i;:::-;;:::i;29812:87::-;;;;;;;;;;;;;:::i;23301:20::-;;;;;;;;;;;;;:::i;54138:142::-;;;;;;;;;;;;;:::i;29507:103::-;;;;;;;;;;;;;:::i;28822:159::-;;;;;;;;;;-1:-1:-1;28822:159:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;29619:85::-;;;;;;;;;;;;;:::i;24154:122::-;;;;;;;;;;-1:-1:-1;24154:122:0;;;;;:::i;:::-;;:::i;40692:80::-;;;;;;;;;;;;;:::i;29198:74::-;;;;;;;;;;;;;:::i;41015:59::-;;;;;;;;;;;;;:::i;34050:70::-;;;;;;;;;;;;;:::i;52798:54::-;;;;;;;;;;;;;:::i;42644:1110::-;;;;;;:::i;:::-;;:::i;34127:62::-;;;;;;;;;;;;;:::i;48355:601::-;;;;;;;;;;-1:-1:-1;48355:601:0;;;;;:::i;:::-;;:::i;23871:161::-;;;;;;;;;;-1:-1:-1;23871:161:0;;;;;:::i;:::-;;:::i;41407:1083::-;;;;;;:::i;:::-;;:::i;54556:1203::-;;;;;;;;;;-1:-1:-1;54556:1203:0;;;;;:::i;:::-;;:::i;41148:100::-;;;;;;;;;;;;;:::i;23328:20::-;;;;;;;;;;;;;:::i;40244:48::-;40289:3;40244:48;:::o;28680:134::-;28755:12;28798:7;28787:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;28780:26;;28680:134;;;;:::o;40313:100::-;-1:-1:-1;;;40313:100:0;:::o;24375:122::-;24456:5;;-1:-1:-1;;;;;24456:5:0;24442:10;:19;24434:28;;;;;;24475:5;:14;;-1:-1:-1;;;;;;24475:14:0;-1:-1:-1;;;;;24475:14:0;;;;;;;;;;24375:122::o;33987:56::-;;;;;;;;;;;;;;-1:-1:-1;;;33987:56:0;;;;:::o;29315:86::-;29359:42;29315:86;:::o;40779:80::-;40817:42;40779:80;:::o;41081:58::-;40551:42;41081:58;:::o;15116:186::-;15186:7;15206:13;15238:8;-1:-1:-1;;;;;15238:13:0;;15252:6;15238:21;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15206:55;;15281:5;-1:-1:-1;;;;;15281:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15274:20;;;15116:186;;;;;:::o;29711:92::-;29761:42;29711:92;:::o;49673:210::-;49758:18;;-1:-1:-1;;;49758:18:0;;49726:4;;;;40551:42;;49758:12;;:18;;49771:4;;49758:18;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49805:14;;-1:-1:-1;;;49805:14:0;;49743:33;;-1:-1:-1;49790:9:0;;-1:-1:-1;40460:42:0;;49805:8;;:14;;49814:4;;49805:14;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49787:32;;;;;;49839:36;49844:25;49849:4;40551:42;-1:-1:-1;;;;;49855:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49844:4;:25::i;:::-;49871:3;49839:4;:36::i;:::-;49832:43;49673:210;-1:-1:-1;;;;49673:210:0:o;40966:42::-;40460;40966;:::o;24670:285::-;23397:5;;-1:-1:-1;;;;;23397:5:0;23406:10;23397:19;23389:28;;;;;;24770:42:::1;-1:-1:-1::0;;;;;24760:52:0;::::1;;24756:192;;;24837:5;::::0;;24829:32:::1;::::0;-1:-1:-1;;;;;24837:5:0;;::::1;::::0;24829:32;::::1;;;::::0;24853:7;;24829:32;24837:5;24829:32;24853:7;24837:5;24829:32;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;24756:192;;;24921:5;::::0;24894:42:::1;::::0;-1:-1:-1;;;;;24894:26:0;;::::1;::::0;24921:5:::1;24928:7:::0;24894:26:::1;:42::i;:::-;24670:285:::0;;:::o;14607:357::-;14693:4;14699;14716:11;14730:8;-1:-1:-1;;;;;14730:12:0;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14716:28;;14755:11;14769:8;-1:-1:-1;;;;;14769:13:0;;14783:6;14769:21;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14755:35;;14804:15;14821:9;14838:3;-1:-1:-1;;;;;14834:13:0;;14848:4;14854:3;14834:24;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14803:55;;;;14871:9;14891:3;-1:-1:-1;;;;;14887:13:0;;14901:4;14887:19;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14869:37;;;;;;14927:10;14939:16;14944:4;14950;14939;:16::i;:::-;14919:37;;;;;;;;;14607:357;;;;;;:::o;24543:80::-;23397:5;;-1:-1:-1;;;;;23397:5:0;23406:10;23397:19;23389:28;;;;;;24608:5:::1;::::0;-1:-1:-1;;;;;24608:5:0::1;24587:28;34196:72:::0;;;;;;;;;;;;;;-1:-1:-1;;;34196:72:0;;;;:::o;40179:45::-;40221:3;40179:45;:::o;15431:336::-;15502:7;;15526:12;:31;;;;;;;;;15522:238;;;-1:-1:-1;15581:42:0;15574:49;;15522:238;15661:21;15645:12;:37;;;;;;;;;15641:119;;;-1:-1:-1;15706:42:0;15699:49;;40868:89;40915:42;40868:89;:::o;29408:90::-;29456:42;29408:90;:::o;49229:357::-;49327:4;49344:10;49357:14;49366:4;49357:8;:14::i;:::-;49399:18;;-1:-1:-1;;;49399:18:0;;49344:27;;-1:-1:-1;49387:8:0;;40551:42;;49399:12;;:18;;49412:4;;49399:18;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49384:33;;;49429:15;49446:9;49459:47;49478:12;49493:6;49501:4;49459:10;:47::i;:::-;49428:78;;;;49526:52;49530:43;49534:32;49538:22;49542:10;49554:5;49538:3;:22::i;:::-;49562:3;49534;:32::i;:::-;49568:4;49530:3;:43::i;:::-;49575:2;49526:3;:52::i;:::-;49519:59;;;;;;49229:357;;;;;;:::o;29812:87::-;29857:42;29812:87;:::o;23301:20::-;;;-1:-1:-1;;;;;23301:20:0;;:::o;54138:142::-;;;-1:-1:-1;;;;;54138:142:0;;:::o;29507:103::-;29567:42;29507:103;:::o;28822:159::-;28890:27;;:::i;:::-;28951:5;28940:33;;;;;;;;;;;;:::i;29619:85::-;29662:42;29619:85;:::o;24154:122::-;24235:5;;-1:-1:-1;;;;;24235:5:0;24221:10;:19;24213:28;;;;;;24254:5;:14;;-1:-1:-1;;;;;;24254:14:0;-1:-1:-1;;;;;24254:14:0;;;;;;;;;;24154:122::o;40692:80::-;40730:42;40692:80;:::o;29198:74::-;;;;;;;;;;;;;;-1:-1:-1;;;29198:74:0;;;;:::o;41015:59::-;40643:42;41015:59;:::o;34050:70::-;;;;;;;;;;;;;;-1:-1:-1;;;34050:70:0;;;;:::o;52798:54::-;;;-1:-1:-1;;;;;52798:54:0;;:::o;42644:1110::-;42847:19;42869:28;42884:12;42869:14;:28::i;:::-;42847:50;;42910:12;42925:38;42942:11;42956:6;42925:8;:38::i;:::-;42910:53;;42974:11;42996;-1:-1:-1;;;;;42988:25:0;;43014:6;42988:33;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42974:47;;43034:13;43050:58;43058:11;43071:6;43079:3;43084:13;:23;;;43050:7;:58::i;:::-;-1:-1:-1;;;;;43121:25:0;;:18;;;:25;43034:74;-1:-1:-1;43187:14:0;:12;:14::i;:::-;:59;;40221:3;43187:59;;;40289:3;43187:59;43157:27;;;:89;43294:27;43302:8;43312;43294:7;:27::i;:::-;43283:38;;43257:23;;;:64;43335:15;43354:20;43257:13;43354:5;:20::i;:::-;43332:42;;;43387:57;43401:11;43414:6;43422:9;43433:10;43387:13;:57::i;:::-;43527:21;:25;43523:99;;43569:41;;:9;;43588:21;43569:41;;;;;;;;;43588:21;43569:9;:41;;;;;;;;;;;;;;;;;;;;;43523:99;41205:42;-1:-1:-1;;;;;43634:10:0;;43653:4;43660:10;43695:6;43703:4;43709:13;:23;;;43734:10;43684:61;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;43634:112;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42644:1110;;;;;;;;;;:::o;34127:62::-;;;;;;;;;;;;;;-1:-1:-1;;;34127:62:0;;;;:::o;48355:601::-;48470:4;48487:10;48500:14;48509:4;48500:8;:14::i;:::-;48487:27;;48528:15;48545:9;48558:47;48577:12;48592:6;48600:4;48558:10;:47::i;:::-;48633:35;;-1:-1:-1;;;48633:35:0;;48527:78;;-1:-1:-1;48527:78:0;-1:-1:-1;48621:8:0;;40551:42;;48633:29;;:35;;48663:4;;48633:35;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48618:50;;;48681:18;48702:45;48706:10;48719:26;48723:14;48727:3;48732:4;48723:3;:14::i;:::-;48739:5;48719:3;:26::i;:::-;48702:3;:45::i;:::-;48681:66;;48760:27;48824:9;-1:-1:-1;;;;;48819:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48814:2;:26;48807:2;:34;48790:13;:52;;;;;;;-1:-1:-1;48945:3:0;48940:2;48915:27;;:33;48908:40;;;;;;;;48355:601;;;;;;:::o;23871:161::-;23952:5;;-1:-1:-1;;;;;23952:5:0;23938:10;:19;23930:28;;;;;;23977:5;;-1:-1:-1;;;;;23977:5:0;:19;23969:28;;;;;41407:1083;41610:19;41632:28;41647:12;41632:14;:28::i;:::-;41610:50;;41673:12;41688:38;41705:11;41719:6;41688:8;:38::i;:::-;41673:53;;41737:11;41759;-1:-1:-1;;;;;41751:25:0;;41777:6;41751:33;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41737:47;;41797:71;41812:11;41825:6;41833:9;41844:13;:23;;;41797:14;:71::i;:::-;-1:-1:-1;;;;;;41881:25:0;;:18;;;:25;41947:14;:12;:14::i;:::-;:59;;40221:3;41947:59;;;40289:3;41947:59;41917:27;;;:89;42020:14;42038:20;41917:13;42038:5;:20::i;:::-;42017:41;;;42084:28;42092:8;42102:9;42084:7;:28::i;:::-;42071:41;;42125:54;42137:11;42150:6;42158:3;42071:41;42174:4;42125:11;:54::i;:::-;42262:21;:25;42258:99;;42304:41;;:9;;42323:21;42304:41;;;;;;;;;42323:21;42304:9;:41;;;;;;;;;;;;;;;;;;;;;42258:99;41205:42;-1:-1:-1;;;;;42369:10:0;;42388:4;42395:10;42430:6;42438:4;42444:13;:23;;;42469:9;42419:60;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;42369:111;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41407:1083;;;;;;;;;:::o;54556:1203::-;54743:24;54782:10;;;;;54933:63;;;;54944:7;54933:63;:::i;:::-;54728:268;;;;;;;;;;;;55009:32;;:::i;:::-;55044:31;55063:11;55044:18;:31::i;:::-;55009:66;;55088:26;;:::i;:::-;55117:223;;;;;;;;55149:5;55117:223;;;;55178:7;55117:223;;;;55212:7;55117:223;;;;55239:4;55117:223;;;;55268:8;-1:-1:-1;;;;;55117:223:0;;;;;55316:11;55304:24;;;;;;;;;;55117:223;;;;;;;;;;55088:252;-1:-1:-1;55353:149:0;;;;55381:38;55395:12;55409:9;55381:13;:38::i;:::-;55353:149;;;55452:38;55466:12;55480:9;55452:13;:38::i;:::-;55514:60;55546:8;55556:17;:7;55568:4;55556:11;:17::i;:::-;55514:31;:60::i;:::-;55657:21;:25;55653:99;;55699:41;;:9;;55718:21;55699:41;;;;;;;;;55718:21;55699:9;:41;;;;;;;;;;;;;;;;;;;41148:100;41205:42;41148:100;:::o;23328:20::-;;;-1:-1:-1;;;;;23328:20:0;;:::o;5410:122::-;5469:9;-1:-1:-1;;;5495:23:0;5499:9;5503:1;5506;5499:3;:9::i;:::-;5516:1;-1:-1:-1;;;5510:7:0;;5495:3;:23::i;:::-;:29;;;;;;;5410:122;-1:-1:-1;;;5410:122:0:o;21347:176::-;21429:86;21449:5;21479:23;;;21504:2;21508:5;21456:58;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;21456:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;21456:58:0;-1:-1:-1;;;;;;21456:58:0;;;;;;;;;;21429:19;:86::i;:::-;21347:176;;;:::o;4499:127::-;4557:9;4587:6;;;:30;;-1:-1:-1;;4602:5:0;;;4616:1;4611;4602:5;4611:1;4597:15;;;;;:20;4587:30;4579:39;;;;;4634:100;4692:9;4725:1;4721;:5;;;;4378:113;4471:5;;;4466:16;;;;4458:25;;;;;44052:819;44182:27;;-1:-1:-1;;;44182:27:0;;44153:4;;;;40730:42;;44182:21;;:27;;44204:4;;44182:27;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44170:39;;44220:18;40460:42;-1:-1:-1;;;;;44241:7:0;;44257:12;-1:-1:-1;;;;;44249:26:0;;44276:6;44249:34;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44241:43;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44220:64;;44297:14;44314:38;44325:12;44339:6;44347:4;44314:10;:38::i;:::-;44297:55;;44383:9;44369:10;:23;44365:86;;44422:17;44426:9;44437:1;44422:3;:17::i;:::-;44409:30;;44365:86;44471:12;-1:-1:-1;;;;;44463:26:0;;44490:6;44502:1;44506:52;44526:10;44538:4;44544:13;44506:19;:52::i;:::-;44463:96;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44578:12;-1:-1:-1;;;;;44570:26:0;;44597:6;44613:4;44620:17;44626:10;44620:5;:17::i;:::-;44570:68;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44655:49:0;;-1:-1:-1;;;44655:49:0;;40460:42;;-1:-1:-1;44655:7:0;;-1:-1:-1;44655:49:0;;44671:4;;40643:42;;44655:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44651:113;;44726:26;;-1:-1:-1;;;44726:26:0;;40460:42;;44726:8;;:26;;40643:42;;44726:26;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44651:113;44776:57;;-1:-1:-1;;;44776:57:0;;40643:42;;44776:30;;:57;;44815:4;;44822:10;;44776:57;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44853:10:0;;44052:819;-1:-1:-1;;;;;;;;;;44052:819:0:o;49891:130::-;49961:52;;-1:-1:-1;;;49961:52:0;;49937:4;;40915:42;;49961:41;;:52;;50003:9;;49961:52;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49954:59;;49891:130;:::o;50029:518::-;50095:4;50116:12;;50112:407;;50145:16;50164:17;-1:-1:-1;;;50164:8:0;:17::i;:::-;50145:36;;50196:14;50213:27;50218:8;50228:11;50213:4;:27::i;:::-;50196:44;-1:-1:-1;50283:1:0;50273:7;:11;50261:9;:23;50257:87;;;-1:-1:-1;50327:1:0;50317:11;;50257:87;50360:18;29567:42;-1:-1:-1;;;;;50381:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50424:50;;-1:-1:-1;;;50424:50:0;;50360:47;;-1:-1:-1;40817:42:0;;50424:27;;:50;;50360:47;;50464:9;;50424:50;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;50498:9;50491:16;;;;;;;50112:407;-1:-1:-1;50538:1:0;50029:518;;;;:::o;34539:1670::-;34600:7;34609:4;34628:15;34654:17;34682:12;29359:42;-1:-1:-1;;;;;34755:35:0;:6;:14;;;-1:-1:-1;;;;;34755:35:0;;34751:201;;;34838:14;;34824:29;;:13;:29::i;:::-;-1:-1:-1;;;;;34807:46:0;;;34921:16;;;;;34868:72;;-1:-1:-1;;;34868:72:0;;;;29456:42;;34868:45;;34921:16;34868:72;;;;;34807:14;;34868:72;;;;;;;34921:16;29456:42;34868:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34751:201;34984:75;34991:6;:16;;;35009:6;:11;;;35022:6;:14;;;35038:6;:20;;;34984:6;:75::i;:::-;34964:16;;;:95;;;;;;;;35139:19;;;;:25;;;:29;35135:228;;35211:34;35221:6;35229:15;35211:9;:34::i;:::-;35185:60;-1:-1:-1;35185:60:0;-1:-1:-1;35262:90:0;;;;35304:6;:19;;;:32;;;35294:42;;35262:90;35433:7;35428:129;;35472:34;35482:6;35490:15;35472:9;:34::i;:::-;35457:49;;35531:6;:14;;;35521:24;;35428:129;35673:1;35637:33;29456:42;35637:10;:33::i;:::-;:37;35633:212;;;35756:62;;-1:-1:-1;;;35756:62:0;;29456:42;;35691:46;;29456:42;;35756:47;;:62;;35812:4;;35756:62;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35691:142;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35633:212;35861:15;;;;-1:-1:-1;;;;;35861:40:0;29456:42;35861:40;35857:302;;;35959:39;35964:6;:15;;;35981:6;:16;;;35959:4;:39::i;:::-;35926:29;29359:42;35926:10;:29::i;:::-;:72;;36000:16;;;;;;;;;;;;;-1:-1:-1;;;36000:16:0;;;35918:99;;;;;-1:-1:-1;;;35918:99:0;;;;;;;;:::i;:::-;;;;;;;;;;35857:302;;;36089:39;36094:6;:15;;;36111:6;:16;;;36089:4;:39::i;:::-;36058:27;36069:6;:15;;;36058:10;:27::i;:::-;:70;;36130:16;;;;;;;;;;;;;-1:-1:-1;;;36130:16:0;;;36050:97;;;;;-1:-1:-1;;;36050:97:0;;;;;;;;:::i;:::-;;35857:302;-1:-1:-1;36179:7:0;;-1:-1:-1;36188:12:0;-1:-1:-1;34539:1670:0;;;:::o;45146:775::-;45257:17;45295:24;45309:9;45295:13;:24::i;:::-;45291:252;;;45341:9;-1:-1:-1;;;;;45336:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;45336:29:0;;45373:7;45336:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45414:22;45428:7;45414:13;:22::i;:::-;45398:38;;45291:252;;;45485:46;45499:31;45511:9;45522:7;45499:11;:31::i;:::-;45485:13;:46::i;:::-;45469:62;;45291:252;45555:69;45605:9;45616:7;45574:9;-1:-1:-1;;;;;45569:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;45555:49:0;;:69;:49;:69::i;:::-;45637:44;;-1:-1:-1;;;45637:44:0;;-1:-1:-1;;;;;45637:20:0;;;;;:44;;45666:4;;45673:7;;45637:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;45717:34:0;;-1:-1:-1;;;45717:34:0;;40460:42;;-1:-1:-1;45694:8:0;;-1:-1:-1;;;;;;45717:26:0;;;;;:34;;45744:6;;45717:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45766;;-1:-1:-1;;;45766:34:0;;-1:-1:-1;;;;;45766:26:0;;;;;:34;;45793:6;;45766:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45823:4;45851;45871:13;45899:1;45694:217;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45146:775;;;;;:::o;46282:648::-;46392:4;46409:15;46427:7;46409:25;;46456:9;-1:-1:-1;;;;;46451:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46476:2;46451:27;46447:119;;46536:9;-1:-1:-1;;;;;46531:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46526:2;:26;46519:2;:34;46508:7;:46;46495:59;;46447:119;46586:12;-1:-1:-1;;;;;46578:26:0;;46605:6;46614:25;46628:10;46614:13;:25::i;:::-;46613:26;;46641:1;46578:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;46654:61:0;;-1:-1:-1;;;46654:61:0;;-1:-1:-1;;;;;46654:26:0;;;-1:-1:-1;46654:26:0;;-1:-1:-1;46654:61:0;;46681:6;;46697:4;;46704:10;;46654:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;46728:44:0;;-1:-1:-1;;;46728:44:0;;-1:-1:-1;;;;;46728:20:0;;;-1:-1:-1;46728:20:0;;-1:-1:-1;46728:44:0;;46757:4;;46764:7;;46728:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46789:24;46803:9;46789:13;:24::i;:::-;46785:111;;;46835:9;-1:-1:-1;;;;;46830:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;46830:30:0;;46861:7;46830:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46785:111;-1:-1:-1;46915:7:0;;46282:648;-1:-1:-1;;;;46282:648:0:o;47306:720::-;47443:34;;-1:-1:-1;;;47443:34:0;;47429:11;;-1:-1:-1;;;;;47443:26:0;;;;;:34;;47470:6;;47443:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47429:48;;47490:14;47507:39;40460:42;47531:3;47536;47541:4;47507:10;:39::i;:::-;47490:56;;47576:9;47563:10;:22;47559:155;;;40817:42;47602:27;47630:6;47638:26;47642:10;47654:9;47638:3;:26::i;:::-;47602:63;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;47693:9;47680:22;;47559:155;47730:61;;-1:-1:-1;;;47730:61:0;;40817:42;;47730:28;;:61;;47767:4;;40643:42;;47730:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47726:153;;47813:54;;-1:-1:-1;;;47813:54:0;;40817:42;;47813:26;;:54;;40643:42;;-1:-1:-1;;47863:2:0;47813:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;47726:153;47891:29;;-1:-1:-1;;;47891:29:0;;40643:42;;47891:12;;:29;;47904:3;;47909:10;;47891:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47941:12;-1:-1:-1;;;;;47933:26:0;;47960:6;47968:1;47971:46;40460:42;48007:3;48012:4;47971:22;:46::i;:::-;47933:85;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47306:720;;;;;;;:::o;57104:1359::-;57238:19;57260:38;57275:10;:22;;;57260:14;:38::i;:::-;57238:60;;57311:12;57326:48;57343:11;57357:10;:16;;;57326:8;:48::i;:::-;57425:16;;57399:43;;-1:-1:-1;;;57399:43:0;;57311:63;;-1:-1:-1;57385:11:0;;-1:-1:-1;;;;;57399:25:0;;;;;:43;;57425:16;57399:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57385:57;;57483:12;57498:73;57515:11;57528:10;:16;;;57546:3;57551:10;:19;;;57498:16;:73::i;:::-;57483:88;;57582:14;57599:75;57614:11;57627:10;:16;;;57645:10;:19;;;57666:7;57599:14;:75::i;:::-;57731:21;;;;;:33;;57704:23;;;:61;-1:-1:-1;;;;;57776:25:0;;:18;;;:25;57582:92;-1:-1:-1;57842:14:0;:12;:14::i;:::-;:59;;40221:3;57842:59;;;40289:3;57842:59;57812:27;;;:89;57915:18;57937:20;57812:13;57937:5;:20::i;:::-;57912:45;;;57987:42;57995:10;:18;;;58015:13;57987:7;:42::i;:::-;58096:16;;57970:59;;;58071:68;;58083:11;;58114:3;57970:59;58134:4;58071:11;:68::i;:::-;58204:108;58219:11;58232:10;:16;;;58250:10;:19;;;58296:10;:14;;;58272:10;:21;;;:38;58204:14;:108::i;:::-;;41205:42;-1:-1:-1;;;;;58325:10:0;;58344:4;58351:10;58391;:16;;;58409:4;58415:13;:23;;;58440:13;58380:74;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;58325:130;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57104:1359;;;;;;;;:::o;55767:1329::-;55901:19;55923:38;55938:10;:22;;;55923:14;:38::i;:::-;55901:60;;55974:12;55989:48;56006:11;56020:10;:16;;;55989:8;:48::i;:::-;56116:16;;56134:43;;-1:-1:-1;;;56134:43:0;;55974:63;;-1:-1:-1;56077:12:0;;56092:86;;56103:11;;-1:-1:-1;;;;;56134:25:0;;;;;:43;;56116:16;;56134:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;56092:86::-;56226:16;;56244:43;;-1:-1:-1;;;56244:43:0;;56077:101;;-1:-1:-1;56189:13:0;;56205:92;;56213:11;;-1:-1:-1;;;;;56244:25:0;;;;;:43;;56226:16;;56244:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56289:7;56205;:92::i;:::-;56189:108;;56388:61;56396:10;:18;;;56427:10;:21;;;56416:8;:32;56388:7;:61::i;:::-;56364:21;;;;;56353:32;;:96;;;;56327:23;;;:122;-1:-1:-1;;;;;56460:25:0;;:18;;;:25;56526:14;:12;:14::i;:::-;:59;;40221:3;56526:59;;;40289:3;56526:59;56496:27;;;:89;56599:17;56620:20;56496:13;56620:5;:20::i;:::-;56596:44;;;56683:79;56697:11;56710:10;:16;;;56728:10;:19;;;56749:12;56683:13;:79::i;:::-;56841:16;;56860:43;;-1:-1:-1;;;56860:43:0;;56820:126;;56828:11;;-1:-1:-1;;;;;56860:25:0;;;;;:43;;56841:16;;56860:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56930:10;:14;;;56906:10;:21;;;:38;56820:7;:126::i;:::-;;41205:42;-1:-1:-1;;;;;56959:10:0;;56978:4;56985:10;57025;:16;;;57043:4;57049:13;:23;;;57074:12;57014:73;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;56959:129;;;;;;;;;;;;;;;;;:::i;19509:181::-;19567:7;19599:5;;;19623:6;;;;19615:46;;;;-1:-1:-1;;;19615:46:0;;;;;;;:::i;53023:220::-;53144:17;;:38;;;-1:-1:-1;;;53144:38:0;;;;53121:20;;-1:-1:-1;;;;;53144:17:0;;:36;;:38;;;;;;;;;;;;;;:17;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53121:61;;53195:40;53212:4;53217:8;53227:7;53195:16;:40::i;4257:113::-;4350:5;;;4345:16;;;;4337:25;;;;;22816:419;22898:23;22924:69;22952:4;22924:69;;;;;;;;;;;;;;;;;22932:5;-1:-1:-1;;;;;22924:27:0;;;:69;;;;;:::i;:::-;23008:17;;22898:95;;-1:-1:-1;23008:21:0;23004:224;;23150:10;23139:30;;;;;;;;;;;;:::i;:::-;23131:85;;;;-1:-1:-1;;;23131:85:0;;;;;;;:::i;11249:344::-;11348:8;11390:17;11394:7;-1:-1:-1;;;11390:3:0;:17::i;:::-;11373:14;:34;11369:217;;;11431:61;11486:5;11445:38;11449:17;11453:7;-1:-1:-1;;;11449:3:0;:17::i;:::-;11468:14;11445:3;:38::i;:::-;:46;;;;;;11431:13;:61::i;:::-;11424:68;;11539:17;11543:7;-1:-1:-1;;;11539:3:0;:17::i;:::-;11514:22;11523:4;11530:5;11514:3;:22::i;:::-;:42;:60;;11570:4;11514:60;;;11566:1;11559:8;;11507:67;-1:-1:-1;;;11249:344:0:o;11708:100::-;11757:4;11781:19;11785:4;-1:-1:-1;;;11781:3:0;:19::i;32885:151::-;32945:7;-1:-1:-1;;;;;32972:25:0;;29359:42;32972:25;:56;;33024:4;32972:56;;;-1:-1:-1;29456:42:0;;32885:151;-1:-1:-1;32885:151:0:o;31199:905::-;31305:17;31339:19;;;;;:71;;-1:-1:-1;31362:48:0;;-1:-1:-1;;;31362:48:0;;29662:42;;31362:41;;:48;;31404:5;;31362:48;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31335:174;;;31444:53;;-1:-1:-1;;;31444:53:0;;29662:42;;31444:46;;:53;;31491:5;;31444:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31427:70;;31335:174;31525:19;31521:576;;-1:-1:-1;31573:1:0;31521:576;;;31629:14;31619:7;:24;;;;;;;-1:-1:-1;31745:2:0;31735:7;:12;31722:9;:26;31718:91;;;-1:-1:-1;31791:2:0;31781:12;;31718:91;31825:18;29567:42;-1:-1:-1;;;;;31846:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31825:47;-1:-1:-1;;;;;;31893:27:0;;29359:42;31893:27;31889:197;;;31941:39;;-1:-1:-1;;;;;31941:28:0;;;:39;;;;;31970:9;;31941:39;;;;31970:9;31941:28;:39;;;;;;;;;;;;;;;;;;;;;31889:197;;;32021:49;-1:-1:-1;;;;;32021:26:0;;32048:10;32060:9;32021:26;:49::i;:::-;31521:576;31199:905;;;;;;:::o;38252:692::-;38442:20;;;;:33;;;38399:77;;-1:-1:-1;;;38399:77:0;;38360:12;;;;29857:42;;38399;;:77;;38442:33;38399:77;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38394:128;;-1:-1:-1;38501:5:0;;-1:-1:-1;38501:5:0;38493:17;;38394:128;38596:20;;;;:28;38539:86;;-1:-1:-1;;;38539:86:0;;29761:42;;38539:56;;:86;;38596:28;38539:86;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38534:137;;-1:-1:-1;38650:5:0;;-1:-1:-1;38650:5:0;38642:17;;38534:137;38747:20;;;;:28;38777:17;;;;38717:15;;38711:84;;-1:-1:-1;;;;;38711:35:0;;;;;:84::i;:::-;38840:20;;;;:28;;38887:32;;;;;38815:121;;-1:-1:-1;;;38815:121:0;;-1:-1:-1;;;;;38815:64:0;;;;;;38887:32;38815:121;;38840:7;;38930:5;;38815:121;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38808:128;;;;38252:692;;;;;;:::o;39210:717::-;39389:15;;;;39332:73;;-1:-1:-1;;;39332:73:0;;39294:17;;29761:42;;39332:56;;:73;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39407:19;;;;;;;;;;;;;-1:-1:-1;;;39407:19:0;;;39324:103;;;;;-1:-1:-1;;;39324:103:0;;;;;;;;:::i;:::-;-1:-1:-1;39476:15:0;;;;39493:17;;;;39446:15;;39440:71;;-1:-1:-1;;;;;39440:35:0;;;;;:71::i;:::-;39537:15;39528:5;:24;;;;;;;;;39524:396;;;39604:7;:15;;;-1:-1:-1;;;;;39584:63:0;;39648:7;:15;;;39665:7;:16;;;39683:7;:17;;;39702:7;:19;;;39584:138;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39569:153;;39524:396;;;39790:7;:15;;;-1:-1:-1;;;;;39770:62:0;;39833:7;:15;;;39850:7;:16;;;39868:7;:18;;;39888:7;:19;;;39770:138;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;30092:275::-;30155:12;-1:-1:-1;;;;;30184:31:0;;29359:42;30184:31;30180:180;;;-1:-1:-1;30242:21:0;30180:180;;;30306:42;;-1:-1:-1;;;30306:42:0;;-1:-1:-1;;;;;30306:27:0;;;;;:42;;30342:4;;30306:42;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;5280:122::-;5339:9;5229:6;5365:23;5369:9;5373:1;5376;5369:3;:9::i;:::-;5386:1;5229:6;5380:7;;13998:436;14063:4;14162:42;-1:-1:-1;;;;;14149:55:0;;;14145:73;;;-1:-1:-1;14213:5:0;14206:12;;14145:73;14299:9;-1:-1:-1;;;;;14294:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;14286:76:0;14320:42;-1:-1:-1;;;;;14286:76:0;;14282:120;;;-1:-1:-1;14386:4:0;14379:11;;14282:120;-1:-1:-1;14421:5:0;13998:436;;;:::o;12255:134::-;12336:2;12310:5;12358:6;;;12350:31;;;;-1:-1:-1;;;12350:31:0;;;;;;;:::i;11979:163::-;12059:7;12086:48;12090:7;12116:9;-1:-1:-1;;;;;12111:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12106:2;:26;12099:2;:34;12086:3;:48::i;21896:281::-;21982:86;22002:5;22032:22;;;22056:7;22065:1;22009:58;;;;;;;;;:::i;21982:86::-;22079:90;22099:5;22129:22;;;22153:7;22162:5;22106:62;;;;;;;;;:::i;13182:424::-;13281:14;13311:9;13331:4;-1:-1:-1;;;;;13327:14:0;;13342:4;13327:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13308:39;;;;;;13361:8;13377:4;-1:-1:-1;;;;;13373:14:0;;13388:4;13394;13373:26;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13358:41;;;13410:8;13425:4;-1:-1:-1;;;;;13421:13:0;;13435:4;13421:19;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13410:30;;13453:8;13464:24;13468:14;13472:3;13477:4;13468:3;:14::i;13464:24::-;13453:35;-1:-1:-1;;;;13453:35:0;13511:9;13499:21;;13567:3;13545:19;13549:9;-1:-1:-1;;;13545:3:0;:19::i;:::-;:25;:53;;13589:9;13545:53;;;13573:9;13585:1;13573:13;13545:53;13533:65;13182:424;-1:-1:-1;;;;;;;;;13182:424:0:o;12580:382::-;12677:10;12700:8;12715:4;-1:-1:-1;;;;;12711:13:0;;12725:4;12711:19;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12700:30;;12746:9;12766:4;-1:-1:-1;;;;;12762:14:0;;12777:4;12762:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12743:39;;;;;;12796:8;12812:4;-1:-1:-1;;;;;12808:14:0;;12823:4;12829;12808:26;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12793:41;;;12856:25;12876:4;12870:3;:10;;;;12856:25;12847:34;;12917:3;12906:6;12901:19;;:53;;12936:18;12950:3;12936:13;:18::i;:::-;12934:20;;12901:53;;;12925:6;12923:8;;12901:53;12892:62;12580:382;-1:-1:-1;;;;;;;12580:382:0:o;53251:355::-;53378:26;:24;:26::i;:::-;-1:-1:-1;;;;;53366:38:0;:8;-1:-1:-1;;;;;53366:38:0;;53363:168;;;53461:12;-1:-1:-1;;;;;53461:17:0;53486:7;53461:37;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53513:7;;53363:168;53543:51;-1:-1:-1;;;;;53543:28:0;;53572:12;53586:7;53543:28;:51::i;17740:196::-;17843:12;17875:53;17898:6;17906:4;17912:1;17915:12;17875:22;:53::i;52532:121::-;52603:42;52532:121;:::o;18502:979::-;18632:12;18665:18;18676:6;18665:10;:18::i;:::-;18657:60;;;;-1:-1:-1;;;18657:60:0;;;;;;;:::i;:::-;18791:12;18805:23;18832:6;-1:-1:-1;;;;;18832:11:0;18852:8;18863:4;18832:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18790:78;;;;18883:7;18879:595;;;18914:10;-1:-1:-1;18907:17:0;;-1:-1:-1;18907:17:0;18879:595;19028:17;;:21;19024:439;;19291:10;19285:17;19352:15;19339:10;19335:2;19331:19;19324:44;19239:148;19434:12;19427:20;;-1:-1:-1;;;19427:20:0;;;;;;;;:::i;16527:619::-;16587:4;17055:20;;16898:66;17095:23;;;;;;:42;;-1:-1:-1;;17122:15:0;;;16527:619;-1:-1:-1;;16527:619:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5:130::-;72:20;;97:33;72:20;97:33;:::i;142:134::-;220:13;;238:33;220:13;238:33;:::i;1496:440::-;;1597:3;1590:4;1582:6;1578:17;1574:27;1564:2;;-1:-1;;1605:12;1564:2;1652:6;1639:20;1674:64;1689:48;1730:6;1689:48;:::i;:::-;1674:64;:::i;:::-;1665:73;;1758:6;1751:5;1744:21;1862:3;1794:4;1853:6;1786;1844:16;;1841:25;1838:2;;;1879:1;;1869:12;1838:2;52165:6;1794:4;1786:6;1782:17;1794:4;1820:5;1816:16;52142:30;52221:1;52203:16;;;1794:4;52203:16;52196:27;1820:5;1557:379;-1:-1;;1557:379::o;1945:442::-;;2057:3;2050:4;2042:6;2038:17;2034:27;2024:2;;-1:-1;;2065:12;2024:2;2105:6;2099:13;2127:64;2142:48;2183:6;2142:48;:::i;2127:64::-;2118:73;;2211:6;2204:5;2197:21;2315:3;2247:4;2306:6;2239;2297:16;;2294:25;2291:2;;;2332:1;;2322:12;2291:2;2342:39;2374:6;2247:4;2273:5;2269:16;2247:4;2239:6;2235:17;2342:39;:::i;:::-;;2017:370;;;;:::o;2908:162::-;2991:20;;53789:1;53779:12;;53769:2;;53805:1;;53795:12;3119:1898;;3238:6;;3226:9;3221:3;3217:19;3213:32;3210:2;;;-1:-1;;3248:12;3210:2;3276:22;3238:6;3276:22;:::i;:::-;3267:31;;;3383:49;3428:3;3404:22;3383:49;:::i;:::-;3365:16;3358:75;3531:49;3576:3;3498:2;3556:9;3552:22;3531:49;:::i;:::-;3498:2;3517:5;3513:16;3506:75;3647:2;3705:9;3701:22;9671:20;3647:2;3666:5;3662:16;3655:75;3797:2;3855:9;3851:22;9671:20;3797:2;3816:5;3812:16;3805:75;3945:3;4004:9;4000:22;9671:20;3945:3;3965:5;3961:16;3954:75;4099:3;4158:9;4154:22;9671:20;4099:3;4119:5;4115:16;4108:75;4278:49;4323:3;4244;4303:9;4299:22;4278:49;:::i;:::-;4244:3;4264:5;4260:16;4253:75;4426:49;4471:3;4392;4451:9;4447:22;4426:49;:::i;:::-;4392:3;4412:5;4408:16;4401:75;4572:3;;4561:9;4557:19;4544:33;4597:18;;4589:6;4586:30;4583:2;;;3351:1;;4619:12;4583:2;4666:58;4720:3;4711:6;4700:9;4696:22;4666:58;:::i;:::-;4572:3;4650:5;4646:18;4639:86;4822:3;;;;4811:9;4807:19;4794:33;4780:47;;4597:18;4839:6;4836:30;4833:2;;;3351:1;;4869:12;4833:2;;4916:79;4991:3;4982:6;4971:9;4967:22;4916:79;:::i;:::-;4822:3;4900:5;4896:18;4889:107;;;3204:1813;;;;:::o;7120:1179::-;;7239:4;7227:9;7222:3;7218:19;7214:30;7211:2;;;-1:-1;;7247:12;7211:2;7275:20;7239:4;7275:20;:::i;:::-;7266:29;;85:6;72:20;97:33;124:5;97:33;:::i;:::-;7355:75;;7499:2;7553:22;;72:20;97:33;72:20;97:33;:::i;:::-;7499:2;7514:16;;7507:75;7654:2;7708:22;;72:20;97:33;72:20;97:33;:::i;:::-;7687:49;7654:2;7673:5;7669:16;7662:75;;7799:2;7857:9;7853:22;9671:20;7799:2;7818:5;7814:16;7807:75;7950:3;8009:9;8005:22;9671:20;7950:3;7970:5;7966:16;7959:75;8127:3;8116:9;8112:19;8099:33;8152:18;8144:6;8141:30;8138:2;;;-1:-1;;8174:12;8138:2;8219:58;8273:3;8264:6;8253:9;8249:22;8219:58;:::i;:::-;8127:3;8205:5;8201:16;8194:84;;7205:1094;;;;:::o;8348:1249::-;;8478:4;8466:9;8461:3;8457:19;8453:30;8450:2;;;-1:-1;;8486:12;8450:2;8514:20;8478:4;8514:20;:::i;:::-;8505:29;;226:6;220:13;238:33;265:5;238:33;:::i;:::-;8594:86;;8749:2;8814:22;;220:13;238:33;220:13;238:33;:::i;:::-;8749:2;8764:16;;8757:86;8915:2;8980:22;;220:13;238:33;220:13;238:33;:::i;:::-;8948:60;8915:2;8934:5;8930:16;8923:86;;9071:2;9140:9;9136:22;9819:13;9071:2;9090:5;9086:16;9079:86;9233:3;9303:9;9299:22;9819:13;9233:3;9253:5;9249:16;9242:86;9414:3;9403:9;9399:19;9393:26;9439:18;9431:6;9428:30;9425:2;;;-1:-1;;9461:12;9425:2;9506:69;9571:3;9562:6;9551:9;9547:22;9506:69;:::i;10015:241::-;;10119:2;10107:9;10098:7;10094:23;10090:32;10087:2;;;-1:-1;;10125:12;10087:2;85:6;72:20;97:33;124:5;97:33;:::i;10263:263::-;;10378:2;10366:9;10357:7;10353:23;10349:32;10346:2;;;-1:-1;;10384:12;10346:2;226:6;220:13;238:33;265:5;238:33;:::i;10819:366::-;;;10940:2;10928:9;10919:7;10915:23;10911:32;10908:2;;;-1:-1;;10946:12;10908:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;10998:63;11098:2;11137:22;;;;9671:20;;-1:-1;;;10902:283::o;11192:491::-;;;;11330:2;11318:9;11309:7;11305:23;11301:32;11298:2;;;-1:-1;;11336:12;11298:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;11388:63;11488:2;11527:22;;9671:20;;-1:-1;11596:2;11635:22;;;926:20;;11292:391;-1:-1;;;11292:391::o;11690:617::-;;;;;11845:3;11833:9;11824:7;11820:23;11816:33;11813:2;;;-1:-1;;11852:12;11813:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;11904:63;-1:-1;12004:2;12043:22;;9671:20;;-1:-1;12112:2;12151:22;;926:20;;-1:-1;12220:2;12259:22;;72:20;97:33;72:20;97:33;:::i;:::-;11807:500;;;;-1:-1;11807:500;;-1:-1;;11807:500::o;12314:741::-;;;;;;12488:3;12476:9;12467:7;12463:23;12459:33;12456:2;;;-1:-1;;12495:12;12456:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;12547:63;-1:-1;12647:2;12686:22;;9671:20;;-1:-1;12755:2;12794:22;;9671:20;;-1:-1;12891:2;12876:18;;12863:32;12915:18;12904:30;;;12901:2;;;-1:-1;;12937:12;12901:2;13022:6;13011:9;13007:22;;;1265:3;1258:4;1250:6;1246:17;1242:27;1232:2;;-1:-1;;1273:12;1232:2;1316:6;1303:20;12915:18;1335:6;1332:30;1329:2;;;-1:-1;;1365:12;1329:2;1460:3;12647:2;1440:17;1401:6;1426:32;;1423:41;1420:2;;;-1:-1;;1467:12;1420:2;12450:605;;;;-1:-1;12450:605;;-1:-1;12647:2;1397:17;;12957:82;12450:605;-1:-1;;;12450:605::o;13062:257::-;;13174:2;13162:9;13153:7;13149:23;13145:32;13142:2;;;-1:-1;;13180:12;13142:2;805:6;799:13;817:30;841:5;817:30;:::i;13326:393::-;;;13455:2;13443:9;13434:7;13430:23;13426:32;13423:2;;;-1:-1;;13461:12;13423:2;805:6;799:13;817:30;841:5;817:30;:::i;:::-;13621:2;13671:22;;;;9819:13;13513:71;;9819:13;;-1:-1;;;13417:302::o;13726:241::-;;13830:2;13818:9;13809:7;13805:23;13801:32;13798:2;;;-1:-1;;13836:12;13798:2;-1:-1;926:20;;13792:175;-1:-1;13792:175::o;13974:263::-;;14089:2;14077:9;14068:7;14064:23;14060:32;14057:2;;;-1:-1;;14095:12;14057:2;-1:-1;1074:13;;14051:186;-1:-1;14051:186::o;14244:345::-;;14357:2;14345:9;14336:7;14332:23;14328:32;14325:2;;;-1:-1;;14363:12;14325:2;14421:17;14408:31;14459:18;14451:6;14448:30;14445:2;;;-1:-1;;14481:12;14445:2;14511:62;14565:7;14556:6;14545:9;14541:22;14511:62;:::i;14596:979::-;;;;;;;14797:3;14785:9;14776:7;14772:23;14768:33;14765:2;;;-1:-1;;14804:12;14765:2;14862:17;14849:31;14900:18;14892:6;14889:30;14886:2;;;-1:-1;;14922:12;14886:2;14952:62;15006:7;14997:6;14986:9;14982:22;14952:62;:::i;:::-;14942:72;;;15051:2;15094:9;15090:22;9671:20;15059:63;;15159:2;15202:9;15198:22;9671:20;15167:63;;15267:2;15318:9;15314:22;358:20;383:41;418:5;383:41;:::i;:::-;15275:71;-1:-1;15383:3;15420:22;;657:20;682:30;657:20;682:30;:::i;:::-;15392:60;-1:-1;15489:3;15527:22;;9947:20;49477:4;49466:16;;54002:33;;53992:2;;-1:-1;;54039:12;53992:2;15498:61;;;;14759:816;;;;;;;;:::o;15874:398::-;;;16011:2;15999:9;15990:7;15986:23;15982:32;15979:2;;;-1:-1;;16017:12;16809:439;;;16961:2;16949:9;16940:7;16936:23;16932:32;16929:2;;;-1:-1;;16967:12;16929:2;2831:6;2825:13;2843:53;2890:5;2843:53;:::i;17255:273::-;;17375:2;17363:9;17354:7;17350:23;17346:32;17343:2;;;-1:-1;;17381:12;17343:2;17443:69;17504:7;17480:22;17443:69;:::i;17535:387::-;;17669:2;17657:9;17648:7;17644:23;17640:32;17637:2;;;-1:-1;;17675:12;17637:2;17733:17;17720:31;17771:18;17763:6;17760:30;17757:2;;;-1:-1;;17793:12;17757:2;17823:83;17898:7;17889:6;17878:9;17874:22;17823:83;:::i;17929:402::-;;18074:2;18062:9;18053:7;18049:23;18045:32;18042:2;;;-1:-1;;18080:12;18042:2;18131:17;18125:24;18169:18;;18161:6;18158:30;18155:2;;;-1:-1;;18191:12;18155:2;18298:6;18287:9;18283:22;;;5196:6;;5184:9;5179:3;5175:19;5171:32;5168:2;;;-1:-1;;5206:12;5168:2;5234:22;5196:6;5234:22;:::i;:::-;5225:31;;5341:60;5397:3;5373:22;5341:60;:::i;:::-;5323:16;5316:86;5500:60;5556:3;18074:2;5536:9;5532:22;5500:60;:::i;:::-;18074:2;5486:5;5482:16;5475:86;5627:2;5696:9;5692:22;9819:13;5627:2;5646:5;5642:16;5635:86;5788:2;5857:9;5853:22;9819:13;5788:2;5807:5;5803:16;5796:86;5947:3;6017:9;6013:22;9819:13;5947:3;5967:5;5963:16;5956:86;6112:3;6182:9;6178:22;9819:13;6112:3;6132:5;6128:16;6121:86;6302:60;6358:3;6268;6338:9;6334:22;6302:60;:::i;:::-;6268:3;6288:5;6284:16;6277:86;6461:60;6517:3;6427;6497:9;6493:22;6461:60;:::i;:::-;6427:3;6447:5;6443:16;6436:86;6611:3;;6600:9;6596:19;6590:26;18169:18;6628:6;6625:30;6622:2;;;-1:-1;;6658:12;6622:2;6705:69;6770:3;6761:6;6750:9;6746:22;6705:69;:::i;:::-;6611:3;6689:5;6685:18;6678:97;;;6865:3;;6854:9;6850:19;6844:26;18169:18;6882:6;6879:30;6876:2;;;-1:-1;;6912:12;6876:2;6959:90;7045:3;7036:6;7025:9;7021:22;6959:90;:::i;:::-;6939:18;;;6932:118;;;;-1:-1;6943:5;18036:295;-1:-1;;;;;18036:295::o;18338:921::-;;;;;;18556:3;18544:9;18535:7;18531:23;18527:33;18524:2;;;-1:-1;;18563:12;18524:2;18621:17;18608:31;18659:18;18651:6;18648:30;18645:2;;;-1:-1;;18681:12;18645:2;18711:83;18786:7;18777:6;18766:9;18762:22;18711:83;:::i;:::-;18701:93;;;18831:2;18874:9;18870:22;9671:20;18839:63;;18939:2;18982:9;18978:22;9671:20;18947:63;;19047:2;19090:9;19086:22;72:20;97:33;124:5;97:33;:::i;:::-;19055:63;-1:-1;19174:69;19235:7;19155:3;19211:22;;19174:69;:::i;:::-;19164:79;;18518:741;;;;;;;;:::o;19536:399::-;;;19668:2;19656:9;19647:7;19643:23;19639:32;19636:2;;;-1:-1;;19674:12;19636:2;-1:-1;;9819:13;;19837:2;19887:22;;;9819:13;;;;;-1:-1;19630:305::o;19942:809::-;;;;;;20125:3;20113:9;20104:7;20100:23;20096:33;20093:2;;;-1:-1;;20132:12;20093:2;-1:-1;;9819:13;;20295:2;20345:22;;9819:13;20414:2;20464:22;;9819:13;20533:2;20583:22;;9819:13;20652:3;20703:22;;;9819:13;;;;;-1:-1;9819:13;;-1:-1;9819:13;;-1:-1;20087:664;-1:-1;20087:664::o;20907:103::-;-1:-1;;;;;49261:54;20968:37;;20962:48::o;21257:323::-;;21389:5;47435:12;47710:6;47705:3;47698:19;21472:52;21517:6;47747:4;47742:3;47738:14;47747:4;21498:5;21494:16;21472:52;:::i;:::-;52598:7;52582:14;-1:-1;;52578:28;21536:39;;;;47747:4;21536:39;;21337:243;-1:-1;;21337:243::o;27311:1986::-;;27472:6;27572:63;27620:14;27549:16;27543:23;27572:63;:::i;:::-;27718:4;27711:5;27707:16;27701:23;27730:63;27718:4;27782:3;27778:14;27764:12;27730:63;:::i;:::-;;27877:4;27870:5;27866:16;27860:23;27877:4;27941:3;27937:14;21208:37;28037:4;28030:5;28026:16;28020:23;28037:4;28101:3;28097:14;21208:37;28195:4;28188:5;28184:16;28178:23;28195:4;28259:3;28255:14;21208:37;28358:4;28351:5;28347:16;28341:23;28358:4;28422:3;28418:14;21208:37;28512:4;28505:5;28501:16;28495:23;28524:63;28512:4;28576:3;28572:14;28558:12;28524:63;:::i;:::-;;28669:4;28662:5;28658:16;28652:23;28681:63;28669:4;28733:3;28729:14;28715:12;28681:63;:::i;:::-;;28830:6;;28823:5;28819:18;28813:25;27472:6;28830;28862:3;28858:16;28851:40;28906:71;27472:6;27467:3;27463:16;28958:12;28906:71;:::i;:::-;28898:79;;;;29070:6;;29063:5;29059:18;29053:25;29126:3;29120:4;29116:14;29070:6;29102:3;29098:16;29091:40;29146:113;29254:4;29240:12;29146:113;:::i;:::-;29281:11;27445:1852;-1:-1;;;;;;27445:1852::o;29385:1219::-;;4597:18;;49272:42;;;;29611:16;29605:23;49261:54;20975:3;20968:37;49272:42;29784:4;29777:5;29773:16;29767:23;49261:54;29784:4;29848:3;29844:14;20968:37;49272:42;29949:4;29942:5;29938:16;29932:23;49261:54;29949:4;30013:3;30009:14;20968:37;;30104:4;30097:5;30093:16;30087:23;30104:4;30168:3;30164:14;21208:37;30265:4;30258:5;30254:16;30248:23;30265:4;30329:3;30325:14;21208:37;30423:4;30416:5;30412:16;30406:23;29536:4;30423;30453:3;30449:14;30442:38;30495:71;29536:4;29531:3;29527:14;30547:12;30495:71;:::i;30841:271::-;;22097:5;47435:12;22208:52;22253:6;22248:3;22241:4;22234:5;22230:16;22208:52;:::i;:::-;22272:16;;;;;30975:137;-1:-1;;30975:137::o;31119:379::-;31483:10;31307:191::o;31505:222::-;-1:-1;;;;;49261:54;;;;20968:37;;31632:2;31617:18;;31603:124::o;31979:349::-;-1:-1;;;;;49261:54;;;20837:58;;49261:54;;32314:2;32299:18;;20968:37;32142:2;32127:18;;32113:215::o;32335:866::-;-1:-1;;;;;49261:54;;;20837:58;;49261:54;;32834:2;32819:18;;20837:58;32653:3;32871:2;32856:18;;32849:48;;;24827:2;32638:19;;;47698;-1:-1;;;49272:42;47738:14;;24843:36;24898:12;33075:2;33060:18;;33053:48;;;32335:866;;33115:76;;24898:12;;33177:6;33115:76;:::i;:::-;33107:84;32624:577;-1:-1;;;;;32624:577::o;33208:866::-;-1:-1;;;;;49261:54;;;20837:58;;49261:54;;33707:2;33692:18;;20837:58;33526:3;33744:2;33729:18;;33722:48;;;25149:1;33511:19;;;47698;-1:-1;;;49272:42;47738:14;;25164:31;25214:12;33948:2;33933:18;;33926:48;;;33208:866;;33988:76;;25214:12;;34050:6;33988:76;:::i;34081:866::-;-1:-1;;;;;49261:54;;;20837:58;;49261:54;;34580:2;34565:18;;20837:58;34399:3;34617:2;34602:18;;34595:48;;;25465:2;34384:19;;;47698;-1:-1;;;49272:42;47738:14;;25481:36;25536:12;34821:2;34806:18;;34799:48;;;34081:866;;34861:76;;25536:12;;34923:6;34861:76;:::i;34954:866::-;-1:-1;;;;;49261:54;;;20837:58;;49261:54;;35453:2;35438:18;;20837:58;35272:3;35490:2;35475:18;;35468:48;;;25787:1;35257:19;;;47698;-1:-1;;;49272:42;47738:14;;25802:31;25852:12;35694:2;35679:18;;35672:48;;;34954:866;;35734:76;;25852:12;;35796:6;35734:76;:::i;35827:349::-;-1:-1;;;;;49261:54;;;;20837:58;;36162:2;36147:18;;21208:37;35990:2;35975:18;;35961:215::o;36183:640::-;-1:-1;;;;;49261:54;;;20968:37;;49261:54;;36577:2;36562:18;;20968:37;36660:2;36645:18;;21208:37;;;36412:3;36697:2;36682:18;;36675:48;;;36183:640;;36737:76;;36397:19;;36799:6;36737:76;:::i;36830:345::-;-1:-1;;;;;49261:54;;;;20968:37;;49477:4;49466:16;37161:2;37146:18;;23844:56;36991:2;36976:18;;36962:213::o;37522:222::-;21208:37;;;37649:2;37634:18;;37620:124::o;37751:333::-;21208:37;;;-1:-1;;;;;49261:54;38070:2;38055:18;;20968:37;37906:2;37891:18;;37877:207::o;38091:822::-;21208:37;;;-1:-1;;;;;49261:54;;;38544:2;38529:18;;20968:37;49261:54;;;38635:2;38620:18;;20837:58;49261:54;;38726:2;38711:18;;20837:58;38807:3;38792:19;;21208:37;;;;49272:42;38883:19;;23698:57;38379:3;38364:19;;38350:563::o;38920:306::-;;39065:2;39086:17;39079:47;39140:76;39065:2;39054:9;39050:18;39202:6;39140:76;:::i;41170:416::-;41370:2;41384:47;;;24491:2;41355:18;;;47698:19;24527:29;47738:14;;;24507:50;24576:12;;;41341:245::o;41593:416::-;41793:2;41807:47;;;26408:2;41778:18;;;47698:19;26444:31;47738:14;;;26424:52;26495:12;;;41764:245::o;42016:416::-;42216:2;42230:47;;;26746:2;42201:18;;;47698:19;26782:34;47738:14;;;26762:55;-1:-1;;;26837:12;;;26830:34;26883:12;;;42187:245::o;42439:416::-;42639:2;42653:47;;;27134:2;42624:18;;;47698:19;-1:-1;;;47738:14;;;27150:35;27204:12;;;42610:245::o;42862:390::-;;43049:2;43070:17;43063:47;43124:118;43049:2;43038:9;43034:18;43228:6;43124:118;:::i;43259:527::-;;43487:2;43508:17;43501:47;43562:118;43487:2;43476:9;43472:18;43666:6;43562:118;:::i;:::-;43554:126;;52703:1;52696:5;52693:12;52683:2;;52709:9;52683:2;51549:39;43772:2;43761:9;43757:18;23428:63;43458:328;;;;;:::o;44022:460::-;21208:37;;;-1:-1;;;;;49261:54;;;;44385:2;44370:18;;20837:58;44468:2;44453:18;;21208:37;44213:2;44198:18;;44184:298::o;44489:556::-;21208:37;;;-1:-1;;;;;49261:54;;;;44865:2;44850:18;;20968:37;44948:2;44933:18;;21208:37;45031:2;45016:18;;21208:37;44700:3;44685:19;;44671:374::o;45052:436::-;21208:37;;;45393:2;45378:18;;21208:37;;;;45474:2;45459:18;;21208:37;45231:2;45216:18;;45202:286::o;46417:333::-;21208:37;;;46736:2;46721:18;;21208:37;46572:2;46557:18;;46543:207::o;46757:256::-;46819:2;46813:9;46845:17;;;46920:18;46905:34;;46941:22;;;46902:62;46899:2;;;46977:1;;46967:12;46899:2;46819;46986:22;46797:216;;-1:-1;46797:216::o;47020:321::-;;47163:18;47155:6;47152:30;47149:2;;;-1:-1;;47185:12;47149:2;-1:-1;52598:7;47239:17;-1:-1;;47235:33;47326:4;47316:15;;47086:255::o;52238:268::-;52303:1;52310:101;52324:6;52321:1;52318:13;52310:101;;;52391:11;;;52385:18;52372:11;;;52365:39;52346:2;52339:10;52310:101;;;52426:6;52423:1;52420:13;52417:2;;;52303:1;52482:6;52477:3;52473:16;52466:27;52417:2;;52287:219;;;:::o;52732:117::-;-1:-1;;;;;49261:54;;52791:35;;52781:2;;52840:1;;52830:12;52781:2;52775:74;:::o;52996:111::-;53077:5;48532:13;48525:21;53055:5;53052:32;53042:2;;53098:1;;53088:12
Swarm Source
ipfs://a82338d1bbe4f0433c35fa0219f01fc6d69e0309bf732ee2e41e7e83efdb33b2
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.