Spend less on fees, more on crypto. Buy crypto easily with MoonPay Balance. 20M+ users trust MoonPay worldwide.
Ready to onboard to Ethereum? With MetaMask Portfolio, you're in control.
Don’t invest unless you’re prepared to lose all the money you invest.
Everyday giveaways up to 100 ETH, Lucky Spins. Deposit BONUS 300% and Cashbacks!
5000+ Slots & Live Casino Games, 50+cryptos. Register with Etherscan and get 760% deposit bonus. Win Big$, withdraw it fast.
Slots, Roulette, Poker & more - Proud sponsors of UFC, Everton & StakeF1 team!
5000+ Slots & Live Casino Games, 50+cryptos. Register with Etherscan and get 760% deposit bonus. Win Big$, withdraw it fast.
Anonymous play on awesome games - sign up now for 25 free jackpot spins - worth $100s!
100s of games, generous bonuses, 20+ years of trusted gaming. Join CryptoWins & start winning today!
Overview
ETH Balance
Eth Value
$0.00Token Holdings
Could not find any matches!
- ERC-20 Tokens (100)200 FREEFree Coin (FREE)$0.00@0.0047.800872 0xBTC0xBitcoin To... (0xBTC)$5.02@0.10510.00754554 aDAIAave Interes... (aDAI)$0.01@1.00493,108.4452793 ALEPHaleph.im v2 (ALEPH)$20,034.70@0.21529 BEPROBetProtocolT... (BEPRO)$0.01@0.000823.82146 LINKChainLink To... (LINK)$597.44@25.0830,061,571.7324931 DFXDFX Token (DFX)$1,071,351.49@0.03564,318,951.80073054 DHTdHedge DAO T... (DHT)$487,933.58@0.11340 DONUTDonut (DONUT)$0.26@0.0064900,630.2838271 DVGDVGToken (DVG)$7,469.63@0.00836,000 ETHAETHA (ETHA)$6.66@0.001151,791,197.8918872 FOXFOX (FOX)$4,763,030.11@0.092100.40425532 FRONTFrontier Tok... (FRONT)$51.12@0.509142,874.18656721 GSWAPgameswap.org (GSWAP)$10,710.23@0.2498712.9359975 GDAOGovernor (GDAO)$26.05@0.0365299,173.48301452 ICEIceToken (ICE)$188,641.75@0.6305179,876.54752062 ICHIichi.farm (ICHI)$217,650.62@1.211 JRTJarvis Rewar... (JRT)$0.01@0.00532,608,364.62187 K21k21.kanon.ar... (K21)$212,483.19@0.08152,285.1908352 kMPLKiloAmple (kMPL)$313.48@0.1372312.59116512 KNCKyberNetwork (KNC)$260.99@0.83490.25 LPTLivepeer Tok... (LPT)$5.55@22.2118 LONLON Token (LON)$15.73@0.8745,778,383.53141811 MTAMeta (MTA)$174,951.54@0.03037,100,806.84044811 OCCOCC (OCC)$853,460.18@0.1202238.12163347 OCTOOcto.fi (OCTO)$108.40@0.45520.0001 OXTOrchid (OXT)$0.00@0.1379784.0872378 PERPPerpetual (PERP)$972.27@1.24297,084.99613716 RLYRally (RLY)$856.70@0.002935 RENRepublic (REN)$1.66@0.0473148.49994773 SHARESeigniorage ... (SHARE)$0.89@0.0064,330,539.92644 SHROOMshroom.finan... (SHROOM)$60,762.89@0.0140.09 xSUSHISushiBar (xSUSHI)$0.25@2.7515 SUSHISushiToken (SUSHI)$28.20@1.8810,887.1903301 TORNTORN Token (TORN)$151,876.31@13.95425.9 UNIUniswap (UNI)$7,461.77@17.52112.30857475 UDTUnlock Disco... (UDT)$4,346.34@38.7049,431.69647002 VSPVesperToken (VSP)$13,379.18@0.27070.00185 XMONXMON (XMON)$2.02@1,090.820.96519422 YFLYFLink (YFL)$3.84@3.98520.52584105 BATBAT (BAT)$180.02@0.34580.03614274 COMPCompound (COMP)$4.24@117.31110,078.9770236 cDAICompound Dai (cDAI)$2,639.00@0.02449.39543996 cUSDCCompound USD... (cUSDC)$1.20@0.02432,804.86575712 DAIDai Stableco... (DAI)$2,803.02@0.99930.005 MKRMaker (MKR)$10.91@2,181.584.57 USDPPax Dollar (USDP)$4.57@0.999825.63 SAISai Stableco... (SAI)$530.28@20.69492 SNTStatusNetwor... (SNT)$34.79@0.070710 TUSDTrueUSD (TUSD)$10.17@1.0179,019.615852 USDCUSDC (USDC)$9,012.92@0.99930.01008 WBTCWrapped BTC (WBTC)$999.10@99,117.000.34947251 WETHWrapped Ethe... (WETH)$1,397.05@3,997.6064,000 Earn $UNI airdrops at https://www.uniswaplabs.comERC-20: # un... (Earn $...)48,000 Earn $TUSD airdrops at https://www.tenorusd.orgERC-20: $ te... (Earn $...)173,498.6428827 BPTERC-20: Bala... (BPT)20 BASKBasketDAO Gov2.5531 CHAIChai10,000,000 CWAPERC-20: deFI... (CWAP)124.21582298 USDDollars1 DOTCdotc.pro token999,691.2 DUDEERC-20: Dude (DUDE)2,968,570.28226064 GDTGDT$7,896.60@0.00271,604,915.50925926 IDRTWERC-20: IDRT... (IDRTW)888,888 KICKKickToken7,000.01 MFTMainframe Token51,257.61403547 MPLMaple Token$1,156,884.35@22.5732,000 MNEMinereum32,000 MNEMinereum12,950 PRIMALERC-20: Prim... (PRIMAL)500,000,000,000,000 PUPPupper5 RCLEERC-20: Ross... (RCLE)1,555.2 SCOTTERC-20: SCOT... (SCOTT)99.9999648 SHARESeigniorage Shares0.86880565 SLPERC-20: Sush... (SLP)41.90666878 SLPSushiSwap ETH/ALCX LP (SLP)179.53732033 UNI-V2Uniswap LINK/SHROOM LP (UNI-V2)$275.79@1.5361206.4639815 UNI-V2Uniswap ETH/SHROOM LP (UNI-V2)5.28745818 UNI-V2Uniswap UNI/SHROOM LP (UNI-V2)$8.42@1.5917377.12064793 UNI-V2Uniswap GSWAP/ETH LP (UNI-V2)10 VSPTERC-20: Vesp... (VSPT)99,999ERC20 ***16,345,685.7002278 CWAPdeFIRE157,866.26566527 DEXTFDEXTF Token$27,960.38@0.17712 SELFSELF TOKEN2.25055556 sUSDSynth sUSD200 TokenERC-20 TOKEN*[Suspicious]245.44 TokenERC-20 TOKEN*[Suspicious]3,999.99 TokenERC-20 TOKEN*[Suspicious]3,999.99 TokenERC-20 TOKEN*[Suspicious]0.7 TokenERC-20 TOKEN*[Suspicious]400 TokenERC-20 TOKEN*[Suspicious]9,283 TokenERC-20 TOKEN*[Suspicious]98,127 TokenERC-20 TOKEN*[Suspicious]9,283 TokenERC-20 TOKEN*[Spam]132.84 TokenERC-20 TOKEN*[Spam]100 TokenERC-20 TOKEN*[Spam]9,283 TokenERC-20 TOKEN*[Spam]100 TokenERC-20 TOKEN*[Spam]856,420,144,564 TokenERC-20 TOKEN*[Spam]NFT Tokens (24)claim rewards on apyusd.netapyusd.netERC-1155claim rewards on clinkevent.comclinkevent.comERC-1155nft-dai.comDAI Mysterybox NFTERC-1155claim rewards on univ4labs.orguniv4labs.orgERC-1155ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]
More Info
Private Name Tags
ContractCreator
Multichain Info
2 addresses found via- Transactions
- Internal Transactions
- Token Transfers (ERC-20)
- NFT Transfers
- Contract
- Events
- Analytics
- Multichain Portfolio
- Cards New
- Info
Advanced Filter- Filter by Tx Type:
- Tx
- Internal Tx
- ERC-20
- NFTs
Latest 25 from a total of 1,132 transactions
Transaction Hash MethodBlockFromToWithdraw From St... 21318847 2024-12-03 1:58:47 4 days ago 1733191127 IN 0 ETH$0.00 0.00138603 17.71805611 Withdraw From St... 21188366 2024-11-14 20:37:47 22 days ago 1731616667 IN 0 ETH$0.00 0.0021113 27.47092637 Withdraw From St... 20786410 2024-09-19 18:24:11 78 days ago 1726770251 IN 0 ETH$0.00 0.00140683 17.98628811 Withdraw From St... 19442777 2024-03-15 20:38:35 266 days ago 1710535115 IN 0 ETH$0.00 0.00301053 32.75988523 Withdraw From St... 19321270 2024-02-27 20:27:47 283 days ago 1709065667 IN 0 ETH$0.00 0.0052889 56.32062554 Withdraw From St... 19321260 2024-02-27 20:25:35 283 days ago 1709065535 IN 0 ETH$0.00 0.00424614 55.28325544 Withdraw From St... 19321252 2024-02-27 20:23:59 283 days ago 1709065439 IN 0 ETH$0.00 0.00519571 55.3424065 Withdraw From St... 19266364 2024-02-20 3:53:35 291 days ago 1708401215 IN 0 ETH$0.00 0.00237074 25.24300653 Withdraw From St... 19057328 2024-01-21 19:37:47 320 days ago 1705865867 IN 0 ETH$0.00 0.00149678 15.9373035 Withdraw From St... 18700974 2023-12-02 20:01:35 370 days ago 1701547295 IN 0 ETH$0.00 0.00355567 43.52537176 Withdraw From St... 18700872 2023-12-02 19:40:59 370 days ago 1701546059 IN 0 ETH$0.00 0.00386334 47.29736327 Withdraw From St... 18552509 2023-11-12 1:18:11 391 days ago 1699751891 IN 0 ETH$0.00 0.00194604 20.72086607 Withdraw From St... 18417321 2023-10-24 3:04:35 410 days ago 1698116675 IN 0 ETH$0.00 0.00490464 52.22321407 Withdraw From St... 18328310 2023-10-11 16:11:47 422 days ago 1697040707 IN 0 ETH$0.00 0.0016486 17.64719893 Withdraw From St... 17698033 2023-07-15 9:53:59 511 days ago 1689414839 IN 0 ETH$0.00 0.00119354 13.05109658 Withdraw From St... 17637153 2023-07-06 20:23:35 519 days ago 1688675015 IN 0 ETH$0.00 0.00221179 23.09265196 Withdraw From St... 17570795 2023-06-27 12:50:11 529 days ago 1687870211 IN 0 ETH$0.00 0.00169626 18.45833435 Withdraw From St... 17473240 2023-06-13 19:47:11 542 days ago 1686685631 IN 0 ETH$0.00 0.00185739 19.77947841 Withdraw From St... 17473230 2023-06-13 19:45:11 542 days ago 1686685511 IN 0 ETH$0.00 0.0017331 22.56503569 Withdraw From St... 17473220 2023-06-13 19:43:11 542 days ago 1686685391 IN 0 ETH$0.00 0.00187617 19.98461511 Withdraw From St... 17361402 2023-05-29 1:31:59 558 days ago 1685323919 IN 0 ETH$0.00 0.00551699 58.74332542 Withdraw From St... 17226969 2023-05-10 2:14:11 577 days ago 1683684851 IN 0 ETH$0.00 0.00698935 74.42058541 Withdraw From St... 17120844 2023-04-25 4:16:23 592 days ago 1682396183 IN 0 ETH$0.00 0.00353059 37.59266872 Withdraw From St... 16969982 2023-04-03 17:30:35 613 days ago 1680543035 IN 0 ETH$0.00 0.00262411 27.94082662 Withdraw From St... 16834076 2023-03-15 15:06:47 632 days ago 1678892807 IN 0 ETH$0.00 0.00344324 36.65796438 View more zero value Internal Transactions in Advanced View mode
Advanced mode:Loading...LoadingContract Name:Sablier
Compiler Versionv0.5.11+commit.c082d0b4
Optimization Enabled:Yes with 200 runs
Other Settings:default evmVersion, GNU LGPLv3 license, AuditedContract Source Code (Solidity)Audit Report
- interface IERC20
- - function transfer(address to, uint256 ...
- - function approve(address spender, uin ...
- - function transferFrom(address from, a ...
- - function totalSupply()
- - function balanceOf(address who)
- - function allowance(address owner, add ...
- contract Initializable
- - function isConstructor()
- contract ReentrancyGuard is Initia ...
- - function initialize()
- contract CarefulMath
- - function mulUInt(uint a, uint b)
- - function divUInt(uint a, uint b)
- - function subUInt(uint a, uint b)
- - function addUInt(uint a, uint b)
- - function addThenSubUInt(uint a, uint ...
- contract Exponential is CarefulMat ...
- - function getExp(uint num, uint denom)
- - function addExp(Exp memory a, Exp mem ...
- - function subExp(Exp memory a, Exp mem ...
- - function mulScalar(Exp memory a, uint ...
- - function mulScalarTruncate(Exp memory ...
- - function mulScalarTruncateAddUInt(Exp ...
- - function divScalar(Exp memory a, uint ...
- - function divScalarByExp(uint scalar, ...
- - function divScalarByExpTruncate(uint ...
- - function mulExp(Exp memory a, Exp mem ...
- - function mulExp(uint a, uint b)
- - function mulExp3(Exp memory a, Exp me ...
- - function divExp(Exp memory a, Exp mem ...
- - function truncate(Exp memory exp)
- - function lessThanExp(Exp memory left, ...
- - function lessThanOrEqualExp(Exp memor ...
- - function greaterThanExp(Exp memory le ...
- - function isZeroExp(Exp memory value)
- interface ICERC20
- - function balanceOf(address who)
- - function isCToken()
- - function approve(address spender, uin ...
- - function balanceOfUnderlying(address ...
- - function exchangeRateCurrent()
- - function mint(uint256 mintAmount)
- - function redeem(uint256 redeemTokens)
- - function redeemUnderlying(uint256 red ...
- - function transfer(address recipient, ...
- - function transferFrom(address sender, ...
- contract Context
- - function _msgSender()
- - function _msgData()
- contract OwnableWithoutRenounce is ...
- - function initialize(address sender)
- - function owner()
- - function isOwner()
- - function transferOwnership(address ne ...
- - function _transferOwnership(address n ...
- library Roles
- - function add(Role storage role, addre ...
- - function remove(Role storage role, ad ...
- - function has(Role storage role, addre ...
- contract PauserRoleWithoutRenounce ...
- - function initialize(address sender)
- - function isPauser(address account)
- - function addPauser(address account)
- - function _addPauser(address account)
- - function _removePauser(address accoun ...
- contract PausableWithoutRenounce i ...
- - function initialize(address sender)
- - function paused()
- - function pause()
- - function unpause()
- interface ICTokenManager
- - function whitelistCToken(address toke ...
- - function discardCToken(address tokenA ...
- - function isCToken(address tokenAddres ...
- interface IERC1620
- - function balanceOf(uint256 streamId, ...
- - function getStream(uint256 streamId)
- - function createStream(address recipie ...
- - function withdrawFromStream(uint256 s ...
- - function cancelStream(uint256 streamI ...
- library Types
- contract Sablier is IERC1620, Owna ... *
- - function updateFee(uint256 feePercent ...
- - function takeEarnings(address tokenAd ...
- - function getStream(uint256 streamId)
- - function deltaOf(uint256 streamId)
- - function balanceOf(uint256 streamId, ...
- - function isCompoundingStream(uint256 ...
- - function getCompoundingStream(uint256 ...
- - function interestOf(uint256 streamId, ...
- - function getEarnings(address tokenAdd ...
- - function createStream(address recipie ...
- - function createCompoundingStream(
- - function withdrawFromStream(uint256 s ...
- - function cancelStream(uint256 streamI ...
- - function withdrawFromStreamInternal(u ...
- - function withdrawFromCompoundingStrea ...
- - function cancelStreamInternal(uint256 ...
- - function cancelCompoundingStreamInter ...
/** *Submitted for verification at Etherscan.io on 2019-11-12 */ // File: @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol pragma solidity ^0.5.2; /** * @title ERC20 interface * @dev see https://eips.ethereum.org/EIPS/eip-20 */ interface IERC20 { function transfer(address to, uint256 value) external returns (bool); function approve(address spender, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool); function totalSupply() external view returns (uint256); function balanceOf(address who) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); } // File: @openzeppelin/upgrades/contracts/Initializable.sol pragma solidity >=0.4.24 <0.6.0; /** * @title Initializable * * @dev Helper contract to support initializer functions. To use it, replace * the constructor with a function that has the `initializer` modifier. * WARNING: Unlike constructors, initializer functions must be manually * invoked. This applies both to deploying an Initializable contract, as well * as extending an Initializable contract via inheritance. * WARNING: When used with inheritance, manual care must be taken to not invoke * a parent initializer twice, or ensure that all initializers are idempotent, * because this is not dealt with automatically as with constructors. */ contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private initializing; /** * @dev Modifier to use in the initializer function of a contract. */ modifier initializer() { require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); bool isTopLevelCall = !initializing; if (isTopLevelCall) { initializing = true; initialized = true; } _; if (isTopLevelCall) { initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function isConstructor() private view returns (bool) { // extcodesize checks the size of the code stored in an address, and // address returns the current address. Since the code is still not // deployed when running a constructor, any checks on its code size will // yield zero, making it an effective way to detect if a contract is // under construction or not. uint256 cs; assembly { cs := extcodesize(address) } return cs == 0; } // Reserved storage space to allow for layout changes in the future. uint256[50] private ______gap; } // File: @openzeppelin/contracts-ethereum-package/contracts/utils/ReentrancyGuard.sol pragma solidity ^0.5.2; /** * @title Helps contracts guard against reentrancy attacks. * @author Remco Bloemen <remco@2π.com>, Eenae <[email protected]> * @dev If you mark a function `nonReentrant`, you should also * mark it `external`. */ contract ReentrancyGuard is Initializable { /// @dev counter to allow mutex lock with only one SSTORE operation uint256 private _guardCounter; function initialize() public initializer { // The counter starts at one to prevent changing it from zero to a non-zero // value, which is a more expensive operation. _guardCounter = 1; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { _guardCounter += 1; uint256 localCounter = _guardCounter; _; require(localCounter == _guardCounter); } uint256[50] private ______gap; } // File: @sablier/shared-contracts/compound/CarefulMath.sol pragma solidity ^0.5.8; /** * @title Careful Math * @author Compound * @notice Derived from OpenZeppelin's SafeMath library * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol */ contract CarefulMath { /** * @dev Possible error codes that we can return */ enum MathError { NO_ERROR, DIVISION_BY_ZERO, INTEGER_OVERFLOW, INTEGER_UNDERFLOW } /** * @dev Multiplies two numbers, returns an error on overflow. */ function mulUInt(uint a, uint b) internal pure returns (MathError, uint) { if (a == 0) { return (MathError.NO_ERROR, 0); } uint c = a * b; if (c / a != b) { return (MathError.INTEGER_OVERFLOW, 0); } else { return (MathError.NO_ERROR, c); } } /** * @dev Integer division of two numbers, truncating the quotient. */ function divUInt(uint a, uint b) internal pure returns (MathError, uint) { if (b == 0) { return (MathError.DIVISION_BY_ZERO, 0); } return (MathError.NO_ERROR, a / b); } /** * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend). */ function subUInt(uint a, uint b) internal pure returns (MathError, uint) { if (b <= a) { return (MathError.NO_ERROR, a - b); } else { return (MathError.INTEGER_UNDERFLOW, 0); } } /** * @dev Adds two numbers, returns an error on overflow. */ function addUInt(uint a, uint b) internal pure returns (MathError, uint) { uint c = a + b; if (c >= a) { return (MathError.NO_ERROR, c); } else { return (MathError.INTEGER_OVERFLOW, 0); } } /** * @dev add a and b and then subtract c */ function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) { (MathError err0, uint sum) = addUInt(a, b); if (err0 != MathError.NO_ERROR) { return (err0, 0); } return subUInt(sum, c); } } // File: @sablier/shared-contracts/compound/Exponential.sol pragma solidity ^0.5.8; /** * @title Exponential module for storing fixed-decision decimals * @author Compound * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places. * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is: * `Exp({mantissa: 5100000000000000000})`. */ contract Exponential is CarefulMath { uint constant expScale = 1e18; uint constant halfExpScale = expScale/2; uint constant mantissaOne = expScale; struct Exp { uint mantissa; } /** * @dev Creates an exponential from numerator and denominator values. * Note: Returns an error if (`num` * 10e18) > MAX_INT, * or if `denom` is zero. */ function getExp(uint num, uint denom) pure internal returns (MathError, Exp memory) { (MathError err0, uint scaledNumerator) = mulUInt(num, expScale); if (err0 != MathError.NO_ERROR) { return (err0, Exp({mantissa: 0})); } (MathError err1, uint rational) = divUInt(scaledNumerator, denom); if (err1 != MathError.NO_ERROR) { return (err1, Exp({mantissa: 0})); } return (MathError.NO_ERROR, Exp({mantissa: rational})); } /** * @dev Adds two exponentials, returning a new exponential. */ function addExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) { (MathError error, uint result) = addUInt(a.mantissa, b.mantissa); return (error, Exp({mantissa: result})); } /** * @dev Subtracts two exponentials, returning a new exponential. */ function subExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) { (MathError error, uint result) = subUInt(a.mantissa, b.mantissa); return (error, Exp({mantissa: result})); } /** * @dev Multiply an Exp by a scalar, returning a new Exp. */ function mulScalar(Exp memory a, uint scalar) pure internal returns (MathError, Exp memory) { (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar); if (err0 != MathError.NO_ERROR) { return (err0, Exp({mantissa: 0})); } return (MathError.NO_ERROR, Exp({mantissa: scaledMantissa})); } /** * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer. */ function mulScalarTruncate(Exp memory a, uint scalar) pure internal returns (MathError, uint) { (MathError err, Exp memory product) = mulScalar(a, scalar); if (err != MathError.NO_ERROR) { return (err, 0); } return (MathError.NO_ERROR, truncate(product)); } /** * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer. */ function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) pure internal returns (MathError, uint) { (MathError err, Exp memory product) = mulScalar(a, scalar); if (err != MathError.NO_ERROR) { return (err, 0); } return addUInt(truncate(product), addend); } /** * @dev Divide an Exp by a scalar, returning a new Exp. */ function divScalar(Exp memory a, uint scalar) pure internal returns (MathError, Exp memory) { (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar); if (err0 != MathError.NO_ERROR) { return (err0, Exp({mantissa: 0})); } return (MathError.NO_ERROR, Exp({mantissa: descaledMantissa})); } /** * @dev Divide a scalar by an Exp, returning a new Exp. */ function divScalarByExp(uint scalar, Exp memory divisor) pure internal returns (MathError, Exp memory) { /* We are doing this as: getExp(mulUInt(expScale, scalar), divisor.mantissa) How it works: Exp = a / b; Scalar = s; `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale` */ (MathError err0, uint numerator) = mulUInt(expScale, scalar); if (err0 != MathError.NO_ERROR) { return (err0, Exp({mantissa: 0})); } return getExp(numerator, divisor.mantissa); } /** * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer. */ function divScalarByExpTruncate(uint scalar, Exp memory divisor) pure internal returns (MathError, uint) { (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor); if (err != MathError.NO_ERROR) { return (err, 0); } return (MathError.NO_ERROR, truncate(fraction)); } /** * @dev Multiplies two exponentials, returning a new exponential. */ function mulExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) { (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa); if (err0 != MathError.NO_ERROR) { return (err0, Exp({mantissa: 0})); } // We add half the scale before dividing so that we get rounding instead of truncation. // See "Listing 6" and text above it at https://accu.org/index.php/journals/1717 // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18. (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct); if (err1 != MathError.NO_ERROR) { return (err1, Exp({mantissa: 0})); } (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale); // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero. assert(err2 == MathError.NO_ERROR); return (MathError.NO_ERROR, Exp({mantissa: product})); } /** * @dev Multiplies two exponentials given their mantissas, returning a new exponential. */ function mulExp(uint a, uint b) pure internal returns (MathError, Exp memory) { return mulExp(Exp({mantissa: a}), Exp({mantissa: b})); } /** * @dev Multiplies three exponentials, returning a new exponential. */ function mulExp3(Exp memory a, Exp memory b, Exp memory c) pure internal returns (MathError, Exp memory) { (MathError err, Exp memory ab) = mulExp(a, b); if (err != MathError.NO_ERROR) { return (err, ab); } return mulExp(ab, c); } /** * @dev Divides two exponentials, returning a new exponential. * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b, * which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa) */ function divExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) { return getExp(a.mantissa, b.mantissa); } /** * @dev Truncates the given exp to a whole number value. * For example, truncate(Exp{mantissa: 15 * expScale}) = 15 */ function truncate(Exp memory exp) pure internal returns (uint) { // Note: We are not using careful math here as we're performing a division that cannot fail return exp.mantissa / expScale; } /** * @dev Checks if first Exp is less than second Exp. */ function lessThanExp(Exp memory left, Exp memory right) pure internal returns (bool) { return left.mantissa < right.mantissa; //TODO: Add some simple tests and this in another PR yo. } /** * @dev Checks if left Exp <= right Exp. */ function lessThanOrEqualExp(Exp memory left, Exp memory right) pure internal returns (bool) { return left.mantissa <= right.mantissa; } /** * @dev Checks if left Exp > right Exp. */ function greaterThanExp(Exp memory left, Exp memory right) pure internal returns (bool) { return left.mantissa > right.mantissa; } /** * @dev returns true if Exp is exactly zero */ function isZeroExp(Exp memory value) pure internal returns (bool) { return value.mantissa == 0; } } // File: @sablier/shared-contracts/interfaces/ICERC20.sol pragma solidity 0.5.11; /** * @title CERC20 interface * @author Sablier * @dev See https://compound.finance/developers */ interface ICERC20 { function balanceOf(address who) external view returns (uint256); function isCToken() external view returns (bool); function approve(address spender, uint256 value) external returns (bool); function balanceOfUnderlying(address account) external returns (uint256); function exchangeRateCurrent() external returns (uint256); function mint(uint256 mintAmount) external returns (uint256); function redeem(uint256 redeemTokens) external returns (uint256); function redeemUnderlying(uint256 redeemAmount) external returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); } // File: @openzeppelin/contracts-ethereum-package/contracts/GSN/Context.sol pragma solidity ^0.5.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they not should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ contract Context { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, with should be used via inheritance. constructor () internal { } // solhint-disable-previous-line no-empty-blocks function _msgSender() internal view returns (address) { return msg.sender; } function _msgData() internal view returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: @sablier/shared-contracts/lifecycle/OwnableWithoutRenounce.sol pragma solidity 0.5.11; /** * @title OwnableWithoutRenounce * @author Sablier * @dev Fork of OpenZeppelin's Ownable contract, which provides basic authorization control, but with * the `renounceOwnership` function removed to avoid fat-finger errors. * We inherit from `Context` to keep this contract compatible with the Gas Station Network. * See https://github.com/OpenZeppelin/openzeppelin-contracts-ethereum-package/blob/master/contracts/ownership/Ownable.sol * See https://forum.openzeppelin.com/t/contract-request-ownable-without-renounceownership/1400 * See https://docs.openzeppelin.com/contracts/2.x/gsn#_msg_sender_and_msg_data */ contract OwnableWithoutRenounce is Initializable, Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ function initialize(address sender) public initializer { _owner = sender; emit OwnershipTransferred(address(0), _owner); } /** * @return the address of the owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner()); _; } /** * @return true if `msg.sender` is the owner of the contract. */ function isOwner() public view returns (bool) { return _msgSender() == _owner; } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0)); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } uint256[50] private ______gap; } // File: @openzeppelin/contracts-ethereum-package/contracts/access/Roles.sol pragma solidity ^0.5.2; /** * @title Roles * @dev Library for managing addresses assigned to a Role. */ library Roles { struct Role { mapping (address => bool) bearer; } /** * @dev give an account access to this role */ function add(Role storage role, address account) internal { require(account != address(0)); require(!has(role, account)); role.bearer[account] = true; } /** * @dev remove an account's access to this role */ function remove(Role storage role, address account) internal { require(account != address(0)); require(has(role, account)); role.bearer[account] = false; } /** * @dev check if an account has this role * @return bool */ function has(Role storage role, address account) internal view returns (bool) { require(account != address(0)); return role.bearer[account]; } } // File: @sablier/shared-contracts/lifecycle/PauserRoleWithoutRenounce.sol pragma solidity ^0.5.0; /** * @title PauserRoleWithoutRenounce * @author Sablier * @notice Fork of OpenZeppelin's PauserRole, but with the `renouncePauser` function removed to avoid fat-finger errors. * We inherit from `Context` to keep this contract compatible with the Gas Station Network. * See https://github.com/OpenZeppelin/openzeppelin-contracts-ethereum-package/blob/master/contracts/access/roles/PauserRole.sol */ contract PauserRoleWithoutRenounce is Initializable, Context { using Roles for Roles.Role; event PauserAdded(address indexed account); event PauserRemoved(address indexed account); Roles.Role private _pausers; function initialize(address sender) public initializer { if (!isPauser(sender)) { _addPauser(sender); } } modifier onlyPauser() { require(isPauser(_msgSender()), "PauserRole: caller does not have the Pauser role"); _; } function isPauser(address account) public view returns (bool) { return _pausers.has(account); } function addPauser(address account) public onlyPauser { _addPauser(account); } function _addPauser(address account) internal { _pausers.add(account); emit PauserAdded(account); } function _removePauser(address account) internal { _pausers.remove(account); emit PauserRemoved(account); } uint256[50] private ______gap; } // File: @sablier/shared-contracts/lifecycle/PausableWithoutRenounce.sol pragma solidity 0.5.11; /** * @title PausableWithoutRenounce * @author Sablier * @notice Fork of OpenZeppelin's Pausable, a contract module which allows children to implement an * emergency stop mechanism that can be triggered by an authorized account, but with the `renouncePauser` * function removed to avoid fat-finger errors. * We inherit from `Context` to keep this contract compatible with the Gas Station Network. * See https://github.com/OpenZeppelin/openzeppelin-contracts-ethereum-package/blob/master/contracts/lifecycle/Pausable.sol * See https://docs.openzeppelin.com/contracts/2.x/gsn#_msg_sender_and_msg_data */ contract PausableWithoutRenounce is Initializable, Context, PauserRoleWithoutRenounce { /** * @dev Emitted when the pause is triggered by a pauser (`account`). */ event Paused(address account); /** * @dev Emitted when the pause is lifted by a pauser (`account`). */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. Assigns the Pauser role * to the deployer. */ function initialize(address sender) public initializer { PauserRoleWithoutRenounce.initialize(sender); _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. */ modifier whenNotPaused() { require(!_paused, "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. */ modifier whenPaused() { require(_paused, "Pausable: not paused"); _; } /** * @dev Called by a pauser to pause, triggers stopped state. */ function pause() public onlyPauser whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Called by a pauser to unpause, returns to normal state. */ function unpause() public onlyPauser whenPaused { _paused = false; emit Unpaused(_msgSender()); } } // File: contracts/interfaces/ICTokenManager.sol pragma solidity 0.5.11; /** * @title CTokenManager Interface * @author Sablier */ interface ICTokenManager { /** * @notice Emits when the owner discards a cToken. */ event DiscardCToken(address indexed tokenAddress); /** * @notice Emits when the owner whitelists a cToken. */ event WhitelistCToken(address indexed tokenAddress); function whitelistCToken(address tokenAddress) external; function discardCToken(address tokenAddress) external; function isCToken(address tokenAddress) external view returns (bool); } // File: contracts/interfaces/IERC1620.sol pragma solidity 0.5.11; /** * @title ERC-1620 Money Streaming Standard * @author Paul Razvan Berg - <[email protected]> * @dev See https://eips.ethereum.org/EIPS/eip-1620 */ interface IERC1620 { /** * @notice Emits when a stream is successfully created. */ event CreateStream( uint256 indexed streamId, address indexed sender, address indexed recipient, uint256 deposit, address tokenAddress, uint256 startTime, uint256 stopTime ); /** * @notice Emits when the recipient of a stream withdraws a portion or all their pro rata share of the stream. */ event WithdrawFromStream(uint256 indexed streamId, address indexed recipient, uint256 amount); /** * @notice Emits when a stream is successfully cancelled and tokens are transferred back on a pro rata basis. */ event CancelStream( uint256 indexed streamId, address indexed sender, address indexed recipient, uint256 senderBalance, uint256 recipientBalance ); function balanceOf(uint256 streamId, address who) external view returns (uint256 balance); function getStream(uint256 streamId) external view returns ( address sender, address recipient, uint256 deposit, address token, uint256 startTime, uint256 stopTime, uint256 balance, uint256 rate ); function createStream(address recipient, uint256 deposit, address tokenAddress, uint256 startTime, uint256 stopTime) external returns (uint256 streamId); function withdrawFromStream(uint256 streamId, uint256 funds) external returns (bool); function cancelStream(uint256 streamId) external returns (bool); } // File: contracts/Types.sol pragma solidity 0.5.11; /** * @title Sablier Types * @author Sablier */ library Types { struct Stream { uint256 deposit; uint256 ratePerSecond; uint256 remainingBalance; uint256 startTime; uint256 stopTime; address recipient; address sender; address tokenAddress; bool isEntity; } struct CompoundingStreamVars { Exponential.Exp exchangeRateInitial; Exponential.Exp senderShare; Exponential.Exp recipientShare; bool isEntity; } } // File: contracts/Sablier.sol pragma solidity 0.5.11; /** * @title Sablier's Money Streaming * @author Sablier */ contract Sablier is IERC1620, OwnableWithoutRenounce, PausableWithoutRenounce, Exponential, ReentrancyGuard { /*** Storage Properties ***/ /** * @notice In Exp terms, 1e18 is 1, or 100% */ uint256 constant hundredPercent = 1e18; /** * @notice In Exp terms, 1e16 is 0.01, or 1% */ uint256 constant onePercent = 1e16; /** * @notice Stores information about the initial state of the underlying of the cToken. */ mapping(uint256 => Types.CompoundingStreamVars) private compoundingStreamsVars; /** * @notice An instance of CTokenManager, responsible for whitelisting and discarding cTokens. */ ICTokenManager public cTokenManager; /** * @notice The amount of interest has been accrued per token address. */ mapping(address => uint256) private earnings; /** * @notice The percentage fee charged by the contract on the accrued interest. */ Exp public fee; /** * @notice Counter for new stream ids. */ uint256 public nextStreamId; /** * @notice The stream objects identifiable by their unsigned integer ids. */ mapping(uint256 => Types.Stream) private streams; /*** Events ***/ /** * @notice Emits when a compounding stream is successfully created. */ event CreateCompoundingStream( uint256 indexed streamId, uint256 exchangeRate, uint256 senderSharePercentage, uint256 recipientSharePercentage ); /** * @notice Emits when the owner discards a cToken. */ event PayInterest( uint256 indexed streamId, uint256 senderInterest, uint256 recipientInterest, uint256 sablierInterest ); /** * @notice Emits when the owner takes the earnings. */ event TakeEarnings(address indexed tokenAddress, uint256 indexed amount); /** * @notice Emits when the owner updates the percentage fee. */ event UpdateFee(uint256 indexed fee); /*** Modifiers ***/ /** * @dev Throws if the caller is not the sender of the recipient of the stream. */ modifier onlySenderOrRecipient(uint256 streamId) { require( msg.sender == streams[streamId].sender || msg.sender == streams[streamId].recipient, "caller is not the sender or the recipient of the stream" ); _; } /** * @dev Throws if the id does not point to a valid stream. */ modifier streamExists(uint256 streamId) { require(streams[streamId].isEntity, "stream does not exist"); _; } /** * @dev Throws if the id does not point to a valid compounding stream. */ modifier compoundingStreamExists(uint256 streamId) { require(compoundingStreamsVars[streamId].isEntity, "compounding stream does not exist"); _; } /*** Contract Logic Starts Here */ constructor(address cTokenManagerAddress) public { require(cTokenManagerAddress != address(0x00), "cTokenManager contract is the zero address"); OwnableWithoutRenounce.initialize(msg.sender); PausableWithoutRenounce.initialize(msg.sender); cTokenManager = ICTokenManager(cTokenManagerAddress); nextStreamId = 1; } /*** Owner Functions ***/ struct UpdateFeeLocalVars { MathError mathErr; uint256 feeMantissa; } /** * @notice Updates the Sablier fee. * @dev Throws if the caller is not the owner of the contract. * Throws if `feePercentage` is not lower or equal to 100. * @param feePercentage The new fee as a percentage. */ function updateFee(uint256 feePercentage) external onlyOwner { require(feePercentage <= 100, "fee percentage higher than 100%"); UpdateFeeLocalVars memory vars; /* `feePercentage` will be stored as a mantissa, so we scale it up by one percent in Exp terms. */ (vars.mathErr, vars.feeMantissa) = mulUInt(feePercentage, onePercent); /* * `mulUInt` can only return MathError.INTEGER_OVERFLOW but we control `onePercent` * and we know `feePercentage` is maximum 100. */ assert(vars.mathErr == MathError.NO_ERROR); fee = Exp({ mantissa: vars.feeMantissa }); emit UpdateFee(feePercentage); } struct TakeEarningsLocalVars { MathError mathErr; } /** * @notice Withdraws the earnings for the given token address. * @dev Throws if `amount` exceeds the available balance. * @param tokenAddress The address of the token to withdraw earnings for. * @param amount The amount of tokens to withdraw. */ function takeEarnings(address tokenAddress, uint256 amount) external onlyOwner nonReentrant { require(cTokenManager.isCToken(tokenAddress), "cToken is not whitelisted"); require(amount > 0, "amount is zero"); require(earnings[tokenAddress] >= amount, "amount exceeds the available balance"); TakeEarningsLocalVars memory vars; (vars.mathErr, earnings[tokenAddress]) = subUInt(earnings[tokenAddress], amount); /* * `subUInt` can only return MathError.INTEGER_UNDERFLOW but we know `earnings[tokenAddress]` * is at least as big as `amount`. */ assert(vars.mathErr == MathError.NO_ERROR); emit TakeEarnings(tokenAddress, amount); require(IERC20(tokenAddress).transfer(msg.sender, amount), "token transfer failure"); } /*** View Functions ***/ /** * @notice Returns the compounding stream with all its properties. * @dev Throws if the id does not point to a valid stream. * @param streamId The id of the stream to query. * @return The stream object. */ function getStream(uint256 streamId) external view streamExists(streamId) returns ( address sender, address recipient, uint256 deposit, address tokenAddress, uint256 startTime, uint256 stopTime, uint256 remainingBalance, uint256 ratePerSecond ) { sender = streams[streamId].sender; recipient = streams[streamId].recipient; deposit = streams[streamId].deposit; tokenAddress = streams[streamId].tokenAddress; startTime = streams[streamId].startTime; stopTime = streams[streamId].stopTime; remainingBalance = streams[streamId].remainingBalance; ratePerSecond = streams[streamId].ratePerSecond; } /** * @notice Returns either the delta in seconds between `block.timestamp` and `startTime` or * between `stopTime` and `startTime, whichever is smaller. If `block.timestamp` is before * `startTime`, it returns 0. * @dev Throws if the id does not point to a valid stream. * @param streamId The id of the stream for whom to query the delta. * @return The time delta in seconds. */ function deltaOf(uint256 streamId) public view streamExists(streamId) returns (uint256 delta) { Types.Stream memory stream = streams[streamId]; if (block.timestamp <= stream.startTime) return 0; if (block.timestamp < stream.stopTime) return block.timestamp - stream.startTime; return stream.stopTime - stream.startTime; } struct BalanceOfLocalVars { MathError mathErr; uint256 recipientBalance; uint256 withdrawalAmount; uint256 senderBalance; } /** * @notice Returns the available funds for the given stream id and address. * @dev Throws if the id does not point to a valid stream. * @param streamId The id of the stream for whom to query the balance. * @param who The address for whom to query the balance. * @return The total funds allocated to `who` as uint256. */ function balanceOf(uint256 streamId, address who) public view streamExists(streamId) returns (uint256 balance) { Types.Stream memory stream = streams[streamId]; BalanceOfLocalVars memory vars; uint256 delta = deltaOf(streamId); (vars.mathErr, vars.recipientBalance) = mulUInt(delta, stream.ratePerSecond); require(vars.mathErr == MathError.NO_ERROR, "recipient balance calculation error"); /* * If the stream `balance` does not equal `deposit`, it means there have been withdrawals. * We have to subtract the total amount withdrawn from the amount of money that has been * streamed until now. */ if (stream.deposit > stream.remainingBalance) { (vars.mathErr, vars.withdrawalAmount) = subUInt(stream.deposit, stream.remainingBalance); assert(vars.mathErr == MathError.NO_ERROR); (vars.mathErr, vars.recipientBalance) = subUInt(vars.recipientBalance, vars.withdrawalAmount); /* `withdrawalAmount` cannot and should not be bigger than `recipientBalance`. */ assert(vars.mathErr == MathError.NO_ERROR); } if (who == stream.recipient) return vars.recipientBalance; if (who == stream.sender) { (vars.mathErr, vars.senderBalance) = subUInt(stream.remainingBalance, vars.recipientBalance); /* `recipientBalance` cannot and should not be bigger than `remainingBalance`. */ assert(vars.mathErr == MathError.NO_ERROR); return vars.senderBalance; } return 0; } /** * @notice Checks if the given id points to a compounding stream. * @param streamId The id of the compounding stream to check. * @return bool true=it is compounding stream, otherwise false. */ function isCompoundingStream(uint256 streamId) public view returns (bool) { return compoundingStreamsVars[streamId].isEntity; } /** * @notice Returns the compounding stream object with all its properties. * @dev Throws if the id does not point to a valid compounding stream. * @param streamId The id of the compounding stream to query. * @return The compounding stream object. */ function getCompoundingStream(uint256 streamId) external view streamExists(streamId) compoundingStreamExists(streamId) returns ( address sender, address recipient, uint256 deposit, address tokenAddress, uint256 startTime, uint256 stopTime, uint256 remainingBalance, uint256 ratePerSecond, uint256 exchangeRateInitial, uint256 senderSharePercentage, uint256 recipientSharePercentage ) { sender = streams[streamId].sender; recipient = streams[streamId].recipient; deposit = streams[streamId].deposit; tokenAddress = streams[streamId].tokenAddress; startTime = streams[streamId].startTime; stopTime = streams[streamId].stopTime; remainingBalance = streams[streamId].remainingBalance; ratePerSecond = streams[streamId].ratePerSecond; exchangeRateInitial = compoundingStreamsVars[streamId].exchangeRateInitial.mantissa; senderSharePercentage = compoundingStreamsVars[streamId].senderShare.mantissa; recipientSharePercentage = compoundingStreamsVars[streamId].recipientShare.mantissa; } struct InterestOfLocalVars { MathError mathErr; Exp exchangeRateDelta; Exp underlyingInterest; Exp netUnderlyingInterest; Exp senderUnderlyingInterest; Exp recipientUnderlyingInterest; Exp sablierUnderlyingInterest; Exp senderInterest; Exp recipientInterest; Exp sablierInterest; } /** * @notice Computes the interest accrued by keeping the amount of tokens in the contract. Returns (0, 0, 0) if * the stream is not a compounding stream. * @dev Throws if there is a math error. We do not assert the calculations which involve the current * exchange rate, because we can't know what value we'll get back from the cToken contract. * @return The interest accrued by the sender, the recipient and sablier, respectively, as uint256s. */ function interestOf(uint256 streamId, uint256 amount) public streamExists(streamId) returns (uint256 senderInterest, uint256 recipientInterest, uint256 sablierInterest) { if (!compoundingStreamsVars[streamId].isEntity) { return (0, 0, 0); } Types.Stream memory stream = streams[streamId]; Types.CompoundingStreamVars memory compoundingStreamVars = compoundingStreamsVars[streamId]; InterestOfLocalVars memory vars; /* * The exchange rate delta is a key variable, since it leads us to how much interest has been earned * since the compounding stream was created. */ Exp memory exchangeRateCurrent = Exp({ mantissa: ICERC20(stream.tokenAddress).exchangeRateCurrent() }); if (exchangeRateCurrent.mantissa <= compoundingStreamVars.exchangeRateInitial.mantissa) { return (0, 0, 0); } (vars.mathErr, vars.exchangeRateDelta) = subExp(exchangeRateCurrent, compoundingStreamVars.exchangeRateInitial); assert(vars.mathErr == MathError.NO_ERROR); /* Calculate how much interest has been earned by holding `amount` in the smart contract. */ (vars.mathErr, vars.underlyingInterest) = mulScalar(vars.exchangeRateDelta, amount); require(vars.mathErr == MathError.NO_ERROR, "interest calculation error"); /* Calculate our share from that interest. */ if (fee.mantissa == hundredPercent) { (vars.mathErr, vars.sablierInterest) = divExp(vars.underlyingInterest, exchangeRateCurrent); require(vars.mathErr == MathError.NO_ERROR, "sablier interest conversion error"); return (0, 0, truncate(vars.sablierInterest)); } else if (fee.mantissa == 0) { vars.sablierUnderlyingInterest = Exp({ mantissa: 0 }); vars.netUnderlyingInterest = vars.underlyingInterest; } else { (vars.mathErr, vars.sablierUnderlyingInterest) = mulExp(vars.underlyingInterest, fee); require(vars.mathErr == MathError.NO_ERROR, "sablier interest calculation error"); /* Calculate how much interest is left for the sender and the recipient. */ (vars.mathErr, vars.netUnderlyingInterest) = subExp( vars.underlyingInterest, vars.sablierUnderlyingInterest ); /* * `subUInt` can only return MathError.INTEGER_UNDERFLOW but we know that `sablierUnderlyingInterest` * is less or equal than `underlyingInterest`, because we control the value of `fee`. */ assert(vars.mathErr == MathError.NO_ERROR); } /* Calculate the sender's share of the interest. */ (vars.mathErr, vars.senderUnderlyingInterest) = mulExp( vars.netUnderlyingInterest, compoundingStreamVars.senderShare ); require(vars.mathErr == MathError.NO_ERROR, "sender interest calculation error"); /* Calculate the recipient's share of the interest. */ (vars.mathErr, vars.recipientUnderlyingInterest) = subExp( vars.netUnderlyingInterest, vars.senderUnderlyingInterest ); /* * `subUInt` can only return MathError.INTEGER_UNDERFLOW but we know that `senderUnderlyingInterest` * is less or equal than `netUnderlyingInterest`, because `senderShare` is bounded between 1e16 and 1e18. */ assert(vars.mathErr == MathError.NO_ERROR); /* Convert the interest to the equivalent cToken denomination. */ (vars.mathErr, vars.senderInterest) = divExp(vars.senderUnderlyingInterest, exchangeRateCurrent); require(vars.mathErr == MathError.NO_ERROR, "sender interest conversion error"); (vars.mathErr, vars.recipientInterest) = divExp(vars.recipientUnderlyingInterest, exchangeRateCurrent); require(vars.mathErr == MathError.NO_ERROR, "recipient interest conversion error"); (vars.mathErr, vars.sablierInterest) = divExp(vars.sablierUnderlyingInterest, exchangeRateCurrent); require(vars.mathErr == MathError.NO_ERROR, "sablier interest conversion error"); /* Truncating the results means losing everything on the last 1e18 positions of the mantissa */ return (truncate(vars.senderInterest), truncate(vars.recipientInterest), truncate(vars.sablierInterest)); } /** * @notice Returns the amount of interest that has been accrued for the given token address. * @param tokenAddress The address of the token to get the earnings for. * @return The amount of interest as uint256. */ function getEarnings(address tokenAddress) external view returns (uint256) { require(cTokenManager.isCToken(tokenAddress), "token is not cToken"); return earnings[tokenAddress]; } /*** Public Effects & Interactions Functions ***/ struct CreateStreamLocalVars { MathError mathErr; uint256 duration; uint256 ratePerSecond; } /** * @notice Creates a new stream funded by `msg.sender` and paid towards `recipient`. * @dev Throws if paused. * Throws if the recipient is the zero address, the contract itself or the caller. * Throws if the deposit is 0. * Throws if the start time is before `block.timestamp`. * Throws if the stop time is before the start time. * Throws if the duration calculation has a math error. * Throws if the deposit is smaller than the duration. * Throws if the deposit is not a multiple of the duration. * Throws if the rate calculation has a math error. * Throws if the next stream id calculation has a math error. * Throws if the contract is not allowed to transfer enough tokens. * Throws if there is a token transfer failure. * @param recipient The address towards which the money is streamed. * @param deposit The amount of money to be streamed. * @param tokenAddress The ERC20 token to use as streaming currency. * @param startTime The unix timestamp for when the stream starts. * @param stopTime The unix timestamp for when the stream stops. * @return The uint256 id of the newly created stream. */ function createStream(address recipient, uint256 deposit, address tokenAddress, uint256 startTime, uint256 stopTime) public whenNotPaused returns (uint256) { require(recipient != address(0x00), "stream to the zero address"); require(recipient != address(this), "stream to the contract itself"); require(recipient != msg.sender, "stream to the caller"); require(deposit > 0, "deposit is zero"); require(startTime >= block.timestamp, "start time before block.timestamp"); require(stopTime > startTime, "stop time before the start time"); CreateStreamLocalVars memory vars; (vars.mathErr, vars.duration) = subUInt(stopTime, startTime); /* `subUInt` can only return MathError.INTEGER_UNDERFLOW but we know `stopTime` is higher than `startTime`. */ assert(vars.mathErr == MathError.NO_ERROR); /* Without this, the rate per second would be zero. */ require(deposit >= vars.duration, "deposit smaller than time delta"); /* This condition avoids dealing with remainders */ require(deposit % vars.duration == 0, "deposit not multiple of time delta"); (vars.mathErr, vars.ratePerSecond) = divUInt(deposit, vars.duration); /* `divUInt` can only return MathError.DIVISION_BY_ZERO but we know `duration` is not zero. */ assert(vars.mathErr == MathError.NO_ERROR); /* Create and store the stream object. */ uint256 streamId = nextStreamId; streams[streamId] = Types.Stream({ remainingBalance: deposit, deposit: deposit, isEntity: true, ratePerSecond: vars.ratePerSecond, recipient: recipient, sender: msg.sender, startTime: startTime, stopTime: stopTime, tokenAddress: tokenAddress }); /* Increment the next stream id. */ (vars.mathErr, nextStreamId) = addUInt(nextStreamId, uint256(1)); require(vars.mathErr == MathError.NO_ERROR, "next stream id calculation error"); require(IERC20(tokenAddress).transferFrom(msg.sender, address(this), deposit), "token transfer failure"); emit CreateStream(streamId, msg.sender, recipient, deposit, tokenAddress, startTime, stopTime); return streamId; } struct CreateCompoundingStreamLocalVars { MathError mathErr; uint256 shareSum; uint256 underlyingBalance; uint256 senderShareMantissa; uint256 recipientShareMantissa; } /** * @notice Creates a new compounding stream funded by `msg.sender` and paid towards `recipient`. * @dev Inherits all security checks from `createStream`. * Throws if the cToken is not whitelisted. * Throws if the sender share percentage and the recipient share percentage do not sum up to 100. * Throws if the the sender share mantissa calculation has a math error. * Throws if the the recipient share mantissa calculation has a math error. * @param recipient The address towards which the money is streamed. * @param deposit The amount of money to be streamed. * @param tokenAddress The ERC20 token to use as streaming currency. * @param startTime The unix timestamp for when the stream starts. * @param stopTime The unix timestamp for when the stream stops. * @param senderSharePercentage The sender's share of the interest, as a percentage. * @param recipientSharePercentage The recipient's share of the interest, as a percentage. * @return The uint256 id of the newly created compounding stream. */ function createCompoundingStream( address recipient, uint256 deposit, address tokenAddress, uint256 startTime, uint256 stopTime, uint256 senderSharePercentage, uint256 recipientSharePercentage ) external whenNotPaused returns (uint256) { require(cTokenManager.isCToken(tokenAddress), "cToken is not whitelisted"); CreateCompoundingStreamLocalVars memory vars; /* Ensure that the interest shares sum up to 100%. */ (vars.mathErr, vars.shareSum) = addUInt(senderSharePercentage, recipientSharePercentage); require(vars.mathErr == MathError.NO_ERROR, "share sum calculation error"); require(vars.shareSum == 100, "shares do not sum up to 100"); uint256 streamId = createStream(recipient, deposit, tokenAddress, startTime, stopTime); /* * `senderSharePercentage` and `recipientSharePercentage` will be stored as mantissas, so we scale them up * by one percent in Exp terms. */ (vars.mathErr, vars.senderShareMantissa) = mulUInt(senderSharePercentage, onePercent); /* * `mulUInt` can only return MathError.INTEGER_OVERFLOW but we control `onePercent` and * we know `senderSharePercentage` is maximum 100. */ assert(vars.mathErr == MathError.NO_ERROR); (vars.mathErr, vars.recipientShareMantissa) = mulUInt(recipientSharePercentage, onePercent); /* * `mulUInt` can only return MathError.INTEGER_OVERFLOW but we control `onePercent` and * we know `recipientSharePercentage` is maximum 100. */ assert(vars.mathErr == MathError.NO_ERROR); /* Create and store the compounding stream vars. */ uint256 exchangeRateCurrent = ICERC20(tokenAddress).exchangeRateCurrent(); compoundingStreamsVars[streamId] = Types.CompoundingStreamVars({ exchangeRateInitial: Exp({ mantissa: exchangeRateCurrent }), isEntity: true, recipientShare: Exp({ mantissa: vars.recipientShareMantissa }), senderShare: Exp({ mantissa: vars.senderShareMantissa }) }); emit CreateCompoundingStream(streamId, exchangeRateCurrent, senderSharePercentage, recipientSharePercentage); return streamId; } /** * @notice Withdraws from the contract to the recipient's account. * @dev Throws if the id does not point to a valid stream. * Throws if the caller is not the sender or the recipient of the stream. * Throws if the amount exceeds the available balance. * Throws if there is a token transfer failure. * @param streamId The id of the stream to withdraw tokens from. * @param amount The amount of tokens to withdraw. * @return bool true=success, otherwise false. */ function withdrawFromStream(uint256 streamId, uint256 amount) external whenNotPaused nonReentrant streamExists(streamId) onlySenderOrRecipient(streamId) returns (bool) { require(amount > 0, "amount is zero"); Types.Stream memory stream = streams[streamId]; uint256 balance = balanceOf(streamId, stream.recipient); require(balance >= amount, "amount exceeds the available balance"); if (!compoundingStreamsVars[streamId].isEntity) { withdrawFromStreamInternal(streamId, amount); } else { withdrawFromCompoundingStreamInternal(streamId, amount); } return true; } /** * @notice Cancels the stream and transfers the tokens back on a pro rata basis. * @dev Throws if the id does not point to a valid stream. * Throws if the caller is not the sender or the recipient of the stream. * Throws if there is a token transfer failure. * @param streamId The id of the stream to cancel. * @return bool true=success, otherwise false. */ function cancelStream(uint256 streamId) external nonReentrant streamExists(streamId) onlySenderOrRecipient(streamId) returns (bool) { if (!compoundingStreamsVars[streamId].isEntity) { cancelStreamInternal(streamId); } else { cancelCompoundingStreamInternal(streamId); } return true; } /*** Internal Effects & Interactions Functions ***/ struct WithdrawFromStreamInternalLocalVars { MathError mathErr; } /** * @notice Makes the withdrawal to the recipient of the stream. * @dev If the stream balance has been depleted to 0, the stream object is deleted * to save gas and optimise contract storage. * Throws if the stream balance calculation has a math error. * Throws if there is a token transfer failure. */ function withdrawFromStreamInternal(uint256 streamId, uint256 amount) internal { Types.Stream memory stream = streams[streamId]; WithdrawFromStreamInternalLocalVars memory vars; (vars.mathErr, streams[streamId].remainingBalance) = subUInt(stream.remainingBalance, amount); /** * `subUInt` can only return MathError.INTEGER_UNDERFLOW but we know that `remainingBalance` is at least * as big as `amount`. See the `require` check in `withdrawFromInternal`. */ assert(vars.mathErr == MathError.NO_ERROR); if (streams[streamId].remainingBalance == 0) delete streams[streamId]; require(IERC20(stream.tokenAddress).transfer(stream.recipient, amount), "token transfer failure"); emit WithdrawFromStream(streamId, stream.recipient, amount); } struct WithdrawFromCompoundingStreamInternalLocalVars { MathError mathErr; uint256 amountWithoutSenderInterest; uint256 netWithdrawalAmount; } /** * @notice Withdraws to the recipient's account and pays the accrued interest to all parties. * @dev If the stream balance has been depleted to 0, the stream object to save gas and optimise * contract storage. * Throws if there is a math error. * Throws if there is a token transfer failure. */ function withdrawFromCompoundingStreamInternal(uint256 streamId, uint256 amount) internal { Types.Stream memory stream = streams[streamId]; WithdrawFromCompoundingStreamInternalLocalVars memory vars; /* Calculate the interest earned by each party for keeping `stream.balance` in the smart contract. */ (uint256 senderInterest, uint256 recipientInterest, uint256 sablierInterest) = interestOf(streamId, amount); /* * Calculate the net withdrawal amount by subtracting `senderInterest` and `sablierInterest`. * Because the decimal points are lost when we truncate Exponentials, the recipient will implicitly earn * `recipientInterest` plus a tiny-weeny amount of interest, max 2e-8 in cToken denomination. */ (vars.mathErr, vars.amountWithoutSenderInterest) = subUInt(amount, senderInterest); require(vars.mathErr == MathError.NO_ERROR, "amount without sender interest calculation error"); (vars.mathErr, vars.netWithdrawalAmount) = subUInt(vars.amountWithoutSenderInterest, sablierInterest); require(vars.mathErr == MathError.NO_ERROR, "net withdrawal amount calculation error"); /* Subtract `amount` from the remaining balance of the stream. */ (vars.mathErr, streams[streamId].remainingBalance) = subUInt(stream.remainingBalance, amount); require(vars.mathErr == MathError.NO_ERROR, "balance subtraction calculation error"); /* Delete the objects from storage if the remaining balance has been depleted to 0. */ if (streams[streamId].remainingBalance == 0) { delete streams[streamId]; delete compoundingStreamsVars[streamId]; } /* Add the sablier interest to the earnings for this cToken. */ (vars.mathErr, earnings[stream.tokenAddress]) = addUInt(earnings[stream.tokenAddress], sablierInterest); require(vars.mathErr == MathError.NO_ERROR, "earnings addition calculation error"); /* Transfer the tokens to the sender and the recipient. */ ICERC20 cToken = ICERC20(stream.tokenAddress); if (senderInterest > 0) require(cToken.transfer(stream.sender, senderInterest), "sender token transfer failure"); require(cToken.transfer(stream.recipient, vars.netWithdrawalAmount), "recipient token transfer failure"); emit WithdrawFromStream(streamId, stream.recipient, vars.netWithdrawalAmount); emit PayInterest(streamId, senderInterest, recipientInterest, sablierInterest); } /** * @notice Cancels the stream and transfers the tokens back on a pro rata basis. * @dev The stream and compounding stream vars objects get deleted to save gas * and optimise contract storage. * Throws if there is a token transfer failure. */ function cancelStreamInternal(uint256 streamId) internal { Types.Stream memory stream = streams[streamId]; uint256 senderBalance = balanceOf(streamId, stream.sender); uint256 recipientBalance = balanceOf(streamId, stream.recipient); delete streams[streamId]; IERC20 token = IERC20(stream.tokenAddress); if (recipientBalance > 0) require(token.transfer(stream.recipient, recipientBalance), "recipient token transfer failure"); if (senderBalance > 0) require(token.transfer(stream.sender, senderBalance), "sender token transfer failure"); emit CancelStream(streamId, stream.sender, stream.recipient, senderBalance, recipientBalance); } struct CancelCompoundingStreamInternal { MathError mathErr; uint256 netSenderBalance; uint256 recipientBalanceWithoutSenderInterest; uint256 netRecipientBalance; } /** * @notice Cancels the stream, transfers the tokens back on a pro rata basis and pays the accrued * interest to all parties. * @dev Importantly, the money that has not been streamed yet is not considered chargeable. * All the interest generated by that underlying will be returned to the sender. * Throws if there is a math error. * Throws if there is a token transfer failure. */ function cancelCompoundingStreamInternal(uint256 streamId) internal { Types.Stream memory stream = streams[streamId]; CancelCompoundingStreamInternal memory vars; /* * The sender gets back all the money that has not been streamed so far. By that, we mean both * the underlying amount and the interest generated by it. */ uint256 senderBalance = balanceOf(streamId, stream.sender); uint256 recipientBalance = balanceOf(streamId, stream.recipient); /* Calculate the interest earned by each party for keeping `recipientBalance` in the smart contract. */ (uint256 senderInterest, uint256 recipientInterest, uint256 sablierInterest) = interestOf( streamId, recipientBalance ); /* * We add `senderInterest` to `senderBalance` to compute the net balance for the sender. * After this, the rest of the function is similar to `withdrawFromCompoundingStreamInternal`, except * we add the sender's share of the interest generated by `recipientBalance` to `senderBalance`. */ (vars.mathErr, vars.netSenderBalance) = addUInt(senderBalance, senderInterest); require(vars.mathErr == MathError.NO_ERROR, "net sender balance calculation error"); /* * Calculate the net withdrawal amount by subtracting `senderInterest` and `sablierInterest`. * Because the decimal points are lost when we truncate Exponentials, the recipient will implicitly earn * `recipientInterest` plus a tiny-weeny amount of interest, max 2e-8 in cToken denomination. */ (vars.mathErr, vars.recipientBalanceWithoutSenderInterest) = subUInt(recipientBalance, senderInterest); require(vars.mathErr == MathError.NO_ERROR, "recipient balance without sender interest calculation error"); (vars.mathErr, vars.netRecipientBalance) = subUInt(vars.recipientBalanceWithoutSenderInterest, sablierInterest); require(vars.mathErr == MathError.NO_ERROR, "net recipient balance calculation error"); /* Add the sablier interest to the earnings attributed to this cToken. */ (vars.mathErr, earnings[stream.tokenAddress]) = addUInt(earnings[stream.tokenAddress], sablierInterest); require(vars.mathErr == MathError.NO_ERROR, "earnings addition calculation error"); /* Delete the objects from storage. */ delete streams[streamId]; delete compoundingStreamsVars[streamId]; /* Transfer the tokens to the sender and the recipient. */ IERC20 token = IERC20(stream.tokenAddress); if (vars.netSenderBalance > 0) require(token.transfer(stream.sender, vars.netSenderBalance), "sender token transfer failure"); if (vars.netRecipientBalance > 0) require(token.transfer(stream.recipient, vars.netRecipientBalance), "recipient token transfer failure"); emit CancelStream(streamId, stream.sender, stream.recipient, vars.netSenderBalance, vars.netRecipientBalance); emit PayInterest(streamId, senderInterest, recipientInterest, sablierInterest); } }
Contract Security Audit
- Quantstamp - November 25th, 2019 - Security Audit Report
Contract ABI
[{"constant":true,"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"getEarnings","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"nextStreamId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"}],"name":"getCompoundingStream","outputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"stopTime","type":"uint256"},{"internalType":"uint256","name":"remainingBalance","type":"uint256"},{"internalType":"uint256","name":"ratePerSecond","type":"uint256"},{"internalType":"uint256","name":"exchangeRateInitial","type":"uint256"},{"internalType":"uint256","name":"senderSharePercentage","type":"uint256"},{"internalType":"uint256","name":"recipientSharePercentage","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"},{"internalType":"address","name":"who","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isPauser","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"}],"name":"cancelStream","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawFromStream","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"stopTime","type":"uint256"},{"internalType":"uint256","name":"senderSharePercentage","type":"uint256"},{"internalType":"uint256","name":"recipientSharePercentage","type":"uint256"}],"name":"createCompoundingStream","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addPauser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"}],"name":"getStream","outputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"stopTime","type":"uint256"},{"internalType":"uint256","name":"remainingBalance","type":"uint256"},{"internalType":"uint256","name":"ratePerSecond","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"interestOf","outputs":[{"internalType":"uint256","name":"senderInterest","type":"uint256"},{"internalType":"uint256","name":"recipientInterest","type":"uint256"},{"internalType":"uint256","name":"sablierInterest","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"feePercentage","type":"uint256"}],"name":"updateFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"}],"name":"isCompoundingStream","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"}],"name":"deltaOf","outputs":[{"internalType":"uint256","name":"delta","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"takeEarnings","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"stopTime","type":"uint256"}],"name":"createStream","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cTokenManager","outputs":[{"internalType":"contract ICTokenManager","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"fee","outputs":[{"internalType":"uint256","name":"mantissa","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"cTokenManagerAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"streamId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"exchangeRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"senderSharePercentage","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"recipientSharePercentage","type":"uint256"}],"name":"CreateCompoundingStream","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"streamId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"senderInterest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"recipientInterest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sablierInterest","type":"uint256"}],"name":"PayInterest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TakeEarnings","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"UpdateFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"PauserAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"PauserRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"streamId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"deposit","type":"uint256"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stopTime","type":"uint256"}],"name":"CreateStream","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"streamId","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawFromStream","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"streamId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"senderBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"recipientBalance","type":"uint256"}],"name":"CancelStream","type":"event"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162004d7a38038062004d7a833981810160405260208110156200003757600080fd5b50516001600160a01b0381166200009a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018062004d50602a913960400191505060405180910390fd5b620000b033620000f160201b620043e11760201c565b620000c6336200020e60201b6200239f1760201c565b60ce80546001600160a01b0319166001600160a01b0392909216919091179055600160d155620004ff565b600054610100900460ff1680620001165750620001166001600160e01b03620002fb16565b8062000125575060005460ff16155b6200017c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e81526020018062004d22602e913960400191505060405180910390fd5b600054610100900460ff16158015620001a8576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a380156200020a576000805461ff00191690555b5050565b600054610100900460ff1680620002335750620002336001600160e01b03620002fb16565b8062000242575060005460ff16155b62000299576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e81526020018062004d22602e913960400191505060405180910390fd5b600054610100900460ff16158015620002c5576000805460ff1961ff0019909116610100171660011790555b620002db826200030160201b62003faf1760201c565b6099805460ff1916905580156200020a576000805461ff00191690555050565b303b1590565b600054610100900460ff1680620003265750620003266001600160e01b03620002fb16565b8062000335575060005460ff16155b6200038c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e81526020018062004d22602e913960400191505060405180910390fd5b600054610100900460ff16158015620003b8576000805460ff1961ff0019909116610100171660011790555b620003cc826001600160e01b03620003fb16565b620003e557620003e5826001600160e01b036200041e16565b80156200020a576000805461ff00191690555050565b6000620004188260666200047060201b62002b711790919060201c565b92915050565b62000439816066620004a660201b620041011790919060201c565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b60006001600160a01b0382166200048657600080fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b6001600160a01b038116620004ba57600080fd5b620004cf82826001600160e01b036200047016565b15620004da57600080fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b614813806200050f6000396000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c8063894e9a0d116100de578063a82ccd4d11610097578063cc1b4bf611610071578063cc1b4bf614610518578063d2cba55c14610558578063ddca3f4314610560578063f2fde38b146105685761018e565b8063a82ccd4d146104a9578063c1eb9ee0146104c6578063c4d66de8146104f25761018e565b8063894e9a0d146103925780638c9a3252146104025780638da5cb5b146104435780638f32d59b146104675780639012c4a81461046f578063a734d51b1461048c5761018e565b80635c975abb1161014b5780638129fc1c116101255780638129fc1c146103105780638195aeaa1461031857806382dc1ec4146103645780638456cb591461038a5761018e565b80635c975abb146102c85780636db9241b146102d05780637a9b2c6c146102ed5761018e565b8063131b9c04146101935780631e99d569146101cb5780632b8a119d146101d35780633656eec2146102585780633f4ba83a1461028457806346fbf68e1461028e575b600080fd5b6101b9600480360360208110156101a957600080fd5b50356001600160a01b031661058e565b60408051918252519081900360200190f35b6101b961066e565b6101f0600480360360208110156101e957600080fd5b5035610674565b604080516001600160a01b039c8d1681529a8c1660208c01528a810199909952969099166060890152608088019490945260a087019290925260c086015260e08501526101008401526101208301939093526101408201929092529051908190036101600190f35b6101b96004803603604081101561026e57600080fd5b50803590602001356001600160a01b03166108a1565b61028c610b7e565b005b6102b4600480360360208110156102a457600080fd5b50356001600160a01b0316610c67565b604080519115158252519081900360200190f35b6102b4610c80565b6102b4600480360360208110156102e657600080fd5b5035610c89565b6102b46004803603604081101561030357600080fd5b5080359060200135610dbc565b61028c611063565b6101b9600480360360e081101561032e57600080fd5b506001600160a01b0381358116916020810135916040820135169060608101359060808101359060a08101359060c0013561110a565b61028c6004803603602081101561037a57600080fd5b50356001600160a01b03166114ec565b61028c61153b565b6103af600480360360208110156103a857600080fd5b5035611602565b604080516001600160a01b03998a168152978916602089015287810196909652939096166060860152608085019190915260a084015260c083019390935260e08201929092529051908190036101000190f35b6104256004803603604081101561041857600080fd5b50803590602001356116ce565b60408051938452602084019290925282820152519081900360600190f35b61044b611e1d565b604080516001600160a01b039092168252519081900360200190f35b6102b4611e2c565b61028c6004803603602081101561048557600080fd5b5035611e52565b6102b4600480360360208110156104a257600080fd5b5035611f4e565b6101b9600480360360208110156104bf57600080fd5b5035611f66565b61028c600480360360408110156104dc57600080fd5b506001600160a01b038135169060200135612098565b61028c6004803603602081101561050857600080fd5b50356001600160a01b031661239f565b6101b9600480360360a081101561052e57600080fd5b506001600160a01b0381358116916020810135916040820135169060608101359060800135612455565b61044b612ad9565b6101b9612ae8565b61028c6004803603602081101561057e57600080fd5b50356001600160a01b0316612aee565b60ce5460408051632f52e59560e01b81526001600160a01b03848116600483015291516000939290921691632f52e59591602480820192602092909190829003018186803b1580156105df57600080fd5b505afa1580156105f3573d6000803e3d6000fd5b505050506040513d602081101561060957600080fd5b5051610652576040805162461bcd60e51b81526020600482015260136024820152723a37b5b2b71034b9903737ba1031aa37b5b2b760691b604482015290519081900360640190fd5b506001600160a01b0316600090815260cf602052604090205490565b60d15481565b60008060008060008060008060008060008b60d2600082815260200190815260200160002060070160149054906101000a900460ff166106e9576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b60008d815260cd60205260409020600301548d9060ff1661073b5760405162461bcd60e51b81526004018080602001828103825260218152602001806144d36021913960400191505060405180910390fd5b60d260008f815260200190815260200160002060060160009054906101000a90046001600160a01b03169c5060d260008f815260200190815260200160002060050160009054906101000a90046001600160a01b03169b5060d260008f8152602001908152602001600020600001549a5060d260008f815260200190815260200160002060070160009054906101000a90046001600160a01b0316995060d260008f815260200190815260200160002060030154985060d260008f815260200190815260200160002060040154975060d260008f815260200190815260200160002060020154965060d260008f815260200190815260200160002060010154955060cd60008f815260200190815260200160002060000160000154945060cd60008f815260200190815260200160002060010160000154935060cd60008f8152602001908152602001600020600201600001549250505091939597999b90929496989a50565b600082815260d260205260408120600701548390600160a01b900460ff166108fe576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b6109066141fd565b50600084815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff16151561010082015261099c614266565b60006109a787611f66565b90506109b7818460200151612b08565b60208401819052838260038111156109cb57fe5b60038111156109d657fe5b90525060009050825160038111156109ea57fe5b14610a265760405162461bcd60e51b81526004018080602001828103825260238152602001806147856023913960400191505060405180910390fd5b604083015183511115610acb57610a4583600001518460400151612b4a565b6040840181905283826003811115610a5957fe5b6003811115610a6457fe5b9052506000905082516003811115610a7857fe5b14610a7f57fe5b610a9182602001518360400151612b4a565b6020840181905283826003811115610aa557fe5b6003811115610ab057fe5b9052506000905082516003811115610ac457fe5b14610acb57fe5b8260a001516001600160a01b0316866001600160a01b03161415610af75750602001519250610b779050565b8260c001516001600160a01b0316866001600160a01b03161415610b6f57610b2783604001518360200151612b4a565b6060840181905283826003811115610b3b57fe5b6003811115610b4657fe5b9052506000905082516003811115610b5a57fe5b14610b6157fe5b50606001519250610b779050565b600094505050505b5092915050565b610b8e610b89612b6d565b610c67565b610bc95760405162461bcd60e51b81526004018080602001828103825260308152602001806145176030913960400191505060405180910390fd5b60995460ff16610c17576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6099805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610c4a612b6d565b604080516001600160a01b039092168252519081900360200190a1565b6000610c7a60668363ffffffff612b7116565b92915050565b60995460ff1690565b609a805460010190819055600082815260d260205260408120600701549091908390600160a01b900460ff16610cf4576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b600084815260d2602052604090206006015484906001600160a01b0316331480610d375750600081815260d260205260409020600501546001600160a01b031633145b610d725760405162461bcd60e51b81526004018080602001828103825260378152602001806147a86037913960400191505060405180910390fd5b600085815260cd602052604090206003015460ff16610d9957610d9485612ba6565b610da2565b610da285612ef4565b600193505050609a548114610db657600080fd5b50919050565b60995460009060ff1615610e0a576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b609a805460010190819055600084815260d260205260409020600701548490600160a01b900460ff16610e72576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b600085815260d2602052604090206006015485906001600160a01b0316331480610eb55750600081815260d260205260409020600501546001600160a01b031633145b610ef05760405162461bcd60e51b81526004018080602001828103825260378152602001806147a86037913960400191505060405180910390fd5b60008511610f36576040805162461bcd60e51b815260206004820152600e60248201526d616d6f756e74206973207a65726f60901b604482015290519081900360640190fd5b610f3e6141fd565b50600086815260d26020908152604080832081516101208101835281548152600182015493810193909352600281015491830191909152600381015460608301526004810154608083015260058101546001600160a01b0390811660a084018190526006830154821660c085015260079092015490811660e0840152600160a01b900460ff161515610100830152909190610fda9089906108a1565b90508681101561101b5760405162461bcd60e51b815260040180806020018281038252602481526020018061458e6024913960400191505060405180910390fd5b600088815260cd602052604090206003015460ff166110435761103e8888613504565b61104d565b61104d8888613797565b6001955050505050609a548114610b7757600080fd5b600054610100900460ff168061107c575061107c613d7e565b8061108a575060005460ff16155b6110c55760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff161580156110f0576000805460ff1961ff0019909116610100171660011790555b6001609a558015611107576000805461ff00191690555b50565b60995460009060ff1615611158576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b60ce5460408051632f52e59560e01b81526001600160a01b03898116600483015291519190921691632f52e595916024808301926020929190829003018186803b1580156111a557600080fd5b505afa1580156111b9573d6000803e3d6000fd5b505050506040513d60208110156111cf57600080fd5b505161121e576040805162461bcd60e51b815260206004820152601960248201527818d51bdad95b881a5cc81b9bdd081dda1a5d195b1a5cdd1959603a1b604482015290519081900360640190fd5b61122661428f565b6112308484613d84565b602083018190528282600381111561124457fe5b600381111561124f57fe5b905250600090508151600381111561126357fe5b146112b5576040805162461bcd60e51b815260206004820152601b60248201527f73686172652073756d2063616c63756c6174696f6e206572726f720000000000604482015290519081900360640190fd5b806020015160641461130e576040805162461bcd60e51b815260206004820152601b60248201527f73686172657320646f206e6f742073756d20757020746f203130300000000000604482015290519081900360640190fd5b600061131d8a8a8a8a8a612455565b905061133085662386f26fc10000612b08565b606084018190528382600381111561134457fe5b600381111561134f57fe5b905250600090508251600381111561136357fe5b1461136a57fe5b61137b84662386f26fc10000612b08565b608084018190528382600381111561138f57fe5b600381111561139a57fe5b90525060009050825160038111156113ae57fe5b146113b557fe5b6000886001600160a01b031663bd6d894d6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156113f257600080fd5b505af1158015611406573d6000803e3d6000fd5b505050506040513d602081101561141c57600080fd5b50516040805160a08101825260808082018481528252825160208082018552606089810151835281850192835285518083018752938a01518452848601938452600181860181815260008b815260cd8552889020965151875593515190860155925151600285015590516003909301805460ff19169315159390931790925582518481529182018a9052818301899052915192935084927fa9bbfc8562a8e1e6b889a428f128c90ed60c6204c37e4fb4354a202b4db59204929181900390910190a2509998505050505050505050565b6114f7610b89612b6d565b6115325760405162461bcd60e51b81526004018080602001828103825260308152602001806145176030913960400191505060405180910390fd5b61110781613daa565b611546610b89612b6d565b6115815760405162461bcd60e51b81526004018080602001828103825260308152602001806145176030913960400191505060405180910390fd5b60995460ff16156115cc576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6099805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610c4a612b6d565b6000806000806000806000808860d2600082815260200190815260200160002060070160149054906101000a900460ff16611672576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b5050506000968752505060d26020525050604090922060068101546005820154825460078401546003850154600486015460028701546001909701546001600160a01b039687169a958716995093975091909416949092909190565b600082815260d26020526040812060070154819081908590600160a01b900460ff1661172f576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b600086815260cd602052604090206003015460ff166117575760009350839250829150611e15565b61175f6141fd565b50600086815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff1615156101008201526117f56142bf565b50600087815260cd6020908152604091829020825160a08101845281546080820190815281528351808401855260018301548152818401528351928301845260028201548352928301919091526003015460ff16151560608201526118586142f9565b611860614382565b60405180602001604052808560e001516001600160a01b031663bd6d894d6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156118aa57600080fd5b505af11580156118be573d6000803e3d6000fd5b505050506040513d60208110156118d457600080fd5b505190528351518151919250106118f9575060009650869550859450611e1592505050565b611907818460000151613df2565b602084018190528382600381111561191b57fe5b600381111561192657fe5b905250600090508251600381111561193a57fe5b1461194157fe5b61194f82602001518a613e2c565b604084018190528382600381111561196357fe5b600381111561196e57fe5b905250600090508251600381111561198257fe5b146119d4576040805162461bcd60e51b815260206004820152601a60248201527f696e7465726573742063616c63756c6174696f6e206572726f72000000000000604482015290519081900360640190fd5b60d054670de0b6b3a76400001415611a86576119f4826040015182613e94565b610120840181905283826003811115611a0957fe5b6003811115611a1457fe5b9052506000905082516003811115611a2857fe5b14611a645760405162461bcd60e51b81526004018080602001828103825260218152602001806147646021913960400191505060405180910390fd5b600080611a75846101200151613eb7565b91995097509550611e159350505050565b60d054611aad57604080516020810182526000815260c08401528201516060830152611b85565b60408083015181516020810190925260d0548252611aca91613ec6565b60c0840181905283826003811115611ade57fe5b6003811115611ae957fe5b9052506000905082516003811115611afd57fe5b14611b395760405162461bcd60e51b81526004018080602001828103825260228152602001806146196022913960400191505060405180910390fd5b611b4b82604001518360c00151613df2565b6060840181905283826003811115611b5f57fe5b6003811115611b6a57fe5b9052506000905082516003811115611b7e57fe5b14611b8557fe5b611b9782606001518460200151613ec6565b6080840181905283826003811115611bab57fe5b6003811115611bb657fe5b9052506000905082516003811115611bca57fe5b14611c065760405162461bcd60e51b81526004018080602001828103825260218152602001806145d76021913960400191505060405180910390fd5b611c1882606001518360800151613df2565b60a0840181905283826003811115611c2c57fe5b6003811115611c3757fe5b9052506000905082516003811115611c4b57fe5b14611c5257fe5b611c60826080015182613e94565b60e0840181905283826003811115611c7457fe5b6003811115611c7f57fe5b9052506000905082516003811115611c9357fe5b14611ce5576040805162461bcd60e51b815260206004820181905260248201527f73656e64657220696e74657265737420636f6e76657273696f6e206572726f72604482015290519081900360640190fd5b611cf38260a0015182613e94565b610100840181905283826003811115611d0857fe5b6003811115611d1357fe5b9052506000905082516003811115611d2757fe5b14611d635760405162461bcd60e51b815260040180806020018281038252602381526020018061468d6023913960400191505060405180910390fd5b611d718260c0015182613e94565b610120840181905283826003811115611d8657fe5b6003811115611d9157fe5b9052506000905082516003811115611da557fe5b14611de15760405162461bcd60e51b81526004018080602001828103825260218152602001806147646021913960400191505060405180910390fd5b611dee8260e00151613eb7565b611dfc836101000151613eb7565b611e0a846101200151613eb7565b975097509750505050505b509250925092565b6033546001600160a01b031690565b6033546000906001600160a01b0316611e43612b6d565b6001600160a01b031614905090565b611e5a611e2c565b611e6357600080fd5b6064811115611eb9576040805162461bcd60e51b815260206004820152601f60248201527f6665652070657263656e7461676520686967686572207468616e203130302500604482015290519081900360640190fd5b611ec1614395565b611ed282662386f26fc10000612b08565b6020830181905282826003811115611ee657fe5b6003811115611ef157fe5b9052506000905081516003811115611f0557fe5b14611f0c57fe5b60408051602080820183528301519081905260d0555182907f38e229a7f3f9c329892d08eb37c4e91ccac6d12c798d394990ca4f56028ec26690600090a25050565b600090815260cd602052604090206003015460ff1690565b600081815260d260205260408120600701548290600160a01b900460ff16611fc3576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b611fcb6141fd565b50600083815260d26020908152604091829020825161012081018452815481526001820154928101929092526002810154928201929092526003820154606082018190526004830154608083015260058301546001600160a01b0390811660a08401526006840154811660c084015260079093015492831660e0830152600160a01b90920460ff16151561010082015290421161206c576000925050610db6565b8060800151421015612085576060015142039150610db6565b6060810151608090910151039392505050565b6120a0611e2c565b6120a957600080fd5b609a80546001019081905560ce5460408051632f52e59560e01b81526001600160a01b03868116600483015291519190921691632f52e595916024808301926020929190829003018186803b15801561210157600080fd5b505afa158015612115573d6000803e3d6000fd5b505050506040513d602081101561212b57600080fd5b505161217a576040805162461bcd60e51b815260206004820152601960248201527818d51bdad95b881a5cc81b9bdd081dda1a5d195b1a5cdd1959603a1b604482015290519081900360640190fd5b600082116121c0576040805162461bcd60e51b815260206004820152600e60248201526d616d6f756e74206973207a65726f60901b604482015290519081900360640190fd5b6001600160a01b038316600090815260cf60205260409020548211156122175760405162461bcd60e51b815260040180806020018281038252602481526020018061458e6024913960400191505060405180910390fd5b61221f6143ac565b6001600160a01b038416600090815260cf60205260409020546122429084612b4a565b6001600160a01b038616600090815260cf602052604090208190558282600381111561226a57fe5b600381111561227557fe5b905250600090508151600381111561228957fe5b1461229057fe5b60405183906001600160a01b038616907f13e8af02ad3e36f8d82fc8b86dcd67b7ed11f718f0e52fb245d2038eb71856ba90600090a36040805163a9059cbb60e01b81523360048201526024810185905290516001600160a01b0386169163a9059cbb9160448083019260209291908290030181600087803b15801561231557600080fd5b505af1158015612329573d6000803e3d6000fd5b505050506040513d602081101561233f57600080fd5b505161238b576040805162461bcd60e51b8152602060048201526016602482015275746f6b656e207472616e73666572206661696c75726560501b604482015290519081900360640190fd5b50609a54811461239a57600080fd5b505050565b600054610100900460ff16806123b857506123b8613d7e565b806123c6575060005460ff16155b6124015760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff1615801561242c576000805460ff1961ff0019909116610100171660011790555b61243582613faf565b6099805460ff191690558015612451576000805461ff00191690555b5050565b60995460009060ff16156124a3576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b0386166124fe576040805162461bcd60e51b815260206004820152601a60248201527f73747265616d20746f20746865207a65726f2061646472657373000000000000604482015290519081900360640190fd5b6001600160a01b03861630141561255c576040805162461bcd60e51b815260206004820152601d60248201527f73747265616d20746f2074686520636f6e747261637420697473656c66000000604482015290519081900360640190fd5b6001600160a01b0386163314156125b1576040805162461bcd60e51b815260206004820152601460248201527339ba3932b0b6903a37903a34329031b0b63632b960611b604482015290519081900360640190fd5b600085116125f8576040805162461bcd60e51b815260206004820152600f60248201526e6465706f736974206973207a65726f60881b604482015290519081900360640190fd5b428310156126375760405162461bcd60e51b81526004018080602001828103825260218152602001806145f86021913960400191505060405180910390fd5b82821161268b576040805162461bcd60e51b815260206004820152601f60248201527f73746f702074696d65206265666f7265207468652073746172742074696d6500604482015290519081900360640190fd5b6126936143bf565b61269d8385612b4a565b60208301819052828260038111156126b157fe5b60038111156126bc57fe5b90525060009050815160038111156126d057fe5b146126d757fe5b8060200151861015612730576040805162461bcd60e51b815260206004820152601f60248201527f6465706f73697420736d616c6c6572207468616e2074696d652064656c746100604482015290519081900360640190fd5b8060200151868161273d57fe5b061561277a5760405162461bcd60e51b815260040180806020018281038252602281526020018061463b6022913960400191505060405180910390fd5b612788868260200151614067565b604083018190528282600381111561279c57fe5b60038111156127a757fe5b90525060009050815160038111156127bb57fe5b146127c257fe5b600060d154905060405180610120016040528088815260200183604001518152602001888152602001868152602001858152602001896001600160a01b03168152602001336001600160a01b03168152602001876001600160a01b031681526020016001151581525060d26000838152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c08201518160060160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060e08201518160070160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160070160146101000a81548160ff02191690831515021790555090505061292860d1546001613d84565b60d18190558382600381111561293a57fe5b600381111561294557fe5b905250600090508251600381111561295957fe5b146129ab576040805162461bcd60e51b815260206004820181905260248201527f6e6578742073747265616d2069642063616c63756c6174696f6e206572726f72604482015290519081900360640190fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038816916323b872dd9160648083019260209291908290030181600087803b158015612a0057600080fd5b505af1158015612a14573d6000803e3d6000fd5b505050506040513d6020811015612a2a57600080fd5b5051612a76576040805162461bcd60e51b8152602060048201526016602482015275746f6b656e207472616e73666572206661696c75726560501b604482015290519081900360640190fd5b604080518881526001600160a01b038881166020830152818301889052606082018790529151918a1691339184917f7b01d409597969366dc268d7f957a990d1ca3d3449baf8fb45db67351aecfe789181900360800190a4979650505050505050565b60ce546001600160a01b031681565b60d05481565b612af6611e2c565b612aff57600080fd5b61110781614092565b60008083612b1b57506000905080612b43565b83830283858281612b2857fe5b0414612b3c57506002915060009050612b43565b6000925090505b9250929050565b600080838311612b61575060009050818303612b43565b50600390506000612b43565b3390565b60006001600160a01b038216612b8657600080fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b612bae6141fd565b50600081815260d26020908152604080832081516101208101835281548152600182015493810193909352600281015491830191909152600381015460608301526004810154608083015260058101546001600160a01b0390811660a08401526006820154811660c0840181905260079092015490811660e0840152600160a01b900460ff161515610100830152909190612c4a9084906108a1565b90506000612c5c848460a001516108a1565b600085815260d26020526040812081815560018101829055600281018290556003810182905560048101919091556005810180546001600160a01b0319908116909155600682018054909116905560070180546001600160a81b031916905560e08401519091508115612daa57806001600160a01b031663a9059cbb8560a00151846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612d2d57600080fd5b505af1158015612d41573d6000803e3d6000fd5b505050506040513d6020811015612d5757600080fd5b5051612daa576040805162461bcd60e51b815260206004820181905260248201527f726563697069656e7420746f6b656e207472616e73666572206661696c757265604482015290519081900360640190fd5b8215612e9157806001600160a01b031663a9059cbb8560c00151856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612e1457600080fd5b505af1158015612e28573d6000803e3d6000fd5b505050506040513d6020811015612e3e57600080fd5b5051612e91576040805162461bcd60e51b815260206004820152601d60248201527f73656e64657220746f6b656e207472616e73666572206661696c757265000000604482015290519081900360640190fd5b8360a001516001600160a01b03168460c001516001600160a01b0316867fca3e6079b726e7728802a0537949e2d1c7762304fa641fb06eb56daf2ba8c6b98686604051808381526020018281526020019250505060405180910390a45050505050565b612efc6141fd565b50600081815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff161515610100820152612f92614266565b6000612fa2848460c001516108a1565b90506000612fb4858560a001516108a1565b90506000806000612fc588856116ce565b925092509250612fd58584613d84565b6020880181905287826003811115612fe957fe5b6003811115612ff457fe5b905250600090508651600381111561300857fe5b146130445760405162461bcd60e51b81526004018080602001828103825260248152602001806147406024913960400191505060405180910390fd5b61304e8484612b4a565b604088018190528782600381111561306257fe5b600381111561306d57fe5b905250600090508651600381111561308157fe5b146130bd5760405162461bcd60e51b815260040180806020018281038252603b8152602001806146b0603b913960400191505060405180910390fd5b6130cb866040015182612b4a565b60608801819052878260038111156130df57fe5b60038111156130ea57fe5b90525060009050865160038111156130fe57fe5b1461313a5760405162461bcd60e51b81526004018080602001828103825260278152602001806146eb6027913960400191505060405180910390fd5b60e08701516001600160a01b0316600090815260cf60205260409020546131619082613d84565b60e08901516001600160a01b0316600090815260cf602052604090208190558782600381111561318d57fe5b600381111561319857fe5b90525060009050865160038111156131ac57fe5b146131e85760405162461bcd60e51b81526004018080602001828103825260238152602001806144f46023913960400191505060405180910390fd5b600088815260d260209081526040808320838155600180820185905560028083018690556003808401879055600484018790556005840180546001600160a01b03199081169091556006850180549091169055600790930180546001600160a81b031916905560cd855292852085815590810185905591820193909355909101805460ff1916905560e0880151908701511561336357806001600160a01b031663a9059cbb8960c0015189602001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156132e657600080fd5b505af11580156132fa573d6000803e3d6000fd5b505050506040513d602081101561331057600080fd5b5051613363576040805162461bcd60e51b815260206004820152601d60248201527f73656e64657220746f6b656e207472616e73666572206661696c757265000000604482015290519081900360640190fd5b60608701511561345257806001600160a01b031663a9059cbb8960a0015189606001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156133d557600080fd5b505af11580156133e9573d6000803e3d6000fd5b505050506040513d60208110156133ff57600080fd5b5051613452576040805162461bcd60e51b815260206004820181905260248201527f726563697069656e7420746f6b656e207472616e73666572206661696c757265604482015290519081900360640190fd5b8760a001516001600160a01b03168860c001516001600160a01b03168a7fca3e6079b726e7728802a0537949e2d1c7762304fa641fb06eb56daf2ba8c6b98a602001518b60600151604051808381526020018281526020019250505060405180910390a4604080518581526020810185905280820184905290518a917f5a8a03e48302e0bd2e011a3a2b54d1f849c55497f462f404bf52dce4290456b5919081900360600190a2505050505050505050565b61350c6141fd565b50600082815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff1615156101008201526135a26143ac565b6135b0826040015184612b4a565b600086815260d260205260409020600201819055828260038111156135d157fe5b60038111156135dc57fe5b90525060009050815160038111156135f057fe5b146135f757fe5b600084815260d2602052604090206002015461366d57600084815260d26020526040812081815560018101829055600281018290556003810182905560048101919091556005810180546001600160a01b0319908116909155600682018054909116905560070180546001600160a81b03191690555b8160e001516001600160a01b031663a9059cbb8360a00151856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156136d557600080fd5b505af11580156136e9573d6000803e3d6000fd5b505050506040513d60208110156136ff57600080fd5b505161374b576040805162461bcd60e51b8152602060048201526016602482015275746f6b656e207472616e73666572206661696c75726560501b604482015290519081900360640190fd5b8160a001516001600160a01b0316847f36c3ab437e6a424ed25dc4bfdeb62706aa06558660fab2dab229d2555adaf89c856040518082815260200191505060405180910390a350505050565b61379f6141fd565b50600082815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff1615156101008201526138356143bf565b600080600061384487876116ce565b9250925092506138548684612b4a565b602086018190528582600381111561386857fe5b600381111561387357fe5b905250600090508451600381111561388757fe5b146138c35760405162461bcd60e51b815260040180806020018281038252603081526020018061465d6030913960400191505060405180910390fd5b6138d1846020015182612b4a565b60408601819052858260038111156138e557fe5b60038111156138f057fe5b905250600090508451600381111561390457fe5b146139405760405162461bcd60e51b81526004018080602001828103825260278152602001806145476027913960400191505060405180910390fd5b61394e856040015187612b4a565b600089815260d2602052604090206002018190558582600381111561396f57fe5b600381111561397a57fe5b905250600090508451600381111561398e57fe5b146139ca5760405162461bcd60e51b81526004018080602001828103825260258152602001806145b26025913960400191505060405180910390fd5b600087815260d26020526040902060020154613a6857600087815260d260209081526040808320838155600180820185905560028083018690556003808401879055600484018790556005840180546001600160a01b03199081169091556006850180549091169055600790930180546001600160a81b031916905560cd9094529184208481559182018490559181019290925501805460ff191690555b60e08501516001600160a01b0316600090815260cf6020526040902054613a8f9082613d84565b60e08701516001600160a01b0316600090815260cf6020526040902081905585826003811115613abb57fe5b6003811115613ac657fe5b9052506000905084516003811115613ada57fe5b14613b165760405162461bcd60e51b81526004018080602001828103825260238152602001806144f46023913960400191505060405180910390fd5b60e08501518315613c0257806001600160a01b031663a9059cbb8760c00151866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015613b8557600080fd5b505af1158015613b99573d6000803e3d6000fd5b505050506040513d6020811015613baf57600080fd5b5051613c02576040805162461bcd60e51b815260206004820152601d60248201527f73656e64657220746f6b656e207472616e73666572206661696c757265000000604482015290519081900360640190fd5b806001600160a01b031663a9059cbb8760a0015187604001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015613c6a57600080fd5b505af1158015613c7e573d6000803e3d6000fd5b505050506040513d6020811015613c9457600080fd5b5051613ce7576040805162461bcd60e51b815260206004820181905260248201527f726563697069656e7420746f6b656e207472616e73666572206661696c757265604482015290519081900360640190fd5b8560a001516001600160a01b0316887f36c3ab437e6a424ed25dc4bfdeb62706aa06558660fab2dab229d2555adaf89c87604001516040518082815260200191505060405180910390a36040805185815260208101859052808201849052905189917f5a8a03e48302e0bd2e011a3a2b54d1f849c55497f462f404bf52dce4290456b5919081900360600190a25050505050505050565b303b1590565b600080838301848110613d9c57600092509050612b43565b506002915060009050612b43565b613dbb60668263ffffffff61410116565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6000613dfc614382565b600080613e1186600001518660000151612b4a565b60408051602081019091529081529097909650945050505050565b6000613e36614382565b600080613e47866000015186612b08565b90925090506000826003811115613e5a57fe5b14613e7957506040805160208101909152600081529092509050612b43565b60408051602081019091529081526000969095509350505050565b6000613e9e614382565b83518351613eac919061414d565b915091509250929050565b51670de0b6b3a7640000900490565b6000613ed0614382565b600080613ee586600001518660000151612b08565b90925090506000826003811115613ef857fe5b14613f1757506040805160208101909152600081529092509050612b43565b600080613f2c6706f05b59d3b2000084613d84565b90925090506000826003811115613f3f57fe5b14613f6157506040805160208101909152600081529094509250612b43915050565b600080613f7683670de0b6b3a7640000614067565b90925090506000826003811115613f8957fe5b14613f9057fe5b604080516020810190915290815260009a909950975050505050505050565b600054610100900460ff1680613fc85750613fc8613d7e565b80613fd6575060005460ff16155b6140115760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff1615801561403c576000805460ff1961ff0019909116610100171660011790555b61404582610c67565b6140525761405282613daa565b8015612451576000805461ff00191690555050565b6000808261407b5750600190506000612b43565b600083858161408657fe5b04915091509250929050565b6001600160a01b0381166140a557600080fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03811661411457600080fd5b61411e8282612b71565b1561412857600080fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6000614157614382565b60008061416c86670de0b6b3a7640000612b08565b9092509050600082600381111561417f57fe5b1461419e57506040805160208101909152600081529092509050612b43565b6000806141ab8388614067565b909250905060008260038111156141be57fe5b146141e057506040805160208101909152600081529094509250612b43915050565b604080516020810190915290815260009890975095505050505050565b604051806101200160405280600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000151581525090565b604080516080810190915280600081526020016000815260200160008152602001600081525090565b6040805160a081019091528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806142d2614382565b81526020016142df614382565b81526020016142ec614382565b8152600060209091015290565b6040805161014081019091528060008152602001614315614382565b8152602001614322614382565b815260200161432f614382565b815260200161433c614382565b8152602001614349614382565b8152602001614356614382565b8152602001614363614382565b8152602001614370614382565b815260200161437d614382565b905290565b6040518060200160405280600081525090565b604080518082019091526000808252602082015290565b604080516020810190915280600061437d565b6040805160608101909152806000815260200160008152602001600081525090565b600054610100900460ff16806143fa57506143fa613d7e565b80614408575060005460ff16155b6144435760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff1615801561446e576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015612451576000805461ff0019169055505056fe636f6d706f756e64696e672073747265616d20646f6573206e6f742065786973746561726e696e6773206164646974696f6e2063616c63756c6174696f6e206572726f72506175736572526f6c653a2063616c6c657220646f6573206e6f742068617665207468652050617573657220726f6c656e6574207769746864726177616c20616d6f756e742063616c63756c6174696f6e206572726f7273747265616d20646f6573206e6f742065786973740000000000000000000000616d6f756e7420657863656564732074686520617661696c61626c652062616c616e636562616c616e6365207375627472616374696f6e2063616c63756c6174696f6e206572726f7273656e64657220696e7465726573742063616c63756c6174696f6e206572726f7273746172742074696d65206265666f726520626c6f636b2e74696d657374616d707361626c69657220696e7465726573742063616c63756c6174696f6e206572726f726465706f736974206e6f74206d756c7469706c65206f662074696d652064656c7461616d6f756e7420776974686f75742073656e64657220696e7465726573742063616c63756c6174696f6e206572726f72726563697069656e7420696e74657265737420636f6e76657273696f6e206572726f72726563697069656e742062616c616e636520776974686f75742073656e64657220696e7465726573742063616c63756c6174696f6e206572726f726e657420726563697069656e742062616c616e63652063616c63756c6174696f6e206572726f72436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65646e65742073656e6465722062616c616e63652063616c63756c6174696f6e206572726f727361626c69657220696e74657265737420636f6e76657273696f6e206572726f72726563697069656e742062616c616e63652063616c63756c6174696f6e206572726f7263616c6c6572206973206e6f74207468652073656e646572206f722074686520726563697069656e74206f66207468652073747265616da265627a7a72315820d5ad0c39f51a54f8b3b77f6b8f02e3d034b5fabbacccfa1751ca957d1cd14a2d64736f6c634300050b0032436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a656463546f6b656e4d616e6167657220636f6e747261637420697320746865207a65726f2061646472657373000000000000000000000000342a6596f50b4db7c3246c0f4efb1f06843d7405Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061018e5760003560e01c8063894e9a0d116100de578063a82ccd4d11610097578063cc1b4bf611610071578063cc1b4bf614610518578063d2cba55c14610558578063ddca3f4314610560578063f2fde38b146105685761018e565b8063a82ccd4d146104a9578063c1eb9ee0146104c6578063c4d66de8146104f25761018e565b8063894e9a0d146103925780638c9a3252146104025780638da5cb5b146104435780638f32d59b146104675780639012c4a81461046f578063a734d51b1461048c5761018e565b80635c975abb1161014b5780638129fc1c116101255780638129fc1c146103105780638195aeaa1461031857806382dc1ec4146103645780638456cb591461038a5761018e565b80635c975abb146102c85780636db9241b146102d05780637a9b2c6c146102ed5761018e565b8063131b9c04146101935780631e99d569146101cb5780632b8a119d146101d35780633656eec2146102585780633f4ba83a1461028457806346fbf68e1461028e575b600080fd5b6101b9600480360360208110156101a957600080fd5b50356001600160a01b031661058e565b60408051918252519081900360200190f35b6101b961066e565b6101f0600480360360208110156101e957600080fd5b5035610674565b604080516001600160a01b039c8d1681529a8c1660208c01528a810199909952969099166060890152608088019490945260a087019290925260c086015260e08501526101008401526101208301939093526101408201929092529051908190036101600190f35b6101b96004803603604081101561026e57600080fd5b50803590602001356001600160a01b03166108a1565b61028c610b7e565b005b6102b4600480360360208110156102a457600080fd5b50356001600160a01b0316610c67565b604080519115158252519081900360200190f35b6102b4610c80565b6102b4600480360360208110156102e657600080fd5b5035610c89565b6102b46004803603604081101561030357600080fd5b5080359060200135610dbc565b61028c611063565b6101b9600480360360e081101561032e57600080fd5b506001600160a01b0381358116916020810135916040820135169060608101359060808101359060a08101359060c0013561110a565b61028c6004803603602081101561037a57600080fd5b50356001600160a01b03166114ec565b61028c61153b565b6103af600480360360208110156103a857600080fd5b5035611602565b604080516001600160a01b03998a168152978916602089015287810196909652939096166060860152608085019190915260a084015260c083019390935260e08201929092529051908190036101000190f35b6104256004803603604081101561041857600080fd5b50803590602001356116ce565b60408051938452602084019290925282820152519081900360600190f35b61044b611e1d565b604080516001600160a01b039092168252519081900360200190f35b6102b4611e2c565b61028c6004803603602081101561048557600080fd5b5035611e52565b6102b4600480360360208110156104a257600080fd5b5035611f4e565b6101b9600480360360208110156104bf57600080fd5b5035611f66565b61028c600480360360408110156104dc57600080fd5b506001600160a01b038135169060200135612098565b61028c6004803603602081101561050857600080fd5b50356001600160a01b031661239f565b6101b9600480360360a081101561052e57600080fd5b506001600160a01b0381358116916020810135916040820135169060608101359060800135612455565b61044b612ad9565b6101b9612ae8565b61028c6004803603602081101561057e57600080fd5b50356001600160a01b0316612aee565b60ce5460408051632f52e59560e01b81526001600160a01b03848116600483015291516000939290921691632f52e59591602480820192602092909190829003018186803b1580156105df57600080fd5b505afa1580156105f3573d6000803e3d6000fd5b505050506040513d602081101561060957600080fd5b5051610652576040805162461bcd60e51b81526020600482015260136024820152723a37b5b2b71034b9903737ba1031aa37b5b2b760691b604482015290519081900360640190fd5b506001600160a01b0316600090815260cf602052604090205490565b60d15481565b60008060008060008060008060008060008b60d2600082815260200190815260200160002060070160149054906101000a900460ff166106e9576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b60008d815260cd60205260409020600301548d9060ff1661073b5760405162461bcd60e51b81526004018080602001828103825260218152602001806144d36021913960400191505060405180910390fd5b60d260008f815260200190815260200160002060060160009054906101000a90046001600160a01b03169c5060d260008f815260200190815260200160002060050160009054906101000a90046001600160a01b03169b5060d260008f8152602001908152602001600020600001549a5060d260008f815260200190815260200160002060070160009054906101000a90046001600160a01b0316995060d260008f815260200190815260200160002060030154985060d260008f815260200190815260200160002060040154975060d260008f815260200190815260200160002060020154965060d260008f815260200190815260200160002060010154955060cd60008f815260200190815260200160002060000160000154945060cd60008f815260200190815260200160002060010160000154935060cd60008f8152602001908152602001600020600201600001549250505091939597999b90929496989a50565b600082815260d260205260408120600701548390600160a01b900460ff166108fe576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b6109066141fd565b50600084815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff16151561010082015261099c614266565b60006109a787611f66565b90506109b7818460200151612b08565b60208401819052838260038111156109cb57fe5b60038111156109d657fe5b90525060009050825160038111156109ea57fe5b14610a265760405162461bcd60e51b81526004018080602001828103825260238152602001806147856023913960400191505060405180910390fd5b604083015183511115610acb57610a4583600001518460400151612b4a565b6040840181905283826003811115610a5957fe5b6003811115610a6457fe5b9052506000905082516003811115610a7857fe5b14610a7f57fe5b610a9182602001518360400151612b4a565b6020840181905283826003811115610aa557fe5b6003811115610ab057fe5b9052506000905082516003811115610ac457fe5b14610acb57fe5b8260a001516001600160a01b0316866001600160a01b03161415610af75750602001519250610b779050565b8260c001516001600160a01b0316866001600160a01b03161415610b6f57610b2783604001518360200151612b4a565b6060840181905283826003811115610b3b57fe5b6003811115610b4657fe5b9052506000905082516003811115610b5a57fe5b14610b6157fe5b50606001519250610b779050565b600094505050505b5092915050565b610b8e610b89612b6d565b610c67565b610bc95760405162461bcd60e51b81526004018080602001828103825260308152602001806145176030913960400191505060405180910390fd5b60995460ff16610c17576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6099805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610c4a612b6d565b604080516001600160a01b039092168252519081900360200190a1565b6000610c7a60668363ffffffff612b7116565b92915050565b60995460ff1690565b609a805460010190819055600082815260d260205260408120600701549091908390600160a01b900460ff16610cf4576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b600084815260d2602052604090206006015484906001600160a01b0316331480610d375750600081815260d260205260409020600501546001600160a01b031633145b610d725760405162461bcd60e51b81526004018080602001828103825260378152602001806147a86037913960400191505060405180910390fd5b600085815260cd602052604090206003015460ff16610d9957610d9485612ba6565b610da2565b610da285612ef4565b600193505050609a548114610db657600080fd5b50919050565b60995460009060ff1615610e0a576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b609a805460010190819055600084815260d260205260409020600701548490600160a01b900460ff16610e72576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b600085815260d2602052604090206006015485906001600160a01b0316331480610eb55750600081815260d260205260409020600501546001600160a01b031633145b610ef05760405162461bcd60e51b81526004018080602001828103825260378152602001806147a86037913960400191505060405180910390fd5b60008511610f36576040805162461bcd60e51b815260206004820152600e60248201526d616d6f756e74206973207a65726f60901b604482015290519081900360640190fd5b610f3e6141fd565b50600086815260d26020908152604080832081516101208101835281548152600182015493810193909352600281015491830191909152600381015460608301526004810154608083015260058101546001600160a01b0390811660a084018190526006830154821660c085015260079092015490811660e0840152600160a01b900460ff161515610100830152909190610fda9089906108a1565b90508681101561101b5760405162461bcd60e51b815260040180806020018281038252602481526020018061458e6024913960400191505060405180910390fd5b600088815260cd602052604090206003015460ff166110435761103e8888613504565b61104d565b61104d8888613797565b6001955050505050609a548114610b7757600080fd5b600054610100900460ff168061107c575061107c613d7e565b8061108a575060005460ff16155b6110c55760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff161580156110f0576000805460ff1961ff0019909116610100171660011790555b6001609a558015611107576000805461ff00191690555b50565b60995460009060ff1615611158576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b60ce5460408051632f52e59560e01b81526001600160a01b03898116600483015291519190921691632f52e595916024808301926020929190829003018186803b1580156111a557600080fd5b505afa1580156111b9573d6000803e3d6000fd5b505050506040513d60208110156111cf57600080fd5b505161121e576040805162461bcd60e51b815260206004820152601960248201527818d51bdad95b881a5cc81b9bdd081dda1a5d195b1a5cdd1959603a1b604482015290519081900360640190fd5b61122661428f565b6112308484613d84565b602083018190528282600381111561124457fe5b600381111561124f57fe5b905250600090508151600381111561126357fe5b146112b5576040805162461bcd60e51b815260206004820152601b60248201527f73686172652073756d2063616c63756c6174696f6e206572726f720000000000604482015290519081900360640190fd5b806020015160641461130e576040805162461bcd60e51b815260206004820152601b60248201527f73686172657320646f206e6f742073756d20757020746f203130300000000000604482015290519081900360640190fd5b600061131d8a8a8a8a8a612455565b905061133085662386f26fc10000612b08565b606084018190528382600381111561134457fe5b600381111561134f57fe5b905250600090508251600381111561136357fe5b1461136a57fe5b61137b84662386f26fc10000612b08565b608084018190528382600381111561138f57fe5b600381111561139a57fe5b90525060009050825160038111156113ae57fe5b146113b557fe5b6000886001600160a01b031663bd6d894d6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156113f257600080fd5b505af1158015611406573d6000803e3d6000fd5b505050506040513d602081101561141c57600080fd5b50516040805160a08101825260808082018481528252825160208082018552606089810151835281850192835285518083018752938a01518452848601938452600181860181815260008b815260cd8552889020965151875593515190860155925151600285015590516003909301805460ff19169315159390931790925582518481529182018a9052818301899052915192935084927fa9bbfc8562a8e1e6b889a428f128c90ed60c6204c37e4fb4354a202b4db59204929181900390910190a2509998505050505050505050565b6114f7610b89612b6d565b6115325760405162461bcd60e51b81526004018080602001828103825260308152602001806145176030913960400191505060405180910390fd5b61110781613daa565b611546610b89612b6d565b6115815760405162461bcd60e51b81526004018080602001828103825260308152602001806145176030913960400191505060405180910390fd5b60995460ff16156115cc576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6099805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610c4a612b6d565b6000806000806000806000808860d2600082815260200190815260200160002060070160149054906101000a900460ff16611672576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b5050506000968752505060d26020525050604090922060068101546005820154825460078401546003850154600486015460028701546001909701546001600160a01b039687169a958716995093975091909416949092909190565b600082815260d26020526040812060070154819081908590600160a01b900460ff1661172f576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b600086815260cd602052604090206003015460ff166117575760009350839250829150611e15565b61175f6141fd565b50600086815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff1615156101008201526117f56142bf565b50600087815260cd6020908152604091829020825160a08101845281546080820190815281528351808401855260018301548152818401528351928301845260028201548352928301919091526003015460ff16151560608201526118586142f9565b611860614382565b60405180602001604052808560e001516001600160a01b031663bd6d894d6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156118aa57600080fd5b505af11580156118be573d6000803e3d6000fd5b505050506040513d60208110156118d457600080fd5b505190528351518151919250106118f9575060009650869550859450611e1592505050565b611907818460000151613df2565b602084018190528382600381111561191b57fe5b600381111561192657fe5b905250600090508251600381111561193a57fe5b1461194157fe5b61194f82602001518a613e2c565b604084018190528382600381111561196357fe5b600381111561196e57fe5b905250600090508251600381111561198257fe5b146119d4576040805162461bcd60e51b815260206004820152601a60248201527f696e7465726573742063616c63756c6174696f6e206572726f72000000000000604482015290519081900360640190fd5b60d054670de0b6b3a76400001415611a86576119f4826040015182613e94565b610120840181905283826003811115611a0957fe5b6003811115611a1457fe5b9052506000905082516003811115611a2857fe5b14611a645760405162461bcd60e51b81526004018080602001828103825260218152602001806147646021913960400191505060405180910390fd5b600080611a75846101200151613eb7565b91995097509550611e159350505050565b60d054611aad57604080516020810182526000815260c08401528201516060830152611b85565b60408083015181516020810190925260d0548252611aca91613ec6565b60c0840181905283826003811115611ade57fe5b6003811115611ae957fe5b9052506000905082516003811115611afd57fe5b14611b395760405162461bcd60e51b81526004018080602001828103825260228152602001806146196022913960400191505060405180910390fd5b611b4b82604001518360c00151613df2565b6060840181905283826003811115611b5f57fe5b6003811115611b6a57fe5b9052506000905082516003811115611b7e57fe5b14611b8557fe5b611b9782606001518460200151613ec6565b6080840181905283826003811115611bab57fe5b6003811115611bb657fe5b9052506000905082516003811115611bca57fe5b14611c065760405162461bcd60e51b81526004018080602001828103825260218152602001806145d76021913960400191505060405180910390fd5b611c1882606001518360800151613df2565b60a0840181905283826003811115611c2c57fe5b6003811115611c3757fe5b9052506000905082516003811115611c4b57fe5b14611c5257fe5b611c60826080015182613e94565b60e0840181905283826003811115611c7457fe5b6003811115611c7f57fe5b9052506000905082516003811115611c9357fe5b14611ce5576040805162461bcd60e51b815260206004820181905260248201527f73656e64657220696e74657265737420636f6e76657273696f6e206572726f72604482015290519081900360640190fd5b611cf38260a0015182613e94565b610100840181905283826003811115611d0857fe5b6003811115611d1357fe5b9052506000905082516003811115611d2757fe5b14611d635760405162461bcd60e51b815260040180806020018281038252602381526020018061468d6023913960400191505060405180910390fd5b611d718260c0015182613e94565b610120840181905283826003811115611d8657fe5b6003811115611d9157fe5b9052506000905082516003811115611da557fe5b14611de15760405162461bcd60e51b81526004018080602001828103825260218152602001806147646021913960400191505060405180910390fd5b611dee8260e00151613eb7565b611dfc836101000151613eb7565b611e0a846101200151613eb7565b975097509750505050505b509250925092565b6033546001600160a01b031690565b6033546000906001600160a01b0316611e43612b6d565b6001600160a01b031614905090565b611e5a611e2c565b611e6357600080fd5b6064811115611eb9576040805162461bcd60e51b815260206004820152601f60248201527f6665652070657263656e7461676520686967686572207468616e203130302500604482015290519081900360640190fd5b611ec1614395565b611ed282662386f26fc10000612b08565b6020830181905282826003811115611ee657fe5b6003811115611ef157fe5b9052506000905081516003811115611f0557fe5b14611f0c57fe5b60408051602080820183528301519081905260d0555182907f38e229a7f3f9c329892d08eb37c4e91ccac6d12c798d394990ca4f56028ec26690600090a25050565b600090815260cd602052604090206003015460ff1690565b600081815260d260205260408120600701548290600160a01b900460ff16611fc3576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b611fcb6141fd565b50600083815260d26020908152604091829020825161012081018452815481526001820154928101929092526002810154928201929092526003820154606082018190526004830154608083015260058301546001600160a01b0390811660a08401526006840154811660c084015260079093015492831660e0830152600160a01b90920460ff16151561010082015290421161206c576000925050610db6565b8060800151421015612085576060015142039150610db6565b6060810151608090910151039392505050565b6120a0611e2c565b6120a957600080fd5b609a80546001019081905560ce5460408051632f52e59560e01b81526001600160a01b03868116600483015291519190921691632f52e595916024808301926020929190829003018186803b15801561210157600080fd5b505afa158015612115573d6000803e3d6000fd5b505050506040513d602081101561212b57600080fd5b505161217a576040805162461bcd60e51b815260206004820152601960248201527818d51bdad95b881a5cc81b9bdd081dda1a5d195b1a5cdd1959603a1b604482015290519081900360640190fd5b600082116121c0576040805162461bcd60e51b815260206004820152600e60248201526d616d6f756e74206973207a65726f60901b604482015290519081900360640190fd5b6001600160a01b038316600090815260cf60205260409020548211156122175760405162461bcd60e51b815260040180806020018281038252602481526020018061458e6024913960400191505060405180910390fd5b61221f6143ac565b6001600160a01b038416600090815260cf60205260409020546122429084612b4a565b6001600160a01b038616600090815260cf602052604090208190558282600381111561226a57fe5b600381111561227557fe5b905250600090508151600381111561228957fe5b1461229057fe5b60405183906001600160a01b038616907f13e8af02ad3e36f8d82fc8b86dcd67b7ed11f718f0e52fb245d2038eb71856ba90600090a36040805163a9059cbb60e01b81523360048201526024810185905290516001600160a01b0386169163a9059cbb9160448083019260209291908290030181600087803b15801561231557600080fd5b505af1158015612329573d6000803e3d6000fd5b505050506040513d602081101561233f57600080fd5b505161238b576040805162461bcd60e51b8152602060048201526016602482015275746f6b656e207472616e73666572206661696c75726560501b604482015290519081900360640190fd5b50609a54811461239a57600080fd5b505050565b600054610100900460ff16806123b857506123b8613d7e565b806123c6575060005460ff16155b6124015760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff1615801561242c576000805460ff1961ff0019909116610100171660011790555b61243582613faf565b6099805460ff191690558015612451576000805461ff00191690555b5050565b60995460009060ff16156124a3576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b0386166124fe576040805162461bcd60e51b815260206004820152601a60248201527f73747265616d20746f20746865207a65726f2061646472657373000000000000604482015290519081900360640190fd5b6001600160a01b03861630141561255c576040805162461bcd60e51b815260206004820152601d60248201527f73747265616d20746f2074686520636f6e747261637420697473656c66000000604482015290519081900360640190fd5b6001600160a01b0386163314156125b1576040805162461bcd60e51b815260206004820152601460248201527339ba3932b0b6903a37903a34329031b0b63632b960611b604482015290519081900360640190fd5b600085116125f8576040805162461bcd60e51b815260206004820152600f60248201526e6465706f736974206973207a65726f60881b604482015290519081900360640190fd5b428310156126375760405162461bcd60e51b81526004018080602001828103825260218152602001806145f86021913960400191505060405180910390fd5b82821161268b576040805162461bcd60e51b815260206004820152601f60248201527f73746f702074696d65206265666f7265207468652073746172742074696d6500604482015290519081900360640190fd5b6126936143bf565b61269d8385612b4a565b60208301819052828260038111156126b157fe5b60038111156126bc57fe5b90525060009050815160038111156126d057fe5b146126d757fe5b8060200151861015612730576040805162461bcd60e51b815260206004820152601f60248201527f6465706f73697420736d616c6c6572207468616e2074696d652064656c746100604482015290519081900360640190fd5b8060200151868161273d57fe5b061561277a5760405162461bcd60e51b815260040180806020018281038252602281526020018061463b6022913960400191505060405180910390fd5b612788868260200151614067565b604083018190528282600381111561279c57fe5b60038111156127a757fe5b90525060009050815160038111156127bb57fe5b146127c257fe5b600060d154905060405180610120016040528088815260200183604001518152602001888152602001868152602001858152602001896001600160a01b03168152602001336001600160a01b03168152602001876001600160a01b031681526020016001151581525060d26000838152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c08201518160060160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060e08201518160070160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160070160146101000a81548160ff02191690831515021790555090505061292860d1546001613d84565b60d18190558382600381111561293a57fe5b600381111561294557fe5b905250600090508251600381111561295957fe5b146129ab576040805162461bcd60e51b815260206004820181905260248201527f6e6578742073747265616d2069642063616c63756c6174696f6e206572726f72604482015290519081900360640190fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038816916323b872dd9160648083019260209291908290030181600087803b158015612a0057600080fd5b505af1158015612a14573d6000803e3d6000fd5b505050506040513d6020811015612a2a57600080fd5b5051612a76576040805162461bcd60e51b8152602060048201526016602482015275746f6b656e207472616e73666572206661696c75726560501b604482015290519081900360640190fd5b604080518881526001600160a01b038881166020830152818301889052606082018790529151918a1691339184917f7b01d409597969366dc268d7f957a990d1ca3d3449baf8fb45db67351aecfe789181900360800190a4979650505050505050565b60ce546001600160a01b031681565b60d05481565b612af6611e2c565b612aff57600080fd5b61110781614092565b60008083612b1b57506000905080612b43565b83830283858281612b2857fe5b0414612b3c57506002915060009050612b43565b6000925090505b9250929050565b600080838311612b61575060009050818303612b43565b50600390506000612b43565b3390565b60006001600160a01b038216612b8657600080fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b612bae6141fd565b50600081815260d26020908152604080832081516101208101835281548152600182015493810193909352600281015491830191909152600381015460608301526004810154608083015260058101546001600160a01b0390811660a08401526006820154811660c0840181905260079092015490811660e0840152600160a01b900460ff161515610100830152909190612c4a9084906108a1565b90506000612c5c848460a001516108a1565b600085815260d26020526040812081815560018101829055600281018290556003810182905560048101919091556005810180546001600160a01b0319908116909155600682018054909116905560070180546001600160a81b031916905560e08401519091508115612daa57806001600160a01b031663a9059cbb8560a00151846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612d2d57600080fd5b505af1158015612d41573d6000803e3d6000fd5b505050506040513d6020811015612d5757600080fd5b5051612daa576040805162461bcd60e51b815260206004820181905260248201527f726563697069656e7420746f6b656e207472616e73666572206661696c757265604482015290519081900360640190fd5b8215612e9157806001600160a01b031663a9059cbb8560c00151856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612e1457600080fd5b505af1158015612e28573d6000803e3d6000fd5b505050506040513d6020811015612e3e57600080fd5b5051612e91576040805162461bcd60e51b815260206004820152601d60248201527f73656e64657220746f6b656e207472616e73666572206661696c757265000000604482015290519081900360640190fd5b8360a001516001600160a01b03168460c001516001600160a01b0316867fca3e6079b726e7728802a0537949e2d1c7762304fa641fb06eb56daf2ba8c6b98686604051808381526020018281526020019250505060405180910390a45050505050565b612efc6141fd565b50600081815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff161515610100820152612f92614266565b6000612fa2848460c001516108a1565b90506000612fb4858560a001516108a1565b90506000806000612fc588856116ce565b925092509250612fd58584613d84565b6020880181905287826003811115612fe957fe5b6003811115612ff457fe5b905250600090508651600381111561300857fe5b146130445760405162461bcd60e51b81526004018080602001828103825260248152602001806147406024913960400191505060405180910390fd5b61304e8484612b4a565b604088018190528782600381111561306257fe5b600381111561306d57fe5b905250600090508651600381111561308157fe5b146130bd5760405162461bcd60e51b815260040180806020018281038252603b8152602001806146b0603b913960400191505060405180910390fd5b6130cb866040015182612b4a565b60608801819052878260038111156130df57fe5b60038111156130ea57fe5b90525060009050865160038111156130fe57fe5b1461313a5760405162461bcd60e51b81526004018080602001828103825260278152602001806146eb6027913960400191505060405180910390fd5b60e08701516001600160a01b0316600090815260cf60205260409020546131619082613d84565b60e08901516001600160a01b0316600090815260cf602052604090208190558782600381111561318d57fe5b600381111561319857fe5b90525060009050865160038111156131ac57fe5b146131e85760405162461bcd60e51b81526004018080602001828103825260238152602001806144f46023913960400191505060405180910390fd5b600088815260d260209081526040808320838155600180820185905560028083018690556003808401879055600484018790556005840180546001600160a01b03199081169091556006850180549091169055600790930180546001600160a81b031916905560cd855292852085815590810185905591820193909355909101805460ff1916905560e0880151908701511561336357806001600160a01b031663a9059cbb8960c0015189602001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156132e657600080fd5b505af11580156132fa573d6000803e3d6000fd5b505050506040513d602081101561331057600080fd5b5051613363576040805162461bcd60e51b815260206004820152601d60248201527f73656e64657220746f6b656e207472616e73666572206661696c757265000000604482015290519081900360640190fd5b60608701511561345257806001600160a01b031663a9059cbb8960a0015189606001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156133d557600080fd5b505af11580156133e9573d6000803e3d6000fd5b505050506040513d60208110156133ff57600080fd5b5051613452576040805162461bcd60e51b815260206004820181905260248201527f726563697069656e7420746f6b656e207472616e73666572206661696c757265604482015290519081900360640190fd5b8760a001516001600160a01b03168860c001516001600160a01b03168a7fca3e6079b726e7728802a0537949e2d1c7762304fa641fb06eb56daf2ba8c6b98a602001518b60600151604051808381526020018281526020019250505060405180910390a4604080518581526020810185905280820184905290518a917f5a8a03e48302e0bd2e011a3a2b54d1f849c55497f462f404bf52dce4290456b5919081900360600190a2505050505050505050565b61350c6141fd565b50600082815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff1615156101008201526135a26143ac565b6135b0826040015184612b4a565b600086815260d260205260409020600201819055828260038111156135d157fe5b60038111156135dc57fe5b90525060009050815160038111156135f057fe5b146135f757fe5b600084815260d2602052604090206002015461366d57600084815260d26020526040812081815560018101829055600281018290556003810182905560048101919091556005810180546001600160a01b0319908116909155600682018054909116905560070180546001600160a81b03191690555b8160e001516001600160a01b031663a9059cbb8360a00151856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156136d557600080fd5b505af11580156136e9573d6000803e3d6000fd5b505050506040513d60208110156136ff57600080fd5b505161374b576040805162461bcd60e51b8152602060048201526016602482015275746f6b656e207472616e73666572206661696c75726560501b604482015290519081900360640190fd5b8160a001516001600160a01b0316847f36c3ab437e6a424ed25dc4bfdeb62706aa06558660fab2dab229d2555adaf89c856040518082815260200191505060405180910390a350505050565b61379f6141fd565b50600082815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff1615156101008201526138356143bf565b600080600061384487876116ce565b9250925092506138548684612b4a565b602086018190528582600381111561386857fe5b600381111561387357fe5b905250600090508451600381111561388757fe5b146138c35760405162461bcd60e51b815260040180806020018281038252603081526020018061465d6030913960400191505060405180910390fd5b6138d1846020015182612b4a565b60408601819052858260038111156138e557fe5b60038111156138f057fe5b905250600090508451600381111561390457fe5b146139405760405162461bcd60e51b81526004018080602001828103825260278152602001806145476027913960400191505060405180910390fd5b61394e856040015187612b4a565b600089815260d2602052604090206002018190558582600381111561396f57fe5b600381111561397a57fe5b905250600090508451600381111561398e57fe5b146139ca5760405162461bcd60e51b81526004018080602001828103825260258152602001806145b26025913960400191505060405180910390fd5b600087815260d26020526040902060020154613a6857600087815260d260209081526040808320838155600180820185905560028083018690556003808401879055600484018790556005840180546001600160a01b03199081169091556006850180549091169055600790930180546001600160a81b031916905560cd9094529184208481559182018490559181019290925501805460ff191690555b60e08501516001600160a01b0316600090815260cf6020526040902054613a8f9082613d84565b60e08701516001600160a01b0316600090815260cf6020526040902081905585826003811115613abb57fe5b6003811115613ac657fe5b9052506000905084516003811115613ada57fe5b14613b165760405162461bcd60e51b81526004018080602001828103825260238152602001806144f46023913960400191505060405180910390fd5b60e08501518315613c0257806001600160a01b031663a9059cbb8760c00151866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015613b8557600080fd5b505af1158015613b99573d6000803e3d6000fd5b505050506040513d6020811015613baf57600080fd5b5051613c02576040805162461bcd60e51b815260206004820152601d60248201527f73656e64657220746f6b656e207472616e73666572206661696c757265000000604482015290519081900360640190fd5b806001600160a01b031663a9059cbb8760a0015187604001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015613c6a57600080fd5b505af1158015613c7e573d6000803e3d6000fd5b505050506040513d6020811015613c9457600080fd5b5051613ce7576040805162461bcd60e51b815260206004820181905260248201527f726563697069656e7420746f6b656e207472616e73666572206661696c757265604482015290519081900360640190fd5b8560a001516001600160a01b0316887f36c3ab437e6a424ed25dc4bfdeb62706aa06558660fab2dab229d2555adaf89c87604001516040518082815260200191505060405180910390a36040805185815260208101859052808201849052905189917f5a8a03e48302e0bd2e011a3a2b54d1f849c55497f462f404bf52dce4290456b5919081900360600190a25050505050505050565b303b1590565b600080838301848110613d9c57600092509050612b43565b506002915060009050612b43565b613dbb60668263ffffffff61410116565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6000613dfc614382565b600080613e1186600001518660000151612b4a565b60408051602081019091529081529097909650945050505050565b6000613e36614382565b600080613e47866000015186612b08565b90925090506000826003811115613e5a57fe5b14613e7957506040805160208101909152600081529092509050612b43565b60408051602081019091529081526000969095509350505050565b6000613e9e614382565b83518351613eac919061414d565b915091509250929050565b51670de0b6b3a7640000900490565b6000613ed0614382565b600080613ee586600001518660000151612b08565b90925090506000826003811115613ef857fe5b14613f1757506040805160208101909152600081529092509050612b43565b600080613f2c6706f05b59d3b2000084613d84565b90925090506000826003811115613f3f57fe5b14613f6157506040805160208101909152600081529094509250612b43915050565b600080613f7683670de0b6b3a7640000614067565b90925090506000826003811115613f8957fe5b14613f9057fe5b604080516020810190915290815260009a909950975050505050505050565b600054610100900460ff1680613fc85750613fc8613d7e565b80613fd6575060005460ff16155b6140115760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff1615801561403c576000805460ff1961ff0019909116610100171660011790555b61404582610c67565b6140525761405282613daa565b8015612451576000805461ff00191690555050565b6000808261407b5750600190506000612b43565b600083858161408657fe5b04915091509250929050565b6001600160a01b0381166140a557600080fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03811661411457600080fd5b61411e8282612b71565b1561412857600080fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6000614157614382565b60008061416c86670de0b6b3a7640000612b08565b9092509050600082600381111561417f57fe5b1461419e57506040805160208101909152600081529092509050612b43565b6000806141ab8388614067565b909250905060008260038111156141be57fe5b146141e057506040805160208101909152600081529094509250612b43915050565b604080516020810190915290815260009890975095505050505050565b604051806101200160405280600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000151581525090565b604080516080810190915280600081526020016000815260200160008152602001600081525090565b6040805160a081019091528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806142d2614382565b81526020016142df614382565b81526020016142ec614382565b8152600060209091015290565b6040805161014081019091528060008152602001614315614382565b8152602001614322614382565b815260200161432f614382565b815260200161433c614382565b8152602001614349614382565b8152602001614356614382565b8152602001614363614382565b8152602001614370614382565b815260200161437d614382565b905290565b6040518060200160405280600081525090565b604080518082019091526000808252602082015290565b604080516020810190915280600061437d565b6040805160608101909152806000815260200160008152602001600081525090565b600054610100900460ff16806143fa57506143fa613d7e565b80614408575060005460ff16155b6144435760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff1615801561446e576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015612451576000805461ff0019169055505056fe636f6d706f756e64696e672073747265616d20646f6573206e6f742065786973746561726e696e6773206164646974696f6e2063616c63756c6174696f6e206572726f72506175736572526f6c653a2063616c6c657220646f6573206e6f742068617665207468652050617573657220726f6c656e6574207769746864726177616c20616d6f756e742063616c63756c6174696f6e206572726f7273747265616d20646f6573206e6f742065786973740000000000000000000000616d6f756e7420657863656564732074686520617661696c61626c652062616c616e636562616c616e6365207375627472616374696f6e2063616c63756c6174696f6e206572726f7273656e64657220696e7465726573742063616c63756c6174696f6e206572726f7273746172742074696d65206265666f726520626c6f636b2e74696d657374616d707361626c69657220696e7465726573742063616c63756c6174696f6e206572726f726465706f736974206e6f74206d756c7469706c65206f662074696d652064656c7461616d6f756e7420776974686f75742073656e64657220696e7465726573742063616c63756c6174696f6e206572726f72726563697069656e7420696e74657265737420636f6e76657273696f6e206572726f72726563697069656e742062616c616e636520776974686f75742073656e64657220696e7465726573742063616c63756c6174696f6e206572726f726e657420726563697069656e742062616c616e63652063616c63756c6174696f6e206572726f72436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65646e65742073656e6465722062616c616e63652063616c63756c6174696f6e206572726f727361626c69657220696e74657265737420636f6e76657273696f6e206572726f72726563697069656e742062616c616e63652063616c63756c6174696f6e206572726f7263616c6c6572206973206e6f74207468652073656e646572206f722074686520726563697069656e74206f66207468652073747265616da265627a7a72315820d5ad0c39f51a54f8b3b77f6b8f02e3d034b5fabbacccfa1751ca957d1cd14a2d64736f6c634300050b0032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000342a6596f50b4db7c3246c0f4efb1f06843d7405
-----Decoded View---------------
Arg [0] : cTokenManagerAddress (address): 0x342A6596F50b4Db7c3246C0F4eFb1f06843d7405
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000342a6596f50b4db7c3246c0f4efb1f06843d7405Deployed Bytecode Sourcemap
28122:36493:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;28122:36493:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45476:202;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;45476:202:0;-1:-1:-1;;;;;45476:202:0;;:::i;:::-;;;;;;;;;;;;;;;;29189:27;;;:::i;38548:1286::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;38548:1286:0;;:::i;:::-;;;;-1:-1:-1;;;;;38548:1286:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36255:1624;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36255:1624:0;;;;;;-1:-1:-1;;;;;36255:1624:0;;:::i;24641:120::-;;;:::i;:::-;;21844:109;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21844:109:0;-1:-1:-1;;;;;21844:109:0;;:::i;:::-;;;;;;;;;;;;;;;;;;23848:78;;;:::i;54875:401::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54875:401:0;;:::i;53733:724::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;53733:724:0;;;;;;;:::i;3486:218::-;;;:::i;50839:2359::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;50839:2359:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;21961:92::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21961:92:0;-1:-1:-1;;;;;21961:92:0;;:::i;24428:118::-;;;:::i;34089:823::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;34089:823:0;;:::i;:::-;;;;-1:-1:-1;;;;;34089:823:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40719:4504;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;40719:4504:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;18614:79;;;:::i;:::-;;;;-1:-1:-1;;;;;18614:79:0;;;;;;;;;;;;;;18949:94;;;:::i;31910:696::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;31910:696:0;;:::i;38112:141::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;38112:141:0;;:::i;35349:362::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;35349:362:0;;:::i;32971:834::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;32971:834:0;;;;;;;;:::i;23604:144::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;23604:144:0;-1:-1:-1;;;;;23604:144:0;;:::i;47114:2386::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;47114:2386:0;;;;;;;;;;;;;;;;;;;;;;;;;:::i;28812:35::-;;;:::i;29104:14::-;;;:::i;19220:109::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;19220:109:0;-1:-1:-1;;;;;19220:109:0;;:::i;45476:202::-;45570:13;;:36;;;-1:-1:-1;;;45570:36:0;;-1:-1:-1;;;;;45570:36:0;;;;;;;;;45542:7;;45570:13;;;;;:22;;:36;;;;;;;;;;;;;;;:13;:36;;;5:2:-1;;;;30:1;27;20:12;5:2;45570:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;45570:36:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;45570:36:0;45562:68;;;;;-1:-1:-1;;;45562:68:0;;;;;;;;;;;;-1:-1:-1;;;45562:68:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;;45648:22:0;;;;;:8;:22;;;;;;;45476:202::o;29189:27::-;;;;:::o;38548:1286::-;38735:14;38764:17;38796:15;38826:20;38861:17;38893:16;38924:24;38963:21;38999:27;39041:29;39085:32;38650:8;30763:7;:17;30771:8;30763:17;;;;;;;;;;;:26;;;;;;;;;;;;30755:60;;;;;-1:-1:-1;;;30755:60:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30755:60:0;;;;;;;;;;;;;;;31007:32;;;;:22;:32;;;;;:41;;;38693:8;;31007:41;;30999:87;;;;-1:-1:-1;;;30999:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39154:7;:17;39162:8;39154:17;;;;;;;;;;;:24;;;;;;;;;;-1:-1:-1;;;;;39154:24:0;39145:33;;39201:7;:17;39209:8;39201:17;;;;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;;;;39201:27:0;39189:39;;39249:7;:17;39257:8;39249:17;;;;;;;;;;;:25;;;39239:35;;39300:7;:17;39308:8;39300:17;;;;;;;;;;;:30;;;;;;;;;;-1:-1:-1;;;;;39300:30:0;39285:45;;39353:7;:17;39361:8;39353:17;;;;;;;;;;;:27;;;39341:39;;39402:7;:17;39410:8;39402:17;;;;;;;;;;;:26;;;39391:37;;39458:7;:17;39466:8;39458:17;;;;;;;;;;;:34;;;39439:53;;39519:7;:17;39527:8;39519:17;;;;;;;;;;;:31;;;39503:47;;39583:22;:32;39606:8;39583:32;;;;;;;;;;;:52;;:61;;;39561:83;;39679:22;:32;39702:8;39679:32;;;;;;;;;;;:44;;:53;;;39655:77;;39770:22;:32;39793:8;39770:32;;;;;;;;;;;:47;;:56;;;39743:83;;30826:1;38548:1286;;;;;;;;;;;;;;:::o;36255:1624::-;36349:15;30763:17;;;:7;:17;;;;;:26;;;:17;;-1:-1:-1;;;30763:26:0;;;;30755:60;;;;;-1:-1:-1;;;30755:60:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30755:60:0;;;;;;;;;;;;;;;36377:26;;:::i;:::-;-1:-1:-1;36406:17:0;;;;:7;:17;;;;;;;;;36377:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;36377:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;36377:46:0;;;;;;;;;;;36434:30;;:::i;:::-;36477:13;36493:17;36501:8;36493:7;:17::i;:::-;36477:33;;36561:36;36569:5;36576:6;:20;;;36561:7;:36::i;:::-;36536:21;;;36521:76;;;36522:4;36521:76;;;;;;;;;;;;;;;;;;;-1:-1:-1;36632:18:0;;-1:-1:-1;36616:12:0;;:34;;;;;;;;;36608:82;;;;-1:-1:-1;;;36608:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36979:23;;;;36962:14;;:40;36958:478;;;37059:48;37067:6;:14;;;37083:6;:23;;;37059:7;:48::i;:::-;37034:21;;;37019:88;;;37020:4;37019:88;;;;;;;;;;;;;;;;;;;-1:-1:-1;37145:18:0;;-1:-1:-1;37129:12:0;;:34;;;;;;;;;37122:42;;;;37219:53;37227:4;:21;;;37250:4;:21;;;37219:7;:53::i;:::-;37194:21;;;37179:93;;;37180:4;37179:93;;;;;;;;;;;;;;;;;;;-1:-1:-1;37405:18:0;;-1:-1:-1;37389:12:0;;:34;;;;;;;;;37382:42;;;;37459:6;:16;;;-1:-1:-1;;;;;37452:23:0;:3;-1:-1:-1;;;;;37452:23:0;;37448:57;;;-1:-1:-1;37484:21:0;;;;-1:-1:-1;37477:28:0;;-1:-1:-1;37477:28:0;37448:57;37527:6;:13;;;-1:-1:-1;;;;;37520:20:0;:3;-1:-1:-1;;;;;37520:20:0;;37516:337;;;37594:55;37602:6;:23;;;37627:4;:21;;;37594:7;:55::i;:::-;37572:18;;;37557:92;;;37558:4;37557:92;;;;;;;;;;;;;;;;;;;-1:-1:-1;37782:18:0;;-1:-1:-1;37766:12:0;;:34;;;;;;;;;37759:42;;;;-1:-1:-1;37823:18:0;;;;-1:-1:-1;37816:25:0;;-1:-1:-1;37816:25:0;37516:337;37870:1;37863:8;;;;;30826:1;36255:1624;;;;;:::o;24641:120::-;21741:22;21750:12;:10;:12::i;:::-;21741:8;:22::i;:::-;21733:83;;;;-1:-1:-1;;;21733:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24284:7;;;;24276:40;;;;;-1:-1:-1;;;24276:40:0;;;;;;;;;;;;-1:-1:-1;;;24276:40:0;;;;;;;;;;;;;;;24700:7;:15;;-1:-1:-1;;24700:15:0;;;24731:22;24740:12;:10;:12::i;:::-;24731:22;;;-1:-1:-1;;;;;24731:22:0;;;;;;;;;;;;;;24641:120::o;21844:109::-;21900:4;21924:21;:8;21937:7;21924:21;:12;:21;:::i;:::-;21917:28;21844:109;-1:-1:-1;;21844:109:0:o;23848:78::-;23911:7;;;;23848:78;:::o;54875:401::-;4123:13;:18;;4140:1;4123:18;;;;;-1:-1:-1;30763:17:0;;;:7;:17;;;;;:26;;;-1:-1:-1;;4123:18:0;30763:17;;-1:-1:-1;;;30763:26:0;;;;30755:60;;;;;-1:-1:-1;;;30755:60:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30755:60:0;;;;;;;;;;;;;;;30442:17;;;;:7;:17;;;;;:24;;;:17;;-1:-1:-1;;;;;30442:24:0;30428:10;:38;;:83;;-1:-1:-1;30484:17:0;;;;:7;:17;;;;;:27;;;-1:-1:-1;;;;;30484:27:0;30470:10;:41;30428:83;30406:188;;;;-1:-1:-1;;;30406:188:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55073:32;;;;:22;:32;;;;;:41;;;;;55068:179;;55131:30;55152:8;55131:20;:30::i;:::-;55068:179;;;55194:41;55226:8;55194:31;:41::i;:::-;55264:4;55257:11;;30826:1;4199;4235:13;;4219:12;:29;4211:38;;;;;;54875:401;;;;:::o;53733:724::-;24085:7;;53949:4;;24085:7;;24084:8;24076:37;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;;;;4123:13;:18;;4140:1;4123:18;;;;;-1:-1:-1;30763:17:0;;;:7;:17;;;;;:26;;;:17;;-1:-1:-1;;;30763:26:0;;;;30755:60;;;;;-1:-1:-1;;;30755:60:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30755:60:0;;;;;;;;;;;;;;;30442:17;;;;:7;:17;;;;;:24;;;:17;;-1:-1:-1;;;;;30442:24:0;30428:10;:38;;:83;;-1:-1:-1;30484:17:0;;;;:7;:17;;;;;:27;;;-1:-1:-1;;;;;30484:27:0;30470:10;:41;30428:83;30406:188;;;;-1:-1:-1;;;30406:188:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53988:1;53979:6;:10;53971:37;;;;;-1:-1:-1;;;53971:37:0;;;;;;;;;;;;-1:-1:-1;;;53971:37:0;;;;;;;;;;;;;;;54019:26;;:::i;:::-;-1:-1:-1;54048:17:0;;;;:7;:17;;;;;;;;54019:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;54019:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;54019:46:0;;;;;;;;;;;;54048:17;54094:37;;54048:17;;54094:9;:37::i;:::-;54076:55;;54161:6;54150:7;:17;;54142:66;;;;-1:-1:-1;;;54142:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54226:32;;;;:22;:32;;;;;:41;;;;;54221:207;;54284:44;54311:8;54321:6;54284:26;:44::i;:::-;54221:207;;;54361:55;54399:8;54409:6;54361:37;:55::i;:::-;54445:4;54438:11;;;;30826:1;4199;4235:13;;4219:12;:29;4211:38;;;;;3486:218;1987:12;;;;;;;;:31;;;2003:15;:13;:15::i;:::-;1987:47;;;-1:-1:-1;2023:11:0;;;;2022:12;1987:47;1979:106;;;;-1:-1:-1;;;1979:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2094:19;2117:12;;;;;;2116:13;2136:83;;;;2165:12;:19;;-1:-1:-1;;;;2165:19:0;;;;;2193:18;2180:4;2193:18;;;2136:83;3695:1;3679:13;:17;2237:57;;;;2281:5;2266:20;;-1:-1:-1;;2266:20:0;;;2237:57;3486:218;:::o;50839:2359::-;24085:7;;51134;;24085;;24084:8;24076:37;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;;;;51162:13;;:36;;;-1:-1:-1;;;51162:36:0;;-1:-1:-1;;;;;51162:36:0;;;;;;;;;:13;;;;;:22;;:36;;;;;;;;;;;;;;:13;:36;;;5:2:-1;;;;30:1;27;20:12;5:2;51162:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51162:36:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51162:36:0;51154:74;;;;;-1:-1:-1;;;51154:74:0;;;;;;;;;;;;-1:-1:-1;;;51154:74:0;;;;;;;;;;;;;;;51239:44;;:::i;:::-;51391:56;51399:21;51422:24;51391:7;:56::i;:::-;51374:13;;;51359:88;;;51360:4;51359:88;;;;;;;;;;;;;;;;;;;-1:-1:-1;51482:18:0;;-1:-1:-1;51466:12:0;;:34;;;;;;;;;51458:74;;;;;-1:-1:-1;;;51458:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;51551:4;:13;;;51568:3;51551:20;51543:60;;;;;-1:-1:-1;;;51543:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;51616:16;51635:67;51648:9;51659:7;51668:12;51682:9;51693:8;51635:12;:67::i;:::-;51616:86;;51940:42;51948:21;28485:4;51940:7;:42::i;:::-;51912:24;;;51897:85;;;51898:4;51897:85;;;;;;;;;;;;;;;;;;;-1:-1:-1;52198:18:0;;-1:-1:-1;52182:12:0;;:34;;;;;;;;;52175:42;;;;52276:45;52284:24;28485:4;52276:7;:45::i;:::-;52245:27;;;52230:91;;;52231:4;52230:91;;;;;;;;;;;;;;;;;;;-1:-1:-1;52540:18:0;;-1:-1:-1;52524:12:0;;:34;;;;;;;;;52517:42;;;;52633:27;52671:12;-1:-1:-1;;;;;52663:41:0;;:43;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52663:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52663:43:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52663:43:0;52752:291;;;52816:38;;;;;52752:291;;;;52816:38;;;52752:291;;52988:43;;52663;52988;;;;;53004:24;;;;;52988:43;;52752:291;;;;;;52914:46;;;;;;;52930:27;;;;52914:46;;-1:-1:-1;;;52752:291:0;;;52879:4;52752:291;;;;;;-1:-1:-1;52717:32:0;;;:22;:32;;;;;:326;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;52717:326:0;;;;;;;;;;;53061:103;;;;;;;;;;;;;;;;;;;52663:43;;-1:-1:-1;52717:32:0;;53061:103;;;;;;;;;;;-1:-1:-1;53182:8:0;50839:2359;-1:-1:-1;;;;;;;;;50839:2359:0:o;21961:92::-;21741:22;21750:12;:10;:12::i;21741:22::-;21733:83;;;;-1:-1:-1;;;21733:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22026:19;22037:7;22026:10;:19::i;24428:118::-;21741:22;21750:12;:10;:12::i;21741:22::-;21733:83;;;;-1:-1:-1;;;21733:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24085:7;;;;24084:8;24076:37;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;;;;24488:7;:14;;-1:-1:-1;;24488:14:0;24498:4;24488:14;;;24518:20;24525:12;:10;:12::i;34089:823::-;34222:14;34251:17;34283:15;34313:20;34348:17;34380:16;34411:24;34450:21;34180:8;30763:7;:17;30771:8;30763:17;;;;;;;;;;;:26;;;;;;;;;;;;30755:60;;;;;-1:-1:-1;;;30755:60:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30755:60:0;;;;;;;;;;;;;;;-1:-1:-1;;;34508:17:0;;;;-1:-1:-1;;34508:7:0;:17;;-1:-1:-1;;34508:17:0;;;;:24;;;;34555:27;;;;34603:25;;34654:30;;;;34707:27;;;;34756:26;;;;34812:34;;;;34508:24;34873:31;;;;-1:-1:-1;;;;;34508:24:0;;;;34555:27;;;;-1:-1:-1;34603:25:0;;-1:-1:-1;34654:30:0;;;;;34756:26;;34812:34;;34873:31;34089:823::o;40719:4504::-;40839:22;30763:17;;;:7;:17;;;;;:26;;;40839:22;;;;30763:17;;-1:-1:-1;;;30763:26:0;;;;30755:60;;;;;-1:-1:-1;;;30755:60:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30755:60:0;;;;;;;;;;;;;;;40936:32;;;;:22;:32;;;;;:41;;;;;40931:91;;41002:1;;-1:-1:-1;41002:1:0;;-1:-1:-1;41002:1:0;;-1:-1:-1;40994:16:0;;40931:91;41032:26;;:::i;:::-;-1:-1:-1;41061:17:0;;;;:7;:17;;;;;;;;;41032:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41032:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;41032:46:0;;;;;;;;;;;41089:56;;:::i;:::-;-1:-1:-1;41148:32:0;;;;:22;:32;;;;;;;;;41089:91;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;41089:91:0;;;;;;;;;;;;;;;41191:31;;:::i;:::-;41424:30;;:::i;:::-;41457:69;;;;;;;;41481:6;:19;;;-1:-1:-1;;;;;41473:48:0;;:50;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41473:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;41473:50:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;41473:50:0;41457:69;;41573:41;;:50;41541:28;;41424:102;;-1:-1:-1;;41537:131:0;;-1:-1:-1;41648:1:0;;-1:-1:-1;41648:1:0;;-1:-1:-1;41648:1:0;;-1:-1:-1;41640:16:0;;-1:-1:-1;;;41640:16:0;41537:131;41719:70;41726:19;41747:21;:41;;;41719:6;:70::i;:::-;41693:22;;;41678:111;;;41679:4;41678:111;;;;;;;;;;;;;;;;;;;-1:-1:-1;41823:18:0;;-1:-1:-1;41807:12:0;;:34;;;;;;;;;41800:42;;;;41999:41;42009:4;:22;;;42033:6;41999:9;:41::i;:::-;41972:23;;;41957:83;;;41958:4;41957:83;;;;;;;;;;;;;;;;;;;-1:-1:-1;42075:18:0;;-1:-1:-1;42059:12:0;;:34;;;;;;;;;42051:73;;;;;-1:-1:-1;;;42051:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;42196:3;:12;28374:4;42196:30;42192:1266;;;42282:52;42289:4;:23;;;42314:19;42282:6;:52::i;:::-;42258:20;;;42243:91;;;42244:4;42243:91;;;;;;;;;;;;;;;;;;;-1:-1:-1;42373:18:0;;-1:-1:-1;42357:12:0;;:34;;;;;;;;;42349:80;;;;-1:-1:-1;;;42349:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42452:1;42455;42458:30;42467:4;:20;;;42458:8;:30::i;:::-;42444:45;;-1:-1:-1;42444:45:0;-1:-1:-1;42444:45:0;-1:-1:-1;42444:45:0;;-1:-1:-1;;;;42444:45:0;42192:1266;42511:3;:12;42507:951;;42578:20;;;;;;;;-1:-1:-1;42578:20:0;;42545:30;;;:53;42642:23;;;42613:26;;;:52;42507:951;;;42754:23;;;;;42747:36;;;;;;;;42779:3;42747:36;;;;;:6;:36::i;:::-;42713:30;;;42698:85;;;42699:4;42698:85;;;;;;;;;;;;;;;;;;;-1:-1:-1;42822:18:0;;-1:-1:-1;42806:12:0;;:34;;;;;;;;;42798:81;;;;-1:-1:-1;;;42798:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43030:112;43055:4;:23;;;43097:4;:30;;;43030:6;:112::i;:::-;43000:26;;;42985:157;;;42986:4;42985:157;;;;;;;;;;;;;;;;;;;-1:-1:-1;43427:18:0;;-1:-1:-1;43411:12:0;;:34;;;;;;;;;43404:42;;;;43579:106;43600:4;:26;;;43641:21;:33;;;43579:6;:106::i;:::-;43546:29;;;43531:154;;;43532:4;43531:154;;;;;;;;;;;;;;;;;;;-1:-1:-1;43720:18:0;;-1:-1:-1;43704:12:0;;:34;;;;;;;;;43696:80;;;;-1:-1:-1;;;43696:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43904:102;43925:4;:26;;;43966:4;:29;;;43904:6;:102::i;:::-;43868:32;;;43853:153;;;43854:4;43853:153;;;;;;;;;;;;;;;;;;;-1:-1:-1;44290:18:0;;-1:-1:-1;44274:12:0;;:34;;;;;;;;;44267:42;;;;44435:58;44442:4;:29;;;44473:19;44435:6;:58::i;:::-;44412:19;;;44397:96;;;44398:4;44397:96;;;;;;;;;;;;;;;;;;;-1:-1:-1;44528:18:0;;-1:-1:-1;44512:12:0;;:34;;;;;;;;;44504:79;;;;;-1:-1:-1;;;44504:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44637:61;44644:4;:32;;;44678:19;44637:6;:61::i;:::-;44611:22;;;44596:102;;;44597:4;44596:102;;;;;;;;;;;;;;;;;;;-1:-1:-1;44733:18:0;;-1:-1:-1;44717:12:0;;:34;;;;;;;;;44709:82;;;;-1:-1:-1;;;44709:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44843:59;44850:4;:30;;;44882:19;44843:6;:59::i;:::-;44819:20;;;44804:98;;;44805:4;44804:98;;;;;;;;;;;;;;;;;;;-1:-1:-1;44937:18:0;;-1:-1:-1;44921:12:0;;:34;;;;;;;;;44913:80;;;;-1:-1:-1;;;44913:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45119:29;45128:4;:19;;;45119:8;:29::i;:::-;45150:32;45159:4;:22;;;45150:8;:32::i;:::-;45184:30;45193:4;:20;;;45184:8;:30::i;:::-;45111:104;;;;;;;;;;30826:1;40719:4504;;;;;;:::o;18614:79::-;18679:6;;-1:-1:-1;;;;;18679:6:0;18614:79;:::o;18949:94::-;19029:6;;18989:4;;-1:-1:-1;;;;;19029:6:0;19013:12;:10;:12::i;:::-;-1:-1:-1;;;;;19013:22:0;;19006:29;;18949:94;:::o;31910:696::-;18826:9;:7;:9::i;:::-;18818:18;;;;;;32007:3;31990:13;:20;;31982:64;;;;;-1:-1:-1;;;31982:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;32057:30;;:::i;:::-;32243:34;32251:13;28485:4;32243:7;:34::i;:::-;32223:16;;;32208:69;;;32209:4;32208:69;;;;;;;;;;;;;;;;;;;-1:-1:-1;32485:18:0;;-1:-1:-1;32469:12:0;;:34;;;;;;;;;32462:42;;;;32523:35;;;;;;;;;32539:16;;;32523:35;;;;32517:3;:41;32574:24;32584:13;;32574:24;;-1:-1:-1;;32574:24:0;18847:1;31910:696;:::o;38112:141::-;38180:4;38204:32;;;:22;:32;;;;;:41;;;;;;38112:141::o;35349:362::-;35428:13;30763:17;;;:7;:17;;;;;:26;;;:17;;-1:-1:-1;;;30763:26:0;;;;30755:60;;;;;-1:-1:-1;;;30755:60:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30755:60:0;;;;;;;;;;;;;;;35454:26;;:::i;:::-;-1:-1:-1;35483:17:0;;;;:7;:17;;;;;;;;;35454:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;35454:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;35454:46:0;;;;;;;;;;;;35515:15;:35;35511:49;;35559:1;35552:8;;;;;35511:49;35593:6;:15;;;35575;:33;35571:80;;;35635:16;;;35617:15;:34;;-1:-1:-1;35610:41:0;;35571:80;35687:16;;;;35669:15;;;;;:34;;35349:362;-1:-1:-1;;;35349:362:0:o;32971:834::-;18826:9;:7;:9::i;:::-;18818:18;;;;;;4123:13;:18;;4140:1;4123:18;;;;;33082:13;;:36;;;-1:-1:-1;;;33082:36:0;;-1:-1:-1;;;;;33082:36:0;;;;;;;;;:13;;;;;:22;;:36;;;;;;;;;;;;;;:13;:36;;;5:2:-1;;;;30:1;27;20:12;5:2;33082:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33082:36:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33082:36:0;33074:74;;;;;-1:-1:-1;;;33074:74:0;;;;;;;;;;;;-1:-1:-1;;;33074:74:0;;;;;;;;;;;;;;;33176:1;33167:6;:10;33159:37;;;;;-1:-1:-1;;;33159:37:0;;;;;;;;;;;;-1:-1:-1;;;33159:37:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;33215:22:0;;;;;;:8;:22;;;;;;:32;-1:-1:-1;33215:32:0;33207:81;;;;-1:-1:-1;;;33207:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33301:33;;:::i;:::-;-1:-1:-1;;;;;33394:22:0;;;;;;:8;:22;;;;;;33386:39;;33418:6;33386:7;:39::i;:::-;-1:-1:-1;;;;;33360:22:0;;33346:12;33360:22;;;:8;:22;;;;;33345:80;;;33346:4;33345:80;;;;;;;;;;;;;;;;;;;-1:-1:-1;33631:18:0;;-1:-1:-1;33615:12:0;;:34;;;;;;;;;33608:42;;;;33668:34;;33695:6;;-1:-1:-1;;;;;33668:34:0;;;;;;;;33721:49;;;-1:-1:-1;;;33721:49:0;;33751:10;33721:49;;;;;;;;;;;;-1:-1:-1;;;;;33721:29:0;;;;;:49;;;;;;;;;;;;;;-1:-1:-1;33721:29:0;:49;;;5:2:-1;;;;30:1;27;20:12;5:2;33721:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33721:49:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33721:49:0;33713:84;;;;;-1:-1:-1;;;33713:84:0;;;;;;;;;;;;-1:-1:-1;;;33713:84:0;;;;;;;;;;;;;;;4199:1;4235:13;;4219:12;:29;4211:38;;;;;;18847:1;32971:834;;:::o;23604:144::-;1987:12;;;;;;;;:31;;;2003:15;:13;:15::i;:::-;1987:47;;;-1:-1:-1;2023:11:0;;;;2022:12;1987:47;1979:106;;;;-1:-1:-1;;;1979:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2094:19;2117:12;;;;;;2116:13;2136:83;;;;2165:12;:19;;-1:-1:-1;;;;2165:19:0;;;;;2193:18;2180:4;2193:18;;;2136:83;23670:44;23707:6;23670:36;:44::i;:::-;23725:7;:15;;-1:-1:-1;;23725:15:0;;;2237:57;;;;2281:5;2266:20;;-1:-1:-1;;2266:20:0;;;2237:57;23604:144;;:::o;47114:2386::-;24085:7;;47288;;24085;;24084:8;24076:37;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;47321:26:0;;47313:65;;;;;-1:-1:-1;;;47313:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47397:26:0;;47418:4;47397:26;;47389:68;;;;;-1:-1:-1;;;47389:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47476:23:0;;47489:10;47476:23;;47468:56;;;;;-1:-1:-1;;;47468:56:0;;;;;;;;;;;;-1:-1:-1;;;47468:56:0;;;;;;;;;;;;;;;47553:1;47543:7;:11;47535:39;;;;;-1:-1:-1;;;47535:39:0;;;;;;;;;;;;-1:-1:-1;;;47535:39:0;;;;;;;;;;;;;;;47606:15;47593:9;:28;;47585:74;;;;-1:-1:-1;;;47585:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47689:9;47678:8;:20;47670:64;;;;;-1:-1:-1;;;47670:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;47747:33;;:::i;:::-;47823:28;47831:8;47841:9;47823:7;:28::i;:::-;47806:13;;;47791:60;;;47792:4;47791:60;;;;;;;;;;;;;;;;;;;-1:-1:-1;48005:18:0;;-1:-1:-1;47989:12:0;;:34;;;;;;;;;47982:42;;;;48120:4;:13;;;48109:7;:24;;48101:68;;;;;-1:-1:-1;;;48101:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48261:4;:13;;;48251:7;:23;;;;;;:28;48243:75;;;;-1:-1:-1;;;48243:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48368:31;48376:7;48385:4;:13;;;48368:7;:31::i;:::-;48346:18;;;48331:68;;;48332:4;48331:68;;;;;;;;;;;;;;;;;;;-1:-1:-1;48537:18:0;;-1:-1:-1;48521:12:0;;:34;;;;;;;;;48514:42;;;;48620:16;48639:12;;48620:31;;48682:350;;;;;;;;48759:7;48682:350;;;;48825:4;:18;;;48682:350;;;;48728:7;48682:350;;;;48937:9;48682:350;;;;48971:8;48682:350;;;;48869:9;-1:-1:-1;;;;;48682:350:0;;;;;48901:10;-1:-1:-1;;;;;48682:350:0;;;;;49008:12;-1:-1:-1;;;;;48682:350:0;;;;;48791:4;48682:350;;;;;48662:7;:17;48670:8;48662:17;;;;;;;;;;;:370;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48662:370:0;;;;;-1:-1:-1;;;;;48662:370:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48662:370:0;;;;;-1:-1:-1;;;;;48662:370:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48662:370:0;;;;;-1:-1:-1;;;;;48662:370:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49121:33;49129:12;;49151:1;49121:7;:33::i;:::-;49105:12;49090:64;;;49091:4;49090:64;;;;;;;;;;;;;;;;;;;-1:-1:-1;49189:18:0;;-1:-1:-1;49173:12:0;;:34;;;;;;;;;49165:79;;;;;-1:-1:-1;;;49165:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49265:69;;;-1:-1:-1;;;49265:69:0;;49299:10;49265:69;;;;49319:4;49265:69;;;;;;;;;;;;-1:-1:-1;;;;;49265:33:0;;;;;:69;;;;;;;;;;;;;;-1:-1:-1;49265:33:0;:69;;;5:2:-1;;;;30:1;27;20:12;5:2;49265:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;49265:69:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;49265:69:0;49257:104;;;;;-1:-1:-1;;;49257:104:0;;;;;;;;;;;;-1:-1:-1;;;49257:104:0;;;;;;;;;;;;;;;49377:89;;;;;;-1:-1:-1;;;;;49377:89:0;;;;;;;;;;;;;;;;;;;;;;;;;49400:10;;49390:8;;49377:89;;;;;;;;;49484:8;47114:2386;-1:-1:-1;;;;;;;47114:2386:0:o;28812:35::-;;;-1:-1:-1;;;;;28812:35:0;;:::o;29104:14::-;;;;:::o;19220:109::-;18826:9;:7;:9::i;:::-;18818:18;;;;;;19293:28;19312:8;19293:18;:28::i;4930:343::-;4986:9;;5018:6;5014:69;;-1:-1:-1;5049:18:0;;-1:-1:-1;5049:18:0;5041:30;;5014:69;5104:5;;;5108:1;5104;:5;:1;5126:5;;;;;:10;5122:144;;-1:-1:-1;5161:26:0;;-1:-1:-1;5189:1:0;;-1:-1:-1;5153:38:0;;5122:144;5232:18;;-1:-1:-1;5252:1:0;-1:-1:-1;4930:343:0;;;;;;:::o;5718:236::-;5774:9;5785:4;5811:1;5806;:6;5802:145;;-1:-1:-1;5837:18:0;;-1:-1:-1;5857:5:0;;;5829:34;;5802:145;-1:-1:-1;5904:27:0;;-1:-1:-1;5933:1:0;5896:39;;17012:90;17084:10;17012:90;:::o;20612:165::-;20684:4;-1:-1:-1;;;;;20709:21:0;;20701:30;;;;;;-1:-1:-1;;;;;;20749:20:0;:11;:20;;;;;;;;;;;;;;;20612:165::o;60027:729::-;60095:26;;:::i;:::-;-1:-1:-1;60124:17:0;;;;:7;:17;;;;;;;;60095:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;60095:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;60095:46:0;;;;;;;;;;;;60124:17;60176:34;;60124:17;;60176:9;:34::i;:::-;60152:58;;60221:24;60248:37;60258:8;60268:6;:16;;;60248:9;:37::i;:::-;60305:17;;;;:7;:17;;;;;60298:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;60298:24:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;60298:24:0;;;60357:19;;;;60221:64;;-1:-1:-1;60392:20:0;;60388:134;;60435:5;-1:-1:-1;;;;;60435:14:0;;60450:6;:16;;;60468;60435:50;;;;;;;;;;;;;-1:-1:-1;;;;;60435:50:0;-1:-1:-1;;;;;60435:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60435:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60435:50:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;60435:50:0;60427:95;;;;;-1:-1:-1;;;60427:95:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60537:17;;60533:109;;60564:5;-1:-1:-1;;;;;60564:14:0;;60579:6;:13;;;60594;60564:44;;;;;;;;;;;;;-1:-1:-1;;;;;60564:44:0;-1:-1:-1;;;;;60564:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60564:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60564:44:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;60564:44:0;60556:86;;;;;-1:-1:-1;;;60556:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;60698:6;:16;;;-1:-1:-1;;;;;60660:88:0;60683:6;:13;;;-1:-1:-1;;;;;60660:88:0;60673:8;60660:88;60716:13;60731:16;60660:88;;;;;;;;;;;;;;;;;;;;;;;;60027:729;;;;;:::o;61410:3202::-;61489:26;;:::i;:::-;-1:-1:-1;61518:17:0;;;;:7;:17;;;;;;;;;61489:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;61489:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;61489:46:0;;;;;;;;;;;61546:43;;:::i;:::-;61799:21;61823:34;61833:8;61843:6;:13;;;61823:9;:34::i;:::-;61799:58;;61868:24;61895:37;61905:8;61915:6;:16;;;61895:9;:37::i;:::-;61868:64;;62059:22;62083:25;62110:23;62137:75;62162:8;62185:16;62137:10;:75::i;:::-;62058:154;;;;;;62605:38;62613:13;62628:14;62605:7;:38::i;:::-;62580:21;;;62565:78;;;62566:4;62565:78;;;;;;;;;;;;;;;;;;;-1:-1:-1;62678:18:0;;-1:-1:-1;62662:12:0;;:34;;;;;;;;;62654:83;;;;-1:-1:-1;;;62654:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63156:41;63164:16;63182:14;63156:7;:41::i;:::-;63110:42;;;63095:102;;;63096:4;63095:102;;;;;;;;;;;;;;;;;;;-1:-1:-1;63232:18:0;;-1:-1:-1;63216:12:0;;:34;;;;;;;;;63208:106;;;;-1:-1:-1;;;63208:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63368:68;63376:4;:42;;;63420:15;63368:7;:68::i;:::-;63340:24;;;63325:111;;;63326:4;63325:111;;;;;;;;;;;;;;;;;;;-1:-1:-1;63471:18:0;;-1:-1:-1;63455:12:0;;:34;;;;;;;;;63447:86;;;;-1:-1:-1;;;63447:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63694:19;;;;-1:-1:-1;;;;;63685:29:0;;;;;:8;:29;;;;;;63677:55;;63716:15;63677:7;:55::i;:::-;63653:19;;;;-1:-1:-1;;;;;63644:29:0;63630:12;63644:29;;;:8;:29;;;;;63629:103;;;63630:4;63629:103;;;;;;;;;;;;;;;;;;;-1:-1:-1;63767:18:0;;-1:-1:-1;63751:12:0;;:34;;;;;;;;;63743:82;;;;-1:-1:-1;;;63743:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63893:17;;;;:7;:17;;;;;;;;63886:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;63886:24:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;63886:24:0;;;63928:22;:32;;;;;63921:39;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;63921:39:0;;;64063:19;;;;64098:21;;;;:25;64094:138;;64146:5;-1:-1:-1;;;;;64146:14:0;;64161:6;:13;;;64176:4;:21;;;64146:52;;;;;;;;;;;;;-1:-1:-1;;;;;64146:52:0;-1:-1:-1;;;;;64146:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64146:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64146:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64146:52:0;64138:94;;;;;-1:-1:-1;;;64138:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;64247:24;;;;:28;64243:150;;64298:5;-1:-1:-1;;;;;64298:14:0;;64313:6;:16;;;64331:4;:24;;;64298:58;;;;;;;;;;;;;-1:-1:-1;;;;;64298:58:0;-1:-1:-1;;;;;64298:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64298:58:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64298:58:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64298:58:0;64290:103;;;;;-1:-1:-1;;;64290:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64449:6;:16;;;-1:-1:-1;;;;;64411:104:0;64434:6;:13;;;-1:-1:-1;;;;;64411:104:0;64424:8;64411:104;64467:4;:21;;;64490:4;:24;;;64411:104;;;;;;;;;;;;;;;;;;;;;;;;64531:73;;;;;;;;;;;;;;;;;;;;64543:8;;64531:73;;;;;;;;;;61410:3202;;;;;;;;;:::o;55779:844::-;55869:26;;:::i;:::-;-1:-1:-1;55898:17:0;;;;:7;:17;;;;;;;;;55869:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55869:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;55869:46:0;;;;;;;;;;;55926:47;;:::i;:::-;56037:40;56045:6;:23;;;56070:6;56037:7;:40::i;:::-;55985:12;55999:17;;;:7;:17;;;;;:34;;55984:93;;;55985:4;55984:93;;;;;;;;;;;;;;;;;;;-1:-1:-1;56334:18:0;;-1:-1:-1;56318:12:0;;:34;;;;;;;;;56311:42;;;;56370:17;;;;:7;:17;;;;;:34;;;56366:69;;56418:17;;;;:7;:17;;;;;56411:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;56411:24:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;56411:24:0;;;56366:69;56463:6;:19;;;-1:-1:-1;;;;;56456:36:0;;56493:6;:16;;;56511:6;56456:62;;;;;;;;;;;;;-1:-1:-1;;;;;56456:62:0;-1:-1:-1;;;;;56456:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56456:62:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56456:62:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;56456:62:0;56448:97;;;;;-1:-1:-1;;;56448:97:0;;;;;;;;;;;;-1:-1:-1;;;56448:97:0;;;;;;;;;;;;;;;56590:6;:16;;;-1:-1:-1;;;;;56561:54:0;56580:8;56561:54;56608:6;56561:54;;;;;;;;;;;;;;;;;;55779:844;;;;:::o;57155:2582::-;57256:26;;:::i;:::-;-1:-1:-1;57285:17:0;;;;:7;:17;;;;;;;;;57256:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57256:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;57256:46:0;;;;;;;;;;;57313:58;;:::i;:::-;57496:22;57520:25;57547:23;57574:28;57585:8;57595:6;57574:10;:28::i;:::-;57495:107;;;;;;58011:31;58019:6;58027:14;58011:7;:31::i;:::-;57975:32;;;57960:82;;;57961:4;57960:82;;;;;;;;;;;;;;;;;;;-1:-1:-1;58077:18:0;;-1:-1:-1;58061:12:0;;:34;;;;;;;;;58053:95;;;;-1:-1:-1;;;58053:95:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58202:58;58210:4;:32;;;58244:15;58202:7;:58::i;:::-;58174:24;;;58159:101;;;58160:4;58159:101;;;;;;;;;;;;;;;;;;;-1:-1:-1;58295:18:0;;-1:-1:-1;58279:12:0;;:34;;;;;;;;;58271:86;;;;-1:-1:-1;;;58271:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58498:40;58506:6;:23;;;58531:6;58498:7;:40::i;:::-;58446:12;58460:17;;;:7;:17;;;;;:34;;58445:93;;;58446:4;58445:93;;;;;;;;;;;;;;;;;;;-1:-1:-1;58573:18:0;;-1:-1:-1;58557:12:0;;:34;;;;;;;;;58549:84;;;;-1:-1:-1;;;58549:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58746:17;;;;:7;:17;;;;;:34;;;58742:150;;58809:17;;;;:7;:17;;;;;;;;58802:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;58802:24:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;58802:24:0;;;58848:22;:32;;;;;;58841:39;;;;;;;;;;;;;;;;;;;-1:-1:-1;;58841:39:0;;;58742:150;59042:19;;;;-1:-1:-1;;;;;59033:29:0;;;;;:8;:29;;;;;;59025:55;;59064:15;59025:7;:55::i;:::-;59001:19;;;;-1:-1:-1;;;;;58992:29:0;58978:12;58992:29;;;:8;:29;;;;;58977:103;;;58978:4;58977:103;;;;;;;;;;;;;;;;;;;-1:-1:-1;59115:18:0;;-1:-1:-1;59099:12:0;;:34;;;;;;;;;59091:82;;;;-1:-1:-1;;;59091:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59279:19;;;;59314:18;;59310:125;;59355:6;-1:-1:-1;;;;;59355:15:0;;59371:6;:13;;;59386:14;59355:46;;;;;;;;;;;;;-1:-1:-1;;;;;59355:46:0;-1:-1:-1;;;;;59355:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59355:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59355:46:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59355:46:0;59347:88;;;;;-1:-1:-1;;;59347:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;59454:6;-1:-1:-1;;;;;59454:15:0;;59470:6;:16;;;59488:4;:24;;;59454:59;;;;;;;;;;;;;-1:-1:-1;;;;;59454:59:0;-1:-1:-1;;;;;59454:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59454:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59454:59:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59454:59:0;59446:104;;;;;-1:-1:-1;;;59446:104:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59597:6;:16;;;-1:-1:-1;;;;;59568:72:0;59587:8;59568:72;59615:4;:24;;;59568:72;;;;;;;;;;;;;;;;;;59656:73;;;;;;;;;;;;;;;;;;;;59668:8;;59656:73;;;;;;;;;;57155:2582;;;;;;;;:::o;2388:476::-;2828:7;2816:20;2851:7;2388:476;:::o;6039:258::-;6095:9;;6132:5;;;6154:6;;;6150:140;;6185:18;;-1:-1:-1;6205:1:0;-1:-1:-1;6177:30:0;;6150:140;-1:-1:-1;6248:26:0;;-1:-1:-1;6276:1:0;;-1:-1:-1;6240:38:0;;22061:122;22118:21;:8;22131:7;22118:21;:12;:21;:::i;:::-;22155:20;;-1:-1:-1;;;;;22155:20:0;;;;;;;;22061:122;:::o;8416:225::-;8483:9;8494:10;;:::i;:::-;8518:15;8535:11;8550:31;8558:1;:10;;;8570:1;:10;;;8550:7;:31::i;:::-;8609:23;;;;;;;;;;;;8517:64;;8609:23;;-1:-1:-1;8416:225:0;-1:-1:-1;;;;;8416:225:0:o;8730:353::-;8799:9;8810:10;;:::i;:::-;8834:14;8850:19;8873:27;8881:1;:10;;;8893:6;8873:7;:27::i;:::-;8833:67;;-1:-1:-1;8833:67:0;-1:-1:-1;8923:18:0;8915:4;:26;;;;;;;;;8911:92;;-1:-1:-1;8972:18:0;;;;;;;;;-1:-1:-1;8972:18:0;;8966:4;;-1:-1:-1;8972:18:0;-1:-1:-1;8958:33:0;;8911:92;9043:31;;;;;;;;;;;;-1:-1:-1;;9043:31:0;;-1:-1:-1;8730:353:0;-1:-1:-1;;;;8730:353:0:o;13705:146::-;13772:9;13783:10;;:::i;:::-;13820;;13832;;13813:30;;13820:10;13813:6;:30::i;:::-;13806:37;;;;13705:146;;;;;:::o;14009:213::-;14191:12;7135:4;14191:23;;;14009:213::o;11678:1136::-;11745:9;11756:10;;:::i;:::-;11782:14;11798:24;11826:31;11834:1;:10;;;11846:1;:10;;;11826:7;:31::i;:::-;11781:76;;-1:-1:-1;11781:76:0;-1:-1:-1;11880:18:0;11872:4;:26;;;;;;;;;11868:92;;-1:-1:-1;11929:18:0;;;;;;;;;-1:-1:-1;11929:18:0;;11923:4;;-1:-1:-1;11929:18:0;-1:-1:-1;11915:33:0;;11868:92;12277:14;;12334:42;7175:10;12356:19;12334:7;:42::i;:::-;12276:100;;-1:-1:-1;12276:100:0;-1:-1:-1;12399:18:0;12391:4;:26;;;;;;;;;12387:92;;-1:-1:-1;12448:18:0;;;;;;;;;-1:-1:-1;12448:18:0;;12442:4;;-1:-1:-1;12448:18:0;-1:-1:-1;12434:33:0;;-1:-1:-1;;12434:33:0;12387:92;12492:14;12508:12;12524:51;12532:32;7135:4;12524:7;:51::i;:::-;12491:84;;-1:-1:-1;12491:84:0;-1:-1:-1;12721:18:0;12713:4;:26;;;;;;;;;12706:34;;;;12781:24;;;;;;;;;;;;-1:-1:-1;;12781:24:0;;-1:-1:-1;11678:1136:0;-1:-1:-1;;;;;;;;11678:1136:0:o;21551:141::-;1987:12;;;;;;;;:31;;;2003:15;:13;:15::i;:::-;1987:47;;;-1:-1:-1;2023:11:0;;;;2022:12;1987:47;1979:106;;;;-1:-1:-1;;;1979:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2094:19;2117:12;;;;;;2116:13;2136:83;;;;2165:12;:19;;-1:-1:-1;;;;2165:19:0;;;;;2193:18;2180:4;2193:18;;;2136:83;21622:16;21631:6;21622:8;:16::i;:::-;21617:68;;21655:18;21666:6;21655:10;:18::i;:::-;2241:14;2237:57;;;2281:5;2266:20;;-1:-1:-1;;2266:20:0;;;21551:141;;:::o;5368:215::-;5424:9;;5456:6;5452:77;;-1:-1:-1;5487:26:0;;-1:-1:-1;5515:1:0;5479:38;;5452:77;5549:18;5573:1;5569;:5;;;;;;5541:34;;;;5368:215;;;;;:::o;19479:187::-;-1:-1:-1;;;;;19553:22:0;;19545:31;;;;;;19613:6;;19592:38;;-1:-1:-1;;;;;19592:38:0;;;;19613:6;;19592:38;;19613:6;;19592:38;19641:6;:17;;-1:-1:-1;;;;;;19641:17:0;-1:-1:-1;;;;;19641:17:0;;;;;;;;;;19479:187::o;20064:186::-;-1:-1:-1;;;;;20141:21:0;;20133:30;;;;;;20183:18;20187:4;20193:7;20183:3;:18::i;:::-;20182:19;20174:28;;;;;;-1:-1:-1;;;;;20215:20:0;:11;:20;;;;;;;;;;;:27;;-1:-1:-1;;20215:27:0;20238:4;20215:27;;;20064:186::o;7489:515::-;7550:9;7561:10;;:::i;:::-;7585:14;7601:20;7625:22;7633:3;7135:4;7625:7;:22::i;:::-;7584:63;;-1:-1:-1;7584:63:0;-1:-1:-1;7670:18:0;7662:4;:26;;;;;;;;;7658:92;;-1:-1:-1;7719:18:0;;;;;;;;;-1:-1:-1;7719:18:0;;7713:4;;-1:-1:-1;7719:18:0;-1:-1:-1;7705:33:0;;7658:92;7763:14;7779:13;7796:31;7804:15;7821:5;7796:7;:31::i;:::-;7762:65;;-1:-1:-1;7762:65:0;-1:-1:-1;7850:18:0;7842:4;:26;;;;;;;;;7838:92;;-1:-1:-1;7899:18:0;;;;;;;;;-1:-1:-1;7899:18:0;;7893:4;;-1:-1:-1;7899:18:0;-1:-1:-1;7885:33:0;;-1:-1:-1;;7885:33:0;7838:92;7970:25;;;;;;;;;;;;-1:-1:-1;;7970:25:0;;-1:-1:-1;7489:515:0;-1:-1:-1;;;;;;7489:515:0:o;28122:36493::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;28122:36493:0;;;;;;-1:-1:-1;;;;;28122:36493:0;;;;;;-1:-1:-1;;;;;28122:36493:0;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;-1:-1:-1;28122:36493:0;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;-1:-1:-1;28122:36493:0;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;-1:-1:-1;28122:36493:0;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;-1:-1:-1;28122:36493:0;;;;;;;;:::o;:::-;;;;;;;;;;;-1:-1:-1;28122:36493:0;;;;;;;;;;;;;-1:-1:-1;28122:36493:0;;;;;;;;;;;;;;:::o;18401:145::-;1987:12;;;;;;;;:31;;;2003:15;:13;:15::i;:::-;1987:47;;;-1:-1:-1;2023:11:0;;;;2022:12;1987:47;1979:106;;;;-1:-1:-1;;;1979:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2094:19;2117:12;;;;;;2116:13;2136:83;;;;2165:12;:19;;-1:-1:-1;;;;2165:19:0;;;;;2193:18;2180:4;2193:18;;;2136:83;18467:6;:15;;-1:-1:-1;;;;;;18467:15:0;-1:-1:-1;;;;;18467:15:0;;;;;;;;;;;18498:40;;18531:6;;;-1:-1:-1;;18498:40:0;;-1:-1:-1;;18498:40:0;2241:14;2237:57;;;2281:5;2266:20;;-1:-1:-1;;2266:20:0;;;18401:145;;:::o
Swarm Source
bzzr://d5ad0c39f51a54f8b3b77f6b8f02e3d034b5fabbacccfa1751ca957d1cd14a2d
Loading...LoadingLoading...Loading
Loading...Loading
Loading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingOVERVIEW
The core piece of technology powering Sablier, the protocol for real-time finance on Ethereum.
Multichain Portfolio | 30 Chains
Chain Token Portfolio % Price Amount Value ETH 50.35% $0.091966 51,791,197.8919 $4,763,030.11 ETH 12.23% $22.57 51,257.614 $1,156,884.35 ETH 11.33% $0.035639 30,061,571.7325 $1,071,351.49 ETH 9.02% $0.120192 7,100,806.8404 $853,460.18 ETH 5.16% $0.112975 4,318,951.8007 $487,933.58 ETH 2.30% $1.21 179,876.5475 $217,650.62 ETH 2.25% $0.081462 2,608,364.6219 $212,483.19 ETH 1.99% $0.630543 299,173.483 $188,641.75 ETH 1.85% $0.030277 5,778,383.5314 $174,951.54 ETH 1.61% $13.95 10,887.1903 $151,876.31 ETH 0.64% $0.014031 4,330,539.9264 $60,762.89 ETH 0.30% $0.177114 157,866.2657 $27,960.38 ETH 0.21% $0.215176 93,108.4453 $20,034.7 ETH 0.14% $0.27066 49,431.6965 $13,379.18 ETH 0.11% $0.249806 42,874.1866 $10,710.23 ETH 0.10% $0.999258 9,019.6159 $9,012.92 ETH 0.08% $0.00266 2,968,570.2823 $7,896.6 ETH 0.08% $0.008294 900,630.2838 $7,469.63 ETH 0.08% $17.52 425.9 $7,461.77 ETH 0.05% $38.7 112.3086 $4,346.34 ETH 0.03% $0.999343 2,804.8658 $2,803.02 ETH 0.03% $0.023974 110,078.977 $2,639 ETH 0.01% $3,997.61 0.3495 $1,397.05 ETH 0.01% $99,117 0.0101 $999.1 ETH 0.01% $1.24 784.0872 $972.27 ETH <0.01% $0.002884 297,084.9961 $856.7 ETH <0.01% $25.08 23.8215 $597.44 ETH <0.01% $20.69 25.63 $530.28 ETH <0.01% $0.137181 2,285.1908 $313.48 ETH <0.01% $1.54 179.5373 $275.79 ETH <0.01% $0.834922 312.5912 $260.99 ETH <0.01% $0.345849 520.5258 $180.02 ETH <0.01% $0.455246 238.1216 $108.4 ETH <0.01% $0.509133 100.4043 $51.12 ETH <0.01% $0.070702 492 $34.79 ETH <0.01% $1.88 15 $28.2 ETH <0.01% $0.036538 712.936 $26.05 ETH <0.01% $0.873955 18 $15.73 ETH <0.01% $2,181.58 0.005 $10.91 ETH <0.01% $1.02 10 $10.17 ETH <0.01% $1.59 5.2875 $8.42 ETH <0.01% $0.00111 6,000 $6.66 ETH <0.01% $22.21 0.25 $5.55 ETH <0.01% $0.105094 47.8009 $5.02 ETH <0.01% $0.999779 4.57 $4.57 ETH <0.01% $117.31 0.0361 $4.24 ETH <0.01% $3.98 0.9652 $3.84 ETH <0.01% $1,090.82 0.00185 $2.02 ETH <0.01% $0.047314 35 $1.66 ETH <0.01% $0.024324 49.3954 $1.2 ETH <0.01% $0.005966 148.4999 $0.8859 ETH <0.01% $0.006405 40 $0.2562 ETH <0.01% $2.75 0.09 $0.2474 FTM <0.01% $2.12 5 $10.6 FTM <0.01% $1.37 0.011 $0.015117 AVAX <0.01% $0.024218 50 $1.21 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.
Address QR Code
My Address - Private Name Tag or Note
My Name Tag:
Private Name Tags (up to 35 characters) can be used for easy identification of addressesPrivate Note:
A private note (up to 500 characters) can be attached to this address.
Please DO NOT store any passwords or private keys here.Compiler specific version warnings:
The compiled contract might be susceptible to AbiReencodingHeadOverflowWithStaticArrayCleanup (medium-severity), DirtyBytesArrayToStorage (low-severity), NestedCalldataArrayAbiReencodingSizeValidation (very low-severity), ABIDecodeTwoDimensionalArrayMemory (very low-severity), KeccakCaching (medium-severity), EmptyByteArrayCopy (medium-severity), DynamicArrayCleanup (medium-severity), ImplicitConstructorCallvalueCheck (very low-severity), TupleAssignmentMultiStackSlotComponents (very low-severity), MemoryArrayCreationOverflow (low-severity), privateCanBeOverridden (low-severity), YulOptimizerRedundantAssignmentBreakContinue0.5 (low-severity) Solidity Compiler Bugs.
Connect a Wallet
Connecting wallet for read function is optional, useful if you want to call certain functions or simply use your wallet's node.Connect a Wallet
Connecting wallet for read function is optional, useful if you want to call certain functions or simply use your wallet's node.Connect a Wallet
Connecting wallet for read function is optional, useful if you want to call certain functions or simply use your wallet's node.SignIn
Address Cards
To use this feature, please login to your Etherscan account and return to this page.Before You Copy
Transaction Private Note
This website uses cookies to improve your experience. By continuing to use this website, you agree to its Terms and Privacy Policy.