More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 13822715 | 1056 days ago | IN | 0 ETH | 0.27882325 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
18209708 | 410 days ago | 23.57657433 ETH | ||||
18209708 | 410 days ago | 11.04354203 ETH | ||||
18209708 | 410 days ago | 12.53303229 ETH | ||||
18185025 | 413 days ago | 7.75895228 ETH | ||||
18185025 | 413 days ago | 2.32702264 ETH | ||||
18185025 | 413 days ago | 5.43192963 ETH | ||||
17973399 | 443 days ago | 3.84527206 ETH | ||||
17973399 | 443 days ago | 2.53560414 ETH | ||||
17973399 | 443 days ago | 1.30966791 ETH | ||||
17937675 | 448 days ago | 5.51269915 ETH | ||||
17937675 | 448 days ago | 4.63357068 ETH | ||||
17937675 | 448 days ago | 0.87912846 ETH | ||||
17937675 | 448 days ago | 7.71080774 ETH | ||||
17937675 | 448 days ago | 5.72709474 ETH | ||||
17937675 | 448 days ago | 1.98371299 ETH | ||||
17937674 | 448 days ago | 7.57876313 ETH | ||||
17937674 | 448 days ago | 5.73233245 ETH | ||||
17937674 | 448 days ago | 1.84643067 ETH | ||||
17864703 | 458 days ago | 31.7700799 ETH | ||||
17864703 | 458 days ago | 17.48471584 ETH | ||||
17864703 | 458 days ago | 14.28536405 ETH | ||||
17752402 | 474 days ago | 4.05954421 ETH | ||||
17752402 | 474 days ago | 2.61889688 ETH | ||||
17752402 | 474 days ago | 1.44064732 ETH | ||||
17481015 | 512 days ago | 9.52247716 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-12-17 */ 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)); } } 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, true); _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 /// @param _toEth If we want wrapped or plain eth to be returned function drawCollateral( address _managerAddr, uint256 _cdpId, address _joinAddr, uint256 _amount, bool _toEth ) 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) && _toEth) { 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 ILendingPoolAddressesProviderV2 { event LendingPoolUpdated(address indexed newAddress); event ConfigurationAdminUpdated(address indexed newAddress); event EmergencyAdminUpdated(address indexed newAddress); event LendingPoolConfiguratorUpdated(address indexed newAddress); event LendingPoolCollateralManagerUpdated(address indexed newAddress); event PriceOracleUpdated(address indexed newAddress); event LendingRateOracleUpdated(address indexed newAddress); event ProxyCreated(bytes32 id, address indexed newAddress); event AddressSet(bytes32 id, address indexed newAddress, bool hasProxy); function setAddress(bytes32 id, address newAddress) external; function setAddressAsProxy(bytes32 id, address impl) external; function getAddress(bytes32 id) external view returns (address); function getLendingPool() external view returns (address); function setLendingPoolImpl(address pool) external; function getLendingPoolConfigurator() external view returns (address); function setLendingPoolConfiguratorImpl(address configurator) external; function getLendingPoolCollateralManager() external view returns (address); function setLendingPoolCollateralManager(address manager) external; function getPoolAdmin() external view returns (address); function setPoolAdmin(address admin) external; function getEmergencyAdmin() external view returns (address); function setEmergencyAdmin(address admin) external; function getPriceOracle() external view returns (address); function setPriceOracle(address priceOracle) external; function getLendingRateOracle() external view returns (address); function setLendingRateOracle(address lendingRateOracle) external; } /// @title Receiver of Aave flash loan and performs the fl repay/boost logic contract MCDSaverFlashLoan is MCDSaverProxy, AdminAuth { address internal constant AAVE_MARKET_ADDR = 0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5; address internal constant BALANCER_VAULT_ADDR = 0xBA12222222228d8Ba445958a75a0704d566BF2C8; struct SaverData { uint256 cdpId; uint256 gasCost; uint256 loanAmount; uint256 fee; address joinAddr; ManagerType managerType; } // Balancer fl callback function receiveFlashLoan( address[] memory _tokens, uint256[] memory _amounts, uint256[] memory _fees, bytes memory _params ) external { require(msg.sender == BALANCER_VAULT_ADDR, "Only balancer can call"); _receiveFl(_tokens[0], _amounts[0], _fees[0], _params); ERC20(_tokens[0]).safeTransfer(address(BALANCER_VAULT_ADDR), add(_amounts[0], _fees[0])); } // AaveV2 fl callback function executeOperation( address[] memory _assets, uint256[] memory _amounts, uint256[] memory _fees, address, bytes memory _params ) public returns (bool) { address lendingPool = ILendingPoolAddressesProviderV2(AAVE_MARKET_ADDR).getLendingPool(); require(msg.sender == lendingPool, "Only aave pool can call"); _receiveFl(_assets[0], _amounts[0], _fees[0], _params); ERC20(_assets[0]).safeApprove(lendingPool, add(_amounts[0], _fees[0])); return true; } /// @notice Gets called by fl entry point functions function _receiveFl( address _tokenAddr, uint256 _amount, uint256 _fee, bytes memory _params ) internal { ( 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); // we get weth from FL, withdraw it to weth if (_tokenAddr == EXCHANGE_WETH_ADDRESS) { TokenInterface(EXCHANGE_WETH_ADDRESS).withdraw(_amount); } 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); } // 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, true ); // 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), false ); logger.Log( address(this), msg.sender, "MCDFlashRepay", abi.encode(_saverData.cdpId, user, _exchangeData.srcAmount, paybackAmount) ); } receive() external payable override(DFSExchangeCore) {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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":"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":"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":"_assets","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"_fees","type":"uint256[]"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"_params","type":"bytes"}],"name":"executeOperation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"_fees","type":"uint256[]"},{"internalType":"bytes","name":"_params","type":"bytes"}],"name":"receiveFlashLoan","outputs":[],"stateMutability":"nonpayable","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
608060405234801561001057600080fd5b50600080546001600160a01b031990811673bc841b0de0b93205e912cfbbd1d0c160a1ec6f0017909155600180549091167325efa336886c74ea8e282ac466bdcd0199f85bb917905561527f806100686000396000f3fe6080604052600436106102605760003560e01c80638aa0fd0e11610144578063c50ebaf8116100b6578063dd6d903c1161007a578063dd6d903c14610607578063deca5f8814610627578063e870b9cd14610647578063f04f27071461065a578063f24ccbfe1461067a578063f851a4401461068f57610267565b8063c50ebaf8146105ca578063c7975824146105df578063cc694d48146105f2578063cf786f8f146103b1578063cfac57c7146105b557610267565b8063a3b8e5d111610108578063a3b8e5d114610529578063a46a66c914610556578063a7304bf71461056b578063acbeba611461058b578063ae08fd10146105a0578063c11645bc146105b557610267565b80638aa0fd0e1461049d5780638c8a7958146104bd5780638da5cb5b146104d2578063920f5c84146104e7578063a342f2381461051457610267565b806331d98b3f116101dd578063449b9ffa116101a1578063449b9ffa146104295780634d2ab9dc1461043e5780634d93667e14610453578063526d6461146104735780636738929f1461034757806381b942801461048857610267565b806331d98b3f1461039157806336569e77146103b15780633a128322146103c65780634115fe6b146103e657806341c0e1b51461041457610267565b806329f7fc9e1161022457806329f7fc9e146103105780632a4c0a1a146103325780632e77468d146103475780632f634a901461035c578063314b63321461037c57610267565b806304c9805c1461026c57806308d4f52a14610297578063186cab76146102c45780631e48907b146102d9578063278d5831146102fb57610267565b3661026757005b600080fd5b34801561027857600080fd5b506102816106a4565b60405161028e9190614f43565b60405180910390f35b3480156102a357600080fd5b506102b76102b23660046149f9565b6106aa565b60405161028e9190614f98565b3480156102d057600080fd5b506102816106d4565b3480156102e557600080fd5b506102f96102f4366004614630565b6106e0565b005b34801561030757600080fd5b506102b7610719565b34801561031c57600080fd5b50610325610741565b60405161028e9190614d5f565b34801561033e57600080fd5b50610325610759565b34801561035357600080fd5b50610325610771565b34801561036857600080fd5b506103256103773660046149af565b610789565b34801561038857600080fd5b50610325610885565b34801561039d57600080fd5b506102816103ac3660046148c0565b61089d565b3480156103bd57600080fd5b50610325610a5b565b3480156103d257600080fd5b506102f96103e1366004614668565b610a73565b3480156103f257600080fd5b50610406610401366004614693565b610b0c565b60405161028e929190615181565b34801561042057600080fd5b506102f9610d28565b34801561043557600080fd5b506102b7610d4d565b34801561044a57600080fd5b50610281610d7f565b34801561045f57600080fd5b5061032561046e3660046149de565b610d85565b34801561047f57600080fd5b50610325610de4565b34801561049457600080fd5b50610325610dfc565b3480156104a957600080fd5b506102816104b8366004614693565b610e14565b3480156104c957600080fd5b50610325610ef5565b3480156104de57600080fd5b50610325610f0d565b3480156104f357600080fd5b50610507610502366004614710565b610f1c565b60405161028e9190614f38565b34801561052057600080fd5b5061032561108f565b34801561053557600080fd5b506105496105443660046148f0565b6110a7565b60405161028e91906150e9565b34801561056257600080fd5b506103256110c3565b34801561057757600080fd5b506102f9610586366004614630565b6110db565b34801561059757600080fd5b50610325611114565b3480156105ac57600080fd5b506102b761112c565b3480156105c157600080fd5b5061032561115d565b3480156105d657600080fd5b506102b7611175565b6102f96105ed366004614b32565b6111a4565b3480156105fe57600080fd5b506102b7611390565b34801561061357600080fd5b506102816106223660046146c7565b6113bb565b34801561063357600080fd5b506102f9610642366004614630565b611545565b6102f9610655366004614b32565b611572565b34801561066657600080fd5b506102f96106753660046147cc565b611755565b34801561068657600080fd5b50610325611840565b34801561069b57600080fd5b50610325611858565b61014d81565b6060816040516020016106bd91906150e9565b60405160208183030381529060405290505b919050565b644554482d4160d81b81565b6001546001600160a01b031633146106f757600080fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b81525081565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b736b175474e89094c44da98b954eedeac495271d0f81565b7365c79fcb50ca1594b025960e539ed7a9a6d434a381565b600080836001600160a01b0316638161b120846040518263ffffffff1660e01b81526004016107b89190614f43565b60206040518083038186803b1580156107d057600080fd5b505afa1580156107e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610808919061464c565b9050806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561084357600080fd5b505afa158015610857573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087b919061464c565b9150505b92915050565b7325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d81565b604051636cb1c69b60e11b815260009081907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906108d9908690600401614f43565b604080518083038186803b1580156108f057600080fd5b505afa158015610904573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092891906149c1565b604051636cb1c69b60e11b8152909250600091507335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063d9638d3690610966908790600401614f43565b60a06040518083038186803b15801561097e57600080fd5b505afa158015610992573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b69190614bc7565b505092505050610a53610a4d827365c79fcb50ca1594b025960e539ed7a9a6d434a36001600160a01b031663495d32cb6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1057600080fd5b505afa158015610a24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4891906148d8565b611867565b83611867565b949350505050565b7335d1b3f3d7966a1dfe207aa4514c12a259a0492b81565b6000546001600160a01b03163314610a8a57600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b0383161415610aee57600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015610ae8573d6000803e3d6000fd5b50610b08565b600054610b08906001600160a01b038481169116836118a6565b5050565b6000806000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b158015610b4a57600080fd5b505afa158015610b5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b82919061464c565b90506000866001600160a01b0316632726b073876040518263ffffffff1660e01b8152600401610bb29190614f43565b60206040518083038186803b158015610bca57600080fd5b505afa158015610bde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c02919061464c565b9050600080836001600160a01b0316632424be5c88856040518363ffffffff1660e01b8152600401610c35929190614f4c565b604080518083038186803b158015610c4c57600080fd5b505afa158015610c60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c849190614ba4565b915091506000846001600160a01b031663d9638d36896040518263ffffffff1660e01b8152600401610cb69190614f43565b60a06040518083038186803b158015610cce57600080fd5b505afa158015610ce2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d069190614bc7565b50505091505082610d178383611867565b965096505050505050935093915050565b6000546001600160a01b03163314610d3f57600080fd5b6000546001600160a01b0316ff5b6040518060400160405280601681526020017516995c9bde08195e18da185b99d9481a5b9d985b1a5960521b81525081565b61019081565b600080826001811115610d9457fe5b1415610db55750735ef30b9986345249bc32d8928b7ee64de9435e396106cf565b6001826001811115610dc357fe5b14156106cf5750733f30c2381cd8b917dd96eb2f1a4f96d91324bbed6106cf565b73637726f8b08a7abe3ae3acab01a80e2d8ddef77b81565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600080610e208361089d565b604051636cb1c69b60e11b81529091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d3690610e5d908790600401614f43565b604080518083038186803b158015610e7457600080fd5b505afa158015610e88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eac91906149c1565b915050600080610ebd888888610b0c565b91509150610ee7610ee0610eda610ed48588611901565b86611925565b83611930565b600a611930565b9450505050505b9392505050565b734ba1f38427b33b8ab7bb0490200dae1f1c36823f81565b6000546001600160a01b031681565b60008073b53c1a33016b2dc2ff3653530bff1848a515c8c56001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f6c57600080fd5b505afa158015610f80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa4919061464c565b9050336001600160a01b03821614610fd75760405162461bcd60e51b8152600401610fce9061508c565b60405180910390fd5b61101f87600081518110610fe757fe5b602002602001015187600081518110610ffc57fe5b60200260200101518760008151811061101157fe5b602002602001015186611940565b611082816110558860008151811061103357fe5b60200260200101518860008151811061104857fe5b6020026020010151611ac3565b8960008151811061106257fe5b60200260200101516001600160a01b0316611ad39092919063ffffffff16565b5060019695505050505050565b7339c4a92dc506300c3ea4c67ca4ca611102ee6f2a81565b6110af614182565b8180602001905181019061087f9190614a2b565b731b14e8d511c9a4395425314f849bd737baf8208f81565b6001546001600160a01b031633146110f257600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b7319c0976f590d67707e62397c87829d896dc0f1f181565b6040518060400160405280601581526020017413d99998da185a5b8819185d18481a5b9d985b1a59605a1b81525081565b739759a6ac90977b93b58547b4a71c78317f391a2881565b604051806040016040528060138152602001724465737420616d6f756e74206d697373696e6760681b81525081565b60006111af82610d85565b905060006111bd8287610789565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016111ed9190614f43565b60206040518083038186803b15801561120557600080fd5b505afa158015611219573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123d91906148d8565b905060006112518489848c60400151611b12565b6001600160a01b03841660c08b0152905061126a611f42565b6112765761019061127a565b61014d5b60a08a01526112928161128d8982611fd1565b611930565b60408a015260006112a28a6120c8565b9150506112b1858a898461240f565b47156112e55760405132904780156108fc02916000818181858888f193505050501580156112e3573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338c888f60400151876040516020016113259493929190615147565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161135293929190614de7565b600060405180830381600087803b15801561136c57600080fd5b505af1158015611380573d6000803e3d6000fd5b5050505050505050505050505050565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b81525081565b6000806113c78461089d565b90506000806113d7888888610b0c565b604051636cb1c69b60e11b815291935091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d3690611416908a90600401614f43565b604080518083038186803b15801561142d57600080fd5b505afa158015611441573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146591906149c1565b91505060006114818461128d61147b8587611901565b88611925565b90506000876001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b1580156114be57600080fd5b505afa1580156114d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f691906148d8565b905060128111156115195760405162461bcd60e51b8152600401610fce90614fab565b600081601203600a0a838161152a57fe5b04905060646063820204975050505050505050949350505050565b6000546001600160a01b0316331461155c57600080fd5b6001546001600160a01b0316156110f257600080fd5b600061157d82610d85565b9050600061158b8287610789565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016115bb9190614f43565b60206040518083038186803b1580156115d357600080fd5b505afa1580156115e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160b91906148d8565b905061161f8388878b604001516001612761565b506001600160a01b03821660c0890152611637611f42565b61164357610190611647565b61014d5b60a08901526000611657896120c8565b9150506116688161128d8984611fd1565b90506116778489848487612a33565b47156116ab5760405132904780156108fc02916000818181858888f193505050501580156116a9573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338b878e60400151876040516020016116eb9493929190615147565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161171893929190614e84565b600060405180830381600087803b15801561173257600080fd5b505af1158015611746573d6000803e3d6000fd5b50505050505050505050505050565b3373ba12222222228d8ba445958a75a0704d566bf2c8146117885760405162461bcd60e51b8152600401610fce90614fdb565b6117d08460008151811061179857fe5b6020026020010151846000815181106117ad57fe5b6020026020010151846000815181106117c257fe5b602002602001015184611940565b61183a73ba12222222228d8ba445958a75a0704d566bf2c861180d856000815181106117f857fe5b60200260200101518560008151811061104857fe5b8660008151811061181a57fe5b60200260200101516001600160a01b03166118a69092919063ffffffff16565b50505050565b735c55b921f590a89c1ebe84df170e655a82b6212681565b6001546001600160a01b031681565b6000676765c793fa10079d601b1b6118976118828585611901565b6002676765c793fa10079d601b1b5b04611ac3565b8161189e57fe5b049392505050565b6118fc8363a9059cbb60e01b84846040516024016118c5929190614ed0565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612db2565b505050565b600081158061191c5750508082028282828161191957fe5b04145b61087f57600080fd5b600081838161189e57fe5b8082038281111561087f57600080fd5b606060008060008060008680602001905181019061195e9190614922565b955095509550955095509550611972614182565b61197b876110a7565b90506001600160a01b038b1673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21415611a0c57604051632e1a7d4d60e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d906119d9908d90600401614f43565b600060405180830381600087803b1580156119f357600080fd5b505af1158015611a07573d6000803e3d6000fd5b505050505b611a146141fe565b6040518060c001604052808881526020018781526020018c81526020018b8152602001866001600160a01b031681526020018460ff166001811115611a5557fe5b6001811115611a6057fe5b905290508315611a7957611a748282612e41565b611a83565b611a838282613052565b4715611ab55760405132904780156108fc02916000818181858888f19350505050158015611746573d6000803e3d6000fd5b505050505050505050505050565b8082018281101561087f57600080fd5b611af38363095ea7b360e01b8460006040516024016118c5929190614f1c565b6118fc8363095ea7b360e01b84846040516024016118c5929190614ed0565b60405163089c54b560e31b815260009081907319c0976f590d67707e62397c87829d896dc0f1f1906344e2a5a890611b4e908790600401614f43565b602060405180830381600087803b158015611b6857600080fd5b505af1158015611b7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba091906148d8565b905060007335d1b3f3d7966a1dfe207aa4514c12a259a0492b6001600160a01b0316636c25b346886001600160a01b0316632726b073896040518263ffffffff1660e01b8152600401611bf39190614f43565b60206040518083038186803b158015611c0b57600080fd5b505afa158015611c1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c43919061464c565b6040518263ffffffff1660e01b8152600401611c5f9190614d5f565b60206040518083038186803b158015611c7757600080fd5b505afa158015611c8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611caf91906148d8565b90506000611cbe888888610e14565b9050808510611cd557611cd2816001611930565b94505b876001600160a01b03166345e6bdcd886000611cf289888861331b565b6040518463ffffffff1660e01b8152600401611d109392919061516b565b600060405180830381600087803b158015611d2a57600080fd5b505af1158015611d3e573d6000803e3d6000fd5b50505050876001600160a01b031663f9f30db68830611d5c8961339e565b6040518463ffffffff1660e01b8152600401611d7a93929190615128565b600060405180830381600087803b158015611d9457600080fd5b505af1158015611da8573d6000803e3d6000fd5b5050604051634538c4eb60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250634538c4eb9150611df9903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614d73565b60206040518083038186803b158015611e1157600080fd5b505afa158015611e25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4991906148d8565b611ecb576040516328ec8bf160e21b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063a3b22fc490611e9890739759a6ac90977b93b58547b4a71c78317f391a2890600401614d5f565b600060405180830381600087803b158015611eb257600080fd5b505af1158015611ec6573d6000803e3d6000fd5b505050505b60405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a289063ef693bed90611f049030908990600401614ed0565b600060405180830381600087803b158015611f1e57600080fd5b505af1158015611f32573d6000803e3d6000fd5b50969a9950505050505050505050565b6040516320eb73ed60e11b815260009073637726f8b08a7abe3ae3acab01a80e2d8ddef77b906341d6e7da90611f7c903290600401614d5f565b60206040518083038186803b158015611f9457600080fd5b505afa158015611fa8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fcc9190614873565b905090565b600082156120bf576000611fec644554482d4160d81b61089d565b90506000611ffa8583611867565b90506005840481111561200d5750600583045b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561205c57600080fd5b505afa158015612070573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612094919061464c565b90506120b5736b175474e89094c44da98b954eedeac495271d0f82846118a6565b50915061087f9050565b50600092915050565b600080600080600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b031686600001516001600160a01b0316141561218357855161210d906133b5565b6001600160a01b031686526040808701518151630d0e30db60e41b8152915173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29263d0e30db09291600480830192600092919082900301818588803b15801561216957600080fd5b505af115801561217d573d6000803e3d6000fd5b50505050505b61219f86604001518760c0015188600001518960a001516133fc565b60408701805191909103905261012086015160600151156121dc576121c586600061364f565b9250905080156121dc578561012001516020015192505b806121f6576121ec86600061384d565b91508560e0015192505b600061221573c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2613a8f565b11156122fb576040516370a0823160e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d9082906370a082319061225a903090600401614d5f565b602060405180830381600087803b15801561227457600080fd5b505af1158015612288573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122ac91906148d8565b6040518263ffffffff1660e01b81526004016122c89190614f43565b600060405180830381600087803b1580156122e257600080fd5b505af11580156122f6573d6000803e3d6000fd5b505050505b60208601516001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2141561239e5761233686608001518760400151613b39565b61235373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee613a8f565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906123985760405162461bcd60e51b8152600401610fce9190614f98565b50612404565b6123b086608001518760400151613b39565b6123bd8760200151613a8f565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906124025760405162461bcd60e51b8152600401610fce9190614f98565b505b509092509050915091565b600061241a83613b61565b156124f357826001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561245857600080fd5b505afa15801561246c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612490919061464c565b6001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b1580156124ca57600080fd5b505af11580156124de573d6000803e3d6000fd5b50505050506124ec82613c3e565b9050612508565b6125056125008484613c60565b613c3e565b90505b61258e8383856001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561254657600080fd5b505afa15801561255a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257e919061464c565b6001600160a01b03169190611ad3565b604051633b4da69f60e01b81526001600160a01b03841690633b4da69f906125bc9030908690600401614ed0565b600060405180830381600087803b1580156125d657600080fd5b505af11580156125ea573d6000803e3d6000fd5b5050604051632c2cb9fd60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250637608870391506001600160a01b03881690632c2cb9fd90612636908990600401614f43565b60206040518083038186803b15801561264e57600080fd5b505afa158015612662573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268691906148d8565b604051632726b07360e01b81526001600160a01b03891690632726b073906126b2908a90600401614f43565b60206040518083038186803b1580156126ca57600080fd5b505afa1580156126de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612702919061464c565b30308660006040518763ffffffff1660e01b815260040161272896959493929190614f63565b600060405180830381600087803b15801561274257600080fd5b505af1158015612756573d6000803e3d6000fd5b505050505050505050565b6000808390506000856001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b1580156127a257600080fd5b505afa1580156127b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127da91906148d8565b905060128111156127fd5760405162461bcd60e51b8152600401610fce90614fab565b806012146128115780601203600a0a850291505b876001600160a01b03166345e6bdcd8861282a85613c3e565b60000360006040518463ffffffff1660e01b815260040161284d9392919061516b565b600060405180830381600087803b15801561286757600080fd5b505af115801561287b573d6000803e3d6000fd5b50506040516313771f0760e31b81526001600160a01b038b169250639bb8f83891506128af908a9030908790600401615128565b600060405180830381600087803b1580156128c957600080fd5b505af11580156128dd573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038916925063ef693bed915061290f9030908990600401614ed0565b600060405180830381600087803b15801561292957600080fd5b505af115801561293d573d6000803e3d6000fd5b5050505061294a86613b61565b80156129535750835b15612a2757856001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561299157600080fd5b505afa1580156129a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c9919061464c565b6001600160a01b0316632e1a7d4d866040518263ffffffff1660e01b81526004016129f49190614f43565b600060405180830381600087803b158015612a0e57600080fd5b505af1158015612a22573d6000803e3d6000fd5b505050505b50929695505050505050565b604051632726b07360e01b81526000906001600160a01b03871690632726b07390612a62908890600401614f43565b60206040518083038186803b158015612a7a57600080fd5b505afa158015612a8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ab2919061464c565b90506000612ad67335d1b3f3d7966a1dfe207aa4514c12a259a0492b838488613ce2565b905080841115612b7957736b175474e89094c44da98b954eedeac495271d0f63a9059cbb84612b058785611930565b6040518363ffffffff1660e01b8152600401612b22929190614ed0565b602060405180830381600087803b158015612b3c57600080fd5b505af1158015612b50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b749190614873565b508093505b604051636eb1769f60e11b8152736b175474e89094c44da98b954eedeac495271d0f9063dd62ed3e90612bc6903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614d73565b60206040518083038186803b158015612bde57600080fd5b505afa158015612bf2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c1691906148d8565b612cbd5760405163095ea7b360e01b8152736b175474e89094c44da98b954eedeac495271d0f9063095ea7b390612c6990739759a6ac90977b93b58547b4a71c78317f391a289060001990600401614ed0565b602060405180830381600087803b158015612c8357600080fd5b505af1158015612c97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cbb9190614873565b505b604051633b4da69f60e01b8152739759a6ac90977b93b58547b4a71c78317f391a2890633b4da69f90612cf69085908890600401614ed0565b600060405180830381600087803b158015612d1057600080fd5b505af1158015612d24573d6000803e3d6000fd5b50505050866001600160a01b03166345e6bdcd876000612d597335d1b3f3d7966a1dfe207aa4514c12a259a0492b878b613ebd565b6040518463ffffffff1660e01b8152600401612d779392919061516b565b600060405180830381600087803b158015612d9157600080fd5b505af1158015612da5573d6000803e3d6000fd5b5050505050505050505050565b6060612e07826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661407b9092919063ffffffff16565b8051909150156118fc5780806020019051810190612e259190614873565b6118fc5760405162461bcd60e51b8152600401610fce90615042565b6000612e508260a00151610d85565b90506000612e62828460000151610789565b8351604051632c2cb9fd60e01b81529192506000916001600160a01b03851691632c2cb9fd91612e959190600401614f43565b60206040518083038186803b158015612ead57600080fd5b505afa158015612ec1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ee591906148d8565b90506000612efd8486600001518488608001516113bb565b90506000612f178587600001518860800151856001612761565b9050612f27866040015182611ac3565b60408801526001600160a01b03841660c0880152612f43611f42565b612f4f57610190612f53565b61014d5b60a08801526000612f63886120c8565b915050612f788161128d896020015184611fd1565b9050612f8b868860000151868489612a33565b612fb28688600001518960800151612fab8b604001518c60600151611ac3565b6000612761565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338a60000151898d6040015187604051602001612ff79493929190615147565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161302493929190614e33565b600060405180830381600087803b15801561303e57600080fd5b505af1158015611ab5573d6000803e3d6000fd5b60006130618260a00151610d85565b90506000613073828460000151610789565b8351604051632c2cb9fd60e01b81529192506000916130fd9185916001600160a01b03831690632c2cb9fd906130ad908490600401614f43565b60206040518083038186803b1580156130c557600080fd5b505afa1580156130d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b891906148d8565b8451604051632c2cb9fd60e01b815291925060009161318d9186916001600160a01b03831690632c2cb9fd90613137908490600401614f43565b60206040518083038186803b15801561314f57600080fd5b505afa158015613163573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061318791906148d8565b85611b12565b90506131bb6131a0828760400151611ac3565b61128d87602001516131b6858a60400151611ac3565b611fd1565b60408701526001600160a01b03831660c08701526131d7611f42565b6131e3576101906131e7565b61014d5b60a087015260006131f7876120c8565b91505061320e85876000015188608001518461240f565b8551604051632c2cb9fd60e01b81526132a99187916001600160a01b03831690632c2cb9fd90613242908490600401614f43565b60206040518083038186803b15801561325a57600080fd5b505afa15801561326e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061329291906148d8565b6132a48a604001518b60600151611ac3565b611b12565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338960000151888c60400151876040516020016132ee9493929190615147565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612d7793929190614d8d565b600061333284676765c793fa10079d601b1b611901565b821015610eee576133688361335b61335587676765c793fa10079d601b1b611901565b85611930565b8161336257fe5b04613c3e565b905061337f84676765c793fa10079d601b1b611901565b6133898285611901565b106133945780610a53565b6001019392505050565b600061087f82676765c793fa10079d601b1b611901565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146133e1578161087f565b5073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2919050565b6000811580159061348f5750604051632cdc77ab60e21b8152731b14e8d511c9a4395425314f849bd737baf8208f9063b371deac9061343f908790600401614d5f565b60206040518083038186803b15801561345757600080fd5b505afa15801561346b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348f9190614873565b1561351e57604051636eeb543160e01b8152731b14e8d511c9a4395425314f849bd737baf8208f90636eeb5431906134cb908790600401614d5f565b60206040518083038186803b1580156134e357600080fd5b505afa1580156134f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061351b91906148d8565b91505b8161352b57506000610a53565b81858161353457fe5b049050600a85048111156135485750600a84045b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561359757600080fd5b505afa1580156135ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135cf919061464c565b90506001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415613632576040516001600160a01b0382169083156108fc029084906000818181858888f1935050505015801561362c573d6000803e3d6000fd5b50613646565b6136466001600160a01b03851682846118a6565b50949350505050565b610120820151602001516040516302f5cc7960e11b81526000918291734ba1f38427b33b8ab7bb0490200dae1f1c36823f916305eb98f2916136949190600401614d5f565b60206040518083038186803b1580156136ac57600080fd5b505afa1580156136c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136e49190614873565b6136f357506000905080613846565b6101208401515160405163e0aa279760e01b81527325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa2797916137309190600401614d5f565b60206040518083038186803b15801561374857600080fd5b505afa15801561375c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137809190614873565b61378f57506000905080613846565b61012084015151604085015185516137b2926001600160a01b03909116916118a6565b610120840151805160809091015160405163097396a160e31b81526001600160a01b0390921691634b9cb50891906137f090889088906004016150fc565b60408051808303818588803b15801561380857600080fd5b505af115801561381c573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190613841919061488f565b915091505b9250929050565b60e082015160405163e0aa279760e01b81526000917325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa27979161388a91600401614d5f565b60206040518083038186803b1580156138a257600080fd5b505afa1580156138b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138da9190614873565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b815250906139205760405162461bcd60e51b8152600401610fce9190614f98565b5060e083015160408401518451613942926001600160a01b03909116916118a6565b600082600181111561395057fe5b14156139f6578260e001516001600160a01b0316635b6f36fc8460000151856020015186604001518761010001516040518563ffffffff1660e01b815260040161399d9493929190614ee9565b602060405180830381600087803b1580156139b757600080fd5b505af11580156139cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139ef91906148d8565b905061087f565b8260e001516001600160a01b0316633924db668460000151856020015186606001518761010001516040518563ffffffff1660e01b8152600401613a3d9493929190614ee9565b602060405180830381600087803b158015613a5757600080fd5b505af1158015613a6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eee91906148d8565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415613abd5750476106cf565b6040516370a0823160e01b81526001600160a01b038316906370a0823190613ae9903090600401614d5f565b60206040518083038186803b158015613b0157600080fd5b505afa158015613b15573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087f91906148d8565b6000670de0b6b3a7640000611897613b518585611901565b6002670de0b6b3a7640000611891565b6000739759a6ac90977b93b58547b4a71c78317f391a286001600160a01b0383161415613b90575060006106cf565b816001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015613bc957600080fd5b505afa158015613bdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c01919061464c565b6001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03161415613c36575060016106cf565b506000919050565b8060008112156106cf5760405162461bcd60e51b8152600401610fce906150c3565b6000610eee82846001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b158015613c9f57600080fd5b505afa158015613cb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cd791906148d8565b601203600a0a611901565b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b8152600401613d119190614f43565b60a06040518083038186803b158015613d2957600080fd5b505afa158015613d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d619190614bc7565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b8152600401613d97929190614f4c565b604080518083038186803b158015613dae57600080fd5b505afa158015613dc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613de69190614ba4565b9150506000876001600160a01b0316636c25b346886040518263ffffffff1660e01b8152600401613e179190614d5f565b60206040518083038186803b158015613e2f57600080fd5b505afa158015613e43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e6791906148d8565b90506000613e78610eda8486611901565b9050676765c793fa10079d601b1b8104945080613ea086676765c793fa10079d601b1b611901565b10613eab5784613eb0565b846001015b9998505050505050505050565b600080846001600160a01b0316636c25b346856040518263ffffffff1660e01b8152600401613eec9190614d5f565b60206040518083038186803b158015613f0457600080fd5b505afa158015613f18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f3c91906148d8565b90506000856001600160a01b031663d9638d36856040518263ffffffff1660e01b8152600401613f6c9190614f43565b60a06040518083038186803b158015613f8457600080fd5b505afa158015613f98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fbc9190614bc7565b5050509150506000866001600160a01b0316632424be5c86886040518363ffffffff1660e01b8152600401613ff2929190614f4c565b604080518083038186803b15801561400957600080fd5b505afa15801561401d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140419190614ba4565b91505061405082848161336257fe5b93508084111561406b5761406381613c3e565b600003614070565b836000035b979650505050505050565b6060610a538484600085606061409085614149565b6140ac5760405162461bcd60e51b8152600401610fce9061500b565b60006060866001600160a01b031685876040516140c99190614d43565b60006040518083038185875af1925050503d8060008114614106576040519150601f19603f3d011682016040523d82523d6000602084013e61410b565b606091505b5091509150811561411f579150610a539050565b80511561412f5780518082602001fd5b8360405162461bcd60e51b8152600401610fce9190614f98565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610a53575050151592915050565b60405180610140016040528060006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016141f9614242565b905290565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b03168152602001600060018111156141f957fe5b6040518060c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001606081525090565b803561087f81615223565b805161087f81615223565b600082601f8301126142b9578081fd5b81356142cc6142c7826151b5565b61518f565b8181529150602080830190848101818402860182018710156142ed57600080fd5b60005b8481101561431557813561430381615223565b845292820192908201906001016142f0565b505050505092915050565b600082601f830112614330578081fd5b813561433e6142c7826151b5565b81815291506020808301908481018184028601820187101561435f57600080fd5b60005b8481101561431557813584529282019290820190600101614362565b600082601f83011261438e578081fd5b813561439c6142c7826151d4565b91508082528360208285010111156143b357600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126143dc578081fd5b81516143ea6142c7826151d4565b915080825283602082850101111561440157600080fd5b6144128160208401602086016151f7565b5092915050565b80356002811061087f57600080fd5b600061014080838503121561443b578182fd5b6144448161518f565b9150506144518383614293565b81526144608360208401614293565b602082015260408201356040820152606082013560608201526080820135608082015260a082013560a082015261449a8360c08401614293565b60c08201526144ac8360e08401614293565b60e0820152610100808301356001600160401b03808211156144cd57600080fd5b6144d98683870161437e565b838501526101209250828501359150808211156144f557600080fd5b506145028582860161450e565b82840152505092915050565b600060c0828403121561451f578081fd5b61452960c061518f565b9050813561453681615223565b8152602082013561454681615223565b6020820152604082013561455981615223565b80604083015250606082013560608201526080820135608082015260a08201356001600160401b0381111561458d57600080fd5b6145998482850161437e565b60a08301525092915050565b600060c082840312156145b6578081fd5b6145c060c061518f565b905081516145cd81615223565b815260208201516145dd81615223565b602082015260408201516145f081615223565b80604083015250606082015160608201526080820151608082015260a08201516001600160401b0381111561462457600080fd5b614599848285016143cc565b600060208284031215614641578081fd5b8135610eee81615223565b60006020828403121561465d578081fd5b8151610eee81615223565b6000806040838503121561467a578081fd5b823561468581615223565b946020939093013593505050565b6000806000606084860312156146a7578081fd5b83356146b281615223565b95602085013595506040909401359392505050565b600080600080608085870312156146dc578182fd5b84356146e781615223565b93506020850135925060408501359150606085013561470581615223565b939692955090935050565b600080600080600060a08688031215614727578283fd5b85356001600160401b038082111561473d578485fd5b61474989838a016142a9565b9650602088013591508082111561475e578485fd5b61476a89838a01614320565b9550604088013591508082111561477f578485fd5b61478b89838a01614320565b94506060880135915061479d82615223565b909250608087013590808211156147b2578283fd5b506147bf8882890161437e565b9150509295509295909350565b600080600080608085870312156147e1578182fd5b84356001600160401b03808211156147f7578384fd5b614803888389016142a9565b95506020870135915080821115614818578384fd5b61482488838901614320565b94506040870135915080821115614839578384fd5b61484588838901614320565b9350606087013591508082111561485a578283fd5b506148678782880161437e565b91505092959194509250565b600060208284031215614884578081fd5b8151610eee8161523b565b600080604083850312156148a1578182fd5b825180151581146148b0578283fd5b6020939093015192949293505050565b6000602082840312156148d1578081fd5b5035919050565b6000602082840312156148e9578081fd5b5051919050565b600060208284031215614901578081fd5b81356001600160401b03811115614916578182fd5b61087b8482850161437e565b60008060008060008060c0878903121561493a578384fd5b86516001600160401b0381111561494f578485fd5b61495b89828a016143cc565b9650506020870151945060408701519350606087015161497a81615223565b608088015190935061498b8161523b565b60a088015190925060ff811681146149a1578182fd5b809150509295509295509295565b6000806040838503121561467a578182fd5b600080604083850312156149d3578182fd5b82516148b081615223565b6000602082840312156149ef578081fd5b610eee8383614419565b600060208284031215614a0a578081fd5b81356001600160401b03811115614a1f578182fd5b61087b84828501614428565b600060208284031215614a3c578081fd5b81516001600160401b0380821115614a52578283fd5b8184019150610140808387031215614a68578384fd5b614a718161518f565b9050614a7d868461429e565b8152614a8c866020850161429e565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a0820152614ac68660c0850161429e565b60c0820152614ad88660e0850161429e565b60e08201526101008084015183811115614af0578586fd5b614afc888287016143cc565b8284015250506101208084015183811115614b15578586fd5b614b21888287016145a5565b918301919091525095945050505050565b600080600080600060a08688031215614b49578283fd5b85356001600160401b03811115614b5e578384fd5b614b6a88828901614428565b95505060208601359350604086013592506060860135614b8981615223565b9150614b988760808801614419565b90509295509295909350565b60008060408385031215614bb6578182fd5b505080516020909101519092909150565b600080600080600060a08688031215614bde578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b6001600160a01b03169052565b60008151808452614c2b8160208601602086016151f7565b601f01601f19169290920160200192915050565b6000610140614c4f848451614c06565b6020830151614c616020860182614c06565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c0830151614c9c60c0860182614c06565b5060e0830151614caf60e0860182614c06565b50610100808401518282870152614cc883870182614c13565b925050506101208084015185830382870152614ce48382614cee565b9695505050505050565b600060018060a01b0380835116845280602084015116602085015280604084015116604085015250606082015160608401526080820151608084015260a082015160c060a085015261087b60c0850182614c13565b60008251614d558184602087016151f7565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c1350d1119b185cda109bdbdcdd609a1b60a082015260c060608201819052600090614dde90830184614c13565b95945050505050565b6001600160a01b03848116825283166020820152608060408201819052600890820152671350d1109bdbdcdd60c21b60a082015260c060608201819052600090614dde90830184614c13565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c4d4344466c617368526570617960981b60a082015260c060608201819052600090614dde90830184614c13565b6001600160a01b03848116825283166020820152608060408201819052600890820152674d4344526570617960c01b60a082015260c060608201819052600090614dde90830184614c13565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614ce490830184614c13565b6001600160a01b0392909216825260ff16602082015260400190565b901515815260200190565b90815260200190565b9182526001600160a01b0316602082015260400190565b9586526001600160a01b039485166020870152928416604086015292166060840152608083019190915260a082015260c00190565b600060208252610eee6020830184614c13565b602080825260169082015275546f6b656e20646563696d616c7320746f6f2062696760501b604082015260600190565b60208082526016908201527513db9b1e4818985b185b98d95c8818d85b8818d85b1b60521b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526017908201527f4f6e6c79206161766520706f6f6c2063616e2063616c6c000000000000000000604082015260600190565b6020808252600c908201526b696e742d6f766572666c6f7760a01b604082015260600190565b600060208252610eee6020830184614c3f565b60006040825261510f6040830185614c3f565b90506002831061511b57fe5b8260208301529392505050565b9283526001600160a01b03919091166020830152604082015260600190565b9384526001600160a01b039290921660208401526040830152606082015260800190565b9283526020830191909152604082015260600190565b918252602082015260400190565b6040518181016001600160401b03811182821017156151ad57600080fd5b604052919050565b60006001600160401b038211156151ca578081fd5b5060209081020190565b60006001600160401b038211156151e9578081fd5b50601f01601f191660200190565b60005b838110156152125781810151838201526020016151fa565b8381111561183a5750506000910152565b6001600160a01b038116811461523857600080fd5b50565b801515811461523857600080fdfea2646970667358221220dec659417d70d3ec958a4b9da14fc85d0a3f1da92a0b507ae95761b6ef65093964736f6c634300060c0033
Deployed Bytecode
0x6080604052600436106102605760003560e01c80638aa0fd0e11610144578063c50ebaf8116100b6578063dd6d903c1161007a578063dd6d903c14610607578063deca5f8814610627578063e870b9cd14610647578063f04f27071461065a578063f24ccbfe1461067a578063f851a4401461068f57610267565b8063c50ebaf8146105ca578063c7975824146105df578063cc694d48146105f2578063cf786f8f146103b1578063cfac57c7146105b557610267565b8063a3b8e5d111610108578063a3b8e5d114610529578063a46a66c914610556578063a7304bf71461056b578063acbeba611461058b578063ae08fd10146105a0578063c11645bc146105b557610267565b80638aa0fd0e1461049d5780638c8a7958146104bd5780638da5cb5b146104d2578063920f5c84146104e7578063a342f2381461051457610267565b806331d98b3f116101dd578063449b9ffa116101a1578063449b9ffa146104295780634d2ab9dc1461043e5780634d93667e14610453578063526d6461146104735780636738929f1461034757806381b942801461048857610267565b806331d98b3f1461039157806336569e77146103b15780633a128322146103c65780634115fe6b146103e657806341c0e1b51461041457610267565b806329f7fc9e1161022457806329f7fc9e146103105780632a4c0a1a146103325780632e77468d146103475780632f634a901461035c578063314b63321461037c57610267565b806304c9805c1461026c57806308d4f52a14610297578063186cab76146102c45780631e48907b146102d9578063278d5831146102fb57610267565b3661026757005b600080fd5b34801561027857600080fd5b506102816106a4565b60405161028e9190614f43565b60405180910390f35b3480156102a357600080fd5b506102b76102b23660046149f9565b6106aa565b60405161028e9190614f98565b3480156102d057600080fd5b506102816106d4565b3480156102e557600080fd5b506102f96102f4366004614630565b6106e0565b005b34801561030757600080fd5b506102b7610719565b34801561031c57600080fd5b50610325610741565b60405161028e9190614d5f565b34801561033e57600080fd5b50610325610759565b34801561035357600080fd5b50610325610771565b34801561036857600080fd5b506103256103773660046149af565b610789565b34801561038857600080fd5b50610325610885565b34801561039d57600080fd5b506102816103ac3660046148c0565b61089d565b3480156103bd57600080fd5b50610325610a5b565b3480156103d257600080fd5b506102f96103e1366004614668565b610a73565b3480156103f257600080fd5b50610406610401366004614693565b610b0c565b60405161028e929190615181565b34801561042057600080fd5b506102f9610d28565b34801561043557600080fd5b506102b7610d4d565b34801561044a57600080fd5b50610281610d7f565b34801561045f57600080fd5b5061032561046e3660046149de565b610d85565b34801561047f57600080fd5b50610325610de4565b34801561049457600080fd5b50610325610dfc565b3480156104a957600080fd5b506102816104b8366004614693565b610e14565b3480156104c957600080fd5b50610325610ef5565b3480156104de57600080fd5b50610325610f0d565b3480156104f357600080fd5b50610507610502366004614710565b610f1c565b60405161028e9190614f38565b34801561052057600080fd5b5061032561108f565b34801561053557600080fd5b506105496105443660046148f0565b6110a7565b60405161028e91906150e9565b34801561056257600080fd5b506103256110c3565b34801561057757600080fd5b506102f9610586366004614630565b6110db565b34801561059757600080fd5b50610325611114565b3480156105ac57600080fd5b506102b761112c565b3480156105c157600080fd5b5061032561115d565b3480156105d657600080fd5b506102b7611175565b6102f96105ed366004614b32565b6111a4565b3480156105fe57600080fd5b506102b7611390565b34801561061357600080fd5b506102816106223660046146c7565b6113bb565b34801561063357600080fd5b506102f9610642366004614630565b611545565b6102f9610655366004614b32565b611572565b34801561066657600080fd5b506102f96106753660046147cc565b611755565b34801561068657600080fd5b50610325611840565b34801561069b57600080fd5b50610325611858565b61014d81565b6060816040516020016106bd91906150e9565b60405160208183030381529060405290505b919050565b644554482d4160d81b81565b6001546001600160a01b031633146106f757600080fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b81525081565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b736b175474e89094c44da98b954eedeac495271d0f81565b7365c79fcb50ca1594b025960e539ed7a9a6d434a381565b600080836001600160a01b0316638161b120846040518263ffffffff1660e01b81526004016107b89190614f43565b60206040518083038186803b1580156107d057600080fd5b505afa1580156107e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610808919061464c565b9050806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561084357600080fd5b505afa158015610857573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087b919061464c565b9150505b92915050565b7325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d81565b604051636cb1c69b60e11b815260009081907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906108d9908690600401614f43565b604080518083038186803b1580156108f057600080fd5b505afa158015610904573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092891906149c1565b604051636cb1c69b60e11b8152909250600091507335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063d9638d3690610966908790600401614f43565b60a06040518083038186803b15801561097e57600080fd5b505afa158015610992573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b69190614bc7565b505092505050610a53610a4d827365c79fcb50ca1594b025960e539ed7a9a6d434a36001600160a01b031663495d32cb6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1057600080fd5b505afa158015610a24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4891906148d8565b611867565b83611867565b949350505050565b7335d1b3f3d7966a1dfe207aa4514c12a259a0492b81565b6000546001600160a01b03163314610a8a57600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b0383161415610aee57600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015610ae8573d6000803e3d6000fd5b50610b08565b600054610b08906001600160a01b038481169116836118a6565b5050565b6000806000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b158015610b4a57600080fd5b505afa158015610b5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b82919061464c565b90506000866001600160a01b0316632726b073876040518263ffffffff1660e01b8152600401610bb29190614f43565b60206040518083038186803b158015610bca57600080fd5b505afa158015610bde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c02919061464c565b9050600080836001600160a01b0316632424be5c88856040518363ffffffff1660e01b8152600401610c35929190614f4c565b604080518083038186803b158015610c4c57600080fd5b505afa158015610c60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c849190614ba4565b915091506000846001600160a01b031663d9638d36896040518263ffffffff1660e01b8152600401610cb69190614f43565b60a06040518083038186803b158015610cce57600080fd5b505afa158015610ce2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d069190614bc7565b50505091505082610d178383611867565b965096505050505050935093915050565b6000546001600160a01b03163314610d3f57600080fd5b6000546001600160a01b0316ff5b6040518060400160405280601681526020017516995c9bde08195e18da185b99d9481a5b9d985b1a5960521b81525081565b61019081565b600080826001811115610d9457fe5b1415610db55750735ef30b9986345249bc32d8928b7ee64de9435e396106cf565b6001826001811115610dc357fe5b14156106cf5750733f30c2381cd8b917dd96eb2f1a4f96d91324bbed6106cf565b73637726f8b08a7abe3ae3acab01a80e2d8ddef77b81565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600080610e208361089d565b604051636cb1c69b60e11b81529091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d3690610e5d908790600401614f43565b604080518083038186803b158015610e7457600080fd5b505afa158015610e88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eac91906149c1565b915050600080610ebd888888610b0c565b91509150610ee7610ee0610eda610ed48588611901565b86611925565b83611930565b600a611930565b9450505050505b9392505050565b734ba1f38427b33b8ab7bb0490200dae1f1c36823f81565b6000546001600160a01b031681565b60008073b53c1a33016b2dc2ff3653530bff1848a515c8c56001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f6c57600080fd5b505afa158015610f80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa4919061464c565b9050336001600160a01b03821614610fd75760405162461bcd60e51b8152600401610fce9061508c565b60405180910390fd5b61101f87600081518110610fe757fe5b602002602001015187600081518110610ffc57fe5b60200260200101518760008151811061101157fe5b602002602001015186611940565b611082816110558860008151811061103357fe5b60200260200101518860008151811061104857fe5b6020026020010151611ac3565b8960008151811061106257fe5b60200260200101516001600160a01b0316611ad39092919063ffffffff16565b5060019695505050505050565b7339c4a92dc506300c3ea4c67ca4ca611102ee6f2a81565b6110af614182565b8180602001905181019061087f9190614a2b565b731b14e8d511c9a4395425314f849bd737baf8208f81565b6001546001600160a01b031633146110f257600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b7319c0976f590d67707e62397c87829d896dc0f1f181565b6040518060400160405280601581526020017413d99998da185a5b8819185d18481a5b9d985b1a59605a1b81525081565b739759a6ac90977b93b58547b4a71c78317f391a2881565b604051806040016040528060138152602001724465737420616d6f756e74206d697373696e6760681b81525081565b60006111af82610d85565b905060006111bd8287610789565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016111ed9190614f43565b60206040518083038186803b15801561120557600080fd5b505afa158015611219573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123d91906148d8565b905060006112518489848c60400151611b12565b6001600160a01b03841660c08b0152905061126a611f42565b6112765761019061127a565b61014d5b60a08a01526112928161128d8982611fd1565b611930565b60408a015260006112a28a6120c8565b9150506112b1858a898461240f565b47156112e55760405132904780156108fc02916000818181858888f193505050501580156112e3573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338c888f60400151876040516020016113259493929190615147565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161135293929190614de7565b600060405180830381600087803b15801561136c57600080fd5b505af1158015611380573d6000803e3d6000fd5b5050505050505050505050505050565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b81525081565b6000806113c78461089d565b90506000806113d7888888610b0c565b604051636cb1c69b60e11b815291935091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d3690611416908a90600401614f43565b604080518083038186803b15801561142d57600080fd5b505afa158015611441573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146591906149c1565b91505060006114818461128d61147b8587611901565b88611925565b90506000876001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b1580156114be57600080fd5b505afa1580156114d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f691906148d8565b905060128111156115195760405162461bcd60e51b8152600401610fce90614fab565b600081601203600a0a838161152a57fe5b04905060646063820204975050505050505050949350505050565b6000546001600160a01b0316331461155c57600080fd5b6001546001600160a01b0316156110f257600080fd5b600061157d82610d85565b9050600061158b8287610789565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016115bb9190614f43565b60206040518083038186803b1580156115d357600080fd5b505afa1580156115e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160b91906148d8565b905061161f8388878b604001516001612761565b506001600160a01b03821660c0890152611637611f42565b61164357610190611647565b61014d5b60a08901526000611657896120c8565b9150506116688161128d8984611fd1565b90506116778489848487612a33565b47156116ab5760405132904780156108fc02916000818181858888f193505050501580156116a9573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338b878e60400151876040516020016116eb9493929190615147565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161171893929190614e84565b600060405180830381600087803b15801561173257600080fd5b505af1158015611746573d6000803e3d6000fd5b50505050505050505050505050565b3373ba12222222228d8ba445958a75a0704d566bf2c8146117885760405162461bcd60e51b8152600401610fce90614fdb565b6117d08460008151811061179857fe5b6020026020010151846000815181106117ad57fe5b6020026020010151846000815181106117c257fe5b602002602001015184611940565b61183a73ba12222222228d8ba445958a75a0704d566bf2c861180d856000815181106117f857fe5b60200260200101518560008151811061104857fe5b8660008151811061181a57fe5b60200260200101516001600160a01b03166118a69092919063ffffffff16565b50505050565b735c55b921f590a89c1ebe84df170e655a82b6212681565b6001546001600160a01b031681565b6000676765c793fa10079d601b1b6118976118828585611901565b6002676765c793fa10079d601b1b5b04611ac3565b8161189e57fe5b049392505050565b6118fc8363a9059cbb60e01b84846040516024016118c5929190614ed0565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612db2565b505050565b600081158061191c5750508082028282828161191957fe5b04145b61087f57600080fd5b600081838161189e57fe5b8082038281111561087f57600080fd5b606060008060008060008680602001905181019061195e9190614922565b955095509550955095509550611972614182565b61197b876110a7565b90506001600160a01b038b1673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21415611a0c57604051632e1a7d4d60e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d906119d9908d90600401614f43565b600060405180830381600087803b1580156119f357600080fd5b505af1158015611a07573d6000803e3d6000fd5b505050505b611a146141fe565b6040518060c001604052808881526020018781526020018c81526020018b8152602001866001600160a01b031681526020018460ff166001811115611a5557fe5b6001811115611a6057fe5b905290508315611a7957611a748282612e41565b611a83565b611a838282613052565b4715611ab55760405132904780156108fc02916000818181858888f19350505050158015611746573d6000803e3d6000fd5b505050505050505050505050565b8082018281101561087f57600080fd5b611af38363095ea7b360e01b8460006040516024016118c5929190614f1c565b6118fc8363095ea7b360e01b84846040516024016118c5929190614ed0565b60405163089c54b560e31b815260009081907319c0976f590d67707e62397c87829d896dc0f1f1906344e2a5a890611b4e908790600401614f43565b602060405180830381600087803b158015611b6857600080fd5b505af1158015611b7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba091906148d8565b905060007335d1b3f3d7966a1dfe207aa4514c12a259a0492b6001600160a01b0316636c25b346886001600160a01b0316632726b073896040518263ffffffff1660e01b8152600401611bf39190614f43565b60206040518083038186803b158015611c0b57600080fd5b505afa158015611c1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c43919061464c565b6040518263ffffffff1660e01b8152600401611c5f9190614d5f565b60206040518083038186803b158015611c7757600080fd5b505afa158015611c8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611caf91906148d8565b90506000611cbe888888610e14565b9050808510611cd557611cd2816001611930565b94505b876001600160a01b03166345e6bdcd886000611cf289888861331b565b6040518463ffffffff1660e01b8152600401611d109392919061516b565b600060405180830381600087803b158015611d2a57600080fd5b505af1158015611d3e573d6000803e3d6000fd5b50505050876001600160a01b031663f9f30db68830611d5c8961339e565b6040518463ffffffff1660e01b8152600401611d7a93929190615128565b600060405180830381600087803b158015611d9457600080fd5b505af1158015611da8573d6000803e3d6000fd5b5050604051634538c4eb60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250634538c4eb9150611df9903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614d73565b60206040518083038186803b158015611e1157600080fd5b505afa158015611e25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4991906148d8565b611ecb576040516328ec8bf160e21b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063a3b22fc490611e9890739759a6ac90977b93b58547b4a71c78317f391a2890600401614d5f565b600060405180830381600087803b158015611eb257600080fd5b505af1158015611ec6573d6000803e3d6000fd5b505050505b60405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a289063ef693bed90611f049030908990600401614ed0565b600060405180830381600087803b158015611f1e57600080fd5b505af1158015611f32573d6000803e3d6000fd5b50969a9950505050505050505050565b6040516320eb73ed60e11b815260009073637726f8b08a7abe3ae3acab01a80e2d8ddef77b906341d6e7da90611f7c903290600401614d5f565b60206040518083038186803b158015611f9457600080fd5b505afa158015611fa8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fcc9190614873565b905090565b600082156120bf576000611fec644554482d4160d81b61089d565b90506000611ffa8583611867565b90506005840481111561200d5750600583045b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561205c57600080fd5b505afa158015612070573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612094919061464c565b90506120b5736b175474e89094c44da98b954eedeac495271d0f82846118a6565b50915061087f9050565b50600092915050565b600080600080600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b031686600001516001600160a01b0316141561218357855161210d906133b5565b6001600160a01b031686526040808701518151630d0e30db60e41b8152915173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29263d0e30db09291600480830192600092919082900301818588803b15801561216957600080fd5b505af115801561217d573d6000803e3d6000fd5b50505050505b61219f86604001518760c0015188600001518960a001516133fc565b60408701805191909103905261012086015160600151156121dc576121c586600061364f565b9250905080156121dc578561012001516020015192505b806121f6576121ec86600061384d565b91508560e0015192505b600061221573c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2613a8f565b11156122fb576040516370a0823160e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d9082906370a082319061225a903090600401614d5f565b602060405180830381600087803b15801561227457600080fd5b505af1158015612288573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122ac91906148d8565b6040518263ffffffff1660e01b81526004016122c89190614f43565b600060405180830381600087803b1580156122e257600080fd5b505af11580156122f6573d6000803e3d6000fd5b505050505b60208601516001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2141561239e5761233686608001518760400151613b39565b61235373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee613a8f565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906123985760405162461bcd60e51b8152600401610fce9190614f98565b50612404565b6123b086608001518760400151613b39565b6123bd8760200151613a8f565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906124025760405162461bcd60e51b8152600401610fce9190614f98565b505b509092509050915091565b600061241a83613b61565b156124f357826001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561245857600080fd5b505afa15801561246c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612490919061464c565b6001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b1580156124ca57600080fd5b505af11580156124de573d6000803e3d6000fd5b50505050506124ec82613c3e565b9050612508565b6125056125008484613c60565b613c3e565b90505b61258e8383856001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561254657600080fd5b505afa15801561255a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257e919061464c565b6001600160a01b03169190611ad3565b604051633b4da69f60e01b81526001600160a01b03841690633b4da69f906125bc9030908690600401614ed0565b600060405180830381600087803b1580156125d657600080fd5b505af11580156125ea573d6000803e3d6000fd5b5050604051632c2cb9fd60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250637608870391506001600160a01b03881690632c2cb9fd90612636908990600401614f43565b60206040518083038186803b15801561264e57600080fd5b505afa158015612662573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268691906148d8565b604051632726b07360e01b81526001600160a01b03891690632726b073906126b2908a90600401614f43565b60206040518083038186803b1580156126ca57600080fd5b505afa1580156126de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612702919061464c565b30308660006040518763ffffffff1660e01b815260040161272896959493929190614f63565b600060405180830381600087803b15801561274257600080fd5b505af1158015612756573d6000803e3d6000fd5b505050505050505050565b6000808390506000856001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b1580156127a257600080fd5b505afa1580156127b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127da91906148d8565b905060128111156127fd5760405162461bcd60e51b8152600401610fce90614fab565b806012146128115780601203600a0a850291505b876001600160a01b03166345e6bdcd8861282a85613c3e565b60000360006040518463ffffffff1660e01b815260040161284d9392919061516b565b600060405180830381600087803b15801561286757600080fd5b505af115801561287b573d6000803e3d6000fd5b50506040516313771f0760e31b81526001600160a01b038b169250639bb8f83891506128af908a9030908790600401615128565b600060405180830381600087803b1580156128c957600080fd5b505af11580156128dd573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038916925063ef693bed915061290f9030908990600401614ed0565b600060405180830381600087803b15801561292957600080fd5b505af115801561293d573d6000803e3d6000fd5b5050505061294a86613b61565b80156129535750835b15612a2757856001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561299157600080fd5b505afa1580156129a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c9919061464c565b6001600160a01b0316632e1a7d4d866040518263ffffffff1660e01b81526004016129f49190614f43565b600060405180830381600087803b158015612a0e57600080fd5b505af1158015612a22573d6000803e3d6000fd5b505050505b50929695505050505050565b604051632726b07360e01b81526000906001600160a01b03871690632726b07390612a62908890600401614f43565b60206040518083038186803b158015612a7a57600080fd5b505afa158015612a8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ab2919061464c565b90506000612ad67335d1b3f3d7966a1dfe207aa4514c12a259a0492b838488613ce2565b905080841115612b7957736b175474e89094c44da98b954eedeac495271d0f63a9059cbb84612b058785611930565b6040518363ffffffff1660e01b8152600401612b22929190614ed0565b602060405180830381600087803b158015612b3c57600080fd5b505af1158015612b50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b749190614873565b508093505b604051636eb1769f60e11b8152736b175474e89094c44da98b954eedeac495271d0f9063dd62ed3e90612bc6903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614d73565b60206040518083038186803b158015612bde57600080fd5b505afa158015612bf2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c1691906148d8565b612cbd5760405163095ea7b360e01b8152736b175474e89094c44da98b954eedeac495271d0f9063095ea7b390612c6990739759a6ac90977b93b58547b4a71c78317f391a289060001990600401614ed0565b602060405180830381600087803b158015612c8357600080fd5b505af1158015612c97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cbb9190614873565b505b604051633b4da69f60e01b8152739759a6ac90977b93b58547b4a71c78317f391a2890633b4da69f90612cf69085908890600401614ed0565b600060405180830381600087803b158015612d1057600080fd5b505af1158015612d24573d6000803e3d6000fd5b50505050866001600160a01b03166345e6bdcd876000612d597335d1b3f3d7966a1dfe207aa4514c12a259a0492b878b613ebd565b6040518463ffffffff1660e01b8152600401612d779392919061516b565b600060405180830381600087803b158015612d9157600080fd5b505af1158015612da5573d6000803e3d6000fd5b5050505050505050505050565b6060612e07826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661407b9092919063ffffffff16565b8051909150156118fc5780806020019051810190612e259190614873565b6118fc5760405162461bcd60e51b8152600401610fce90615042565b6000612e508260a00151610d85565b90506000612e62828460000151610789565b8351604051632c2cb9fd60e01b81529192506000916001600160a01b03851691632c2cb9fd91612e959190600401614f43565b60206040518083038186803b158015612ead57600080fd5b505afa158015612ec1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ee591906148d8565b90506000612efd8486600001518488608001516113bb565b90506000612f178587600001518860800151856001612761565b9050612f27866040015182611ac3565b60408801526001600160a01b03841660c0880152612f43611f42565b612f4f57610190612f53565b61014d5b60a08801526000612f63886120c8565b915050612f788161128d896020015184611fd1565b9050612f8b868860000151868489612a33565b612fb28688600001518960800151612fab8b604001518c60600151611ac3565b6000612761565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338a60000151898d6040015187604051602001612ff79493929190615147565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161302493929190614e33565b600060405180830381600087803b15801561303e57600080fd5b505af1158015611ab5573d6000803e3d6000fd5b60006130618260a00151610d85565b90506000613073828460000151610789565b8351604051632c2cb9fd60e01b81529192506000916130fd9185916001600160a01b03831690632c2cb9fd906130ad908490600401614f43565b60206040518083038186803b1580156130c557600080fd5b505afa1580156130d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b891906148d8565b8451604051632c2cb9fd60e01b815291925060009161318d9186916001600160a01b03831690632c2cb9fd90613137908490600401614f43565b60206040518083038186803b15801561314f57600080fd5b505afa158015613163573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061318791906148d8565b85611b12565b90506131bb6131a0828760400151611ac3565b61128d87602001516131b6858a60400151611ac3565b611fd1565b60408701526001600160a01b03831660c08701526131d7611f42565b6131e3576101906131e7565b61014d5b60a087015260006131f7876120c8565b91505061320e85876000015188608001518461240f565b8551604051632c2cb9fd60e01b81526132a99187916001600160a01b03831690632c2cb9fd90613242908490600401614f43565b60206040518083038186803b15801561325a57600080fd5b505afa15801561326e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061329291906148d8565b6132a48a604001518b60600151611ac3565b611b12565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338960000151888c60400151876040516020016132ee9493929190615147565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612d7793929190614d8d565b600061333284676765c793fa10079d601b1b611901565b821015610eee576133688361335b61335587676765c793fa10079d601b1b611901565b85611930565b8161336257fe5b04613c3e565b905061337f84676765c793fa10079d601b1b611901565b6133898285611901565b106133945780610a53565b6001019392505050565b600061087f82676765c793fa10079d601b1b611901565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146133e1578161087f565b5073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2919050565b6000811580159061348f5750604051632cdc77ab60e21b8152731b14e8d511c9a4395425314f849bd737baf8208f9063b371deac9061343f908790600401614d5f565b60206040518083038186803b15801561345757600080fd5b505afa15801561346b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348f9190614873565b1561351e57604051636eeb543160e01b8152731b14e8d511c9a4395425314f849bd737baf8208f90636eeb5431906134cb908790600401614d5f565b60206040518083038186803b1580156134e357600080fd5b505afa1580156134f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061351b91906148d8565b91505b8161352b57506000610a53565b81858161353457fe5b049050600a85048111156135485750600a84045b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561359757600080fd5b505afa1580156135ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135cf919061464c565b90506001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415613632576040516001600160a01b0382169083156108fc029084906000818181858888f1935050505015801561362c573d6000803e3d6000fd5b50613646565b6136466001600160a01b03851682846118a6565b50949350505050565b610120820151602001516040516302f5cc7960e11b81526000918291734ba1f38427b33b8ab7bb0490200dae1f1c36823f916305eb98f2916136949190600401614d5f565b60206040518083038186803b1580156136ac57600080fd5b505afa1580156136c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136e49190614873565b6136f357506000905080613846565b6101208401515160405163e0aa279760e01b81527325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa2797916137309190600401614d5f565b60206040518083038186803b15801561374857600080fd5b505afa15801561375c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137809190614873565b61378f57506000905080613846565b61012084015151604085015185516137b2926001600160a01b03909116916118a6565b610120840151805160809091015160405163097396a160e31b81526001600160a01b0390921691634b9cb50891906137f090889088906004016150fc565b60408051808303818588803b15801561380857600080fd5b505af115801561381c573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190613841919061488f565b915091505b9250929050565b60e082015160405163e0aa279760e01b81526000917325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa27979161388a91600401614d5f565b60206040518083038186803b1580156138a257600080fd5b505afa1580156138b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138da9190614873565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b815250906139205760405162461bcd60e51b8152600401610fce9190614f98565b5060e083015160408401518451613942926001600160a01b03909116916118a6565b600082600181111561395057fe5b14156139f6578260e001516001600160a01b0316635b6f36fc8460000151856020015186604001518761010001516040518563ffffffff1660e01b815260040161399d9493929190614ee9565b602060405180830381600087803b1580156139b757600080fd5b505af11580156139cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139ef91906148d8565b905061087f565b8260e001516001600160a01b0316633924db668460000151856020015186606001518761010001516040518563ffffffff1660e01b8152600401613a3d9493929190614ee9565b602060405180830381600087803b158015613a5757600080fd5b505af1158015613a6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eee91906148d8565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415613abd5750476106cf565b6040516370a0823160e01b81526001600160a01b038316906370a0823190613ae9903090600401614d5f565b60206040518083038186803b158015613b0157600080fd5b505afa158015613b15573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087f91906148d8565b6000670de0b6b3a7640000611897613b518585611901565b6002670de0b6b3a7640000611891565b6000739759a6ac90977b93b58547b4a71c78317f391a286001600160a01b0383161415613b90575060006106cf565b816001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015613bc957600080fd5b505afa158015613bdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c01919061464c565b6001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03161415613c36575060016106cf565b506000919050565b8060008112156106cf5760405162461bcd60e51b8152600401610fce906150c3565b6000610eee82846001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b158015613c9f57600080fd5b505afa158015613cb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cd791906148d8565b601203600a0a611901565b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b8152600401613d119190614f43565b60a06040518083038186803b158015613d2957600080fd5b505afa158015613d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d619190614bc7565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b8152600401613d97929190614f4c565b604080518083038186803b158015613dae57600080fd5b505afa158015613dc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613de69190614ba4565b9150506000876001600160a01b0316636c25b346886040518263ffffffff1660e01b8152600401613e179190614d5f565b60206040518083038186803b158015613e2f57600080fd5b505afa158015613e43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e6791906148d8565b90506000613e78610eda8486611901565b9050676765c793fa10079d601b1b8104945080613ea086676765c793fa10079d601b1b611901565b10613eab5784613eb0565b846001015b9998505050505050505050565b600080846001600160a01b0316636c25b346856040518263ffffffff1660e01b8152600401613eec9190614d5f565b60206040518083038186803b158015613f0457600080fd5b505afa158015613f18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f3c91906148d8565b90506000856001600160a01b031663d9638d36856040518263ffffffff1660e01b8152600401613f6c9190614f43565b60a06040518083038186803b158015613f8457600080fd5b505afa158015613f98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fbc9190614bc7565b5050509150506000866001600160a01b0316632424be5c86886040518363ffffffff1660e01b8152600401613ff2929190614f4c565b604080518083038186803b15801561400957600080fd5b505afa15801561401d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140419190614ba4565b91505061405082848161336257fe5b93508084111561406b5761406381613c3e565b600003614070565b836000035b979650505050505050565b6060610a538484600085606061409085614149565b6140ac5760405162461bcd60e51b8152600401610fce9061500b565b60006060866001600160a01b031685876040516140c99190614d43565b60006040518083038185875af1925050503d8060008114614106576040519150601f19603f3d011682016040523d82523d6000602084013e61410b565b606091505b5091509150811561411f579150610a539050565b80511561412f5780518082602001fd5b8360405162461bcd60e51b8152600401610fce9190614f98565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610a53575050151592915050565b60405180610140016040528060006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016141f9614242565b905290565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b03168152602001600060018111156141f957fe5b6040518060c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001606081525090565b803561087f81615223565b805161087f81615223565b600082601f8301126142b9578081fd5b81356142cc6142c7826151b5565b61518f565b8181529150602080830190848101818402860182018710156142ed57600080fd5b60005b8481101561431557813561430381615223565b845292820192908201906001016142f0565b505050505092915050565b600082601f830112614330578081fd5b813561433e6142c7826151b5565b81815291506020808301908481018184028601820187101561435f57600080fd5b60005b8481101561431557813584529282019290820190600101614362565b600082601f83011261438e578081fd5b813561439c6142c7826151d4565b91508082528360208285010111156143b357600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126143dc578081fd5b81516143ea6142c7826151d4565b915080825283602082850101111561440157600080fd5b6144128160208401602086016151f7565b5092915050565b80356002811061087f57600080fd5b600061014080838503121561443b578182fd5b6144448161518f565b9150506144518383614293565b81526144608360208401614293565b602082015260408201356040820152606082013560608201526080820135608082015260a082013560a082015261449a8360c08401614293565b60c08201526144ac8360e08401614293565b60e0820152610100808301356001600160401b03808211156144cd57600080fd5b6144d98683870161437e565b838501526101209250828501359150808211156144f557600080fd5b506145028582860161450e565b82840152505092915050565b600060c0828403121561451f578081fd5b61452960c061518f565b9050813561453681615223565b8152602082013561454681615223565b6020820152604082013561455981615223565b80604083015250606082013560608201526080820135608082015260a08201356001600160401b0381111561458d57600080fd5b6145998482850161437e565b60a08301525092915050565b600060c082840312156145b6578081fd5b6145c060c061518f565b905081516145cd81615223565b815260208201516145dd81615223565b602082015260408201516145f081615223565b80604083015250606082015160608201526080820151608082015260a08201516001600160401b0381111561462457600080fd5b614599848285016143cc565b600060208284031215614641578081fd5b8135610eee81615223565b60006020828403121561465d578081fd5b8151610eee81615223565b6000806040838503121561467a578081fd5b823561468581615223565b946020939093013593505050565b6000806000606084860312156146a7578081fd5b83356146b281615223565b95602085013595506040909401359392505050565b600080600080608085870312156146dc578182fd5b84356146e781615223565b93506020850135925060408501359150606085013561470581615223565b939692955090935050565b600080600080600060a08688031215614727578283fd5b85356001600160401b038082111561473d578485fd5b61474989838a016142a9565b9650602088013591508082111561475e578485fd5b61476a89838a01614320565b9550604088013591508082111561477f578485fd5b61478b89838a01614320565b94506060880135915061479d82615223565b909250608087013590808211156147b2578283fd5b506147bf8882890161437e565b9150509295509295909350565b600080600080608085870312156147e1578182fd5b84356001600160401b03808211156147f7578384fd5b614803888389016142a9565b95506020870135915080821115614818578384fd5b61482488838901614320565b94506040870135915080821115614839578384fd5b61484588838901614320565b9350606087013591508082111561485a578283fd5b506148678782880161437e565b91505092959194509250565b600060208284031215614884578081fd5b8151610eee8161523b565b600080604083850312156148a1578182fd5b825180151581146148b0578283fd5b6020939093015192949293505050565b6000602082840312156148d1578081fd5b5035919050565b6000602082840312156148e9578081fd5b5051919050565b600060208284031215614901578081fd5b81356001600160401b03811115614916578182fd5b61087b8482850161437e565b60008060008060008060c0878903121561493a578384fd5b86516001600160401b0381111561494f578485fd5b61495b89828a016143cc565b9650506020870151945060408701519350606087015161497a81615223565b608088015190935061498b8161523b565b60a088015190925060ff811681146149a1578182fd5b809150509295509295509295565b6000806040838503121561467a578182fd5b600080604083850312156149d3578182fd5b82516148b081615223565b6000602082840312156149ef578081fd5b610eee8383614419565b600060208284031215614a0a578081fd5b81356001600160401b03811115614a1f578182fd5b61087b84828501614428565b600060208284031215614a3c578081fd5b81516001600160401b0380821115614a52578283fd5b8184019150610140808387031215614a68578384fd5b614a718161518f565b9050614a7d868461429e565b8152614a8c866020850161429e565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a0820152614ac68660c0850161429e565b60c0820152614ad88660e0850161429e565b60e08201526101008084015183811115614af0578586fd5b614afc888287016143cc565b8284015250506101208084015183811115614b15578586fd5b614b21888287016145a5565b918301919091525095945050505050565b600080600080600060a08688031215614b49578283fd5b85356001600160401b03811115614b5e578384fd5b614b6a88828901614428565b95505060208601359350604086013592506060860135614b8981615223565b9150614b988760808801614419565b90509295509295909350565b60008060408385031215614bb6578182fd5b505080516020909101519092909150565b600080600080600060a08688031215614bde578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b6001600160a01b03169052565b60008151808452614c2b8160208601602086016151f7565b601f01601f19169290920160200192915050565b6000610140614c4f848451614c06565b6020830151614c616020860182614c06565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c0830151614c9c60c0860182614c06565b5060e0830151614caf60e0860182614c06565b50610100808401518282870152614cc883870182614c13565b925050506101208084015185830382870152614ce48382614cee565b9695505050505050565b600060018060a01b0380835116845280602084015116602085015280604084015116604085015250606082015160608401526080820151608084015260a082015160c060a085015261087b60c0850182614c13565b60008251614d558184602087016151f7565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c1350d1119b185cda109bdbdcdd609a1b60a082015260c060608201819052600090614dde90830184614c13565b95945050505050565b6001600160a01b03848116825283166020820152608060408201819052600890820152671350d1109bdbdcdd60c21b60a082015260c060608201819052600090614dde90830184614c13565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c4d4344466c617368526570617960981b60a082015260c060608201819052600090614dde90830184614c13565b6001600160a01b03848116825283166020820152608060408201819052600890820152674d4344526570617960c01b60a082015260c060608201819052600090614dde90830184614c13565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614ce490830184614c13565b6001600160a01b0392909216825260ff16602082015260400190565b901515815260200190565b90815260200190565b9182526001600160a01b0316602082015260400190565b9586526001600160a01b039485166020870152928416604086015292166060840152608083019190915260a082015260c00190565b600060208252610eee6020830184614c13565b602080825260169082015275546f6b656e20646563696d616c7320746f6f2062696760501b604082015260600190565b60208082526016908201527513db9b1e4818985b185b98d95c8818d85b8818d85b1b60521b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526017908201527f4f6e6c79206161766520706f6f6c2063616e2063616c6c000000000000000000604082015260600190565b6020808252600c908201526b696e742d6f766572666c6f7760a01b604082015260600190565b600060208252610eee6020830184614c3f565b60006040825261510f6040830185614c3f565b90506002831061511b57fe5b8260208301529392505050565b9283526001600160a01b03919091166020830152604082015260600190565b9384526001600160a01b039290921660208401526040830152606082015260800190565b9283526020830191909152604082015260600190565b918252602082015260400190565b6040518181016001600160401b03811182821017156151ad57600080fd5b604052919050565b60006001600160401b038211156151ca578081fd5b5060209081020190565b60006001600160401b038211156151e9578081fd5b50601f01601f191660200190565b60005b838110156152125781810151838201526020016151fa565b8381111561183a5750506000910152565b6001600160a01b038116811461523857600080fd5b50565b801515811461523857600080fdfea2646970667358221220dec659417d70d3ec958a4b9da14fc85d0a3f1da92a0b507ae95761b6ef65093964736f6c634300060c0033
Deployed Bytecode Sourcemap
53307:6186:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40196:51;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28638:134;;;;;;;;;;-1:-1:-1;28638:134:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;40268:109::-;;;;;;;;;;;;;:::i;24344:122::-;;;;;;;;;;-1:-1:-1;24344:122:0;;;;;:::i;:::-;;:::i;:::-;;33940:56;;;;;;;;;;;;;:::i;29273:86::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;40743:80::-;;;;;;;;;;;;;:::i;41045:58::-;;;;;;;;;;;;;:::i;15085:186::-;;;;;;;;;;-1:-1:-1;15085:186:0;;;;;:::i;:::-;;:::i;29669:92::-;;;;;;;;;;;;;:::i;50539:223::-;;;;;;;;;;-1:-1:-1;50539:223:0;;;;;:::i;:::-;;:::i;40930:42::-;;;;;;;;;;;;;:::i;24639:285::-;;;;;;;;;;-1:-1:-1;24639:285:0;;;;;:::i;:::-;;:::i;14576:357::-;;;;;;;;;;-1:-1:-1;14576:357:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;24512:80::-;;;;;;;;;;;;;:::i;34149:72::-;;;;;;;;;;;;;:::i;40128:48::-;;;;;;;;;;;;;:::i;15400:336::-;;;;;;;;;;-1:-1:-1;15400:336:0;;;;;:::i;:::-;;:::i;40832:89::-;;;;;;;;;;;;;:::i;29366:90::-;;;;;;;;;;;;;:::i;50043:409::-;;;;;;;;;;-1:-1:-1;50043:409:0;;;;;:::i;:::-;;:::i;29770:87::-;;;;;;;;;;;;;:::i;23270:20::-;;;;;;;;;;;;;:::i;54258:561::-;;;;;;;;;;-1:-1:-1;54258:561:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;29465:103::-;;;;;;;;;;;;;:::i;28780:159::-;;;;;;;;;;-1:-1:-1;28780:159:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;29577:85::-;;;;;;;;;;;;;:::i;24123:122::-;;;;;;;;;;-1:-1:-1;24123:122:0;;;;;:::i;:::-;;:::i;40656:80::-;;;;;;;;;;;;;:::i;29156:74::-;;;;;;;;;;;;;:::i;40979:59::-;;;;;;;;;;;;;:::i;34003:70::-;;;;;;;;;;;;;:::i;42706:1193::-;;;;;;:::i;:::-;;:::i;34080:62::-;;;;;;;;;;;;;:::i;48988:782::-;;;;;;;;;;-1:-1:-1;48988:782:0;;;;;:::i;:::-;;:::i;23840:161::-;;;;;;;;;;-1:-1:-1;23840:161:0;;;;;:::i;:::-;;:::i;41380:1172::-;;;;;;:::i;:::-;;:::i;53789:433::-;;;;;;;;;;-1:-1:-1;53789:433:0;;;;;:::i;:::-;;:::i;41112:109::-;;;;;;;;;;;;;:::i;23297:20::-;;;;;;;;;;;;;:::i;40196:51::-;40244:3;40196:51;:::o;28638:134::-;28713:12;28756:7;28745:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;28738:26;;28638:134;;;;:::o;40268:109::-;-1:-1:-1;;;40268:109:0;:::o;24344:122::-;24425:5;;-1:-1:-1;;;;;24425:5:0;24411:10;:19;24403:28;;;;;;24444:5;:14;;-1:-1:-1;;;;;;24444:14:0;-1:-1:-1;;;;;24444:14:0;;;;;;;;;;24344:122::o;33940:56::-;;;;;;;;;;;;;;-1:-1:-1;;;33940:56:0;;;;:::o;29273:86::-;29317:42;29273:86;:::o;40743:80::-;40781:42;40743:80;:::o;41045:58::-;40515:42;41045:58;:::o;15085:186::-;15155:7;15175:13;15207:8;-1:-1:-1;;;;;15207:13:0;;15221:6;15207:21;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15175:55;;15250:5;-1:-1:-1;;;;;15250:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15243:20;;;15085:186;;;;;:::o;29669:92::-;29719:42;29669:92;:::o;50539:223::-;50630:18;;-1:-1:-1;;;50630:18:0;;50592:7;;;;40515:42;;50630:12;;:18;;50643:4;;50630:18;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50684:14;;-1:-1:-1;;;50684:14:0;;50612:36;;-1:-1:-1;50664:12:0;;-1:-1:-1;40424:42:0;;50684:8;;:14;;50693:4;;50684:14;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50659:39;;;;;;50718:36;50723:25;50728:4;40515:42;-1:-1:-1;;;;;50734:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50723:4;:25::i;:::-;50750:3;50718:4;:36::i;:::-;50711:43;50539:223;-1:-1:-1;;;;50539:223:0:o;40930:42::-;40424;40930;:::o;24639:285::-;23366:5;;-1:-1:-1;;;;;23366:5:0;23375:10;23366:19;23358:28;;;;;;24739:42:::1;-1:-1:-1::0;;;;;24729:52:0;::::1;;24725:192;;;24806:5;::::0;;24798:32:::1;::::0;-1:-1:-1;;;;;24806:5:0;;::::1;::::0;24798:32;::::1;;;::::0;24822:7;;24798:32;24806:5;24798:32;24822:7;24806:5;24798:32;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;24725:192;;;24890:5;::::0;24863:42:::1;::::0;-1:-1:-1;;;;;24863:26:0;;::::1;::::0;24890:5:::1;24897:7:::0;24863:26:::1;:42::i;:::-;24639:285:::0;;:::o;14576:357::-;14662:4;14668;14685:11;14699:8;-1:-1:-1;;;;;14699:12:0;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14685:28;;14724:11;14738:8;-1:-1:-1;;;;;14738:13:0;;14752:6;14738:21;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14724:35;;14773:15;14790:9;14807:3;-1:-1:-1;;;;;14803:13:0;;14817:4;14823:3;14803:24;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14772:55;;;;14840:9;14860:3;-1:-1:-1;;;;;14856:13:0;;14870:4;14856:19;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14838:37;;;;;;14896:10;14908:16;14913:4;14919;14908;:16::i;:::-;14888:37;;;;;;;;;14576:357;;;;;;:::o;24512:80::-;23366:5;;-1:-1:-1;;;;;23366:5:0;23375:10;23366:19;23358:28;;;;;;24577:5:::1;::::0;-1:-1:-1;;;;;24577:5:0::1;24556:28;34149:72:::0;;;;;;;;;;;;;;-1:-1:-1;;;34149:72:0;;;;:::o;40128:48::-;40173:3;40128:48;:::o;15400:336::-;15471:7;;15495:12;:31;;;;;;;;;15491:238;;;-1:-1:-1;15550:42:0;15543:49;;15491:238;15630:21;15614:12;:37;;;;;;;;;15610:119;;;-1:-1:-1;15675:42:0;15668:49;;40832:89;40879:42;40832:89;:::o;29366:90::-;29414:42;29366:90;:::o;50043:409::-;50178:7;50198:13;50214:14;50223:4;50214:8;:14::i;:::-;50259:18;;-1:-1:-1;;;50259:18:0;;50198:30;;-1:-1:-1;50244:11:0;;40515:42;;50259:12;;:18;;50272:4;;50259:18;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50241:36;;;50289:18;50309:12;50325:47;50344:12;50359:6;50367:4;50325:10;:47::i;:::-;50288:84;;;;50392:52;50396:43;50400:32;50404:22;50408:10;50420:5;50404:3;:22::i;:::-;50428:3;50400;:32::i;:::-;50434:4;50396:3;:43::i;:::-;50441:2;50392:3;:52::i;:::-;50385:59;;;;;;50043:409;;;;;;:::o;29770:87::-;29815:42;29770:87;:::o;23270:20::-;;;-1:-1:-1;;;;;23270:20:0;;:::o;54258:561::-;54460:4;54477:19;53416:42;-1:-1:-1;;;;;54499:64:0;;:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54477:88;-1:-1:-1;54584:10:0;-1:-1:-1;;;;;54584:25:0;;;54576:61;;;;-1:-1:-1;;;54576:61:0;;;;;;;:::i;:::-;;;;;;;;;54650:54;54661:7;54669:1;54661:10;;;;;;;;;;;;;;54673:8;54682:1;54673:11;;;;;;;;;;;;;;54686:5;54692:1;54686:8;;;;;;;;;;;;;;54696:7;54650:10;:54::i;:::-;54717:70;54747:11;54760:26;54764:8;54773:1;54764:11;;;;;;;;;;;;;;54777:5;54783:1;54777:8;;;;;;;;;;;;;;54760:3;:26::i;:::-;54723:7;54731:1;54723:10;;;;;;;;;;;;;;-1:-1:-1;;;;;54717:29:0;;;:70;;;;;:::i;:::-;-1:-1:-1;54807:4:0;;54258:561;-1:-1:-1;;;;;;54258:561:0:o;29465:103::-;29525:42;29465:103;:::o;28780:159::-;28848:27;;:::i;:::-;28909:5;28898:33;;;;;;;;;;;;:::i;29577:85::-;29620:42;29577:85;:::o;24123:122::-;24204:5;;-1:-1:-1;;;;;24204:5:0;24190:10;:19;24182:28;;;;;;24223:5;:14;;-1:-1:-1;;;;;;24223:14:0;-1:-1:-1;;;;;24223:14:0;;;;;;;;;;24123:122::o;40656:80::-;40694:42;40656:80;:::o;29156:74::-;;;;;;;;;;;;;;-1:-1:-1;;;29156:74:0;;;;:::o;40979:59::-;40607:42;40979:59;:::o;34003:70::-;;;;;;;;;;;;;;-1:-1:-1;;;34003:70:0;;;;:::o;42706:1193::-;42913:19;42935:28;42950:12;42935:14;:28::i;:::-;42913:50;;42976:12;42991:38;43008:11;43022:6;42991:8;:38::i;:::-;42976:53;;43040:11;43062;-1:-1:-1;;;;;43054:25:0;;43080:6;43054:33;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43040:47;;43100:16;43119:58;43127:11;43140:6;43148:3;43153:13;:23;;;43119:7;:58::i;:::-;-1:-1:-1;;;;;43190:25:0;;:18;;;:25;43100:77;-1:-1:-1;43256:14:0;:12;:14::i;:::-;:59;;40173:3;43256:59;;;40244:3;43256:59;43226:27;;;:89;43352:42;43356:8;43366:27;43374:8;43356;43366:7;:27::i;:::-;43352:3;:42::i;:::-;43326:23;;;:68;43408:18;43430:20;43326:13;43430:5;:20::i;:::-;43405:45;;;43463:57;43477:11;43490:6;43498:9;43509:10;43463:13;:57::i;:::-;43609:21;:25;43605:99;;43651:41;;:9;;43670:21;43651:41;;;;;;;;;43670:21;43651:9;:41;;;;;;;;;;;;;;;;;;;;;43605:99;41178:42;-1:-1:-1;;;;;43716:10:0;;43749:4;43769:10;43830:6;43838:4;43844:13;:23;;;43869:10;43819:61;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;43716:175;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42706:1193;;;;;;;;;;:::o;34080:62::-;;;;;;;;;;;;;;-1:-1:-1;;;34080:62:0;;;;:::o;48988:782::-;49149:7;49169:13;49185:14;49194:4;49185:8;:14::i;:::-;49169:30;;49213:18;49233:12;49249:47;49268:12;49283:6;49291:4;49249:10;:47::i;:::-;49327:35;;-1:-1:-1;;;49327:35:0;;49212:84;;-1:-1:-1;49212:84:0;-1:-1:-1;49312:11:0;;40515:42;;49327:29;;:35;;49357:4;;49327:35;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49309:53;;;49375:21;49399:45;49403:10;49416:26;49420:14;49424:3;49429:4;49420:3;:14::i;:::-;49436:5;49416:3;:26::i;49399:45::-;49375:69;;49457:20;49485:9;-1:-1:-1;;;;;49480:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49457:44;;49538:2;49522:12;:18;;49514:53;;;;-1:-1:-1;;;49514:53:0;;;;;;;:::i;:::-;49580:30;49640:12;49635:2;:17;49630:2;:23;49613:13;:41;;;;;;;-1:-1:-1;49759:3:0;49753:2;49728:27;;49727:35;49720:42;;;;;;;;;48988:782;;;;;;:::o;23840:161::-;23921:5;;-1:-1:-1;;;;;23921:5:0;23907:10;:19;23899:28;;;;;;23946:5;;-1:-1:-1;;;;;23946:5:0;:19;23938:28;;;;;41380:1172;41587:19;41609:28;41624:12;41609:14;:28::i;:::-;41587:50;;41650:12;41665:38;41682:11;41696:6;41665:8;:38::i;:::-;41650:53;;41714:11;41736;-1:-1:-1;;;;;41728:25:0;;41754:6;41728:33;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41714:47;;41774:77;41789:11;41802:6;41810:9;41821:13;:23;;;41846:4;41774:14;:77::i;:::-;-1:-1:-1;;;;;;41864:25:0;;:18;;;:25;41930:14;:12;:14::i;:::-;:59;;40173:3;41930:59;;;40244:3;41930:59;41900:27;;;:89;42003:17;42024:20;41900:13;42024:5;:20::i;:::-;42000:44;;;42069;42073:9;42084:28;42092:8;42102:9;42084:7;:28::i;42069:44::-;42057:56;;42126:54;42138:11;42151:6;42159:3;42164:9;42175:4;42126:11;:54::i;:::-;42263:21;:25;42259:99;;42305:41;;:9;;42324:21;42305:41;;;;;;;;;42324:21;42305:9;:41;;;;;;;;;;;;;;;;;;;;;42259:99;41178:42;-1:-1:-1;;;;;42370:10:0;;42403:4;42423:10;42484:6;42492:4;42498:13;:23;;;42523:9;42473:60;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;42370:174;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41380:1172;;;;;;;;;:::o;53789:433::-;53986:10;53513:42;53986:33;53978:68;;;;-1:-1:-1;;;53978:68:0;;;;;;;:::i;:::-;54059:54;54070:7;54078:1;54070:10;;;;;;;;;;;;;;54082:8;54091:1;54082:11;;;;;;;;;;;;;;54095:5;54101:1;54095:8;;;;;;;;;;;;;;54105:7;54059:10;:54::i;:::-;54126:88;53513:42;54187:26;54191:8;54200:1;54191:11;;;;;;;;;;;;;;54204:5;54210:1;54204:8;;;;;;;54187:26;54132:7;54140:1;54132:10;;;;;;;;;;;;;;-1:-1:-1;;;;;54126:30:0;;;:88;;;;;:::i;:::-;53789:433;;;;:::o;41112:109::-;41178:42;41112:109;:::o;23297:20::-;;;-1:-1:-1;;;;;23297:20:0;;:::o;5379:122::-;5438:9;-1:-1:-1;;;5464:23:0;5468:9;5472:1;5475;5468:3;:9::i;:::-;5485:1;-1:-1:-1;;;5479:7:0;;5464:3;:23::i;:::-;:29;;;;;;;5379:122;-1:-1:-1;;;5379:122:0:o;21316:176::-;21398:86;21418:5;21448:23;;;21473:2;21477:5;21425:58;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;21425:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;21425:58:0;-1:-1:-1;;;;;;21425:58:0;;;;;;;;;;21398:19;:86::i;:::-;21316:176;;;:::o;4468:127::-;4526:9;4556:6;;;:30;;-1:-1:-1;;4571:5:0;;;4585:1;4580;4571:5;4580:1;4566:15;;;;;:20;4556:30;4548:39;;;;;4603:100;4661:9;4694:1;4690;:5;;;;4347:113;4440:5;;;4435:16;;;;4427:25;;;;;54884:1303;55055:24;55094:13;55122:15;55152:16;55183:12;55210:17;55252:7;55241:68;;;;;;;;;;;;:::i;:::-;55040:269;;;;;;;;;;;;55322:32;;:::i;:::-;55357:31;55376:11;55357:18;:31::i;:::-;55322:66;-1:-1:-1;;;;;;55458:35:0;;29414:42;55458:35;55454:123;;;55510:55;;-1:-1:-1;;;55510:55:0;;29414:42;;55510:46;;:55;;55557:7;;55510:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55454:123;55589:26;;:::i;:::-;55618:223;;;;;;;;55650:5;55618:223;;;;55679:7;55618:223;;;;55713:7;55618:223;;;;55740:4;55618:223;;;;55769:8;-1:-1:-1;;;;;55618:223:0;;;;;55817:11;55805:24;;;;;;;;;;55618:223;;;;;;;;;;55589:252;-1:-1:-1;55854:149:0;;;;55882:38;55896:12;55910:9;55882:13;:38::i;:::-;55854:149;;;55953:38;55967:12;55981:9;55953:13;:38::i;:::-;56085:21;:25;56081:99;;56127:41;;:9;;56146:21;56127:41;;;;;;;;;56146:21;56127:9;:41;;;;;;;;;;;;;;;;;;;56081:99;54884:1303;;;;;;;;;;;;:::o;4226:113::-;4319:5;;;4314:16;;;;4306:25;;;;;21865:281;21951:86;21971:5;22001:22;;;22025:7;22034:1;21978:58;;;;;;;;;:::i;21951:86::-;22048:90;22068:5;22098:22;;;22122:7;22131:5;22075:62;;;;;;;;;:::i;44197:933::-;44382:27;;-1:-1:-1;;;44382:27:0;;44347:7;;;;40694:42;;44382:21;;:27;;44404:4;;44382:27;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44367:42;;44420:21;40424:42;-1:-1:-1;;;;;44444:7:0;;44460:12;-1:-1:-1;;;;;44452:26:0;;44479:6;44452:34;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44444:43;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44420:67;;44500:17;44520:38;44531:12;44545:6;44553:4;44520:10;:38::i;:::-;44500:58;;44589:9;44575:10;:23;44571:86;;44628:17;44632:9;44643:1;44628:3;:17::i;:::-;44615:30;;44571:86;44677:12;-1:-1:-1;;;;;44669:26:0;;44710:6;44738:1;44755:52;44775:10;44787:4;44793:13;44755:19;:52::i;:::-;44669:149;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44837:12;-1:-1:-1;;;;;44829:26:0;;44856:6;44872:4;44879:17;44885:10;44879:5;:17::i;:::-;44829:68;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44914:49:0;;-1:-1:-1;;;44914:49:0;;40424:42;;-1:-1:-1;44914:7:0;;-1:-1:-1;44914:49:0;;44930:4;;40607:42;;44914:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44910:113;;44985:26;;-1:-1:-1;;;44985:26:0;;40424:42;;44985:8;;:26;;40607:42;;44985:26;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44910:113;45035:57;;-1:-1:-1;;;45035:57:0;;40607:42;;45035:30;;:57;;45074:4;;45081:10;;45035:57;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45112:10:0;;44197:933;-1:-1:-1;;;;;;;;;;44197:933:0:o;50770:131::-;50841:52;;-1:-1:-1;;;50841:52:0;;50817:4;;40879:42;;50841:41;;:52;;50883:9;;50841:52;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50834:59;;50770:131;:::o;50909:535::-;50979:7;51003:12;;50999:417;;51032:19;51054:17;-1:-1:-1;;;51054:8:0;:17::i;:::-;51032:39;;51086:17;51106:27;51111:8;51121:11;51106:4;:27::i;:::-;51086:47;-1:-1:-1;51176:1:0;51166:7;:11;51154:9;:23;51150:87;;;-1:-1:-1;51220:1:0;51210:11;;51150:87;51253:18;29525:42;-1:-1:-1;;;;;51274:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51253:47;-1:-1:-1;51317:54:0;40781:42;51253:47;51361:9;51317:31;:54::i;:::-;-1:-1:-1;51395:9:0;-1:-1:-1;51388:16:0;;-1:-1:-1;51388:16:0;50999:417;-1:-1:-1;51435:1:0;50909:535;;;;:::o;34492:1670::-;34553:7;34562:4;34581:15;34607:17;34635:12;29317:42;-1:-1:-1;;;;;34708:35:0;:6;:14;;;-1:-1:-1;;;;;34708:35:0;;34704:201;;;34791:14;;34777:29;;:13;:29::i;:::-;-1:-1:-1;;;;;34760:46:0;;;34874:16;;;;;34821:72;;-1:-1:-1;;;34821:72:0;;;;29414:42;;34821:45;;34874:16;34821:72;;;;;34760:14;;34821:72;;;;;;;34874:16;29414:42;34821:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34704:201;34937:75;34944:6;:16;;;34962:6;:11;;;34975:6;:14;;;34991:6;:20;;;34937:6;:75::i;:::-;34917:16;;;:95;;;;;;;;35092:19;;;;:25;;;:29;35088:228;;35164:34;35174:6;35182:15;35164:9;:34::i;:::-;35138:60;-1:-1:-1;35138:60:0;-1:-1:-1;35215:90:0;;;;35257:6;:19;;;:32;;;35247:42;;35215:90;35386:7;35381:129;;35425:34;35435:6;35443:15;35425:9;:34::i;:::-;35410:49;;35484:6;:14;;;35474:24;;35381:129;35626:1;35590:33;29414:42;35590:10;:33::i;:::-;:37;35586:212;;;35709:62;;-1:-1:-1;;;35709:62:0;;29414:42;;35644:46;;29414:42;;35709:47;;:62;;35765:4;;35709:62;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35644:142;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35586:212;35814:15;;;;-1:-1:-1;;;;;35814:40:0;29414:42;35814:40;35810:302;;;35912:39;35917:6;:15;;;35934:6;:16;;;35912:4;:39::i;:::-;35879:29;29317:42;35879:10;:29::i;:::-;:72;;35953:16;;;;;;;;;;;;;-1:-1:-1;;;35953:16:0;;;35871:99;;;;;-1:-1:-1;;;35871:99:0;;;;;;;;:::i;:::-;;35810:302;;;36042:39;36047:6;:15;;;36064:6;:16;;;36042:4;:39::i;:::-;36011:27;36022:6;:15;;;36011:10;:27::i;:::-;:70;;36083:16;;;;;;;;;;;;;-1:-1:-1;;;36083:16:0;;;36003:97;;;;;-1:-1:-1;;;36003:97:0;;;;;;;;:::i;:::-;;35810:302;-1:-1:-1;36132:7:0;;-1:-1:-1;36141:12:0;-1:-1:-1;34492:1670:0;;;:::o;45405:825::-;45565:20;45606:24;45620:9;45606:13;:24::i;:::-;45602:252;;;45652:9;-1:-1:-1;;;;;45647:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;45647:29:0;;45684:7;45647:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45725:22;45739:7;45725:13;:22::i;:::-;45709:38;;45602:252;;;45796:46;45810:31;45822:9;45833:7;45810:11;:31::i;:::-;45796:13;:46::i;:::-;45780:62;;45602:252;45866:69;45916:9;45927:7;45885:9;-1:-1:-1;;;;;45880:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;45866:49:0;;:69;:49;:69::i;:::-;45948:44;;-1:-1:-1;;;45948:44:0;;-1:-1:-1;;;;;45948:20:0;;;;;:44;;45977:4;;45984:7;;45948:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;46028:34:0;;-1:-1:-1;;;46028:34:0;;40424:42;;-1:-1:-1;46005:8:0;;-1:-1:-1;;;;;;46028:26:0;;;;;:34;;46055:6;;46028:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46077;;-1:-1:-1;;;46077:34:0;;-1:-1:-1;;;;;46077:26:0;;;;;:34;;46104:6;;46077:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46134:4;46162;46182:13;46210:1;46005:217;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45405:825;;;;;:::o;46661:838::-;46842:7;46862:18;46883:7;46862:28;;46903:20;46931:9;-1:-1:-1;;;;;46926:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46903:44;;46984:2;46968:12;:18;;46960:53;;;;-1:-1:-1;;;46960:53:0;;;;;;;:::i;:::-;47030:12;47046:2;47030:18;47026:99;;47099:12;47094:2;:17;47089:2;:23;47078:7;:35;47065:48;;47026:99;47145:12;-1:-1:-1;;;;;47137:26:0;;47164:6;47173:25;47187:10;47173:13;:25::i;:::-;47172:26;;47200:1;47137:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;47213:61:0;;-1:-1:-1;;;47213:61:0;;-1:-1:-1;;;;;47213:26:0;;;-1:-1:-1;47213:26:0;;-1:-1:-1;47213:61:0;;47240:6;;47256:4;;47263:10;;47213:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;47287:44:0;;-1:-1:-1;;;47287:44:0;;-1:-1:-1;;;;;47287:20:0;;;-1:-1:-1;47287:20:0;;-1:-1:-1;47287:44:0;;47316:4;;47323:7;;47287:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47348:24;47362:9;47348:13;:24::i;:::-;:34;;;;;47376:6;47348:34;47344:121;;;47404:9;-1:-1:-1;;;;;47399:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;47399:30:0;;47430:7;47399:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47344:121;-1:-1:-1;47484:7:0;;46661:838;-1:-1:-1;;;;;;46661:838:0:o;47875:784::-;48070:34;;-1:-1:-1;;;48070:34:0;;48056:11;;-1:-1:-1;;;;;48070:26:0;;;;;:34;;48097:6;;48070:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48056:48;;48117:17;48137:39;40424:42;48161:3;48166;48171:4;48137:10;:39::i;:::-;48117:59;;48206:9;48193:10;:22;48189:155;;;40781:42;48232:27;48260:6;48268:26;48272:10;48284:9;48268:3;:26::i;:::-;48232:63;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;48323:9;48310:22;;48189:155;48360:61;;-1:-1:-1;;;48360:61:0;;40781:42;;48360:28;;:61;;48397:4;;40607:42;;48360:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48356:156;;48443:57;;-1:-1:-1;;;48443:57:0;;40781:42;;48443:26;;:57;;40607:42;;-1:-1:-1;;48496:2:0;48443:57;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;48356:156;48524:29;;-1:-1:-1;;;48524:29:0;;40607:42;;48524:12;;:29;;48537:3;;48542:10;;48524:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48574:12;-1:-1:-1;;;;;48566:26:0;;48593:6;48601:1;48604:46;40424:42;48640:3;48645:4;48604:22;:46::i;:::-;48566:85;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47875:784;;;;;;;:::o;22785:419::-;22867:23;22893:69;22921:4;22893:69;;;;;;;;;;;;;;;;;22901:5;-1:-1:-1;;;;;22893:27:0;;;:69;;;;;:::i;:::-;22977:17;;22867:95;;-1:-1:-1;22977:21:0;22973:224;;23119:10;23108:30;;;;;;;;;;;;:::i;:::-;23100:85;;;;-1:-1:-1;;;23100:85:0;;;;;;;:::i;57819:1608::-;57940:19;57962:38;57977:10;:22;;;57962:14;:38::i;:::-;57940:60;;58013:12;58028:48;58045:11;58059:10;:16;;;58028:8;:48::i;:::-;58127:16;;58101:43;;-1:-1:-1;;;58101:43:0;;58013:63;;-1:-1:-1;58087:11:0;;-1:-1:-1;;;;;58101:25:0;;;;;:43;;58127:16;58101:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58087:57;;58185:15;58203:73;58220:11;58233:10;:16;;;58251:3;58256:10;:19;;;58203:16;:73::i;:::-;58185:91;;58287:17;58307:157;58336:11;58362:10;:16;;;58393:10;:19;;;58427:7;58449:4;58307:14;:157::i;:::-;58287:177;;58520:37;58524:10;:21;;;58547:9;58520:3;:37::i;:::-;58494:23;;;:63;-1:-1:-1;;;;;58568:25:0;;:18;;;:25;58634:14;:12;:14::i;:::-;:59;;40173:3;58634:59;;;40244:3;58634:59;58604:27;;;:89;58707:21;58732:20;58604:13;58732:5;:20::i;:::-;58704:48;;;58781:62;58785:13;58800:42;58808:10;:18;;;58828:13;58800:7;:42::i;58781:62::-;58765:78;;58885:68;58897:11;58910:10;:16;;;58928:3;58933:13;58948:4;58885:11;:68::i;:::-;59018:193;59047:11;59073:10;:16;;;59104:10;:19;;;59138:42;59142:10;:21;;;59165:10;:14;;;59138:3;:42::i;:::-;59195:5;59018:14;:193::i;:::-;;41178:42;-1:-1:-1;;;;;59226:10:0;;59259:4;59279:10;59345;:16;;;59363:4;59369:13;:23;;;59394:13;59334:74;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;59226:193;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56195:1616;56316:19;56338:38;56353:10;:22;;;56338:14;:38::i;:::-;56316:60;;56387:12;56402:48;56419:11;56433:10;:16;;;56402:8;:48::i;:::-;56559:16;;56590:43;;-1:-1:-1;;;56590:43:0;;56387:63;;-1:-1:-1;56490:15:0;;56508:136;;56533:11;;-1:-1:-1;;;;;56590:25:0;;;;;:43;;56559:16;;56590:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;56508:136::-;56722:16;;56753:43;;-1:-1:-1;;;56753:43:0;;56490:154;;-1:-1:-1;56655:16:0;;56674:155;;56696:11;;-1:-1:-1;;;;;56753:25:0;;;;;:43;;56722:16;;56753:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56811:7;56674;:155::i;:::-;56655:174;;56885:145;56903:36;56907:8;56917:10;:21;;;56903:3;:36::i;:::-;56954:65;56962:10;:18;;;56982:36;56986:8;56996:10;:21;;;56982:3;:36::i;:::-;56954:7;:65::i;56885:145::-;56859:23;;;:171;-1:-1:-1;;;;;57043:25:0;;:18;;;:25;57109:14;:12;:14::i;:::-;:59;;40173:3;57109:59;;;40244:3;57109:59;57079:27;;;:89;57182:20;57206;57079:13;57206:5;:20::i;:::-;57179:47;;;57269:79;57283:11;57296:10;:16;;;57314:10;:19;;;57335:12;57269:13;:79::i;:::-;57454:16;;57485:43;;-1:-1:-1;;;57485:43:0;;57406:190;;57428:11;;-1:-1:-1;;;;;57485:25:0;;;;;:43;;57454:16;;57485:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57543:42;57547:10;:21;;;57570:10;:14;;;57543:3;:42::i;:::-;57406:7;:190::i;:::-;;41178:42;-1:-1:-1;;;;;57611:10:0;;57644:4;57664:10;57730;:16;;;57748:4;57754:13;:23;;;57779:12;57719:73;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;57611:192;;;;;;;;;;;;;;;;;:::i;11218:344::-;11317:8;11359:17;11363:7;-1:-1:-1;;;11359:3:0;:17::i;:::-;11342:14;:34;11338:217;;;11400:61;11455:5;11414:38;11418:17;11422:7;-1:-1:-1;;;11418:3:0;:17::i;:::-;11437:14;11414:3;:38::i;:::-;:46;;;;;;11400:13;:61::i;:::-;11393:68;;11508:17;11512:7;-1:-1:-1;;;11508:3:0;:17::i;:::-;11483:22;11492:4;11499:5;11483:3;:22::i;:::-;:42;:60;;11539:4;11483:60;;;11535:1;11528:8;;11476:67;-1:-1:-1;;;11218:344:0:o;11677:100::-;11726:4;11750:19;11754:4;-1:-1:-1;;;11750:3:0;:19::i;32843:151::-;32903:7;-1:-1:-1;;;;;32930:25:0;;29317:42;32930:25;:56;;32982:4;32930:56;;;-1:-1:-1;29414:42:0;;32843:151;-1:-1:-1;32843:151:0:o;31157:905::-;31263:17;31297:19;;;;;:71;;-1:-1:-1;31320:48:0;;-1:-1:-1;;;31320:48:0;;29620:42;;31320:41;;:48;;31362:5;;31320:48;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31293:174;;;31402:53;;-1:-1:-1;;;31402:53:0;;29620:42;;31402:46;;:53;;31449:5;;31402:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31385:70;;31293:174;31483:19;31479:576;;-1:-1:-1;31531:1:0;31479:576;;;31587:14;31577:7;:24;;;;;;;-1:-1:-1;31703:2:0;31693:7;:12;31680:9;:26;31676:91;;;-1:-1:-1;31749:2:0;31739:12;;31676:91;31783:18;29525:42;-1:-1:-1;;;;;31804:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31783:47;-1:-1:-1;;;;;;31851:27:0;;29317:42;31851:27;31847:197;;;31899:39;;-1:-1:-1;;;;;31899:28:0;;;:39;;;;;31928:9;;31899:39;;;;31928:9;31899:28;:39;;;;;;;;;;;;;;;;;;;;;31847:197;;;31979:49;-1:-1:-1;;;;;31979:26:0;;32006:10;32018:9;31979:26;:49::i;:::-;31479:576;31157:905;;;;;;:::o;38205:692::-;38395:20;;;;:33;;;38352:77;;-1:-1:-1;;;38352:77:0;;38313:12;;;;29815:42;;38352;;:77;;38395:33;38352:77;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38347:128;;-1:-1:-1;38454:5:0;;-1:-1:-1;38454:5:0;38446:17;;38347:128;38549:20;;;;:28;38492:86;;-1:-1:-1;;;38492:86:0;;29719:42;;38492:56;;:86;;38549:28;38492:86;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38487:137;;-1:-1:-1;38603:5:0;;-1:-1:-1;38603:5:0;38595:17;;38487:137;38700:20;;;;:28;38730:17;;;;38670:15;;38664:84;;-1:-1:-1;;;;;38664:35:0;;;;;:84::i;:::-;38793:20;;;;:28;;38840:32;;;;;38768:121;;-1:-1:-1;;;38768:121:0;;-1:-1:-1;;;;;38768:64:0;;;;;;38840:32;38768:121;;38793:7;;38883:5;;38768:121;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38761:128;;;;38205:692;;;;;;:::o;39163:717::-;39342:15;;;;39285:73;;-1:-1:-1;;;39285:73:0;;39247:17;;29719:42;;39285:56;;:73;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39360:19;;;;;;;;;;;;;-1:-1:-1;;;39360:19:0;;;39277:103;;;;;-1:-1:-1;;;39277:103:0;;;;;;;;:::i;:::-;-1:-1:-1;39429:15:0;;;;39446:17;;;;39399:15;;39393:71;;-1:-1:-1;;;;;39393:35:0;;;;;:71::i;:::-;39490:15;39481:5;:24;;;;;;;;;39477:396;;;39557:7;:15;;;-1:-1:-1;;;;;39537:63:0;;39601:7;:15;;;39618:7;:16;;;39636:7;:17;;;39655:7;:19;;;39537:138;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39522:153;;39477:396;;;39743:7;:15;;;-1:-1:-1;;;;;39723:62:0;;39786:7;:15;;;39803:7;:16;;;39821:7;:18;;;39841:7;:19;;;39723:138;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;30050:275::-;30113:12;-1:-1:-1;;;;;30142:31:0;;29317:42;30142:31;30138:180;;;-1:-1:-1;30200:21:0;30138:180;;;30264:42;;-1:-1:-1;;;30264:42:0;;-1:-1:-1;;;;;30264:27:0;;;;;:42;;30300:4;;30264:42;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;5249:122::-;5308:9;5198:6;5334:23;5338:9;5342:1;5345;5338:3;:9::i;:::-;5355:1;5198:6;5349:7;;13967:436;14032:4;14131:42;-1:-1:-1;;;;;14118:55:0;;;14114:73;;;-1:-1:-1;14182:5:0;14175:12;;14114:73;14268:9;-1:-1:-1;;;;;14263:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;14255:76:0;14289:42;-1:-1:-1;;;;;14255:76:0;;14251:120;;;-1:-1:-1;14355:4:0;14348:11;;14251:120;-1:-1:-1;14390:5:0;13967:436;;;:::o;12224:134::-;12305:2;12279:5;12327:6;;;12319:31;;;;-1:-1:-1;;;12319:31:0;;;;;;;:::i;11948:163::-;12028:7;12055:48;12059:7;12085:9;-1:-1:-1;;;;;12080:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12075:2;:26;12068:2;:34;12055:3;:48::i;13151:424::-;13250:14;13280:9;13300:4;-1:-1:-1;;;;;13296:14:0;;13311:4;13296:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13277:39;;;;;;13330:8;13346:4;-1:-1:-1;;;;;13342:14:0;;13357:4;13363;13342:26;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13327:41;;;13379:8;13394:4;-1:-1:-1;;;;;13390:13:0;;13404:4;13390:19;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13379:30;;13422:8;13433:24;13437:14;13441:3;13446:4;13437:3;:14::i;13433:24::-;13422:35;-1:-1:-1;;;;13422:35:0;13480:9;13468:21;;13536:3;13514:19;13518:9;-1:-1:-1;;;13514:3:0;:19::i;:::-;:25;:53;;13558:9;13514:53;;;13542:9;13554:1;13542:13;13514:53;13502:65;13151:424;-1:-1:-1;;;;;;;;;13151:424:0:o;12549:382::-;12646:10;12669:8;12684:4;-1:-1:-1;;;;;12680:13:0;;12694:4;12680:19;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12669:30;;12715:9;12735:4;-1:-1:-1;;;;;12731:14:0;;12746:4;12731:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12712:39;;;;;;12765:8;12781:4;-1:-1:-1;;;;;12777:14:0;;12792:4;12798;12777:26;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12762:41;;;12825:25;12845:4;12839:3;:10;;;;12825:25;12816:34;;12886:3;12875:6;12870:19;;:53;;12905:18;12919:3;12905:13;:18::i;:::-;12903:20;;12870:53;;;12894:6;12892:8;;12870:53;12861:62;12549:382;-1:-1:-1;;;;;;;12549:382:0:o;17709:196::-;17812:12;17844:53;17867:6;17875:4;17881:1;17884:12;18601;18634:18;18645:6;18634:10;:18::i;:::-;18626:60;;;;-1:-1:-1;;;18626:60:0;;;;;;;:::i;:::-;18760:12;18774:23;18801:6;-1:-1:-1;;;;;18801:11:0;18821:8;18832:4;18801:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18759:78;;;;18852:7;18848:595;;;18883:10;-1:-1:-1;18876:17:0;;-1:-1:-1;18876:17:0;18848:595;18997:17;;:21;18993:439;;19260:10;19254:17;19321:15;19308:10;19304:2;19300:19;19293:44;19208:148;19403:12;19396:20;;-1:-1:-1;;;19396:20:0;;;;;;;;:::i;16496:619::-;16556:4;17024:20;;16867:66;17064:23;;;;;;:42;;-1:-1:-1;;17091:15:0;;;16496:619;-1:-1:-1;;16496: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;458:707::-;;575:3;568:4;560:6;556:17;552:27;542:2;;-1:-1;;583:12;542:2;630:6;617:20;652:80;667:64;724:6;667:64;:::i;:::-;652:80;:::i;:::-;760:21;;;643:89;-1:-1;804:4;817:14;;;;792:17;;;906;;;897:27;;;;894:36;-1:-1;891:2;;;943:1;;933:12;891:2;968:1;953:206;978:6;975:1;972:13;953:206;;;85:6;72:20;97:33;124:5;97:33;:::i;:::-;1046:50;;1110:14;;;;1138;;;;1000:1;993:9;953:206;;;957:14;;;;;535:630;;;;:::o;1191:707::-;;1308:3;1301:4;1293:6;1289:17;1285:27;1275:2;;-1:-1;;1316:12;1275:2;1363:6;1350:20;1385:80;1400:64;1457:6;1400:64;:::i;1385:80::-;1493:21;;;1376:89;-1:-1;1537:4;1550:14;;;;1525:17;;;1639;;;1630:27;;;;1627:36;-1:-1;1624:2;;;1676:1;;1666:12;1624:2;1701:1;1686:206;1711:6;1708:1;1705:13;1686:206;;;10495:20;;1779:50;;1843:14;;;;1871;;;;1733:1;1726:9;1686:206;;2320:440;;2421:3;2414:4;2406:6;2402:17;2398:27;2388:2;;-1:-1;;2429:12;2388:2;2476:6;2463:20;2498:64;2513:48;2554:6;2513:48;:::i;2498:64::-;2489:73;;2582:6;2575:5;2568:21;2686:3;2618:4;2677:6;2610;2668:16;;2665:25;2662:2;;;2703:1;;2693:12;2662:2;55319:6;2618:4;2610:6;2606:17;2618:4;2644:5;2640:16;55296:30;55375:1;55357:16;;;2618:4;55357:16;55350:27;2644:5;2381:379;-1:-1;;2381:379::o;2769:442::-;;2881:3;2874:4;2866:6;2862:17;2858:27;2848:2;;-1:-1;;2889:12;2848:2;2929:6;2923:13;2951:64;2966:48;3007:6;2966:48;:::i;2951:64::-;2942:73;;3035:6;3028:5;3021:21;3139:3;3071:4;3130:6;3063;3121:16;;3118:25;3115:2;;;3156:1;;3146:12;3115:2;3166:39;3198:6;3071:4;3097:5;3093:16;3071:4;3063:6;3059:17;3166:39;:::i;:::-;;2841:370;;;;:::o;3732:162::-;3815:20;;56943:1;56933:12;;56923:2;;56959:1;;56949:12;3943:1898;;4062:6;;4050:9;4045:3;4041:19;4037:32;4034:2;;;-1:-1;;4072:12;4034:2;4100:22;4062:6;4100:22;:::i;:::-;4091:31;;;4207:49;4252:3;4228:22;4207:49;:::i;:::-;4189:16;4182:75;4355:49;4400:3;4322:2;4380:9;4376:22;4355:49;:::i;:::-;4322:2;4341:5;4337:16;4330:75;4471:2;4529:9;4525:22;10495:20;4471:2;4490:5;4486:16;4479:75;4621:2;4679:9;4675:22;10495:20;4621:2;4640:5;4636:16;4629:75;4769:3;4828:9;4824:22;10495:20;4769:3;4789:5;4785:16;4778:75;4923:3;4982:9;4978:22;10495:20;4923:3;4943:5;4939:16;4932:75;5102:49;5147:3;5068;5127:9;5123:22;5102:49;:::i;:::-;5068:3;5088:5;5084:16;5077:75;5250:49;5295:3;5216;5275:9;5271:22;5250:49;:::i;:::-;5216:3;5236:5;5232:16;5225:75;5396:3;;5385:9;5381:19;5368:33;-1:-1;;;;;5421:18;5413:6;5410:30;5407:2;;;4175:1;;5443:12;5407:2;5490:58;5544:3;5535:6;5524:9;5520:22;5490:58;:::i;:::-;5396:3;5474:5;5470:18;5463:86;5646:3;;;;5635:9;5631:19;5618:33;5604:47;;5421:18;5663:6;5660:30;5657:2;;;4175:1;;5693:12;5657:2;;5740:79;5815:3;5806:6;5795:9;5791:22;5740:79;:::i;:::-;5646:3;5724:5;5720:18;5713:107;;;4028:1813;;;;:::o;7944:1179::-;;8063:4;8051:9;8046:3;8042:19;8038:30;8035:2;;;-1:-1;;8071:12;8035:2;8099:20;8063:4;8099:20;:::i;:::-;8090:29;;85:6;72:20;97:33;124:5;97:33;:::i;:::-;8179:75;;8323:2;8377:22;;72:20;97:33;72:20;97:33;:::i;:::-;8323:2;8338:16;;8331:75;8478:2;8532:22;;72:20;97:33;72:20;97:33;:::i;:::-;8511:49;8478:2;8497:5;8493:16;8486:75;;8623:2;8681:9;8677:22;10495:20;8623:2;8642:5;8638:16;8631:75;8774:3;8833:9;8829:22;10495:20;8774:3;8794:5;8790:16;8783:75;8951:3;8940:9;8936:19;8923:33;-1:-1;;;;;8968:6;8965:30;8962:2;;;-1:-1;;8998:12;8962:2;9043:58;9097:3;9088:6;9077:9;9073:22;9043:58;:::i;:::-;8951:3;9029:5;9025:16;9018:84;;8029:1094;;;;:::o;9172:1249::-;;9302:4;9290:9;9285:3;9281:19;9277:30;9274:2;;;-1:-1;;9310:12;9274:2;9338:20;9302:4;9338:20;:::i;:::-;9329:29;;226:6;220:13;238:33;265:5;238:33;:::i;:::-;9418:86;;9573:2;9638:22;;220:13;238:33;220:13;238:33;:::i;:::-;9573:2;9588:16;;9581:86;9739:2;9804:22;;220:13;238:33;220:13;238:33;:::i;:::-;9772:60;9739:2;9758:5;9754:16;9747:86;;9895:2;9964:9;9960:22;10643:13;9895:2;9914:5;9910:16;9903:86;10057:3;10127:9;10123:22;10643:13;10057:3;10077:5;10073:16;10066:86;10238:3;10227:9;10223:19;10217:26;-1:-1;;;;;10255:6;10252:30;10249:2;;;-1:-1;;10285:12;10249:2;10330:69;10395:3;10386:6;10375:9;10371:22;10330:69;:::i;10843:241::-;;10947:2;10935:9;10926:7;10922:23;10918:32;10915:2;;;-1:-1;;10953:12;10915:2;85:6;72:20;97:33;124:5;97:33;:::i;11091:263::-;;11206:2;11194:9;11185:7;11181:23;11177:32;11174:2;;;-1:-1;;11212:12;11174:2;226:6;220:13;238:33;265:5;238:33;:::i;11361:366::-;;;11482:2;11470:9;11461:7;11457:23;11453:32;11450:2;;;-1:-1;;11488:12;11450:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;11540:63;11640:2;11679:22;;;;10495:20;;-1:-1;;;11444:283::o;11734:491::-;;;;11872:2;11860:9;11851:7;11847:23;11843:32;11840:2;;;-1:-1;;11878:12;11840:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;11930:63;12030:2;12069:22;;10495:20;;-1:-1;12138:2;12177:22;;;2108:20;;11834:391;-1:-1;;;11834:391::o;12232:617::-;;;;;12387:3;12375:9;12366:7;12362:23;12358:33;12355:2;;;-1:-1;;12394:12;12355:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;12446:63;-1:-1;12546:2;12585:22;;10495:20;;-1:-1;12654:2;12693:22;;2108:20;;-1:-1;12762:2;12801:22;;72:20;97:33;72:20;97:33;:::i;:::-;12349:500;;;;-1:-1;12349:500;;-1:-1;;12349:500::o;12856:1255::-;;;;;;13112:3;13100:9;13091:7;13087:23;13083:33;13080:2;;;-1:-1;;13119:12;13080:2;13177:17;13164:31;-1:-1;;;;;13215:18;13207:6;13204:30;13201:2;;;-1:-1;;13237:12;13201:2;13267:78;13337:7;13328:6;13317:9;13313:22;13267:78;:::i;:::-;13257:88;;13410:2;13399:9;13395:18;13382:32;13368:46;;13215:18;13426:6;13423:30;13420:2;;;-1:-1;;13456:12;13420:2;13486:78;13556:7;13547:6;13536:9;13532:22;13486:78;:::i;:::-;13476:88;;13629:2;13618:9;13614:18;13601:32;13587:46;;13215:18;13645:6;13642:30;13639:2;;;-1:-1;;13675:12;13639:2;13705:78;13775:7;13766:6;13755:9;13751:22;13705:78;:::i;:::-;13695:88;;13820:2;13863:9;13859:22;72:20;63:29;;97:33;124:5;97:33;:::i;:::-;13828:63;;-1:-1;13956:3;13941:19;;13928:33;;13970:30;;;13967:2;;;-1:-1;;14003:12;13967:2;;14033:62;14087:7;14078:6;14067:9;14063:22;14033:62;:::i;:::-;14023:72;;;13074:1037;;;;;;;;:::o;14118:1129::-;;;;;14357:3;14345:9;14336:7;14332:23;14328:33;14325:2;;;-1:-1;;14364:12;14325:2;14422:17;14409:31;-1:-1;;;;;14460:18;14452:6;14449:30;14446:2;;;-1:-1;;14482:12;14446:2;14512:78;14582:7;14573:6;14562:9;14558:22;14512:78;:::i;:::-;14502:88;;14655:2;14644:9;14640:18;14627:32;14613:46;;14460:18;14671:6;14668:30;14665:2;;;-1:-1;;14701:12;14665:2;14731:78;14801:7;14792:6;14781:9;14777:22;14731:78;:::i;:::-;14721:88;;14874:2;14863:9;14859:18;14846:32;14832:46;;14460:18;14890:6;14887:30;14884:2;;;-1:-1;;14920:12;14884:2;14950:78;15020:7;15011:6;15000:9;14996:22;14950:78;:::i;:::-;14940:88;;15093:2;15082:9;15078:18;15065:32;15051:46;;14460:18;15109:6;15106:30;15103:2;;;-1:-1;;15139:12;15103:2;;15169:62;15223:7;15214:6;15203:9;15199:22;15169:62;:::i;:::-;15159:72;;;14319:928;;;;;;;:::o;15254:257::-;;15366:2;15354:9;15345:7;15341:23;15337:32;15334:2;;;-1:-1;;15372:12;15334:2;1987:6;1981:13;1999:30;2023:5;1999:30;:::i;15518:393::-;;;15647:2;15635:9;15626:7;15622:23;15618:32;15615:2;;;-1:-1;;15653:12;15615:2;1987:6;1981:13;56231:5;52043:13;52036:21;56209:5;56206:32;56196:2;;-1:-1;;56242:12;56196:2;15813;15863:22;;;;10643:13;15705:71;;10643:13;;-1:-1;;;15609:302::o;15918:241::-;;16022:2;16010:9;16001:7;15997:23;15993:32;15990:2;;;-1:-1;;16028:12;15990:2;-1:-1;2108:20;;15984:175;-1:-1;15984:175::o;16166:263::-;;16281:2;16269:9;16260:7;16256:23;16252:32;16249:2;;;-1:-1;;16287:12;16249:2;-1:-1;2256:13;;16243:186;-1:-1;16243:186::o;16436:345::-;;16549:2;16537:9;16528:7;16524:23;16520:32;16517:2;;;-1:-1;;16555:12;16517:2;16613:17;16600:31;-1:-1;;;;;16643:6;16640:30;16637:2;;;-1:-1;;16673:12;16637:2;16703:62;16757:7;16748:6;16737:9;16733:22;16703:62;:::i;16788:1049::-;;;;;;;17000:3;16988:9;16979:7;16975:23;16971:33;16968:2;;;-1:-1;;17007:12;16968:2;17058:17;17052:24;-1:-1;;;;;17088:6;17085:30;17082:2;;;-1:-1;;17118:12;17082:2;17148:73;17213:7;17204:6;17193:9;17189:22;17148:73;:::i;:::-;17138:83;;;17258:2;17312:9;17308:22;10643:13;17266:74;;17377:2;17431:9;17427:22;10643:13;17385:74;;17496:2;17558:9;17554:22;369:13;387:41;422:5;387:41;:::i;:::-;17623:3;17671:22;;1981:13;17504:82;;-1:-1;1999:30;1981:13;1999:30;:::i;:::-;17740:3;17789:22;;10782:13;17632:71;;-1:-1;52988:4;52977:16;;57156:33;;57146:2;;-1:-1;;57193:12;57146:2;17749:72;;;;16962:875;;;;;;;;:::o;18136:398::-;;;18273:2;18261:9;18252:7;18248:23;18244:32;18241:2;;;-1:-1;;18279:12;19071:439;;;19223:2;19211:9;19202:7;19198:23;19194:32;19191:2;;;-1:-1;;19229:12;19191:2;3655:6;3649:13;3667:53;3714:5;3667:53;:::i;19517:273::-;;19637:2;19625:9;19616:7;19612:23;19608:32;19605:2;;;-1:-1;;19643:12;19605:2;19705:69;19766:7;19742:22;19705:69;:::i;19797:387::-;;19931:2;19919:9;19910:7;19906:23;19902:32;19899:2;;;-1:-1;;19937:12;19899:2;19995:17;19982:31;-1:-1;;;;;20025:6;20022:30;20019:2;;;-1:-1;;20055:12;20019:2;20085:83;20160:7;20151:6;20140:9;20136:22;20085:83;:::i;20191:402::-;;20336:2;20324:9;20315:7;20311:23;20307:32;20304:2;;;-1:-1;;20342:12;20304:2;20393:17;20387:24;-1:-1;;;;;20431:18;20423:6;20420:30;20417:2;;;-1:-1;;20453:12;20417:2;20560:6;20549:9;20545:22;;;6020:6;;6008:9;6003:3;5999:19;5995:32;5992:2;;;-1:-1;;6030:12;5992:2;6058:22;6020:6;6058:22;:::i;:::-;6049:31;;6165:60;6221:3;6197:22;6165:60;:::i;:::-;6147:16;6140:86;6324:60;6380:3;20336:2;6360:9;6356:22;6324:60;:::i;:::-;20336:2;6310:5;6306:16;6299:86;6451:2;6520:9;6516:22;10643:13;6451:2;6470:5;6466:16;6459:86;6612:2;6681:9;6677:22;10643:13;6612:2;6631:5;6627:16;6620:86;6771:3;6841:9;6837:22;10643:13;6771:3;6791:5;6787:16;6780:86;6936:3;7006:9;7002:22;10643:13;6936:3;6956:5;6952:16;6945:86;7126:60;7182:3;7092;7162:9;7158:22;7126:60;:::i;:::-;7092:3;7112:5;7108:16;7101:86;7285:60;7341:3;7251;7321:9;7317:22;7285:60;:::i;:::-;7251:3;7271:5;7267:16;7260:86;7435:3;;7424:9;7420:19;7414:26;20431:18;7452:6;7449:30;7446:2;;;-1:-1;;7482:12;7446:2;7529:69;7594:3;7585:6;7574:9;7570:22;7529:69;:::i;:::-;7435:3;7513:5;7509:18;7502:97;;;7689:3;;7678:9;7674:19;7668:26;20431:18;7706:6;7703:30;7700:2;;;-1:-1;;7736:12;7700:2;7783:90;7869:3;7860:6;7849:9;7845:22;7783:90;:::i;:::-;7763:18;;;7756:118;;;;-1:-1;7767:5;20298:295;-1:-1;;;;;20298:295::o;20600:921::-;;;;;;20818:3;20806:9;20797:7;20793:23;20789:33;20786:2;;;-1:-1;;20825:12;20786:2;20883:17;20870:31;-1:-1;;;;;20913:6;20910:30;20907:2;;;-1:-1;;20943:12;20907:2;20973:83;21048:7;21039:6;21028:9;21024:22;20973:83;:::i;:::-;20963:93;;;21093:2;21136:9;21132:22;10495:20;21101:63;;21201:2;21244:9;21240:22;10495:20;21209:63;;21309:2;21352:9;21348:22;72:20;97:33;124:5;97:33;:::i;:::-;21317:63;-1:-1;21436:69;21497:7;21417:3;21473:22;;21436:69;:::i;:::-;21426:79;;20780:741;;;;;;;;:::o;21798:399::-;;;21930:2;21918:9;21909:7;21905:23;21901:32;21898:2;;;-1:-1;;21936:12;21898:2;-1:-1;;10643:13;;22099:2;22149:22;;;10643:13;;;;;-1:-1;21892:305::o;22204:809::-;;;;;;22387:3;22375:9;22366:7;22362:23;22358:33;22355:2;;;-1:-1;;22394:12;22355:2;-1:-1;;10643:13;;22557:2;22607:22;;10643:13;22676:2;22726:22;;10643:13;22795:2;22845:22;;10643:13;22914:3;22965:22;;;10643:13;;;;;-1:-1;10643:13;;-1:-1;10643:13;;-1:-1;22349:664;-1:-1;22349:664::o;23169:103::-;-1:-1;;;;;52772:54;23230:37;;23224:48::o;23630:323::-;;23762:5;50946:12;51221:6;51216:3;51209:19;23845:52;23890:6;51258:4;51253:3;51249:14;51258:4;23871:5;23867:16;23845:52;:::i;:::-;55752:7;55736:14;-1:-1;;55732:28;23909:39;;;;51258:4;23909:39;;23710:243;-1:-1;;23710:243::o;29828:1986::-;;29989:6;30089:63;30137:14;30066:16;30060:23;30089:63;:::i;:::-;30235:4;30228:5;30224:16;30218:23;30247:63;30235:4;30299:3;30295:14;30281:12;30247:63;:::i;:::-;;30394:4;30387:5;30383:16;30377:23;30394:4;30458:3;30454:14;23581:37;30554:4;30547:5;30543:16;30537:23;30554:4;30618:3;30614:14;23581:37;30712:4;30705:5;30701:16;30695:23;30712:4;30776:3;30772:14;23581:37;30875:4;30868:5;30864:16;30858:23;30875:4;30939:3;30935:14;23581:37;31029:4;31022:5;31018:16;31012:23;31041:63;31029:4;31093:3;31089:14;31075:12;31041:63;:::i;:::-;;31186:4;31179:5;31175:16;31169:23;31198:63;31186:4;31250:3;31246:14;31232:12;31198:63;:::i;:::-;;31347:6;;31340:5;31336:18;31330:25;29989:6;31347;31379:3;31375:16;31368:40;31423:71;29989:6;29984:3;29980:16;31475:12;31423:71;:::i;:::-;31415:79;;;;31587:6;;31580:5;31576:18;31570:25;31643:3;31637:4;31633:14;31587:6;31619:3;31615:16;31608:40;31663:113;31771:4;31757:12;31663:113;:::i;:::-;31798:11;29962:1852;-1:-1;;;;;;29962:1852::o;31902:1219::-;;5421:18;;52783:42;;;;32128:16;32122:23;52772:54;23237:3;23230:37;52783:42;32301:4;32294:5;32290:16;32284:23;52772:54;32301:4;32365:3;32361:14;23230:37;52783:42;32466:4;32459:5;32455:16;32449:23;52772:54;32466:4;32530:3;32526:14;23230:37;;32621:4;32614:5;32610:16;32604:23;32621:4;32685:3;32681:14;23581:37;32782:4;32775:5;32771:16;32765:23;32782:4;32846:3;32842:14;23581:37;32940:4;32933:5;32929:16;32923:23;32053:4;32940;32970:3;32966:14;32959:38;33012:71;32053:4;32048:3;32044:14;33064:12;33012:71;:::i;33358:271::-;;24470:5;50946:12;24581:52;24626:6;24621:3;24614:4;24607:5;24603:16;24581:52;:::i;:::-;24645:16;;;;;33492:137;-1:-1;;33492:137::o;33636:222::-;-1:-1;;;;;52772:54;;;;23230:37;;33763:2;33748:18;;33734:124::o;34110:349::-;-1:-1;;;;;52772:54;;;23099:58;;52772:54;;34445:2;34430:18;;23230:37;34273:2;34258:18;;34244:215::o;34466:866::-;-1:-1;;;;;52772:54;;;23099:58;;52772:54;;34965:2;34950:18;;23099:58;34784:3;35002:2;34987:18;;34980:48;;;26655:2;34769:19;;;51209;-1:-1;;;52783:42;51249:14;;26671:36;26726:12;35206:2;35191:18;;35184:48;;;34466:866;;35246:76;;26726:12;;35308:6;35246:76;:::i;:::-;35238:84;34755:577;-1:-1;;;;;34755:577::o;35339:866::-;-1:-1;;;;;52772:54;;;23099:58;;52772:54;;35838:2;35823:18;;23099:58;35657:3;35875:2;35860:18;;35853:48;;;27308:1;35642:19;;;51209;-1:-1;;;52783:42;51249:14;;27323:31;27373:12;36079:2;36064:18;;36057:48;;;35339:866;;36119:76;;27373:12;;36181:6;36119:76;:::i;36212:866::-;-1:-1;;;;;52772:54;;;23099:58;;52772:54;;36711:2;36696:18;;23099:58;36530:3;36748:2;36733:18;;36726:48;;;27955:2;36515:19;;;51209;-1:-1;;;52783:42;51249:14;;27971:36;28026:12;36952:2;36937:18;;36930:48;;;36212:866;;36992:76;;28026:12;;37054:6;36992:76;:::i;37085:866::-;-1:-1;;;;;52772:54;;;23099:58;;52772:54;;37584:2;37569:18;;23099:58;37403:3;37621:2;37606:18;;37599:48;;;28277:1;37388:19;;;51209;-1:-1;;;52783:42;51249:14;;28292:31;28342:12;37825:2;37810:18;;37803:48;;;37085:866;;37865:76;;28342:12;;37927:6;37865:76;:::i;37958:349::-;-1:-1;;;;;52772:54;;;;23099:58;;38293:2;38278:18;;23581:37;38121:2;38106:18;;38092:215::o;38314:640::-;-1:-1;;;;;52772:54;;;23230:37;;52772:54;;38708:2;38693:18;;23230:37;38791:2;38776:18;;23581:37;;;38543:3;38828:2;38813:18;;38806:48;;;38314:640;;38868:76;;38528:19;;38930:6;38868:76;:::i;38961:345::-;-1:-1;;;;;52772:54;;;;23230:37;;52988:4;52977:16;39292:2;39277:18;;26008:56;39122:2;39107:18;;39093:213::o;39653:210::-;52043:13;;52036:21;23464:34;;39774:2;39759:18;;39745:118::o;39870:222::-;23581:37;;;39997:2;39982:18;;39968:124::o;40099:333::-;23581:37;;;-1:-1;;;;;52772:54;40418:2;40403:18;;23230:37;40254:2;40239:18;;40225:207::o;40439:822::-;23581:37;;;-1:-1;;;;;52772:54;;;40892:2;40877:18;;23230:37;52772:54;;;40983:2;40968:18;;23099:58;52772:54;;41074:2;41059:18;;23099:58;41155:3;41140:19;;23581:37;;;;52783:42;41231:19;;25862:57;40727:3;40712:19;;40698:563::o;41268:306::-;;41413:2;41434:17;41427:47;41488:76;41413:2;41402:9;41398:18;41550:6;41488:76;:::i;43213:416::-;43413:2;43427:47;;;26977:2;43398:18;;;51209:19;-1:-1;;;51249:14;;;26993:45;27057:12;;;43384:245::o;43636:416::-;43836:2;43850:47;;;27624:2;43821:18;;;51209:19;-1:-1;;;51249:14;;;27640:45;27704:12;;;43807:245::o;44059:416::-;44259:2;44273:47;;;28593:2;44244:18;;;51209:19;28629:31;51249:14;;;28609:52;28680:12;;;44230:245::o;44482:416::-;44682:2;44696:47;;;28931:2;44667:18;;;51209:19;28967:34;51249:14;;;28947:55;-1:-1;;;29022:12;;;29015:34;29068:12;;;44653:245::o;44905:416::-;45105:2;45119:47;;;29319:2;45090:18;;;51209:19;29355:25;51249:14;;;29335:46;29400:12;;;45076:245::o;45328:416::-;45528:2;45542:47;;;29651:2;45513:18;;;51209:19;-1:-1;;;51249:14;;;29667:35;29721:12;;;45499:245::o;45751:390::-;;45938:2;45959:17;45952:47;46013:118;45938:2;45927:9;45923:18;46117:6;46013:118;:::i;46148:527::-;;46376:2;46397:17;46390:47;46451:118;46376:2;46365:9;46361:18;46555:6;46451:118;:::i;:::-;46443:126;;55857:1;55850:5;55847:12;55837:2;;55863:9;55837:2;54703:39;46661:2;46650:9;46646:18;25592:63;46347:328;;;;;:::o;46911:460::-;23581:37;;;-1:-1;;;;;52772:54;;;;47274:2;47259:18;;23099:58;47357:2;47342:18;;23581:37;47102:2;47087:18;;47073:298::o;47378:556::-;23581:37;;;-1:-1;;;;;52772:54;;;;47754:2;47739:18;;23230:37;47837:2;47822:18;;23581:37;47920:2;47905:18;;23581:37;47589:3;47574:19;;47560:374::o;47941:436::-;23581:37;;;48282:2;48267:18;;23581:37;;;;48363:2;48348:18;;23581:37;48120:2;48105:18;;48091:286::o;49306:333::-;23581:37;;;49625:2;49610:18;;23581:37;49461:2;49446:18;;49432:207::o;49646:256::-;49708:2;49702:9;49734:17;;;-1:-1;;;;;49794:34;;49830:22;;;49791:62;49788:2;;;49866:1;;49856:12;49788:2;49708;49875:22;49686:216;;-1:-1;49686:216::o;49909:304::-;;-1:-1;;;;;50060:6;50057:30;50054:2;;;-1:-1;;50090:12;50054:2;-1:-1;50135:4;50123:17;;;50188:15;;49991:222::o;50531:321::-;;-1:-1;;;;;50666:6;50663:30;50660:2;;;-1:-1;;50696:12;50660:2;-1:-1;55752:7;50750:17;-1:-1;;50746:33;50837:4;50827:15;;50597:255::o;55392:268::-;55457:1;55464:101;55478:6;55475:1;55472:13;55464:101;;;55545:11;;;55539:18;55526:11;;;55519:39;55500:2;55493:10;55464:101;;;55580:6;55577:1;55574:13;55571:2;;;-1:-1;;55457:1;55627:16;;55620:27;55441:219::o;55886:117::-;-1:-1;;;;;52772:54;;55945:35;;55935:2;;55994:1;;55984:12;55935:2;55929:74;:::o;56150:111::-;56231:5;52043:13;52036:21;56209:5;56206:32;56196:2;;56252:1;;56242:12
Swarm Source
ipfs://dec659417d70d3ec958a4b9da14fc85d0a3f1da92a0b507ae95761b6ef650939
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.