Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
11884441 | 1429 days ago | 1.81732913 ETH | ||||
11884441 | 1429 days ago | 1.81732913 ETH | ||||
11880084 | 1430 days ago | 3.68996961 ETH | ||||
11880084 | 1430 days ago | 3.68996961 ETH | ||||
11879651 | 1430 days ago | 7.24961363 ETH | ||||
11879651 | 1430 days ago | 7.24961363 ETH | ||||
11879651 | 1430 days ago | 8 ETH | ||||
11879651 | 1430 days ago | 0.75690514 ETH | ||||
11879651 | 1430 days ago | 7.24309485 ETH | ||||
11878683 | 1430 days ago | 7.28913915 ETH | ||||
11878683 | 1430 days ago | 7.28913915 ETH | ||||
11878683 | 1430 days ago | 8 ETH | ||||
11878683 | 1430 days ago | 0.71741517 ETH | ||||
11878683 | 1430 days ago | 7.28258482 ETH | ||||
11878295 | 1430 days ago | 57.17518307 ETH | ||||
11878295 | 1430 days ago | 57.17518307 ETH | ||||
11877404 | 1430 days ago | 0.43231809 ETH | ||||
11877404 | 1430 days ago | 0.43231809 ETH | ||||
11876893 | 1431 days ago | 1,341.42279578 ETH | ||||
11876893 | 1431 days ago | 1,341.42279578 ETH | ||||
11876514 | 1431 days ago | 49.77098896 ETH | ||||
11876514 | 1431 days ago | 49.77098896 ETH | ||||
11876259 | 1431 days ago | 98.42308547 ETH | ||||
11876259 | 1431 days ago | 98.42308547 ETH | ||||
11874829 | 1431 days ago | 109.54978619 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-01-18 */ 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 = msg.sender; admin = 0x25eFA336886C74eA8E282ac466BdCd0199f85BB9; } /// @notice Admin is set by owner first time, after that admin is super role and has permission to change owner /// @param _admin Address of multisig that becomes admin function setAdminByOwner(address _admin) public { require(msg.sender == owner); require(admin == address(0)); admin = _admin; } /// @notice Admin is able to set new admin /// @param _admin Address of multisig that becomes new admin function setAdminByAdmin(address _admin) public { require(msg.sender == admin); admin = _admin; } /// @notice Admin is able to change owner /// @param _owner Address of new owner function setOwnerByAdmin(address _owner) public { require(msg.sender == admin); owner = _owner; } /// @notice Destroy the contract function kill() public onlyOwner { selfdestruct(payable(owner)); } /// @notice withdraw stuck funds function withdrawStuckFunds(address _token, uint _amount) public onlyOwner { if (_token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) { payable(owner).transfer(_amount); } else { ERC20(_token).safeTransfer(owner, _amount); } } } contract BotRegistry is AdminAuth { mapping (address => bool) public botList; constructor() public { botList[0x776B4a13093e30B05781F97F6A4565B6aa8BE330] = true; botList[0xAED662abcC4FA3314985E67Ea993CAD064a7F5cF] = true; botList[0xa5d330F6619d6bF892A5B87D80272e1607b3e34D] = true; botList[0x5feB4DeE5150B589a7f567EA7CADa2759794A90A] = true; botList[0x7ca06417c1d6f480d3bB195B80692F95A6B66158] = true; } function setBot(address _botAddr, bool _state) public onlyOwner { botList[_botAddr] = _state; } } abstract contract TokenInterface { address public constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; function allowance(address, address) public virtual returns (uint256); function balanceOf(address) public virtual returns (uint256); function approve(address, uint256) public virtual; function transfer(address, uint256) public virtual returns (bool); function transferFrom(address, address, uint256) public virtual returns (bool); function deposit() public virtual payable; function withdraw(uint256) public virtual; } interface ExchangeInterfaceV3 { function sell(address _srcAddr, address _destAddr, uint _srcAmount, bytes memory _additionalData) external payable returns (uint); function buy(address _srcAddr, address _destAddr, uint _destAmount, bytes memory _additionalData) external payable returns(uint); function getSellRate(address _srcAddr, address _destAddr, uint _srcAmount, bytes memory _additionalData) external view returns (uint); function getBuyRate(address _srcAddr, address _destAddr, uint _srcAmount, bytes memory _additionalData) external view returns (uint); } contract ZrxAllowlist is AdminAuth { mapping (address => bool) public zrxAllowlist; mapping(address => bool) private nonPayableAddrs; constructor() public { zrxAllowlist[0x6958F5e95332D93D21af0D7B9Ca85B8212fEE0A5] = true; zrxAllowlist[0x61935CbDd02287B511119DDb11Aeb42F1593b7Ef] = true; zrxAllowlist[0xDef1C0ded9bec7F1a1670819833240f027b25EfF] = true; zrxAllowlist[0x080bf510FCbF18b91105470639e9561022937712] = true; nonPayableAddrs[0x080bf510FCbF18b91105470639e9561022937712] = true; } function setAllowlistAddr(address _zrxAddr, bool _state) public onlyOwner { zrxAllowlist[_zrxAddr] = _state; } function isZrxAddr(address _zrxAddr) public view returns (bool) { return zrxAllowlist[_zrxAddr]; } function addNonPayableAddr(address _nonPayableAddr) public onlyOwner { nonPayableAddrs[_nonPayableAddr] = true; } function removeNonPayableAddr(address _nonPayableAddr) public onlyOwner { nonPayableAddrs[_nonPayableAddr] = false; } function isNonPayableAddr(address _addr) public view returns(bool) { return nonPayableAddrs[_addr]; } } contract DFSExchangeData { // first is empty to keep the legacy order in place enum ExchangeType { _, OASIS, KYBER, UNISWAP, ZEROX } enum ActionType { SELL, BUY } struct OffchainData { address wrapper; address exchangeAddr; address allowanceTarget; uint256 price; uint256 protocolFee; bytes callData; } struct ExchangeData { address srcAddr; address destAddr; uint256 srcAmount; uint256 destAmount; uint256 minPrice; uint256 dfsFeeDivider; // service fee divider address user; // user to check special fee address wrapper; bytes wrapperData; OffchainData offchainData; } function packExchangeData(ExchangeData memory _exData) public pure returns(bytes memory) { return abi.encode(_exData); } function unpackExchangeData(bytes memory _data) public pure returns(ExchangeData memory _exData) { _exData = abi.decode(_data, (ExchangeData)); } } 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; address payable public constant WALLET_ID = 0x322d58b9E75a6918f7e7849AEe0fF09369977e08; 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; } if (_token == KYBER_ETH_ADDRESS) { WALLET_ID.transfer(feeAmount); } else { ERC20(_token).safeTransfer(WALLET_ID, 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) { // calculate src amount based on price and add 5% /// @dev this value in exData object will be changed in parent method as well exData.srcAmount = div(mul(wdiv(exData.destAmount, exData.minPrice), 105), 100); swapedTokens = saverSwap(exData, ActionType.BUY); wrapper = exData.wrapper; } // if anything is left in weth, pull it to user as eth if (getBalance(EXCHANGE_WETH_ADDRESS) > 0) { TokenInterface(EXCHANGE_WETH_ADDRESS).withdraw( TokenInterface(EXCHANGE_WETH_ADDRESS).balanceOf(address(this)) ); } if (exData.destAddr == EXCHANGE_WETH_ADDRESS) { require(getBalance(KYBER_ETH_ADDRESS) >= exData.destAmount, ERR_SLIPPAGE_HIT); } else { require(getBalance(exData.destAddr) >= exData.destAmount, ERR_SLIPPAGE_HIT); } return (wrapper, getBalance(exData.destAddr)); } /// @notice Takes order from 0x and returns bool indicating if it is successful /// @param _exData Exchange data function takeOrder( ExchangeData memory _exData, ActionType _type ) private returns (bool success, uint256) { if (!ZrxAllowlist(ZRX_ALLOWLIST_ADDR).isZrxAddr(_exData.offchainData.exchangeAddr)) { return (false, 0); } if (!SaverExchangeRegistry(SAVER_EXCHANGE_REGISTRY).isWrapper(_exData.offchainData.wrapper)) { return (false, 0); } // send src amount ERC20(_exData.srcAddr).safeTransfer(_exData.offchainData.wrapper, _exData.srcAmount); return OffchainWrapperInterface(_exData.offchainData.wrapper).takeOrder{value: _exData.offchainData.protocolFee}(_exData, _type); } /// @notice Calls wraper contract for exchage to preform an on-chain swap /// @param _exData Exchange data struct /// @param _type Type of action SELL|BUY /// @return swapedTokens For Sell that the destAmount, for Buy thats the srcAmount function saverSwap(ExchangeData memory _exData, ActionType _type) internal returns (uint swapedTokens) { require(SaverExchangeRegistry(SAVER_EXCHANGE_REGISTRY).isWrapper(_exData.wrapper), ERR_WRAPPER_INVALID); ERC20(_exData.srcAddr).safeTransfer(_exData.wrapper, _exData.srcAmount); if (_type == ActionType.SELL) { swapedTokens = ExchangeInterfaceV3(_exData.wrapper). sell(_exData.srcAddr, _exData.destAddr, _exData.srcAmount, _exData.wrapperData); } else { swapedTokens = ExchangeInterfaceV3(_exData.wrapper). buy(_exData.srcAddr, _exData.destAddr, _exData.destAmount, _exData.wrapperData); } } // solhint-disable-next-line no-empty-blocks receive() external virtual payable {} } /// @title Implements Boost and Repay for MCD CDPs contract MCDSaverProxy is DFSExchangeCore, MCDSaverProxyHelper { uint public constant MANUAL_SERVICE_FEE = 400; // 0.25% Fee uint public constant AUTOMATIC_SERVICE_FEE = 333; // 0.3% Fee bytes32 public constant ETH_ILK = 0x4554482d41000000000000000000000000000000000000000000000000000000; address public constant VAT_ADDRESS = 0x35D1b3F3D7966A1DFe207aa4514C12a259A0492B; address public constant SPOTTER_ADDRESS = 0x65C79fcB50Ca1594B025960e539eD7A9a6D434A3; address public constant DAI_JOIN_ADDRESS = 0x9759A6Ac90977b93B58547b4A71c78317f391A28; address public constant JUG_ADDRESS = 0x19c0976f590D67707E62397C87829d896Dc0f1F1; address public constant DAI_ADDRESS = 0x6B175474E89094C44Da98b954EedeAC495271d0F; address public constant BOT_REGISTRY_ADDRESS = 0x637726f8b08a7ABE3aE3aCaB01A80E2d8ddeF77B; Vat public constant vat = Vat(VAT_ADDRESS); DaiJoin public constant daiJoin = DaiJoin(DAI_JOIN_ADDRESS); Spotter public constant spotter = Spotter(SPOTTER_ADDRESS); DefisaverLogger public constant logger = DefisaverLogger(0x5c55B921f590a89C1Ebe84dF170E655a82b62126); /// @notice Repay - draws collateral, converts to Dai and repays the debt /// @dev Must be called by the DSProxy contract that owns the CDP function repay( ExchangeData memory _exchangeData, uint _cdpId, uint _gasCost, address _joinAddr, ManagerType _managerType ) public payable { address managerAddr = getManagerAddr(_managerType); address user = getOwner(Manager(managerAddr), _cdpId); bytes32 ilk = Manager(managerAddr).ilks(_cdpId); drawCollateral(managerAddr, _cdpId, _joinAddr, _exchangeData.srcAmount); _exchangeData.user = user; _exchangeData.dfsFeeDivider = isAutomation() ? AUTOMATIC_SERVICE_FEE : MANUAL_SERVICE_FEE; (, uint daiAmount) = _sell(_exchangeData); daiAmount -= takeFee(_gasCost, daiAmount); paybackDebt(managerAddr, _cdpId, ilk, daiAmount, user); // if there is some eth left (0x fee), return it to user if (address(this).balance > 0) { tx.origin.transfer(address(this).balance); } logger.Log(address(this), msg.sender, "MCDRepay", abi.encode(_cdpId, user, _exchangeData.srcAmount, daiAmount)); } /// @notice Boost - draws Dai, converts to collateral and adds to CDP /// @dev Must be called by the DSProxy contract that owns the CDP function boost( ExchangeData memory _exchangeData, uint _cdpId, uint _gasCost, address _joinAddr, ManagerType _managerType ) public payable { address managerAddr = getManagerAddr(_managerType); address user = getOwner(Manager(managerAddr), _cdpId); bytes32 ilk = Manager(managerAddr).ilks(_cdpId); uint daiDrawn = drawDai(managerAddr, _cdpId, ilk, _exchangeData.srcAmount); _exchangeData.user = user; _exchangeData.dfsFeeDivider = isAutomation() ? AUTOMATIC_SERVICE_FEE : MANUAL_SERVICE_FEE; _exchangeData.srcAmount = daiDrawn - takeFee(_gasCost, daiDrawn); (, uint swapedColl) = _sell(_exchangeData); addCollateral(managerAddr, _cdpId, _joinAddr, swapedColl); // if there is some eth left (0x fee), return it to user if (address(this).balance > 0) { tx.origin.transfer(address(this).balance); } logger.Log(address(this), msg.sender, "MCDBoost", abi.encode(_cdpId, user, _exchangeData.srcAmount, swapedColl)); } /// @notice Draws Dai from the CDP /// @dev If _daiAmount is bigger than max available we'll draw max /// @param _managerAddr Address of the CDP Manager /// @param _cdpId Id of the CDP /// @param _ilk Ilk of the CDP /// @param _daiAmount Amount of Dai to draw function drawDai(address _managerAddr, uint _cdpId, bytes32 _ilk, uint _daiAmount) internal returns (uint) { uint rate = Jug(JUG_ADDRESS).drip(_ilk); uint daiVatBalance = vat.dai(Manager(_managerAddr).urns(_cdpId)); uint maxAmount = getMaxDebt(_managerAddr, _cdpId, _ilk); if (_daiAmount >= maxAmount) { _daiAmount = sub(maxAmount, 1); } Manager(_managerAddr).frob(_cdpId, int(0), normalizeDrawAmount(_daiAmount, rate, daiVatBalance)); Manager(_managerAddr).move(_cdpId, address(this), toRad(_daiAmount)); if (vat.can(address(this), address(DAI_JOIN_ADDRESS)) == 0) { vat.hope(DAI_JOIN_ADDRESS); } DaiJoin(DAI_JOIN_ADDRESS).exit(address(this), _daiAmount); return _daiAmount; } /// @notice Adds collateral to the CDP /// @param _managerAddr Address of the CDP Manager /// @param _cdpId Id of the CDP /// @param _joinAddr Address of the join contract for the CDP collateral /// @param _amount Amount of collateral to add function addCollateral(address _managerAddr, uint _cdpId, address _joinAddr, uint _amount) internal { int convertAmount = 0; if (isEthJoinAddr(_joinAddr)) { Join(_joinAddr).gem().deposit{value: _amount}(); convertAmount = toPositiveInt(_amount); } else { convertAmount = toPositiveInt(convertTo18(_joinAddr, _amount)); } ERC20(address(Join(_joinAddr).gem())).safeApprove(_joinAddr, _amount); Join(_joinAddr).join(address(this), _amount); vat.frob( Manager(_managerAddr).ilks(_cdpId), Manager(_managerAddr).urns(_cdpId), address(this), address(this), convertAmount, 0 ); } /// @notice Draws collateral and returns it to DSProxy /// @param _managerAddr Address of the CDP Manager /// @dev If _amount is bigger than max available we'll draw max /// @param _cdpId Id of the CDP /// @param _joinAddr Address of the join contract for the CDP collateral /// @param _amount Amount of collateral to draw function drawCollateral(address _managerAddr, uint _cdpId, address _joinAddr, uint _amount) internal returns (uint) { uint frobAmount = _amount; if (Join(_joinAddr).dec() != 18) { frobAmount = _amount * (10 ** (18 - Join(_joinAddr).dec())); } Manager(_managerAddr).frob(_cdpId, -toPositiveInt(frobAmount), 0); Manager(_managerAddr).flux(_cdpId, address(this), frobAmount); Join(_joinAddr).exit(address(this), _amount); if (isEthJoinAddr(_joinAddr)) { Join(_joinAddr).gem().withdraw(_amount); // Weth -> Eth } return _amount; } /// @notice Paybacks Dai debt /// @param _managerAddr Address of the CDP Manager /// @dev If the _daiAmount is bigger than the whole debt, returns extra Dai /// @param _cdpId Id of the CDP /// @param _ilk Ilk of the CDP /// @param _daiAmount Amount of Dai to payback /// @param _owner Address that owns the DSProxy that owns the CDP function paybackDebt(address _managerAddr, uint _cdpId, bytes32 _ilk, uint _daiAmount, address _owner) internal { address urn = Manager(_managerAddr).urns(_cdpId); uint wholeDebt = getAllDebt(VAT_ADDRESS, urn, urn, _ilk); if (_daiAmount > wholeDebt) { ERC20(DAI_ADDRESS).transfer(_owner, sub(_daiAmount, wholeDebt)); _daiAmount = wholeDebt; } if (ERC20(DAI_ADDRESS).allowance(address(this), DAI_JOIN_ADDRESS) == 0) { ERC20(DAI_ADDRESS).approve(DAI_JOIN_ADDRESS, uint(-1)); } daiJoin.join(urn, _daiAmount); Manager(_managerAddr).frob(_cdpId, 0, normalizePaybackAmount(VAT_ADDRESS, urn, _ilk)); } /// @notice Gets the maximum amount of collateral available to draw /// @param _managerAddr Address of the CDP Manager /// @param _cdpId Id of the CDP /// @param _ilk Ilk of the CDP /// @param _joinAddr Joind address of collateral /// @dev Substracts 10 wei to aviod rounding error later on function getMaxCollateral(address _managerAddr, uint _cdpId, bytes32 _ilk, address _joinAddr) public view returns (uint) { uint price = getPrice(_ilk); (uint collateral, uint debt) = getCdpInfo(Manager(_managerAddr), _cdpId, _ilk); (, uint mat) = Spotter(SPOTTER_ADDRESS).ilks(_ilk); uint maxCollateral = sub(collateral, (div(mul(mat, debt), price))); uint normalizeMaxCollateral = maxCollateral / (10 ** (18 - Join(_joinAddr).dec())); // take one percent due to precision issues return normalizeMaxCollateral * 99 / 100; } /// @notice Gets the maximum amount of debt available to generate /// @param _managerAddr Address of the CDP Manager /// @param _cdpId Id of the CDP /// @param _ilk Ilk of the CDP /// @dev Substracts 10 wei to aviod rounding error later on function getMaxDebt(address _managerAddr, uint _cdpId, bytes32 _ilk) public virtual view returns (uint) { uint price = getPrice(_ilk); (, uint mat) = spotter.ilks(_ilk); (uint collateral, uint debt) = getCdpInfo(Manager(_managerAddr), _cdpId, _ilk); return sub(sub(div(mul(collateral, price), mat), debt), 10); } /// @notice Gets a price of the asset /// @param _ilk Ilk of the CDP function getPrice(bytes32 _ilk) public view returns (uint) { (, uint mat) = spotter.ilks(_ilk); (,,uint spot,,) = vat.ilks(_ilk); return rmul(rmul(spot, spotter.par()), mat); } function isAutomation() internal view returns(bool) { return BotRegistry(BOT_REGISTRY_ADDRESS).botList(tx.origin); } function takeFee(uint256 _gasCost, uint _amount) internal returns(uint) { if (_gasCost > 0) { uint ethDaiPrice = getPrice(ETH_ILK); uint feeAmount = rmul(_gasCost, ethDaiPrice); if (feeAmount > _amount / 10) { feeAmount = _amount / 10; } ERC20(DAI_ADDRESS).transfer(WALLET_ID, feeAmount); return feeAmount; } return 0; } } interface IFlashLoanReceiver { function executeOperation(address _reserve, uint256 _amount, uint256 _fee, bytes calldata _params) external; } abstract contract ILendingPoolAddressesProvider { function getLendingPool() public view virtual returns (address); function setLendingPoolImpl(address _pool) public virtual; function getLendingPoolCore() public virtual view returns (address payable); function setLendingPoolCoreImpl(address _lendingPoolCore) public virtual; function getLendingPoolConfigurator() public virtual view returns (address); function setLendingPoolConfiguratorImpl(address _configurator) public virtual; function getLendingPoolDataProvider() public virtual view returns (address); function setLendingPoolDataProviderImpl(address _provider) public virtual; function getLendingPoolParametersProvider() public virtual view returns (address); function setLendingPoolParametersProviderImpl(address _parametersProvider) public virtual; function getTokenDistributor() public virtual view returns (address); function setTokenDistributor(address _tokenDistributor) public virtual; function getFeeProvider() public virtual view returns (address); function setFeeProviderImpl(address _feeProvider) public virtual; function getLendingPoolLiquidationManager() public virtual view returns (address); function setLendingPoolLiquidationManager(address _manager) public virtual; function getLendingPoolManager() public virtual view returns (address); function setLendingPoolManager(address _lendingPoolManager) public virtual; function getPriceOracle() public virtual view returns (address); function setPriceOracle(address _priceOracle) public virtual; function getLendingRateOracle() public view virtual returns (address); function setLendingRateOracle(address _lendingRateOracle) public virtual; } library EthAddressLib { function ethAddress() internal pure returns(address) { return 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; } } abstract contract FlashLoanReceiverBase is IFlashLoanReceiver { using SafeERC20 for ERC20; using SafeMath for uint256; ILendingPoolAddressesProvider public addressesProvider; constructor(ILendingPoolAddressesProvider _provider) public { addressesProvider = _provider; } receive () external virtual payable {} function transferFundsBackToPoolInternal(address _reserve, uint256 _amount) internal { address payable core = addressesProvider.getLendingPoolCore(); transferInternal(core,_reserve, _amount); } function transferInternal(address payable _destination, address _reserve, uint256 _amount) internal { if(_reserve == EthAddressLib.ethAddress()) { //solium-disable-next-line _destination.call{value: _amount}(""); return; } ERC20(_reserve).safeTransfer(_destination, _amount); } function getBalanceInternal(address _target, address _reserve) internal view returns(uint256) { if(_reserve == EthAddressLib.ethAddress()) { return _target.balance; } return ERC20(_reserve).balanceOf(_target); } } contract MCDSaverFlashLoan is MCDSaverProxy, AdminAuth, FlashLoanReceiverBase { ILendingPoolAddressesProvider public LENDING_POOL_ADDRESS_PROVIDER = ILendingPoolAddressesProvider(0x24a42fD28C976A61Df5D00D0599C34c4f90748c8); constructor() FlashLoanReceiverBase(LENDING_POOL_ADDRESS_PROVIDER) public {} struct SaverData { uint cdpId; uint gasCost; uint loanAmount; uint fee; address joinAddr; ManagerType managerType; } function executeOperation( address _reserve, uint256 _amount, uint256 _fee, bytes calldata _params) external override { //check the contract has the specified balance require(_amount <= getBalanceInternal(address(this), _reserve), "Invalid balance for the contract"); ( bytes memory exDataBytes, uint cdpId, uint gasCost, address joinAddr, bool isRepay, uint8 managerType ) = abi.decode(_params, (bytes,uint256,uint256,address,bool,uint8)); ExchangeData memory exchangeData = unpackExchangeData(exDataBytes); SaverData memory saverData = SaverData({ cdpId: cdpId, gasCost: gasCost, loanAmount: _amount, fee: _fee, joinAddr: joinAddr, managerType: ManagerType(managerType) }); if (isRepay) { repayWithLoan(exchangeData, saverData); } else { boostWithLoan(exchangeData, saverData); } transferFundsBackToPoolInternal(_reserve, _amount.add(_fee)); // if there is some eth left (0x fee), return it to user if (address(this).balance > 0) { tx.origin.transfer(address(this).balance); } } function boostWithLoan( ExchangeData memory _exchangeData, SaverData memory _saverData ) internal { address managerAddr = getManagerAddr(_saverData.managerType); address user = getOwner(Manager(managerAddr), _saverData.cdpId); // Draw users Dai uint maxDebt = getMaxDebt(managerAddr, _saverData.cdpId, Manager(managerAddr).ilks(_saverData.cdpId)); uint daiDrawn = drawDai(managerAddr, _saverData.cdpId, Manager(managerAddr).ilks(_saverData.cdpId), maxDebt); // Swap _exchangeData.srcAmount = daiDrawn + _saverData.loanAmount - takeFee(_saverData.gasCost, daiDrawn + _saverData.loanAmount); _exchangeData.user = user; _exchangeData.dfsFeeDivider = isAutomation() ? AUTOMATIC_SERVICE_FEE : MANUAL_SERVICE_FEE; (, uint swapedAmount) = _sell(_exchangeData); // Return collateral addCollateral(managerAddr, _saverData.cdpId, _saverData.joinAddr, swapedAmount); // Draw Dai to repay the flash loan drawDai(managerAddr, _saverData.cdpId, Manager(managerAddr).ilks(_saverData.cdpId), (_saverData.loanAmount + _saverData.fee)); logger.Log(address(this), msg.sender, "MCDFlashBoost", abi.encode(_saverData.cdpId, user, _exchangeData.srcAmount, swapedAmount)); } function repayWithLoan( ExchangeData memory _exchangeData, SaverData memory _saverData ) internal { address managerAddr = getManagerAddr(_saverData.managerType); address user = getOwner(Manager(managerAddr), _saverData.cdpId); bytes32 ilk = Manager(managerAddr).ilks(_saverData.cdpId); // Draw collateral uint maxColl = getMaxCollateral(managerAddr, _saverData.cdpId, ilk, _saverData.joinAddr); uint collDrawn = drawCollateral(managerAddr, _saverData.cdpId, _saverData.joinAddr, maxColl); // Swap _exchangeData.srcAmount = (_saverData.loanAmount + collDrawn); _exchangeData.user = user; _exchangeData.dfsFeeDivider = isAutomation() ? AUTOMATIC_SERVICE_FEE : MANUAL_SERVICE_FEE; (, uint paybackAmount) = _sell(_exchangeData); paybackAmount -= takeFee(_saverData.gasCost, paybackAmount); paybackAmount = limitLoanAmount(managerAddr, _saverData.cdpId, ilk, paybackAmount, user); // Payback the debt paybackDebt(managerAddr, _saverData.cdpId, ilk, paybackAmount, user); // Draw collateral to repay the flash loan drawCollateral(managerAddr, _saverData.cdpId, _saverData.joinAddr, (_saverData.loanAmount + _saverData.fee)); logger.Log(address(this), msg.sender, "MCDFlashRepay", abi.encode(_saverData.cdpId, user, _exchangeData.srcAmount, paybackAmount)); } /// @notice Handles that the amount is not bigger than cdp debt and not dust function limitLoanAmount(address _managerAddr, uint _cdpId, bytes32 _ilk, uint _paybackAmount, address _owner) internal returns (uint256) { uint debt = getAllDebt(address(vat), Manager(_managerAddr).urns(_cdpId), Manager(_managerAddr).urns(_cdpId), _ilk); if (_paybackAmount > debt) { ERC20(DAI_ADDRESS).transfer(_owner, (_paybackAmount - debt)); return debt; } uint debtLeft = debt - _paybackAmount; (,,,, uint dust) = vat.ilks(_ilk); dust = dust / 10**27; // Less than dust value if (debtLeft < dust) { uint amountOverDust = (dust - debtLeft); ERC20(DAI_ADDRESS).transfer(_owner, amountOverDust); return (_paybackAmount - amountOverDust); } return _paybackAmount; } receive() external override(FlashLoanReceiverBase, DFSExchangeCore) payable {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AUTOMATIC_SERVICE_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BOT_REGISTRY_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAI_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAI_JOIN_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DISCOUNT_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_DEST_AMOUNT_MISSING","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_NOT_ZEROX_EXCHANGE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_OFFCHAIN_DATA_INVALID","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_SLIPPAGE_HIT","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_WRAPPER_INVALID","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_ILK","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXCHANGE_WETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"JUG_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"KYBER_ETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LENDING_POOL_ADDRESS_PROVIDER","outputs":[{"internalType":"contract ILendingPoolAddressesProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANUAL_SERVICE_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SAVER_EXCHANGE_REGISTRY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SPOTTER_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VAT_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WALLET_ID","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ZRX_ALLOWLIST_ADDR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"addressesProvider","outputs":[{"internalType":"contract ILendingPoolAddressesProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"srcAddr","type":"address"},{"internalType":"address","name":"destAddr","type":"address"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"dfsFeeDivider","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"bytes","name":"wrapperData","type":"bytes"},{"components":[{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"address","name":"exchangeAddr","type":"address"},{"internalType":"address","name":"allowanceTarget","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct DFSExchangeData.OffchainData","name":"offchainData","type":"tuple"}],"internalType":"struct DFSExchangeData.ExchangeData","name":"_exchangeData","type":"tuple"},{"internalType":"uint256","name":"_cdpId","type":"uint256"},{"internalType":"uint256","name":"_gasCost","type":"uint256"},{"internalType":"address","name":"_joinAddr","type":"address"},{"internalType":"enum MCDSaverProxyHelper.ManagerType","name":"_managerType","type":"uint8"}],"name":"boost","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"daiJoin","outputs":[{"internalType":"contract DaiJoin","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_reserve","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"bytes","name":"_params","type":"bytes"}],"name":"executeOperation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Manager","name":"_manager","type":"address"},{"internalType":"uint256","name":"_cdpId","type":"uint256"},{"internalType":"bytes32","name":"_ilk","type":"bytes32"}],"name":"getCdpInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum MCDSaverProxyHelper.ManagerType","name":"_managerType","type":"uint8"}],"name":"getManagerAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_managerAddr","type":"address"},{"internalType":"uint256","name":"_cdpId","type":"uint256"},{"internalType":"bytes32","name":"_ilk","type":"bytes32"},{"internalType":"address","name":"_joinAddr","type":"address"}],"name":"getMaxCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_managerAddr","type":"address"},{"internalType":"uint256","name":"_cdpId","type":"uint256"},{"internalType":"bytes32","name":"_ilk","type":"bytes32"}],"name":"getMaxDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract Manager","name":"_manager","type":"address"},{"internalType":"uint256","name":"_cdpId","type":"uint256"}],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_ilk","type":"bytes32"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kill","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"logger","outputs":[{"internalType":"contract DefisaverLogger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"srcAddr","type":"address"},{"internalType":"address","name":"destAddr","type":"address"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"dfsFeeDivider","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"bytes","name":"wrapperData","type":"bytes"},{"components":[{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"address","name":"exchangeAddr","type":"address"},{"internalType":"address","name":"allowanceTarget","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct DFSExchangeData.OffchainData","name":"offchainData","type":"tuple"}],"internalType":"struct DFSExchangeData.ExchangeData","name":"_exData","type":"tuple"}],"name":"packExchangeData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"srcAddr","type":"address"},{"internalType":"address","name":"destAddr","type":"address"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"dfsFeeDivider","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"bytes","name":"wrapperData","type":"bytes"},{"components":[{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"address","name":"exchangeAddr","type":"address"},{"internalType":"address","name":"allowanceTarget","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct DFSExchangeData.OffchainData","name":"offchainData","type":"tuple"}],"internalType":"struct DFSExchangeData.ExchangeData","name":"_exchangeData","type":"tuple"},{"internalType":"uint256","name":"_cdpId","type":"uint256"},{"internalType":"uint256","name":"_gasCost","type":"uint256"},{"internalType":"address","name":"_joinAddr","type":"address"},{"internalType":"enum MCDSaverProxyHelper.ManagerType","name":"_managerType","type":"uint8"}],"name":"repay","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setAdminByAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setAdminByOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwnerByAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"spotter","outputs":[{"internalType":"contract Spotter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"unpackExchangeData","outputs":[{"components":[{"internalType":"address","name":"srcAddr","type":"address"},{"internalType":"address","name":"destAddr","type":"address"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"dfsFeeDivider","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"bytes","name":"wrapperData","type":"bytes"},{"components":[{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"address","name":"exchangeAddr","type":"address"},{"internalType":"address","name":"allowanceTarget","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct DFSExchangeData.OffchainData","name":"offchainData","type":"tuple"}],"internalType":"struct DFSExchangeData.ExchangeData","name":"_exData","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"vat","outputs":[{"internalType":"contract Vat","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawStuckFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6080604052600380546001600160a01b0319167324a42fd28c976a61df5d00d0599c34c4f90748c817905534801561003657600080fd5b50600354600080546001600160a01b031990811633179091556001805482167325efa336886c74ea8e282ac466bdcd0199f85bb9179055600280549091166001600160a01b0390921691909117905561527c806100946000396000f3fe60806040526004361061026b5760003560e01c80638c8a795811610144578063c7975824116100b6578063dd6d903c1161007a578063dd6d903c1461060f578063deca5f881461062f578063e870b9cd1461064f578063ee87255814610662578063f24ccbfe14610682578063f851a4401461069757610272565b8063c7975824146105d2578063cc694d48146105e5578063cf786f8f146103bc578063cfac57c714610593578063d3661fa5146105fa57610272565b8063a7304bf711610108578063a7304bf714610549578063acbeba6114610569578063ae08fd101461057e578063c11645bc14610593578063c50ebaf8146105a8578063c72c4d10146105bd57610272565b80638c8a7958146104c85780638da5cb5b146104dd57806398ab3d49146104f2578063a3b8e5d114610507578063a46a66c91461053457610272565b806336569e77116101dd5780634d2ab9dc116101a15780634d2ab9dc146104495780634d93667e1461045e578063526d64611461047e5780636738929f1461035257806381b94280146104935780638aa0fd0e146104a857610272565b806336569e77146103bc5780633a128322146103d15780634115fe6b146103f157806341c0e1b51461041f578063449b9ffa1461043457610272565b806329f7fc9e1161022f57806329f7fc9e1461031b5780632a4c0a1a1461033d5780632e77468d146103525780632f634a9014610367578063314b63321461038757806331d98b3f1461039c57610272565b806304c9805c1461027757806308d4f52a146102a2578063186cab76146102cf5780631e48907b146102e4578063278d58311461030657610272565b3661027257005b600080fd5b34801561028357600080fd5b5061028c6106ac565b6040516102999190614f84565b60405180910390f35b3480156102ae57600080fd5b506102c26102bd366004614a48565b6106b2565b6040516102999190614fd9565b3480156102db57600080fd5b5061028c6106dc565b3480156102f057600080fd5b506103046102ff366004614755565b6106e8565b005b34801561031257600080fd5b506102c2610721565b34801561032757600080fd5b50610330610749565b6040516102999190614db4565b34801561034957600080fd5b50610330610761565b34801561035e57600080fd5b50610330610779565b34801561037357600080fd5b506103306103823660046149fe565b610791565b34801561039357600080fd5b5061033061088d565b3480156103a857600080fd5b5061028c6103b736600461490f565b6108a5565b3480156103c857600080fd5b50610330610a63565b3480156103dd57600080fd5b506103046103ec36600461478d565b610a7b565b3480156103fd57600080fd5b5061041161040c3660046147b8565b610b14565b604051610299929190615197565b34801561042b57600080fd5b50610304610d30565b34801561044057600080fd5b506102c2610d55565b34801561045557600080fd5b5061028c610d87565b34801561046a57600080fd5b50610330610479366004614a2d565b610d8d565b34801561048a57600080fd5b50610330610dec565b34801561049f57600080fd5b50610330610e04565b3480156104b457600080fd5b5061028c6104c33660046147b8565b610e1c565b3480156104d457600080fd5b50610330610efd565b3480156104e957600080fd5b50610330610f15565b3480156104fe57600080fd5b50610330610f24565b34801561051357600080fd5b5061052761052236600461493f565b610f33565b60405161029991906150ff565b34801561054057600080fd5b50610330610f4f565b34801561055557600080fd5b50610304610564366004614755565b610f67565b34801561057557600080fd5b50610330610fa0565b34801561058a57600080fd5b506102c2610fb8565b34801561059f57600080fd5b50610330610fe9565b3480156105b457600080fd5b506102c2611001565b3480156105c957600080fd5b50610330611030565b6103046105e0366004614b83565b61103f565b3480156105f157600080fd5b506102c2611224565b34801561060657600080fd5b5061033061124f565b34801561061b57600080fd5b5061028c61062a3660046147ec565b611267565b34801561063b57600080fd5b5061030461064a366004614755565b6113cf565b61030461065d366004614b83565b6113fc565b34801561066e57600080fd5b5061030461067d366004614835565b6115d9565b34801561068e57600080fd5b506103306116fa565b3480156106a357600080fd5b50610330611712565b61014d81565b6060816040516020016106c591906150ff565b60405160208183030381529060405290505b919050565b644554482d4160d81b81565b6001546001600160a01b031633146106ff57600080fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b81525081565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b736b175474e89094c44da98b954eedeac495271d0f81565b7365c79fcb50ca1594b025960e539ed7a9a6d434a381565b600080836001600160a01b0316638161b120846040518263ffffffff1660e01b81526004016107c09190614f84565b60206040518083038186803b1580156107d857600080fd5b505afa1580156107ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108109190614771565b9050806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561084b57600080fd5b505afa15801561085f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108839190614771565b9150505b92915050565b7325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d81565b604051636cb1c69b60e11b815260009081907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906108e1908690600401614f84565b604080518083038186803b1580156108f857600080fd5b505afa15801561090c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109309190614a10565b604051636cb1c69b60e11b8152909250600091507335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063d9638d369061096e908790600401614f84565b60a06040518083038186803b15801561098657600080fd5b505afa15801561099a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109be9190614c19565b505092505050610a5b610a55827365c79fcb50ca1594b025960e539ed7a9a6d434a36001600160a01b031663495d32cb6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1857600080fd5b505afa158015610a2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a509190614927565b611721565b83611721565b949350505050565b7335d1b3f3d7966a1dfe207aa4514c12a259a0492b81565b6000546001600160a01b03163314610a9257600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b0383161415610af657600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015610af0573d6000803e3d6000fd5b50610b10565b600054610b10906001600160a01b03848116911683611760565b5050565b6000806000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5257600080fd5b505afa158015610b66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8a9190614771565b90506000866001600160a01b0316632726b073876040518263ffffffff1660e01b8152600401610bba9190614f84565b60206040518083038186803b158015610bd257600080fd5b505afa158015610be6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0a9190614771565b9050600080836001600160a01b0316632424be5c88856040518363ffffffff1660e01b8152600401610c3d929190614f8d565b604080518083038186803b158015610c5457600080fd5b505afa158015610c68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8c9190614bf6565b915091506000846001600160a01b031663d9638d36896040518263ffffffff1660e01b8152600401610cbe9190614f84565b60a06040518083038186803b158015610cd657600080fd5b505afa158015610cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0e9190614c19565b50505091505082610d1f8383611721565b965096505050505050935093915050565b6000546001600160a01b03163314610d4757600080fd5b6000546001600160a01b0316ff5b6040518060400160405280601681526020017516995c9bde08195e18da185b99d9481a5b9d985b1a5960521b81525081565b61019081565b600080826001811115610d9c57fe5b1415610dbd5750735ef30b9986345249bc32d8928b7ee64de9435e396106d7565b6001826001811115610dcb57fe5b14156106d75750733f30c2381cd8b917dd96eb2f1a4f96d91324bbed6106d7565b73637726f8b08a7abe3ae3acab01a80e2d8ddef77b81565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600080610e28836108a5565b604051636cb1c69b60e11b81529091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d3690610e65908790600401614f84565b604080518083038186803b158015610e7c57600080fd5b505afa158015610e90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb49190614a10565b915050600080610ec5888888610b14565b91509150610eef610ee8610ee2610edc85886117bb565b866117df565b836117ea565b600a6117ea565b9450505050505b9392505050565b734ba1f38427b33b8ab7bb0490200dae1f1c36823f81565b6000546001600160a01b031681565b6003546001600160a01b031681565b610f3b614374565b818060200190518101906108879190614a7b565b731b14e8d511c9a4395425314f849bd737baf8208f81565b6001546001600160a01b03163314610f7e57600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b7319c0976f590d67707e62397c87829d896dc0f1f181565b6040518060400160405280601581526020017413d99998da185a5b8819185d18481a5b9d985b1a59605a1b81525081565b739759a6ac90977b93b58547b4a71c78317f391a2881565b604051806040016040528060138152602001724465737420616d6f756e74206d697373696e6760681b81525081565b6002546001600160a01b031681565b600061104a82610d8d565b905060006110588287610791565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016110889190614f84565b60206040518083038186803b1580156110a057600080fd5b505afa1580156110b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d89190614927565b905060006110ec8489848c604001516117fa565b6001600160a01b03841660c08b01529050611105611c2a565b61111157610190611115565b61014d5b60a08a01526111248782611cb9565b810360408a015260006111368a611da7565b915050611145858a89846120ee565b47156111795760405132904780156108fc02916000818181858888f19350505050158015611177573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338c888f60400151876040516020016111b9949392919061515d565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016111e693929190614e33565b600060405180830381600087803b15801561120057600080fd5b505af1158015611214573d6000803e3d6000fd5b5050505050505050505050505050565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b81525081565b73322d58b9e75a6918f7e7849aee0ff09369977e0881565b600080611273846108a5565b9050600080611283888888610b14565b604051636cb1c69b60e11b815291935091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906112c2908a90600401614f84565b604080518083038186803b1580156112d957600080fd5b505afa1580156112ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113119190614a10565b91505060006113328461132d61132785876117bb565b886117df565b6117ea565b90506000876001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561136f57600080fd5b505afa158015611383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a79190614927565b601203600a0a82816113b557fe5b049050606460638202049650505050505050949350505050565b6000546001600160a01b031633146113e657600080fd5b6001546001600160a01b031615610f7e57600080fd5b600061140782610d8d565b905060006114158287610791565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016114459190614f84565b60206040518083038186803b15801561145d57600080fd5b505afa158015611471573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114959190614927565b90506114a78388878b60400151612440565b506001600160a01b03821660c08901526114bf611c2a565b6114cb576101906114cf565b61014d5b60a089015260006114df89611da7565b9150506114ec8782611cb9565b90036114fb8489848487612751565b471561152f5760405132904780156108fc02916000818181858888f1935050505015801561152d573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338b878e604001518760405160200161156f949392919061515d565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161159c93929190614ed0565b600060405180830381600087803b1580156115b657600080fd5b505af11580156115ca573d6000803e3d6000fd5b50505050505050505050505050565b6115e33086612ad0565b84111561160b5760405162461bcd60e51b815260040161160290615023565b60405180910390fd5b606060008080808061161f87890189614972565b955095509550955095509550611633614374565b61163c87610f33565b90506116466143f0565b6040518060c001604052808881526020018781526020018d81526020018c8152602001866001600160a01b031681526020018460ff16600181111561168757fe5b600181111561169257fe5b9052905083156116ab576116a68282612b80565b6116b5565b6116b58282612d9c565b6116c88d6116c38e8e613051565b613076565b47156115ca5760405132904780156108fc02916000818181858888f19350505050158015611214573d6000803e3d6000fd5b735c55b921f590a89c1ebe84df170e655a82b6212681565b6001546001600160a01b031681565b6000676765c793fa10079d601b1b61175161173c85856117bb565b6002676765c793fa10079d601b1b5b04613100565b8161175857fe5b049392505050565b6117b68363a9059cbb60e01b848460405160240161177f929190614f1c565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613110565b505050565b60008115806117d6575050808202828282816117d357fe5b04145b61088757600080fd5b600081838161175857fe5b8082038281111561088757600080fd5b60405163089c54b560e31b815260009081907319c0976f590d67707e62397c87829d896dc0f1f1906344e2a5a890611836908790600401614f84565b602060405180830381600087803b15801561185057600080fd5b505af1158015611864573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118889190614927565b905060007335d1b3f3d7966a1dfe207aa4514c12a259a0492b6001600160a01b0316636c25b346886001600160a01b0316632726b073896040518263ffffffff1660e01b81526004016118db9190614f84565b60206040518083038186803b1580156118f357600080fd5b505afa158015611907573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192b9190614771565b6040518263ffffffff1660e01b81526004016119479190614db4565b60206040518083038186803b15801561195f57600080fd5b505afa158015611973573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119979190614927565b905060006119a6888888610e1c565b90508085106119bd576119ba8160016117ea565b94505b876001600160a01b03166345e6bdcd8860006119da89888861319f565b6040518463ffffffff1660e01b81526004016119f893929190615181565b600060405180830381600087803b158015611a1257600080fd5b505af1158015611a26573d6000803e3d6000fd5b50505050876001600160a01b031663f9f30db68830611a4489613222565b6040518463ffffffff1660e01b8152600401611a629392919061513e565b600060405180830381600087803b158015611a7c57600080fd5b505af1158015611a90573d6000803e3d6000fd5b5050604051634538c4eb60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250634538c4eb9150611ae1903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614dc8565b60206040518083038186803b158015611af957600080fd5b505afa158015611b0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b319190614927565b611bb3576040516328ec8bf160e21b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063a3b22fc490611b8090739759a6ac90977b93b58547b4a71c78317f391a2890600401614db4565b600060405180830381600087803b158015611b9a57600080fd5b505af1158015611bae573d6000803e3d6000fd5b505050505b60405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a289063ef693bed90611bec9030908990600401614f1c565b600060405180830381600087803b158015611c0657600080fd5b505af1158015611c1a573d6000803e3d6000fd5b50969a9950505050505050505050565b6040516320eb73ed60e11b815260009073637726f8b08a7abe3ae3acab01a80e2d8ddef77b906341d6e7da90611c64903290600401614db4565b60206040518083038186803b158015611c7c57600080fd5b505afa158015611c90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb491906148c6565b905090565b60008215611d9e576000611cd4644554482d4160d81b6108a5565b90506000611ce28583611721565b9050600a8404811115611cf55750600a83045b60405163a9059cbb60e01b8152736b175474e89094c44da98b954eedeac495271d0f9063a9059cbb90611d429073322d58b9e75a6918f7e7849aee0ff09369977e08908590600401614f1c565b602060405180830381600087803b158015611d5c57600080fd5b505af1158015611d70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9491906148c6565b5091506108879050565b50600092915050565b600080600080600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b031686600001516001600160a01b03161415611e62578551611dec90613239565b6001600160a01b031686526040808701518151630d0e30db60e41b8152915173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29263d0e30db09291600480830192600092919082900301818588803b158015611e4857600080fd5b505af1158015611e5c573d6000803e3d6000fd5b50505050505b611e7e86604001518760c0015188600001518960a00151613280565b6040870180519190910390526101208601516060015115611ebb57611ea4866000613460565b925090508015611ebb578561012001516020015192505b80611ed557611ecb86600061365e565b91508560e0015192505b6000611ef473c02aaa39b223fe8d0a0e5c4f27ead9083c756cc261387c565b1115611fda576040516370a0823160e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d9082906370a0823190611f39903090600401614db4565b602060405180830381600087803b158015611f5357600080fd5b505af1158015611f67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f8b9190614927565b6040518263ffffffff1660e01b8152600401611fa79190614f84565b600060405180830381600087803b158015611fc157600080fd5b505af1158015611fd5573d6000803e3d6000fd5b505050505b60208601516001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2141561207d5761201586608001518760400151613926565b61203273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee61387c565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906120775760405162461bcd60e51b81526004016116029190614fd9565b506120e3565b61208f86608001518760400151613926565b61209c876020015161387c565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906120e15760405162461bcd60e51b81526004016116029190614fd9565b505b509092509050915091565b60006120f98361394e565b156121d257826001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561213757600080fd5b505afa15801561214b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216f9190614771565b6001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b1580156121a957600080fd5b505af11580156121bd573d6000803e3d6000fd5b50505050506121cb82613a2b565b90506121e7565b6121e46121df8484613a4d565b613a2b565b90505b61226d8383856001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561222557600080fd5b505afa158015612239573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225d9190614771565b6001600160a01b03169190613acf565b604051633b4da69f60e01b81526001600160a01b03841690633b4da69f9061229b9030908690600401614f1c565b600060405180830381600087803b1580156122b557600080fd5b505af11580156122c9573d6000803e3d6000fd5b5050604051632c2cb9fd60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250637608870391506001600160a01b03881690632c2cb9fd90612315908990600401614f84565b60206040518083038186803b15801561232d57600080fd5b505afa158015612341573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123659190614927565b604051632726b07360e01b81526001600160a01b03891690632726b07390612391908a90600401614f84565b60206040518083038186803b1580156123a957600080fd5b505afa1580156123bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e19190614771565b30308660006040518763ffffffff1660e01b815260040161240796959493929190614fa4565b600060405180830381600087803b15801561242157600080fd5b505af1158015612435573d6000803e3d6000fd5b505050505050505050565b600080829050836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561247f57600080fd5b505afa158015612493573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124b79190614927565b60121461253a57836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b1580156124f757600080fd5b505afa15801561250b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061252f9190614927565b601203600a0a830290505b856001600160a01b03166345e6bdcd8661255384613a2b565b60000360006040518463ffffffff1660e01b815260040161257693929190615181565b600060405180830381600087803b15801561259057600080fd5b505af11580156125a4573d6000803e3d6000fd5b50506040516313771f0760e31b81526001600160a01b0389169250639bb8f83891506125d89088903090869060040161513e565b600060405180830381600087803b1580156125f257600080fd5b505af1158015612606573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038716925063ef693bed91506126389030908790600401614f1c565b600060405180830381600087803b15801561265257600080fd5b505af1158015612666573d6000803e3d6000fd5b505050506126738461394e565b1561274757836001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b1580156126b157600080fd5b505afa1580156126c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e99190614771565b6001600160a01b0316632e1a7d4d846040518263ffffffff1660e01b81526004016127149190614f84565b600060405180830381600087803b15801561272e57600080fd5b505af1158015612742573d6000803e3d6000fd5b505050505b5090949350505050565b604051632726b07360e01b81526000906001600160a01b03871690632726b07390612780908890600401614f84565b60206040518083038186803b15801561279857600080fd5b505afa1580156127ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d09190614771565b905060006127f47335d1b3f3d7966a1dfe207aa4514c12a259a0492b838488613b0e565b90508084111561289757736b175474e89094c44da98b954eedeac495271d0f63a9059cbb8461282387856117ea565b6040518363ffffffff1660e01b8152600401612840929190614f1c565b602060405180830381600087803b15801561285a57600080fd5b505af115801561286e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061289291906148c6565b508093505b604051636eb1769f60e11b8152736b175474e89094c44da98b954eedeac495271d0f9063dd62ed3e906128e4903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614dc8565b60206040518083038186803b1580156128fc57600080fd5b505afa158015612910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129349190614927565b6129db5760405163095ea7b360e01b8152736b175474e89094c44da98b954eedeac495271d0f9063095ea7b39061298790739759a6ac90977b93b58547b4a71c78317f391a289060001990600401614f1c565b602060405180830381600087803b1580156129a157600080fd5b505af11580156129b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129d991906148c6565b505b604051633b4da69f60e01b8152739759a6ac90977b93b58547b4a71c78317f391a2890633b4da69f90612a149085908890600401614f1c565b600060405180830381600087803b158015612a2e57600080fd5b505af1158015612a42573d6000803e3d6000fd5b50505050866001600160a01b03166345e6bdcd876000612a777335d1b3f3d7966a1dfe207aa4514c12a259a0492b878b613ce9565b6040518463ffffffff1660e01b8152600401612a9593929190615181565b600060405180830381600087803b158015612aaf57600080fd5b505af1158015612ac3573d6000803e3d6000fd5b5050505050505050505050565b6000612ada613ea7565b6001600160a01b0316826001600160a01b03161415612b0457506001600160a01b03821631610887565b6040516370a0823160e01b81526001600160a01b038316906370a0823190612b30908690600401614db4565b60206040518083038186803b158015612b4857600080fd5b505afa158015612b5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef69190614927565b6000612b8f8260a00151610d8d565b90506000612ba1828460000151610791565b8351604051632c2cb9fd60e01b81529192506000916001600160a01b03851691632c2cb9fd91612bd49190600401614f84565b60206040518083038186803b158015612bec57600080fd5b505afa158015612c00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c249190614927565b90506000612c3c848660000151848860800151611267565b90506000612c54858760000151886080015185612440565b6040808801518201908901526001600160a01b03851660c08901529050612c79611c2a565b612c8557610190612c89565b61014d5b60a08801526000612c9988611da7565b915050612caa876020015182611cb9565b8751910390612cbd908790868489613ebf565b9050612cd0868860000151868489612751565b612cee86886000015189608001518a606001518b6040015101612440565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338a60000151898d6040015187604051602001612d33949392919061515d565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612d6093929190614e7f565b600060405180830381600087803b158015612d7a57600080fd5b505af1158015612d8e573d6000803e3d6000fd5b505050505050505050505050565b6000612dab8260a00151610d8d565b90506000612dbd828460000151610791565b8351604051632c2cb9fd60e01b8152919250600091612e479185916001600160a01b03831690632c2cb9fd90612df7908490600401614f84565b60206040518083038186803b158015612e0f57600080fd5b505afa158015612e23573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c39190614927565b8451604051632c2cb9fd60e01b8152919250600091612ed79186916001600160a01b03831690632c2cb9fd90612e81908490600401614f84565b60206040518083038186803b158015612e9957600080fd5b505afa158015612ead573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ed19190614927565b856117fa565b9050612eed856020015186604001518301611cb9565b604080870151830191909103908701526001600160a01b03831660c0870152612f14611c2a565b612f2057610190612f24565b61014d5b60a08701526000612f3487611da7565b915050612f4b8587600001518860800151846120ee565b8551604051632c2cb9fd60e01b8152612fdf9187916001600160a01b03831690632c2cb9fd90612f7f908490600401614f84565b60206040518083038186803b158015612f9757600080fd5b505afa158015612fab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fcf9190614927565b89606001518a60400151016117fa565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338960000151888c6040015187604051602001613024949392919061515d565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612a9593929190614de2565b600082820183811015610ef65760405162461bcd60e51b815260040161160290614fec565b6002546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b1580156130bb57600080fd5b505afa1580156130cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130f39190614771565b90506117b68184846141d7565b8082018281101561088757600080fd5b6060613165826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661426d9092919063ffffffff16565b8051909150156117b6578080602001905181019061318391906148c6565b6117b65760405162461bcd60e51b81526004016116029061508f565b60006131b684676765c793fa10079d601b1b6117bb565b821015610ef6576131ec836131df6131d987676765c793fa10079d601b1b6117bb565b856117ea565b816131e657fe5b04613a2b565b905061320384676765c793fa10079d601b1b6117bb565b61320d82856117bb565b106132185780610a5b565b6001019392505050565b600061088782676765c793fa10079d601b1b6117bb565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146132655781610887565b5073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2919050565b600081158015906133135750604051632cdc77ab60e21b8152731b14e8d511c9a4395425314f849bd737baf8208f9063b371deac906132c3908790600401614db4565b60206040518083038186803b1580156132db57600080fd5b505afa1580156132ef573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061331391906148c6565b156133a257604051636eeb543160e01b8152731b14e8d511c9a4395425314f849bd737baf8208f90636eeb54319061334f908790600401614db4565b60206040518083038186803b15801561336757600080fd5b505afa15801561337b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061339f9190614927565b91505b816133af57506000610a5b565b8185816133b857fe5b049050600a85048111156133cc5750600a84045b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156134385760405173322d58b9e75a6918f7e7849aee0ff09369977e089082156108fc029083906000818181858888f19350505050158015613432573d6000803e3d6000fd5b50610a5b565b610a5b6001600160a01b03841673322d58b9e75a6918f7e7849aee0ff09369977e0883611760565b610120820151602001516040516302f5cc7960e11b81526000918291734ba1f38427b33b8ab7bb0490200dae1f1c36823f916305eb98f2916134a59190600401614db4565b60206040518083038186803b1580156134bd57600080fd5b505afa1580156134d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134f591906148c6565b61350457506000905080613657565b6101208401515160405163e0aa279760e01b81527325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa2797916135419190600401614db4565b60206040518083038186803b15801561355957600080fd5b505afa15801561356d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061359191906148c6565b6135a057506000905080613657565b61012084015151604085015185516135c3926001600160a01b0390911691611760565b610120840151805160809091015160405163097396a160e31b81526001600160a01b0390921691634b9cb50891906136019088908890600401615112565b60408051808303818588803b15801561361957600080fd5b505af115801561362d573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061365291906148e2565b915091505b9250929050565b60e082015160405163e0aa279760e01b81526000917325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa27979161369b91600401614db4565b60206040518083038186803b1580156136b357600080fd5b505afa1580156136c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136eb91906148c6565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b815250906137315760405162461bcd60e51b81526004016116029190614fd9565b5060e083015160408401518451613753926001600160a01b0390911691611760565b600082600181111561376157fe5b1415613807578260e001516001600160a01b0316635b6f36fc8460000151856020015186604001518761010001516040518563ffffffff1660e01b81526004016137ae9493929190614f35565b602060405180830381600087803b1580156137c857600080fd5b505af11580156137dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138009190614927565b9050610887565b8260e001516001600160a01b0316633924db668460000151856020015186606001518761010001516040518563ffffffff1660e01b815260040161384e9493929190614f35565b602060405180830381600087803b15801561386857600080fd5b505af1158015612b5c573d6000803e3d6000fd5b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156138aa5750476106d7565b6040516370a0823160e01b81526001600160a01b038316906370a08231906138d6903090600401614db4565b60206040518083038186803b1580156138ee57600080fd5b505afa158015613902573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108879190614927565b6000670de0b6b3a764000061175161393e85856117bb565b6002670de0b6b3a764000061174b565b6000739759a6ac90977b93b58547b4a71c78317f391a286001600160a01b038316141561397d575060006106d7565b816001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b1580156139b657600080fd5b505afa1580156139ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139ee9190614771565b6001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03161415613a23575060016106d7565b506000919050565b8060008112156106d75760405162461bcd60e51b8152600401611602906150d9565b6000610ef682846001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b158015613a8c57600080fd5b505afa158015613aa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ac49190614927565b601203600a0a6117bb565b613aef8363095ea7b360e01b84600060405160240161177f929190614f68565b6117b68363095ea7b360e01b848460405160240161177f929190614f1c565b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b8152600401613b3d9190614f84565b60a06040518083038186803b158015613b5557600080fd5b505afa158015613b69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b8d9190614c19565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b8152600401613bc3929190614f8d565b604080518083038186803b158015613bda57600080fd5b505afa158015613bee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c129190614bf6565b9150506000876001600160a01b0316636c25b346886040518263ffffffff1660e01b8152600401613c439190614db4565b60206040518083038186803b158015613c5b57600080fd5b505afa158015613c6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c939190614927565b90506000613ca4610ee284866117bb565b9050676765c793fa10079d601b1b8104945080613ccc86676765c793fa10079d601b1b6117bb565b10613cd75784613cdc565b846001015b9998505050505050505050565b600080846001600160a01b0316636c25b346856040518263ffffffff1660e01b8152600401613d189190614db4565b60206040518083038186803b158015613d3057600080fd5b505afa158015613d44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d689190614927565b90506000856001600160a01b031663d9638d36856040518263ffffffff1660e01b8152600401613d989190614f84565b60a06040518083038186803b158015613db057600080fd5b505afa158015613dc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613de89190614c19565b5050509150506000866001600160a01b0316632424be5c86886040518363ffffffff1660e01b8152600401613e1e929190614f8d565b604080518083038186803b158015613e3557600080fd5b505afa158015613e49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e6d9190614bf6565b915050613e7c8284816131e657fe5b935080841115613e9757613e8f81613a2b565b600003613e9c565b836000035b979650505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b600080613fd87335d1b3f3d7966a1dfe207aa4514c12a259a0492b886001600160a01b0316632726b073896040518263ffffffff1660e01b8152600401613f069190614f84565b60206040518083038186803b158015613f1e57600080fd5b505afa158015613f32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f569190614771565b604051632726b07360e01b81526001600160a01b038b1690632726b07390613f82908c90600401614f84565b60206040518083038186803b158015613f9a57600080fd5b505afa158015613fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fd29190614771565b88613b0e565b9050808411156140775760405163a9059cbb60e01b8152736b175474e89094c44da98b954eedeac495271d0f9063a9059cbb9061401d90869085890390600401614f1c565b602060405180830381600087803b15801561403757600080fd5b505af115801561404b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061406f91906148c6565b5090506141ce565b604051636cb1c69b60e11b8152848203906000907335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063d9638d36906140b5908a90600401614f84565b60a06040518083038186803b1580156140cd57600080fd5b505afa1580156140e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141059190614c19565b945050505050676765c793fa10079d601b1b818161411f57fe5b049050808210156141c75760405163a9059cbb60e01b815282820390736b175474e89094c44da98b954eedeac495271d0f9063a9059cbb906141679089908590600401614f1c565b602060405180830381600087803b15801561418157600080fd5b505af1158015614195573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141b991906148c6565b50860393506141ce92505050565b8593505050505b95945050505050565b6141df613ea7565b6001600160a01b0316826001600160a01b0316141561425957826001600160a01b03168160405161420f90614db1565b60006040518083038185875af1925050503d806000811461424c576040519150601f19603f3d011682016040523d82523d6000602084013e614251565b606091505b5050506117b6565b6117b66001600160a01b0383168483611760565b6060610a5b848460008560606142828561433b565b61429e5760405162461bcd60e51b815260040161160290615058565b60006060866001600160a01b031685876040516142bb9190614d95565b60006040518083038185875af1925050503d80600081146142f8576040519150601f19603f3d011682016040523d82523d6000602084013e6142fd565b606091505b50915091508115614311579150610a5b9050565b8051156143215780518082602001fd5b8360405162461bcd60e51b81526004016116029190614fd9565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610a5b575050151592915050565b60405180610140016040528060006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016143eb614434565b905290565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b03168152602001600060018111156143eb57fe5b6040518060c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001606081525090565b803561088781615220565b805161088781615220565b600082601f8301126144ab578081fd5b81356144be6144b9826151cc565b6151a5565b91508082528360208285010111156144d557600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126144fe578081fd5b815161450c6144b9826151cc565b915080825283602082850101111561452357600080fd5b6145348160208401602086016151f0565b5092915050565b80356002811061088757600080fd5b600061014080838503121561455d578182fd5b614566816151a5565b9150506145738383614485565b81526145828360208401614485565b602082015260408201356040820152606082013560608201526080820135608082015260a082013560a08201526145bc8360c08401614485565b60c08201526145ce8360e08401614485565b60e08201526101008083013567ffffffffffffffff808211156145f057600080fd5b6145fc8683870161449b565b8385015261012092508285013591508082111561461857600080fd5b5061462585828601614631565b82840152505092915050565b600060c08284031215614642578081fd5b61464c60c06151a5565b9050813561465981615220565b8152602082013561466981615220565b6020820152604082013561467c81615220565b80604083015250606082013560608201526080820135608082015260a082013567ffffffffffffffff8111156146b157600080fd5b6146bd8482850161449b565b60a08301525092915050565b600060c082840312156146da578081fd5b6146e460c06151a5565b905081516146f181615220565b8152602082015161470181615220565b6020820152604082015161471481615220565b80604083015250606082015160608201526080820151608082015260a082015167ffffffffffffffff81111561474957600080fd5b6146bd848285016144ee565b600060208284031215614766578081fd5b8135610ef681615220565b600060208284031215614782578081fd5b8151610ef681615220565b6000806040838503121561479f578081fd5b82356147aa81615220565b946020939093013593505050565b6000806000606084860312156147cc578081fd5b83356147d781615220565b95602085013595506040909401359392505050565b60008060008060808587031215614801578182fd5b843561480c81615220565b93506020850135925060408501359150606085013561482a81615220565b939692955090935050565b60008060008060006080868803121561484c578283fd5b853561485781615220565b94506020860135935060408601359250606086013567ffffffffffffffff80821115614881578283fd5b818801915088601f830112614894578283fd5b8135818111156148a2578384fd5b8960208285010111156148b3578384fd5b9699959850939650602001949392505050565b6000602082840312156148d7578081fd5b8151610ef681615238565b600080604083850312156148f4578182fd5b82516148ff81615238565b6020939093015192949293505050565b600060208284031215614920578081fd5b5035919050565b600060208284031215614938578081fd5b5051919050565b600060208284031215614950578081fd5b813567ffffffffffffffff811115614966578182fd5b6108838482850161449b565b60008060008060008060c0878903121561498a578384fd5b863567ffffffffffffffff8111156149a0578485fd5b6149ac89828a0161449b565b965050602087013594506040870135935060608701356149cb81615220565b925060808701356149db81615238565b915060a087013560ff811681146149f0578182fd5b809150509295509295509295565b6000806040838503121561479f578182fd5b60008060408385031215614a22578182fd5b82516148ff81615220565b600060208284031215614a3e578081fd5b610ef6838361453b565b600060208284031215614a59578081fd5b813567ffffffffffffffff811115614a6f578182fd5b6108838482850161454a565b600060208284031215614a8c578081fd5b815167ffffffffffffffff80821115614aa3578283fd5b8184019150610140808387031215614ab9578384fd5b614ac2816151a5565b9050614ace8684614490565b8152614add8660208501614490565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a0820152614b178660c08501614490565b60c0820152614b298660e08501614490565b60e08201526101008084015183811115614b41578586fd5b614b4d888287016144ee565b8284015250506101208084015183811115614b66578586fd5b614b72888287016146c9565b918301919091525095945050505050565b600080600080600060a08688031215614b9a578283fd5b853567ffffffffffffffff811115614bb0578384fd5b614bbc8882890161454a565b95505060208601359350604086013592506060860135614bdb81615220565b9150614bea876080880161453b565b90509295509295909350565b60008060408385031215614c08578182fd5b505080516020909101519092909150565b600080600080600060a08688031215614c30578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b6001600160a01b03169052565b60008151808452614c7d8160208601602086016151f0565b601f01601f19169290920160200192915050565b6000610140614ca1848451614c58565b6020830151614cb36020860182614c58565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c0830151614cee60c0860182614c58565b5060e0830151614d0160e0860182614c58565b50610100808401518282870152614d1a83870182614c65565b925050506101208084015185830382870152614d368382614d40565b9695505050505050565b600060018060a01b0380835116845280602084015116602085015280604084015116604085015250606082015160608401526080820151608084015260a082015160c060a085015261088360c0850182614c65565b60008251614da78184602087016151f0565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c1350d1119b185cda109bdbdcdd609a1b60a082015260c0606082018190526000906141ce90830184614c65565b6001600160a01b03848116825283166020820152608060408201819052600890820152671350d1109bdbdcdd60c21b60a082015260c0606082018190526000906141ce90830184614c65565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c4d4344466c617368526570617960981b60a082015260c0606082018190526000906141ce90830184614c65565b6001600160a01b03848116825283166020820152608060408201819052600890820152674d4344526570617960c01b60a082015260c0606082018190526000906141ce90830184614c65565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614d3690830184614c65565b6001600160a01b0392909216825260ff16602082015260400190565b90815260200190565b9182526001600160a01b0316602082015260400190565b9586526001600160a01b039485166020870152928416604086015292166060840152608083019190915260a082015260c00190565b600060208252610ef66020830184614c65565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252818101527f496e76616c69642062616c616e636520666f722074686520636f6e7472616374604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600c908201526b696e742d6f766572666c6f7760a01b604082015260600190565b600060208252610ef66020830184614c91565b6000604082526151256040830185614c91565b90506002831061513157fe5b8260208301529392505050565b9283526001600160a01b03919091166020830152604082015260600190565b9384526001600160a01b039290921660208401526040830152606082015260800190565b9283526020830191909152604082015260600190565b918252602082015260400190565b60405181810167ffffffffffffffff811182821017156151c457600080fd5b604052919050565b600067ffffffffffffffff8211156151e2578081fd5b50601f01601f191660200190565b60005b8381101561520b5781810151838201526020016151f3565b8381111561521a576000848401525b50505050565b6001600160a01b038116811461523557600080fd5b50565b801515811461523557600080fdfea26469706673582212202a64c0bc4977d4738d4f864eddff328283240776b6a144389bd7025a6527453964736f6c634300060c0033
Deployed Bytecode
0x60806040526004361061026b5760003560e01c80638c8a795811610144578063c7975824116100b6578063dd6d903c1161007a578063dd6d903c1461060f578063deca5f881461062f578063e870b9cd1461064f578063ee87255814610662578063f24ccbfe14610682578063f851a4401461069757610272565b8063c7975824146105d2578063cc694d48146105e5578063cf786f8f146103bc578063cfac57c714610593578063d3661fa5146105fa57610272565b8063a7304bf711610108578063a7304bf714610549578063acbeba6114610569578063ae08fd101461057e578063c11645bc14610593578063c50ebaf8146105a8578063c72c4d10146105bd57610272565b80638c8a7958146104c85780638da5cb5b146104dd57806398ab3d49146104f2578063a3b8e5d114610507578063a46a66c91461053457610272565b806336569e77116101dd5780634d2ab9dc116101a15780634d2ab9dc146104495780634d93667e1461045e578063526d64611461047e5780636738929f1461035257806381b94280146104935780638aa0fd0e146104a857610272565b806336569e77146103bc5780633a128322146103d15780634115fe6b146103f157806341c0e1b51461041f578063449b9ffa1461043457610272565b806329f7fc9e1161022f57806329f7fc9e1461031b5780632a4c0a1a1461033d5780632e77468d146103525780632f634a9014610367578063314b63321461038757806331d98b3f1461039c57610272565b806304c9805c1461027757806308d4f52a146102a2578063186cab76146102cf5780631e48907b146102e4578063278d58311461030657610272565b3661027257005b600080fd5b34801561028357600080fd5b5061028c6106ac565b6040516102999190614f84565b60405180910390f35b3480156102ae57600080fd5b506102c26102bd366004614a48565b6106b2565b6040516102999190614fd9565b3480156102db57600080fd5b5061028c6106dc565b3480156102f057600080fd5b506103046102ff366004614755565b6106e8565b005b34801561031257600080fd5b506102c2610721565b34801561032757600080fd5b50610330610749565b6040516102999190614db4565b34801561034957600080fd5b50610330610761565b34801561035e57600080fd5b50610330610779565b34801561037357600080fd5b506103306103823660046149fe565b610791565b34801561039357600080fd5b5061033061088d565b3480156103a857600080fd5b5061028c6103b736600461490f565b6108a5565b3480156103c857600080fd5b50610330610a63565b3480156103dd57600080fd5b506103046103ec36600461478d565b610a7b565b3480156103fd57600080fd5b5061041161040c3660046147b8565b610b14565b604051610299929190615197565b34801561042b57600080fd5b50610304610d30565b34801561044057600080fd5b506102c2610d55565b34801561045557600080fd5b5061028c610d87565b34801561046a57600080fd5b50610330610479366004614a2d565b610d8d565b34801561048a57600080fd5b50610330610dec565b34801561049f57600080fd5b50610330610e04565b3480156104b457600080fd5b5061028c6104c33660046147b8565b610e1c565b3480156104d457600080fd5b50610330610efd565b3480156104e957600080fd5b50610330610f15565b3480156104fe57600080fd5b50610330610f24565b34801561051357600080fd5b5061052761052236600461493f565b610f33565b60405161029991906150ff565b34801561054057600080fd5b50610330610f4f565b34801561055557600080fd5b50610304610564366004614755565b610f67565b34801561057557600080fd5b50610330610fa0565b34801561058a57600080fd5b506102c2610fb8565b34801561059f57600080fd5b50610330610fe9565b3480156105b457600080fd5b506102c2611001565b3480156105c957600080fd5b50610330611030565b6103046105e0366004614b83565b61103f565b3480156105f157600080fd5b506102c2611224565b34801561060657600080fd5b5061033061124f565b34801561061b57600080fd5b5061028c61062a3660046147ec565b611267565b34801561063b57600080fd5b5061030461064a366004614755565b6113cf565b61030461065d366004614b83565b6113fc565b34801561066e57600080fd5b5061030461067d366004614835565b6115d9565b34801561068e57600080fd5b506103306116fa565b3480156106a357600080fd5b50610330611712565b61014d81565b6060816040516020016106c591906150ff565b60405160208183030381529060405290505b919050565b644554482d4160d81b81565b6001546001600160a01b031633146106ff57600080fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b81525081565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b736b175474e89094c44da98b954eedeac495271d0f81565b7365c79fcb50ca1594b025960e539ed7a9a6d434a381565b600080836001600160a01b0316638161b120846040518263ffffffff1660e01b81526004016107c09190614f84565b60206040518083038186803b1580156107d857600080fd5b505afa1580156107ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108109190614771565b9050806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561084b57600080fd5b505afa15801561085f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108839190614771565b9150505b92915050565b7325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d81565b604051636cb1c69b60e11b815260009081907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906108e1908690600401614f84565b604080518083038186803b1580156108f857600080fd5b505afa15801561090c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109309190614a10565b604051636cb1c69b60e11b8152909250600091507335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063d9638d369061096e908790600401614f84565b60a06040518083038186803b15801561098657600080fd5b505afa15801561099a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109be9190614c19565b505092505050610a5b610a55827365c79fcb50ca1594b025960e539ed7a9a6d434a36001600160a01b031663495d32cb6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1857600080fd5b505afa158015610a2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a509190614927565b611721565b83611721565b949350505050565b7335d1b3f3d7966a1dfe207aa4514c12a259a0492b81565b6000546001600160a01b03163314610a9257600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b0383161415610af657600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015610af0573d6000803e3d6000fd5b50610b10565b600054610b10906001600160a01b03848116911683611760565b5050565b6000806000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5257600080fd5b505afa158015610b66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8a9190614771565b90506000866001600160a01b0316632726b073876040518263ffffffff1660e01b8152600401610bba9190614f84565b60206040518083038186803b158015610bd257600080fd5b505afa158015610be6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0a9190614771565b9050600080836001600160a01b0316632424be5c88856040518363ffffffff1660e01b8152600401610c3d929190614f8d565b604080518083038186803b158015610c5457600080fd5b505afa158015610c68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8c9190614bf6565b915091506000846001600160a01b031663d9638d36896040518263ffffffff1660e01b8152600401610cbe9190614f84565b60a06040518083038186803b158015610cd657600080fd5b505afa158015610cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0e9190614c19565b50505091505082610d1f8383611721565b965096505050505050935093915050565b6000546001600160a01b03163314610d4757600080fd5b6000546001600160a01b0316ff5b6040518060400160405280601681526020017516995c9bde08195e18da185b99d9481a5b9d985b1a5960521b81525081565b61019081565b600080826001811115610d9c57fe5b1415610dbd5750735ef30b9986345249bc32d8928b7ee64de9435e396106d7565b6001826001811115610dcb57fe5b14156106d75750733f30c2381cd8b917dd96eb2f1a4f96d91324bbed6106d7565b73637726f8b08a7abe3ae3acab01a80e2d8ddef77b81565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600080610e28836108a5565b604051636cb1c69b60e11b81529091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d3690610e65908790600401614f84565b604080518083038186803b158015610e7c57600080fd5b505afa158015610e90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb49190614a10565b915050600080610ec5888888610b14565b91509150610eef610ee8610ee2610edc85886117bb565b866117df565b836117ea565b600a6117ea565b9450505050505b9392505050565b734ba1f38427b33b8ab7bb0490200dae1f1c36823f81565b6000546001600160a01b031681565b6003546001600160a01b031681565b610f3b614374565b818060200190518101906108879190614a7b565b731b14e8d511c9a4395425314f849bd737baf8208f81565b6001546001600160a01b03163314610f7e57600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b7319c0976f590d67707e62397c87829d896dc0f1f181565b6040518060400160405280601581526020017413d99998da185a5b8819185d18481a5b9d985b1a59605a1b81525081565b739759a6ac90977b93b58547b4a71c78317f391a2881565b604051806040016040528060138152602001724465737420616d6f756e74206d697373696e6760681b81525081565b6002546001600160a01b031681565b600061104a82610d8d565b905060006110588287610791565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016110889190614f84565b60206040518083038186803b1580156110a057600080fd5b505afa1580156110b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d89190614927565b905060006110ec8489848c604001516117fa565b6001600160a01b03841660c08b01529050611105611c2a565b61111157610190611115565b61014d5b60a08a01526111248782611cb9565b810360408a015260006111368a611da7565b915050611145858a89846120ee565b47156111795760405132904780156108fc02916000818181858888f19350505050158015611177573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338c888f60400151876040516020016111b9949392919061515d565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016111e693929190614e33565b600060405180830381600087803b15801561120057600080fd5b505af1158015611214573d6000803e3d6000fd5b5050505050505050505050505050565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b81525081565b73322d58b9e75a6918f7e7849aee0ff09369977e0881565b600080611273846108a5565b9050600080611283888888610b14565b604051636cb1c69b60e11b815291935091506000907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906112c2908a90600401614f84565b604080518083038186803b1580156112d957600080fd5b505afa1580156112ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113119190614a10565b91505060006113328461132d61132785876117bb565b886117df565b6117ea565b90506000876001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561136f57600080fd5b505afa158015611383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a79190614927565b601203600a0a82816113b557fe5b049050606460638202049650505050505050949350505050565b6000546001600160a01b031633146113e657600080fd5b6001546001600160a01b031615610f7e57600080fd5b600061140782610d8d565b905060006114158287610791565b90506000826001600160a01b0316632c2cb9fd886040518263ffffffff1660e01b81526004016114459190614f84565b60206040518083038186803b15801561145d57600080fd5b505afa158015611471573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114959190614927565b90506114a78388878b60400151612440565b506001600160a01b03821660c08901526114bf611c2a565b6114cb576101906114cf565b61014d5b60a089015260006114df89611da7565b9150506114ec8782611cb9565b90036114fb8489848487612751565b471561152f5760405132904780156108fc02916000818181858888f1935050505015801561152d573d6000803e3d6000fd5b505b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338b878e604001518760405160200161156f949392919061515d565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161159c93929190614ed0565b600060405180830381600087803b1580156115b657600080fd5b505af11580156115ca573d6000803e3d6000fd5b50505050505050505050505050565b6115e33086612ad0565b84111561160b5760405162461bcd60e51b815260040161160290615023565b60405180910390fd5b606060008080808061161f87890189614972565b955095509550955095509550611633614374565b61163c87610f33565b90506116466143f0565b6040518060c001604052808881526020018781526020018d81526020018c8152602001866001600160a01b031681526020018460ff16600181111561168757fe5b600181111561169257fe5b9052905083156116ab576116a68282612b80565b6116b5565b6116b58282612d9c565b6116c88d6116c38e8e613051565b613076565b47156115ca5760405132904780156108fc02916000818181858888f19350505050158015611214573d6000803e3d6000fd5b735c55b921f590a89c1ebe84df170e655a82b6212681565b6001546001600160a01b031681565b6000676765c793fa10079d601b1b61175161173c85856117bb565b6002676765c793fa10079d601b1b5b04613100565b8161175857fe5b049392505050565b6117b68363a9059cbb60e01b848460405160240161177f929190614f1c565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613110565b505050565b60008115806117d6575050808202828282816117d357fe5b04145b61088757600080fd5b600081838161175857fe5b8082038281111561088757600080fd5b60405163089c54b560e31b815260009081907319c0976f590d67707e62397c87829d896dc0f1f1906344e2a5a890611836908790600401614f84565b602060405180830381600087803b15801561185057600080fd5b505af1158015611864573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118889190614927565b905060007335d1b3f3d7966a1dfe207aa4514c12a259a0492b6001600160a01b0316636c25b346886001600160a01b0316632726b073896040518263ffffffff1660e01b81526004016118db9190614f84565b60206040518083038186803b1580156118f357600080fd5b505afa158015611907573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192b9190614771565b6040518263ffffffff1660e01b81526004016119479190614db4565b60206040518083038186803b15801561195f57600080fd5b505afa158015611973573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119979190614927565b905060006119a6888888610e1c565b90508085106119bd576119ba8160016117ea565b94505b876001600160a01b03166345e6bdcd8860006119da89888861319f565b6040518463ffffffff1660e01b81526004016119f893929190615181565b600060405180830381600087803b158015611a1257600080fd5b505af1158015611a26573d6000803e3d6000fd5b50505050876001600160a01b031663f9f30db68830611a4489613222565b6040518463ffffffff1660e01b8152600401611a629392919061513e565b600060405180830381600087803b158015611a7c57600080fd5b505af1158015611a90573d6000803e3d6000fd5b5050604051634538c4eb60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250634538c4eb9150611ae1903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614dc8565b60206040518083038186803b158015611af957600080fd5b505afa158015611b0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b319190614927565b611bb3576040516328ec8bf160e21b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063a3b22fc490611b8090739759a6ac90977b93b58547b4a71c78317f391a2890600401614db4565b600060405180830381600087803b158015611b9a57600080fd5b505af1158015611bae573d6000803e3d6000fd5b505050505b60405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a289063ef693bed90611bec9030908990600401614f1c565b600060405180830381600087803b158015611c0657600080fd5b505af1158015611c1a573d6000803e3d6000fd5b50969a9950505050505050505050565b6040516320eb73ed60e11b815260009073637726f8b08a7abe3ae3acab01a80e2d8ddef77b906341d6e7da90611c64903290600401614db4565b60206040518083038186803b158015611c7c57600080fd5b505afa158015611c90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb491906148c6565b905090565b60008215611d9e576000611cd4644554482d4160d81b6108a5565b90506000611ce28583611721565b9050600a8404811115611cf55750600a83045b60405163a9059cbb60e01b8152736b175474e89094c44da98b954eedeac495271d0f9063a9059cbb90611d429073322d58b9e75a6918f7e7849aee0ff09369977e08908590600401614f1c565b602060405180830381600087803b158015611d5c57600080fd5b505af1158015611d70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9491906148c6565b5091506108879050565b50600092915050565b600080600080600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b031686600001516001600160a01b03161415611e62578551611dec90613239565b6001600160a01b031686526040808701518151630d0e30db60e41b8152915173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29263d0e30db09291600480830192600092919082900301818588803b158015611e4857600080fd5b505af1158015611e5c573d6000803e3d6000fd5b50505050505b611e7e86604001518760c0015188600001518960a00151613280565b6040870180519190910390526101208601516060015115611ebb57611ea4866000613460565b925090508015611ebb578561012001516020015192505b80611ed557611ecb86600061365e565b91508560e0015192505b6000611ef473c02aaa39b223fe8d0a0e5c4f27ead9083c756cc261387c565b1115611fda576040516370a0823160e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d9082906370a0823190611f39903090600401614db4565b602060405180830381600087803b158015611f5357600080fd5b505af1158015611f67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f8b9190614927565b6040518263ffffffff1660e01b8152600401611fa79190614f84565b600060405180830381600087803b158015611fc157600080fd5b505af1158015611fd5573d6000803e3d6000fd5b505050505b60208601516001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2141561207d5761201586608001518760400151613926565b61203273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee61387c565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906120775760405162461bcd60e51b81526004016116029190614fd9565b506120e3565b61208f86608001518760400151613926565b61209c876020015161387c565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906120e15760405162461bcd60e51b81526004016116029190614fd9565b505b509092509050915091565b60006120f98361394e565b156121d257826001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561213757600080fd5b505afa15801561214b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216f9190614771565b6001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b1580156121a957600080fd5b505af11580156121bd573d6000803e3d6000fd5b50505050506121cb82613a2b565b90506121e7565b6121e46121df8484613a4d565b613a2b565b90505b61226d8383856001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561222557600080fd5b505afa158015612239573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225d9190614771565b6001600160a01b03169190613acf565b604051633b4da69f60e01b81526001600160a01b03841690633b4da69f9061229b9030908690600401614f1c565b600060405180830381600087803b1580156122b557600080fd5b505af11580156122c9573d6000803e3d6000fd5b5050604051632c2cb9fd60e01b81527335d1b3f3d7966a1dfe207aa4514c12a259a0492b9250637608870391506001600160a01b03881690632c2cb9fd90612315908990600401614f84565b60206040518083038186803b15801561232d57600080fd5b505afa158015612341573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123659190614927565b604051632726b07360e01b81526001600160a01b03891690632726b07390612391908a90600401614f84565b60206040518083038186803b1580156123a957600080fd5b505afa1580156123bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e19190614771565b30308660006040518763ffffffff1660e01b815260040161240796959493929190614fa4565b600060405180830381600087803b15801561242157600080fd5b505af1158015612435573d6000803e3d6000fd5b505050505050505050565b600080829050836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561247f57600080fd5b505afa158015612493573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124b79190614927565b60121461253a57836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b1580156124f757600080fd5b505afa15801561250b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061252f9190614927565b601203600a0a830290505b856001600160a01b03166345e6bdcd8661255384613a2b565b60000360006040518463ffffffff1660e01b815260040161257693929190615181565b600060405180830381600087803b15801561259057600080fd5b505af11580156125a4573d6000803e3d6000fd5b50506040516313771f0760e31b81526001600160a01b0389169250639bb8f83891506125d89088903090869060040161513e565b600060405180830381600087803b1580156125f257600080fd5b505af1158015612606573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038716925063ef693bed91506126389030908790600401614f1c565b600060405180830381600087803b15801561265257600080fd5b505af1158015612666573d6000803e3d6000fd5b505050506126738461394e565b1561274757836001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b1580156126b157600080fd5b505afa1580156126c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e99190614771565b6001600160a01b0316632e1a7d4d846040518263ffffffff1660e01b81526004016127149190614f84565b600060405180830381600087803b15801561272e57600080fd5b505af1158015612742573d6000803e3d6000fd5b505050505b5090949350505050565b604051632726b07360e01b81526000906001600160a01b03871690632726b07390612780908890600401614f84565b60206040518083038186803b15801561279857600080fd5b505afa1580156127ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d09190614771565b905060006127f47335d1b3f3d7966a1dfe207aa4514c12a259a0492b838488613b0e565b90508084111561289757736b175474e89094c44da98b954eedeac495271d0f63a9059cbb8461282387856117ea565b6040518363ffffffff1660e01b8152600401612840929190614f1c565b602060405180830381600087803b15801561285a57600080fd5b505af115801561286e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061289291906148c6565b508093505b604051636eb1769f60e11b8152736b175474e89094c44da98b954eedeac495271d0f9063dd62ed3e906128e4903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614dc8565b60206040518083038186803b1580156128fc57600080fd5b505afa158015612910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129349190614927565b6129db5760405163095ea7b360e01b8152736b175474e89094c44da98b954eedeac495271d0f9063095ea7b39061298790739759a6ac90977b93b58547b4a71c78317f391a289060001990600401614f1c565b602060405180830381600087803b1580156129a157600080fd5b505af11580156129b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129d991906148c6565b505b604051633b4da69f60e01b8152739759a6ac90977b93b58547b4a71c78317f391a2890633b4da69f90612a149085908890600401614f1c565b600060405180830381600087803b158015612a2e57600080fd5b505af1158015612a42573d6000803e3d6000fd5b50505050866001600160a01b03166345e6bdcd876000612a777335d1b3f3d7966a1dfe207aa4514c12a259a0492b878b613ce9565b6040518463ffffffff1660e01b8152600401612a9593929190615181565b600060405180830381600087803b158015612aaf57600080fd5b505af1158015612ac3573d6000803e3d6000fd5b5050505050505050505050565b6000612ada613ea7565b6001600160a01b0316826001600160a01b03161415612b0457506001600160a01b03821631610887565b6040516370a0823160e01b81526001600160a01b038316906370a0823190612b30908690600401614db4565b60206040518083038186803b158015612b4857600080fd5b505afa158015612b5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef69190614927565b6000612b8f8260a00151610d8d565b90506000612ba1828460000151610791565b8351604051632c2cb9fd60e01b81529192506000916001600160a01b03851691632c2cb9fd91612bd49190600401614f84565b60206040518083038186803b158015612bec57600080fd5b505afa158015612c00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c249190614927565b90506000612c3c848660000151848860800151611267565b90506000612c54858760000151886080015185612440565b6040808801518201908901526001600160a01b03851660c08901529050612c79611c2a565b612c8557610190612c89565b61014d5b60a08801526000612c9988611da7565b915050612caa876020015182611cb9565b8751910390612cbd908790868489613ebf565b9050612cd0868860000151868489612751565b612cee86886000015189608001518a606001518b6040015101612440565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338a60000151898d6040015187604051602001612d33949392919061515d565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612d6093929190614e7f565b600060405180830381600087803b158015612d7a57600080fd5b505af1158015612d8e573d6000803e3d6000fd5b505050505050505050505050565b6000612dab8260a00151610d8d565b90506000612dbd828460000151610791565b8351604051632c2cb9fd60e01b8152919250600091612e479185916001600160a01b03831690632c2cb9fd90612df7908490600401614f84565b60206040518083038186803b158015612e0f57600080fd5b505afa158015612e23573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c39190614927565b8451604051632c2cb9fd60e01b8152919250600091612ed79186916001600160a01b03831690632c2cb9fd90612e81908490600401614f84565b60206040518083038186803b158015612e9957600080fd5b505afa158015612ead573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ed19190614927565b856117fa565b9050612eed856020015186604001518301611cb9565b604080870151830191909103908701526001600160a01b03831660c0870152612f14611c2a565b612f2057610190612f24565b61014d5b60a08701526000612f3487611da7565b915050612f4b8587600001518860800151846120ee565b8551604051632c2cb9fd60e01b8152612fdf9187916001600160a01b03831690632c2cb9fd90612f7f908490600401614f84565b60206040518083038186803b158015612f9757600080fd5b505afa158015612fab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fcf9190614927565b89606001518a60400151016117fa565b50735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce5030338960000151888c6040015187604051602001613024949392919061515d565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612a9593929190614de2565b600082820183811015610ef65760405162461bcd60e51b815260040161160290614fec565b6002546040805163076b7fbb60e51b815290516000926001600160a01b03169163ed6ff760916004808301926020929190829003018186803b1580156130bb57600080fd5b505afa1580156130cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130f39190614771565b90506117b68184846141d7565b8082018281101561088757600080fd5b6060613165826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661426d9092919063ffffffff16565b8051909150156117b6578080602001905181019061318391906148c6565b6117b65760405162461bcd60e51b81526004016116029061508f565b60006131b684676765c793fa10079d601b1b6117bb565b821015610ef6576131ec836131df6131d987676765c793fa10079d601b1b6117bb565b856117ea565b816131e657fe5b04613a2b565b905061320384676765c793fa10079d601b1b6117bb565b61320d82856117bb565b106132185780610a5b565b6001019392505050565b600061088782676765c793fa10079d601b1b6117bb565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146132655781610887565b5073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2919050565b600081158015906133135750604051632cdc77ab60e21b8152731b14e8d511c9a4395425314f849bd737baf8208f9063b371deac906132c3908790600401614db4565b60206040518083038186803b1580156132db57600080fd5b505afa1580156132ef573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061331391906148c6565b156133a257604051636eeb543160e01b8152731b14e8d511c9a4395425314f849bd737baf8208f90636eeb54319061334f908790600401614db4565b60206040518083038186803b15801561336757600080fd5b505afa15801561337b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061339f9190614927565b91505b816133af57506000610a5b565b8185816133b857fe5b049050600a85048111156133cc5750600a84045b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156134385760405173322d58b9e75a6918f7e7849aee0ff09369977e089082156108fc029083906000818181858888f19350505050158015613432573d6000803e3d6000fd5b50610a5b565b610a5b6001600160a01b03841673322d58b9e75a6918f7e7849aee0ff09369977e0883611760565b610120820151602001516040516302f5cc7960e11b81526000918291734ba1f38427b33b8ab7bb0490200dae1f1c36823f916305eb98f2916134a59190600401614db4565b60206040518083038186803b1580156134bd57600080fd5b505afa1580156134d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134f591906148c6565b61350457506000905080613657565b6101208401515160405163e0aa279760e01b81527325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa2797916135419190600401614db4565b60206040518083038186803b15801561355957600080fd5b505afa15801561356d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061359191906148c6565b6135a057506000905080613657565b61012084015151604085015185516135c3926001600160a01b0390911691611760565b610120840151805160809091015160405163097396a160e31b81526001600160a01b0390921691634b9cb50891906136019088908890600401615112565b60408051808303818588803b15801561361957600080fd5b505af115801561362d573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061365291906148e2565b915091505b9250929050565b60e082015160405163e0aa279760e01b81526000917325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa27979161369b91600401614db4565b60206040518083038186803b1580156136b357600080fd5b505afa1580156136c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136eb91906148c6565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b815250906137315760405162461bcd60e51b81526004016116029190614fd9565b5060e083015160408401518451613753926001600160a01b0390911691611760565b600082600181111561376157fe5b1415613807578260e001516001600160a01b0316635b6f36fc8460000151856020015186604001518761010001516040518563ffffffff1660e01b81526004016137ae9493929190614f35565b602060405180830381600087803b1580156137c857600080fd5b505af11580156137dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138009190614927565b9050610887565b8260e001516001600160a01b0316633924db668460000151856020015186606001518761010001516040518563ffffffff1660e01b815260040161384e9493929190614f35565b602060405180830381600087803b15801561386857600080fd5b505af1158015612b5c573d6000803e3d6000fd5b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156138aa5750476106d7565b6040516370a0823160e01b81526001600160a01b038316906370a08231906138d6903090600401614db4565b60206040518083038186803b1580156138ee57600080fd5b505afa158015613902573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108879190614927565b6000670de0b6b3a764000061175161393e85856117bb565b6002670de0b6b3a764000061174b565b6000739759a6ac90977b93b58547b4a71c78317f391a286001600160a01b038316141561397d575060006106d7565b816001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b1580156139b657600080fd5b505afa1580156139ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139ee9190614771565b6001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03161415613a23575060016106d7565b506000919050565b8060008112156106d75760405162461bcd60e51b8152600401611602906150d9565b6000610ef682846001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b158015613a8c57600080fd5b505afa158015613aa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ac49190614927565b601203600a0a6117bb565b613aef8363095ea7b360e01b84600060405160240161177f929190614f68565b6117b68363095ea7b360e01b848460405160240161177f929190614f1c565b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b8152600401613b3d9190614f84565b60a06040518083038186803b158015613b5557600080fd5b505afa158015613b69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b8d9190614c19565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b8152600401613bc3929190614f8d565b604080518083038186803b158015613bda57600080fd5b505afa158015613bee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c129190614bf6565b9150506000876001600160a01b0316636c25b346886040518263ffffffff1660e01b8152600401613c439190614db4565b60206040518083038186803b158015613c5b57600080fd5b505afa158015613c6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c939190614927565b90506000613ca4610ee284866117bb565b9050676765c793fa10079d601b1b8104945080613ccc86676765c793fa10079d601b1b6117bb565b10613cd75784613cdc565b846001015b9998505050505050505050565b600080846001600160a01b0316636c25b346856040518263ffffffff1660e01b8152600401613d189190614db4565b60206040518083038186803b158015613d3057600080fd5b505afa158015613d44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d689190614927565b90506000856001600160a01b031663d9638d36856040518263ffffffff1660e01b8152600401613d989190614f84565b60a06040518083038186803b158015613db057600080fd5b505afa158015613dc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613de89190614c19565b5050509150506000866001600160a01b0316632424be5c86886040518363ffffffff1660e01b8152600401613e1e929190614f8d565b604080518083038186803b158015613e3557600080fd5b505afa158015613e49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e6d9190614bf6565b915050613e7c8284816131e657fe5b935080841115613e9757613e8f81613a2b565b600003613e9c565b836000035b979650505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b600080613fd87335d1b3f3d7966a1dfe207aa4514c12a259a0492b886001600160a01b0316632726b073896040518263ffffffff1660e01b8152600401613f069190614f84565b60206040518083038186803b158015613f1e57600080fd5b505afa158015613f32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f569190614771565b604051632726b07360e01b81526001600160a01b038b1690632726b07390613f82908c90600401614f84565b60206040518083038186803b158015613f9a57600080fd5b505afa158015613fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fd29190614771565b88613b0e565b9050808411156140775760405163a9059cbb60e01b8152736b175474e89094c44da98b954eedeac495271d0f9063a9059cbb9061401d90869085890390600401614f1c565b602060405180830381600087803b15801561403757600080fd5b505af115801561404b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061406f91906148c6565b5090506141ce565b604051636cb1c69b60e11b8152848203906000907335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063d9638d36906140b5908a90600401614f84565b60a06040518083038186803b1580156140cd57600080fd5b505afa1580156140e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141059190614c19565b945050505050676765c793fa10079d601b1b818161411f57fe5b049050808210156141c75760405163a9059cbb60e01b815282820390736b175474e89094c44da98b954eedeac495271d0f9063a9059cbb906141679089908590600401614f1c565b602060405180830381600087803b15801561418157600080fd5b505af1158015614195573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141b991906148c6565b50860393506141ce92505050565b8593505050505b95945050505050565b6141df613ea7565b6001600160a01b0316826001600160a01b0316141561425957826001600160a01b03168160405161420f90614db1565b60006040518083038185875af1925050503d806000811461424c576040519150601f19603f3d011682016040523d82523d6000602084013e614251565b606091505b5050506117b6565b6117b66001600160a01b0383168483611760565b6060610a5b848460008560606142828561433b565b61429e5760405162461bcd60e51b815260040161160290615058565b60006060866001600160a01b031685876040516142bb9190614d95565b60006040518083038185875af1925050503d80600081146142f8576040519150601f19603f3d011682016040523d82523d6000602084013e6142fd565b606091505b50915091508115614311579150610a5b9050565b8051156143215780518082602001fd5b8360405162461bcd60e51b81526004016116029190614fd9565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610a5b575050151592915050565b60405180610140016040528060006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016143eb614434565b905290565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b03168152602001600060018111156143eb57fe5b6040518060c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001606081525090565b803561088781615220565b805161088781615220565b600082601f8301126144ab578081fd5b81356144be6144b9826151cc565b6151a5565b91508082528360208285010111156144d557600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126144fe578081fd5b815161450c6144b9826151cc565b915080825283602082850101111561452357600080fd5b6145348160208401602086016151f0565b5092915050565b80356002811061088757600080fd5b600061014080838503121561455d578182fd5b614566816151a5565b9150506145738383614485565b81526145828360208401614485565b602082015260408201356040820152606082013560608201526080820135608082015260a082013560a08201526145bc8360c08401614485565b60c08201526145ce8360e08401614485565b60e08201526101008083013567ffffffffffffffff808211156145f057600080fd5b6145fc8683870161449b565b8385015261012092508285013591508082111561461857600080fd5b5061462585828601614631565b82840152505092915050565b600060c08284031215614642578081fd5b61464c60c06151a5565b9050813561465981615220565b8152602082013561466981615220565b6020820152604082013561467c81615220565b80604083015250606082013560608201526080820135608082015260a082013567ffffffffffffffff8111156146b157600080fd5b6146bd8482850161449b565b60a08301525092915050565b600060c082840312156146da578081fd5b6146e460c06151a5565b905081516146f181615220565b8152602082015161470181615220565b6020820152604082015161471481615220565b80604083015250606082015160608201526080820151608082015260a082015167ffffffffffffffff81111561474957600080fd5b6146bd848285016144ee565b600060208284031215614766578081fd5b8135610ef681615220565b600060208284031215614782578081fd5b8151610ef681615220565b6000806040838503121561479f578081fd5b82356147aa81615220565b946020939093013593505050565b6000806000606084860312156147cc578081fd5b83356147d781615220565b95602085013595506040909401359392505050565b60008060008060808587031215614801578182fd5b843561480c81615220565b93506020850135925060408501359150606085013561482a81615220565b939692955090935050565b60008060008060006080868803121561484c578283fd5b853561485781615220565b94506020860135935060408601359250606086013567ffffffffffffffff80821115614881578283fd5b818801915088601f830112614894578283fd5b8135818111156148a2578384fd5b8960208285010111156148b3578384fd5b9699959850939650602001949392505050565b6000602082840312156148d7578081fd5b8151610ef681615238565b600080604083850312156148f4578182fd5b82516148ff81615238565b6020939093015192949293505050565b600060208284031215614920578081fd5b5035919050565b600060208284031215614938578081fd5b5051919050565b600060208284031215614950578081fd5b813567ffffffffffffffff811115614966578182fd5b6108838482850161449b565b60008060008060008060c0878903121561498a578384fd5b863567ffffffffffffffff8111156149a0578485fd5b6149ac89828a0161449b565b965050602087013594506040870135935060608701356149cb81615220565b925060808701356149db81615238565b915060a087013560ff811681146149f0578182fd5b809150509295509295509295565b6000806040838503121561479f578182fd5b60008060408385031215614a22578182fd5b82516148ff81615220565b600060208284031215614a3e578081fd5b610ef6838361453b565b600060208284031215614a59578081fd5b813567ffffffffffffffff811115614a6f578182fd5b6108838482850161454a565b600060208284031215614a8c578081fd5b815167ffffffffffffffff80821115614aa3578283fd5b8184019150610140808387031215614ab9578384fd5b614ac2816151a5565b9050614ace8684614490565b8152614add8660208501614490565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a0820152614b178660c08501614490565b60c0820152614b298660e08501614490565b60e08201526101008084015183811115614b41578586fd5b614b4d888287016144ee565b8284015250506101208084015183811115614b66578586fd5b614b72888287016146c9565b918301919091525095945050505050565b600080600080600060a08688031215614b9a578283fd5b853567ffffffffffffffff811115614bb0578384fd5b614bbc8882890161454a565b95505060208601359350604086013592506060860135614bdb81615220565b9150614bea876080880161453b565b90509295509295909350565b60008060408385031215614c08578182fd5b505080516020909101519092909150565b600080600080600060a08688031215614c30578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b6001600160a01b03169052565b60008151808452614c7d8160208601602086016151f0565b601f01601f19169290920160200192915050565b6000610140614ca1848451614c58565b6020830151614cb36020860182614c58565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c0830151614cee60c0860182614c58565b5060e0830151614d0160e0860182614c58565b50610100808401518282870152614d1a83870182614c65565b925050506101208084015185830382870152614d368382614d40565b9695505050505050565b600060018060a01b0380835116845280602084015116602085015280604084015116604085015250606082015160608401526080820151608084015260a082015160c060a085015261088360c0850182614c65565b60008251614da78184602087016151f0565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c1350d1119b185cda109bdbdcdd609a1b60a082015260c0606082018190526000906141ce90830184614c65565b6001600160a01b03848116825283166020820152608060408201819052600890820152671350d1109bdbdcdd60c21b60a082015260c0606082018190526000906141ce90830184614c65565b6001600160a01b03848116825283166020820152608060408201819052600d908201526c4d4344466c617368526570617960981b60a082015260c0606082018190526000906141ce90830184614c65565b6001600160a01b03848116825283166020820152608060408201819052600890820152674d4344526570617960c01b60a082015260c0606082018190526000906141ce90830184614c65565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614d3690830184614c65565b6001600160a01b0392909216825260ff16602082015260400190565b90815260200190565b9182526001600160a01b0316602082015260400190565b9586526001600160a01b039485166020870152928416604086015292166060840152608083019190915260a082015260c00190565b600060208252610ef66020830184614c65565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252818101527f496e76616c69642062616c616e636520666f722074686520636f6e7472616374604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600c908201526b696e742d6f766572666c6f7760a01b604082015260600190565b600060208252610ef66020830184614c91565b6000604082526151256040830185614c91565b90506002831061513157fe5b8260208301529392505050565b9283526001600160a01b03919091166020830152604082015260600190565b9384526001600160a01b039290921660208401526040830152606082015260800190565b9283526020830191909152604082015260600190565b918252602082015260400190565b60405181810167ffffffffffffffff811182821017156151c457600080fd5b604052919050565b600067ffffffffffffffff8211156151e2578081fd5b50601f01601f191660200190565b60005b8381101561520b5781810151838201526020016151f3565b8381111561521a576000848401525b50505050565b6001600160a01b038116811461523557600080fd5b50565b801515811461523557600080fdfea26469706673582212202a64c0bc4977d4738d4f864eddff328283240776b6a144389bd7025a6527453964736f6c634300060c0033
Deployed Bytecode Sourcemap
53741:5714:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40155:48;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28614:134;;;;;;;;;;-1:-1:-1;28614:134:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;40224:100::-;;;;;;;;;;;;;:::i;24308:122::-;;;;;;;;;;-1:-1:-1;24308:122:0;;;;;:::i;:::-;;:::i;:::-;;33650:56;;;;;;;;;;;;;:::i;29072:86::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;40690:80::-;;;;;;;;;;;;;:::i;40992:58::-;;;;;;;;;;;;;:::i;15081:186::-;;;;;;;;;;-1:-1:-1;15081:186:0;;;;;:::i;:::-;;:::i;29449:92::-;;;;;;;;;;;;;:::i;49584:210::-;;;;;;;;;;-1:-1:-1;49584:210:0;;;;;:::i;:::-;;:::i;40877:42::-;;;;;;;;;;;;;:::i;24603:285::-;;;;;;;;;;-1:-1:-1;24603:285:0;;;;;:::i;:::-;;:::i;14572:357::-;;;;;;;;;;-1:-1:-1;14572:357:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;24476:80::-;;;;;;;;;;;;;:::i;33859:72::-;;;;;;;;;;;;;:::i;40090:45::-;;;;;;;;;;;;;:::i;15396:336::-;;;;;;;;;;-1:-1:-1;15396:336:0;;;;;:::i;:::-;;:::i;40779:89::-;;;;;;;;;;;;;:::i;29165:90::-;;;;;;;;;;;;;:::i;49140:357::-;;;;;;;;;;-1:-1:-1;49140:357:0;;;;;:::i;:::-;;:::i;29550:87::-;;;;;;;;;;;;;:::i;23266:20::-;;;;;;;;;;;;;:::i;53828:142::-;;;;;;;;;;;;;:::i;28756:159::-;;;;;;;;;;-1:-1:-1;28756:159:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;29357:85::-;;;;;;;;;;;;;:::i;24087:122::-;;;;;;;;;;-1:-1:-1;24087:122:0;;;;;:::i;:::-;;:::i;40603:80::-;;;;;;;;;;;;;:::i;28955:74::-;;;;;;;;;;;;;:::i;40926:59::-;;;;;;;;;;;;;:::i;33713:70::-;;;;;;;;;;;;;:::i;52646:54::-;;;;;;;;;;;;;:::i;42555:1110::-;;;;;;:::i;:::-;;:::i;33790:62::-;;;;;;;;;;;;;:::i;29264:86::-;;;;;;;;;;;;;:::i;48266:601::-;;;;;;;;;;-1:-1:-1;48266:601:0;;;;;:::i;:::-;;:::i;23804:161::-;;;;;;;;;;-1:-1:-1;23804:161:0;;;;;:::i;:::-;;:::i;41318:1083::-;;;;;;:::i;:::-;;:::i;54246:1384::-;;;;;;;;;;-1:-1:-1;54246:1384:0;;;;;:::i;:::-;;:::i;41059:100::-;;;;;;;;;;;;;:::i;23293:20::-;;;;;;;;;;;;;:::i;40155:48::-;40200:3;40155:48;:::o;28614:134::-;28689:12;28732:7;28721:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;28714:26;;28614:134;;;;:::o;40224:100::-;-1:-1:-1;;;40224:100:0;:::o;24308:122::-;24389:5;;-1:-1:-1;;;;;24389:5:0;24375:10;:19;24367:28;;;;;;24408:5;:14;;-1:-1:-1;;;;;;24408:14:0;-1:-1:-1;;;;;24408:14:0;;;;;;;;;;24308:122::o;33650:56::-;;;;;;;;;;;;;;-1:-1:-1;;;33650:56:0;;;;:::o;29072:86::-;29116:42;29072:86;:::o;40690:80::-;40728:42;40690:80;:::o;40992:58::-;40462:42;40992:58;:::o;15081:186::-;15151:7;15171:13;15203:8;-1:-1:-1;;;;;15203:13:0;;15217:6;15203:21;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15171:55;;15246:5;-1:-1:-1;;;;;15246:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15239:20;;;15081:186;;;;;:::o;29449:92::-;29499:42;29449:92;:::o;49584:210::-;49669:18;;-1:-1:-1;;;49669:18:0;;49637:4;;;;40462:42;;49669:12;;:18;;49682:4;;49669:18;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49716:14;;-1:-1:-1;;;49716:14:0;;49654:33;;-1:-1:-1;49701:9:0;;-1:-1:-1;40371:42:0;;49716:8;;:14;;49725:4;;49716:14;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49698:32;;;;;;49750:36;49755:25;49760:4;40462:42;-1:-1:-1;;;;;49766:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49755:4;:25::i;:::-;49782:3;49750:4;:36::i;:::-;49743:43;49584:210;-1:-1:-1;;;;49584:210:0:o;40877:42::-;40371;40877;:::o;24603:285::-;23362:5;;-1:-1:-1;;;;;23362:5:0;23371:10;23362:19;23354:28;;;;;;24703:42:::1;-1:-1:-1::0;;;;;24693:52:0;::::1;;24689:192;;;24770:5;::::0;;24762:32:::1;::::0;-1:-1:-1;;;;;24770:5:0;;::::1;::::0;24762:32;::::1;;;::::0;24786:7;;24762:32;24770:5;24762:32;24786:7;24770:5;24762:32;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;24689:192;;;24854:5;::::0;24827:42:::1;::::0;-1:-1:-1;;;;;24827:26:0;;::::1;::::0;24854:5:::1;24861:7:::0;24827:26:::1;:42::i;:::-;24603:285:::0;;:::o;14572:357::-;14658:4;14664;14681:11;14695:8;-1:-1:-1;;;;;14695:12:0;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14681:28;;14720:11;14734:8;-1:-1:-1;;;;;14734:13:0;;14748:6;14734:21;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14720:35;;14769:15;14786:9;14803:3;-1:-1:-1;;;;;14799:13:0;;14813:4;14819:3;14799:24;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14768:55;;;;14836:9;14856:3;-1:-1:-1;;;;;14852:13:0;;14866:4;14852:19;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14834:37;;;;;;14892:10;14904:16;14909:4;14915;14904;:16::i;:::-;14884:37;;;;;;;;;14572:357;;;;;;:::o;24476:80::-;23362:5;;-1:-1:-1;;;;;23362:5:0;23371:10;23362:19;23354:28;;;;;;24541:5:::1;::::0;-1:-1:-1;;;;;24541:5:0::1;24520:28;33859:72:::0;;;;;;;;;;;;;;-1:-1:-1;;;33859:72:0;;;;:::o;40090:45::-;40132:3;40090:45;:::o;15396:336::-;15467:7;;15491:12;:31;;;;;;;;;15487:238;;;-1:-1:-1;15546:42:0;15539:49;;15487:238;15626:21;15610:12;:37;;;;;;;;;15606:119;;;-1:-1:-1;15671:42:0;15664:49;;40779:89;40826:42;40779:89;:::o;29165:90::-;29213:42;29165:90;:::o;49140:357::-;49238:4;49255:10;49268:14;49277:4;49268:8;:14::i;:::-;49310:18;;-1:-1:-1;;;49310:18:0;;49255:27;;-1:-1:-1;49298:8:0;;40462:42;;49310:12;;:18;;49323:4;;49310:18;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49295:33;;;49340:15;49357:9;49370:47;49389:12;49404:6;49412:4;49370:10;:47::i;:::-;49339:78;;;;49437:52;49441:43;49445:32;49449:22;49453:10;49465:5;49449:3;:22::i;:::-;49473:3;49445;:32::i;:::-;49479:4;49441:3;:43::i;:::-;49486:2;49437:3;:52::i;:::-;49430:59;;;;;;49140:357;;;;;;:::o;29550:87::-;29595:42;29550:87;:::o;23266:20::-;;;-1:-1:-1;;;;;23266:20:0;;:::o;53828:142::-;;;-1:-1:-1;;;;;53828:142:0;;:::o;28756:159::-;28824:27;;:::i;:::-;28885:5;28874:33;;;;;;;;;;;;:::i;29357:85::-;29400:42;29357:85;:::o;24087:122::-;24168:5;;-1:-1:-1;;;;;24168:5:0;24154:10;:19;24146:28;;;;;;24187:5;:14;;-1:-1:-1;;;;;;24187:14:0;-1:-1:-1;;;;;24187:14:0;;;;;;;;;;24087:122::o;40603:80::-;40641:42;40603:80;:::o;28955:74::-;;;;;;;;;;;;;;-1:-1:-1;;;28955:74:0;;;;:::o;40926:59::-;40554:42;40926:59;:::o;33713:70::-;;;;;;;;;;;;;;-1:-1:-1;;;33713:70:0;;;;:::o;52646:54::-;;;-1:-1:-1;;;;;52646:54:0;;:::o;42555:1110::-;42758:19;42780:28;42795:12;42780:14;:28::i;:::-;42758:50;;42821:12;42836:38;42853:11;42867:6;42836:8;:38::i;:::-;42821:53;;42885:11;42907;-1:-1:-1;;;;;42899:25:0;;42925:6;42899:33;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42885:47;;42945:13;42961:58;42969:11;42982:6;42990:3;42995:13;:23;;;42961:7;:58::i;:::-;-1:-1:-1;;;;;43032:25:0;;:18;;;:25;42945:74;-1:-1:-1;43098:14:0;:12;:14::i;:::-;:59;;40132:3;43098:59;;;40200:3;43098:59;43068:27;;;:89;43205:27;43213:8;43223;43205:7;:27::i;:::-;43194:38;;43168:23;;;:64;43246:15;43265:20;43168:13;43265:5;:20::i;:::-;43243:42;;;43298:57;43312:11;43325:6;43333:9;43344:10;43298:13;:57::i;:::-;43438:21;:25;43434:99;;43480:41;;:9;;43499:21;43480:41;;;;;;;;;43499:21;43480:9;:41;;;;;;;;;;;;;;;;;;;;;43434:99;41116:42;-1:-1:-1;;;;;43545:10:0;;43564:4;43571:10;43606:6;43614:4;43620:13;:23;;;43645:10;43595:61;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;43545:112;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42555:1110;;;;;;;;;;:::o;33790:62::-;;;;;;;;;;;;;;-1:-1:-1;;;33790:62:0;;;;:::o;29264:86::-;29308:42;29264:86;:::o;48266:601::-;48381:4;48398:10;48411:14;48420:4;48411:8;:14::i;:::-;48398:27;;48439:15;48456:9;48469:47;48488:12;48503:6;48511:4;48469:10;:47::i;:::-;48544:35;;-1:-1:-1;;;48544:35:0;;48438:78;;-1:-1:-1;48438:78:0;-1:-1:-1;48532:8:0;;40462:42;;48544:29;;:35;;48574:4;;48544:35;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48529:50;;;48592:18;48613:45;48617:10;48630:26;48634:14;48638:3;48643:4;48634:3;:14::i;:::-;48650:5;48630:3;:26::i;:::-;48613:3;:45::i;:::-;48592:66;;48671:27;48735:9;-1:-1:-1;;;;;48730:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48725:2;:26;48718:2;:34;48701:13;:52;;;;;;;-1:-1:-1;48856:3:0;48851:2;48826:27;;:33;48819:40;;;;;;;;48266:601;;;;;;:::o;23804:161::-;23885:5;;-1:-1:-1;;;;;23885:5:0;23871:10;:19;23863:28;;;;;;23910:5;;-1:-1:-1;;;;;23910:5:0;:19;23902:28;;;;;41318:1083;41521:19;41543:28;41558:12;41543:14;:28::i;:::-;41521:50;;41584:12;41599:38;41616:11;41630:6;41599:8;:38::i;:::-;41584:53;;41648:11;41670;-1:-1:-1;;;;;41662:25:0;;41688:6;41662:33;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41648:47;;41708:71;41723:11;41736:6;41744:9;41755:13;:23;;;41708:14;:71::i;:::-;-1:-1:-1;;;;;;41792:25:0;;:18;;;:25;41858:14;:12;:14::i;:::-;:59;;40132:3;41858:59;;;40200:3;41858:59;41828:27;;;:89;41931:14;41949:20;41828:13;41949:5;:20::i;:::-;41928:41;;;41995:28;42003:8;42013:9;41995:7;:28::i;:::-;41982:41;;42036:54;42048:11;42061:6;42069:3;41982:41;42085:4;42036:11;:54::i;:::-;42173:21;:25;42169:99;;42215:41;;:9;;42234:21;42215:41;;;;;;;;;42234:21;42215:9;:41;;;;;;;;;;;;;;;;;;;;;42169:99;41116:42;-1:-1:-1;;;;;42280:10:0;;42299:4;42306:10;42341:6;42349:4;42355:13;:23;;;42380:9;42330:60;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;42280:111;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41318:1083;;;;;;;;;:::o;54246:1384::-;54493:43;54520:4;54527:8;54493:18;:43::i;:::-;54482:7;:54;;54474:112;;;;-1:-1:-1;;;54474:112:0;;;;;;;:::i;:::-;;;;;;;;;54614:24;54653:10;;;;;54804:63;;;;54815:7;54804:63;:::i;:::-;54599:268;;;;;;;;;;;;54880:32;;:::i;:::-;54915:31;54934:11;54915:18;:31::i;:::-;54880:66;;54959:26;;:::i;:::-;54988:223;;;;;;;;55020:5;54988:223;;;;55049:7;54988:223;;;;55083:7;54988:223;;;;55110:4;54988:223;;;;55139:8;-1:-1:-1;;;;;54988:223:0;;;;;55187:11;55175:24;;;;;;;;;;54988:223;;;;;;;;;;54959:252;-1:-1:-1;55224:149:0;;;;55252:38;55266:12;55280:9;55252:13;:38::i;:::-;55224:149;;;55323:38;55337:12;55351:9;55323:13;:38::i;:::-;55385:60;55417:8;55427:17;:7;55439:4;55427:11;:17::i;:::-;55385:31;:60::i;:::-;55528:21;:25;55524:99;;55570:41;;:9;;55589:21;55570:41;;;;;;;;;55589:21;55570:9;:41;;;;;;;;;;;;;;;;;;;41059:100;41116:42;41059:100;:::o;23293:20::-;;;-1:-1:-1;;;;;23293:20:0;;:::o;5375:122::-;5434:9;-1:-1:-1;;;5460:23:0;5464:9;5468:1;5471;5464:3;:9::i;:::-;5481:1;-1:-1:-1;;;5475:7:0;;5460:3;:23::i;:::-;:29;;;;;;;5375:122;-1:-1:-1;;;5375:122:0:o;21312:176::-;21394:86;21414:5;21444:23;;;21469:2;21473:5;21421:58;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;21421:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;21421:58:0;-1:-1:-1;;;;;;21421:58:0;;;;;;;;;;21394:19;:86::i;:::-;21312:176;;;:::o;4464:127::-;4522:9;4552:6;;;:30;;-1:-1:-1;;4567:5:0;;;4581:1;4576;4567:5;4576:1;4562:15;;;;;:20;4552:30;4544:39;;;;;4599:100;4657:9;4690:1;4686;:5;;;;4343:113;4436:5;;;4431:16;;;;4423:25;;;;;43963:819;44093:27;;-1:-1:-1;;;44093:27:0;;44064:4;;;;40641:42;;44093:21;;:27;;44115:4;;44093:27;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44081:39;;44131:18;40371:42;-1:-1:-1;;;;;44152:7:0;;44168:12;-1:-1:-1;;;;;44160:26:0;;44187:6;44160:34;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44152:43;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44131:64;;44208:14;44225:38;44236:12;44250:6;44258:4;44225:10;:38::i;:::-;44208:55;;44294:9;44280:10;:23;44276:86;;44333:17;44337:9;44348:1;44333:3;:17::i;:::-;44320:30;;44276:86;44382:12;-1:-1:-1;;;;;44374:26:0;;44401:6;44413:1;44417:52;44437:10;44449:4;44455:13;44417:19;:52::i;:::-;44374:96;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44489:12;-1:-1:-1;;;;;44481:26:0;;44508:6;44524:4;44531:17;44537:10;44531:5;:17::i;:::-;44481:68;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44566:49:0;;-1:-1:-1;;;44566:49:0;;40371:42;;-1:-1:-1;44566:7:0;;-1:-1:-1;44566:49:0;;44582:4;;40554:42;;44566:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44562:113;;44637:26;;-1:-1:-1;;;44637:26:0;;40371:42;;44637:8;;:26;;40554:42;;44637:26;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44562:113;44687:57;;-1:-1:-1;;;44687:57:0;;40554:42;;44687:30;;:57;;44726:4;;44733:10;;44687:57;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44764:10:0;;43963:819;-1:-1:-1;;;;;;;;;;43963:819:0:o;49802:130::-;49872:52;;-1:-1:-1;;;49872:52:0;;49848:4;;40826:42;;49872:41;;:52;;49914:9;;49872:52;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49865:59;;49802:130;:::o;49940:455::-;50006:4;50027:12;;50023:344;;50056:16;50075:17;-1:-1:-1;;;50075:8:0;:17::i;:::-;50056:36;;50107:14;50124:27;50129:8;50139:11;50124:4;:27::i;:::-;50107:44;-1:-1:-1;50194:2:0;50184:7;:12;50172:9;:24;50168:89;;;-1:-1:-1;50239:2:0;50229:12;;50168:89;50273:49;;-1:-1:-1;;;50273:49:0;;40728:42;;50273:27;;:49;;29308:42;;50312:9;;50273:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;50346:9:0;-1:-1:-1;50339:16:0;;-1:-1:-1;50339:16:0;50023:344;-1:-1:-1;50386:1:0;49940:455;;;;:::o;34202:1670::-;34263:7;34272:4;34291:15;34317:17;34345:12;29116:42;-1:-1:-1;;;;;34418:35:0;:6;:14;;;-1:-1:-1;;;;;34418:35:0;;34414:201;;;34501:14;;34487:29;;:13;:29::i;:::-;-1:-1:-1;;;;;34470:46:0;;;34584:16;;;;;34531:72;;-1:-1:-1;;;34531:72:0;;;;29213:42;;34531:45;;34584:16;34531:72;;;;;34470:14;;34531:72;;;;;;;34584:16;29213:42;34531:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34414:201;34647:75;34654:6;:16;;;34672:6;:11;;;34685:6;:14;;;34701:6;:20;;;34647:6;:75::i;:::-;34627:16;;;:95;;;;;;;;34802:19;;;;:25;;;:29;34798:228;;34874:34;34884:6;34892:15;34874:9;:34::i;:::-;34848:60;-1:-1:-1;34848:60:0;-1:-1:-1;34925:90:0;;;;34967:6;:19;;;:32;;;34957:42;;34925:90;35096:7;35091:129;;35135:34;35145:6;35153:15;35135:9;:34::i;:::-;35120:49;;35194:6;:14;;;35184:24;;35091:129;35336:1;35300:33;29213:42;35300:10;:33::i;:::-;:37;35296:212;;;35419:62;;-1:-1:-1;;;35419:62:0;;29213:42;;35354:46;;29213:42;;35419:47;;:62;;35475:4;;35419:62;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35354:142;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35296:212;35524:15;;;;-1:-1:-1;;;;;35524:40:0;29213:42;35524:40;35520:302;;;35622:39;35627:6;:15;;;35644:6;:16;;;35622:4;:39::i;:::-;35589:29;29116:42;35589:10;:29::i;:::-;:72;;35663:16;;;;;;;;;;;;;-1:-1:-1;;;35663:16:0;;;35581:99;;;;;-1:-1:-1;;;35581:99:0;;;;;;;;:::i;:::-;;35520:302;;;35752:39;35757:6;:15;;;35774:6;:16;;;35752:4;:39::i;:::-;35721:27;35732:6;:15;;;35721:10;:27::i;:::-;:70;;35793:16;;;;;;;;;;;;;-1:-1:-1;;;35793:16:0;;;35713:97;;;;;-1:-1:-1;;;35713:97:0;;;;;;;;:::i;:::-;;35520:302;-1:-1:-1;35842:7:0;;-1:-1:-1;35851:12:0;-1:-1:-1;34202:1670:0;;;:::o;45057:775::-;45168:17;45206:24;45220:9;45206:13;:24::i;:::-;45202:252;;;45252:9;-1:-1:-1;;;;;45247:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;45247:29:0;;45284:7;45247:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45325:22;45339:7;45325:13;:22::i;:::-;45309:38;;45202:252;;;45396:46;45410:31;45422:9;45433:7;45410:11;:31::i;:::-;45396:13;:46::i;:::-;45380:62;;45202:252;45466:69;45516:9;45527:7;45485:9;-1:-1:-1;;;;;45480:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;45466:49:0;;:69;:49;:69::i;:::-;45548:44;;-1:-1:-1;;;45548:44:0;;-1:-1:-1;;;;;45548:20:0;;;;;:44;;45577:4;;45584:7;;45548:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;45628:34:0;;-1:-1:-1;;;45628:34:0;;40371:42;;-1:-1:-1;45605:8:0;;-1:-1:-1;;;;;;45628:26:0;;;;;:34;;45655:6;;45628:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45677;;-1:-1:-1;;;45677:34:0;;-1:-1:-1;;;;;45677:26:0;;;;;:34;;45704:6;;45677:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45734:4;45762;45782:13;45810:1;45605:217;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45057:775;;;;;:::o;46193:648::-;46303:4;46320:15;46338:7;46320:25;;46367:9;-1:-1:-1;;;;;46362:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46387:2;46362:27;46358:119;;46447:9;-1:-1:-1;;;;;46442:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46437:2;:26;46430:2;:34;46419:7;:46;46406:59;;46358:119;46497:12;-1:-1:-1;;;;;46489:26:0;;46516:6;46525:25;46539:10;46525:13;:25::i;:::-;46524:26;;46552:1;46489:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;46565:61:0;;-1:-1:-1;;;46565:61:0;;-1:-1:-1;;;;;46565:26:0;;;-1:-1:-1;46565:26:0;;-1:-1:-1;46565:61:0;;46592:6;;46608:4;;46615:10;;46565:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;46639:44:0;;-1:-1:-1;;;46639:44:0;;-1:-1:-1;;;;;46639:20:0;;;-1:-1:-1;46639:20:0;;-1:-1:-1;46639:44:0;;46668:4;;46675:7;;46639:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46700:24;46714:9;46700:13;:24::i;:::-;46696:111;;;46746:9;-1:-1:-1;;;;;46741:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;46741:30:0;;46772:7;46741:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46696:111;-1:-1:-1;46826:7:0;;46193:648;-1:-1:-1;;;;46193:648:0:o;47217:720::-;47354:34;;-1:-1:-1;;;47354:34:0;;47340:11;;-1:-1:-1;;;;;47354:26:0;;;;;:34;;47381:6;;47354:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47340:48;;47401:14;47418:39;40371:42;47442:3;47447;47452:4;47418:10;:39::i;:::-;47401:56;;47487:9;47474:10;:22;47470:155;;;40728:42;47513:27;47541:6;47549:26;47553:10;47565:9;47549:3;:26::i;:::-;47513:63;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;47604:9;47591:22;;47470:155;47641:61;;-1:-1:-1;;;47641:61:0;;40728:42;;47641:28;;:61;;47678:4;;40554:42;;47641:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47637:153;;47724:54;;-1:-1:-1;;;47724:54:0;;40728:42;;47724:26;;:54;;40554:42;;-1:-1:-1;;47774:2:0;47724:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;47637:153;47802:29;;-1:-1:-1;;;47802:29:0;;40554:42;;47802:12;;:29;;47815:3;;47820:10;;47802:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47852:12;-1:-1:-1;;;;;47844:26:0;;47871:6;47879:1;47882:46;40371:42;47918:3;47923:4;47882:22;:46::i;:::-;47844:85;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47217:720;;;;;;;:::o;53462:262::-;53547:7;53582:26;:24;:26::i;:::-;-1:-1:-1;;;;;53570:38:0;:8;-1:-1:-1;;;;;53570:38:0;;53567:94;;;-1:-1:-1;;;;;;53634:15:0;;;53627:22;;53567:94;53680:34;;-1:-1:-1;;;53680:34:0;;-1:-1:-1;;;;;53680:25:0;;;;;:34;;53706:7;;53680:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;56975:1458::-;57109:19;57131:38;57146:10;:22;;;57131:14;:38::i;:::-;57109:60;;57182:12;57197:48;57214:11;57228:10;:16;;;57197:8;:48::i;:::-;57296:16;;57270:43;;-1:-1:-1;;;57270:43:0;;57182:63;;-1:-1:-1;57256:11:0;;-1:-1:-1;;;;;57270:25:0;;;;;:43;;57296:16;57270:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57256:57;;57354:12;57369:73;57386:11;57399:10;:16;;;57417:3;57422:10;:19;;;57369:16;:73::i;:::-;57354:88;;57453:14;57470:75;57485:11;57498:10;:16;;;57516:10;:19;;;57537:7;57470:14;:75::i;:::-;57602:21;;;;;:33;;57575:23;;;:61;-1:-1:-1;;;;;57647:25:0;;:18;;;:25;57453:92;-1:-1:-1;57713:14:0;:12;:14::i;:::-;:59;;40132:3;57713:59;;;40200:3;57713:59;57683:27;;;:89;57786:18;57808:20;57683:13;57808:5;:20::i;:::-;57783:45;;;57858:42;57866:10;:18;;;57886:13;57858:7;:42::i;:::-;57956:16;;57841:59;;;57927:72;;57943:11;;57974:3;57841:59;57994:4;57927:15;:72::i;:::-;57911:88;;58041:68;58053:11;58066:10;:16;;;58084:3;58089:13;58104:4;58041:11;:68::i;:::-;58174:108;58189:11;58202:10;:16;;;58220:10;:19;;;58266:10;:14;;;58242:10;:21;;;:38;58174:14;:108::i;:::-;;41116:42;-1:-1:-1;;;;;58295:10:0;;58314:4;58321:10;58361;:16;;;58379:4;58385:13;:23;;;58410:13;58350:74;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;58295:130;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56975:1458;;;;;;;;:::o;55638:1329::-;55772:19;55794:38;55809:10;:22;;;55794:14;:38::i;:::-;55772:60;;55845:12;55860:48;55877:11;55891:10;:16;;;55860:8;:48::i;:::-;55987:16;;56005:43;;-1:-1:-1;;;56005:43:0;;55845:63;;-1:-1:-1;55948:12:0;;55963:86;;55974:11;;-1:-1:-1;;;;;56005:25:0;;;;;:43;;55987:16;;56005:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;55963:86::-;56097:16;;56115:43;;-1:-1:-1;;;56115:43:0;;55948:101;;-1:-1:-1;56060:13:0;;56076:92;;56084:11;;-1:-1:-1;;;;;56115:25:0;;;;;:43;;56097:16;;56115:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56160:7;56076;:92::i;:::-;56060:108;;56259:61;56267:10;:18;;;56298:10;:21;;;56287:8;:32;56259:7;:61::i;:::-;56235:21;;;;;56224:32;;:96;;;;56198:23;;;:122;-1:-1:-1;;;;;56331:25:0;;:18;;;:25;56397:14;:12;:14::i;:::-;:59;;40132:3;56397:59;;;40200:3;56397:59;56367:27;;;:89;56470:17;56491:20;56367:13;56491:5;:20::i;:::-;56467:44;;;56554:79;56568:11;56581:10;:16;;;56599:10;:19;;;56620:12;56554:13;:79::i;:::-;56712:16;;56731:43;;-1:-1:-1;;;56731:43:0;;56691:126;;56699:11;;-1:-1:-1;;;;;56731:25:0;;;;;:43;;56712:16;;56731:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56801:10;:14;;;56777:10;:21;;;:38;56691:7;:126::i;:::-;;41116:42;-1:-1:-1;;;;;56830:10:0;;56849:4;56856:10;56896;:16;;;56914:4;56920:13;:23;;;56945:12;56885:73;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;56830:129;;;;;;;;;;;;;;;;;:::i;19474:181::-;19532:7;19564:5;;;19588:6;;;;19580:46;;;;-1:-1:-1;;;19580:46:0;;;;;;;:::i;52871:220::-;52992:17;;:38;;;-1:-1:-1;;;52992:38:0;;;;52969:20;;-1:-1:-1;;;;;52992:17:0;;:36;;:38;;;;;;;;;;;;;;:17;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52969:61;;53043:40;53060:4;53065:8;53075:7;53043:16;:40::i;4222:113::-;4315:5;;;4310:16;;;;4302:25;;;;;22781:419;22863:23;22889:69;22917:4;22889:69;;;;;;;;;;;;;;;;;22897:5;-1:-1:-1;;;;;22889:27:0;;;:69;;;;;:::i;:::-;22973:17;;22863:95;;-1:-1:-1;22973:21:0;22969:224;;23115:10;23104:30;;;;;;;;;;;;:::i;:::-;23096:85;;;;-1:-1:-1;;;23096:85:0;;;;;;;:::i;11214:344::-;11313:8;11355:17;11359:7;-1:-1:-1;;;11355:3:0;:17::i;:::-;11338:14;:34;11334:217;;;11396:61;11451:5;11410:38;11414:17;11418:7;-1:-1:-1;;;11414:3:0;:17::i;:::-;11433:14;11410:3;:38::i;:::-;:46;;;;;;11396:13;:61::i;:::-;11389:68;;11504:17;11508:7;-1:-1:-1;;;11504:3:0;:17::i;:::-;11479:22;11488:4;11495:5;11479:3;:22::i;:::-;:42;:60;;11535:4;11479:60;;;11531:1;11524:8;;11472:67;-1:-1:-1;;;11214:344:0:o;11673:100::-;11722:4;11746:19;11750:4;-1:-1:-1;;;11746:3:0;:19::i;32548:151::-;32608:7;-1:-1:-1;;;;;32635:25:0;;29116:42;32635:25;:56;;32687:4;32635:56;;;-1:-1:-1;29213:42:0;;32548:151;-1:-1:-1;32548:151:0:o;30937:830::-;31043:17;31077:19;;;;;:71;;-1:-1:-1;31100:48:0;;-1:-1:-1;;;31100:48:0;;29400:42;;31100:41;;:48;;31142:5;;31100:48;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31073:174;;;31182:53;;-1:-1:-1;;;31182:53:0;;29400:42;;31182:46;;:53;;31229:5;;31182:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31165:70;;31073:174;31263:19;31259:501;;-1:-1:-1;31311:1:0;31259:501;;;31367:14;31357:7;:24;;;;;;;-1:-1:-1;31483:2:0;31473:7;:12;31460:9;:26;31456:91;;;-1:-1:-1;31529:2:0;31519:12;;31456:91;-1:-1:-1;;;;;31567:27:0;;29116:42;31567:27;31563:186;;;31615:29;;29308:42;;31615:29;;;;;31634:9;;31615:29;;;;31634:9;29308:42;31615:29;;;;;;;;;;;;;;;;;;;;;31563:186;;;31685:48;-1:-1:-1;;;;;31685:26:0;;29308:42;31723:9;31685:26;:48::i;38163:692::-;38353:20;;;;:33;;;38310:77;;-1:-1:-1;;;38310:77:0;;38271:12;;;;29595:42;;38310;;:77;;38353:33;38310:77;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38305:128;;-1:-1:-1;38412:5:0;;-1:-1:-1;38412:5:0;38404:17;;38305:128;38507:20;;;;:28;38450:86;;-1:-1:-1;;;38450:86:0;;29499:42;;38450:56;;:86;;38507:28;38450:86;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38445:137;;-1:-1:-1;38561:5:0;;-1:-1:-1;38561:5:0;38553:17;;38445:137;38658:20;;;;:28;38688:17;;;;38628:15;;38622:84;;-1:-1:-1;;;;;38622:35:0;;;;;:84::i;:::-;38751:20;;;;:28;;38798:32;;;;;38726:121;;-1:-1:-1;;;38726:121:0;;-1:-1:-1;;;;;38726:64:0;;;;;;38798:32;38726:121;;38751:7;;38841:5;;38726:121;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38719:128;;;;38163:692;;;;;;:::o;39121:717::-;39300:15;;;;39243:73;;-1:-1:-1;;;39243:73:0;;39205:17;;29499:42;;39243:56;;:73;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39318:19;;;;;;;;;;;;;-1:-1:-1;;;39318:19:0;;;39235:103;;;;;-1:-1:-1;;;39235:103:0;;;;;;;;:::i;:::-;-1:-1:-1;39387:15:0;;;;39404:17;;;;39357:15;;39351:71;;-1:-1:-1;;;;;39351:35:0;;;;;:71::i;:::-;39448:15;39439:5;:24;;;;;;;;;39435:396;;;39515:7;:15;;;-1:-1:-1;;;;;39495:63:0;;39559:7;:15;;;39576:7;:16;;;39594:7;:17;;;39613:7;:19;;;39495:138;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39480:153;;39435:396;;;39701:7;:15;;;-1:-1:-1;;;;;39681:62:0;;39744:7;:15;;;39761:7;:16;;;39779:7;:18;;;39799:7;:19;;;39681:138;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29830:275;29893:12;-1:-1:-1;;;;;29922:31:0;;29116:42;29922:31;29918:180;;;-1:-1:-1;29980:21:0;29918:180;;;30044:42;;-1:-1:-1;;;30044:42:0;;-1:-1:-1;;;;;30044:27:0;;;;;:42;;30080:4;;30044:42;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;5245:122::-;5304:9;5194:6;5330:23;5334:9;5338:1;5341;5334:3;:9::i;:::-;5351:1;5194:6;5345:7;;13963:436;14028:4;14127:42;-1:-1:-1;;;;;14114:55:0;;;14110:73;;;-1:-1:-1;14178:5:0;14171:12;;14110:73;14264:9;-1:-1:-1;;;;;14259:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;14251:76:0;14285:42;-1:-1:-1;;;;;14251:76:0;;14247:120;;;-1:-1:-1;14351:4:0;14344:11;;14247:120;-1:-1:-1;14386:5:0;13963:436;;;:::o;12220:134::-;12301:2;12275:5;12323:6;;;12315:31;;;;-1:-1:-1;;;12315:31:0;;;;;;;:::i;11944:163::-;12024:7;12051:48;12055:7;12081:9;-1:-1:-1;;;;;12076:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12071:2;:26;12064:2;:34;12051:3;:48::i;21861:281::-;21947:86;21967:5;21997:22;;;22021:7;22030:1;21974:58;;;;;;;;;:::i;21947:86::-;22044:90;22064:5;22094:22;;;22118:7;22127:5;22071:62;;;;;;;;;:::i;13147:424::-;13246:14;13276:9;13296:4;-1:-1:-1;;;;;13292:14:0;;13307:4;13292:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13273:39;;;;;;13326:8;13342:4;-1:-1:-1;;;;;13338:14:0;;13353:4;13359;13338:26;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13323:41;;;13375:8;13390:4;-1:-1:-1;;;;;13386:13:0;;13400:4;13386:19;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13375:30;;13418:8;13429:24;13433:14;13437:3;13442:4;13433:3;:14::i;13429:24::-;13418:35;-1:-1:-1;;;;13418:35:0;13476:9;13464:21;;13532:3;13510:19;13514:9;-1:-1:-1;;;13510:3:0;:19::i;:::-;:25;:53;;13554:9;13510:53;;;13538:9;13550:1;13538:13;13510:53;13498:65;13147:424;-1:-1:-1;;;;;;;;;13147:424:0:o;12545:382::-;12642:10;12665:8;12680:4;-1:-1:-1;;;;;12676:13:0;;12690:4;12676:19;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12665:30;;12711:9;12731:4;-1:-1:-1;;;;;12727:14:0;;12742:4;12727:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12708:39;;;;;;12761:8;12777:4;-1:-1:-1;;;;;12773:14:0;;12788:4;12794;12773:26;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12758:41;;;12821:25;12841:4;12835:3;:10;;;;12821:25;12812:34;;12882:3;12871:6;12866:19;;:53;;12901:18;12915:3;12901:13;:18::i;:::-;12899:20;;12866:53;;;12890:6;12888:8;;12866:53;12857:62;12545:382;-1:-1:-1;;;;;;;12545:382:0:o;52380:121::-;52451:42;52380:121;:::o;58523:841::-;58652:7;58672:9;58684:102;40371:42;58717:12;-1:-1:-1;;;;;58709:26:0;;58736:6;58709:34;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58745;;-1:-1:-1;;;58745:34:0;;-1:-1:-1;;;;;58745:26:0;;;;;:34;;58772:6;;58745:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58781:4;58684:10;:102::i;:::-;58672:114;;58820:4;58803:14;:21;58799:140;;;58841:60;;-1:-1:-1;;;58841:60:0;;40728:42;;58841:27;;:60;;58869:6;;58878:21;;;;58841:60;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;58923:4:0;-1:-1:-1;58916:11:0;;58799:140;59020:14;;-1:-1:-1;;;59020:14:0;;58967:21;;;;58951:13;;40371:42;;59020:8;;:14;;59029:4;;59020:14;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59001:33;;;;;;-1:-1:-1;;;59052:4:0;:13;;;;;;59045:20;;59126:4;59115:8;:15;59111:212;;;59203:51;;-1:-1:-1;;;59203:51:0;;59170:15;;;;40728:42;;59203:27;;:51;;59231:6;;59170:15;;59203:51;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;59279:31:0;;;-1:-1:-1;59271:40:0;;-1:-1:-1;;;59271:40:0;59111:212;59342:14;59335:21;;;;;58523:841;;;;;;;;:::o;53099:355::-;53226:26;:24;:26::i;:::-;-1:-1:-1;;;;;53214:38:0;:8;-1:-1:-1;;;;;53214:38:0;;53211:168;;;53309:12;-1:-1:-1;;;;;53309:17:0;53334:7;53309:37;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53361:7;;53211:168;53391:51;-1:-1:-1;;;;;53391:28:0;;53420:12;53434:7;53391:28;:51::i;17705:196::-;17808:12;17840:53;17863:6;17871:4;17877:1;17880:12;18597;18630:18;18641:6;18630:10;:18::i;:::-;18622:60;;;;-1:-1:-1;;;18622:60:0;;;;;;;:::i;:::-;18756:12;18770:23;18797:6;-1:-1:-1;;;;;18797:11:0;18817:8;18828:4;18797:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18755:78;;;;18848:7;18844:595;;;18879:10;-1:-1:-1;18872:17:0;;-1:-1:-1;18872:17:0;18844:595;18993:17;;:21;18989:439;;19256:10;19250:17;19317:15;19304:10;19300:2;19296:19;19289:44;19204:148;19399:12;19392:20;;-1:-1:-1;;;19392:20:0;;;;;;;;:::i;16492:619::-;16552:4;17020:20;;16863:66;17060:23;;;;;;:42;;-1:-1:-1;;17087:15:0;;;16492:619;-1:-1:-1;;16492:619:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5:130::-;72:20;;97:33;72:20;97:33;:::i;142:134::-;220:13;;238:33;220:13;238:33;:::i;1496:440::-;;1597:3;1590:4;1582:6;1578:17;1574:27;1564:2;;-1:-1;;1605:12;1564:2;1652:6;1639:20;1674:64;1689:48;1730:6;1689:48;:::i;:::-;1674:64;:::i;:::-;1665:73;;1758:6;1751:5;1744:21;1862:3;1794:4;1853:6;1786;1844:16;;1841:25;1838:2;;;1879:1;;1869:12;1838:2;52575:6;1794:4;1786:6;1782:17;1794:4;1820:5;1816:16;52552:30;52631:1;52613:16;;;1794:4;52613:16;52606:27;1820:5;1557:379;-1:-1;;1557:379::o;1945:442::-;;2057:3;2050:4;2042:6;2038:17;2034:27;2024:2;;-1:-1;;2065:12;2024:2;2105:6;2099:13;2127:64;2142:48;2183:6;2142:48;:::i;2127:64::-;2118:73;;2211:6;2204:5;2197:21;2315:3;2247:4;2306:6;2239;2297:16;;2294:25;2291:2;;;2332:1;;2322:12;2291:2;2342:39;2374:6;2247:4;2273:5;2269:16;2247:4;2239:6;2235:17;2342:39;:::i;:::-;;2017:370;;;;:::o;2908:162::-;2991:20;;54199:1;54189:12;;54179:2;;54215:1;;54205:12;3119:1898;;3238:6;;3226:9;3221:3;3217:19;3213:32;3210:2;;;-1:-1;;3248:12;3210:2;3276:22;3238:6;3276:22;:::i;:::-;3267:31;;;3383:49;3428:3;3404:22;3383:49;:::i;:::-;3365:16;3358:75;3531:49;3576:3;3498:2;3556:9;3552:22;3531:49;:::i;:::-;3498:2;3517:5;3513:16;3506:75;3647:2;3705:9;3701:22;9671:20;3647:2;3666:5;3662:16;3655:75;3797:2;3855:9;3851:22;9671:20;3797:2;3816:5;3812:16;3805:75;3945:3;4004:9;4000:22;9671:20;3945:3;3965:5;3961:16;3954:75;4099:3;4158:9;4154:22;9671:20;4099:3;4119:5;4115:16;4108:75;4278:49;4323:3;4244;4303:9;4299:22;4278:49;:::i;:::-;4244:3;4264:5;4260:16;4253:75;4426:49;4471:3;4392;4451:9;4447:22;4426:49;:::i;:::-;4392:3;4412:5;4408:16;4401:75;4572:3;;4561:9;4557:19;4544:33;4597:18;;4589:6;4586:30;4583:2;;;3351:1;;4619:12;4583:2;4666:58;4720:3;4711:6;4700:9;4696:22;4666:58;:::i;:::-;4572:3;4650:5;4646:18;4639:86;4822:3;;;;4811:9;4807:19;4794:33;4780:47;;4597:18;4839:6;4836:30;4833:2;;;3351:1;;4869:12;4833:2;;4916:79;4991:3;4982:6;4971:9;4967:22;4916:79;:::i;:::-;4822:3;4900:5;4896:18;4889:107;;;3204:1813;;;;:::o;7120:1179::-;;7239:4;7227:9;7222:3;7218:19;7214:30;7211:2;;;-1:-1;;7247:12;7211:2;7275:20;7239:4;7275:20;:::i;:::-;7266:29;;85:6;72:20;97:33;124:5;97:33;:::i;:::-;7355:75;;7499:2;7553:22;;72:20;97:33;72:20;97:33;:::i;:::-;7499:2;7514:16;;7507:75;7654:2;7708:22;;72:20;97:33;72:20;97:33;:::i;:::-;7687:49;7654:2;7673:5;7669:16;7662:75;;7799:2;7857:9;7853:22;9671:20;7799:2;7818:5;7814:16;7807:75;7950:3;8009:9;8005:22;9671:20;7950:3;7970:5;7966:16;7959:75;8127:3;8116:9;8112:19;8099:33;8152:18;8144:6;8141:30;8138:2;;;-1:-1;;8174:12;8138:2;8219:58;8273:3;8264:6;8253:9;8249:22;8219:58;:::i;:::-;8127:3;8205:5;8201:16;8194:84;;7205:1094;;;;:::o;8348:1249::-;;8478:4;8466:9;8461:3;8457:19;8453:30;8450:2;;;-1:-1;;8486:12;8450:2;8514:20;8478:4;8514:20;:::i;:::-;8505:29;;226:6;220:13;238:33;265:5;238:33;:::i;:::-;8594:86;;8749:2;8814:22;;220:13;238:33;220:13;238:33;:::i;:::-;8749:2;8764:16;;8757:86;8915:2;8980:22;;220:13;238:33;220:13;238:33;:::i;:::-;8948:60;8915:2;8934:5;8930:16;8923:86;;9071:2;9140:9;9136:22;9819:13;9071:2;9090:5;9086:16;9079:86;9233:3;9303:9;9299:22;9819:13;9233:3;9253:5;9249:16;9242:86;9414:3;9403:9;9399:19;9393:26;9439:18;9431:6;9428:30;9425:2;;;-1:-1;;9461:12;9425:2;9506:69;9571:3;9562:6;9551:9;9547:22;9506:69;:::i;10015:241::-;;10119:2;10107:9;10098:7;10094:23;10090:32;10087:2;;;-1:-1;;10125:12;10087:2;85:6;72:20;97:33;124:5;97:33;:::i;10263:263::-;;10378:2;10366:9;10357:7;10353:23;10349:32;10346:2;;;-1:-1;;10384:12;10346:2;226:6;220:13;238:33;265:5;238:33;:::i;10819:366::-;;;10940:2;10928:9;10919:7;10915:23;10911:32;10908:2;;;-1:-1;;10946:12;10908:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;10998:63;11098:2;11137:22;;;;9671:20;;-1:-1;;;10902:283::o;11192:491::-;;;;11330:2;11318:9;11309:7;11305:23;11301:32;11298:2;;;-1:-1;;11336:12;11298:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;11388:63;11488:2;11527:22;;9671:20;;-1:-1;11596:2;11635:22;;;926:20;;11292:391;-1:-1;;;11292:391::o;11690:617::-;;;;;11845:3;11833:9;11824:7;11820:23;11816:33;11813:2;;;-1:-1;;11852:12;11813:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;11904:63;-1:-1;12004:2;12043:22;;9671:20;;-1:-1;12112:2;12151:22;;926:20;;-1:-1;12220:2;12259:22;;72:20;97:33;72:20;97:33;:::i;:::-;11807:500;;;;-1:-1;11807:500;;-1:-1;;11807:500::o;12314:741::-;;;;;;12488:3;12476:9;12467:7;12463:23;12459:33;12456:2;;;-1:-1;;12495:12;12456:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;12547:63;-1:-1;12647:2;12686:22;;9671:20;;-1:-1;12755:2;12794:22;;9671:20;;-1:-1;12891:2;12876:18;;12863:32;12915:18;12904:30;;;12901:2;;;-1:-1;;12937:12;12901:2;13022:6;13011:9;13007:22;;;1265:3;1258:4;1250:6;1246:17;1242:27;1232:2;;-1:-1;;1273:12;1232:2;1316:6;1303:20;12915:18;1335:6;1332:30;1329:2;;;-1:-1;;1365:12;1329:2;1460:3;12647:2;1440:17;1401:6;1426:32;;1423:41;1420:2;;;-1:-1;;1467:12;1420:2;12450:605;;;;-1:-1;12450:605;;-1:-1;12647:2;1397:17;;12957:82;12450:605;-1:-1;;;12450:605::o;13062:257::-;;13174:2;13162:9;13153:7;13149:23;13145:32;13142:2;;;-1:-1;;13180:12;13142:2;805:6;799:13;817:30;841:5;817:30;:::i;13326:393::-;;;13455:2;13443:9;13434:7;13430:23;13426:32;13423:2;;;-1:-1;;13461:12;13423:2;805:6;799:13;817:30;841:5;817:30;:::i;:::-;13621:2;13671:22;;;;9819:13;13513:71;;9819:13;;-1:-1;;;13417:302::o;13726:241::-;;13830:2;13818:9;13809:7;13805:23;13801:32;13798:2;;;-1:-1;;13836:12;13798:2;-1:-1;926:20;;13792:175;-1:-1;13792:175::o;13974:263::-;;14089:2;14077:9;14068:7;14064:23;14060:32;14057:2;;;-1:-1;;14095:12;14057:2;-1:-1;1074:13;;14051:186;-1:-1;14051:186::o;14244:345::-;;14357:2;14345:9;14336:7;14332:23;14328:32;14325:2;;;-1:-1;;14363:12;14325:2;14421:17;14408:31;14459:18;14451:6;14448:30;14445:2;;;-1:-1;;14481:12;14445:2;14511:62;14565:7;14556:6;14545:9;14541:22;14511:62;:::i;14596:979::-;;;;;;;14797:3;14785:9;14776:7;14772:23;14768:33;14765:2;;;-1:-1;;14804:12;14765:2;14862:17;14849:31;14900:18;14892:6;14889:30;14886:2;;;-1:-1;;14922:12;14886:2;14952:62;15006:7;14997:6;14986:9;14982:22;14952:62;:::i;:::-;14942:72;;;15051:2;15094:9;15090:22;9671:20;15059:63;;15159:2;15202:9;15198:22;9671:20;15167:63;;15267:2;15318:9;15314:22;358:20;383:41;418:5;383:41;:::i;:::-;15275:71;-1:-1;15383:3;15420:22;;657:20;682:30;657:20;682:30;:::i;:::-;15392:60;-1:-1;15489:3;15527:22;;9947:20;50196:4;50185:16;;54412:33;;54402:2;;-1:-1;;54449:12;54402:2;15498:61;;;;14759:816;;;;;;;;:::o;15874:398::-;;;16011:2;15999:9;15990:7;15986:23;15982:32;15979:2;;;-1:-1;;16017:12;16809:439;;;16961:2;16949:9;16940:7;16936:23;16932:32;16929:2;;;-1:-1;;16967:12;16929:2;2831:6;2825:13;2843:53;2890:5;2843:53;:::i;17255:273::-;;17375:2;17363:9;17354:7;17350:23;17346:32;17343:2;;;-1:-1;;17381:12;17343:2;17443:69;17504:7;17480:22;17443:69;:::i;17535:387::-;;17669:2;17657:9;17648:7;17644:23;17640:32;17637:2;;;-1:-1;;17675:12;17637:2;17733:17;17720:31;17771:18;17763:6;17760:30;17757:2;;;-1:-1;;17793:12;17757:2;17823:83;17898:7;17889:6;17878:9;17874:22;17823:83;:::i;17929:402::-;;18074:2;18062:9;18053:7;18049:23;18045:32;18042:2;;;-1:-1;;18080:12;18042:2;18131:17;18125:24;18169:18;;18161:6;18158:30;18155:2;;;-1:-1;;18191:12;18155:2;18298:6;18287:9;18283:22;;;5196:6;;5184:9;5179:3;5175:19;5171:32;5168:2;;;-1:-1;;5206:12;5168:2;5234:22;5196:6;5234:22;:::i;:::-;5225:31;;5341:60;5397:3;5373:22;5341:60;:::i;:::-;5323:16;5316:86;5500:60;5556:3;18074:2;5536:9;5532:22;5500:60;:::i;:::-;18074:2;5486:5;5482:16;5475:86;5627:2;5696:9;5692:22;9819:13;5627:2;5646:5;5642:16;5635:86;5788:2;5857:9;5853:22;9819:13;5788:2;5807:5;5803:16;5796:86;5947:3;6017:9;6013:22;9819:13;5947:3;5967:5;5963:16;5956:86;6112:3;6182:9;6178:22;9819:13;6112:3;6132:5;6128:16;6121:86;6302:60;6358:3;6268;6338:9;6334:22;6302:60;:::i;:::-;6268:3;6288:5;6284:16;6277:86;6461:60;6517:3;6427;6497:9;6493:22;6461:60;:::i;:::-;6427:3;6447:5;6443:16;6436:86;6611:3;;6600:9;6596:19;6590:26;18169:18;6628:6;6625:30;6622:2;;;-1:-1;;6658:12;6622:2;6705:69;6770:3;6761:6;6750:9;6746:22;6705:69;:::i;:::-;6611:3;6689:5;6685:18;6678:97;;;6865:3;;6854:9;6850:19;6844:26;18169:18;6882:6;6879:30;6876:2;;;-1:-1;;6912:12;6876:2;6959:90;7045:3;7036:6;7025:9;7021:22;6959:90;:::i;:::-;6939:18;;;6932:118;;;;-1:-1;6943:5;18036:295;-1:-1;;;;;18036:295::o;18338:921::-;;;;;;18556:3;18544:9;18535:7;18531:23;18527:33;18524:2;;;-1:-1;;18563:12;18524:2;18621:17;18608:31;18659:18;18651:6;18648:30;18645:2;;;-1:-1;;18681:12;18645:2;18711:83;18786:7;18777:6;18766:9;18762:22;18711:83;:::i;:::-;18701:93;;;18831:2;18874:9;18870:22;9671:20;18839:63;;18939:2;18982:9;18978:22;9671:20;18947:63;;19047:2;19090:9;19086:22;72:20;97:33;124:5;97:33;:::i;:::-;19055:63;-1:-1;19174:69;19235:7;19155:3;19211:22;;19174:69;:::i;:::-;19164:79;;18518:741;;;;;;;;:::o;19536:399::-;;;19668:2;19656:9;19647:7;19643:23;19639:32;19636:2;;;-1:-1;;19674:12;19636:2;-1:-1;;9819:13;;19837:2;19887:22;;;9819:13;;;;;-1:-1;19630:305::o;19942:809::-;;;;;;20125:3;20113:9;20104:7;20100:23;20096:33;20093:2;;;-1:-1;;20132:12;20093:2;-1:-1;;9819:13;;20295:2;20345:22;;9819:13;20414:2;20464:22;;9819:13;20533:2;20583:22;;9819:13;20652:3;20703:22;;;9819:13;;;;;-1:-1;9819:13;;-1:-1;9819:13;;-1:-1;20087:664;-1:-1;20087:664::o;20907:137::-;-1:-1;;;;;49980:54;20994:45;;20988:56::o;21401:323::-;;21533:5;48154:12;48429:6;48424:3;48417:19;21616:52;21661:6;48466:4;48461:3;48457:14;48466:4;21642:5;21638:16;21616:52;:::i;:::-;53008:7;52992:14;-1:-1;;52988:28;21680:39;;;;48466:4;21680:39;;21481:243;-1:-1;;21481:243::o;27619:1986::-;;27780:6;27880:63;27928:14;27857:16;27851:23;27880:63;:::i;:::-;28026:4;28019:5;28015:16;28009:23;28038:63;28026:4;28090:3;28086:14;28072:12;28038:63;:::i;:::-;;28185:4;28178:5;28174:16;28168:23;28185:4;28249:3;28245:14;21352:37;28345:4;28338:5;28334:16;28328:23;28345:4;28409:3;28405:14;21352:37;28503:4;28496:5;28492:16;28486:23;28503:4;28567:3;28563:14;21352:37;28666:4;28659:5;28655:16;28649:23;28666:4;28730:3;28726:14;21352:37;28820:4;28813:5;28809:16;28803:23;28832:63;28820:4;28884:3;28880:14;28866:12;28832:63;:::i;:::-;;28977:4;28970:5;28966:16;28960:23;28989:63;28977:4;29041:3;29037:14;29023:12;28989:63;:::i;:::-;;29138:6;;29131:5;29127:18;29121:25;27780:6;29138;29170:3;29166:16;29159:40;29214:71;27780:6;27775:3;27771:16;29266:12;29214:71;:::i;:::-;29206:79;;;;29378:6;;29371:5;29367:18;29361:25;29434:3;29428:4;29424:14;29378:6;29410:3;29406:16;29399:40;29454:113;29562:4;29548:12;29454:113;:::i;:::-;29589:11;27753:1852;-1:-1;;;;;;27753:1852::o;29693:1219::-;;4597:18;;49991:42;;;;29919:16;29913:23;49980:54;21001:3;20994:45;49991:42;30092:4;30085:5;30081:16;30075:23;49980:54;30092:4;30156:3;30152:14;20994:45;49991:42;30257:4;30250:5;30246:16;30240:23;49980:54;30257:4;30321:3;30317:14;20994:45;;30412:4;30405:5;30401:16;30395:23;30412:4;30476:3;30472:14;21352:37;30573:4;30566:5;30562:16;30556:23;30573:4;30637:3;30633:14;21352:37;30731:4;30724:5;30720:16;30714:23;29844:4;30731;30761:3;30757:14;30750:38;30803:71;29844:4;29839:3;29835:14;30855:12;30803:71;:::i;31149:271::-;;22241:5;48154:12;22352:52;22397:6;22392:3;22385:4;22378:5;22374:16;22352:52;:::i;:::-;22416:16;;;;;31283:137;-1:-1;;31283:137::o;31427:379::-;31791:10;31615:191::o;31813:222::-;-1:-1;;;;;49980:54;;;;20994:45;;31940:2;31925:18;;31911:124::o;32548:349::-;-1:-1;;;;;49980:54;;;20837:58;;49980:54;;32883:2;32868:18;;20994:45;32711:2;32696:18;;32682:215::o;32904:866::-;-1:-1;;;;;49980:54;;;20837:58;;49980:54;;33403:2;33388:18;;20837:58;33222:3;33440:2;33425:18;;33418:48;;;24794:2;33207:19;;;48417;-1:-1;;;49991:42;48457:14;;24810:36;24865:12;33644:2;33629:18;;33622:48;;;32904:866;;33684:76;;24865:12;;33746:6;33684:76;:::i;33777:866::-;-1:-1;;;;;49980:54;;;20837:58;;49980:54;;34276:2;34261:18;;20837:58;34095:3;34313:2;34298:18;;34291:48;;;25116:1;34080:19;;;48417;-1:-1;;;49991:42;48457:14;;25131:31;25181:12;34517:2;34502:18;;34495:48;;;33777:866;;34557:76;;25181:12;;34619:6;34557:76;:::i;34650:866::-;-1:-1;;;;;49980:54;;;20837:58;;49980:54;;35149:2;35134:18;;20837:58;34968:3;35186:2;35171:18;;35164:48;;;25432:2;34953:19;;;48417;-1:-1;;;49991:42;48457:14;;25448:36;25503:12;35390:2;35375:18;;35368:48;;;34650:866;;35430:76;;25503:12;;35492:6;35430:76;:::i;35523:866::-;-1:-1;;;;;49980:54;;;20837:58;;49980:54;;36022:2;36007:18;;20837:58;35841:3;36059:2;36044:18;;36037:48;;;26095:1;35826:19;;;48417;-1:-1;;;49991:42;48457:14;;26110:31;26160:12;36263:2;36248:18;;36241:48;;;35523:866;;36303:76;;26160:12;;36365:6;36303:76;:::i;36396:349::-;-1:-1;;;;;49980:54;;;;20837:58;;36731:2;36716:18;;21352:37;36559:2;36544:18;;36530:215::o;36752:640::-;-1:-1;;;;;49980:54;;;20994:45;;49980:54;;37146:2;37131:18;;20994:45;37229:2;37214:18;;21352:37;;;36981:3;37266:2;37251:18;;37244:48;;;36752:640;;37306:76;;36966:19;;37368:6;37306:76;:::i;37399:345::-;-1:-1;;;;;49980:54;;;;20994:45;;50196:4;50185:16;37730:2;37715:18;;23811:56;37560:2;37545:18;;37531:213::o;38091:222::-;21352:37;;;38218:2;38203:18;;38189:124::o;38320:333::-;21352:37;;;-1:-1;;;;;49980:54;38639:2;38624:18;;20994:45;38475:2;38460:18;;38446:207::o;38660:822::-;21352:37;;;-1:-1;;;;;49980:54;;;39113:2;39098:18;;20994:45;49980:54;;;39204:2;39189:18;;20837:58;49980:54;;39295:2;39280:18;;20837:58;39376:3;39361:19;;21352:37;;;;49991:42;39452:19;;23665:57;38948:3;38933:19;;38919:563::o;39489:306::-;;39634:2;39655:17;39648:47;39709:76;39634:2;39623:9;39619:18;39771:6;39709:76;:::i;41466:416::-;41666:2;41680:47;;;24458:2;41651:18;;;48417:19;24494:29;48457:14;;;24474:50;24543:12;;;41637:245::o;41889:416::-;42089:2;42103:47;;;42074:18;;;48417:19;25790:34;48457:14;;;25770:55;25844:12;;;42060:245::o;42312:416::-;42512:2;42526:47;;;26716:2;42497:18;;;48417:19;26752:31;48457:14;;;26732:52;26803:12;;;42483:245::o;42735:416::-;42935:2;42949:47;;;27054:2;42920:18;;;48417:19;27090:34;48457:14;;;27070:55;-1:-1;;;27145:12;;;27138:34;27191:12;;;42906:245::o;43158:416::-;43358:2;43372:47;;;27442:2;43343:18;;;48417:19;-1:-1;;;48457:14;;;27458:35;27512:12;;;43329:245::o;43581:390::-;;43768:2;43789:17;43782:47;43843:118;43768:2;43757:9;43753:18;43947:6;43843:118;:::i;43978:527::-;;44206:2;44227:17;44220:47;44281:118;44206:2;44195:9;44191:18;44385:6;44281:118;:::i;:::-;44273:126;;53113:1;53106:5;53103:12;53093:2;;53119:9;53093:2;51959:39;44491:2;44480:9;44476:18;23395:63;44177:328;;;;;:::o;44741:460::-;21352:37;;;-1:-1;;;;;49980:54;;;;45104:2;45089:18;;20837:58;45187:2;45172:18;;21352:37;44932:2;44917:18;;44903:298::o;45208:556::-;21352:37;;;-1:-1;;;;;49980:54;;;;45584:2;45569:18;;20994:45;45667:2;45652:18;;21352:37;45750:2;45735:18;;21352:37;45419:3;45404:19;;45390:374::o;45771:436::-;21352:37;;;46112:2;46097:18;;21352:37;;;;46193:2;46178:18;;21352:37;45950:2;45935:18;;45921:286::o;47136:333::-;21352:37;;;47455:2;47440:18;;21352:37;47291:2;47276:18;;47262:207::o;47476:256::-;47538:2;47532:9;47564:17;;;47639:18;47624:34;;47660:22;;;47621:62;47618:2;;;47696:1;;47686:12;47618:2;47538;47705:22;47516:216;;-1:-1;47516:216::o;47739:321::-;;47882:18;47874:6;47871:30;47868:2;;;-1:-1;;47904:12;47868:2;-1:-1;53008:7;47958:17;-1:-1;;47954:33;48045:4;48035:15;;47805:255::o;52648:268::-;52713:1;52720:101;52734:6;52731:1;52728:13;52720:101;;;52801:11;;;52795:18;52782:11;;;52775:39;52756:2;52749:10;52720:101;;;52836:6;52833:1;52830:13;52827:2;;;52713:1;52892:6;52887:3;52883:16;52876:27;52827:2;;52697:219;;;:::o;53142:117::-;-1:-1;;;;;49980:54;;53201:35;;53191:2;;53250:1;;53240:12;53191:2;53185:74;:::o;53406:111::-;53487:5;49251:13;49244:21;53465:5;53462:32;53452:2;;53508:1;;53498:12
Swarm Source
ipfs://2a64c0bc4977d4738d4f864eddff328283240776b6a144389bd7025a65274539
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.