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 | 13222986 | 1162 days ago | IN | 0 ETH | 0.18659422 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
13860218 | 1062 days ago | 0.80142153 ETH | ||||
13860218 | 1062 days ago | 0.80142153 ETH | ||||
13860218 | 1062 days ago | 4.52146104 ETH | ||||
13860218 | 1062 days ago | 3.72076013 ETH | ||||
13860218 | 1062 days ago | 0.8007009 ETH | ||||
13858653 | 1062 days ago | 52.74831639 ETH | ||||
13858653 | 1062 days ago | 52.74831639 ETH | ||||
13855705 | 1063 days ago | 0.15076485 ETH | ||||
13855705 | 1063 days ago | 0.15076485 ETH | ||||
13855705 | 1063 days ago | 11.61033567 ETH | ||||
13855705 | 1063 days ago | 11.45970638 ETH | ||||
13855705 | 1063 days ago | 0.15062928 ETH | ||||
13850548 | 1064 days ago | 66.24417606 ETH | ||||
13850548 | 1064 days ago | 66.24417606 ETH | ||||
13850548 | 1064 days ago | 110.27206641 ETH | ||||
13850548 | 1064 days ago | 44.08745649 ETH | ||||
13850548 | 1064 days ago | 66.18460991 ETH | ||||
13841637 | 1065 days ago | 0.0486507 ETH | ||||
13841637 | 1065 days ago | 0.0486507 ETH | ||||
13841637 | 1065 days ago | 3.72464833 ETH | ||||
13841637 | 1065 days ago | 3.67604136 ETH | ||||
13841637 | 1065 days ago | 0.04860696 ETH | ||||
13840590 | 1065 days ago | 4.65079389 ETH | ||||
13840590 | 1065 days ago | 4.65079389 ETH | ||||
13840590 | 1065 days ago | 61.85544789 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-09-14 */ 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 returns (uint); function getBuyRate(address _srcAddr, address _destAddr, uint _srcAmount, bytes memory _additionalData) external 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)); } } // SPDX-License-Identifier: MIT 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 { uint256 public constant MANUAL_SERVICE_FEE = 400; // 0.25% Fee uint256 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, uint256 _cdpId, uint256 _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; (, uint256 daiAmount) = _sell(_exchangeData); daiAmount = sub(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, uint256 _cdpId, uint256 _gasCost, address _joinAddr, ManagerType _managerType ) public payable { address managerAddr = getManagerAddr(_managerType); address user = getOwner(Manager(managerAddr), _cdpId); bytes32 ilk = Manager(managerAddr).ilks(_cdpId); uint256 daiDrawn = drawDai(managerAddr, _cdpId, ilk, _exchangeData.srcAmount); _exchangeData.user = user; _exchangeData.dfsFeeDivider = isAutomation() ? AUTOMATIC_SERVICE_FEE : MANUAL_SERVICE_FEE; _exchangeData.srcAmount = sub(daiDrawn, takeFee(_gasCost, daiDrawn)); (, uint256 swapedColl) = _sell(_exchangeData); addCollateral(managerAddr, _cdpId, _joinAddr, swapedColl); // if there is some eth left (0x fee), return it to the caller 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, uint256 _cdpId, bytes32 _ilk, uint256 _daiAmount ) internal returns (uint256) { uint256 rate = Jug(JUG_ADDRESS).drip(_ilk); uint256 daiVatBalance = vat.dai(Manager(_managerAddr).urns(_cdpId)); uint256 maxAmount = getMaxDebt(_managerAddr, _cdpId, _ilk); if (_daiAmount >= maxAmount) { _daiAmount = sub(maxAmount, 1); } Manager(_managerAddr).frob( _cdpId, int256(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, uint256 _cdpId, address _joinAddr, uint256 _amount ) internal { int256 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, uint256 _cdpId, address _joinAddr, uint256 _amount ) internal returns (uint256) { uint256 frobAmount = _amount; uint256 tokenDecimal = Join(_joinAddr).dec(); require(tokenDecimal <= 18, "Token decimals too big"); if (tokenDecimal != 18) { frobAmount = _amount * (10**(18 - tokenDecimal)); } 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, uint256 _cdpId, bytes32 _ilk, uint256 _daiAmount, address _owner ) internal { address urn = Manager(_managerAddr).urns(_cdpId); uint256 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, uint256(-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, uint256 _cdpId, bytes32 _ilk, address _joinAddr ) public view returns (uint256) { uint256 price = getPrice(_ilk); (uint256 collateral, uint256 debt) = getCdpInfo(Manager(_managerAddr), _cdpId, _ilk); (, uint256 mat) = Spotter(SPOTTER_ADDRESS).ilks(_ilk); uint256 maxCollateral = sub(collateral, (div(mul(mat, debt), price))); uint256 tokenDecimal = Join(_joinAddr).dec(); require(tokenDecimal <= 18, "Token decimals too big"); uint256 normalizeMaxCollateral = maxCollateral / (10**(18 - tokenDecimal)); // 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, uint256 _cdpId, bytes32 _ilk ) public view virtual returns (uint256) { uint256 price = getPrice(_ilk); (, uint256 mat) = spotter.ilks(_ilk); (uint256 collateral, uint256 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 (uint256) { (, uint256 mat) = spotter.ilks(_ilk); (, , uint256 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, uint256 _amount) internal returns (uint256) { if (_gasCost > 0) { uint256 ethDaiPrice = getPrice(ETH_ILK); uint256 feeAmount = rmul(_gasCost, ethDaiPrice); if (feeAmount > _amount / 5) { feeAmount = _amount / 5; } address walletAddr = _feeRecipient.getFeeAddr(); ERC20(DAI_ADDRESS).safeTransfer(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 Aave flash loan and performs the fl repay/boost logic contract MCDSaverFlashLoan is MCDSaverProxy, AdminAuth, FlashLoanReceiverBase { ILendingPoolAddressesProvider public LENDING_POOL_ADDRESS_PROVIDER = ILendingPoolAddressesProvider(0x24a42fD28C976A61Df5D00D0599C34c4f90748c8); constructor() public FlashLoanReceiverBase(LENDING_POOL_ADDRESS_PROVIDER) {} struct SaverData { uint256 cdpId; uint256 gasCost; uint256 loanAmount; uint256 fee; address joinAddr; ManagerType managerType; } function executeOperation( address _reserve, uint256 _amount, uint256 _fee, bytes calldata _params ) external override { ( bytes memory exDataBytes, uint256 cdpId, uint256 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 uint256 maxDebt = getMaxDebt( managerAddr, _saverData.cdpId, Manager(managerAddr).ilks(_saverData.cdpId) ); uint256 daiDrawn = drawDai( managerAddr, _saverData.cdpId, Manager(managerAddr).ilks(_saverData.cdpId), maxDebt ); // Swap _exchangeData.srcAmount = sub( add(daiDrawn, _saverData.loanAmount), takeFee(_saverData.gasCost, add(daiDrawn, _saverData.loanAmount)) ); _exchangeData.user = user; _exchangeData.dfsFeeDivider = isAutomation() ? AUTOMATIC_SERVICE_FEE : MANUAL_SERVICE_FEE; (, uint256 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), add(_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 uint256 maxColl = getMaxCollateral(managerAddr, _saverData.cdpId, ilk, _saverData.joinAddr); uint256 collDrawn = drawCollateral( managerAddr, _saverData.cdpId, _saverData.joinAddr, maxColl ); // Swap _exchangeData.srcAmount = add(_saverData.loanAmount, collDrawn); _exchangeData.user = user; _exchangeData.dfsFeeDivider = isAutomation() ? AUTOMATIC_SERVICE_FEE : MANUAL_SERVICE_FEE; (, uint256 paybackAmount) = _sell(_exchangeData); paybackAmount = sub(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, add(_saverData.loanAmount, _saverData.fee) ); logger.Log( address(this), msg.sender, "MCDFlashRepay", abi.encode(_saverData.cdpId, user, _exchangeData.srcAmount, paybackAmount) ); } receive() external payable override(FlashLoanReceiverBase, DFSExchangeCore) {} }
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
6080604052600380546001600160a01b0319167324a42fd28c976a61df5d00d0599c34c4f90748c817905534801561003657600080fd5b50600354600080546001600160a01b031990811673bc841b0de0b93205e912cfbbd1d0c160a1ec6f00179091556001805482167325efa336886c74ea8e282ac466bdcd0199f85bb9179055600280549091166001600160a01b03909216919091179055614f2b806100a86000396000f3fe60806040526004361061026b5760003560e01c80638c8a795811610144578063c72c4d10116100b6578063dd6d903c1161007a578063dd6d903c1461060f578063deca5f881461062f578063e870b9cd1461064f578063ee87255814610662578063f24ccbfe14610682578063f851a4401461069757610272565b8063c72c4d10146105d2578063c7975824146105e7578063cc694d48146105fa578063cf786f8f146103bc578063cfac57c7146105a857610272565b8063a46a66c911610108578063a46a66c914610549578063a7304bf71461055e578063acbeba611461057e578063ae08fd1014610593578063c11645bc146105a8578063c50ebaf8146105bd57610272565b80638c8a7958146104c85780638da5cb5b146104dd57806398ab3d49146104f2578063a342f23814610507578063a3b8e5d11461051c57610272565b806336569e77116101dd5780634d2ab9dc116101a15780634d2ab9dc146104495780634d93667e1461045e578063526d64611461047e5780636738929f1461035257806381b94280146104935780638aa0fd0e146104a857610272565b806336569e77146103bc5780633a128322146103d15780634115fe6b146103f157806341c0e1b51461041f578063449b9ffa1461043457610272565b806329f7fc9e1161022f57806329f7fc9e1461031b5780632a4c0a1a1461033d5780632e77468d146103525780632f634a9014610367578063314b63321461038757806331d98b3f1461039c57610272565b806304c9805c1461027757806308d4f52a146102a2578063186cab76146102cf5780631e48907b146102e4578063278d58311461030657610272565b3661027257005b600080fd5b34801561028357600080fd5b5061028c6106ac565b6040516102999190614c38565b60405180910390f35b3480156102ae57600080fd5b506102c26102bd3660046146f3565b6106b2565b6040516102999190614c8d565b3480156102db57600080fd5b5061028c6106dc565b3480156102f057600080fd5b506103046102ff366004614400565b6106e8565b005b34801561031257600080fd5b506102c2610721565b34801561032757600080fd5b50610330610749565b6040516102999190614a5f565b34801561034957600080fd5b50610330610761565b34801561035e57600080fd5b50610330610779565b34801561037357600080fd5b506103306103823660046146a9565b610791565b34801561039357600080fd5b5061033061088d565b3480156103a857600080fd5b5061028c6103b73660046145ba565b6108a5565b3480156103c857600080fd5b50610330610a63565b3480156103dd57600080fd5b506103046103ec366004614438565b610a7b565b3480156103fd57600080fd5b5061041161040c366004614463565b610b14565b604051610299929190614e46565b34801561042b57600080fd5b50610304610d30565b34801561044057600080fd5b506102c2610d55565b34801561045557600080fd5b5061028c610d87565b34801561046a57600080fd5b506103306104793660046146d8565b610d8d565b34801561048a57600080fd5b50610330610dec565b34801561049f57600080fd5b50610330610e04565b3480156104b457600080fd5b5061028c6104c3366004614463565b610e1c565b3480156104d457600080fd5b50610330610efd565b3480156104e957600080fd5b50610330610f15565b3480156104fe57600080fd5b50610330610f24565b34801561051357600080fd5b50610330610f33565b34801561052857600080fd5b5061053c6105373660046145ea565b610f4b565b6040516102999190614dae565b34801561055557600080fd5b50610330610f67565b34801561056a57600080fd5b50610304610579366004614400565b610f7f565b34801561058a57600080fd5b50610330610fb8565b34801561059f57600080fd5b506102c2610fd0565b3480156105b457600080fd5b50610330611001565b3480156105c957600080fd5b506102c2611019565b3480156105de57600080fd5b50610330611048565b6103046105f536600461482e565b611057565b34801561060657600080fd5b506102c2611243565b34801561061b57600080fd5b5061028c61062a366004614497565b61126e565b34801561063b57600080fd5b5061030461064a366004614400565b611401565b61030461065d36600461482e565b61142e565b34801561066e57600080fd5b5061030461067d3660046144e0565b61160f565b34801561068e57600080fd5b506103306116fe565b3480156106a357600080fd5b50610330611716565b61014d81565b6060816040516020016106c59190614dae565b60405160208183030381529060405290505b919050565b644554482d4160d81b81565b6001546001600160a01b031633146106ff57600080fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b81525081565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b736b175474e89094c44da98b954eedeac495271d0f81565b7365c79fcb50ca1594b025960e539ed7a9a6d434a381565b600080836001600160a01b0316638161b120846040518263ffffffff1660e01b81526004016107c09190614c38565b60206040518083038186803b1580156107d857600080fd5b505afa1580156107ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610810919061441c565b9050806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561084b57600080fd5b505afa15801561085f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610883919061441c565b9150505b92915050565b7325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d81565b604051636cb1c69b60e11b815260009081907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906108e1908690600401614c38565b604080518083038186803b1580156108f857600080fd5b505afa15801561090c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093091906146bb565b604051636cb1c69b60e11b8152909250600091507335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063d9638d369061096e908790600401614c38565b60a06040518083038186803b15801561098657600080fd5b505afa15801561099a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109be91906148c4565b505092505050610a5b610a55827365c79fcb50ca1594b025960e539ed7a9a6d434a36001600160a01b031663495d32cb6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1857600080fd5b505afa158015610a2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5091906145d2565b611725565b83611725565b949350505050565b7335d1b3f3d7966a1dfe207aa4514c12a259a0492b81565b6000546001600160a01b03163314610a9257600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b0383161415610af657600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015610af0573d6000803e3d6000fd5b50610b10565b600054610b10906001600160a01b03848116911683611764565b5050565b6000806000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5257600080fd5b505afa158015610b66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8a919061441c565b90506000866001600160a01b0316632726b073876040518263ffffffff1660e01b8152600401610bba9190614c38565b60206040518083038186803b158015610bd257600080fd5b505afa158015610be6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0a919061441c565b9050600080836001600160a01b0316632424be5c88856040518363ffffffff1660e01b8152600401610c3d929190614c41565b604080518083038186803b158015610c5457600080fd5b505afa158015610c68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8c91906148a1565b915091506000846001600160a01b031663d9638d36896040518263ffffffff1660e01b8152600401610cbe9190614c38565b60a06040518083038186803b158015610cd657600080fd5b505afa158015610cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0e91906148c4565b50505091505082610d1f8383611725565b965096505050505050935093915050565b6000546001600160a01b03163314610d4757600080fd5b6000546001600160a01b0316ff5b6040518060400160405280601681526020017516995c9bde08195e18da185b99d9481a5b9d985b1a5960521b81525081565b61019081565b600080826001811115610d9c57fe5b1415610dbd5750735ef30b9986345249bc32d8928b7ee64de9435e396106d7565b6001826001811115610dcb57fe5b14156106d75750733f30c2381cd8b917dd96eb2f1a4f96d91324bbed6106d7565b73637726f8b08a7abe3ae3acab01a80e2d8ddef77b81565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600080610e28836108a5565b604051636cb1c69b60e11b81529091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d3690610e65908790600401614c38565b604080518083038186803b158015610e7c57600080fd5b505afa158015610e90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb491906146bb565b915050600080610ec5888888610b14565b91509150610eef610ee8610ee2610edc85886117bf565b866117e3565b836117ee565b600a6117ee565b9450505050505b9392505050565b734ba1f38427b33b8ab7bb0490200dae1f1c36823f81565b6000546001600160a01b031681565b6003546001600160a01b031681565b7339c4a92dc506300c3ea4c67ca4ca611102ee6f2a81565b610f5361401f565b818060200190518101906108879190614726565b731b14e8d511c9a4395425314f849bd737baf8208f81565b6001546001600160a01b03163314610f9657600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b7319c0976f590d67707e62397c87829d896dc0f1f181565b6040518060400160405280601581526020017413d99998da185a5b8819185d18481a5b9d985b1a59605a1b81525081565b739759a6ac90977b93b58547b4a71c78317f391a2881565b604051806040016040528060138152602001724465737420616d6f756e74206d697373696e6760681b81525081565b6002546001600160a01b031681565b600061106282610d8d565b905060006110708287610791565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016110a09190614c38565b60206040518083038186803b1580156110b857600080fd5b505afa1580156110cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f091906145d2565b905060006111048489848c604001516117fe565b6001600160a01b03841660c08b0152905061111d611c2e565b6111295761019061112d565b61014d5b60a08a0152611145816111408982611cbd565b6117ee565b60408a015260006111558a611db4565b915050611164858a89846120fb565b47156111985760405132904780156108fc02916000818181858888f19350505050158015611196573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338c888f60400151876040516020016111d89493929190614e0c565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161120593929190614ae7565b600060405180830381600087803b15801561121f57600080fd5b505af1158015611233573d6000803e3d6000fd5b5050505050505050505050505050565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b81525081565b60008061127a846108a5565b905060008061128a888888610b14565b604051636cb1c69b60e11b815291935091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906112c9908a90600401614c38565b604080518083038186803b1580156112e057600080fd5b505afa1580156112f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061131891906146bb565b91505060006113348461114061132e85876117bf565b886117e3565b90506000876001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561137157600080fd5b505afa158015611385573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a991906145d2565b905060128111156113d55760405162461bcd60e51b81526004016113cc90614cd7565b60405180910390fd5b600081601203600a0a83816113e657fe5b04905060646063820204975050505050505050949350505050565b6000546001600160a01b0316331461141857600080fd5b6001546001600160a01b031615610f9657600080fd5b600061143982610d8d565b905060006114478287610791565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016114779190614c38565b60206040518083038186803b15801561148f57600080fd5b505afa1580156114a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c791906145d2565b90506114d98388878b6040015161244d565b506001600160a01b03821660c08901526114f1611c2e565b6114fd57610190611501565b61014d5b60a0890152600061151189611db4565b915050611522816111408984611cbd565b90506115318489848487612715565b47156115655760405132904780156108fc02916000818181858888f19350505050158015611563573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338b878e60400151876040516020016115a59493929190614e0c565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016115d293929190614b84565b600060405180830381600087803b1580156115ec57600080fd5b505af1158015611600573d6000803e3d6000fd5b50505050505050505050505050565b60606000808080806116238789018961461d565b95509550955095509550955061163761401f565b61164087610f4b565b905061164a61409b565b6040518060c001604052808881526020018781526020018d81526020018c8152602001866001600160a01b031681526020018460ff16600181111561168b57fe5b600181111561169657fe5b9052905083156116af576116aa8282612a94565b6116b9565b6116b98282612caf565b6116cc8d6116c78e8e612f78565b612f9d565b47156116005760405132904780156108fc02916000818181858888f19350505050158015611233573d6000803e3d6000fd5b735c55b921f590a89c1ebe84df170e655a82b6212681565b6001546001600160a01b031681565b6000676765c793fa10079d601b1b61175561174085856117bf565b6002676765c793fa10079d601b1b5b04613027565b8161175c57fe5b049392505050565b6117ba8363a9059cbb60e01b8484604051602401611783929190614bd0565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613037565b505050565b60008115806117da575050808202828282816117d757fe5b04145b61088757600080fd5b600081838161175c57fe5b8082038281111561088757600080fd5b60405163089c54b560e31b815260009081907319c0976f590d67707e62397c87829d896dc0f1f1906344e2a5a89061183a908790600401614c38565b602060405180830381600087803b15801561185457600080fd5b505af1158015611868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188c91906145d2565b905060007335d1b3f3d7966a1dfe207aa4514c12a259a0492b6001600160a01b0316636c25b346886001600160a01b0316632726b073896040518263ffffffff1660e01b81526004016118df9190614c38565b60206040518083038186803b1580156118f757600080fd5b505afa15801561190b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192f919061441c565b6040518263ffffffff1660e01b815260040161194b9190614a5f565b60206040518083038186803b15801561196357600080fd5b505afa158015611977573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061199b91906145d2565b905060006119aa888888610e1c565b90508085106119c1576119be8160016117ee565b94505b876001600160a01b03166345e6bdcd8860006119de8988886130c6565b6040518463ffffffff1660e01b81526004016119fc93929190614e30565b600060405180830381600087803b158015611a1657600080fd5b505af1158015611a2a573d6000803e3d6000fd5b50505050876001600160a01b031663f9f30db68830611a4889613149565b6040518463ffffffff1660e01b8152600401611a6693929190614ded565b600060405180830381600087803b158015611a8057600080fd5b505af1158015611a94573d6000803e3d6000fd5b5050604051634538c4eb60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250634538c4eb9150611ae5903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614a73565b60206040518083038186803b158015611afd57600080fd5b505afa158015611b11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3591906145d2565b611bb7576040516328ec8bf160e21b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063a3b22fc490611b8490739759a6ac90977b93b58547b4a71c78317f391a2890600401614a5f565b600060405180830381600087803b158015611b9e57600080fd5b505af1158015611bb2573d6000803e3d6000fd5b505050505b60405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a289063ef693bed90611bf09030908990600401614bd0565b600060405180830381600087803b158015611c0a57600080fd5b505af1158015611c1e573d6000803e3d6000fd5b50969a9950505050505050505050565b6040516320eb73ed60e11b815260009073637726f8b08a7abe3ae3acab01a80e2d8ddef77b906341d6e7da90611c68903290600401614a5f565b60206040518083038186803b158015611c8057600080fd5b505afa158015611c94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb89190614571565b905090565b60008215611dab576000611cd8644554482d4160d81b6108a5565b90506000611ce68583611725565b905060058404811115611cf95750600583045b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b158015611d4857600080fd5b505afa158015611d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d80919061441c565b9050611da1736b175474e89094c44da98b954eedeac495271d0f8284611764565b5091506108879050565b50600092915050565b600080600080600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b031686600001516001600160a01b03161415611e6f578551611df990613160565b6001600160a01b031686526040808701518151630d0e30db60e41b8152915173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29263d0e30db09291600480830192600092919082900301818588803b158015611e5557600080fd5b505af1158015611e69573d6000803e3d6000fd5b50505050505b611e8b86604001518760c0015188600001518960a001516131a7565b6040870180519190910390526101208601516060015115611ec857611eb18660006133fa565b925090508015611ec8578561012001516020015192505b80611ee257611ed88660006135f8565b91508560e0015192505b6000611f0173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc261383a565b1115611fe7576040516370a0823160e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d9082906370a0823190611f46903090600401614a5f565b602060405180830381600087803b158015611f6057600080fd5b505af1158015611f74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9891906145d2565b6040518263ffffffff1660e01b8152600401611fb49190614c38565b600060405180830381600087803b158015611fce57600080fd5b505af1158015611fe2573d6000803e3d6000fd5b505050505b60208601516001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2141561208a57612022866080015187604001516138e4565b61203f73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee61383a565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906120845760405162461bcd60e51b81526004016113cc9190614c8d565b506120f0565b61209c866080015187604001516138e4565b6120a9876020015161383a565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906120ee5760405162461bcd60e51b81526004016113cc9190614c8d565b505b509092509050915091565b60006121068361390c565b156121df57826001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561214457600080fd5b505afa158015612158573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217c919061441c565b6001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b1580156121b657600080fd5b505af11580156121ca573d6000803e3d6000fd5b50505050506121d8826139e9565b90506121f4565b6121f16121ec8484613a0b565b6139e9565b90505b61227a8383856001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561223257600080fd5b505afa158015612246573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226a919061441c565b6001600160a01b03169190613a8d565b604051633b4da69f60e01b81526001600160a01b03841690633b4da69f906122a89030908690600401614bd0565b600060405180830381600087803b1580156122c257600080fd5b505af11580156122d6573d6000803e3d6000fd5b5050604051632c2cb9fd60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250637608870391506001600160a01b03881690632c2cb9fd90612322908990600401614c38565b60206040518083038186803b15801561233a57600080fd5b505afa15801561234e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061237291906145d2565b604051632726b07360e01b81526001600160a01b03891690632726b0739061239e908a90600401614c38565b60206040518083038186803b1580156123b657600080fd5b505afa1580156123ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ee919061441c565b30308660006040518763ffffffff1660e01b815260040161241496959493929190614c58565b600060405180830381600087803b15801561242e57600080fd5b505af1158015612442573d6000803e3d6000fd5b505050505050505050565b6000808290506000846001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561248e57600080fd5b505afa1580156124a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c691906145d2565b905060128111156124e95760405162461bcd60e51b81526004016113cc90614cd7565b806012146124fd5780601203600a0a840291505b866001600160a01b03166345e6bdcd87612516856139e9565b60000360006040518463ffffffff1660e01b815260040161253993929190614e30565b600060405180830381600087803b15801561255357600080fd5b505af1158015612567573d6000803e3d6000fd5b50506040516313771f0760e31b81526001600160a01b038a169250639bb8f838915061259b90899030908790600401614ded565b600060405180830381600087803b1580156125b557600080fd5b505af11580156125c9573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038816925063ef693bed91506125fb9030908890600401614bd0565b600060405180830381600087803b15801561261557600080fd5b505af1158015612629573d6000803e3d6000fd5b505050506126368561390c565b1561270a57846001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561267457600080fd5b505afa158015612688573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ac919061441c565b6001600160a01b0316632e1a7d4d856040518263ffffffff1660e01b81526004016126d79190614c38565b600060405180830381600087803b1580156126f157600080fd5b505af1158015612705573d6000803e3d6000fd5b505050505b509195945050505050565b604051632726b07360e01b81526000906001600160a01b03871690632726b07390612744908890600401614c38565b60206040518083038186803b15801561275c57600080fd5b505afa158015612770573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612794919061441c565b905060006127b87335d1b3f3d7966a1dfe207aa4514c12a259a0492b838488613acc565b90508084111561285b57736b175474e89094c44da98b954eedeac495271d0f63a9059cbb846127e787856117ee565b6040518363ffffffff1660e01b8152600401612804929190614bd0565b602060405180830381600087803b15801561281e57600080fd5b505af1158015612832573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128569190614571565b508093505b604051636eb1769f60e11b8152736b175474e89094c44da98b954eedeac495271d0f9063dd62ed3e906128a8903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614a73565b60206040518083038186803b1580156128c057600080fd5b505afa1580156128d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128f891906145d2565b61299f5760405163095ea7b360e01b8152736b175474e89094c44da98b954eedeac495271d0f9063095ea7b39061294b90739759a6ac90977b93b58547b4a71c78317f391a289060001990600401614bd0565b602060405180830381600087803b15801561296557600080fd5b505af1158015612979573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299d9190614571565b505b604051633b4da69f60e01b8152739759a6ac90977b93b58547b4a71c78317f391a2890633b4da69f906129d89085908890600401614bd0565b600060405180830381600087803b1580156129f257600080fd5b505af1158015612a06573d6000803e3d6000fd5b50505050866001600160a01b03166345e6bdcd876000612a3b7335d1b3f3d7966a1dfe207aa4514c12a259a0492b878b613ca7565b6040518463ffffffff1660e01b8152600401612a5993929190614e30565b600060405180830381600087803b158015612a7357600080fd5b505af1158015612a87573d6000803e3d6000fd5b5050505050505050505050565b6000612aa38260a00151610d8d565b90506000612ab5828460000151610791565b8351604051632c2cb9fd60e01b81529192506000916001600160a01b03851691632c2cb9fd91612ae89190600401614c38565b60206040518083038186803b158015612b0057600080fd5b505afa158015612b14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b3891906145d2565b90506000612b5084866000015184886080015161126e565b90506000612b6885876000015188608001518561244d565b9050612b78866040015182613027565b60408801526001600160a01b03841660c0880152612b94611c2e565b612ba057610190612ba4565b61014d5b60a08801526000612bb488611db4565b915050612bc981611140896020015184611cbd565b9050612bdc868860000151868489612715565b612c018688600001518960800151612bfc8b604001518c60600151613027565b61244d565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338a60000151898d6040015187604051602001612c469493929190614e0c565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612c7393929190614b33565b600060405180830381600087803b158015612c8d57600080fd5b505af1158015612ca1573d6000803e3d6000fd5b505050505050505050505050565b6000612cbe8260a00151610d8d565b90506000612cd0828460000151610791565b8351604051632c2cb9fd60e01b8152919250600091612d5a9185916001600160a01b03831690632c2cb9fd90612d0a908490600401614c38565b60206040518083038186803b158015612d2257600080fd5b505afa158015612d36573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c391906145d2565b8451604051632c2cb9fd60e01b8152919250600091612dea9186916001600160a01b03831690632c2cb9fd90612d94908490600401614c38565b60206040518083038186803b158015612dac57600080fd5b505afa158015612dc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612de491906145d2565b856117fe565b9050612e18612dfd828760400151613027565b6111408760200151612e13858a60400151613027565b611cbd565b60408701526001600160a01b03831660c0870152612e34611c2e565b612e4057610190612e44565b61014d5b60a08701526000612e5487611db4565b915050612e6b8587600001518860800151846120fb565b8551604051632c2cb9fd60e01b8152612f069187916001600160a01b03831690632c2cb9fd90612e9f908490600401614c38565b60206040518083038186803b158015612eb757600080fd5b505afa158015612ecb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eef91906145d2565b612f018a604001518b60600151613027565b6117fe565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338960000151888c6040015187604051602001612f4b9493929190614e0c565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612a5993929190614a8d565b600082820183811015610ef65760405162461bcd60e51b81526004016113cc90614ca0565b6002546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b158015612fe257600080fd5b505afa158015612ff6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061301a919061441c565b90506117ba818484613e65565b8082018281101561088757600080fd5b606061308c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613efb9092919063ffffffff16565b8051909150156117ba57808060200190518101906130aa9190614571565b6117ba5760405162461bcd60e51b81526004016113cc90614d3e565b60006130dd84676765c793fa10079d601b1b6117bf565b821015610ef6576131138361310661310087676765c793fa10079d601b1b6117bf565b856117ee565b8161310d57fe5b046139e9565b905061312a84676765c793fa10079d601b1b6117bf565b61313482856117bf565b1061313f5780610a5b565b6001019392505050565b600061088782676765c793fa10079d601b1b6117bf565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461318c5781610887565b5073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2919050565b6000811580159061323a5750604051632cdc77ab60e21b8152731b14e8d511c9a4395425314f849bd737baf8208f9063b371deac906131ea908790600401614a5f565b60206040518083038186803b15801561320257600080fd5b505afa158015613216573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061323a9190614571565b156132c957604051636eeb543160e01b8152731b14e8d511c9a4395425314f849bd737baf8208f90636eeb543190613276908790600401614a5f565b60206040518083038186803b15801561328e57600080fd5b505afa1580156132a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c691906145d2565b91505b816132d657506000610a5b565b8185816132df57fe5b049050600a85048111156132f35750600a84045b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561334257600080fd5b505afa158015613356573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061337a919061441c565b90506001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156133dd576040516001600160a01b0382169083156108fc029084906000818181858888f193505050501580156133d7573d6000803e3d6000fd5b506133f1565b6133f16001600160a01b0385168284611764565b50949350505050565b610120820151602001516040516302f5cc7960e11b81526000918291734ba1f38427b33b8ab7bb0490200dae1f1c36823f916305eb98f29161343f9190600401614a5f565b60206040518083038186803b15801561345757600080fd5b505afa15801561346b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348f9190614571565b61349e575060009050806135f1565b6101208401515160405163e0aa279760e01b81527325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa2797916134db9190600401614a5f565b60206040518083038186803b1580156134f357600080fd5b505afa158015613507573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061352b9190614571565b61353a575060009050806135f1565b610120840151516040850151855161355d926001600160a01b0390911691611764565b610120840151805160809091015160405163097396a160e31b81526001600160a01b0390921691634b9cb508919061359b9088908890600401614dc1565b60408051808303818588803b1580156135b357600080fd5b505af11580156135c7573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906135ec919061458d565b915091505b9250929050565b60e082015160405163e0aa279760e01b81526000917325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa27979161363591600401614a5f565b60206040518083038186803b15801561364d57600080fd5b505afa158015613661573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136859190614571565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b815250906136cb5760405162461bcd60e51b81526004016113cc9190614c8d565b5060e0830151604084015184516136ed926001600160a01b0390911691611764565b60008260018111156136fb57fe5b14156137a1578260e001516001600160a01b0316635b6f36fc8460000151856020015186604001518761010001516040518563ffffffff1660e01b81526004016137489493929190614be9565b602060405180830381600087803b15801561376257600080fd5b505af1158015613776573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061379a91906145d2565b9050610887565b8260e001516001600160a01b0316633924db668460000151856020015186606001518761010001516040518563ffffffff1660e01b81526004016137e89493929190614be9565b602060405180830381600087803b15801561380257600080fd5b505af1158015613816573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef691906145d2565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156138685750476106d7565b6040516370a0823160e01b81526001600160a01b038316906370a0823190613894903090600401614a5f565b60206040518083038186803b1580156138ac57600080fd5b505afa1580156138c0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088791906145d2565b6000670de0b6b3a76400006117556138fc85856117bf565b6002670de0b6b3a764000061174f565b6000739759a6ac90977b93b58547b4a71c78317f391a286001600160a01b038316141561393b575060006106d7565b816001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561397457600080fd5b505afa158015613988573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139ac919061441c565b6001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031614156139e1575060016106d7565b506000919050565b8060008112156106d75760405162461bcd60e51b81526004016113cc90614d88565b6000610ef682846001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b158015613a4a57600080fd5b505afa158015613a5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a8291906145d2565b601203600a0a6117bf565b613aad8363095ea7b360e01b846000604051602401611783929190614c1c565b6117ba8363095ea7b360e01b8484604051602401611783929190614bd0565b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b8152600401613afb9190614c38565b60a06040518083038186803b158015613b1357600080fd5b505afa158015613b27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b4b91906148c4565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b8152600401613b81929190614c41565b604080518083038186803b158015613b9857600080fd5b505afa158015613bac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bd091906148a1565b9150506000876001600160a01b0316636c25b346886040518263ffffffff1660e01b8152600401613c019190614a5f565b60206040518083038186803b158015613c1957600080fd5b505afa158015613c2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c5191906145d2565b90506000613c62610ee284866117bf565b9050676765c793fa10079d601b1b8104945080613c8a86676765c793fa10079d601b1b6117bf565b10613c955784613c9a565b846001015b9998505050505050505050565b600080846001600160a01b0316636c25b346856040518263ffffffff1660e01b8152600401613cd69190614a5f565b60206040518083038186803b158015613cee57600080fd5b505afa158015613d02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d2691906145d2565b90506000856001600160a01b031663d9638d36856040518263ffffffff1660e01b8152600401613d569190614c38565b60a06040518083038186803b158015613d6e57600080fd5b505afa158015613d82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613da691906148c4565b5050509150506000866001600160a01b0316632424be5c86886040518363ffffffff1660e01b8152600401613ddc929190614c41565b604080518083038186803b158015613df357600080fd5b505afa158015613e07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e2b91906148a1565b915050613e3a82848161310d57fe5b935080841115613e5557613e4d816139e9565b600003613e5a565b836000035b979650505050505050565b613e6d613f0a565b6001600160a01b0316826001600160a01b03161415613ee757826001600160a01b031681604051613e9d90614a5c565b60006040518083038185875af1925050503d8060008114613eda576040519150601f19603f3d011682016040523d82523d6000602084013e613edf565b606091505b5050506117ba565b6117ba6001600160a01b0383168483611764565b6060610a5b8484600085613f22565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b6060613f2d85613fe6565b613f495760405162461bcd60e51b81526004016113cc90614d07565b60006060866001600160a01b03168587604051613f669190614a40565b60006040518083038185875af1925050503d8060008114613fa3576040519150601f19603f3d011682016040523d82523d6000602084013e613fa8565b606091505b50915091508115613fbc579150610a5b9050565b805115613fcc5780518082602001fd5b8360405162461bcd60e51b81526004016113cc9190614c8d565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610a5b575050151592915050565b60405180610140016040528060006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016140966140df565b905290565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016000600181111561409657fe5b6040518060c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001606081525090565b803561088781614ecf565b805161088781614ecf565b600082601f830112614156578081fd5b813561416961416482614e7b565b614e54565b915080825283602082850101111561418057600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126141a9578081fd5b81516141b761416482614e7b565b91508082528360208285010111156141ce57600080fd5b6141df816020840160208601614e9f565b5092915050565b80356002811061088757600080fd5b6000610140808385031215614208578182fd5b61421181614e54565b91505061421e8383614130565b815261422d8360208401614130565b602082015260408201356040820152606082013560608201526080820135608082015260a082013560a08201526142678360c08401614130565b60c08201526142798360e08401614130565b60e08201526101008083013567ffffffffffffffff8082111561429b57600080fd5b6142a786838701614146565b838501526101209250828501359150808211156142c357600080fd5b506142d0858286016142dc565b82840152505092915050565b600060c082840312156142ed578081fd5b6142f760c0614e54565b9050813561430481614ecf565b8152602082013561431481614ecf565b6020820152604082013561432781614ecf565b80604083015250606082013560608201526080820135608082015260a082013567ffffffffffffffff81111561435c57600080fd5b61436884828501614146565b60a08301525092915050565b600060c08284031215614385578081fd5b61438f60c0614e54565b9050815161439c81614ecf565b815260208201516143ac81614ecf565b602082015260408201516143bf81614ecf565b80604083015250606082015160608201526080820151608082015260a082015167ffffffffffffffff8111156143f457600080fd5b61436884828501614199565b600060208284031215614411578081fd5b8135610ef681614ecf565b60006020828403121561442d578081fd5b8151610ef681614ecf565b6000806040838503121561444a578081fd5b823561445581614ecf565b946020939093013593505050565b600080600060608486031215614477578081fd5b833561448281614ecf565b95602085013595506040909401359392505050565b600080600080608085870312156144ac578182fd5b84356144b781614ecf565b9350602085013592506040850135915060608501356144d581614ecf565b939692955090935050565b6000806000806000608086880312156144f7578283fd5b853561450281614ecf565b94506020860135935060408601359250606086013567ffffffffffffffff8082111561452c578283fd5b818801915088601f83011261453f578283fd5b81358181111561454d578384fd5b89602082850101111561455e578384fd5b9699959850939650602001949392505050565b600060208284031215614582578081fd5b8151610ef681614ee7565b6000806040838503121561459f578182fd5b82516145aa81614ee7565b6020939093015192949293505050565b6000602082840312156145cb578081fd5b5035919050565b6000602082840312156145e3578081fd5b5051919050565b6000602082840312156145fb578081fd5b813567ffffffffffffffff811115614611578182fd5b61088384828501614146565b60008060008060008060c08789031215614635578384fd5b863567ffffffffffffffff81111561464b578485fd5b61465789828a01614146565b9650506020870135945060408701359350606087013561467681614ecf565b9250608087013561468681614ee7565b915060a087013560ff8116811461469b578182fd5b809150509295509295509295565b6000806040838503121561444a578182fd5b600080604083850312156146cd578182fd5b82516145aa81614ecf565b6000602082840312156146e9578081fd5b610ef683836141e6565b600060208284031215614704578081fd5b813567ffffffffffffffff81111561471a578182fd5b610883848285016141f5565b600060208284031215614737578081fd5b815167ffffffffffffffff8082111561474e578283fd5b8184019150610140808387031215614764578384fd5b61476d81614e54565b9050614779868461413b565b8152614788866020850161413b565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201526147c28660c0850161413b565b60c08201526147d48660e0850161413b565b60e082015261010080840151838111156147ec578586fd5b6147f888828701614199565b8284015250506101208084015183811115614811578586fd5b61481d88828701614374565b918301919091525095945050505050565b600080600080600060a08688031215614845578283fd5b853567ffffffffffffffff81111561485b578384fd5b614867888289016141f5565b9550506020860135935060408601359250606086013561488681614ecf565b915061489587608088016141e6565b90509295509295909350565b600080604083850312156148b3578182fd5b505080516020909101519092909150565b600080600080600060a086880312156148db578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b6001600160a01b03169052565b60008151808452614928816020860160208601614e9f565b601f01601f19169290920160200192915050565b600061014061494c848451614903565b602083015161495e6020860182614903565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015161499960c0860182614903565b5060e08301516149ac60e0860182614903565b506101008084015182828701526149c583870182614910565b9250505061012080840151858303828701526149e183826149eb565b9695505050505050565b600060018060a01b0380835116845280602084015116602085015280604084015116604085015250606082015160608401526080820151608084015260a082015160c060a085015261088360c0850182614910565b60008251614a52818460208701614e9f565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c1350d1119b185cda109bdbdcdd609a1b60a082015260c060608201819052600090614ade90830184614910565b95945050505050565b6001600160a01b03848116825283166020820152608060408201819052600890820152671350d1109bdbdcdd60c21b60a082015260c060608201819052600090614ade90830184614910565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c4d4344466c617368526570617960981b60a082015260c060608201819052600090614ade90830184614910565b6001600160a01b03848116825283166020820152608060408201819052600890820152674d4344526570617960c01b60a082015260c060608201819052600090614ade90830184614910565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906149e190830184614910565b6001600160a01b0392909216825260ff16602082015260400190565b90815260200190565b9182526001600160a01b0316602082015260400190565b9586526001600160a01b039485166020870152928416604086015292166060840152608083019190915260a082015260c00190565b600060208252610ef66020830184614910565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b602080825260169082015275546f6b656e20646563696d616c7320746f6f2062696760501b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600c908201526b696e742d6f766572666c6f7760a01b604082015260600190565b600060208252610ef6602083018461493c565b600060408252614dd4604083018561493c565b905060028310614de057fe5b8260208301529392505050565b9283526001600160a01b03919091166020830152604082015260600190565b9384526001600160a01b039290921660208401526040830152606082015260800190565b9283526020830191909152604082015260600190565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715614e7357600080fd5b604052919050565b600067ffffffffffffffff821115614e91578081fd5b50601f01601f191660200190565b60005b83811015614eba578181015183820152602001614ea2565b83811115614ec9576000848401525b50505050565b6001600160a01b0381168114614ee457600080fd5b50565b8015158114614ee457600080fdfea26469706673582212201a2cf479e908fd9855096af3a224a6ccc54d175af895b69b7b272aaa1b3c93c364736f6c634300060c0033
Deployed Bytecode
0x60806040526004361061026b5760003560e01c80638c8a795811610144578063c72c4d10116100b6578063dd6d903c1161007a578063dd6d903c1461060f578063deca5f881461062f578063e870b9cd1461064f578063ee87255814610662578063f24ccbfe14610682578063f851a4401461069757610272565b8063c72c4d10146105d2578063c7975824146105e7578063cc694d48146105fa578063cf786f8f146103bc578063cfac57c7146105a857610272565b8063a46a66c911610108578063a46a66c914610549578063a7304bf71461055e578063acbeba611461057e578063ae08fd1014610593578063c11645bc146105a8578063c50ebaf8146105bd57610272565b80638c8a7958146104c85780638da5cb5b146104dd57806398ab3d49146104f2578063a342f23814610507578063a3b8e5d11461051c57610272565b806336569e77116101dd5780634d2ab9dc116101a15780634d2ab9dc146104495780634d93667e1461045e578063526d64611461047e5780636738929f1461035257806381b94280146104935780638aa0fd0e146104a857610272565b806336569e77146103bc5780633a128322146103d15780634115fe6b146103f157806341c0e1b51461041f578063449b9ffa1461043457610272565b806329f7fc9e1161022f57806329f7fc9e1461031b5780632a4c0a1a1461033d5780632e77468d146103525780632f634a9014610367578063314b63321461038757806331d98b3f1461039c57610272565b806304c9805c1461027757806308d4f52a146102a2578063186cab76146102cf5780631e48907b146102e4578063278d58311461030657610272565b3661027257005b600080fd5b34801561028357600080fd5b5061028c6106ac565b6040516102999190614c38565b60405180910390f35b3480156102ae57600080fd5b506102c26102bd3660046146f3565b6106b2565b6040516102999190614c8d565b3480156102db57600080fd5b5061028c6106dc565b3480156102f057600080fd5b506103046102ff366004614400565b6106e8565b005b34801561031257600080fd5b506102c2610721565b34801561032757600080fd5b50610330610749565b6040516102999190614a5f565b34801561034957600080fd5b50610330610761565b34801561035e57600080fd5b50610330610779565b34801561037357600080fd5b506103306103823660046146a9565b610791565b34801561039357600080fd5b5061033061088d565b3480156103a857600080fd5b5061028c6103b73660046145ba565b6108a5565b3480156103c857600080fd5b50610330610a63565b3480156103dd57600080fd5b506103046103ec366004614438565b610a7b565b3480156103fd57600080fd5b5061041161040c366004614463565b610b14565b604051610299929190614e46565b34801561042b57600080fd5b50610304610d30565b34801561044057600080fd5b506102c2610d55565b34801561045557600080fd5b5061028c610d87565b34801561046a57600080fd5b506103306104793660046146d8565b610d8d565b34801561048a57600080fd5b50610330610dec565b34801561049f57600080fd5b50610330610e04565b3480156104b457600080fd5b5061028c6104c3366004614463565b610e1c565b3480156104d457600080fd5b50610330610efd565b3480156104e957600080fd5b50610330610f15565b3480156104fe57600080fd5b50610330610f24565b34801561051357600080fd5b50610330610f33565b34801561052857600080fd5b5061053c6105373660046145ea565b610f4b565b6040516102999190614dae565b34801561055557600080fd5b50610330610f67565b34801561056a57600080fd5b50610304610579366004614400565b610f7f565b34801561058a57600080fd5b50610330610fb8565b34801561059f57600080fd5b506102c2610fd0565b3480156105b457600080fd5b50610330611001565b3480156105c957600080fd5b506102c2611019565b3480156105de57600080fd5b50610330611048565b6103046105f536600461482e565b611057565b34801561060657600080fd5b506102c2611243565b34801561061b57600080fd5b5061028c61062a366004614497565b61126e565b34801561063b57600080fd5b5061030461064a366004614400565b611401565b61030461065d36600461482e565b61142e565b34801561066e57600080fd5b5061030461067d3660046144e0565b61160f565b34801561068e57600080fd5b506103306116fe565b3480156106a357600080fd5b50610330611716565b61014d81565b6060816040516020016106c59190614dae565b60405160208183030381529060405290505b919050565b644554482d4160d81b81565b6001546001600160a01b031633146106ff57600080fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b81525081565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b736b175474e89094c44da98b954eedeac495271d0f81565b7365c79fcb50ca1594b025960e539ed7a9a6d434a381565b600080836001600160a01b0316638161b120846040518263ffffffff1660e01b81526004016107c09190614c38565b60206040518083038186803b1580156107d857600080fd5b505afa1580156107ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610810919061441c565b9050806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561084b57600080fd5b505afa15801561085f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610883919061441c565b9150505b92915050565b7325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d81565b604051636cb1c69b60e11b815260009081907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906108e1908690600401614c38565b604080518083038186803b1580156108f857600080fd5b505afa15801561090c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093091906146bb565b604051636cb1c69b60e11b8152909250600091507335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063d9638d369061096e908790600401614c38565b60a06040518083038186803b15801561098657600080fd5b505afa15801561099a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109be91906148c4565b505092505050610a5b610a55827365c79fcb50ca1594b025960e539ed7a9a6d434a36001600160a01b031663495d32cb6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1857600080fd5b505afa158015610a2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5091906145d2565b611725565b83611725565b949350505050565b7335d1b3f3d7966a1dfe207aa4514c12a259a0492b81565b6000546001600160a01b03163314610a9257600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b0383161415610af657600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015610af0573d6000803e3d6000fd5b50610b10565b600054610b10906001600160a01b03848116911683611764565b5050565b6000806000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5257600080fd5b505afa158015610b66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8a919061441c565b90506000866001600160a01b0316632726b073876040518263ffffffff1660e01b8152600401610bba9190614c38565b60206040518083038186803b158015610bd257600080fd5b505afa158015610be6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0a919061441c565b9050600080836001600160a01b0316632424be5c88856040518363ffffffff1660e01b8152600401610c3d929190614c41565b604080518083038186803b158015610c5457600080fd5b505afa158015610c68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8c91906148a1565b915091506000846001600160a01b031663d9638d36896040518263ffffffff1660e01b8152600401610cbe9190614c38565b60a06040518083038186803b158015610cd657600080fd5b505afa158015610cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0e91906148c4565b50505091505082610d1f8383611725565b965096505050505050935093915050565b6000546001600160a01b03163314610d4757600080fd5b6000546001600160a01b0316ff5b6040518060400160405280601681526020017516995c9bde08195e18da185b99d9481a5b9d985b1a5960521b81525081565b61019081565b600080826001811115610d9c57fe5b1415610dbd5750735ef30b9986345249bc32d8928b7ee64de9435e396106d7565b6001826001811115610dcb57fe5b14156106d75750733f30c2381cd8b917dd96eb2f1a4f96d91324bbed6106d7565b73637726f8b08a7abe3ae3acab01a80e2d8ddef77b81565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600080610e28836108a5565b604051636cb1c69b60e11b81529091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d3690610e65908790600401614c38565b604080518083038186803b158015610e7c57600080fd5b505afa158015610e90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb491906146bb565b915050600080610ec5888888610b14565b91509150610eef610ee8610ee2610edc85886117bf565b866117e3565b836117ee565b600a6117ee565b9450505050505b9392505050565b734ba1f38427b33b8ab7bb0490200dae1f1c36823f81565b6000546001600160a01b031681565b6003546001600160a01b031681565b7339c4a92dc506300c3ea4c67ca4ca611102ee6f2a81565b610f5361401f565b818060200190518101906108879190614726565b731b14e8d511c9a4395425314f849bd737baf8208f81565b6001546001600160a01b03163314610f9657600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b7319c0976f590d67707e62397c87829d896dc0f1f181565b6040518060400160405280601581526020017413d99998da185a5b8819185d18481a5b9d985b1a59605a1b81525081565b739759a6ac90977b93b58547b4a71c78317f391a2881565b604051806040016040528060138152602001724465737420616d6f756e74206d697373696e6760681b81525081565b6002546001600160a01b031681565b600061106282610d8d565b905060006110708287610791565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016110a09190614c38565b60206040518083038186803b1580156110b857600080fd5b505afa1580156110cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f091906145d2565b905060006111048489848c604001516117fe565b6001600160a01b03841660c08b0152905061111d611c2e565b6111295761019061112d565b61014d5b60a08a0152611145816111408982611cbd565b6117ee565b60408a015260006111558a611db4565b915050611164858a89846120fb565b47156111985760405132904780156108fc02916000818181858888f19350505050158015611196573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338c888f60400151876040516020016111d89493929190614e0c565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161120593929190614ae7565b600060405180830381600087803b15801561121f57600080fd5b505af1158015611233573d6000803e3d6000fd5b5050505050505050505050505050565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b81525081565b60008061127a846108a5565b905060008061128a888888610b14565b604051636cb1c69b60e11b815291935091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906112c9908a90600401614c38565b604080518083038186803b1580156112e057600080fd5b505afa1580156112f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061131891906146bb565b91505060006113348461114061132e85876117bf565b886117e3565b90506000876001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561137157600080fd5b505afa158015611385573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a991906145d2565b905060128111156113d55760405162461bcd60e51b81526004016113cc90614cd7565b60405180910390fd5b600081601203600a0a83816113e657fe5b04905060646063820204975050505050505050949350505050565b6000546001600160a01b0316331461141857600080fd5b6001546001600160a01b031615610f9657600080fd5b600061143982610d8d565b905060006114478287610791565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016114779190614c38565b60206040518083038186803b15801561148f57600080fd5b505afa1580156114a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c791906145d2565b90506114d98388878b6040015161244d565b506001600160a01b03821660c08901526114f1611c2e565b6114fd57610190611501565b61014d5b60a0890152600061151189611db4565b915050611522816111408984611cbd565b90506115318489848487612715565b47156115655760405132904780156108fc02916000818181858888f19350505050158015611563573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338b878e60400151876040516020016115a59493929190614e0c565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016115d293929190614b84565b600060405180830381600087803b1580156115ec57600080fd5b505af1158015611600573d6000803e3d6000fd5b50505050505050505050505050565b60606000808080806116238789018961461d565b95509550955095509550955061163761401f565b61164087610f4b565b905061164a61409b565b6040518060c001604052808881526020018781526020018d81526020018c8152602001866001600160a01b031681526020018460ff16600181111561168b57fe5b600181111561169657fe5b9052905083156116af576116aa8282612a94565b6116b9565b6116b98282612caf565b6116cc8d6116c78e8e612f78565b612f9d565b47156116005760405132904780156108fc02916000818181858888f19350505050158015611233573d6000803e3d6000fd5b735c55b921f590a89c1ebe84df170e655a82b6212681565b6001546001600160a01b031681565b6000676765c793fa10079d601b1b61175561174085856117bf565b6002676765c793fa10079d601b1b5b04613027565b8161175c57fe5b049392505050565b6117ba8363a9059cbb60e01b8484604051602401611783929190614bd0565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613037565b505050565b60008115806117da575050808202828282816117d757fe5b04145b61088757600080fd5b600081838161175c57fe5b8082038281111561088757600080fd5b60405163089c54b560e31b815260009081907319c0976f590d67707e62397c87829d896dc0f1f1906344e2a5a89061183a908790600401614c38565b602060405180830381600087803b15801561185457600080fd5b505af1158015611868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188c91906145d2565b905060007335d1b3f3d7966a1dfe207aa4514c12a259a0492b6001600160a01b0316636c25b346886001600160a01b0316632726b073896040518263ffffffff1660e01b81526004016118df9190614c38565b60206040518083038186803b1580156118f757600080fd5b505afa15801561190b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192f919061441c565b6040518263ffffffff1660e01b815260040161194b9190614a5f565b60206040518083038186803b15801561196357600080fd5b505afa158015611977573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061199b91906145d2565b905060006119aa888888610e1c565b90508085106119c1576119be8160016117ee565b94505b876001600160a01b03166345e6bdcd8860006119de8988886130c6565b6040518463ffffffff1660e01b81526004016119fc93929190614e30565b600060405180830381600087803b158015611a1657600080fd5b505af1158015611a2a573d6000803e3d6000fd5b50505050876001600160a01b031663f9f30db68830611a4889613149565b6040518463ffffffff1660e01b8152600401611a6693929190614ded565b600060405180830381600087803b158015611a8057600080fd5b505af1158015611a94573d6000803e3d6000fd5b5050604051634538c4eb60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250634538c4eb9150611ae5903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614a73565b60206040518083038186803b158015611afd57600080fd5b505afa158015611b11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3591906145d2565b611bb7576040516328ec8bf160e21b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063a3b22fc490611b8490739759a6ac90977b93b58547b4a71c78317f391a2890600401614a5f565b600060405180830381600087803b158015611b9e57600080fd5b505af1158015611bb2573d6000803e3d6000fd5b505050505b60405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a289063ef693bed90611bf09030908990600401614bd0565b600060405180830381600087803b158015611c0a57600080fd5b505af1158015611c1e573d6000803e3d6000fd5b50969a9950505050505050505050565b6040516320eb73ed60e11b815260009073637726f8b08a7abe3ae3acab01a80e2d8ddef77b906341d6e7da90611c68903290600401614a5f565b60206040518083038186803b158015611c8057600080fd5b505afa158015611c94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb89190614571565b905090565b60008215611dab576000611cd8644554482d4160d81b6108a5565b90506000611ce68583611725565b905060058404811115611cf95750600583045b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b158015611d4857600080fd5b505afa158015611d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d80919061441c565b9050611da1736b175474e89094c44da98b954eedeac495271d0f8284611764565b5091506108879050565b50600092915050565b600080600080600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b031686600001516001600160a01b03161415611e6f578551611df990613160565b6001600160a01b031686526040808701518151630d0e30db60e41b8152915173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29263d0e30db09291600480830192600092919082900301818588803b158015611e5557600080fd5b505af1158015611e69573d6000803e3d6000fd5b50505050505b611e8b86604001518760c0015188600001518960a001516131a7565b6040870180519190910390526101208601516060015115611ec857611eb18660006133fa565b925090508015611ec8578561012001516020015192505b80611ee257611ed88660006135f8565b91508560e0015192505b6000611f0173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc261383a565b1115611fe7576040516370a0823160e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d9082906370a0823190611f46903090600401614a5f565b602060405180830381600087803b158015611f6057600080fd5b505af1158015611f74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9891906145d2565b6040518263ffffffff1660e01b8152600401611fb49190614c38565b600060405180830381600087803b158015611fce57600080fd5b505af1158015611fe2573d6000803e3d6000fd5b505050505b60208601516001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2141561208a57612022866080015187604001516138e4565b61203f73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee61383a565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906120845760405162461bcd60e51b81526004016113cc9190614c8d565b506120f0565b61209c866080015187604001516138e4565b6120a9876020015161383a565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906120ee5760405162461bcd60e51b81526004016113cc9190614c8d565b505b509092509050915091565b60006121068361390c565b156121df57826001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561214457600080fd5b505afa158015612158573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217c919061441c565b6001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b1580156121b657600080fd5b505af11580156121ca573d6000803e3d6000fd5b50505050506121d8826139e9565b90506121f4565b6121f16121ec8484613a0b565b6139e9565b90505b61227a8383856001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561223257600080fd5b505afa158015612246573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226a919061441c565b6001600160a01b03169190613a8d565b604051633b4da69f60e01b81526001600160a01b03841690633b4da69f906122a89030908690600401614bd0565b600060405180830381600087803b1580156122c257600080fd5b505af11580156122d6573d6000803e3d6000fd5b5050604051632c2cb9fd60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250637608870391506001600160a01b03881690632c2cb9fd90612322908990600401614c38565b60206040518083038186803b15801561233a57600080fd5b505afa15801561234e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061237291906145d2565b604051632726b07360e01b81526001600160a01b03891690632726b0739061239e908a90600401614c38565b60206040518083038186803b1580156123b657600080fd5b505afa1580156123ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ee919061441c565b30308660006040518763ffffffff1660e01b815260040161241496959493929190614c58565b600060405180830381600087803b15801561242e57600080fd5b505af1158015612442573d6000803e3d6000fd5b505050505050505050565b6000808290506000846001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561248e57600080fd5b505afa1580156124a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c691906145d2565b905060128111156124e95760405162461bcd60e51b81526004016113cc90614cd7565b806012146124fd5780601203600a0a840291505b866001600160a01b03166345e6bdcd87612516856139e9565b60000360006040518463ffffffff1660e01b815260040161253993929190614e30565b600060405180830381600087803b15801561255357600080fd5b505af1158015612567573d6000803e3d6000fd5b50506040516313771f0760e31b81526001600160a01b038a169250639bb8f838915061259b90899030908790600401614ded565b600060405180830381600087803b1580156125b557600080fd5b505af11580156125c9573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038816925063ef693bed91506125fb9030908890600401614bd0565b600060405180830381600087803b15801561261557600080fd5b505af1158015612629573d6000803e3d6000fd5b505050506126368561390c565b1561270a57846001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561267457600080fd5b505afa158015612688573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ac919061441c565b6001600160a01b0316632e1a7d4d856040518263ffffffff1660e01b81526004016126d79190614c38565b600060405180830381600087803b1580156126f157600080fd5b505af1158015612705573d6000803e3d6000fd5b505050505b509195945050505050565b604051632726b07360e01b81526000906001600160a01b03871690632726b07390612744908890600401614c38565b60206040518083038186803b15801561275c57600080fd5b505afa158015612770573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612794919061441c565b905060006127b87335d1b3f3d7966a1dfe207aa4514c12a259a0492b838488613acc565b90508084111561285b57736b175474e89094c44da98b954eedeac495271d0f63a9059cbb846127e787856117ee565b6040518363ffffffff1660e01b8152600401612804929190614bd0565b602060405180830381600087803b15801561281e57600080fd5b505af1158015612832573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128569190614571565b508093505b604051636eb1769f60e11b8152736b175474e89094c44da98b954eedeac495271d0f9063dd62ed3e906128a8903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614a73565b60206040518083038186803b1580156128c057600080fd5b505afa1580156128d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128f891906145d2565b61299f5760405163095ea7b360e01b8152736b175474e89094c44da98b954eedeac495271d0f9063095ea7b39061294b90739759a6ac90977b93b58547b4a71c78317f391a289060001990600401614bd0565b602060405180830381600087803b15801561296557600080fd5b505af1158015612979573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299d9190614571565b505b604051633b4da69f60e01b8152739759a6ac90977b93b58547b4a71c78317f391a2890633b4da69f906129d89085908890600401614bd0565b600060405180830381600087803b1580156129f257600080fd5b505af1158015612a06573d6000803e3d6000fd5b50505050866001600160a01b03166345e6bdcd876000612a3b7335d1b3f3d7966a1dfe207aa4514c12a259a0492b878b613ca7565b6040518463ffffffff1660e01b8152600401612a5993929190614e30565b600060405180830381600087803b158015612a7357600080fd5b505af1158015612a87573d6000803e3d6000fd5b5050505050505050505050565b6000612aa38260a00151610d8d565b90506000612ab5828460000151610791565b8351604051632c2cb9fd60e01b81529192506000916001600160a01b03851691632c2cb9fd91612ae89190600401614c38565b60206040518083038186803b158015612b0057600080fd5b505afa158015612b14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b3891906145d2565b90506000612b5084866000015184886080015161126e565b90506000612b6885876000015188608001518561244d565b9050612b78866040015182613027565b60408801526001600160a01b03841660c0880152612b94611c2e565b612ba057610190612ba4565b61014d5b60a08801526000612bb488611db4565b915050612bc981611140896020015184611cbd565b9050612bdc868860000151868489612715565b612c018688600001518960800151612bfc8b604001518c60600151613027565b61244d565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338a60000151898d6040015187604051602001612c469493929190614e0c565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612c7393929190614b33565b600060405180830381600087803b158015612c8d57600080fd5b505af1158015612ca1573d6000803e3d6000fd5b505050505050505050505050565b6000612cbe8260a00151610d8d565b90506000612cd0828460000151610791565b8351604051632c2cb9fd60e01b8152919250600091612d5a9185916001600160a01b03831690632c2cb9fd90612d0a908490600401614c38565b60206040518083038186803b158015612d2257600080fd5b505afa158015612d36573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c391906145d2565b8451604051632c2cb9fd60e01b8152919250600091612dea9186916001600160a01b03831690632c2cb9fd90612d94908490600401614c38565b60206040518083038186803b158015612dac57600080fd5b505afa158015612dc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612de491906145d2565b856117fe565b9050612e18612dfd828760400151613027565b6111408760200151612e13858a60400151613027565b611cbd565b60408701526001600160a01b03831660c0870152612e34611c2e565b612e4057610190612e44565b61014d5b60a08701526000612e5487611db4565b915050612e6b8587600001518860800151846120fb565b8551604051632c2cb9fd60e01b8152612f069187916001600160a01b03831690632c2cb9fd90612e9f908490600401614c38565b60206040518083038186803b158015612eb757600080fd5b505afa158015612ecb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eef91906145d2565b612f018a604001518b60600151613027565b6117fe565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338960000151888c6040015187604051602001612f4b9493929190614e0c565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612a5993929190614a8d565b600082820183811015610ef65760405162461bcd60e51b81526004016113cc90614ca0565b6002546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b158015612fe257600080fd5b505afa158015612ff6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061301a919061441c565b90506117ba818484613e65565b8082018281101561088757600080fd5b606061308c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613efb9092919063ffffffff16565b8051909150156117ba57808060200190518101906130aa9190614571565b6117ba5760405162461bcd60e51b81526004016113cc90614d3e565b60006130dd84676765c793fa10079d601b1b6117bf565b821015610ef6576131138361310661310087676765c793fa10079d601b1b6117bf565b856117ee565b8161310d57fe5b046139e9565b905061312a84676765c793fa10079d601b1b6117bf565b61313482856117bf565b1061313f5780610a5b565b6001019392505050565b600061088782676765c793fa10079d601b1b6117bf565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461318c5781610887565b5073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2919050565b6000811580159061323a5750604051632cdc77ab60e21b8152731b14e8d511c9a4395425314f849bd737baf8208f9063b371deac906131ea908790600401614a5f565b60206040518083038186803b15801561320257600080fd5b505afa158015613216573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061323a9190614571565b156132c957604051636eeb543160e01b8152731b14e8d511c9a4395425314f849bd737baf8208f90636eeb543190613276908790600401614a5f565b60206040518083038186803b15801561328e57600080fd5b505afa1580156132a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c691906145d2565b91505b816132d657506000610a5b565b8185816132df57fe5b049050600a85048111156132f35750600a84045b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561334257600080fd5b505afa158015613356573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061337a919061441c565b90506001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156133dd576040516001600160a01b0382169083156108fc029084906000818181858888f193505050501580156133d7573d6000803e3d6000fd5b506133f1565b6133f16001600160a01b0385168284611764565b50949350505050565b610120820151602001516040516302f5cc7960e11b81526000918291734ba1f38427b33b8ab7bb0490200dae1f1c36823f916305eb98f29161343f9190600401614a5f565b60206040518083038186803b15801561345757600080fd5b505afa15801561346b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348f9190614571565b61349e575060009050806135f1565b6101208401515160405163e0aa279760e01b81527325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa2797916134db9190600401614a5f565b60206040518083038186803b1580156134f357600080fd5b505afa158015613507573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061352b9190614571565b61353a575060009050806135f1565b610120840151516040850151855161355d926001600160a01b0390911691611764565b610120840151805160809091015160405163097396a160e31b81526001600160a01b0390921691634b9cb508919061359b9088908890600401614dc1565b60408051808303818588803b1580156135b357600080fd5b505af11580156135c7573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906135ec919061458d565b915091505b9250929050565b60e082015160405163e0aa279760e01b81526000917325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa27979161363591600401614a5f565b60206040518083038186803b15801561364d57600080fd5b505afa158015613661573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136859190614571565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b815250906136cb5760405162461bcd60e51b81526004016113cc9190614c8d565b5060e0830151604084015184516136ed926001600160a01b0390911691611764565b60008260018111156136fb57fe5b14156137a1578260e001516001600160a01b0316635b6f36fc8460000151856020015186604001518761010001516040518563ffffffff1660e01b81526004016137489493929190614be9565b602060405180830381600087803b15801561376257600080fd5b505af1158015613776573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061379a91906145d2565b9050610887565b8260e001516001600160a01b0316633924db668460000151856020015186606001518761010001516040518563ffffffff1660e01b81526004016137e89493929190614be9565b602060405180830381600087803b15801561380257600080fd5b505af1158015613816573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef691906145d2565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156138685750476106d7565b6040516370a0823160e01b81526001600160a01b038316906370a0823190613894903090600401614a5f565b60206040518083038186803b1580156138ac57600080fd5b505afa1580156138c0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088791906145d2565b6000670de0b6b3a76400006117556138fc85856117bf565b6002670de0b6b3a764000061174f565b6000739759a6ac90977b93b58547b4a71c78317f391a286001600160a01b038316141561393b575060006106d7565b816001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561397457600080fd5b505afa158015613988573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139ac919061441c565b6001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031614156139e1575060016106d7565b506000919050565b8060008112156106d75760405162461bcd60e51b81526004016113cc90614d88565b6000610ef682846001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b158015613a4a57600080fd5b505afa158015613a5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a8291906145d2565b601203600a0a6117bf565b613aad8363095ea7b360e01b846000604051602401611783929190614c1c565b6117ba8363095ea7b360e01b8484604051602401611783929190614bd0565b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b8152600401613afb9190614c38565b60a06040518083038186803b158015613b1357600080fd5b505afa158015613b27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b4b91906148c4565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b8152600401613b81929190614c41565b604080518083038186803b158015613b9857600080fd5b505afa158015613bac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bd091906148a1565b9150506000876001600160a01b0316636c25b346886040518263ffffffff1660e01b8152600401613c019190614a5f565b60206040518083038186803b158015613c1957600080fd5b505afa158015613c2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c5191906145d2565b90506000613c62610ee284866117bf565b9050676765c793fa10079d601b1b8104945080613c8a86676765c793fa10079d601b1b6117bf565b10613c955784613c9a565b846001015b9998505050505050505050565b600080846001600160a01b0316636c25b346856040518263ffffffff1660e01b8152600401613cd69190614a5f565b60206040518083038186803b158015613cee57600080fd5b505afa158015613d02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d2691906145d2565b90506000856001600160a01b031663d9638d36856040518263ffffffff1660e01b8152600401613d569190614c38565b60a06040518083038186803b158015613d6e57600080fd5b505afa158015613d82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613da691906148c4565b5050509150506000866001600160a01b0316632424be5c86886040518363ffffffff1660e01b8152600401613ddc929190614c41565b604080518083038186803b158015613df357600080fd5b505afa158015613e07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e2b91906148a1565b915050613e3a82848161310d57fe5b935080841115613e5557613e4d816139e9565b600003613e5a565b836000035b979650505050505050565b613e6d613f0a565b6001600160a01b0316826001600160a01b03161415613ee757826001600160a01b031681604051613e9d90614a5c565b60006040518083038185875af1925050503d8060008114613eda576040519150601f19603f3d011682016040523d82523d6000602084013e613edf565b606091505b5050506117ba565b6117ba6001600160a01b0383168483611764565b6060610a5b8484600085613f22565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b6060613f2d85613fe6565b613f495760405162461bcd60e51b81526004016113cc90614d07565b60006060866001600160a01b03168587604051613f669190614a40565b60006040518083038185875af1925050503d8060008114613fa3576040519150601f19603f3d011682016040523d82523d6000602084013e613fa8565b606091505b50915091508115613fbc579150610a5b9050565b805115613fcc5780518082602001fd5b8360405162461bcd60e51b81526004016113cc9190614c8d565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610a5b575050151592915050565b60405180610140016040528060006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016140966140df565b905290565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016000600181111561409657fe5b6040518060c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001606081525090565b803561088781614ecf565b805161088781614ecf565b600082601f830112614156578081fd5b813561416961416482614e7b565b614e54565b915080825283602082850101111561418057600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126141a9578081fd5b81516141b761416482614e7b565b91508082528360208285010111156141ce57600080fd5b6141df816020840160208601614e9f565b5092915050565b80356002811061088757600080fd5b6000610140808385031215614208578182fd5b61421181614e54565b91505061421e8383614130565b815261422d8360208401614130565b602082015260408201356040820152606082013560608201526080820135608082015260a082013560a08201526142678360c08401614130565b60c08201526142798360e08401614130565b60e08201526101008083013567ffffffffffffffff8082111561429b57600080fd5b6142a786838701614146565b838501526101209250828501359150808211156142c357600080fd5b506142d0858286016142dc565b82840152505092915050565b600060c082840312156142ed578081fd5b6142f760c0614e54565b9050813561430481614ecf565b8152602082013561431481614ecf565b6020820152604082013561432781614ecf565b80604083015250606082013560608201526080820135608082015260a082013567ffffffffffffffff81111561435c57600080fd5b61436884828501614146565b60a08301525092915050565b600060c08284031215614385578081fd5b61438f60c0614e54565b9050815161439c81614ecf565b815260208201516143ac81614ecf565b602082015260408201516143bf81614ecf565b80604083015250606082015160608201526080820151608082015260a082015167ffffffffffffffff8111156143f457600080fd5b61436884828501614199565b600060208284031215614411578081fd5b8135610ef681614ecf565b60006020828403121561442d578081fd5b8151610ef681614ecf565b6000806040838503121561444a578081fd5b823561445581614ecf565b946020939093013593505050565b600080600060608486031215614477578081fd5b833561448281614ecf565b95602085013595506040909401359392505050565b600080600080608085870312156144ac578182fd5b84356144b781614ecf565b9350602085013592506040850135915060608501356144d581614ecf565b939692955090935050565b6000806000806000608086880312156144f7578283fd5b853561450281614ecf565b94506020860135935060408601359250606086013567ffffffffffffffff8082111561452c578283fd5b818801915088601f83011261453f578283fd5b81358181111561454d578384fd5b89602082850101111561455e578384fd5b9699959850939650602001949392505050565b600060208284031215614582578081fd5b8151610ef681614ee7565b6000806040838503121561459f578182fd5b82516145aa81614ee7565b6020939093015192949293505050565b6000602082840312156145cb578081fd5b5035919050565b6000602082840312156145e3578081fd5b5051919050565b6000602082840312156145fb578081fd5b813567ffffffffffffffff811115614611578182fd5b61088384828501614146565b60008060008060008060c08789031215614635578384fd5b863567ffffffffffffffff81111561464b578485fd5b61465789828a01614146565b9650506020870135945060408701359350606087013561467681614ecf565b9250608087013561468681614ee7565b915060a087013560ff8116811461469b578182fd5b809150509295509295509295565b6000806040838503121561444a578182fd5b600080604083850312156146cd578182fd5b82516145aa81614ecf565b6000602082840312156146e9578081fd5b610ef683836141e6565b600060208284031215614704578081fd5b813567ffffffffffffffff81111561471a578182fd5b610883848285016141f5565b600060208284031215614737578081fd5b815167ffffffffffffffff8082111561474e578283fd5b8184019150610140808387031215614764578384fd5b61476d81614e54565b9050614779868461413b565b8152614788866020850161413b565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201526147c28660c0850161413b565b60c08201526147d48660e0850161413b565b60e082015261010080840151838111156147ec578586fd5b6147f888828701614199565b8284015250506101208084015183811115614811578586fd5b61481d88828701614374565b918301919091525095945050505050565b600080600080600060a08688031215614845578283fd5b853567ffffffffffffffff81111561485b578384fd5b614867888289016141f5565b9550506020860135935060408601359250606086013561488681614ecf565b915061489587608088016141e6565b90509295509295909350565b600080604083850312156148b3578182fd5b505080516020909101519092909150565b600080600080600060a086880312156148db578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b6001600160a01b03169052565b60008151808452614928816020860160208601614e9f565b601f01601f19169290920160200192915050565b600061014061494c848451614903565b602083015161495e6020860182614903565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015161499960c0860182614903565b5060e08301516149ac60e0860182614903565b506101008084015182828701526149c583870182614910565b9250505061012080840151858303828701526149e183826149eb565b9695505050505050565b600060018060a01b0380835116845280602084015116602085015280604084015116604085015250606082015160608401526080820151608084015260a082015160c060a085015261088360c0850182614910565b60008251614a52818460208701614e9f565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c1350d1119b185cda109bdbdcdd609a1b60a082015260c060608201819052600090614ade90830184614910565b95945050505050565b6001600160a01b03848116825283166020820152608060408201819052600890820152671350d1109bdbdcdd60c21b60a082015260c060608201819052600090614ade90830184614910565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c4d4344466c617368526570617960981b60a082015260c060608201819052600090614ade90830184614910565b6001600160a01b03848116825283166020820152608060408201819052600890820152674d4344526570617960c01b60a082015260c060608201819052600090614ade90830184614910565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906149e190830184614910565b6001600160a01b0392909216825260ff16602082015260400190565b90815260200190565b9182526001600160a01b0316602082015260400190565b9586526001600160a01b039485166020870152928416604086015292166060840152608083019190915260a082015260c00190565b600060208252610ef66020830184614910565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b602080825260169082015275546f6b656e20646563696d616c7320746f6f2062696760501b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600c908201526b696e742d6f766572666c6f7760a01b604082015260600190565b600060208252610ef6602083018461493c565b600060408252614dd4604083018561493c565b905060028310614de057fe5b8260208301529392505050565b9283526001600160a01b03919091166020830152604082015260600190565b9384526001600160a01b039290921660208401526040830152606082015260800190565b9283526020830191909152604082015260600190565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715614e7357600080fd5b604052919050565b600067ffffffffffffffff821115614e91578081fd5b50601f01601f191660200190565b60005b83811015614eba578181015183820152602001614ea2565b83811115614ec9576000848401525b50505050565b6001600160a01b0381168114614ee457600080fd5b50565b8015158114614ee457600080fdfea26469706673582212201a2cf479e908fd9855096af3a224a6ccc54d175af895b69b7b272aaa1b3c93c364736f6c634300060c0033
Deployed Bytecode Sourcemap
54795:5013:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40231:51;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28634:134;;;;;;;;;;-1:-1:-1;28634:134:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;40303:109::-;;;;;;;;;;;;;:::i;24340:122::-;;;;;;;;;;-1:-1:-1;24340:122:0;;;;;:::i;:::-;;:::i;:::-;;33973:56;;;;;;;;;;;;;:::i;29301:86::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;40778:80::-;;;;;;;;;;;;;:::i;41080:58::-;;;;;;;;;;;;;:::i;15081:186::-;;;;;;;;;;-1:-1:-1;15081:186:0;;;;;:::i;:::-;;:::i;29697:92::-;;;;;;;;;;;;;:::i;50466:223::-;;;;;;;;;;-1:-1:-1;50466:223:0;;;;;:::i;:::-;;:::i;40965:42::-;;;;;;;;;;;;;:::i;24635:285::-;;;;;;;;;;-1:-1:-1;24635:285:0;;;;;:::i;:::-;;:::i;14572:357::-;;;;;;;;;;-1:-1:-1;14572:357:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;24508:80::-;;;;;;;;;;;;;:::i;34182:72::-;;;;;;;;;;;;;:::i;40163:48::-;;;;;;;;;;;;;:::i;15396:336::-;;;;;;;;;;-1:-1:-1;15396:336:0;;;;;:::i;:::-;;:::i;40867:89::-;;;;;;;;;;;;;:::i;29394:90::-;;;;;;;;;;;;;:::i;49970:409::-;;;;;;;;;;-1:-1:-1;49970:409:0;;;;;:::i;:::-;;:::i;29798:87::-;;;;;;;;;;;;;:::i;23266:20::-;;;;;;;;;;;;;:::i;54880:151::-;;;;;;;;;;;;;:::i;29493:103::-;;;;;;;;;;;;;:::i;28776:159::-;;;;;;;;;;-1:-1:-1;28776:159:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;29605:85::-;;;;;;;;;;;;;:::i;24119:122::-;;;;;;;;;;-1:-1:-1;24119:122:0;;;;;:::i;:::-;;:::i;40691:80::-;;;;;;;;;;;;;:::i;29184:74::-;;;;;;;;;;;;;:::i;41014:59::-;;;;;;;;;;;;;:::i;34036:70::-;;;;;;;;;;;;;:::i;53622:54::-;;;;;;;;;;;;;:::i;42735:1193::-;;;;;;:::i;:::-;;:::i;34113:62::-;;;;;;;;;;;;;:::i;48915:782::-;;;;;;;;;;-1:-1:-1;48915:782:0;;;;;:::i;:::-;;:::i;23836:161::-;;;;;;;;;;-1:-1:-1;23836:161:0;;;;;:::i;:::-;;:::i;41415:1166::-;;;;;;:::i;:::-;;:::i;55319:1203::-;;;;;;;;;;-1:-1:-1;55319:1203:0;;;;;:::i;:::-;;:::i;41147:109::-;;;;;;;;;;;;;:::i;23293:20::-;;;;;;;;;;;;;:::i;40231:51::-;40279:3;40231:51;:::o;28634:134::-;28709:12;28752:7;28741:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;28734:26;;28634:134;;;;:::o;40303:109::-;-1:-1:-1;;;40303:109:0;:::o;24340:122::-;24421:5;;-1:-1:-1;;;;;24421:5:0;24407:10;:19;24399:28;;;;;;24440:5;:14;;-1:-1:-1;;;;;;24440:14:0;-1:-1:-1;;;;;24440:14:0;;;;;;;;;;24340:122::o;33973:56::-;;;;;;;;;;;;;;-1:-1:-1;;;33973:56:0;;;;:::o;29301:86::-;29345:42;29301:86;:::o;40778:80::-;40816:42;40778:80;:::o;41080:58::-;40550:42;41080:58;:::o;15081:186::-;15151:7;15171:13;15203:8;-1:-1:-1;;;;;15203:13:0;;15217:6;15203:21;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15171:55;;15246:5;-1:-1:-1;;;;;15246:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15239:20;;;15081:186;;;;;:::o;29697:92::-;29747:42;29697:92;:::o;50466:223::-;50557:18;;-1:-1:-1;;;50557:18:0;;50519:7;;;;40550:42;;50557:12;;:18;;50570:4;;50557:18;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50611:14;;-1:-1:-1;;;50611:14:0;;50539:36;;-1:-1:-1;50591:12:0;;-1:-1:-1;40459:42:0;;50611:8;;:14;;50620:4;;50611:14;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50586:39;;;;;;50645:36;50650:25;50655:4;40550:42;-1:-1:-1;;;;;50661:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50650:4;:25::i;:::-;50677:3;50645:4;:36::i;:::-;50638:43;50466:223;-1:-1:-1;;;;50466:223:0:o;40965:42::-;40459;40965;:::o;24635:285::-;23362:5;;-1:-1:-1;;;;;23362:5:0;23371:10;23362:19;23354:28;;;;;;24735:42:::1;-1:-1:-1::0;;;;;24725:52:0;::::1;;24721:192;;;24802:5;::::0;;24794:32:::1;::::0;-1:-1:-1;;;;;24802:5:0;;::::1;::::0;24794:32;::::1;;;::::0;24818:7;;24794:32;24802:5;24794:32;24818:7;24802:5;24794:32;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;24721:192;;;24886:5;::::0;24859:42:::1;::::0;-1:-1:-1;;;;;24859:26:0;;::::1;::::0;24886:5:::1;24893:7:::0;24859:26:::1;:42::i;:::-;24635:285:::0;;:::o;14572:357::-;14658:4;14664;14681:11;14695:8;-1:-1:-1;;;;;14695:12:0;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14681:28;;14720:11;14734:8;-1:-1:-1;;;;;14734:13:0;;14748:6;14734:21;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14720:35;;14769:15;14786:9;14803:3;-1:-1:-1;;;;;14799:13:0;;14813:4;14819:3;14799:24;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14768:55;;;;14836:9;14856:3;-1:-1:-1;;;;;14852:13:0;;14866:4;14852:19;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14834:37;;;;;;14892:10;14904:16;14909:4;14915;14904;:16::i;:::-;14884:37;;;;;;;;;14572:357;;;;;;:::o;24508:80::-;23362:5;;-1:-1:-1;;;;;23362:5:0;23371:10;23362:19;23354:28;;;;;;24573:5:::1;::::0;-1:-1:-1;;;;;24573:5:0::1;24552:28;34182:72:::0;;;;;;;;;;;;;;-1:-1:-1;;;34182:72:0;;;;:::o;40163:48::-;40208:3;40163:48;:::o;15396:336::-;15467:7;;15491:12;:31;;;;;;;;;15487:238;;;-1:-1:-1;15546:42:0;15539:49;;15487:238;15626:21;15610:12;:37;;;;;;;;;15606:119;;;-1:-1:-1;15671:42:0;15664:49;;40867:89;40914:42;40867:89;:::o;29394:90::-;29442:42;29394:90;:::o;49970:409::-;50105:7;50125:13;50141:14;50150:4;50141:8;:14::i;:::-;50186:18;;-1:-1:-1;;;50186:18:0;;50125:30;;-1:-1:-1;50171:11:0;;40550:42;;50186:12;;:18;;50199:4;;50186:18;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50168:36;;;50216:18;50236:12;50252:47;50271:12;50286:6;50294:4;50252:10;:47::i;:::-;50215:84;;;;50319:52;50323:43;50327:32;50331:22;50335:10;50347:5;50331:3;:22::i;:::-;50355:3;50327;:32::i;:::-;50361:4;50323:3;:43::i;:::-;50368:2;50319:3;:52::i;:::-;50312:59;;;;;;49970:409;;;;;;:::o;29798:87::-;29843:42;29798:87;:::o;23266:20::-;;;-1:-1:-1;;;;;23266:20:0;;:::o;54880:151::-;;;-1:-1:-1;;;;;54880:151:0;;:::o;29493:103::-;29553:42;29493:103;:::o;28776:159::-;28844:27;;:::i;:::-;28905:5;28894:33;;;;;;;;;;;;:::i;29605:85::-;29648:42;29605:85;:::o;24119:122::-;24200:5;;-1:-1:-1;;;;;24200:5:0;24186:10;:19;24178:28;;;;;;24219:5;:14;;-1:-1:-1;;;;;;24219:14:0;-1:-1:-1;;;;;24219:14:0;;;;;;;;;;24119:122::o;40691:80::-;40729:42;40691:80;:::o;29184:74::-;;;;;;;;;;;;;;-1:-1:-1;;;29184:74:0;;;;:::o;41014:59::-;40642:42;41014:59;:::o;34036:70::-;;;;;;;;;;;;;;-1:-1:-1;;;34036:70:0;;;;:::o;53622:54::-;;;-1:-1:-1;;;;;53622:54:0;;:::o;42735:1193::-;42942:19;42964:28;42979:12;42964:14;:28::i;:::-;42942:50;;43005:12;43020:38;43037:11;43051:6;43020:8;:38::i;:::-;43005:53;;43069:11;43091;-1:-1:-1;;;;;43083:25:0;;43109:6;43083:33;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43069:47;;43129:16;43148:58;43156:11;43169:6;43177:3;43182:13;:23;;;43148:7;:58::i;:::-;-1:-1:-1;;;;;43219:25:0;;:18;;;:25;43129:77;-1:-1:-1;43285:14:0;:12;:14::i;:::-;:59;;40208:3;43285:59;;;40279:3;43285:59;43255:27;;;:89;43381:42;43385:8;43395:27;43403:8;43385;43395:7;:27::i;:::-;43381:3;:42::i;:::-;43355:23;;;:68;43437:18;43459:20;43355:13;43459:5;:20::i;:::-;43434:45;;;43492:57;43506:11;43519:6;43527:9;43538:10;43492:13;:57::i;:::-;43638:21;:25;43634:99;;43680:41;;:9;;43699:21;43680:41;;;;;;;;;43699:21;43680:9;:41;;;;;;;;;;;;;;;;;;;;;43634:99;41213:42;-1:-1:-1;;;;;43745:10:0;;43778:4;43798:10;43859:6;43867:4;43873:13;:23;;;43898:10;43848:61;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;43745:175;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42735:1193;;;;;;;;;;:::o;34113:62::-;;;;;;;;;;;;;;-1:-1:-1;;;34113:62:0;;;;:::o;48915:782::-;49076:7;49096:13;49112:14;49121:4;49112:8;:14::i;:::-;49096:30;;49140:18;49160:12;49176:47;49195:12;49210:6;49218:4;49176:10;:47::i;:::-;49254:35;;-1:-1:-1;;;49254:35:0;;49139:84;;-1:-1:-1;49139:84:0;-1:-1:-1;49239:11:0;;40550:42;;49254:29;;:35;;49284:4;;49254:35;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49236:53;;;49302:21;49326:45;49330:10;49343:26;49347:14;49351:3;49356:4;49347:3;:14::i;:::-;49363:5;49343:3;:26::i;49326:45::-;49302:69;;49384:20;49412:9;-1:-1:-1;;;;;49407:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49384:44;;49465:2;49449:12;:18;;49441:53;;;;-1:-1:-1;;;49441:53:0;;;;;;;:::i;:::-;;;;;;;;;49507:30;49567:12;49562:2;:17;49557:2;:23;49540:13;:41;;;;;;;-1:-1:-1;49686:3:0;49680:2;49655:27;;49654:35;49647:42;;;;;;;;;48915:782;;;;;;:::o;23836:161::-;23917:5;;-1:-1:-1;;;;;23917:5:0;23903:10;:19;23895:28;;;;;;23942:5;;-1:-1:-1;;;;;23942:5:0;:19;23934:28;;;;;41415:1166;41622:19;41644:28;41659:12;41644:14;:28::i;:::-;41622:50;;41685:12;41700:38;41717:11;41731:6;41700:8;:38::i;:::-;41685:53;;41749:11;41771;-1:-1:-1;;;;;41763:25:0;;41789:6;41763:33;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41749:47;;41809:71;41824:11;41837:6;41845:9;41856:13;:23;;;41809:14;:71::i;:::-;-1:-1:-1;;;;;;41893:25:0;;:18;;;:25;41959:14;:12;:14::i;:::-;:59;;40208:3;41959:59;;;40279:3;41959:59;41929:27;;;:89;42032:17;42053:20;41929:13;42053:5;:20::i;:::-;42029:44;;;42098;42102:9;42113:28;42121:8;42131:9;42113:7;:28::i;42098:44::-;42086:56;;42155:54;42167:11;42180:6;42188:3;42193:9;42204:4;42155:11;:54::i;:::-;42292:21;:25;42288:99;;42334:41;;:9;;42353:21;42334:41;;;;;;;;;42353:21;42334:9;:41;;;;;;;;;;;;;;;;;;;;;42288:99;41213:42;-1:-1:-1;;;;;42399:10:0;;42432:4;42452:10;42513:6;42521:4;42527:13;:23;;;42552:9;42502:60;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;42399:174;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41415:1166;;;;;;;;;:::o;55319:1203::-;55505:24;55544:13;;;;;55691:68;;;;55702:7;55691:68;:::i;:::-;55490:269;;;;;;;;;;;;55772:32;;:::i;:::-;55807:31;55826:11;55807:18;:31::i;:::-;55772:66;;55851:26;;:::i;:::-;55880:223;;;;;;;;55912:5;55880:223;;;;55941:7;55880:223;;;;55975:7;55880:223;;;;56002:4;55880:223;;;;56031:8;-1:-1:-1;;;;;55880:223:0;;;;;56079:11;56067:24;;;;;;;;;;55880:223;;;;;;;;;;55851:252;-1:-1:-1;56116:149:0;;;;56144:38;56158:12;56172:9;56144:13;:38::i;:::-;56116:149;;;56215:38;56229:12;56243:9;56215:13;:38::i;:::-;56277:60;56309:8;56319:17;:7;56331:4;56319:11;:17::i;:::-;56277:31;:60::i;:::-;56420:21;:25;56416:99;;56462:41;;:9;;56481:21;56462:41;;;;;;;;;56481:21;56462:9;:41;;;;;;;;;;;;;;;;;;;41147:109;41213:42;41147:109;:::o;23293:20::-;;;-1:-1:-1;;;;;23293:20:0;;:::o;5375:122::-;5434:9;-1:-1:-1;;;5460:23:0;5464:9;5468:1;5471;5464:3;:9::i;:::-;5481:1;-1:-1:-1;;;5475:7:0;;5460:3;:23::i;:::-;:29;;;;;;;5375:122;-1:-1:-1;;;5375:122:0:o;21312:176::-;21394:86;21414:5;21444:23;;;21469:2;21473:5;21421:58;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;21421:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;21421:58:0;-1:-1:-1;;;;;;21421:58:0;;;;;;;;;;21394:19;:86::i;:::-;21312:176;;;:::o;4464:127::-;4522:9;4552:6;;;:30;;-1:-1:-1;;4567:5:0;;;4581:1;4576;4567:5;4576:1;4562:15;;;;;:20;4552:30;4544:39;;;;;4599:100;4657:9;4690:1;4686;:5;;;;4343:113;4436:5;;;4431:16;;;;4423:25;;;;;44226:933;44411:27;;-1:-1:-1;;;44411:27:0;;44376:7;;;;40729:42;;44411:21;;:27;;44433:4;;44411:27;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44396:42;;44449:21;40459:42;-1:-1:-1;;;;;44473:7:0;;44489:12;-1:-1:-1;;;;;44481:26:0;;44508:6;44481:34;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44473:43;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44449:67;;44529:17;44549:38;44560:12;44574:6;44582:4;44549:10;:38::i;:::-;44529:58;;44618:9;44604:10;:23;44600:86;;44657:17;44661:9;44672:1;44657:3;:17::i;:::-;44644:30;;44600:86;44706:12;-1:-1:-1;;;;;44698:26:0;;44739:6;44767:1;44784:52;44804:10;44816:4;44822:13;44784:19;:52::i;:::-;44698:149;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44866:12;-1:-1:-1;;;;;44858:26:0;;44885:6;44901:4;44908:17;44914:10;44908:5;:17::i;:::-;44858:68;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44943:49:0;;-1:-1:-1;;;44943:49:0;;40459:42;;-1:-1:-1;44943:7:0;;-1:-1:-1;44943:49:0;;44959:4;;40642:42;;44943:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44939:113;;45014:26;;-1:-1:-1;;;45014:26:0;;40459:42;;45014:8;;:26;;40642:42;;45014:26;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44939:113;45064:57;;-1:-1:-1;;;45064:57:0;;40642:42;;45064:30;;:57;;45103:4;;45110:10;;45064:57;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45141:10:0;;44226:933;-1:-1:-1;;;;;;;;;;44226:933:0:o;50697:131::-;50768:52;;-1:-1:-1;;;50768:52:0;;50744:4;;40914:42;;50768:41;;:52;;50810:9;;50768:52;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50761:59;;50697:131;:::o;50836:535::-;50906:7;50930:12;;50926:417;;50959:19;50981:17;-1:-1:-1;;;50981:8:0;:17::i;:::-;50959:39;;51013:17;51033:27;51038:8;51048:11;51033:4;:27::i;:::-;51013:47;-1:-1:-1;51103:1:0;51093:7;:11;51081:9;:23;51077:87;;;-1:-1:-1;51147:1:0;51137:11;;51077:87;51180:18;29553:42;-1:-1:-1;;;;;51201:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51180:47;-1:-1:-1;51244:54:0;40816:42;51180:47;51288:9;51244:31;:54::i;:::-;-1:-1:-1;51322:9:0;-1:-1:-1;51315:16:0;;-1:-1:-1;51315:16:0;50926:417;-1:-1:-1;51362:1:0;50836:535;;;;:::o;34525:1670::-;34586:7;34595:4;34614:15;34640:17;34668:12;29345:42;-1:-1:-1;;;;;34741:35:0;:6;:14;;;-1:-1:-1;;;;;34741:35:0;;34737:201;;;34824:14;;34810:29;;:13;:29::i;:::-;-1:-1:-1;;;;;34793:46:0;;;34907:16;;;;;34854:72;;-1:-1:-1;;;34854:72:0;;;;29442:42;;34854:45;;34907:16;34854:72;;;;;34793:14;;34854:72;;;;;;;34907:16;29442:42;34854:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34737:201;34970:75;34977:6;:16;;;34995:6;:11;;;35008:6;:14;;;35024:6;:20;;;34970:6;:75::i;:::-;34950:16;;;:95;;;;;;;;35125:19;;;;:25;;;:29;35121:228;;35197:34;35207:6;35215:15;35197:9;:34::i;:::-;35171:60;-1:-1:-1;35171:60:0;-1:-1:-1;35248:90:0;;;;35290:6;:19;;;:32;;;35280:42;;35248:90;35419:7;35414:129;;35458:34;35468:6;35476:15;35458:9;:34::i;:::-;35443:49;;35517:6;:14;;;35507:24;;35414:129;35659:1;35623:33;29442:42;35623:10;:33::i;:::-;:37;35619:212;;;35742:62;;-1:-1:-1;;;35742:62:0;;29442:42;;35677:46;;29442:42;;35742:47;;:62;;35798:4;;35742:62;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35677:142;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35619:212;35847:15;;;;-1:-1:-1;;;;;35847:40:0;29442:42;35847:40;35843:302;;;35945:39;35950:6;:15;;;35967:6;:16;;;35945:4;:39::i;:::-;35912:29;29345:42;35912:10;:29::i;:::-;:72;;35986:16;;;;;;;;;;;;;-1:-1:-1;;;35986:16:0;;;35904:99;;;;;-1:-1:-1;;;35904:99:0;;;;;;;;:::i;:::-;;35843:302;;;36075:39;36080:6;:15;;;36097:6;:16;;;36075:4;:39::i;:::-;36044:27;36055:6;:15;;;36044:10;:27::i;:::-;:70;;36116:16;;;;;;;;;;;;;-1:-1:-1;;;36116:16:0;;;36036:97;;;;;-1:-1:-1;;;36036:97:0;;;;;;;;:::i;:::-;;35843:302;-1:-1:-1;36165:7:0;;-1:-1:-1;36174:12:0;-1:-1:-1;34525:1670:0;;;:::o;45434:825::-;45594:20;45635:24;45649:9;45635:13;:24::i;:::-;45631:252;;;45681:9;-1:-1:-1;;;;;45676:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;45676:29:0;;45713:7;45676:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45754:22;45768:7;45754:13;:22::i;:::-;45738:38;;45631:252;;;45825:46;45839:31;45851:9;45862:7;45839:11;:31::i;:::-;45825:13;:46::i;:::-;45809:62;;45631:252;45895:69;45945:9;45956:7;45914:9;-1:-1:-1;;;;;45909:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;45895:49:0;;:69;:49;:69::i;:::-;45977:44;;-1:-1:-1;;;45977:44:0;;-1:-1:-1;;;;;45977:20:0;;;;;:44;;46006:4;;46013:7;;45977:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;46057:34:0;;-1:-1:-1;;;46057:34:0;;40459:42;;-1:-1:-1;46034:8:0;;-1:-1:-1;;;;;;46057:26:0;;;;;:34;;46084:6;;46057:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46106;;-1:-1:-1;;;46106:34:0;;-1:-1:-1;;;;;46106:26:0;;;;;:34;;46133:6;;46106:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46163:4;46191;46211:13;46239:1;46034:217;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45434:825;;;;;:::o;46620:806::-;46779:7;46799:18;46820:7;46799:28;;46840:20;46868:9;-1:-1:-1;;;;;46863:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46840:44;;46921:2;46905:12;:18;;46897:53;;;;-1:-1:-1;;;46897:53:0;;;;;;;:::i;:::-;46967:12;46983:2;46967:18;46963:99;;47036:12;47031:2;:17;47026:2;:23;47015:7;:35;47002:48;;46963:99;47082:12;-1:-1:-1;;;;;47074:26:0;;47101:6;47110:25;47124:10;47110:13;:25::i;:::-;47109:26;;47137:1;47074:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;47150:61:0;;-1:-1:-1;;;47150:61:0;;-1:-1:-1;;;;;47150:26:0;;;-1:-1:-1;47150:26:0;;-1:-1:-1;47150:61:0;;47177:6;;47193:4;;47200:10;;47150:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;47224:44:0;;-1:-1:-1;;;47224:44:0;;-1:-1:-1;;;;;47224:20:0;;;-1:-1:-1;47224:20:0;;-1:-1:-1;47224:44:0;;47253:4;;47260:7;;47224:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47285:24;47299:9;47285:13;:24::i;:::-;47281:111;;;47331:9;-1:-1:-1;;;;;47326:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;47326:30:0;;47357:7;47326:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47281:111;-1:-1:-1;47411:7:0;;46620:806;-1:-1:-1;;;;;46620:806:0:o;47802:784::-;47997:34;;-1:-1:-1;;;47997:34:0;;47983:11;;-1:-1:-1;;;;;47997:26:0;;;;;:34;;48024:6;;47997:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47983:48;;48044:17;48064:39;40459:42;48088:3;48093;48098:4;48064:10;:39::i;:::-;48044:59;;48133:9;48120:10;:22;48116:155;;;40816:42;48159:27;48187:6;48195:26;48199:10;48211:9;48195:3;:26::i;:::-;48159:63;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;48250:9;48237:22;;48116:155;48287:61;;-1:-1:-1;;;48287:61:0;;40816:42;;48287:28;;:61;;48324:4;;40642:42;;48287:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48283:156;;48370:57;;-1:-1:-1;;;48370:57:0;;40816:42;;48370:26;;:57;;40642:42;;-1:-1:-1;;48423:2:0;48370:57;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;48283:156;48451:29;;-1:-1:-1;;;48451:29:0;;40642:42;;48451:12;;:29;;48464:3;;48469:10;;48451:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48501:12;-1:-1:-1;;;;;48493:26:0;;48520:6;48528:1;48531:46;40459:42;48567:3;48572:4;48531:22;:46::i;:::-;48493:85;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47802:784;;;;;;;:::o;58152:1567::-;58273:19;58295:38;58310:10;:22;;;58295:14;:38::i;:::-;58273:60;;58346:12;58361:48;58378:11;58392:10;:16;;;58361:8;:48::i;:::-;58460:16;;58434:43;;-1:-1:-1;;;58434:43:0;;58346:63;;-1:-1:-1;58420:11:0;;-1:-1:-1;;;;;58434:25:0;;;;;:43;;58460:16;58434:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58420:57;;58518:15;58536:73;58553:11;58566:10;:16;;;58584:3;58589:10;:19;;;58536:16;:73::i;:::-;58518:91;;58620:17;58640:138;58669:11;58695:10;:16;;;58726:10;:19;;;58760:7;58640:14;:138::i;:::-;58620:158;;58834:37;58838:10;:21;;;58861:9;58834:3;:37::i;:::-;58808:23;;;:63;-1:-1:-1;;;;;58882:25:0;;:18;;;:25;58948:14;:12;:14::i;:::-;:59;;40208:3;58948:59;;;40279:3;58948:59;58918:27;;;:89;59021:21;59046:20;58918:13;59046:5;:20::i;:::-;59018:48;;;59095:62;59099:13;59114:42;59122:10;:18;;;59142:13;59114:7;:42::i;59095:62::-;59079:78;;59199:68;59211:11;59224:10;:16;;;59242:3;59247:13;59262:4;59199:11;:68::i;:::-;59332:173;59361:11;59387:10;:16;;;59418:10;:19;;;59452:42;59456:10;:21;;;59479:10;:14;;;59452:3;:42::i;:::-;59332:14;:173::i;:::-;;41213:42;-1:-1:-1;;;;;59518:10:0;;59551:4;59571:10;59637;:16;;;59655:4;59661:13;:23;;;59686:13;59626:74;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;59518:193;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58152:1567;;;;;;;;:::o;56530:1614::-;56651:19;56673:38;56688:10;:22;;;56673:14;:38::i;:::-;56651:60;;56722:12;56737:48;56754:11;56768:10;:16;;;56737:8;:48::i;:::-;56894:16;;56925:43;;-1:-1:-1;;;56925:43:0;;56722:63;;-1:-1:-1;56825:15:0;;56843:136;;56868:11;;-1:-1:-1;;;;;56925:25:0;;;;;:43;;56894:16;;56925:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;56843:136::-;57057:16;;57088:43;;-1:-1:-1;;;57088:43:0;;56825:154;;-1:-1:-1;56990:16:0;;57009:155;;57031:11;;-1:-1:-1;;;;;57088:25:0;;;;;:43;;57057:16;;57088:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57146:7;57009;:155::i;:::-;56990:174;;57220:145;57238:36;57242:8;57252:10;:21;;;57238:3;:36::i;:::-;57289:65;57297:10;:18;;;57317:36;57321:8;57331:10;:21;;;57317:3;:36::i;:::-;57289:7;:65::i;57220:145::-;57194:23;;;:171;-1:-1:-1;;;;;57378:25:0;;:18;;;:25;57444:14;:12;:14::i;:::-;:59;;40208:3;57444:59;;;40279:3;57444:59;57414:27;;;:89;57517:20;57541;57414:13;57541:5;:20::i;:::-;57514:47;;;57604:79;57618:11;57631:10;:16;;;57649:10;:19;;;57670:12;57604:13;:79::i;:::-;57789:16;;57820:43;;-1:-1:-1;;;57820:43:0;;57741:190;;57763:11;;-1:-1:-1;;;;;57820:25:0;;;;;:43;;57789:16;;57820:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57878:42;57882:10;:21;;;57905:10;:14;;;57878:3;:42::i;:::-;57741:7;:190::i;:::-;;41213:42;-1:-1:-1;;;;;57944:10:0;;57977:4;57997:10;58063;:16;;;58081:4;58087:13;:23;;;58112:12;58052:73;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;57944:192;;;;;;;;;;;;;;;;;:::i;19474:181::-;19532:7;19564:5;;;19588:6;;;;19580:46;;;;-1:-1:-1;;;19580:46:0;;;;;;;:::i;53847:220::-;53968:17;;:38;;;-1:-1:-1;;;53968:38:0;;;;53945:20;;-1:-1:-1;;;;;53968:17:0;;:36;;:38;;;;;;;;;;;;;;:17;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53945:61;;54019:40;54036:4;54041:8;54051:7;54019:16;:40::i;4222:113::-;4315:5;;;4310:16;;;;4302:25;;;;;22781:419;22863:23;22889:69;22917:4;22889:69;;;;;;;;;;;;;;;;;22897:5;-1:-1:-1;;;;;22889:27:0;;;:69;;;;;:::i;:::-;22973:17;;22863:95;;-1:-1:-1;22973:21:0;22969:224;;23115:10;23104:30;;;;;;;;;;;;:::i;:::-;23096:85;;;;-1:-1:-1;;;23096:85:0;;;;;;;:::i;11214:344::-;11313:8;11355:17;11359:7;-1:-1:-1;;;11355:3:0;:17::i;:::-;11338:14;:34;11334:217;;;11396:61;11451:5;11410:38;11414:17;11418:7;-1:-1:-1;;;11414:3:0;:17::i;:::-;11433:14;11410:3;:38::i;:::-;:46;;;;;;11396:13;:61::i;:::-;11389:68;;11504:17;11508:7;-1:-1:-1;;;11504:3:0;:17::i;:::-;11479:22;11488:4;11495:5;11479:3;:22::i;:::-;:42;:60;;11535:4;11479:60;;;11531:1;11524:8;;11472:67;-1:-1:-1;;;11214:344:0:o;11673:100::-;11722:4;11746:19;11750:4;-1:-1:-1;;;11746:3:0;:19::i;32871:151::-;32931:7;-1:-1:-1;;;;;32958:25:0;;29345:42;32958:25;:56;;33010:4;32958:56;;;-1:-1:-1;29442:42:0;;32871:151;-1:-1:-1;32871:151:0:o;31185:905::-;31291:17;31325:19;;;;;:71;;-1:-1:-1;31348:48:0;;-1:-1:-1;;;31348:48:0;;29648:42;;31348:41;;:48;;31390:5;;31348:48;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31321:174;;;31430:53;;-1:-1:-1;;;31430:53:0;;29648:42;;31430:46;;:53;;31477:5;;31430:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31413:70;;31321:174;31511:19;31507:576;;-1:-1:-1;31559:1:0;31507:576;;;31615:14;31605:7;:24;;;;;;;-1:-1:-1;31731:2:0;31721:7;:12;31708:9;:26;31704:91;;;-1:-1:-1;31777:2:0;31767:12;;31704:91;31811:18;29553:42;-1:-1:-1;;;;;31832:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31811:47;-1:-1:-1;;;;;;31879:27:0;;29345:42;31879:27;31875:197;;;31927:39;;-1:-1:-1;;;;;31927:28:0;;;:39;;;;;31956:9;;31927:39;;;;31956:9;31927:28;:39;;;;;;;;;;;;;;;;;;;;;31875:197;;;32007:49;-1:-1:-1;;;;;32007:26:0;;32034:10;32046:9;32007:26;:49::i;:::-;31507:576;31185:905;;;;;;:::o;38238:692::-;38428:20;;;;:33;;;38385:77;;-1:-1:-1;;;38385:77:0;;38346:12;;;;29843:42;;38385;;:77;;38428:33;38385:77;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38380:128;;-1:-1:-1;38487:5:0;;-1:-1:-1;38487:5:0;38479:17;;38380:128;38582:20;;;;:28;38525:86;;-1:-1:-1;;;38525:86:0;;29747:42;;38525:56;;:86;;38582:28;38525:86;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38520:137;;-1:-1:-1;38636:5:0;;-1:-1:-1;38636:5:0;38628:17;;38520:137;38733:20;;;;:28;38763:17;;;;38703:15;;38697:84;;-1:-1:-1;;;;;38697:35:0;;;;;:84::i;:::-;38826:20;;;;:28;;38873:32;;;;;38801:121;;-1:-1:-1;;;38801:121:0;;-1:-1:-1;;;;;38801:64:0;;;;;;38873:32;38801:121;;38826:7;;38916:5;;38801:121;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38794:128;;;;38238:692;;;;;;:::o;39196:717::-;39375:15;;;;39318:73;;-1:-1:-1;;;39318:73:0;;39280:17;;29747:42;;39318:56;;:73;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39393:19;;;;;;;;;;;;;-1:-1:-1;;;39393:19:0;;;39310:103;;;;;-1:-1:-1;;;39310:103:0;;;;;;;;:::i;:::-;-1:-1:-1;39462:15:0;;;;39479:17;;;;39432:15;;39426:71;;-1:-1:-1;;;;;39426:35:0;;;;;:71::i;:::-;39523:15;39514:5;:24;;;;;;;;;39510:396;;;39590:7;:15;;;-1:-1:-1;;;;;39570:63:0;;39634:7;:15;;;39651:7;:16;;;39669:7;:17;;;39688:7;:19;;;39570:138;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39555:153;;39510:396;;;39776:7;:15;;;-1:-1:-1;;;;;39756:62:0;;39819:7;:15;;;39836:7;:16;;;39854:7;:18;;;39874:7;:19;;;39756:138;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;30078:275::-;30141:12;-1:-1:-1;;;;;30170:31:0;;29345:42;30170:31;30166:180;;;-1:-1:-1;30228:21:0;30166:180;;;30292:42;;-1:-1:-1;;;30292:42:0;;-1:-1:-1;;;;;30292:27:0;;;;;:42;;30328:4;;30292:42;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;5245:122::-;5304:9;5194:6;5330:23;5334:9;5338:1;5341;5334:3;:9::i;:::-;5351:1;5194:6;5345:7;;13963:436;14028:4;14127:42;-1:-1:-1;;;;;14114:55:0;;;14110:73;;;-1:-1:-1;14178:5:0;14171:12;;14110:73;14264:9;-1:-1:-1;;;;;14259:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;14251:76:0;14285:42;-1:-1:-1;;;;;14251:76:0;;14247:120;;;-1:-1:-1;14351:4:0;14344:11;;14247:120;-1:-1:-1;14386:5:0;13963:436;;;:::o;12220:134::-;12301:2;12275:5;12323:6;;;12315:31;;;;-1:-1:-1;;;12315:31:0;;;;;;;:::i;11944:163::-;12024:7;12051:48;12055:7;12081:9;-1:-1:-1;;;;;12076:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12071:2;:26;12064:2;:34;12051:3;:48::i;21861:281::-;21947:86;21967:5;21997:22;;;22021:7;22030:1;21974:58;;;;;;;;;:::i;21947:86::-;22044:90;22064:5;22094:22;;;22118:7;22127:5;22071:62;;;;;;;;;:::i;13147:424::-;13246:14;13276:9;13296:4;-1:-1:-1;;;;;13292:14:0;;13307:4;13292:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13273:39;;;;;;13326:8;13342:4;-1:-1:-1;;;;;13338:14:0;;13353:4;13359;13338:26;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13323:41;;;13375:8;13390:4;-1:-1:-1;;;;;13386:13:0;;13400:4;13386:19;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13375:30;;13418:8;13429:24;13433:14;13437:3;13442:4;13433:3;:14::i;13429:24::-;13418:35;-1:-1:-1;;;;13418:35:0;13476:9;13464:21;;13532:3;13510:19;13514:9;-1:-1:-1;;;13510:3:0;:19::i;:::-;:25;:53;;13554:9;13510:53;;;13538:9;13550:1;13538:13;13510:53;13498:65;13147:424;-1:-1:-1;;;;;;;;;13147:424:0:o;12545:382::-;12642:10;12665:8;12680:4;-1:-1:-1;;;;;12676:13:0;;12690:4;12676:19;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12665:30;;12711:9;12731:4;-1:-1:-1;;;;;12727:14:0;;12742:4;12727:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12708:39;;;;;;12761:8;12777:4;-1:-1:-1;;;;;12773:14:0;;12788:4;12794;12773:26;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12758:41;;;12821:25;12841:4;12835:3;:10;;;;12821:25;12812:34;;12882:3;12871:6;12866:19;;:53;;12901:18;12915:3;12901:13;:18::i;:::-;12899:20;;12866:53;;;12890:6;12888:8;;12866:53;12857:62;12545:382;-1:-1:-1;;;;;;;12545:382:0:o;54075:355::-;54202:26;:24;:26::i;:::-;-1:-1:-1;;;;;54190:38:0;:8;-1:-1:-1;;;;;54190:38:0;;54187:168;;;54285:12;-1:-1:-1;;;;;54285:17:0;54310:7;54285:37;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54337:7;;54187:168;54367:51;-1:-1:-1;;;;;54367:28:0;;54396:12;54410:7;54367:28;:51::i;17705:196::-;17808:12;17840:53;17863:6;17871:4;17877:1;17880:12;17840:22;:53::i;53356:121::-;53427:42;53356:121;:::o;18467:979::-;18597:12;18630:18;18641:6;18630:10;:18::i;:::-;18622:60;;;;-1:-1:-1;;;18622:60:0;;;;;;;:::i;:::-;18756:12;18770:23;18797:6;-1:-1:-1;;;;;18797:11:0;18817:8;18828:4;18797:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18755:78;;;;18848:7;18844:595;;;18879:10;-1:-1:-1;18872:17:0;;-1:-1:-1;18872:17:0;18844:595;18993:17;;:21;18989:439;;19256:10;19250:17;19317:15;19304:10;19300:2;19296:19;19289:44;19204:148;19399:12;19392:20;;-1:-1:-1;;;19392:20:0;;;;;;;;:::i;16492:619::-;16552:4;17020:20;;16863:66;17060:23;;;;;;:42;;-1:-1:-1;;17087:15:0;;;16492:619;-1:-1:-1;;16492: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;52919:6;1794:4;1786:6;1782:17;1794:4;1820:5;1816:16;52896:30;52975:1;52957:16;;;1794:4;52957:16;52950: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;;54543:1;54533:12;;54523:2;;54559:1;;54549: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;50231:4;50220:16;;54756:33;;54746:2;;-1:-1;;54793:12;54746: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;;;;;50015:54;20968:37;;20962:48::o;21257:323::-;;21389:5;48189:12;48464:6;48459:3;48452:19;21472:52;21517:6;48501:4;48496:3;48492:14;48501:4;21498:5;21494:16;21472:52;:::i;:::-;53352:7;53336:14;-1:-1;;53332:28;21536:39;;;;48501:4;21536:39;;21337:243;-1:-1;;21337:243::o;27642:1986::-;;27803:6;27903:63;27951:14;27880:16;27874:23;27903:63;:::i;:::-;28049:4;28042:5;28038:16;28032:23;28061:63;28049:4;28113:3;28109:14;28095:12;28061:63;:::i;:::-;;28208:4;28201:5;28197:16;28191:23;28208:4;28272:3;28268:14;21208:37;28368:4;28361:5;28357:16;28351:23;28368:4;28432:3;28428:14;21208:37;28526:4;28519:5;28515:16;28509:23;28526:4;28590:3;28586:14;21208:37;28689:4;28682:5;28678:16;28672:23;28689:4;28753:3;28749:14;21208:37;28843:4;28836:5;28832:16;28826:23;28855:63;28843:4;28907:3;28903:14;28889:12;28855:63;:::i;:::-;;29000:4;28993:5;28989:16;28983:23;29012:63;29000:4;29064:3;29060:14;29046:12;29012:63;:::i;:::-;;29161:6;;29154:5;29150:18;29144:25;27803:6;29161;29193:3;29189:16;29182:40;29237:71;27803:6;27798:3;27794:16;29289:12;29237:71;:::i;:::-;29229:79;;;;29401:6;;29394:5;29390:18;29384:25;29457:3;29451:4;29447:14;29401:6;29433:3;29429:16;29422:40;29477:113;29585:4;29571:12;29477:113;:::i;:::-;29612:11;27776:1852;-1:-1;;;;;;27776:1852::o;29716:1219::-;;4597:18;;50026:42;;;;29942:16;29936:23;50015:54;20975:3;20968:37;50026:42;30115:4;30108:5;30104:16;30098:23;50015:54;30115:4;30179:3;30175:14;20968:37;50026:42;30280:4;30273:5;30269:16;30263:23;50015:54;30280:4;30344:3;30340:14;20968:37;;30435:4;30428:5;30424:16;30418:23;30435:4;30499:3;30495:14;21208:37;30596:4;30589:5;30585:16;30579:23;30596:4;30660:3;30656:14;21208:37;30754:4;30747:5;30743:16;30737:23;29867:4;30754;30784:3;30780:14;30773:38;30826:71;29867:4;29862:3;29858:14;30878:12;30826:71;:::i;31172:271::-;;22097:5;48189:12;22208:52;22253:6;22248:3;22241:4;22234:5;22230:16;22208:52;:::i;:::-;22272:16;;;;;31306:137;-1:-1;;31306:137::o;31450:379::-;31814:10;31638:191::o;31836:222::-;-1:-1;;;;;50015:54;;;;20968:37;;31963:2;31948:18;;31934:124::o;32310:349::-;-1:-1;;;;;50015:54;;;20837:58;;50015:54;;32645:2;32630:18;;20968:37;32473:2;32458:18;;32444:215::o;32666:866::-;-1:-1;;;;;50015:54;;;20837:58;;50015:54;;33165:2;33150:18;;20837:58;32984:3;33202:2;33187:18;;33180:48;;;24827:2;32969:19;;;48452;-1:-1;;;50026:42;48492:14;;24843:36;24898:12;33406:2;33391:18;;33384:48;;;32666:866;;33446:76;;24898:12;;33508:6;33446:76;:::i;:::-;33438:84;32955:577;-1:-1;;;;;32955:577::o;33539:866::-;-1:-1;;;;;50015:54;;;20837:58;;50015:54;;34038:2;34023:18;;20837:58;33857:3;34075:2;34060:18;;34053:48;;;25480:1;33842:19;;;48452;-1:-1;;;50026:42;48492:14;;25495:31;25545:12;34279:2;34264:18;;34257:48;;;33539:866;;34319:76;;25545:12;;34381:6;34319:76;:::i;34412:866::-;-1:-1;;;;;50015:54;;;20837:58;;50015:54;;34911:2;34896:18;;20837:58;34730:3;34948:2;34933:18;;34926:48;;;25796:2;34715:19;;;48452;-1:-1;;;50026:42;48492:14;;25812:36;25867:12;35152:2;35137:18;;35130:48;;;34412:866;;35192:76;;25867:12;;35254:6;35192:76;:::i;35285:866::-;-1:-1;;;;;50015:54;;;20837:58;;50015:54;;35784:2;35769:18;;20837:58;35603:3;35821:2;35806:18;;35799:48;;;26118:1;35588:19;;;48452;-1:-1;;;50026:42;48492:14;;26133:31;26183:12;36025:2;36010:18;;36003:48;;;35285:866;;36065:76;;26183:12;;36127:6;36065:76;:::i;36158:349::-;-1:-1;;;;;50015:54;;;;20837:58;;36493:2;36478:18;;21208:37;36321:2;36306:18;;36292:215::o;36514:640::-;-1:-1;;;;;50015:54;;;20968:37;;50015:54;;36908:2;36893:18;;20968:37;36991:2;36976:18;;21208:37;;;36743:3;37028:2;37013:18;;37006:48;;;36514:640;;37068:76;;36728:19;;37130:6;37068:76;:::i;37161:345::-;-1:-1;;;;;50015:54;;;;20968:37;;50231:4;50220:16;37492:2;37477:18;;23844:56;37322:2;37307:18;;37293:213::o;37853:222::-;21208:37;;;37980:2;37965:18;;37951:124::o;38082:333::-;21208:37;;;-1:-1;;;;;50015:54;38401:2;38386:18;;20968:37;38237:2;38222:18;;38208:207::o;38422:822::-;21208:37;;;-1:-1;;;;;50015:54;;;38875:2;38860:18;;20968:37;50015:54;;;38966:2;38951:18;;20837:58;50015:54;;39057:2;39042:18;;20837:58;39138:3;39123:19;;21208:37;;;;50026:42;39214:19;;23698:57;38710:3;38695:19;;38681:563::o;39251:306::-;;39396:2;39417:17;39410:47;39471:76;39396:2;39385:9;39381:18;39533:6;39471:76;:::i;41501:416::-;41701:2;41715:47;;;24491:2;41686:18;;;48452:19;24527:29;48492:14;;;24507:50;24576:12;;;41672:245::o;41924:416::-;42124:2;42138:47;;;25149:2;42109:18;;;48452:19;-1:-1;;;48492:14;;;25165:45;25229:12;;;42095:245::o;42347:416::-;42547:2;42561:47;;;26739:2;42532:18;;;48452:19;26775:31;48492:14;;;26755:52;26826:12;;;42518:245::o;42770:416::-;42970:2;42984:47;;;27077:2;42955:18;;;48452:19;27113:34;48492:14;;;27093:55;-1:-1;;;27168:12;;;27161:34;27214:12;;;42941:245::o;43193:416::-;43393:2;43407:47;;;27465:2;43378:18;;;48452:19;-1:-1;;;48492:14;;;27481:35;27535:12;;;43364:245::o;43616:390::-;;43803:2;43824:17;43817:47;43878:118;43803:2;43792:9;43788:18;43982:6;43878:118;:::i;44013:527::-;;44241:2;44262:17;44255:47;44316:118;44241:2;44230:9;44226:18;44420:6;44316:118;:::i;:::-;44308:126;;53457:1;53450:5;53447:12;53437:2;;53463:9;53437:2;52303:39;44526:2;44515:9;44511:18;23428:63;44212:328;;;;;:::o;44776:460::-;21208:37;;;-1:-1;;;;;50015:54;;;;45139:2;45124:18;;20837:58;45222:2;45207:18;;21208:37;44967:2;44952:18;;44938:298::o;45243:556::-;21208:37;;;-1:-1;;;;;50015:54;;;;45619:2;45604:18;;20968:37;45702:2;45687:18;;21208:37;45785:2;45770:18;;21208:37;45454:3;45439:19;;45425:374::o;45806:436::-;21208:37;;;46147:2;46132:18;;21208:37;;;;46228:2;46213:18;;21208:37;45985:2;45970:18;;45956:286::o;47171:333::-;21208:37;;;47490:2;47475:18;;21208:37;47326:2;47311:18;;47297:207::o;47511:256::-;47573:2;47567:9;47599:17;;;47674:18;47659:34;;47695:22;;;47656:62;47653:2;;;47731:1;;47721:12;47653:2;47573;47740:22;47551:216;;-1:-1;47551:216::o;47774:321::-;;47917:18;47909:6;47906:30;47903:2;;;-1:-1;;47939:12;47903:2;-1:-1;53352:7;47993:17;-1:-1;;47989:33;48080:4;48070:15;;47840:255::o;52992:268::-;53057:1;53064:101;53078:6;53075:1;53072:13;53064:101;;;53145:11;;;53139:18;53126:11;;;53119:39;53100:2;53093:10;53064:101;;;53180:6;53177:1;53174:13;53171:2;;;53057:1;53236:6;53231:3;53227:16;53220:27;53171:2;;53041:219;;;:::o;53486:117::-;-1:-1;;;;;50015:54;;53545:35;;53535:2;;53594:1;;53584:12;53535:2;53529:74;:::o;53750:111::-;53831:5;49286:13;49279:21;53809:5;53806:32;53796:2;;53852:1;;53842:12
Swarm Source
ipfs://1a2cf479e908fd9855096af3a224a6ccc54d175af895b69b7b272aaa1b3c93c3
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.