Feature Tip: Add private address tag to any address under My Name Tag !
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
|
|||
---|---|---|---|---|---|---|
11093183 | 1565 days ago | 0.00063 ETH | ||||
11093183 | 1565 days ago | 0.00063 ETH | ||||
11093183 | 1565 days ago | 0.00371 ETH | ||||
11093183 | 1565 days ago | 0.00371 ETH | ||||
11093108 | 1565 days ago | 211.96708507 ETH | ||||
11093108 | 1565 days ago | 211.96694507 ETH | ||||
11093108 | 1565 days ago | 0.00014 ETH | ||||
11093108 | 1565 days ago | 0.01372 ETH | ||||
11093108 | 1565 days ago | 507.56825232 ETH | ||||
11093108 | 1565 days ago | 507.56825232 ETH | ||||
11093108 | 1565 days ago | 0.01372 ETH | ||||
11092706 | 1565 days ago | 18.49262593 ETH | ||||
11092706 | 1565 days ago | 18.49262593 ETH | ||||
11092706 | 1565 days ago | 43.70547133 ETH | ||||
11092706 | 1565 days ago | 43.70547133 ETH | ||||
11090593 | 1566 days ago | 0.00133 ETH | ||||
11090593 | 1566 days ago | 0.00448 ETH | ||||
11090593 | 1566 days ago | 1,161.03 ETH | ||||
11090593 | 1566 days ago | 1,161.03 ETH | ||||
11090593 | 1566 days ago | 0.00448 ETH | ||||
11090584 | 1566 days ago | 0.002135 ETH | ||||
11090584 | 1566 days ago | 0.00448 ETH | ||||
11090584 | 1566 days ago | 1,161.03 ETH | ||||
11090584 | 1566 days ago | 1,161.03 ETH | ||||
11090584 | 1566 days ago | 0.00448 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
MCDCloseFlashLoan
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-10-15 */ pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; 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); } //TODO: currenlty only adjusted to kyber, but should be genric interfaces for more dec. exchanges interface ExchangeInterface { function swapEtherToToken(uint256 _ethAmount, address _tokenAddress, uint256 _maxAmount) external payable returns (uint256, uint256); function swapTokenToEther(address _tokenAddress, uint256 _amount, uint256 _maxAmount) external returns (uint256); function swapTokenToToken(address _src, address _dest, uint256 _amount) external payable returns (uint256); function getExpectedRate(address src, address dest, uint256 srcQty) external view returns (uint256 expectedRate); } 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 { /// @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 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(); } } 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, 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); _; } constructor() public { owner = msg.sender; } /// @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 { 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 ExchangeInterfaceV2 { function sell(address _srcAddr, address _destAddr, uint _srcAmount) external payable returns (uint); function buy(address _srcAddr, address _destAddr, uint _destAmount) external payable returns(uint); function getSellRate(address _srcAddr, address _destAddr, uint _srcAmount) external view returns (uint); function getBuyRate(address _srcAddr, address _destAddr, uint _srcAmount) 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 SaverExchangeHelper { using SafeERC20 for ERC20; address public constant KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address public constant 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 ERC20_PROXY_0X = 0x95E6F48254609A6ee006F7D493c8e5fB97094ceF; 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 approve0xProxy(address _tokenAddr, uint _amount) internal { if (_tokenAddr != KYBER_ETH_ADDRESS) { ERC20(_tokenAddr).safeApprove(address(ERC20_PROXY_0X), _amount); } } 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)); } } 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; } } 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]; } } contract SaverExchangeCore is SaverExchangeHelper, DSMath { // first is empty to keep the legacy order in place enum ExchangeType { _, OASIS, KYBER, UNISWAP, ZEROX } enum ActionType { SELL, BUY } struct ExchangeData { address srcAddr; address destAddr; uint srcAmount; uint destAmount; uint minPrice; address wrapper; address exchangeAddr; bytes callData; uint256 price0x; } /// @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; uint tokensLeft = exData.srcAmount; // if selling eth, convert to weth if (exData.srcAddr == KYBER_ETH_ADDRESS) { exData.srcAddr = ethToWethAddr(exData.srcAddr); TokenInterface(WETH_ADDRESS).deposit.value(exData.srcAmount)(); } // Try 0x first and then fallback on specific wrapper if (exData.price0x > 0) { approve0xProxy(exData.srcAddr, exData.srcAmount); uint ethAmount = getProtocolFee(exData.srcAddr, exData.srcAmount); (success, swapedTokens, tokensLeft) = takeOrder(exData, ethAmount, ActionType.SELL); if (success) { wrapper = exData.exchangeAddr; } } // fallback to desired wrapper if 0x failed if (!success) { swapedTokens = saverSwap(exData, ActionType.SELL); wrapper = exData.wrapper; } require(getBalance(exData.destAddr) >= wmul(exData.minPrice, exData.srcAmount), "Final amount isn't correct"); // if anything is left in weth, pull it to user as eth if (getBalance(WETH_ADDRESS) > 0) { TokenInterface(WETH_ADDRESS).withdraw( TokenInterface(WETH_ADDRESS).balanceOf(address(this)) ); } 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, "Dest amount must be specified"); // if selling eth, convert to weth if (exData.srcAddr == KYBER_ETH_ADDRESS) { exData.srcAddr = ethToWethAddr(exData.srcAddr); TokenInterface(WETH_ADDRESS).deposit.value(exData.srcAmount)(); } if (exData.price0x > 0) { approve0xProxy(exData.srcAddr, exData.srcAmount); uint ethAmount = getProtocolFee(exData.srcAddr, exData.srcAmount); (success, swapedTokens,) = takeOrder(exData, ethAmount, ActionType.BUY); if (success) { wrapper = exData.exchangeAddr; } } // fallback to desired wrapper if 0x failed if (!success) { swapedTokens = saverSwap(exData, ActionType.BUY); wrapper = exData.wrapper; } require(getBalance(exData.destAddr) >= exData.destAmount, "Final amount isn't correct"); // if anything is left in weth, pull it to user as eth if (getBalance(WETH_ADDRESS) > 0) { TokenInterface(WETH_ADDRESS).withdraw( TokenInterface(WETH_ADDRESS).balanceOf(address(this)) ); } return (wrapper, getBalance(exData.destAddr)); } /// @notice Takes order from 0x and returns bool indicating if it is successful /// @param _exData Exchange data /// @param _ethAmount Ether fee needed for 0x order function takeOrder( ExchangeData memory _exData, uint256 _ethAmount, ActionType _type ) private returns (bool success, uint256, uint256) { // write in the exact amount we are selling/buing in an order if (_type == ActionType.SELL) { writeUint256(_exData.callData, 36, _exData.srcAmount); } else { writeUint256(_exData.callData, 36, _exData.destAmount); } if (ZrxAllowlist(ZRX_ALLOWLIST_ADDR).isNonPayableAddr(_exData.exchangeAddr)) { _ethAmount = 0; } uint256 tokensBefore = getBalance(_exData.destAddr); if (ZrxAllowlist(ZRX_ALLOWLIST_ADDR).isZrxAddr(_exData.exchangeAddr)) { (success, ) = _exData.exchangeAddr.call{value: _ethAmount}(_exData.callData); } else { success = false; } uint256 tokensSwaped = 0; uint256 tokensLeft = _exData.srcAmount; if (success) { // check to see if any _src tokens are left over after exchange tokensLeft = getBalance(_exData.srcAddr); // convert weth -> eth if needed if (_exData.destAddr == KYBER_ETH_ADDRESS) { TokenInterface(WETH_ADDRESS).withdraw( TokenInterface(WETH_ADDRESS).balanceOf(address(this)) ); } // get the current balance of the swaped tokens tokensSwaped = getBalance(_exData.destAddr) - tokensBefore; } return (success, tokensSwaped, tokensLeft); } /// @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), "Wrapper is not valid"); uint ethValue = 0; ERC20(_exData.srcAddr).safeTransfer(_exData.wrapper, _exData.srcAmount); if (_type == ActionType.SELL) { swapedTokens = ExchangeInterfaceV2(_exData.wrapper). sell{value: ethValue}(_exData.srcAddr, _exData.destAddr, _exData.srcAmount); } else { swapedTokens = ExchangeInterfaceV2(_exData.wrapper). buy{value: ethValue}(_exData.srcAddr, _exData.destAddr, _exData.destAmount); } } function writeUint256(bytes memory _b, uint256 _index, uint _input) internal pure { if (_b.length < _index + 32) { revert("Incorrent lengt while writting bytes32"); } 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 ? WETH_ADDRESS : _src; } /// @notice Calculates protocol fee /// @param _srcAddr selling token address (if eth should be WETH) /// @param _srcAmount amount we are selling function getProtocolFee(address _srcAddr, uint256 _srcAmount) internal view returns(uint256) { // if we are not selling ETH msg value is always the protocol fee if (_srcAddr != WETH_ADDRESS) return address(this).balance; // if msg value is larger than srcAmount, that means that msg value is protocol fee + srcAmount, so we subsctract srcAmount from msg value // we have an edge case here when protocol fee is higher than selling amount if (address(this).balance > _srcAmount) return address(this).balance - _srcAmount; // if msg value is lower than src amount, that means that srcAmount isn't included in msg value, so we return msg value return address(this).balance; } function packExchangeData(ExchangeData memory _exData) public pure returns(bytes memory) { // splitting in two different bytes and encoding all because of stack too deep in decoding part bytes memory part1 = abi.encode( _exData.srcAddr, _exData.destAddr, _exData.srcAmount, _exData.destAmount ); bytes memory part2 = abi.encode( _exData.minPrice, _exData.wrapper, _exData.exchangeAddr, _exData.callData, _exData.price0x ); return abi.encode(part1, part2); } function unpackExchangeData(bytes memory _data) public pure returns(ExchangeData memory _exData) { ( bytes memory part1, bytes memory part2 ) = abi.decode(_data, (bytes,bytes)); ( _exData.srcAddr, _exData.destAddr, _exData.srcAmount, _exData.destAmount ) = abi.decode(part1, (address,address,uint256,uint256)); ( _exData.minPrice, _exData.wrapper, _exData.exchangeAddr, _exData.callData, _exData.price0x ) = abi.decode(part2, (uint256,address,address,bytes,uint256)); } // solhint-disable-next-line no-empty-blocks receive() external virtual payable {} } /// @title Implements Boost and Repay for MCD CDPs contract MCDSaverProxy is SaverExchangeCore, 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 MANAGER_ADDRESS = 0x5ef30b9986345249bc32d8928B7ee64DE9435E39; 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 ETH_JOIN_ADDRESS = 0x2F0b23f53734252Bda2277357e97e1517d6B042A; address public constant DAI_ADDRESS = 0x6B175474E89094C44Da98b954EedeAC495271d0F; address public constant BOT_REGISTRY_ADDRESS = 0x637726f8b08a7ABE3aE3aCaB01A80E2d8ddeF77B; Manager public constant manager = Manager(MANAGER_ADDRESS); 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( SaverExchangeCore.ExchangeData memory _exchangeData, uint _cdpId, uint _gasCost, address _joinAddr ) public payable { address owner = getOwner(manager, _cdpId); bytes32 ilk = manager.ilks(_cdpId); drawCollateral(_cdpId, _joinAddr, _exchangeData.srcAmount); (, uint daiAmount) = _sell(_exchangeData); uint daiAfterFee = sub(daiAmount, getFee(daiAmount, _gasCost, owner)); paybackDebt(_cdpId, ilk, daiAfterFee, owner); // 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, owner, _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( SaverExchangeCore.ExchangeData memory _exchangeData, uint _cdpId, uint _gasCost, address _joinAddr ) public payable { address owner = getOwner(manager, _cdpId); bytes32 ilk = manager.ilks(_cdpId); uint daiDrawn = drawDai(_cdpId, ilk, _exchangeData.srcAmount); uint daiAfterFee = sub(daiDrawn, getFee(daiDrawn, _gasCost, owner)); _exchangeData.srcAmount = daiAfterFee; (, uint swapedColl) = _sell(_exchangeData); addCollateral(_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, owner, _exchangeData.srcAmount, swapedColl)); } /// @notice Draws Dai from the CDP /// @dev If _daiAmount is bigger than max available we'll draw max /// @param _cdpId Id of the CDP /// @param _ilk Ilk of the CDP /// @param _daiAmount Amount of Dai to draw function drawDai(uint _cdpId, bytes32 _ilk, uint _daiAmount) internal returns (uint) { uint rate = Jug(JUG_ADDRESS).drip(_ilk); uint daiVatBalance = vat.dai(manager.urns(_cdpId)); uint maxAmount = getMaxDebt(_cdpId, _ilk); if (_daiAmount >= maxAmount) { _daiAmount = sub(maxAmount, 1); } manager.frob(_cdpId, int(0), normalizeDrawAmount(_daiAmount, rate, daiVatBalance)); manager.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 _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(uint _cdpId, address _joinAddr, uint _amount) internal { int convertAmount = 0; if (_joinAddr == ETH_JOIN_ADDRESS) { Join(_joinAddr).gem().deposit{value: _amount}(); convertAmount = toPositiveInt(_amount); } else { convertAmount = toPositiveInt(convertTo18(_joinAddr, _amount)); } ERC20(address(Join(_joinAddr).gem())).safeApprove(_joinAddr, 0); ERC20(address(Join(_joinAddr).gem())).safeApprove(_joinAddr, _amount); Join(_joinAddr).join(address(this), _amount); vat.frob( manager.ilks(_cdpId), manager.urns(_cdpId), address(this), address(this), convertAmount, 0 ); } /// @notice Draws collateral and returns it to DSProxy /// @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(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.frob(_cdpId, -toPositiveInt(frobAmount), 0); manager.flux(_cdpId, address(this), frobAmount); Join(_joinAddr).exit(address(this), _amount); if (_joinAddr == ETH_JOIN_ADDRESS) { Join(_joinAddr).gem().withdraw(_amount); // Weth -> Eth } return _amount; } /// @notice Paybacks Dai debt /// @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(uint _cdpId, bytes32 _ilk, uint _daiAmount, address _owner) internal { address urn = manager.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.frob(_cdpId, 0, normalizePaybackAmount(VAT_ADDRESS, urn, _ilk)); } /// @notice Calculates the fee amount /// @param _amount Dai amount that is converted /// @param _gasCost Used for Monitor, estimated gas cost of tx /// @param _owner The address that controlls the DSProxy that owns the CDP function getFee(uint _amount, uint _gasCost, address _owner) internal returns (uint feeAmount) { uint fee = MANUAL_SERVICE_FEE; if (BotRegistry(BOT_REGISTRY_ADDRESS).botList(tx.origin)) { fee = AUTOMATIC_SERVICE_FEE; } if (Discount(DISCOUNT_ADDRESS).isCustomFeeSet(_owner)) { fee = Discount(DISCOUNT_ADDRESS).getCustomServiceFee(_owner); } feeAmount = (fee == 0) ? 0 : (_amount / fee); if (_gasCost != 0) { uint ethDaiPrice = getPrice(ETH_ILK); _gasCost = rmul(_gasCost, ethDaiPrice); feeAmount = add(feeAmount, _gasCost); } // fee can't go over 20% of the whole amount if (feeAmount > (_amount / 5)) { feeAmount = _amount / 5; } ERC20(DAI_ADDRESS).transfer(WALLET_ID, feeAmount); } /// @notice Gets the maximum amount of collateral available to draw /// @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(uint _cdpId, bytes32 _ilk, address _joinAddr) public view returns (uint) { uint price = getPrice(_ilk); (uint collateral, uint debt) = getCdpInfo(manager, _cdpId, _ilk); (, uint mat) = Spotter(SPOTTER_ADDRESS).ilks(_ilk); uint maxCollateral = sub(sub(collateral, (div(mul(mat, debt), price))), 10); uint normalizeMaxCollateral = maxCollateral; if (Join(_joinAddr).dec() != 18) { normalizeMaxCollateral = maxCollateral / (10 ** (18 - Join(_joinAddr).dec())); } return normalizeMaxCollateral; } /// @notice Gets the maximum amount of debt available to generate /// @param _cdpId Id of the CDP /// @param _ilk Ilk of the CDP /// @dev Substracts 10 wei to aviod rounding error later on function getMaxDebt(uint _cdpId, bytes32 _ilk) public virtual view returns (uint) { uint price = getPrice(_ilk); (, uint mat) = spotter.ilks(_ilk); (uint collateral, uint debt) = getCdpInfo(manager, _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); } /// @notice Gets CDP ratio /// @param _cdpId Id of the CDP /// @param _ilk Ilk of the CDP function getRatio(uint _cdpId, bytes32 _ilk) public view returns (uint) { uint price = getPrice( _ilk); (uint collateral, uint debt) = getCdpInfo(manager, _cdpId, _ilk); if (debt == 0) return 0; return rdiv(wmul(collateral, price), debt); } /// @notice Gets CDP info (collateral, debt, price, ilk) /// @param _cdpId Id of the CDP function getCdpDetailedInfo(uint _cdpId) public view returns (uint collateral, uint debt, uint price, bytes32 ilk) { address urn = manager.urns(_cdpId); ilk = manager.ilks(_cdpId); (collateral, debt) = vat.urns(ilk, urn); (,uint rate,,,) = vat.ilks(ilk); debt = rmul(debt, rate); price = getPrice(ilk); } } 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 MCDCloseFlashLoan is SaverExchangeCore, MCDSaverProxyHelper, FlashLoanReceiverBase, AdminAuth { ILendingPoolAddressesProvider public LENDING_POOL_ADDRESS_PROVIDER = ILendingPoolAddressesProvider(0x24a42fD28C976A61Df5D00D0599C34c4f90748c8); uint public constant SERVICE_FEE = 400; // 0.25% Fee bytes32 internal constant ETH_ILK = 0x4554482d41000000000000000000000000000000000000000000000000000000; address public constant DAI_ADDRESS = 0x6B175474E89094C44Da98b954EedeAC495271d0F; address public constant DAI_JOIN_ADDRESS = 0x9759A6Ac90977b93B58547b4A71c78317f391A28; address public constant ETH_JOIN_ADDRESS = 0x2F0b23f53734252Bda2277357e97e1517d6B042A; address public constant SPOTTER_ADDRESS = 0x65C79fcB50Ca1594B025960e539eD7A9a6D434A3; address public constant VAT_ADDRESS = 0x35D1b3F3D7966A1DFe207aa4514C12a259A0492B; Manager public constant manager = Manager(0x5ef30b9986345249bc32d8928B7ee64DE9435E39); DaiJoin public constant daiJoin = DaiJoin(DAI_JOIN_ADDRESS); Spotter public constant spotter = Spotter(SPOTTER_ADDRESS); Vat public constant vat = Vat(VAT_ADDRESS); struct CloseData { uint cdpId; uint collAmount; uint daiAmount; uint minAccepted; address joinAddr; address proxy; uint flFee; bool toDai; address reserve; uint amount; } constructor() FlashLoanReceiverBase(LENDING_POOL_ADDRESS_PROVIDER) public {} function executeOperation( address _reserve, uint256 _amount, uint256 _fee, bytes calldata _params) external override { ( uint[8] memory numData, address[5] memory addrData, bytes memory callData, address proxy, bool toDai ) = abi.decode(_params, (uint256[8],address[5],bytes,address,bool)); ExchangeData memory exchangeData = ExchangeData({ srcAddr: addrData[0], destAddr: addrData[1], srcAmount: numData[4], destAmount: numData[5], minPrice: numData[6], wrapper: addrData[3], exchangeAddr: addrData[2], callData: callData, price0x: numData[7] }); CloseData memory closeData = CloseData({ cdpId: numData[0], collAmount: numData[1], daiAmount: numData[2], minAccepted: numData[3], joinAddr: addrData[4], proxy: proxy, flFee: _fee, toDai: toDai, reserve: _reserve, amount: _amount }); address user = DSProxy(payable(closeData.proxy)).owner(); closeCDP(closeData, exchangeData, user); } function closeCDP( CloseData memory _closeData, ExchangeData memory _exchangeData, address _user ) internal { paybackDebt(_closeData.cdpId, manager.ilks(_closeData.cdpId), _closeData.daiAmount); // payback whole debt uint drawnAmount = drawMaxCollateral(_closeData.cdpId, _closeData.joinAddr, _closeData.collAmount); // draw whole collateral uint daiSwaped = 0; uint dfsFee = 0; if (_closeData.toDai) { _exchangeData.srcAmount = drawnAmount; (, daiSwaped) = _sell(_exchangeData); dfsFee = getFee(daiSwaped, _user); } else { dfsFee = getFee(_closeData.daiAmount, _user); _exchangeData.destAmount = (_closeData.daiAmount + _closeData.flFee + dfsFee); (, daiSwaped) = _buy(_exchangeData); } takeFee(dfsFee); address tokenAddr = getVaultCollAddr(_closeData.joinAddr); if (_closeData.toDai) { tokenAddr = DAI_ADDRESS; } require(getBalance(tokenAddr) >= _closeData.minAccepted, "Below min. number of eth specified"); transferFundsBackToPoolInternal(_closeData.reserve, _closeData.amount.add(_closeData.flFee)); sendLeftover(tokenAddr, DAI_ADDRESS, payable(_user)); } function drawMaxCollateral(uint _cdpId, address _joinAddr, uint _amount) internal returns (uint) { manager.frob(_cdpId, -toPositiveInt(_amount), 0); manager.flux(_cdpId, address(this), _amount); uint joinAmount = _amount; if (Join(_joinAddr).dec() != 18) { joinAmount = _amount / (10 ** (18 - Join(_joinAddr).dec())); } Join(_joinAddr).exit(address(this), joinAmount); if (_joinAddr == ETH_JOIN_ADDRESS) { Join(_joinAddr).gem().withdraw(joinAmount); // Weth -> Eth } return joinAmount; } function paybackDebt(uint _cdpId, bytes32 _ilk, uint _daiAmount) internal { address urn = manager.urns(_cdpId); daiJoin.dai().approve(DAI_JOIN_ADDRESS, _daiAmount); daiJoin.join(urn, _daiAmount); manager.frob(_cdpId, 0, normalizePaybackAmount(VAT_ADDRESS, urn, _ilk)); } function takeFee(uint _feeAmount) internal returns (uint) { ERC20(DAI_ADDRESS).transfer(WALLET_ID, _feeAmount); } function getFee(uint _amount, address _owner) internal view returns (uint feeAmount) { uint fee = SERVICE_FEE; if (Discount(DISCOUNT_ADDRESS).isCustomFeeSet(_owner)) { fee = Discount(DISCOUNT_ADDRESS).getCustomServiceFee(_owner); } feeAmount = (fee == 0) ? 0 : (_amount / fee); // fee can't go over 20% of the whole amount if (feeAmount > (_amount / 5)) { feeAmount = _amount / 5; } } function getVaultCollAddr(address _joinAddr) internal view returns (address) { address tokenAddr = address(Join(_joinAddr).gem()); if (tokenAddr == WETH_ADDRESS) { return KYBER_ETH_ADDRESS; } return tokenAddr; } function getPrice(bytes32 _ilk) public view returns (uint256) { (, uint256 mat) = spotter.ilks(_ilk); (, , uint256 spot, , ) = vat.ilks(_ilk); return rmul(rmul(spot, spotter.par()), mat); } receive() external override(FlashLoanReceiverBase, SaverExchangeCore) payable {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":"ERC20_PROXY_0X","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_JOIN_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":"SAVER_EXCHANGE_REGISTRY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SERVICE_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"WETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ZRX_ALLOWLIST_ADDR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"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":[],"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":"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":"manager","outputs":[{"internalType":"contract Manager","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":"address","name":"wrapper","type":"address"},{"internalType":"address","name":"exchangeAddr","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"price0x","type":"uint256"}],"internalType":"struct SaverExchangeCore.ExchangeData","name":"_exData","type":"tuple"}],"name":"packExchangeData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","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":"address","name":"wrapper","type":"address"},{"internalType":"address","name":"exchangeAddr","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"price0x","type":"uint256"}],"internalType":"struct SaverExchangeCore.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
6080604052600380546001600160a01b0319167324a42fd28c976a61df5d00d0599c34c4f90748c817905534801561003657600080fd5b50600354600080546001600160a01b03199081166001600160a01b039093169290921790556001805490911633179055613904806100756000396000f3fe6080604052600436106101e75760003560e01c80638c8a795811610102578063cf786f8f11610095578063deca5f8811610064578063deca5f88146104a5578063ee872558146104c5578063f1d25396146104e5578063f851a440146104fa576101ee565b8063cf786f8f146102e1578063cfac57c714610451578063d0cc72891461047b578063d3661fa514610490576101ee565b8063a46a66c9116100d1578063a46a66c91461041c578063a7304bf714610431578063c11645bc14610451578063c72c4d1014610466576101ee565b80638c8a7958146103b05780638da5cb5b146103c557806398ab3d49146103da578063a3b8e5d1146103ef576101ee565b806336569e771161017a578063481c6a7511610149578063481c6a751461035957806350c86de51461036e57806353485907146103835780636738929f1461026a576101ee565b806336569e77146102e15780633a128322146102f65780634115fe6b1461031657806341c0e1b514610344576101ee565b80632e77468d116101b65780632e77468d1461026a5780632f634a901461027f578063314b63321461029f57806331d98b3f146102b4576101ee565b8063040141e5146101f35780631e48907b1461021e57806329f7fc9e146102405780632a4c0a1a14610255576101ee565b366101ee57005b600080fd5b3480156101ff57600080fd5b5061020861050f565b6040516102159190613430565b60405180910390f35b34801561022a57600080fd5b5061023e610239366004612ed6565b610527565b005b34801561024c57600080fd5b50610208610560565b34801561026157600080fd5b50610208610578565b34801561027657600080fd5b50610208610590565b34801561028b57600080fd5b5061020861029a366004612f55565b6105a8565b3480156102ab57600080fd5b506102086106a4565b3480156102c057600080fd5b506102d46102cf3660046130f9565b6106bc565b60405161021591906134aa565b3480156102ed57600080fd5b5061020861087c565b34801561030257600080fd5b5061023e610311366004612f55565b610894565b34801561032257600080fd5b506103366103313660046131bd565b61092e565b60405161021592919061381f565b34801561035057600080fd5b5061023e610b4a565b34801561036557600080fd5b50610208610b6f565b34801561037a57600080fd5b506102d4610b87565b34801561038f57600080fd5b506103a361039e36600461321e565b610b8d565b60405161021591906134ca565b3480156103bc57600080fd5b50610208610c31565b3480156103d157600080fd5b50610208610c49565b3480156103e657600080fd5b50610208610c58565b3480156103fb57600080fd5b5061040f61040a366004613129565b610c67565b604051610215919061370d565b34801561042857600080fd5b50610208610d01565b34801561043d57600080fd5b5061023e61044c366004612ed6565b610d19565b34801561045d57600080fd5b50610208610d52565b34801561047257600080fd5b50610208610d6a565b34801561048757600080fd5b50610208610d79565b34801561049c57600080fd5b50610208610d91565b3480156104b157600080fd5b5061023e6104c0366004612ed6565b610da9565b3480156104d157600080fd5b5061023e6104e0366004612f80565b610dd6565b3480156104f157600080fd5b50610208610f91565b34801561050657600080fd5b50610208610fa9565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6002546001600160a01b0316331461053e57600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b736b175474e89094c44da98b954eedeac495271d0f81565b7365c79fcb50ca1594b025960e539ed7a9a6d434a381565b600080836001600160a01b0316638161b120846040518263ffffffff1660e01b81526004016105d791906134aa565b60206040518083038186803b1580156105ef57600080fd5b505afa158015610603573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106279190612ef2565b9050806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561066257600080fd5b505afa158015610676573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061069a9190612ef2565b9150505b92915050565b7325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d81565b604051636cb1c69b60e11b815260009081907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906106f89086906004016134aa565b604080518083038186803b15801561070f57600080fd5b505afa158015610723573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074791906131f1565b604051636cb1c69b60e11b8152909250600091507335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063d9638d36906107859087906004016134aa565b60a06040518083038186803b15801561079d57600080fd5b505afa1580156107b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d59190613399565b50509250505061087261086c827365c79fcb50ca1594b025960e539ed7a9a6d434a36001600160a01b031663495d32cb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561082f57600080fd5b505afa158015610843573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108679190613111565b610fb8565b83610fb8565b925050505b919050565b7335d1b3f3d7966a1dfe207aa4514c12a259a0492b81565b6001546001600160a01b031633146108ab57600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b0383161415610910576001546040516001600160a01b039091169082156108fc029083906000818181858888f1935050505015801561090a573d6000803e3d6000fd5b5061092a565b60015461092a906001600160a01b03848116911683610ff9565b5050565b6000806000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b15801561096c57600080fd5b505afa158015610980573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a49190612ef2565b90506000866001600160a01b0316632726b073876040518263ffffffff1660e01b81526004016109d491906134aa565b60206040518083038186803b1580156109ec57600080fd5b505afa158015610a00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a249190612ef2565b9050600080836001600160a01b0316632424be5c88856040518363ffffffff1660e01b8152600401610a579291906134b3565b604080518083038186803b158015610a6e57600080fd5b505afa158015610a82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa69190613376565b915091506000846001600160a01b031663d9638d36896040518263ffffffff1660e01b8152600401610ad891906134aa565b60a06040518083038186803b158015610af057600080fd5b505afa158015610b04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b289190613399565b50505091505082610b398383610fb8565b965096505050505050935093915050565b6001546001600160a01b03163314610b6157600080fd5b6001546001600160a01b0316ff5b735ef30b9986345249bc32d8928b7ee64de9435e3981565b61019081565b6060808260000151836020015184604001518560600151604051602001610bb79493929190613481565b60408051601f1981840301815290829052608085015160a086015160c087015160e0880151610100890151949650606095610bf595906020016137c5565b60405160208183030381529060405290508181604051602001610c199291906134dd565b60405160208183030381529060405292505050919050565b734ba1f38427b33b8ab7bb0490200dae1f1c36823f81565b6001546001600160a01b031681565b6003546001600160a01b031681565b610c6f612ca7565b60608083806020019051810190610c86919061315c565b9150915081806020019051810190610c9e9190612f0e565b606087015260408601526001600160a01b03908116602080870191909152911684528151610cd3919083018101908301613300565b61010088015260e08701526001600160a01b0390811660c08701521660a08501526080840152509092915050565b731b14e8d511c9a4395425314f849bd737baf8208f81565b6002546001600160a01b03163314610d3057600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b739759a6ac90977b93b58547b4a71c78317f391a2881565b6000546001600160a01b031681565b7395e6f48254609a6ee006f7d493c8e5fb97094cef81565b73322d58b9e75a6918f7e7849aee0ff09369977e0881565b6001546001600160a01b03163314610dc057600080fd5b6002546001600160a01b031615610d3057600080fd5b610dde612d17565b610de6612d36565b6060600080610df786880188613011565b94509450945094509450610e09612ca7565b50604080516101208101825285516001600160a01b0390811682526020808801518216908301526080888101518385015260a0808a015160608086019190915260c0808c01519386019390935289015183169084015292870151169181019190915260e0808201859052860151610100820152610e84612d54565b6040805161014081018252885181526020808a0151908201528882015191810191909152606080890151908201526080810187600460200201516001600160a01b03168152602001856001600160a01b031681526020018b815260200184151581526020018d6001600160a01b031681526020018c815250905060008160a001516001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f3d57600080fd5b505afa158015610f51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f759190612ef2565b9050610f82828483611054565b50505050505050505050505050565b732f0b23f53734252bda2277357e97e1517d6b042a81565b6002546001600160a01b031681565b60006b033b2e3c9fd0803ce8000000610fea610fd4858561122b565b60026b033b2e3c9fd0803ce80000005b0461124f565b81610ff157fe5b049392505050565b61104f8363a9059cbb60e01b8484604051602401611018929190613444565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261125f565b505050565b8251604051632c2cb9fd60e01b81526110ec9190735ef30b9986345249bc32d8928b7ee64de9435e3990632c2cb9fd906110929084906004016134aa565b60206040518083038186803b1580156110aa57600080fd5b505afa1580156110be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e29190613111565b85604001516112ee565b600061110584600001518560800151866020015161157a565b90506000808560e00151156111395760408501839052611124856118be565b925061113290508285611b35565b9050611168565b611147866040015185611b35565b60c087015160408801510181016060870152905061116485611c85565b9250505b61117181611f16565b5060006111818760800151611fbe565b90508660e00151156111a45750736b175474e89094c44da98b954eedeac495271d0f5b86606001516111b282612076565b10156111d95760405162461bcd60e51b81526004016111d090613542565b60405180910390fd5b6112038761010001516111fe8960c001518a610120015161212090919063ffffffff16565b61214c565b61122281736b175474e89094c44da98b954eedeac495271d0f876121e0565b50505050505050565b60008115806112465750508082028282828161124357fe5b04145b61069e57600080fd5b8082018281101561069e57600080fd5b60606112b4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661227b9092919063ffffffff16565b80519091501561104f57808060200190518101906112d291906130dd565b61104f5760405162461bcd60e51b81526004016111d09061369d565b604051632726b07360e01b8152600090735ef30b9986345249bc32d8928b7ee64de9435e3990632726b073906113289087906004016134aa565b60206040518083038186803b15801561134057600080fd5b505afa158015611354573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113789190612ef2565b9050739759a6ac90977b93b58547b4a71c78317f391a286001600160a01b031663f4b9fa756040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156113c957600080fd5b505af11580156113dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114019190612ef2565b6001600160a01b031663095ea7b3739759a6ac90977b93b58547b4a71c78317f391a28846040518363ffffffff1660e01b8152600401611442929190613444565b600060405180830381600087803b15801561145c57600080fd5b505af1158015611470573d6000803e3d6000fd5b5050604051633b4da69f60e01b8152739759a6ac90977b93b58547b4a71c78317f391a289250633b4da69f91506114ad9084908690600401613444565b600060405180830381600087803b1580156114c757600080fd5b505af11580156114db573d6000803e3d6000fd5b50505050735ef30b9986345249bc32d8928b7ee64de9435e396001600160a01b03166345e6bdcd8560006115247335d1b3f3d7966a1dfe207aa4514c12a259a0492b868961228a565b6040518463ffffffff1660e01b815260040161154293929190613809565b600060405180830381600087803b15801561155c57600080fd5b505af1158015611570573d6000803e3d6000fd5b5050505050505050565b6000735ef30b9986345249bc32d8928b7ee64de9435e396345e6bdcd856115a08561244e565b60000360006040518463ffffffff1660e01b81526004016115c393929190613809565b600060405180830381600087803b1580156115dd57600080fd5b505af11580156115f1573d6000803e3d6000fd5b50506040516313771f0760e31b8152735ef30b9986345249bc32d8928b7ee64de9435e399250639bb8f8389150611630908790309087906004016137a6565b600060405180830381600087803b15801561164a57600080fd5b505af115801561165e573d6000803e3d6000fd5b505050506000829050836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b1580156116a057600080fd5b505afa1580156116b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d89190613111565b60121461176257836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561171857600080fd5b505afa15801561172c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117509190613111565b601203600a0a838161175e57fe5b0490505b60405163ef693bed60e01b81526001600160a01b0385169063ef693bed906117909030908590600401613444565b600060405180830381600087803b1580156117aa57600080fd5b505af11580156117be573d6000803e3d6000fd5b505050506001600160a01b038416732f0b23f53734252bda2277357e97e1517d6b042a14156118b657836001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561182057600080fd5b505afa158015611834573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118589190612ef2565b6001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040161188391906134aa565b600060405180830381600087803b15801561189d57600080fd5b505af11580156118b1573d6000803e3d6000fd5b505050505b949350505050565b604081015181516000918291829182918291906001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141561197657865161190090612470565b6001600160a01b031687526040808801518151630d0e30db60e41b8152915173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29263d0e30db09291600480830192600092919082900301818588803b15801561195c57600080fd5b505af1158015611970573d6000803e3d6000fd5b50505050505b610100870151156119cd57611993876000015188604001516124b7565b60006119a788600001518960400151612503565b90506119b58882600061254a565b909550909350915082156119cb578760c0015194505b505b816119e7576119dd87600061287b565b92508660a0015193505b6119f987608001518860400151612a89565b611a068860200151612076565b1015611a245760405162461bcd60e51b81526004016111d0906135e9565b6000611a4373c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2612076565b1115611b29576040516370a0823160e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d9082906370a0823190611a88903090600401613430565b602060405180830381600087803b158015611aa257600080fd5b505af1158015611ab6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ada9190613111565b6040518263ffffffff1660e01b8152600401611af691906134aa565b600060405180830381600087803b158015611b1057600080fd5b505af1158015611b24573d6000803e3d6000fd5b505050505b50919350915050915091565b604051632cdc77ab60e21b815260009061019090731b14e8d511c9a4395425314f849bd737baf8208f9063b371deac90611b73908690600401613430565b60206040518083038186803b158015611b8b57600080fd5b505afa158015611b9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc391906130dd565b15611c5257604051636eeb543160e01b8152731b14e8d511c9a4395425314f849bd737baf8208f90636eeb543190611bff908690600401613430565b60206040518083038186803b158015611c1757600080fd5b505afa158015611c2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c4f9190613111565b90505b8015611c6757808481611c6157fe5b04611c6a565b60005b915060058404821115611c7e576005840491505b5092915050565b6000806000806000856060015160001415611cb25760405162461bcd60e51b81526004016111d09061350b565b85516001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415611d59578551611ce390612470565b6001600160a01b031686526040808701518151630d0e30db60e41b8152915173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29263d0e30db09291600480830192600092919082900301818588803b158015611d3f57600080fd5b505af1158015611d53573d6000803e3d6000fd5b50505050505b61010086015115611dad57611d76866000015187604001516124b7565b6000611d8a87600001518860400151612503565b9050611d988782600161254a565b50935091508115611dab578660c0015193505b505b80611dc757611dbd86600161287b565b91508560a0015192505b8560600151611dd98760200151612076565b1015611df75760405162461bcd60e51b81526004016111d0906135e9565b6000611e1673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2612076565b1115611efc576040516370a0823160e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d9082906370a0823190611e5b903090600401613430565b602060405180830381600087803b158015611e7557600080fd5b505af1158015611e89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ead9190613111565b6040518263ffffffff1660e01b8152600401611ec991906134aa565b600060405180830381600087803b158015611ee357600080fd5b505af1158015611ef7573d6000803e3d6000fd5b505050505b82611f0a8760200151612076565b94509450505050915091565b60405163a9059cbb60e01b8152600090736b175474e89094c44da98b954eedeac495271d0f9063a9059cbb90611f669073322d58b9e75a6918f7e7849aee0ff09369977e08908690600401613444565b602060405180830381600087803b158015611f8057600080fd5b505af1158015611f94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb891906130dd565b50919050565b600080826001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015611ffa57600080fd5b505afa15801561200e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120329190612ef2565b90506001600160a01b03811673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2141561069e5773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee915050610877565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156120a4575047610877565b6040516370a0823160e01b81526001600160a01b038316906370a08231906120d0903090600401613430565b60206040518083038186803b1580156120e857600080fd5b505afa1580156120fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061069e9190613111565b6000828201838110156121455760405162461bcd60e51b81526004016111d090613584565b9392505050565b60008060009054906101000a90046001600160a01b03166001600160a01b031663ed6ff7606040518163ffffffff1660e01b815260040160206040518083038186803b15801561219b57600080fd5b505afa1580156121af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d39190612ef2565b905061104f818484612ab1565b471561221d576040516001600160a01b038216904780156108fc02916000818181858888f1935050505015801561221b573d6000803e3d6000fd5b505b600061222884612076565b111561224c5761224c8161223b85612076565b6001600160a01b0386169190610ff9565b600061225783612076565b111561104f5761104f8161226a84612076565b6001600160a01b0385169190610ff9565b60606118b68484600085612b47565b600080846001600160a01b0316636c25b346856040518263ffffffff1660e01b81526004016122b99190613430565b60206040518083038186803b1580156122d157600080fd5b505afa1580156122e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123099190613111565b90506000856001600160a01b031663d9638d36856040518263ffffffff1660e01b815260040161233991906134aa565b60a06040518083038186803b15801561235157600080fd5b505afa158015612365573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123899190613399565b5050509150506000866001600160a01b0316632424be5c86886040518363ffffffff1660e01b81526004016123bf9291906134b3565b604080518083038186803b1580156123d657600080fd5b505afa1580156123ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240e9190613376565b91505061242382848161241d57fe5b0461244e565b93508084111561243e576124368161244e565b600003612443565b836000035b979650505050505050565b8060008112156108775760405162461bcd60e51b81526004016111d0906136e7565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461249c578161069e565b5073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2919050565b6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461092a5761092a6001600160a01b0383167395e6f48254609a6ee006f7d493c8e5fb97094cef83612c0b565b60006001600160a01b03831673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21461253057504761069e565b8147111561254257814703905061069e565b504792915050565b600080808084600181111561255b57fe5b141561257a576125758660e0015160248860400151612c2a565b61258e565b61258e8660e0015160248860600151612c2a565b60c0860151604051620c045f60e41b8152734ba1f38427b33b8ab7bb0490200dae1f1c36823f9162c045f0916125c79190600401613430565b60206040518083038186803b1580156125df57600080fd5b505afa1580156125f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061261791906130dd565b1561262157600094505b60006126308760200151612076565b60c08801516040516302f5cc7960e11b8152919250734ba1f38427b33b8ab7bb0490200dae1f1c36823f916305eb98f29161266d91600401613430565b60206040518083038186803b15801561268557600080fd5b505afa158015612699573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126bd91906130dd565b15612730578660c001516001600160a01b0316868860e001516040516126e39190613411565b60006040518083038185875af1925050503d8060008114612720576040519150601f19603f3d011682016040523d82523d6000602084013e612725565b606091505b505080945050612735565b600093505b6040870151600090851561286c57885161274e90612076565b60208a01519091506001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141561285a576040516370a0823160e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d9082906370a08231906127b9903090600401613430565b602060405180830381600087803b1580156127d357600080fd5b505af11580156127e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280b9190613111565b6040518263ffffffff1660e01b815260040161282791906134aa565b600060405180830381600087803b15801561284157600080fd5b505af1158015612855573d6000803e3d6000fd5b505050505b826128688a60200151612076565b0391505b90935091505093509350939050565b60a082015160405163e0aa279760e01b81526000917325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa2797916128b891600401613430565b60206040518083038186803b1580156128d057600080fd5b505afa1580156128e4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290891906130dd565b6129245760405162461bcd60e51b81526004016111d0906135bb565b60a083015160408401518451600092612948926001600160a01b0390921691610ff9565b600083600181111561295657fe5b14156129f6578360a001516001600160a01b031663cae270b6828660000151876020015188604001516040518563ffffffff1660e01b815260040161299d9392919061345d565b6020604051808303818588803b1580156129b657600080fd5b505af11580156129ca573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906129ef9190613111565b9150611c7e565b8360a001516001600160a01b031663153e66e6828660000151876020015188606001516040518563ffffffff1660e01b8152600401612a379392919061345d565b6020604051808303818588803b158015612a5057600080fd5b505af1158015612a64573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061069a9190613111565b6000670de0b6b3a7640000610fea612aa1858561122b565b6002670de0b6b3a7640000610fe4565b612ab9612c56565b6001600160a01b0316826001600160a01b03161415612b3357826001600160a01b031681604051612ae99061342d565b60006040518083038185875af1925050503d8060008114612b26576040519150601f19603f3d011682016040523d82523d6000602084013e612b2b565b606091505b50505061104f565b61104f6001600160a01b0383168483610ff9565b6060612b5285612c6e565b612b6e5760405162461bcd60e51b81526004016111d090613666565b60006060866001600160a01b03168587604051612b8b9190613411565b60006040518083038185875af1925050503d8060008114612bc8576040519150601f19603f3d011682016040523d82523d6000602084013e612bcd565b606091505b50915091508115612be15791506118b69050565b805115612bf15780518082602001fd5b8360405162461bcd60e51b81526004016111d091906134ca565b61104f8363095ea7b360e01b8484604051602401611018929190613444565b8160200183511015612c4e5760405162461bcd60e51b81526004016111d090613620565b910160200152565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610872575050151592915050565b60405180610120016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160608152602001600081525090565b6040518061010001604052806008906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b6040518061014001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160001515815260200160006001600160a01b03168152602001600081525090565b803561069e816138a8565b600082601f830112612ddf578081fd5b612de960a061382d565b905080828460a085011115612dfd57600080fd5b60005b6005811015612e29578135612e14816138a8565b83526020928301929190910190600101612e00565b50505092915050565b803561069e816138c0565b600082601f830112612e4d578081fd5b8135612e60612e5b82613854565b61382d565b9150808252836020828501011115612e7757600080fd5b8060208401602084013760009082016020015292915050565b600082601f830112612ea0578081fd5b8151612eae612e5b82613854565b9150808252836020828501011115612ec557600080fd5b611c7e816020840160208601613878565b600060208284031215612ee7578081fd5b8135612145816138a8565b600060208284031215612f03578081fd5b8151612145816138a8565b60008060008060808587031215612f23578283fd5b8451612f2e816138a8565b6020860151909450612f3f816138a8565b6040860151606090960151949790965092505050565b60008060408385031215612f67578182fd5b8235612f72816138a8565b946020939093013593505050565b600080600080600060808688031215612f97578283fd5b8535612fa2816138a8565b94506020860135935060408601359250606086013567ffffffffffffffff80821115612fcc578283fd5b818801915088601f830112612fdf578283fd5b813581811115612fed578384fd5b896020828501011115612ffe578384fd5b9699959850939650602001949392505050565b60008060008060006102008688031215613029578283fd5b86601f870112613037578283fd5b6101006130438161382d565b9087019080888a841115613055578687fd5b865b6008811015613076578135845260209384019390910190600101613057565b505080975050506130878882612dcf565b9450506101a086013567ffffffffffffffff8111156130a4578384fd5b6130b088828901612e3d565b9350506130c1876101c08801612dc4565b91506130d1876101e08801612e32565b90509295509295909350565b6000602082840312156130ee578081fd5b8151612145816138c0565b60006020828403121561310a578081fd5b5035919050565b600060208284031215613122578081fd5b5051919050565b60006020828403121561313a578081fd5b813567ffffffffffffffff811115613150578182fd5b61069a84828501612e3d565b6000806040838503121561316e578182fd5b825167ffffffffffffffff80821115613185578384fd5b61319186838701612e90565b935060208501519150808211156131a6578283fd5b506131b385828601612e90565b9150509250929050565b6000806000606084860312156131d1578081fd5b83356131dc816138a8565b95602085013595506040909401359392505050565b60008060408385031215613203578182fd5b825161320e816138a8565b6020939093015192949293505050565b60006020828403121561322f578081fd5b813567ffffffffffffffff80821115613246578283fd5b818401915061012080838703121561325c578384fd5b6132658161382d565b90506132718684612dc4565b81526132808660208501612dc4565b60208201526040830135604082015260608301356060820152608083013560808201526132b08660a08501612dc4565b60a08201526132c28660c08501612dc4565b60c082015260e0830135828111156132d8578485fd5b6132e487828601612e3d565b60e0830152506101009283013592810192909252509392505050565b600080600080600060a08688031215613317578283fd5b855194506020860151613329816138a8565b604087015190945061333a816138a8565b606087015190935067ffffffffffffffff811115613356578182fd5b61336288828901612e90565b925050608086015190509295509295909350565b60008060408385031215613388578182fd5b505080516020909101519092909150565b600080600080600060a086880312156133b0578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b6001600160a01b03169052565b600081518084526133fd816020860160208601613878565b601f01601f19169290920160200192915050565b60008251613423818460208701613878565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b90815260200190565b9182526001600160a01b0316602082015260400190565b60006020825261214560208301846133e5565b6000604082526134f060408301856133e5565b828103602084015261350281856133e5565b95945050505050565b6020808252601d908201527f4465737420616d6f756e74206d75737420626520737065636966696564000000604082015260600190565b60208082526022908201527f42656c6f77206d696e2e206e756d626572206f66206574682073706563696669604082015261195960f21b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526014908201527315dc985c1c195c881a5cc81b9bdd081d985b1a5960621b604082015260600190565b6020808252601a908201527f46696e616c20616d6f756e742069736e277420636f7272656374000000000000604082015260600190565b60208082526026908201527f496e636f7272656e74206c656e6774207768696c65207772697474696e6720626040820152653cba32b9999960d11b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600c908201526b696e742d6f766572666c6f7760a01b604082015260600190565b6000602082526137216020830184516133d8565b602083015161373360408401826133d8565b506040830151606083015260608301516080830152608083015160a083015260a083015161376460c08401826133d8565b5060c083015161377760e08401826133d8565b5060e083015161012061010081818601526137966101408601846133e5565b9501519301929092525090919050565b9283526001600160a01b03919091166020830152604082015260600190565b8581526001600160a01b0385811660208301528416604082015260a0606082018190526000906137f7908301856133e5565b90508260808301529695505050505050565b9283526020830191909152604082015260600190565b918252602082015260400190565b60405181810167ffffffffffffffff8111828210171561384c57600080fd5b604052919050565b600067ffffffffffffffff82111561386a578081fd5b50601f01601f191660200190565b60005b8381101561389357818101518382015260200161387b565b838111156138a2576000848401525b50505050565b6001600160a01b03811681146138bd57600080fd5b50565b80151581146138bd57600080fdfea2646970667358221220580a83bdc6e1f6ce59c76cac0ce6537999b79b83447ea7b4ea98af412853b0a664736f6c634300060c0033
Deployed Bytecode
0x6080604052600436106101e75760003560e01c80638c8a795811610102578063cf786f8f11610095578063deca5f8811610064578063deca5f88146104a5578063ee872558146104c5578063f1d25396146104e5578063f851a440146104fa576101ee565b8063cf786f8f146102e1578063cfac57c714610451578063d0cc72891461047b578063d3661fa514610490576101ee565b8063a46a66c9116100d1578063a46a66c91461041c578063a7304bf714610431578063c11645bc14610451578063c72c4d1014610466576101ee565b80638c8a7958146103b05780638da5cb5b146103c557806398ab3d49146103da578063a3b8e5d1146103ef576101ee565b806336569e771161017a578063481c6a7511610149578063481c6a751461035957806350c86de51461036e57806353485907146103835780636738929f1461026a576101ee565b806336569e77146102e15780633a128322146102f65780634115fe6b1461031657806341c0e1b514610344576101ee565b80632e77468d116101b65780632e77468d1461026a5780632f634a901461027f578063314b63321461029f57806331d98b3f146102b4576101ee565b8063040141e5146101f35780631e48907b1461021e57806329f7fc9e146102405780632a4c0a1a14610255576101ee565b366101ee57005b600080fd5b3480156101ff57600080fd5b5061020861050f565b6040516102159190613430565b60405180910390f35b34801561022a57600080fd5b5061023e610239366004612ed6565b610527565b005b34801561024c57600080fd5b50610208610560565b34801561026157600080fd5b50610208610578565b34801561027657600080fd5b50610208610590565b34801561028b57600080fd5b5061020861029a366004612f55565b6105a8565b3480156102ab57600080fd5b506102086106a4565b3480156102c057600080fd5b506102d46102cf3660046130f9565b6106bc565b60405161021591906134aa565b3480156102ed57600080fd5b5061020861087c565b34801561030257600080fd5b5061023e610311366004612f55565b610894565b34801561032257600080fd5b506103366103313660046131bd565b61092e565b60405161021592919061381f565b34801561035057600080fd5b5061023e610b4a565b34801561036557600080fd5b50610208610b6f565b34801561037a57600080fd5b506102d4610b87565b34801561038f57600080fd5b506103a361039e36600461321e565b610b8d565b60405161021591906134ca565b3480156103bc57600080fd5b50610208610c31565b3480156103d157600080fd5b50610208610c49565b3480156103e657600080fd5b50610208610c58565b3480156103fb57600080fd5b5061040f61040a366004613129565b610c67565b604051610215919061370d565b34801561042857600080fd5b50610208610d01565b34801561043d57600080fd5b5061023e61044c366004612ed6565b610d19565b34801561045d57600080fd5b50610208610d52565b34801561047257600080fd5b50610208610d6a565b34801561048757600080fd5b50610208610d79565b34801561049c57600080fd5b50610208610d91565b3480156104b157600080fd5b5061023e6104c0366004612ed6565b610da9565b3480156104d157600080fd5b5061023e6104e0366004612f80565b610dd6565b3480156104f157600080fd5b50610208610f91565b34801561050657600080fd5b50610208610fa9565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6002546001600160a01b0316331461053e57600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b736b175474e89094c44da98b954eedeac495271d0f81565b7365c79fcb50ca1594b025960e539ed7a9a6d434a381565b600080836001600160a01b0316638161b120846040518263ffffffff1660e01b81526004016105d791906134aa565b60206040518083038186803b1580156105ef57600080fd5b505afa158015610603573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106279190612ef2565b9050806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561066257600080fd5b505afa158015610676573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061069a9190612ef2565b9150505b92915050565b7325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d81565b604051636cb1c69b60e11b815260009081907365c79fcb50ca1594b025960e539ed7a9a6d434a39063d9638d36906106f89086906004016134aa565b604080518083038186803b15801561070f57600080fd5b505afa158015610723573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074791906131f1565b604051636cb1c69b60e11b8152909250600091507335d1b3f3d7966a1dfe207aa4514c12a259a0492b9063d9638d36906107859087906004016134aa565b60a06040518083038186803b15801561079d57600080fd5b505afa1580156107b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d59190613399565b50509250505061087261086c827365c79fcb50ca1594b025960e539ed7a9a6d434a36001600160a01b031663495d32cb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561082f57600080fd5b505afa158015610843573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108679190613111565b610fb8565b83610fb8565b925050505b919050565b7335d1b3f3d7966a1dfe207aa4514c12a259a0492b81565b6001546001600160a01b031633146108ab57600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b0383161415610910576001546040516001600160a01b039091169082156108fc029083906000818181858888f1935050505015801561090a573d6000803e3d6000fd5b5061092a565b60015461092a906001600160a01b03848116911683610ff9565b5050565b6000806000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b15801561096c57600080fd5b505afa158015610980573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a49190612ef2565b90506000866001600160a01b0316632726b073876040518263ffffffff1660e01b81526004016109d491906134aa565b60206040518083038186803b1580156109ec57600080fd5b505afa158015610a00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a249190612ef2565b9050600080836001600160a01b0316632424be5c88856040518363ffffffff1660e01b8152600401610a579291906134b3565b604080518083038186803b158015610a6e57600080fd5b505afa158015610a82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa69190613376565b915091506000846001600160a01b031663d9638d36896040518263ffffffff1660e01b8152600401610ad891906134aa565b60a06040518083038186803b158015610af057600080fd5b505afa158015610b04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b289190613399565b50505091505082610b398383610fb8565b965096505050505050935093915050565b6001546001600160a01b03163314610b6157600080fd5b6001546001600160a01b0316ff5b735ef30b9986345249bc32d8928b7ee64de9435e3981565b61019081565b6060808260000151836020015184604001518560600151604051602001610bb79493929190613481565b60408051601f1981840301815290829052608085015160a086015160c087015160e0880151610100890151949650606095610bf595906020016137c5565b60405160208183030381529060405290508181604051602001610c199291906134dd565b60405160208183030381529060405292505050919050565b734ba1f38427b33b8ab7bb0490200dae1f1c36823f81565b6001546001600160a01b031681565b6003546001600160a01b031681565b610c6f612ca7565b60608083806020019051810190610c86919061315c565b9150915081806020019051810190610c9e9190612f0e565b606087015260408601526001600160a01b03908116602080870191909152911684528151610cd3919083018101908301613300565b61010088015260e08701526001600160a01b0390811660c08701521660a08501526080840152509092915050565b731b14e8d511c9a4395425314f849bd737baf8208f81565b6002546001600160a01b03163314610d3057600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b739759a6ac90977b93b58547b4a71c78317f391a2881565b6000546001600160a01b031681565b7395e6f48254609a6ee006f7d493c8e5fb97094cef81565b73322d58b9e75a6918f7e7849aee0ff09369977e0881565b6001546001600160a01b03163314610dc057600080fd5b6002546001600160a01b031615610d3057600080fd5b610dde612d17565b610de6612d36565b6060600080610df786880188613011565b94509450945094509450610e09612ca7565b50604080516101208101825285516001600160a01b0390811682526020808801518216908301526080888101518385015260a0808a015160608086019190915260c0808c01519386019390935289015183169084015292870151169181019190915260e0808201859052860151610100820152610e84612d54565b6040805161014081018252885181526020808a0151908201528882015191810191909152606080890151908201526080810187600460200201516001600160a01b03168152602001856001600160a01b031681526020018b815260200184151581526020018d6001600160a01b031681526020018c815250905060008160a001516001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f3d57600080fd5b505afa158015610f51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f759190612ef2565b9050610f82828483611054565b50505050505050505050505050565b732f0b23f53734252bda2277357e97e1517d6b042a81565b6002546001600160a01b031681565b60006b033b2e3c9fd0803ce8000000610fea610fd4858561122b565b60026b033b2e3c9fd0803ce80000005b0461124f565b81610ff157fe5b049392505050565b61104f8363a9059cbb60e01b8484604051602401611018929190613444565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261125f565b505050565b8251604051632c2cb9fd60e01b81526110ec9190735ef30b9986345249bc32d8928b7ee64de9435e3990632c2cb9fd906110929084906004016134aa565b60206040518083038186803b1580156110aa57600080fd5b505afa1580156110be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e29190613111565b85604001516112ee565b600061110584600001518560800151866020015161157a565b90506000808560e00151156111395760408501839052611124856118be565b925061113290508285611b35565b9050611168565b611147866040015185611b35565b60c087015160408801510181016060870152905061116485611c85565b9250505b61117181611f16565b5060006111818760800151611fbe565b90508660e00151156111a45750736b175474e89094c44da98b954eedeac495271d0f5b86606001516111b282612076565b10156111d95760405162461bcd60e51b81526004016111d090613542565b60405180910390fd5b6112038761010001516111fe8960c001518a610120015161212090919063ffffffff16565b61214c565b61122281736b175474e89094c44da98b954eedeac495271d0f876121e0565b50505050505050565b60008115806112465750508082028282828161124357fe5b04145b61069e57600080fd5b8082018281101561069e57600080fd5b60606112b4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661227b9092919063ffffffff16565b80519091501561104f57808060200190518101906112d291906130dd565b61104f5760405162461bcd60e51b81526004016111d09061369d565b604051632726b07360e01b8152600090735ef30b9986345249bc32d8928b7ee64de9435e3990632726b073906113289087906004016134aa565b60206040518083038186803b15801561134057600080fd5b505afa158015611354573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113789190612ef2565b9050739759a6ac90977b93b58547b4a71c78317f391a286001600160a01b031663f4b9fa756040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156113c957600080fd5b505af11580156113dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114019190612ef2565b6001600160a01b031663095ea7b3739759a6ac90977b93b58547b4a71c78317f391a28846040518363ffffffff1660e01b8152600401611442929190613444565b600060405180830381600087803b15801561145c57600080fd5b505af1158015611470573d6000803e3d6000fd5b5050604051633b4da69f60e01b8152739759a6ac90977b93b58547b4a71c78317f391a289250633b4da69f91506114ad9084908690600401613444565b600060405180830381600087803b1580156114c757600080fd5b505af11580156114db573d6000803e3d6000fd5b50505050735ef30b9986345249bc32d8928b7ee64de9435e396001600160a01b03166345e6bdcd8560006115247335d1b3f3d7966a1dfe207aa4514c12a259a0492b868961228a565b6040518463ffffffff1660e01b815260040161154293929190613809565b600060405180830381600087803b15801561155c57600080fd5b505af1158015611570573d6000803e3d6000fd5b5050505050505050565b6000735ef30b9986345249bc32d8928b7ee64de9435e396345e6bdcd856115a08561244e565b60000360006040518463ffffffff1660e01b81526004016115c393929190613809565b600060405180830381600087803b1580156115dd57600080fd5b505af11580156115f1573d6000803e3d6000fd5b50506040516313771f0760e31b8152735ef30b9986345249bc32d8928b7ee64de9435e399250639bb8f8389150611630908790309087906004016137a6565b600060405180830381600087803b15801561164a57600080fd5b505af115801561165e573d6000803e3d6000fd5b505050506000829050836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b1580156116a057600080fd5b505afa1580156116b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d89190613111565b60121461176257836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561171857600080fd5b505afa15801561172c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117509190613111565b601203600a0a838161175e57fe5b0490505b60405163ef693bed60e01b81526001600160a01b0385169063ef693bed906117909030908590600401613444565b600060405180830381600087803b1580156117aa57600080fd5b505af11580156117be573d6000803e3d6000fd5b505050506001600160a01b038416732f0b23f53734252bda2277357e97e1517d6b042a14156118b657836001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561182057600080fd5b505afa158015611834573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118589190612ef2565b6001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040161188391906134aa565b600060405180830381600087803b15801561189d57600080fd5b505af11580156118b1573d6000803e3d6000fd5b505050505b949350505050565b604081015181516000918291829182918291906001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141561197657865161190090612470565b6001600160a01b031687526040808801518151630d0e30db60e41b8152915173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29263d0e30db09291600480830192600092919082900301818588803b15801561195c57600080fd5b505af1158015611970573d6000803e3d6000fd5b50505050505b610100870151156119cd57611993876000015188604001516124b7565b60006119a788600001518960400151612503565b90506119b58882600061254a565b909550909350915082156119cb578760c0015194505b505b816119e7576119dd87600061287b565b92508660a0015193505b6119f987608001518860400151612a89565b611a068860200151612076565b1015611a245760405162461bcd60e51b81526004016111d0906135e9565b6000611a4373c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2612076565b1115611b29576040516370a0823160e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d9082906370a0823190611a88903090600401613430565b602060405180830381600087803b158015611aa257600080fd5b505af1158015611ab6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ada9190613111565b6040518263ffffffff1660e01b8152600401611af691906134aa565b600060405180830381600087803b158015611b1057600080fd5b505af1158015611b24573d6000803e3d6000fd5b505050505b50919350915050915091565b604051632cdc77ab60e21b815260009061019090731b14e8d511c9a4395425314f849bd737baf8208f9063b371deac90611b73908690600401613430565b60206040518083038186803b158015611b8b57600080fd5b505afa158015611b9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc391906130dd565b15611c5257604051636eeb543160e01b8152731b14e8d511c9a4395425314f849bd737baf8208f90636eeb543190611bff908690600401613430565b60206040518083038186803b158015611c1757600080fd5b505afa158015611c2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c4f9190613111565b90505b8015611c6757808481611c6157fe5b04611c6a565b60005b915060058404821115611c7e576005840491505b5092915050565b6000806000806000856060015160001415611cb25760405162461bcd60e51b81526004016111d09061350b565b85516001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415611d59578551611ce390612470565b6001600160a01b031686526040808701518151630d0e30db60e41b8152915173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29263d0e30db09291600480830192600092919082900301818588803b158015611d3f57600080fd5b505af1158015611d53573d6000803e3d6000fd5b50505050505b61010086015115611dad57611d76866000015187604001516124b7565b6000611d8a87600001518860400151612503565b9050611d988782600161254a565b50935091508115611dab578660c0015193505b505b80611dc757611dbd86600161287b565b91508560a0015192505b8560600151611dd98760200151612076565b1015611df75760405162461bcd60e51b81526004016111d0906135e9565b6000611e1673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2612076565b1115611efc576040516370a0823160e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d9082906370a0823190611e5b903090600401613430565b602060405180830381600087803b158015611e7557600080fd5b505af1158015611e89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ead9190613111565b6040518263ffffffff1660e01b8152600401611ec991906134aa565b600060405180830381600087803b158015611ee357600080fd5b505af1158015611ef7573d6000803e3d6000fd5b505050505b82611f0a8760200151612076565b94509450505050915091565b60405163a9059cbb60e01b8152600090736b175474e89094c44da98b954eedeac495271d0f9063a9059cbb90611f669073322d58b9e75a6918f7e7849aee0ff09369977e08908690600401613444565b602060405180830381600087803b158015611f8057600080fd5b505af1158015611f94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb891906130dd565b50919050565b600080826001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015611ffa57600080fd5b505afa15801561200e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120329190612ef2565b90506001600160a01b03811673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2141561069e5773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee915050610877565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156120a4575047610877565b6040516370a0823160e01b81526001600160a01b038316906370a08231906120d0903090600401613430565b60206040518083038186803b1580156120e857600080fd5b505afa1580156120fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061069e9190613111565b6000828201838110156121455760405162461bcd60e51b81526004016111d090613584565b9392505050565b60008060009054906101000a90046001600160a01b03166001600160a01b031663ed6ff7606040518163ffffffff1660e01b815260040160206040518083038186803b15801561219b57600080fd5b505afa1580156121af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d39190612ef2565b905061104f818484612ab1565b471561221d576040516001600160a01b038216904780156108fc02916000818181858888f1935050505015801561221b573d6000803e3d6000fd5b505b600061222884612076565b111561224c5761224c8161223b85612076565b6001600160a01b0386169190610ff9565b600061225783612076565b111561104f5761104f8161226a84612076565b6001600160a01b0385169190610ff9565b60606118b68484600085612b47565b600080846001600160a01b0316636c25b346856040518263ffffffff1660e01b81526004016122b99190613430565b60206040518083038186803b1580156122d157600080fd5b505afa1580156122e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123099190613111565b90506000856001600160a01b031663d9638d36856040518263ffffffff1660e01b815260040161233991906134aa565b60a06040518083038186803b15801561235157600080fd5b505afa158015612365573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123899190613399565b5050509150506000866001600160a01b0316632424be5c86886040518363ffffffff1660e01b81526004016123bf9291906134b3565b604080518083038186803b1580156123d657600080fd5b505afa1580156123ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240e9190613376565b91505061242382848161241d57fe5b0461244e565b93508084111561243e576124368161244e565b600003612443565b836000035b979650505050505050565b8060008112156108775760405162461bcd60e51b81526004016111d0906136e7565b60006001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461249c578161069e565b5073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2919050565b6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461092a5761092a6001600160a01b0383167395e6f48254609a6ee006f7d493c8e5fb97094cef83612c0b565b60006001600160a01b03831673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21461253057504761069e565b8147111561254257814703905061069e565b504792915050565b600080808084600181111561255b57fe5b141561257a576125758660e0015160248860400151612c2a565b61258e565b61258e8660e0015160248860600151612c2a565b60c0860151604051620c045f60e41b8152734ba1f38427b33b8ab7bb0490200dae1f1c36823f9162c045f0916125c79190600401613430565b60206040518083038186803b1580156125df57600080fd5b505afa1580156125f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061261791906130dd565b1561262157600094505b60006126308760200151612076565b60c08801516040516302f5cc7960e11b8152919250734ba1f38427b33b8ab7bb0490200dae1f1c36823f916305eb98f29161266d91600401613430565b60206040518083038186803b15801561268557600080fd5b505afa158015612699573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126bd91906130dd565b15612730578660c001516001600160a01b0316868860e001516040516126e39190613411565b60006040518083038185875af1925050503d8060008114612720576040519150601f19603f3d011682016040523d82523d6000602084013e612725565b606091505b505080945050612735565b600093505b6040870151600090851561286c57885161274e90612076565b60208a01519091506001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141561285a576040516370a0823160e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d9082906370a08231906127b9903090600401613430565b602060405180830381600087803b1580156127d357600080fd5b505af11580156127e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280b9190613111565b6040518263ffffffff1660e01b815260040161282791906134aa565b600060405180830381600087803b15801561284157600080fd5b505af1158015612855573d6000803e3d6000fd5b505050505b826128688a60200151612076565b0391505b90935091505093509350939050565b60a082015160405163e0aa279760e01b81526000917325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa2797916128b891600401613430565b60206040518083038186803b1580156128d057600080fd5b505afa1580156128e4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290891906130dd565b6129245760405162461bcd60e51b81526004016111d0906135bb565b60a083015160408401518451600092612948926001600160a01b0390921691610ff9565b600083600181111561295657fe5b14156129f6578360a001516001600160a01b031663cae270b6828660000151876020015188604001516040518563ffffffff1660e01b815260040161299d9392919061345d565b6020604051808303818588803b1580156129b657600080fd5b505af11580156129ca573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906129ef9190613111565b9150611c7e565b8360a001516001600160a01b031663153e66e6828660000151876020015188606001516040518563ffffffff1660e01b8152600401612a379392919061345d565b6020604051808303818588803b158015612a5057600080fd5b505af1158015612a64573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061069a9190613111565b6000670de0b6b3a7640000610fea612aa1858561122b565b6002670de0b6b3a7640000610fe4565b612ab9612c56565b6001600160a01b0316826001600160a01b03161415612b3357826001600160a01b031681604051612ae99061342d565b60006040518083038185875af1925050503d8060008114612b26576040519150601f19603f3d011682016040523d82523d6000602084013e612b2b565b606091505b50505061104f565b61104f6001600160a01b0383168483610ff9565b6060612b5285612c6e565b612b6e5760405162461bcd60e51b81526004016111d090613666565b60006060866001600160a01b03168587604051612b8b9190613411565b60006040518083038185875af1925050503d8060008114612bc8576040519150601f19603f3d011682016040523d82523d6000602084013e612bcd565b606091505b50915091508115612be15791506118b69050565b805115612bf15780518082602001fd5b8360405162461bcd60e51b81526004016111d091906134ca565b61104f8363095ea7b360e01b8484604051602401611018929190613444565b8160200183511015612c4e5760405162461bcd60e51b81526004016111d090613620565b910160200152565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610872575050151592915050565b60405180610120016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160608152602001600081525090565b6040518061010001604052806008906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b6040518061014001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160001515815260200160006001600160a01b03168152602001600081525090565b803561069e816138a8565b600082601f830112612ddf578081fd5b612de960a061382d565b905080828460a085011115612dfd57600080fd5b60005b6005811015612e29578135612e14816138a8565b83526020928301929190910190600101612e00565b50505092915050565b803561069e816138c0565b600082601f830112612e4d578081fd5b8135612e60612e5b82613854565b61382d565b9150808252836020828501011115612e7757600080fd5b8060208401602084013760009082016020015292915050565b600082601f830112612ea0578081fd5b8151612eae612e5b82613854565b9150808252836020828501011115612ec557600080fd5b611c7e816020840160208601613878565b600060208284031215612ee7578081fd5b8135612145816138a8565b600060208284031215612f03578081fd5b8151612145816138a8565b60008060008060808587031215612f23578283fd5b8451612f2e816138a8565b6020860151909450612f3f816138a8565b6040860151606090960151949790965092505050565b60008060408385031215612f67578182fd5b8235612f72816138a8565b946020939093013593505050565b600080600080600060808688031215612f97578283fd5b8535612fa2816138a8565b94506020860135935060408601359250606086013567ffffffffffffffff80821115612fcc578283fd5b818801915088601f830112612fdf578283fd5b813581811115612fed578384fd5b896020828501011115612ffe578384fd5b9699959850939650602001949392505050565b60008060008060006102008688031215613029578283fd5b86601f870112613037578283fd5b6101006130438161382d565b9087019080888a841115613055578687fd5b865b6008811015613076578135845260209384019390910190600101613057565b505080975050506130878882612dcf565b9450506101a086013567ffffffffffffffff8111156130a4578384fd5b6130b088828901612e3d565b9350506130c1876101c08801612dc4565b91506130d1876101e08801612e32565b90509295509295909350565b6000602082840312156130ee578081fd5b8151612145816138c0565b60006020828403121561310a578081fd5b5035919050565b600060208284031215613122578081fd5b5051919050565b60006020828403121561313a578081fd5b813567ffffffffffffffff811115613150578182fd5b61069a84828501612e3d565b6000806040838503121561316e578182fd5b825167ffffffffffffffff80821115613185578384fd5b61319186838701612e90565b935060208501519150808211156131a6578283fd5b506131b385828601612e90565b9150509250929050565b6000806000606084860312156131d1578081fd5b83356131dc816138a8565b95602085013595506040909401359392505050565b60008060408385031215613203578182fd5b825161320e816138a8565b6020939093015192949293505050565b60006020828403121561322f578081fd5b813567ffffffffffffffff80821115613246578283fd5b818401915061012080838703121561325c578384fd5b6132658161382d565b90506132718684612dc4565b81526132808660208501612dc4565b60208201526040830135604082015260608301356060820152608083013560808201526132b08660a08501612dc4565b60a08201526132c28660c08501612dc4565b60c082015260e0830135828111156132d8578485fd5b6132e487828601612e3d565b60e0830152506101009283013592810192909252509392505050565b600080600080600060a08688031215613317578283fd5b855194506020860151613329816138a8565b604087015190945061333a816138a8565b606087015190935067ffffffffffffffff811115613356578182fd5b61336288828901612e90565b925050608086015190509295509295909350565b60008060408385031215613388578182fd5b505080516020909101519092909150565b600080600080600060a086880312156133b0578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b6001600160a01b03169052565b600081518084526133fd816020860160208601613878565b601f01601f19169290920160200192915050565b60008251613423818460208701613878565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b90815260200190565b9182526001600160a01b0316602082015260400190565b60006020825261214560208301846133e5565b6000604082526134f060408301856133e5565b828103602084015261350281856133e5565b95945050505050565b6020808252601d908201527f4465737420616d6f756e74206d75737420626520737065636966696564000000604082015260600190565b60208082526022908201527f42656c6f77206d696e2e206e756d626572206f66206574682073706563696669604082015261195960f21b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526014908201527315dc985c1c195c881a5cc81b9bdd081d985b1a5960621b604082015260600190565b6020808252601a908201527f46696e616c20616d6f756e742069736e277420636f7272656374000000000000604082015260600190565b60208082526026908201527f496e636f7272656e74206c656e6774207768696c65207772697474696e6720626040820152653cba32b9999960d11b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600c908201526b696e742d6f766572666c6f7760a01b604082015260600190565b6000602082526137216020830184516133d8565b602083015161373360408401826133d8565b506040830151606083015260608301516080830152608083015160a083015260a083015161376460c08401826133d8565b5060c083015161377760e08401826133d8565b5060e083015161012061010081818601526137966101408601846133e5565b9501519301929092525090919050565b9283526001600160a01b03919091166020830152604082015260600190565b8581526001600160a01b0385811660208301528416604082015260a0606082018190526000906137f7908301856133e5565b90508260808301529695505050505050565b9283526020830191909152604082015260600190565b918252602082015260400190565b60405181810167ffffffffffffffff8111828210171561384c57600080fd5b604052919050565b600067ffffffffffffffff82111561386a578081fd5b50601f01601f191660200190565b60005b8381101561389357818101518382015260200161387b565b838111156138a2576000848401525b50505050565b6001600160a01b03811681146138bd57600080fd5b50565b80151581146138bd57600080fdfea2646970667358221220580a83bdc6e1f6ce59c76cac0ce6537999b79b83447ea7b4ea98af412853b0a664736f6c634300060c0033
Deployed Bytecode Sourcemap
54214:6362:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27203:81;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;23713:122;;;;;;;;;;-1:-1:-1;23713:122:0;;;;;:::i;:::-;;:::i;:::-;;27110:86;;;;;;;;;;;;;:::i;54646:80::-;;;;;;;;;;;;;:::i;55255:58::-;;;;;;;;;;;;;:::i;15930:186::-;;;;;;;;;;-1:-1:-1;15930:186:0;;;;;:::i;:::-;;:::i;27478:92::-;;;;;;;;;;;;;:::i;60260:223::-;;;;;;;;;;-1:-1:-1;60260:223:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;55320:42::-;;;;;;;;;;;;;:::i;24008:285::-;;;;;;;;;;-1:-1:-1;24008:285:0;;;;;:::i;:::-;;:::i;15421:357::-;;;;;;;;;;-1:-1:-1;15421:357:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;23881:80::-;;;;;;;;;;;;;:::i;55097:85::-;;;;;;;;;;;;;:::i;54475:38::-;;;;;;;;;;;;;:::i;38259:641::-;;;;;;;;;;-1:-1:-1;38259:641:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;27669:87::-;;;;;;;;;;;;;:::i;22820:20::-;;;;;;;;;;;;;:::i;54324:142::-;;;;;;;;;;;;;:::i;38908:684::-;;;;;;;;;;-1:-1:-1;38908:684:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;27386:85::-;;;;;;;;;;;;;:::i;23492:122::-;;;;;;;;;;-1:-1:-1;23492:122:0;;;;;:::i;:::-;;:::i;55189:59::-;;;;;;;;;;;;;:::i;53117:54::-;;;;;;;;;;;;;:::i;27579:83::-;;;;;;;;;;;;;:::i;27293:86::-;;;;;;;;;;;;;:::i;23209:161::-;;;;;;;;;;-1:-1:-1;23209:161:0;;;;;:::i;:::-;;:::i;55728:1334::-;;;;;;;;;;-1:-1:-1;55728:1334:0;;;;;:::i;:::-;;:::i;54825:85::-;;;;;;;;;;;;;:::i;22847:20::-;;;;;;;;;;;;;:::i;27203:81::-;27242:42;27203:81;:::o;23713:122::-;23794:5;;-1:-1:-1;;;;;23794:5:0;23780:10;:19;23772:28;;;;;;23813:5;:14;;-1:-1:-1;;;;;;23813:14:0;-1:-1:-1;;;;;23813:14:0;;;;;;;;;;23713:122::o;27110:86::-;27154:42;27110:86;:::o;54646:80::-;54684:42;54646:80;:::o;55255:58::-;54959:42;55255:58;:::o;15930:186::-;16000:7;16020:13;16052:8;-1:-1:-1;;;;;16052:13:0;;16066:6;16052:21;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16020:55;;16095:5;-1:-1:-1;;;;;16095:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16088:20;;;15930:186;;;;;:::o;27478:92::-;27528:42;27478:92;:::o;60260:223::-;60351:18;;-1:-1:-1;;;60351:18:0;;60313:7;;;;54959:42;;60351:12;;:18;;60364:4;;60351:18;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60405:14;;-1:-1:-1;;;60405:14:0;;60333:36;;-1:-1:-1;60385:12:0;;-1:-1:-1;55046:42:0;;60405:8;;:14;;60414:4;;60405:14;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60380:39;;;;;;60439:36;60444:25;60449:4;54959:42;-1:-1:-1;;;;;60455:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60444:4;:25::i;:::-;60471:3;60439:4;:36::i;:::-;60432:43;;;;60260:223;;;;:::o;55320:42::-;55046;55320;:::o;24008:285::-;22916:5;;-1:-1:-1;;;;;22916:5:0;22925:10;22916:19;22908:28;;;;;;24108:42:::1;-1:-1:-1::0;;;;;24098:52:0;::::1;;24094:192;;;24175:5;::::0;24167:32:::1;::::0;-1:-1:-1;;;;;24175:5:0;;::::1;::::0;24167:32;::::1;;;::::0;24191:7;;24175:5:::1;24167:32:::0;24175:5;24167:32;24191:7;24175:5;24167:32;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;24094:192;;;24259:5;::::0;24232:42:::1;::::0;-1:-1:-1;;;;;24232:26:0;;::::1;::::0;24259:5:::1;24266:7:::0;24232:26:::1;:42::i;:::-;24008:285:::0;;:::o;15421:357::-;15507:4;15513;15530:11;15544:8;-1:-1:-1;;;;;15544:12:0;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15530:28;;15569:11;15583:8;-1:-1:-1;;;;;15583:13:0;;15597:6;15583:21;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15569:35;;15618:15;15635:9;15652:3;-1:-1:-1;;;;;15648:13:0;;15662:4;15668:3;15648:24;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15617:55;;;;15685:9;15705:3;-1:-1:-1;;;;;15701:13:0;;15715:4;15701:19;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15683:37;;;;;;15741:10;15753:16;15758:4;15764;15753;:16::i;:::-;15733:37;;;;;;;;;15421:357;;;;;;:::o;23881:80::-;22916:5;;-1:-1:-1;;;;;22916:5:0;22925:10;22916:19;22908:28;;;;;;23946:5:::1;::::0;-1:-1:-1;;;;;23946:5:0::1;23925:28;55097:85:::0;55139:42;55097:85;:::o;54475:38::-;54510:3;54475:38;:::o;38259:641::-;38334:12;38466:18;38512:7;:15;;;38542:7;:16;;;38573:7;:17;;;38605:7;:18;;;38487:147;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;38487:147:0;;;;;;;;;;38693:16;;;;38724:15;;;;38754:20;;;;38789:16;;;;38820:15;;;;38487:147;;-1:-1:-1;38647:18:0;;38668:178;;38820:15;38487:147;38668:178;;:::i;:::-;;;;;;;;;;;;;38647:199;;38879:5;38886;38868:24;;;;;;;;;:::i;:::-;;;;;;;;;;;;;38861:31;;;;38259:641;;;:::o;27669:87::-;27714:42;27669:87;:::o;22820:20::-;;;-1:-1:-1;;;;;22820:20:0;;:::o;54324:142::-;;;-1:-1:-1;;;;;54324:142:0;;:::o;38908:684::-;38976:27;;:::i;:::-;39031:18;39064;39107:5;39096:32;;;;;;;;;;;;:::i;:::-;39016:112;;;;39292:5;39281:52;;;;;;;;;;;;:::i;:::-;39249:18;;;39141:192;39217:17;;;39141:192;-1:-1:-1;;;;;39141:192:0;;;39186:16;;;;39141:192;;;;;;;;39526:58;;;;;;;;;;;;;:::i;:::-;39488:15;;;39346:238;39457:16;;;39346:238;-1:-1:-1;;;;;39346:238:0;;;39422:20;;;39346:238;;39392:15;;;39346:238;39361:16;;;39346:238;-1:-1:-1;39361:7:0;;38908:684;-1:-1:-1;;38908:684:0:o;27386:85::-;27429:42;27386:85;:::o;23492:122::-;23573:5;;-1:-1:-1;;;;;23573:5:0;23559:10;:19;23551:28;;;;;;23592:5;:14;;-1:-1:-1;;;;;;23592:14:0;-1:-1:-1;;;;;23592:14:0;;;;;;;;;;23492:122::o;55189:59::-;54776:42;55189:59;:::o;53117:54::-;;;-1:-1:-1;;;;;53117:54:0;;:::o;27579:83::-;27620:42;27579:83;:::o;27293:86::-;27337:42;27293:86;:::o;23209:161::-;23290:5;;-1:-1:-1;;;;;23290:5:0;23276:10;:19;23268:28;;;;;;23315:5;;-1:-1:-1;;;;;23315:5:0;:19;23307:28;;;;;55728:1334;55915:22;;:::i;:::-;55952:26;;:::i;:::-;55993:21;56029:13;;56091:63;;;;56102:7;56091:63;:::i;:::-;55900:254;;;;;;;;;;56167:32;;:::i;:::-;-1:-1:-1;56202:346:0;;;;;;;;56239:11;;-1:-1:-1;;;;;56202:346:0;;;;;56239:11;56275;;;;56202:346;;;;;;56312:10;;;;;56202:346;;;;56349:10;;;;;56202:346;;;;;;;;56384:10;;;;;56202:346;;;;;;;56418:11;;;56202:346;;;;;;56458:11;;;;56202:346;;;;;;;;;;;;;;;56526:10;;;56202:346;;;;56561:26;;:::i;:::-;56590:343;;;;;;;;56622:10;;56590:343;;56622:10;56659;;;;56590:343;;;;56695:10;;;;56590:343;;;;;;;;56733:10;;;;56590:343;;;;;;;56768:8;56777:1;56768:11;;;;-1:-1:-1;;;;;56590:343:0;;;;;56801:5;-1:-1:-1;;;;;56590:343:0;;;;;56828:4;56590:343;;;;56854:5;56590:343;;;;;;56883:8;-1:-1:-1;;;;;56590:343:0;;;;;56914:7;56590:343;;;56561:372;;56946:12;56977:9;:15;;;-1:-1:-1;;;;;56961:39:0;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56946:56;;57015:39;57024:9;57035:12;57049:4;57015:8;:39::i;:::-;55728:1334;;;;;;;;;;;;;:::o;54825:85::-;54868:42;54825:85;:::o;22847:20::-;;;-1:-1:-1;;;;;22847:20:0;;:::o;6835:122::-;6894:9;6690:6;6920:23;6924:9;6928:1;6931;6924:3;:9::i;:::-;6941:1;6690:6;6935:7;;6920:3;:23::i;:::-;:29;;;;;;;6835:122;-1:-1:-1;;;6835:122:0:o;20963:176::-;21045:86;21065:5;21095:23;;;21120:2;21124:5;21072:58;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;21072:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;21072:58:0;-1:-1:-1;;;;;;21072:58:0;;;;;;;;;;21045:19;:86::i;:::-;20963:176;;;:::o;57070:1338::-;57235:16;;57253:30;;-1:-1:-1;;;57253:30:0;;57223:83;;57235:16;55139:42;;57253:12;;:30;;57235:16;;57253:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57285:10;:20;;;57223:11;:83::i;:::-;57339:16;57358:79;57376:10;:16;;;57394:10;:19;;;57415:10;:21;;;57358:17;:79::i;:::-;57339:98;;57475:14;57504:11;57536:10;:16;;;57532:408;;;57569:23;;;:37;;;57637:20;57569:13;57637:5;:20::i;:::-;57621:36;-1:-1:-1;57683:24:0;;-1:-1:-1;57621:36:0;57701:5;57683:6;:24::i;:::-;57674:33;;57532:408;;;57749:35;57756:10;:20;;;57778:5;57749:6;:35::i;:::-;57852:16;;;;57829:20;;;;:39;:48;;57801:24;;;:77;57740:44;-1:-1:-1;57909:19:0;57801:13;57909:4;:19::i;:::-;57893:35;-1:-1:-1;;57532:408:0;57952:15;57960:6;57952:7;:15::i;:::-;;57980:17;58000:37;58017:10;:19;;;58000:16;:37::i;:::-;57980:57;;58054:10;:16;;;58050:72;;;-1:-1:-1;54684:42:0;58050:72;58167:10;:22;;;58142:21;58153:9;58142:10;:21::i;:::-;:47;;58134:94;;;;-1:-1:-1;;;58134:94:0;;;;;;;:::i;:::-;;;;;;;;;58241:92;58273:10;:18;;;58293:39;58315:10;:16;;;58293:10;:17;;;:21;;:39;;;;:::i;:::-;58241:31;:92::i;:::-;58346:52;58359:9;54684:42;58391:5;58346:12;:52::i;:::-;57070:1338;;;;;;;:::o;5924:127::-;5982:9;6012:6;;;:30;;-1:-1:-1;;6027:5:0;;;6041:1;6036;6027:5;6036:1;6022:15;;;;;:20;6012:30;6004:39;;;;;5682:113;5775:5;;;5770:16;;;;5762:25;;;;;22335:419;22417:23;22443:69;22471:4;22443:69;;;;;;;;;;;;;;;;;22451:5;-1:-1:-1;;;;;22443:27:0;;;:69;;;;;:::i;:::-;22527:17;;22417:95;;-1:-1:-1;22527:21:0;22523:224;;22669:10;22658:30;;;;;;;;;;;;:::i;:::-;22650:85;;;;-1:-1:-1;;;22650:85:0;;;;;;;:::i;59033:315::-;59132:20;;-1:-1:-1;;;59132:20:0;;59118:11;;55139:42;;59132:12;;:20;;59145:6;;59132:20;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59118:34;;54776:42;-1:-1:-1;;;;;59165:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;59165:21:0;;54776:42;59205:10;59165:51;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;59227:29:0;;-1:-1:-1;;;59227:29:0;;54776:42;;-1:-1:-1;59227:12:0;;-1:-1:-1;59227:29:0;;59240:3;;59245:10;;59227:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55139:42;-1:-1:-1;;;;;59269:12:0;;59282:6;59290:1;59293:46;55046:42;59329:3;59334:4;59293:22;:46::i;:::-;59269:71;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59033:315;;;;:::o;58416:609::-;58507:4;55139:42;58524:12;58537:6;58546:22;58560:7;58546:13;:22::i;:::-;58545:23;;58570:1;58524:48;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;58583:44:0;;-1:-1:-1;;;58583:44:0;;55139:42;;-1:-1:-1;58583:12:0;;-1:-1:-1;58583:44:0;;58596:6;;58612:4;;58619:7;;58583:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58640:15;58658:7;58640:25;;58687:9;-1:-1:-1;;;;;58682:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58707:2;58682:27;58678:119;;58767:9;-1:-1:-1;;;;;58762:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58757:2;:26;58750:2;:34;58739:7;:46;;;;;;58726:59;;58678:119;58809:47;;-1:-1:-1;;;58809:47:0;;-1:-1:-1;;;;;58809:20:0;;;;;:47;;58838:4;;58845:10;;58809:47;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;58873:29:0;;54868:42;58873:29;58869:119;;;58924:9;-1:-1:-1;;;;;58919:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;58919:30:0;;58950:10;58919:42;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58869:119;59007:10;58416:609;-1:-1:-1;;;;58416:609:0:o;30638:1522::-;30822:16;;;;30899:14;;30699:7;;;;;;;;;;30822:16;-1:-1:-1;;;;;30899:35:0;27154:42;30899:35;30895:191;;;30982:14;;30968:29;;:13;:29::i;:::-;-1:-1:-1;;;;;30951:46:0;;;31055:16;;;;;31012:62;;-1:-1:-1;;;31012:62:0;;;;27242:42;;31012:36;;31055:16;31012:62;;;;;30951:14;;31012:62;;;;;;;31055:16;27242:42;31012:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30895:191;31165:14;;;;:18;31161:372;;31200:48;31215:6;:14;;;31231:6;:16;;;31200:14;:48::i;:::-;31265:14;31282:48;31297:6;:14;;;31313:6;:16;;;31282:14;:48::i;:::-;31265:65;;31383:45;31393:6;31401:9;31412:15;31383:9;:45::i;:::-;31345:83;;-1:-1:-1;31345:83:0;;-1:-1:-1;31345:83:0;-1:-1:-1;31445:77:0;;;;31487:6;:19;;;31477:29;;31445:77;31161:372;;31603:7;31598:129;;31642:34;31652:6;31660:15;31642:9;:34::i;:::-;31627:49;;31701:6;:14;;;31691:24;;31598:129;31778:39;31783:6;:15;;;31800:6;:16;;;31778:4;:39::i;:::-;31747:27;31758:6;:15;;;31747:10;:27::i;:::-;:70;;31739:109;;;;-1:-1:-1;;;31739:109:0;;;;;;;:::i;:::-;31956:1;31929:24;27242:42;31929:10;:24::i;:::-;:28;31925:185;;;32030:53;;-1:-1:-1;;;32030:53:0;;27242:42;;31974:37;;27242:42;;32030:38;;:53;;32077:4;;32030:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31974:124;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31925:185;-1:-1:-1;32130:7:0;;-1:-1:-1;32139:12:0;-1:-1:-1;;30638:1522:0;;;:::o;59491:484::-;59626:49;;-1:-1:-1;;;59626:49:0;;59560:14;;54510:3;;27429:42;;59626:41;;:49;;59668:6;;59626:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59622:142;;;59698:54;;-1:-1:-1;;;59698:54:0;;27429:42;;59698:46;;:54;;59745:6;;59698:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59692:60;;59622:142;59789:8;;59788:32;;59816:3;59806:7;:13;;;;;;59788:32;;;59801:1;59788:32;59776:44;-1:-1:-1;59914:1:0;59904:7;:11;59891:9;:25;59887:81;;;59955:1;59945:7;:11;59933:23;;59887:81;59491:484;;;;;:::o;32428:1470::-;32488:7;32497:4;32516:15;32542:17;32570:12;32603:6;:17;;;32624:1;32603:22;;32595:64;;;;-1:-1:-1;;;32595:64:0;;;;;;;:::i;:::-;32720:14;;-1:-1:-1;;;;;32720:35:0;27154:42;32720:35;32716:191;;;32803:14;;32789:29;;:13;:29::i;:::-;-1:-1:-1;;;;;32772:46:0;;;32876:16;;;;;32833:62;;-1:-1:-1;;;32833:62:0;;;;27242:42;;32833:36;;32876:16;32833:62;;;;;32772:14;;32833:62;;;;;;;32876:16;27242:42;32833:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32716:191;32923:14;;;;:18;32919:360;;32958:48;32973:6;:14;;;32989:6;:16;;;32958:14;:48::i;:::-;33023:14;33040:48;33055:6;:14;;;33071:6;:16;;;33040:14;:48::i;:::-;33023:65;;33130:44;33140:6;33148:9;33159:14;33130:9;:44::i;:::-;-1:-1:-1;33103:71:0;-1:-1:-1;33103:71:0;-1:-1:-1;33191:77:0;;;;33233:6;:19;;;33223:29;;33191:77;32919:360;;33349:7;33344:128;;33388:33;33398:6;33406:14;33388:9;:33::i;:::-;33373:48;;33446:6;:14;;;33436:24;;33344:128;33523:6;:17;;;33492:27;33503:6;:15;;;33492:10;:27::i;:::-;:48;;33484:87;;;;-1:-1:-1;;;33484:87:0;;;;;;;:::i;:::-;33679:1;33652:24;27242:42;33652:10;:24::i;:::-;:28;33648:185;;;33753:53;;-1:-1:-1;;;33753:53:0;;27242:42;;33697:37;;27242:42;;33753:38;;:53;;33800:4;;33753:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;33697:124;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33648:185;33853:7;33862:27;33873:6;:15;;;33862:10;:27::i;:::-;33845:45;;;;;;;32428:1470;;;:::o;59356:127::-;59425:50;;-1:-1:-1;;;59425:50:0;;59408:4;;54684:42;;59425:27;;:50;;27337:42;;59464:10;;59425:50;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;59356:127;;;:::o;59983:269::-;60051:7;60071:17;60104:9;-1:-1:-1;;;;;60099:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60071:50;-1:-1:-1;;;;;;60138:25:0;;27242:42;60138:25;60134:82;;;27154:42;60180:24;;;;;27949:275;28012:12;-1:-1:-1;;;;;28041:31:0;;27154:42;28041:31;28037:180;;;-1:-1:-1;28099:21:0;28037:180;;;28163:42;;-1:-1:-1;;;28163:42:0;;-1:-1:-1;;;;;28163:27:0;;;;;:42;;28199:4;;28163:42;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;19125:181::-;19183:7;19215:5;;;19239:6;;;;19231:46;;;;-1:-1:-1;;;19231:46:0;;;;;;;:::i;:::-;19297:1;19125:181;-1:-1:-1;;;19125:181:0:o;53342:220::-;53440:20;53463:17;;;;;;;;;-1:-1:-1;;;;;53463:17:0;-1:-1:-1;;;;;53463:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53440:61;;53514:40;53531:4;53536:8;53546:7;53514:16;:40::i;28452:502::-;28607:21;:25;28603:93;;28649:35;;-1:-1:-1;;;;;28649:12:0;;;28662:21;28649:35;;;;;;;;;28662:21;28649:12;:35;;;;;;;;;;;;;;;;;;;;;28603:93;28735:1;28712:20;28723:8;28712:10;:20::i;:::-;:24;28708:112;;;28753:55;28782:3;28787:20;28798:8;28787:10;:20::i;:::-;-1:-1:-1;;;;;28753:28:0;;;:55;:28;:55::i;:::-;28860:1;28836:21;28847:9;28836:10;:21::i;:::-;:25;28832:115;;;28878:57;28908:3;28913:21;28924:9;28913:10;:21::i;:::-;-1:-1:-1;;;;;28878:29:0;;;:57;:29;:57::i;17356:196::-;17459:12;17491:53;17514:6;17522:4;17528:1;17531:12;17491:22;:53::i;13962:382::-;14059:10;14082:8;14097:4;-1:-1:-1;;;;;14093:13:0;;14107:4;14093:19;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14082:30;;14128:9;14148:4;-1:-1:-1;;;;;14144:14:0;;14159:4;14144:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14125:39;;;;;;14178:8;14194:4;-1:-1:-1;;;;;14190:14:0;;14205:4;14211;14190:26;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14175:41;;;14238:25;14258:4;14252:3;:10;;;;;;14238:13;:25::i;:::-;14229:34;;14299:3;14288:6;14283:19;;:53;;14318:18;14332:3;14318:13;:18::i;:::-;14316:20;;14283:53;;;14307:6;14305:8;;14283:53;14274:62;13962:382;-1:-1:-1;;;;;;;13962:382:0:o;13637:134::-;13718:2;13692:5;13740:6;;;13732:31;;;;-1:-1:-1;;;13732:31:0;;;;;;;:::i;37197:142::-;37257:7;-1:-1:-1;;;;;37284:25:0;;27154:42;37284:25;:47;;37327:4;37284:47;;;-1:-1:-1;27242:42:0;;37197:142;-1:-1:-1;37197:142:0:o;28232:212::-;-1:-1:-1;;;;;28314:31:0;;27154:42;28314:31;28310:127;;28362:63;-1:-1:-1;;;;;28362:29:0;;27620:42;28417:7;28362:29;:63::i;37508:743::-;37592:7;-1:-1:-1;;;;;37691:24:0;;27242:42;37691:24;37687:58;;-1:-1:-1;37724:21:0;37717:28;;37687:58;38020:10;37996:21;:34;37992:81;;;38063:10;38039:21;:34;38032:41;;;;37992:81;-1:-1:-1;38222:21:0;37508:743;;;;:::o;34086:1602::-;34223:12;;;;34343:5;:24;;;;;;;;;34339:197;;;34384:53;34397:7;:16;;;34415:2;34419:7;:17;;;34384:12;:53::i;:::-;34339:197;;;34470:54;34483:7;:16;;;34501:2;34505:7;:18;;;34470:12;:54::i;:::-;34602:20;;;;34552:71;;-1:-1:-1;;;34552:71:0;;27714:42;;34552:49;;:71;;34602:20;34552:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34548:118;;;34653:1;34640:14;;34548:118;34678:20;34701:28;34712:7;:16;;;34701:10;:28::i;:::-;34789:20;;;;34746:64;;-1:-1:-1;;;34746:64:0;;34678:51;;-1:-1:-1;27714:42:0;;34746;;:64;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34742:221;;;34841:7;:20;;;-1:-1:-1;;;;;34841:25:0;34874:10;34886:7;:16;;;34841:62;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34827:76;;;;;34742:221;;;34946:5;34936:15;;34742:221;35031:17;;;;34975:20;;35061:565;;;;35190:15;;35179:27;;:10;:27::i;:::-;35273:16;;;;35166:40;;-1:-1:-1;;;;;;35273:37:0;27154:42;35273:37;35269:210;;;35391:53;;-1:-1:-1;;;35391:53:0;;27242:42;;35331:37;;27242:42;;35391:38;;:53;;35438:4;;35391:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35331:132;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35269:210;35602:12;35571:28;35582:7;:16;;;35571:10;:28::i;:::-;:43;35556:58;;35061:565;35655:12;;-1:-1:-1;35669:10:0;-1:-1:-1;;34086:1602:0;;;;;;;:::o;35954:742::-;36133:15;;;;36076:73;;-1:-1:-1;;;36076:73:0;;36038:17;;27528:42;;36076:56;;:73;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;36068:106;;;;-1:-1:-1;;;36068:106:0;;;;;;;:::i;:::-;36253:15;;;;36270:17;;;;36223:15;;36187:13;;36217:71;;-1:-1:-1;;;;;36217:35:0;;;;;:71::i;:::-;36314:15;36305:5;:24;;;;;;;;;36301:388;;;36381:7;:15;;;-1:-1:-1;;;;;36361:63:0;;36432:8;36442:7;:15;;;36459:7;:16;;;36477:7;:17;;;36361:134;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;36346:149;;36301:388;;;36563:7;:15;;;-1:-1:-1;;;;;36543:62:0;;36613:8;36623:7;:15;;;36640:7;:16;;;36658:7;:18;;;36543:134;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;6705:122::-;6764:9;6654:6;6790:23;6794:9;6798:1;6801;6794:3;:9::i;:::-;6811:1;6654:6;6805:7;;53570:355;53697:26;:24;:26::i;:::-;-1:-1:-1;;;;;53685:38:0;:8;-1:-1:-1;;;;;53685:38:0;;53682:168;;;53780:12;-1:-1:-1;;;;;53780:17:0;53805:7;53780:37;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53832:7;;53682:168;53862:51;-1:-1:-1;;;;;53862:28:0;;53891:12;53905:7;53862:28;:51::i;18118:979::-;18248:12;18281:18;18292:6;18281:10;:18::i;:::-;18273:60;;;;-1:-1:-1;;;18273:60:0;;;;;;;:::i;:::-;18407:12;18421:23;18448:6;-1:-1:-1;;;;;18448:11:0;18468:8;18479:4;18448:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18406:78;;;;18499:7;18495:595;;;18530:10;-1:-1:-1;18523:17:0;;-1:-1:-1;18523:17:0;18495:595;18644:17;;:21;18640:439;;18907:10;18901:17;18968:15;18955:10;18951:2;18947:19;18940:44;18855:148;19050:12;19043:20;;-1:-1:-1;;;19043:20:0;;;;;;;;:::i;21512:184::-;21598:90;21618:5;21648:22;;;21672:7;21681:5;21625:62;;;;;;;;;:::i;36704:397::-;36813:6;36822:2;36813:11;36801:2;:9;:23;36797:104;;;36841:48;;-1:-1:-1;;;36841:48:0;;;;;;;:::i;36797:104::-;37060:15;;36967:2;37060:15;37053:30;37038:56::o;52851:121::-;52922:42;52851:121;:::o;16143:619::-;16203:4;16671:20;;16514:66;16711:23;;;;;;:42;;-1:-1:-1;;16738:15:0;;;16143:619;-1:-1:-1;;16143:619:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5:130::-;72:20;;97:33;72:20;97:33;:::i;612:616::-;;727:3;720:4;712:6;708:17;704:27;694:2;;-1:-1;;735:12;694:2;788:78;38167:17;788:78;:::i;:::-;779:87;;872:16;931:17;989:3;38167:17;964:3;960:27;957:36;954:2;;;1006:1;;996:12;954:2;1031:1;1016:206;769:4;1038:1;1035:13;1016:206;;;85:6;72:20;97:33;124:5;97:33;:::i;:::-;1109:50;;38179:4;1173:14;;;;1201;;;;;1063:1;1056:9;1016:206;;;1020:14;;;687:541;;;;:::o;1879:124::-;1943:20;;1968:30;1943:20;1968:30;:::i;2782:440::-;;2883:3;2876:4;2868:6;2864:17;2860:27;2850:2;;-1:-1;;2891:12;2850:2;2938:6;2925:20;2960:64;2975:48;3016:6;2975:48;:::i;:::-;2960:64;:::i;:::-;2951:73;;3044:6;3037:5;3030:21;3148:3;3080:4;3139:6;3072;3130:16;;3127:25;3124:2;;;3165:1;;3155:12;3124:2;42782:6;3080:4;3072:6;3068:17;3080:4;3106:5;3102:16;42759:30;42838:1;42820:16;;;3080:4;42820:16;42813:27;3106:5;2843:379;-1:-1;;2843:379::o;3231:442::-;;3343:3;3336:4;3328:6;3324:17;3320:27;3310:2;;-1:-1;;3351:12;3310:2;3391:6;3385:13;3413:64;3428:48;3469:6;3428:48;:::i;3413:64::-;3404:73;;3497:6;3490:5;3483:21;3601:3;3533:4;3592:6;3525;3583:16;;3580:25;3577:2;;;3618:1;;3608:12;3577:2;3628:39;3660:6;3533:4;3559:5;3555:16;3533:4;3525:6;3521:17;3628:39;:::i;6149:241::-;;6253:2;6241:9;6232:7;6228:23;6224:32;6221:2;;;-1:-1;;6259:12;6221:2;85:6;72:20;97:33;124:5;97:33;:::i;6397:263::-;;6512:2;6500:9;6491:7;6487:23;6483:32;6480:2;;;-1:-1;;6518:12;6480:2;226:6;220:13;238:33;265:5;238:33;:::i;6953:704::-;;;;;7135:3;7123:9;7114:7;7110:23;7106:33;7103:2;;;-1:-1;;7142:12;7103:2;528:6;522:13;540:41;575:5;540:41;:::i;:::-;7313:2;7371:22;;522:13;7194:82;;-1:-1;540:41;522:13;540:41;:::i;:::-;7440:2;7490:22;;6086:13;7559:2;7609:22;;;6086:13;7097:560;;7321:82;;-1:-1;7097:560;-1:-1;;;7097:560::o;7664:366::-;;;7785:2;7773:9;7764:7;7760:23;7756:32;7753:2;;;-1:-1;;7791:12;7753:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;7843:63;7943:2;7982:22;;;;5938:20;;-1:-1;;;7747:283::o;8037:741::-;;;;;;8211:3;8199:9;8190:7;8186:23;8182:33;8179:2;;;-1:-1;;8218:12;8179:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;8270:63;-1:-1;8370:2;8409:22;;5938:20;;-1:-1;8478:2;8517:22;;5938:20;;-1:-1;8614:2;8599:18;;8586:32;8638:18;8627:30;;;8624:2;;;-1:-1;;8660:12;8624:2;8745:6;8734:9;8730:22;;;2551:3;2544:4;2536:6;2532:17;2528:27;2518:2;;-1:-1;;2559:12;2518:2;2602:6;2589:20;8638:18;2621:6;2618:30;2615:2;;;-1:-1;;2651:12;2615:2;2746:3;8370:2;2726:17;2687:6;2712:32;;2709:41;2706:2;;;-1:-1;;2753:12;2706:2;8173:605;;;;-1:-1;8173:605;;-1:-1;8370:2;2683:17;;8680:82;8173:605;-1:-1;;;8173:605::o;8785:952::-;;;;;;9017:3;9005:9;8996:7;8992:23;8988:33;8985:2;;;-1:-1;;9024:12;8985:2;1370:3;1363:4;1355:6;1351:17;1347:27;1337:2;;-1:-1;;1378:12;1337:2;38167:17;1431:78;38167:17;1431:78;:::i;:::-;1603:27;;;;1515:16;1574:17;1600:36;;;1597:2;;;-1:-1;;1639:12;1597:2;-1:-1;1659:206;1412:4;1681:1;1678:13;1659:206;;;5938:20;;1752:50;;38179:4;1816:14;;;;1844;;;;1706:1;1699:9;1659:206;;;1663:14;;9076:86;;;;;9218:76;9286:7;9262:22;9218:76;:::i;:::-;9208:86;;;9359:3;9348:9;9344:19;9331:33;38112:18;9376:6;9373:30;9370:2;;;-1:-1;;9406:12;9370:2;9436:62;9490:7;9481:6;9470:9;9466:22;9436:62;:::i;:::-;9426:72;;;9554:61;9607:7;9535:3;9587:9;9583:22;9554:61;:::i;:::-;9544:71;;9671:50;9713:7;9652:3;9693:9;9689:22;9671:50;:::i;:::-;9661:60;;8979:758;;;;;;;;:::o;9744:257::-;;9856:2;9844:9;9835:7;9831:23;9827:32;9824:2;;;-1:-1;;9862:12;9824:2;2091:6;2085:13;2103:30;2127:5;2103:30;:::i;10008:241::-;;10112:2;10100:9;10091:7;10087:23;10083:32;10080:2;;;-1:-1;;10118:12;10080:2;-1:-1;2212:20;;10074:175;-1:-1;10074:175::o;10256:263::-;;10371:2;10359:9;10350:7;10346:23;10342:32;10339:2;;;-1:-1;;10377:12;10339:2;-1:-1;2360:13;;10333:186;-1:-1;10333:186::o;10526:345::-;;10639:2;10627:9;10618:7;10614:23;10610:32;10607:2;;;-1:-1;;10645:12;10607:2;10703:17;10690:31;10741:18;10733:6;10730:30;10727:2;;;-1:-1;;10763:12;10727:2;10793:62;10847:7;10838:6;10827:9;10823:22;10793:62;:::i;10878:593::-;;;11028:2;11016:9;11007:7;11003:23;10999:32;10996:2;;;-1:-1;;11034:12;10996:2;11085:17;11079:24;11123:18;;11115:6;11112:30;11109:2;;;-1:-1;;11145:12;11109:2;11175:73;11240:7;11231:6;11220:9;11216:22;11175:73;:::i;:::-;11165:83;;11306:2;11295:9;11291:18;11285:25;11271:39;;11123:18;11322:6;11319:30;11316:2;;;-1:-1;;11352:12;11316:2;;11382:73;11447:7;11438:6;11427:9;11423:22;11382:73;:::i;:::-;11372:83;;;10990:481;;;;;:::o;12175:523::-;;;;12329:2;12317:9;12308:7;12304:23;12300:32;12297:2;;;-1:-1;;12335:12;12297:2;3940:6;3927:20;3952:49;3995:5;3952:49;:::i;:::-;12387:79;12503:2;12542:22;;5938:20;;-1:-1;12611:2;12650:22;;;2212:20;;12291:407;-1:-1;;;12291:407::o;12705:439::-;;;12857:2;12845:9;12836:7;12832:23;12828:32;12825:2;;;-1:-1;;12863:12;12825:2;4117:6;4111:13;4129:53;4176:5;4129:53;:::i;:::-;13046:2;13096:22;;;;6086:13;12915:94;;6086:13;;-1:-1;;;12819:325::o;13151:387::-;;13285:2;13273:9;13264:7;13260:23;13256:32;13253:2;;;-1:-1;;13291:12;13253:2;13349:17;13336:31;13387:18;;13379:6;13376:30;13373:2;;;-1:-1;;13409:12;13373:2;13505:6;13494:9;13490:22;;;4357:6;;4345:9;4340:3;4336:19;4332:32;4329:2;;;-1:-1;;4367:12;4329:2;4395:22;4357:6;4395:22;:::i;:::-;4386:31;;4502:49;4547:3;4523:22;4502:49;:::i;:::-;4484:16;4477:75;4650:49;4695:3;13285:2;4675:9;4671:22;4650:49;:::i;:::-;13285:2;4636:5;4632:16;4625:75;4766:2;4824:9;4820:22;5938:20;4766:2;4785:5;4781:16;4774:75;4916:2;4974:9;4970:22;5938:20;4916:2;4935:5;4931:16;4924:75;5064:3;5123:9;5119:22;5938:20;5064:3;5084:5;5080:16;5073:75;5246:49;5291:3;5212;5271:9;5267:22;5246:49;:::i;:::-;5212:3;5232:5;5228:16;5221:75;5399:49;5444:3;5365;5424:9;5420:22;5399:49;:::i;:::-;5365:3;5385:5;5381:16;5374:75;5542:3;5531:9;5527:19;5514:33;13387:18;5559:6;5556:30;5553:2;;;-1:-1;;5589:12;5553:2;5634:58;5688:3;5679:6;5668:9;5664:22;5634:58;:::i;:::-;5542:3;5616:16;;5609:84;-1:-1;5757:3;5814:22;;;5938:20;5773:18;;;5766:77;;;;-1:-1;5620:5;13247:291;-1:-1;;;13247:291::o;13815:938::-;;;;;;14023:3;14011:9;14002:7;13998:23;13994:33;13991:2;;;-1:-1;;14030:12;13991:2;6092:6;6086:13;14082:74;;14193:2;14255:9;14251:22;522:13;540:41;575:5;540:41;:::i;:::-;14320:2;14378:22;;522:13;14201:82;;-1:-1;540:41;522:13;540:41;:::i;:::-;14468:2;14453:18;;14447:25;14328:82;;-1:-1;14492:18;14481:30;;14478:2;;;-1:-1;;14514:12;14478:2;14544:73;14609:7;14600:6;14589:9;14585:22;14544:73;:::i;:::-;14534:83;;;14654:3;14709:9;14705:22;6086:13;14663:74;;13985:768;;;;;;;;:::o;14760:399::-;;;14892:2;14880:9;14871:7;14867:23;14863:32;14860:2;;;-1:-1;;14898:12;14860:2;-1:-1;;6086:13;;15061:2;15111:22;;;6086:13;;;;;-1:-1;14854:305::o;15166:809::-;;;;;;15349:3;15337:9;15328:7;15324:23;15320:33;15317:2;;;-1:-1;;15356:12;15317:2;-1:-1;;6086:13;;15519:2;15569:22;;6086:13;15638:2;15688:22;;6086:13;15757:2;15807:22;;6086:13;15876:3;15927:22;;;6086:13;;;;;-1:-1;6086:13;;-1:-1;6086:13;;-1:-1;15311:664;-1:-1;15311:664::o;16131:137::-;-1:-1;;;;;40555:54;16218:45;;16212:56::o;16625:323::-;;16757:5;38872:12;39147:6;39142:3;39135:19;16840:52;16885:6;39184:4;39179:3;39175:14;39184:4;16866:5;16862:16;16840:52;:::i;:::-;43215:7;43199:14;-1:-1;;43195:28;16904:39;;;;39184:4;16904:39;;16705:243;-1:-1;;16705:243::o;24620:271::-;;17465:5;38872:12;17576:52;17621:6;17616:3;17609:4;17602:5;17598:16;17576:52;:::i;:::-;17640:16;;;;;24754:137;-1:-1;;24754:137::o;24898:379::-;25262:10;25086:191::o;25284:222::-;-1:-1;;;;;40555:54;;;;16218:45;;25411:2;25396:18;;25382:124::o;26019:349::-;-1:-1;;;;;40555:54;;;;16061:58;;26354:2;26339:18;;16576:37;26182:2;26167:18;;26153:215::o;26375:444::-;-1:-1;;;;;40555:54;;;16218:45;;40555:54;;;;26722:2;26707:18;;16218:45;26805:2;26790:18;;16576:37;;;;26558:2;26543:18;;26529:290::o;26826:556::-;-1:-1;;;;;40555:54;;;16218:45;;40555:54;;;;27202:2;27187:18;;16218:45;27285:2;27270:18;;16576:37;27368:2;27353:18;;16576:37;;;;27037:3;27022:19;;27008:374::o;27729:222::-;16576:37;;;27856:2;27841:18;;27827:124::o;27958:333::-;16576:37;;;-1:-1;;;;;40555:54;28277:2;28262:18;;16218:45;28113:2;28098:18;;28084:207::o;28298:306::-;;28443:2;28464:17;28457:47;28518:76;28443:2;28432:9;28428:18;28580:6;28518:76;:::i;28611:501::-;;28802:2;28823:17;28816:47;28877:76;28802:2;28791:9;28787:18;28939:6;28877:76;:::i;:::-;29001:9;28995:4;28991:20;28986:2;28975:9;28971:18;28964:48;29026:76;29097:4;29088:6;29026:76;:::i;:::-;29018:84;28773:339;-1:-1;;;;;28773:339::o;30771:416::-;30971:2;30985:47;;;19366:2;30956:18;;;39135:19;19402:31;39175:14;;;19382:52;19453:12;;;30942:245::o;31194:416::-;31394:2;31408:47;;;19704:2;31379:18;;;39135:19;19740:34;39175:14;;;19720:55;-1:-1;;;19795:12;;;19788:26;19833:12;;;31365:245::o;31617:416::-;31817:2;31831:47;;;20084:2;31802:18;;;39135:19;20120:29;39175:14;;;20100:50;20169:12;;;31788:245::o;32040:416::-;32240:2;32254:47;;;20420:2;32225:18;;;39135:19;-1:-1;;;39175:14;;;20436:43;20498:12;;;32211:245::o;32463:416::-;32663:2;32677:47;;;20749:2;32648:18;;;39135:19;20785:28;39175:14;;;20765:49;20833:12;;;32634:245::o;32886:416::-;33086:2;33100:47;;;21084:2;33071:18;;;39135:19;21120:34;39175:14;;;21100:55;-1:-1;;;21175:12;;;21168:30;21217:12;;;33057:245::o;33309:416::-;33509:2;33523:47;;;21773:2;33494:18;;;39135:19;21809:31;39175:14;;;21789:52;21860:12;;;33480:245::o;33732:416::-;33932:2;33946:47;;;22111:2;33917:18;;;39135:19;22147:34;39175:14;;;22127:55;-1:-1;;;22202:12;;;22195:34;22248:12;;;33903:245::o;34155:416::-;34355:2;34369:47;;;22499:2;34340:18;;;39135:19;-1:-1;;;39175:14;;;22515:35;22569:12;;;34326:245::o;34578:390::-;;34765:2;34786:17;34779:47;22941:63;34765:2;34754:9;34750:18;22918:16;22912:23;22941:63;:::i;:::-;34765:2;23080:5;23076:16;23070:23;23099:63;23147:14;34754:9;23147:14;23133:12;23099:63;:::i;:::-;;23147:14;23239:5;23235:16;23229:23;23306:14;34754:9;23306:14;16576:37;23306:14;23399:5;23395:16;23389:23;23466:14;34754:9;23466:14;16576:37;23466:14;23557:5;23553:16;23547:23;23624:14;34754:9;23624:14;16576:37;23624:14;23714:5;23710:16;23704:23;23733:63;23781:14;34754:9;23781:14;23767:12;23733:63;:::i;:::-;;23781:14;23876:5;23872:16;23866:23;23895:63;23943:14;34754:9;23943:14;23929:12;23895:63;:::i;:::-;;23943:14;24034:5;24030:16;24024:23;22841:6;24067:14;22841:6;24067:14;34754:9;24067:14;24060:38;24113:71;22832:16;34754:9;22832:16;24165:12;24113:71;:::i;:::-;24261:18;;24255:25;24334:16;;16576:37;;;;-1:-1;24105:79;;34736:232;-1:-1;34736:232::o;35204:460::-;16576:37;;;-1:-1;;;;;40555:54;;;;35567:2;35552:18;;16061:58;35650:2;35635:18;;16576:37;35395:2;35380:18;;35366:298::o;35671:752::-;16576:37;;;-1:-1;;;;;40555:54;;;36093:2;36078:18;;16218:45;40555:54;;36176:2;36161:18;;16218:45;40566:42;36213:2;36198:18;;36191:48;;;35671:752;;36253:76;;35913:19;;36315:6;36253:76;:::i;:::-;36245:84;;16606:5;36408:3;36397:9;36393:19;16576:37;35899:524;;;;;;;;:::o;36430:454::-;16576:37;;;36780:2;36765:18;;16576:37;;;;36870:2;36855:18;;18718:57;36618:2;36603:18;;36589:295::o;37352:333::-;16576:37;;;37671:2;37656:18;;16576:37;37507:2;37492:18;;37478:207::o;37692:256::-;37754:2;37748:9;37780:17;;;37855:18;37840:34;;37876:22;;;37837:62;37834:2;;;37912:1;;37902:12;37834:2;37754;37921:22;37732:216;;-1:-1;37732:216::o;38457:321::-;;38600:18;38592:6;38589:30;38586:2;;;-1:-1;;38622:12;38586:2;-1:-1;43215:7;38676:17;-1:-1;;38672:33;38763:4;38753:15;;38523:255::o;42855:268::-;42920:1;42927:101;42941:6;42938:1;42935:13;42927:101;;;43008:11;;;43002:18;42989:11;;;42982:39;42963:2;42956:10;42927:101;;;43043:6;43040:1;43037:13;43034:2;;;42920:1;43099:6;43094:3;43090:16;43083:27;43034:2;;42904:219;;;:::o;43236:117::-;-1:-1;;;;;40555:54;;43295:35;;43285:2;;43344:1;;43334:12;43285:2;43279:74;:::o;43500:111::-;43581:5;39969:13;39962:21;43559:5;43556:32;43546:2;;43602:1;;43592:12
Swarm Source
ipfs://580a83bdc6e1f6ce59c76cac0ce6537999b79b83447ea7b4ea98af412853b0a6
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.