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.
Ready to simplify your web3 experience? Try the all-in-one web3 app trusted by millions worldwide.
No gas? No problem. MetaMask Gas Station includes gas fees directly in your quote.
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
$7,511.74 (@ $3,342.48/ETH)Token Holdings
Could not find any matches!
- ERC-20 Tokens (22)100 ICEIce Coin (ICE)3,925.19641958 EYEBehodler.io (EYE)$352.28@0.089723.97738974 LINKChainLink To... (LINK)$510.00@21.274,061.16303751 OXTOrchid (OXT)$489.90@0.120620,589.9466941 PNKPinakion (PNK)$437.60@0.0213547.45043759 BATBAT (BAT)$131.74@0.2406611.93654372 DAIDai Stableco... (DAI)$611.65@0.99950.25644589 MKRMaker (MKR)$396.83@1,547.4480,000 Earn $BAT rewards at https://brave.farmERC-20: $ BR... (Earn $...)7,445.72529591 LOOMLoom Token$418.41@0.056253.59610528 UNI-V2Uniswap EYE/SCX LP (UNI-V2)$592.18@11.0489383.5010811 UNI-V2Uniswap EYE/DAI LP (UNI-V2)$436.62@1.13850.39614453 UNI-V2Uniswap SCX/ETH LP (UNI-V2)$448.85@1,133.0547421,190.43058699ERC20 ***0 WETH10ERC-20: WETH... (WETH10)0.11977598 WETH10ERC-20: WETH... (WETH10)1.4 TokenERC-20 TOKEN*[Suspicious]1.7 TokenERC-20 TOKEN*[Suspicious]1.5 TokenERC-20 TOKEN*[Suspicious]3,999.99 TokenERC-20 TOKEN*[Suspicious]132.84 TokenERC-20 TOKEN*[Spam]245.44 TokenERC-20 TOKEN*[Spam]NFT Tokens (23)claim rewards on apylink.orgapylink.orgERC-1155VoucherapyrETH.comERC-1155claim rewards on apyusd.netapyusd.netERC-1155nft-dai.comDAI Mysterybox NFTERC-1155claim rewards on link-get.comlink-get.comERC-1155claim rewards on pool-eth.orgpool-eth.orgERC-1155Reward Club [jAjR9klw]Reward Club [aJueGpMm]ERC-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*[Spam]
- 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 9,314 transactions
Transaction Hash MethodBlockFromToTransfer 21484922 2024-12-26 6:43:35 46 hrs ago 1735195415 IN 0 ETH$0.00 0.00033276 6.2292626 Transfer 21460737 2024-12-22 21:31:59 5 days ago 1734903119 IN 0 ETH$0.00 0.00047707 7.25786364 Set Valid Token 21442922 2024-12-20 9:45:47 7 days ago 1734687947 IN 0 ETH$0.00 0.00059609 22.27634346 Set Valid Token 21440395 2024-12-20 1:17:23 8 days ago 1734657443 IN 0 ETH$0.00 0.00027275 10.19293643 Set Valid Token 21440392 2024-12-20 1:16:47 8 days ago 1734657407 IN 0 ETH$0.00 0.00032367 12.0958853 Set Valid Token 21440390 2024-12-20 1:16:23 8 days ago 1734657383 IN 0 ETH$0.00 0.00028145 10.51832624 Set Valid Token 21440386 2024-12-20 1:15:35 8 days ago 1734657335 IN 0 ETH$0.00 0.00033595 12.2219108 Set Valid Token 21440383 2024-12-20 1:14:59 8 days ago 1734657299 IN 0 ETH$0.00 0.00030104 11.25031413 Set Valid Token 21440381 2024-12-20 1:14:35 8 days ago 1734657275 IN 0 ETH$0.00 0.00030624 11.44450041 Set Valid Token 21440378 2024-12-20 1:13:59 8 days ago 1734657239 IN 0 ETH$0.00 0.00029461 11.00991886 Set Valid Token 21440374 2024-12-20 1:13:11 8 days ago 1734657191 IN 0 ETH$0.00 0.00028624 10.69706396 Set Valid Token 21440371 2024-12-20 1:12:35 8 days ago 1734657155 IN 0 ETH$0.00 0.00031809 11.8874944 Set Valid Token 21440365 2024-12-20 1:11:23 8 days ago 1734657083 IN 0 ETH$0.00 0.00028735 10.73852003 Set Valid Token 21440363 2024-12-20 1:10:59 8 days ago 1734657059 IN 0 ETH$0.00 0.00028748 10.74335867 Add Liquidity 21437706 2024-12-19 16:17:35 8 days ago 1734625055 IN 0 ETH$0.00 0.00256719 23.16254432 Add Liquidity 21437683 2024-12-19 16:12:59 8 days ago 1734624779 IN 0.01779943 ETH$59.49 0.00311638 24.83711128 Approve 21436981 2024-12-19 13:51:47 8 days ago 1734616307 IN 0 ETH$0.00 0.00066298 14.27546119 Transfer 21436721 2024-12-19 12:59:47 8 days ago 1734613187 IN 0 ETH$0.00 0.00085912 13.07247865 Transfer 21436718 2024-12-19 12:59:11 8 days ago 1734613151 IN 0 ETH$0.00 0.00073619 13.78739279 Add Liquidity 21436702 2024-12-19 12:55:59 8 days ago 1734612959 IN 0 ETH$0.00 0.00180187 14.08394269 Add Liquidity 21436687 2024-12-19 12:52:59 8 days ago 1734612779 IN 0.02 ETH$66.85 0.00160407 14.80466035 Approve 21436673 2024-12-19 12:49:59 8 days ago 1734612599 IN 0 ETH$0.00 0.0006079 13.0725743 Transfer 21436669 2024-12-19 12:49:11 8 days ago 1734612551 IN 0 ETH$0.00 0.000768 10.89430958 Add Liquidity 21436629 2024-12-19 12:41:11 8 days ago 1734612071 IN 0 ETH$0.00 0.00192272 13.51635231 Add Liquidity 21436478 2024-12-19 12:10:35 8 days ago 1734610235 IN 0 ETH$0.00 0.0018968 13.41891593 Latest 25 internal transactions (View All)
Advanced mode:Parent Transaction Hash Block FromTo21437683 2024-12-19 16:12:59 8 days ago 1734624779 0.01779943 ETH$59.49 21436687 2024-12-19 12:52:59 8 days ago 1734612779 0.02 ETH$66.85 21436441 2024-12-19 12:03:11 8 days ago 1734609791 0.06 ETH$200.55 21421598 2024-12-17 10:16:23 10 days ago 1734430583 0.005 ETH$16.71 19748947 2024-04-27 20:07:47 244 days ago 1714248467 0.00648986 ETH$21.69 19704130 2024-04-21 13:39:11 250 days ago 1713706751 0.07 ETH$233.97 19683105 2024-04-18 15:01:47 253 days ago 1713452507 0.15 ETH$501.37 19661300 2024-04-15 13:46:59 256 days ago 1713188819 0.1 ETH$334.25 19646495 2024-04-13 11:57:11 258 days ago 1713009431 0.01607536 ETH$53.73 19643760 2024-04-13 2:44:35 259 days ago 1712976275 0.05953524 ETH$199.00 19643758 2024-04-13 2:44:11 259 days ago 1712976251 0.05953524 ETH$199.00 19643739 2024-04-13 2:40:23 259 days ago 1712976023 0.015 ETH$50.14 19643736 2024-04-13 2:39:47 259 days ago 1712975987 0.00468653 ETH$15.66 19643732 2024-04-13 2:38:59 259 days ago 1712975939 0.00312636 ETH$10.45 19643724 2024-04-13 2:37:23 259 days ago 1712975843 0.00156564 ETH$5.23 19640376 2024-04-12 15:18:59 259 days ago 1712935139 0.27 ETH$902.47 19640158 2024-04-12 14:34:59 259 days ago 1712932499 0.02 ETH$66.85 19640153 2024-04-12 14:33:59 259 days ago 1712932439 0.04590057 ETH$153.42 19639760 2024-04-12 13:15:23 259 days ago 1712927723 0.2 ETH$668.50 19639758 2024-04-12 13:14:59 259 days ago 1712927699 0.1 ETH$334.25 19639172 2024-04-12 11:16:35 259 days ago 1712920595 0.09 ETH$300.82 19638988 2024-04-12 10:39:23 259 days ago 1712918363 0.16 ETH$534.80 19638825 2024-04-12 10:06:47 259 days ago 1712916407 0.022 ETH$73.53 19638814 2024-04-12 10:04:35 259 days ago 1712916275 0.02026736 ETH$67.74 19638707 2024-04-12 9:43:11 259 days ago 1712914991 0.03 ETH$100.27 Loading...LoadingThis contract contains unverified libraries: AddressBalanceCheckThis contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.Contract Name:Behodler
Compiler Versionv0.7.6+commit.7338295f
Contract Source Code (Solidity)
- - function canBorrow (address borrower)
- - function execute (address caller)
- - function cut(address token)
- - function measure(
- - function burn (uint amount)
- - function symbol()
- - function burn (address holder, uint a ...
- contract Ownable
- - function owner()
- - function renounceOwnership()
- - function transferOwnership(address ne ...
- library SafeMath
- - function add(uint256 a, uint256 b)
- - function sub(uint256 a, uint256 b)
- - function sub(uint256 a, uint256 b, st ...
- - function mul(uint256 a, uint256 b)
- - function div(uint256 a, uint256 b)
- - function div(uint256 a, uint256 b, st ...
- - function mod(uint256 a, uint256 b)
- - function mod(uint256 a, uint256 b, st ...
- interface IERC20
- - function totalSupply()
- - function balanceOf(address account)
- - function decimals()
- - function transfer(address recipient, ...
- - function allowance(address owner, add ...
- - function approve(address spender, uin ...
- - function transferFrom(
- interface IERC2612
- - function permit(address owner, addres ...
- - function nonces(address owner)
- interface IERC3156FlashBorrower
- - function onFlashLoan(
- interface IERC3156FlashLender
- - function maxFlashLoan(
- - function flashFee(
- - function flashLoan(
- interface IWETH10 is IERC20, IERC2612 ...
- - function flashMinted()
- - function deposit()
- - function depositTo(address to)
- - function withdraw(uint256 value)
- - function withdrawTo(address payable t ...
- - function withdrawFrom(address from, a ...
- - function depositToAndCall(address to, ...
- - function approveAndCall(address spend ...
- - function transferAndCall(address to, ...
- interface ITransferReceiver
- - function onTokenTransfer(address, uin ...
- interface IApprovalReceiver
- - function onTokenApproval(address, uin ...
- contract WETH10 is IWETH10
- - function totalSupply()
- - function deposit()
- - function depositTo(address to)
- - function depositToAndCall(address to, ...
- - function maxFlashLoan(address token)
- - function flashFee(address token, uint ...
- - function flashLoan(IERC3156FlashBorro ...
- - function withdraw(uint256 value)
- - function withdrawTo(address payable t ...
- - function withdrawFrom(address from, a ...
- - function approve(address spender, uin ...
- - function approveAndCall(address spend ...
- - function permit(address owner, addres ...
- - function transfer(address to, uint256 ...
- - function transferFrom(address from, a ...
- - function transferAndCall(address to, ...
- contract Scarcity is IERC20, Ownab ...
- - function configureScarcity(
- - function getConfiguration()
- - function setMigrator(address m)
- - function name()
- - function symbol()
- - function decimals()
- - function totalSupply()
- - function balanceOf(address account)
- - function transfer(address recipient, ...
- - function allowance(address owner, add ...
- - function approve(address spender, uin ...
- - function transferFrom(
- - function burn(uint256 value)
- - function burn(address holder, uint256 ...
- - function mint(address recipient, uint ...
- - function migrateMint(address recipien ...
- - function _approve(
- - function _transfer(
- - function applyBurnFee(address token, ...
- library AddressBalanceCheck
- - function tokenBalance(address token)
- - function shiftedBalance(address token ...
- - function transferIn(
- - function transferOut(
- library ABDK
- - function fromUInt(uint256 x)
- - function add(int128 x, int128 y)
- - function log_2(uint256 x)
- contract Behodler is Scarcity *
- - function setSafetParameters(
- - function getMaxLiquidityExit()
- - function seed(
- - function swap(
- - function addLiquidity(address inputTo ...
- - function withdrawLiquidity(address ou ...
- - function withdrawLiquidityFindSCX(
- - function grantFlashLoan(uint256 amoun ...
- - function setWhiteListUser(address use ...
- - function burnToken(address token, uin ...
- - function setValidToken(
/** *Submitted for verification at Etherscan.io on 2021-02-24 */ // SPDX-License-Identifier: MIT pragma solidity ^0.7.6; abstract contract FlashLoanArbiter { function canBorrow (address borrower) public virtual returns (bool); } abstract contract FlashLoanReceiver { function execute (address caller) public virtual; } abstract contract LachesisLike { function cut(address token) public virtual view returns (bool, bool); function measure( address token, bool valid, bool burnable ) public virtual; } abstract contract Burnable { function burn (uint amount) public virtual; function symbol() public virtual pure returns (string memory); function burn (address holder, uint amount) public virtual; } contract Ownable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); constructor () { _owner = msg.sender; emit OwnershipTransferred(address(0), msg.sender); } function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(_owner == msg.sender, "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function decimals() external returns (uint8); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval( address indexed owner, address indexed spender, uint256 value ); } interface IERC2612 { /** * @dev Sets `amount` as the allowance of `spender` over `owner`'s tokens, * given `owner`'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; /** * @dev Returns the current ERC2612 nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); } interface IERC3156FlashBorrower { /** * @dev Receive a flash loan. * @param initiator The initiator of the loan. * @param token The loan currency. * @param amount The amount of tokens lent. * @param fee The additional amount of tokens to repay. * @param data Arbitrary data structure, intended to contain user-defined parameters. * @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan" */ function onFlashLoan( address initiator, address token, uint256 amount, uint256 fee, bytes calldata data ) external returns (bytes32); } interface IERC3156FlashLender { /** * @dev The amount of currency available to be lended. * @param token The loan currency. * @return The amount of `token` that can be borrowed. */ function maxFlashLoan( address token ) external view returns (uint256); /** * @dev The fee to be charged for a given loan. * @param token The loan currency. * @param amount The amount of tokens lent. * @return The amount of `token` to be charged for the loan, on top of the returned principal. */ function flashFee( address token, uint256 amount ) external view returns (uint256); /** * @dev Initiate a flash loan. * @param receiver The receiver of the tokens in the loan, and the receiver of the callback. * @param token The loan currency. * @param amount The amount of tokens lent. * @param data Arbitrary data structure, intended to contain user-defined parameters. */ function flashLoan( IERC3156FlashBorrower receiver, address token, uint256 amount, bytes calldata data ) external returns (bool); } /// @dev Wrapped Ether v10 (WETH10) is an Ether (ETH) ERC-20 wrapper. You can `deposit` ETH and obtain an WETH10 balance which can then be operated as an ERC-20 token. You can /// `withdraw` ETH from WETH10, which will then burn WETH10 token in your wallet. The amount of WETH10 token in any wallet is always identical to the /// balance of ETH deposited minus the ETH withdrawn with that specific wallet. interface IWETH10 is IERC20, IERC2612, IERC3156FlashLender { /// @dev Returns current amount of flash-minted WETH10 token. function flashMinted() external view returns(uint256); /// @dev `msg.value` of ETH sent to this contract grants caller account a matching increase in WETH10 token balance. /// Emits {Transfer} event to reflect WETH10 token mint of `msg.value` from zero address to caller account. function deposit() external payable; /// @dev `msg.value` of ETH sent to this contract grants `to` account a matching increase in WETH10 token balance. /// Emits {Transfer} event to reflect WETH10 token mint of `msg.value` from zero address to `to` account. function depositTo(address to) external payable; /// @dev Burn `value` WETH10 token from caller account and withdraw matching ETH to the same. /// Emits {Transfer} event to reflect WETH10 token burn of `value` to zero address from caller account. /// Requirements: /// - caller account must have at least `value` balance of WETH10 token. function withdraw(uint256 value) external; /// @dev Burn `value` WETH10 token from caller account and withdraw matching ETH to account (`to`). /// Emits {Transfer} event to reflect WETH10 token burn of `value` to zero address from caller account. /// Requirements: /// - caller account must have at least `value` balance of WETH10 token. function withdrawTo(address payable to, uint256 value) external; /// @dev Burn `value` WETH10 token from account (`from`) and withdraw matching ETH to account (`to`). /// Emits {Approval} event to reflect reduced allowance `value` for caller account to spend from account (`from`), /// unless allowance is set to `type(uint256).max` /// Emits {Transfer} event to reflect WETH10 token burn of `value` to zero address from account (`from`). /// Requirements: /// - `from` account must have at least `value` balance of WETH10 token. /// - `from` account must have approved caller to spend at least `value` of WETH10 token, unless `from` and caller are the same account. function withdrawFrom(address from, address payable to, uint256 value) external; /// @dev `msg.value` of ETH sent to this contract grants `to` account a matching increase in WETH10 token balance, /// after which a call is executed to an ERC677-compliant contract with the `data` parameter. /// Emits {Transfer} event. /// Returns boolean value indicating whether operation succeeded. /// For more information on *transferAndCall* format, see https://github.com/ethereum/EIPs/issues/677. function depositToAndCall(address to, bytes calldata data) external payable returns (bool); /// @dev Sets `value` as allowance of `spender` account over caller account's WETH10 token, /// after which a call is executed to an ERC677-compliant contract with the `data` parameter. /// Emits {Approval} event. /// Returns boolean value indicating whether operation succeeded. /// For more information on approveAndCall format, see https://github.com/ethereum/EIPs/issues/677. function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); /// @dev Moves `value` WETH10 token from caller's account to account (`to`), /// after which a call is executed to an ERC677-compliant contract with the `data` parameter. /// A transfer to `address(0)` triggers an ETH withdraw matching the sent WETH10 token in favor of caller. /// Emits {Transfer} event. /// Returns boolean value indicating whether operation succeeded. /// Requirements: /// - caller account must have at least `value` WETH10 token. /// For more information on transferAndCall format, see https://github.com/ethereum/EIPs/issues/677. function transferAndCall(address to, uint value, bytes calldata data) external returns (bool); } interface ITransferReceiver { function onTokenTransfer(address, uint, bytes calldata) external returns (bool); } interface IApprovalReceiver { function onTokenApproval(address, uint, bytes calldata) external returns (bool); } /// @dev Wrapped Ether v10 (WETH10) is an Ether (ETH) ERC-20 wrapper. You can `deposit` ETH and obtain an WETH10 balance which can then be operated as an ERC-20 token. You can /// `withdraw` ETH from WETH10, which will then burn WETH10 token in your wallet. The amount of WETH10 token in any wallet is always identical to the /// balance of ETH deposited minus the ETH withdrawn with that specific wallet. contract WETH10 is IWETH10 { string public constant name = "WETH10"; string public constant symbol = "WETH10"; uint8 public override constant decimals = 18; bytes32 public immutable CALLBACK_SUCCESS = keccak256("ERC3156FlashBorrower.onFlashLoan"); bytes32 public immutable PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); /// @dev Records amount of WETH10 token owned by account. mapping (address => uint256) public override balanceOf; /// @dev Records current ERC2612 nonce for account. This value must be included whenever signature is generated for {permit}. /// Every successful call to {permit} increases account's nonce by one. This prevents signature from being used multiple times. mapping (address => uint256) public override nonces; /// @dev Records number of WETH10 token that account (second) will be allowed to spend on behalf of another account (first) through {transferFrom}. mapping (address => mapping (address => uint256)) public override allowance; /// @dev Current amount of flash-minted WETH10 token. uint256 public override flashMinted; /// @dev Returns the total supply of WETH10 token as the ETH held in this contract. function totalSupply() external view override returns(uint256) { return address(this).balance + flashMinted; } /// @dev Fallback, `msg.value` of ETH sent to this contract grants caller account a matching increase in WETH10 token balance. /// Emits {Transfer} event to reflect WETH10 token mint of `msg.value` from zero address to caller account. receive() external payable { // _mintTo(msg.sender, msg.value); balanceOf[msg.sender] += msg.value; emit Transfer(address(0), msg.sender, msg.value); } /// @dev `msg.value` of ETH sent to this contract grants caller account a matching increase in WETH10 token balance. /// Emits {Transfer} event to reflect WETH10 token mint of `msg.value` from zero address to caller account. function deposit() external override payable { // _mintTo(msg.sender, msg.value); balanceOf[msg.sender] += msg.value; emit Transfer(address(0), msg.sender, msg.value); } /// @dev `msg.value` of ETH sent to this contract grants `to` account a matching increase in WETH10 token balance. /// Emits {Transfer} event to reflect WETH10 token mint of `msg.value` from zero address to `to` account. function depositTo(address to) external override payable { // _mintTo(to, msg.value); balanceOf[to] += msg.value; emit Transfer(address(0), to, msg.value); } /// @dev `msg.value` of ETH sent to this contract grants `to` account a matching increase in WETH10 token balance, /// after which a call is executed to an ERC677-compliant contract with the `data` parameter. /// Emits {Transfer} event. /// Returns boolean value indicating whether operation succeeded. /// For more information on *transferAndCall* format, see https://github.com/ethereum/EIPs/issues/677. function depositToAndCall(address to, bytes calldata data) external override payable returns (bool success) { // _mintTo(to, msg.value); balanceOf[to] += msg.value; emit Transfer(address(0), to, msg.value); return ITransferReceiver(to).onTokenTransfer(msg.sender, msg.value, data); } /// @dev Return the amount of WETH10 token that can be flash-lent. function maxFlashLoan(address token) external view override returns (uint256) { return token == address(this) ? type(uint112).max - flashMinted : 0; // Can't underflow } /// @dev Return the fee (zero) for flash-lending an amount of WETH10 token. function flashFee(address token, uint256) external view override returns (uint256) { require(token == address(this), "WETH: flash mint only WETH10"); return 0; } /// @dev Flash lends `value` WETH10 token to the receiver address. /// By the end of the transaction, `value` WETH10 token will be burned from the receiver. /// The flash-minted WETH10 token is not backed by real ETH, but can be withdrawn as such up to the ETH balance of this contract. /// Arbitrary data can be passed as a bytes calldata parameter. /// Emits {Approval} event to reflect reduced allowance `value` for this contract to spend from receiver account (`receiver`), /// unless allowance is set to `type(uint256).max` /// Emits two {Transfer} events for minting and burning of the flash-minted amount. /// Returns boolean value indicating whether operation succeeded. /// Requirements: /// - `value` must be less or equal to type(uint112).max. /// - The total of all flash loans in a tx must be less or equal to type(uint112).max. function flashLoan(IERC3156FlashBorrower receiver, address token, uint256 value, bytes calldata data) external override returns(bool) { require(token == address(this), "WETH: flash mint only WETH10"); require(value <= type(uint112).max, "WETH: individual loan limit exceeded"); flashMinted = flashMinted + value; require(flashMinted <= type(uint112).max, "WETH: total loan limit exceeded"); // _mintTo(address(receiver), value); balanceOf[address(receiver)] += value; emit Transfer(address(0), address(receiver), value); require( receiver.onFlashLoan(msg.sender, address(this), value, 0, data) == CALLBACK_SUCCESS, "WETH: flash loan failed" ); // _decreaseAllowance(address(receiver), address(this), value); uint256 allowed = allowance[address(receiver)][address(this)]; if (allowed != type(uint256).max) { require(allowed >= value, "WETH: request exceeds allowance"); uint256 reduced = allowed - value; allowance[address(receiver)][address(this)] = reduced; emit Approval(address(receiver), address(this), reduced); } // _burnFrom(address(receiver), value); uint256 balance = balanceOf[address(receiver)]; require(balance >= value, "WETH: burn amount exceeds balance"); balanceOf[address(receiver)] = balance - value; emit Transfer(address(receiver), address(0), value); flashMinted = flashMinted - value; return true; } /// @dev Burn `value` WETH10 token from caller account and withdraw matching ETH to the same. /// Emits {Transfer} event to reflect WETH10 token burn of `value` to zero address from caller account. /// Requirements: /// - caller account must have at least `value` balance of WETH10 token. function withdraw(uint256 value) external override { // _burnFrom(msg.sender, value); uint256 balance = balanceOf[msg.sender]; require(balance >= value, "WETH: burn amount exceeds balance"); balanceOf[msg.sender] = balance - value; emit Transfer(msg.sender, address(0), value); // _transferEther(msg.sender, value); (bool success, ) = msg.sender.call{value: value}(""); require(success, "WETH: ETH transfer failed"); } /// @dev Burn `value` WETH10 token from caller account and withdraw matching ETH to account (`to`). /// Emits {Transfer} event to reflect WETH10 token burn of `value` to zero address from caller account. /// Requirements: /// - caller account must have at least `value` balance of WETH10 token. function withdrawTo(address payable to, uint256 value) external override { // _burnFrom(msg.sender, value); uint256 balance = balanceOf[msg.sender]; require(balance >= value, "WETH: burn amount exceeds balance"); balanceOf[msg.sender] = balance - value; emit Transfer(msg.sender, address(0), value); // _transferEther(to, value); (bool success, ) = to.call{value: value}(""); require(success, "WETH: ETH transfer failed"); } /// @dev Burn `value` WETH10 token from account (`from`) and withdraw matching ETH to account (`to`). /// Emits {Approval} event to reflect reduced allowance `value` for caller account to spend from account (`from`), /// unless allowance is set to `type(uint256).max` /// Emits {Transfer} event to reflect WETH10 token burn of `value` to zero address from account (`from`). /// Requirements: /// - `from` account must have at least `value` balance of WETH10 token. /// - `from` account must have approved caller to spend at least `value` of WETH10 token, unless `from` and caller are the same account. function withdrawFrom(address from, address payable to, uint256 value) external override { if (from != msg.sender) { // _decreaseAllowance(from, msg.sender, value); uint256 allowed = allowance[from][msg.sender]; if (allowed != type(uint256).max) { require(allowed >= value, "WETH: request exceeds allowance"); uint256 reduced = allowed - value; allowance[from][msg.sender] = reduced; emit Approval(from, msg.sender, reduced); } } // _burnFrom(from, value); uint256 balance = balanceOf[from]; require(balance >= value, "WETH: burn amount exceeds balance"); balanceOf[from] = balance - value; emit Transfer(from, address(0), value); // _transferEther(to, value); (bool success, ) = to.call{value: value}(""); require(success, "WETH: Ether transfer failed"); } /// @dev Sets `value` as allowance of `spender` account over caller account's WETH10 token. /// Emits {Approval} event. /// Returns boolean value indicating whether operation succeeded. function approve(address spender, uint256 value) external override returns (bool) { // _approve(msg.sender, spender, value); allowance[msg.sender][spender] = value; emit Approval(msg.sender, spender, value); return true; } /// @dev Sets `value` as allowance of `spender` account over caller account's WETH10 token, /// after which a call is executed to an ERC677-compliant contract with the `data` parameter. /// Emits {Approval} event. /// Returns boolean value indicating whether operation succeeded. /// For more information on approveAndCall format, see https://github.com/ethereum/EIPs/issues/677. function approveAndCall(address spender, uint256 value, bytes calldata data) external override returns (bool) { // _approve(msg.sender, spender, value); allowance[msg.sender][spender] = value; emit Approval(msg.sender, spender, value); return IApprovalReceiver(spender).onTokenApproval(msg.sender, value, data); } /// @dev Sets `value` as allowance of `spender` account over `owner` account's WETH10 token, given `owner` account's signed approval. /// Emits {Approval} event. /// Requirements: /// - `deadline` must be timestamp in future. /// - `v`, `r` and `s` must be valid `secp256k1` signature from `owner` account over EIP712-formatted function arguments. /// - the signature must use `owner` account's current nonce (see {nonces}). /// - the signer cannot be zero address and must be `owner` account. /// For more information on signature format, see https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP section]. /// WETH10 token implementation adapted from https://github.com/albertocuestacanada/ERC20Permit/blob/master/contracts/ERC20Permit.sol. function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external override { require(block.timestamp <= deadline, "WETH: Expired permit"); uint256 chainId; assembly {chainId := chainid()} bytes32 DOMAIN_SEPARATOR = keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256(bytes("1")), chainId, address(this))); bytes32 hashStruct = keccak256( abi.encode( PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)); bytes32 hash = keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR, hashStruct)); address signer = ecrecover(hash, v, r, s); require(signer != address(0) && signer == owner, "WETH: invalid permit"); // _approve(owner, spender, value); allowance[owner][spender] = value; emit Approval(owner, spender, value); } /// @dev Moves `value` WETH10 token from caller's account to account (`to`). /// A transfer to `address(0)` triggers an ETH withdraw matching the sent WETH10 token in favor of caller. /// Emits {Transfer} event. /// Returns boolean value indicating whether operation succeeded. /// Requirements: /// - caller account must have at least `value` WETH10 token. function transfer(address to, uint256 value) external override returns (bool) { // _transferFrom(msg.sender, to, value); if (to != address(0)) { // Transfer uint256 balance = balanceOf[msg.sender]; require(balance >= value, "WETH: transfer amount exceeds balance"); balanceOf[msg.sender] = balance - value; balanceOf[to] += value; emit Transfer(msg.sender, to, value); } else { // Withdraw uint256 balance = balanceOf[msg.sender]; require(balance >= value, "WETH: burn amount exceeds balance"); balanceOf[msg.sender] = balance - value; emit Transfer(msg.sender, address(0), value); (bool success, ) = msg.sender.call{value: value}(""); require(success, "WETH: ETH transfer failed"); } return true; } /// @dev Moves `value` WETH10 token from account (`from`) to account (`to`) using allowance mechanism. /// `value` is then deducted from caller account's allowance, unless set to `type(uint256).max`. /// A transfer to `address(0)` triggers an ETH withdraw matching the sent WETH10 token in favor of caller. /// Emits {Approval} event to reflect reduced allowance `value` for caller account to spend from account (`from`), /// unless allowance is set to `type(uint256).max` /// Emits {Transfer} event. /// Returns boolean value indicating whether operation succeeded. /// Requirements: /// - `from` account must have at least `value` balance of WETH10 token. /// - `from` account must have approved caller to spend at least `value` of WETH10 token, unless `from` and caller are the same account. function transferFrom(address from, address to, uint256 value) external override returns (bool) { if (from != msg.sender) { // _decreaseAllowance(from, msg.sender, value); uint256 allowed = allowance[from][msg.sender]; if (allowed != type(uint256).max) { require(allowed >= value, "WETH: request exceeds allowance"); uint256 reduced = allowed - value; allowance[from][msg.sender] = reduced; emit Approval(from, msg.sender, reduced); } } // _transferFrom(from, to, value); if (to != address(0)) { // Transfer uint256 balance = balanceOf[from]; require(balance >= value, "WETH: transfer amount exceeds balance"); balanceOf[from] = balance - value; balanceOf[to] += value; emit Transfer(from, to, value); } else { // Withdraw uint256 balance = balanceOf[from]; require(balance >= value, "WETH: burn amount exceeds balance"); balanceOf[from] = balance - value; emit Transfer(from, address(0), value); (bool success, ) = msg.sender.call{value: value}(""); require(success, "WETH: ETH transfer failed"); } return true; } /// @dev Moves `value` WETH10 token from caller's account to account (`to`), /// after which a call is executed to an ERC677-compliant contract with the `data` parameter. /// A transfer to `address(0)` triggers an ETH withdraw matching the sent WETH10 token in favor of caller. /// Emits {Transfer} event. /// Returns boolean value indicating whether operation succeeded. /// Requirements: /// - caller account must have at least `value` WETH10 token. /// For more information on transferAndCall format, see https://github.com/ethereum/EIPs/issues/677. function transferAndCall(address to, uint value, bytes calldata data) external override returns (bool) { // _transferFrom(msg.sender, to, value); if (to != address(0)) { // Transfer uint256 balance = balanceOf[msg.sender]; require(balance >= value, "WETH: transfer amount exceeds balance"); balanceOf[msg.sender] = balance - value; balanceOf[to] += value; emit Transfer(msg.sender, to, value); } else { // Withdraw uint256 balance = balanceOf[msg.sender]; require(balance >= value, "WETH: burn amount exceeds balance"); balanceOf[msg.sender] = balance - value; emit Transfer(msg.sender, address(0), value); (bool success, ) = msg.sender.call{value: value}(""); require(success, "WETH: ETH transfer failed"); } return ITransferReceiver(to).onTokenTransfer(msg.sender, value, data); } } /* Scarcity is the bonding curve token that underpins Behodler functionality Scarcity burns on transfer and also exacts a fee outside of Behodler. */ contract Scarcity is IERC20, Ownable { using SafeMath for uint256; event Mint(address sender, address recipient, uint256 value); event Burn(uint256 value); mapping(address => uint256) internal balances; mapping(address => mapping(address => uint256)) internal _allowances; uint256 internal _totalSupply; address public migrator; struct BurnConfig { uint256 transferFee; // percentage expressed as number betewen 1 and 1000 uint256 burnFee; // percentage expressed as number betewen 1 and 1000 address feeDestination; } BurnConfig public config; function configureScarcity( uint256 transferFee, uint256 burnFee, address feeDestination ) public onlyOwner { require(config.transferFee + config.burnFee < 1000); config.transferFee = transferFee; config.burnFee = burnFee; config.feeDestination = feeDestination; } function getConfiguration() public view returns ( uint256, uint256, address ) { return (config.transferFee, config.burnFee, config.feeDestination); } function setMigrator(address m) public onlyOwner { migrator = m; } function name() public pure returns (string memory) { return "Scarcity"; } function symbol() public pure returns (string memory) { return "SCX"; } function decimals() public override pure returns (uint8) { return 18; } function totalSupply() external view override returns (uint256) { return _totalSupply; } function balanceOf(address account) external view override returns (uint256) { return balances[account]; } function transfer(address recipient, uint256 amount) external override returns (bool) { _transfer(msg.sender, recipient, amount); return true; } function allowance(address owner, address spender) external view override returns (uint256) { return _allowances[owner][spender]; } function approve(address spender, uint256 amount) external override returns (bool) { _approve(msg.sender, spender, amount); return true; } function transferFrom( address sender, address recipient, uint256 amount ) external override returns (bool) { _transfer(sender, recipient, amount); _approve( sender, msg.sender, _allowances[sender][msg.sender].sub( amount, "ERC20: transfer amount exceeds allowance" ) ); return true; } function burn(uint256 value) external returns (bool) { burn(msg.sender, value); return true; } function burn(address holder, uint256 value) internal { balances[holder] = balances[holder].sub( value, "SCARCITY: insufficient funds" ); _totalSupply = _totalSupply.sub(value); emit Burn(value); } function mint(address recipient, uint256 value) internal { balances[recipient] = balances[recipient].add(value); _totalSupply = _totalSupply.add(value); emit Mint(msg.sender, recipient, value); } function migrateMint(address recipient, uint256 value) public { require(msg.sender == migrator, "SCARCITY: Migration contract only"); mint(recipient, value); } function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } //outside of Behodler, Scarcity transfer incurs a fee. function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require( sender != address(0), "Scarcity: transfer from the zero address" ); require( recipient != address(0), "Scarcity: transfer to the zero address" ); uint256 feeComponent = config.transferFee.mul(amount).div(1000); uint256 burnComponent = config.burnFee.mul(amount).div(1000); _totalSupply = _totalSupply.sub(burnComponent); emit Burn(burnComponent); balances[config.feeDestination] = balances[config.feeDestination].add( feeComponent ); balances[sender] = balances[sender].sub( amount, "Scarcity: transfer amount exceeds balance" ); balances[recipient] = balances[recipient].add( amount.sub(feeComponent.add(burnComponent)) ); emit Transfer(sender, recipient, amount); } function applyBurnFee(address token, uint256 amount,bool proxyBurn) internal returns (uint256) { uint256 burnAmount = config.burnFee.mul(amount).div(1000); Burnable bToken = Burnable(token); if (proxyBurn) { bToken.burn(address(this), burnAmount); } else { bToken.burn(burnAmount); } return burnAmount; } } library AddressBalanceCheck { function tokenBalance(address token) public view returns (uint256) { return IERC20(token).balanceOf(address(this)); } function shiftedBalance(address token, uint256 factor) public view returns (uint256) { return IERC20(token).balanceOf(address(this)) / factor; } function transferIn( address token, address sender, uint256 value ) public { IERC20(token).transferFrom(sender, address(this), value); } function transferOut( address token, address recipient, uint256 value ) public { IERC20(token).transfer(recipient, value); } } /*To following code is sourced from the ABDK library for assistance in dealing with precision logarithms in Ethereum. * ABDK Math 64.64 Smart Contract Library. Copyright © 2019 by ABDK Consulting. * Author: Mikhail Vladimirov <[email protected]> * Source: https://github.com/abdk-consulting/abdk-libraries-solidity/blob/master/ABDKMath64x64.sol#L366 */ library ABDK { /* * Minimum value signed 64.64-bit fixed point number may have. */ int128 private constant MIN_64x64 = -0x80000000000000000000000000000000; /* * Maximum value signed 64.64-bit fixed point number may have. */ int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; /** * Convert unsigned 256-bit integer number into signed 64.64-bit fixed point * number. Revert on overflow. * * @param x unsigned 256-bit integer number * @return signed 64.64-bit fixed point number */ function fromUInt(uint256 x) internal pure returns (int128) { require(x <= 0x7FFFFFFFFFFFFFFF); return int128(x << 64); } /** * Calculate x + y. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function add(int128 x, int128 y) internal pure returns (int128) { int256 result = int256(x) + y; require(result >= MIN_64x64 && result <= MAX_64x64); return int128(result); } /** * Calculate binary logarithm of x. Revert if x <= 0. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function log_2(uint256 x) internal pure returns (uint256) { require(x > 0); uint256 msb = 0; uint256 xc = x; if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; } if (xc >= 0x100000000) { xc >>= 32; msb += 32; } if (xc >= 0x10000) { xc >>= 16; msb += 16; } if (xc >= 0x100) { xc >>= 8; msb += 8; } if (xc >= 0x10) { xc >>= 4; msb += 4; } if (xc >= 0x4) { xc >>= 2; msb += 2; } if (xc >= 0x2) msb += 1; // No need to shift xc anymore uint256 result = (msb - 64) << 64; uint256 ux = uint256(x) << uint256(127 - msb); for (uint256 bit = 0x8000000000000000; bit > 0; bit >>= 1) { ux *= ux; uint256 b = ux >> 255; ux >>= 127 + b; result += bit * b; } return result; } } /* Behodler orchestrates trades using an omnischedule bonding curve. The name is inspired by the Beholder of D&D, a monster with multiple arms ending in eyes peering in all directions. The Behodler is a smart contract that can see the prices of all tokens simultaneously without need for composition or delay. The hodl part of Behodler refers to the fact that with every trade of a token pair, the liquidity pool of each token held by Behodler increases Behodler 1 performed square root calculations which are gas intensive for fixed point arithmetic algorithms. To save gas, Behodler2 never performs square root calculations. It just checks the numbers passed in by the user and reverts if needs be. This techique is called invariant checking and offloads maximum calculation to clients while guaranteeing no cheating is possible. In Behodler 1 some operations were duplicated. For instance, a swap was a scarcity purchase followed by a scarcity sale. Instead, cutting out the middle scarcity allows the factor scaling to be dropped altogether. By bringing Scarcity, Janus, Kharon and Behodler together in one contract, Behodler 2 avoids the EXT_CALL gas fees and can take gas saving shortcuts with Scarcity transfers. The drawback to this approach is less flexibility with fees in the way that Kharon allowed. Behodler 2 now has Flashloan support. Instead of charging a liquidity growing fee, Behodler 2 requires the user fulfil some requirement such as holding an NFT or staking Scarcity. This allows for zero fee flash loans that are front runner resistant and allows a secondary flashloan market to evolve. */ contract Behodler is Scarcity { using SafeMath for uint256; using ABDK for int128; using ABDK for uint256; using AddressBalanceCheck for address; event LiquidityAdded( address sender, address token, uint256 tokenValue, uint256 scx ); event LiquidityWithdrawn( address recipient, address token, uint256 tokenValue, uint256 scx ); event Swap( address sender, address inputToken, address outputToken, uint256 inputValue, uint256 outputValue ); struct WeidaiTokens { address dai; address reserve; address weiDai; } struct PrecisionFactors { uint8 swapPrecisionFactor; uint8 maxLiquidityExit; //percentage as number between 1 and 100 } WeidaiTokens WD; PrecisionFactors safetyParameters; address public Weth; address public Lachesis; address pyroTokenLiquidityReceiver; FlashLoanArbiter public arbiter; address private inputSender; bool[3] unlocked; constructor() { safetyParameters.swapPrecisionFactor = 30; //approximately a billion safetyParameters.maxLiquidityExit = 90; for (uint8 i = 0; i < 3; i++) unlocked[i] = true; } function setSafetParameters( uint8 swapPrecisionFactor, uint8 maxLiquidityExit ) external onlyOwner { safetyParameters.swapPrecisionFactor = swapPrecisionFactor; safetyParameters.maxLiquidityExit = maxLiquidityExit; } function getMaxLiquidityExit() public view returns (uint8) { return safetyParameters.maxLiquidityExit; } function seed( address weth, address lachesis, address flashLoanArbiter, address _pyroTokenLiquidityReceiver, address weidaiReserve, address dai, address weiDai ) external onlyOwner { Weth = weth; Lachesis = lachesis; arbiter = FlashLoanArbiter(flashLoanArbiter); pyroTokenLiquidityReceiver = _pyroTokenLiquidityReceiver; WD.reserve = weidaiReserve; WD.dai = dai; WD.weiDai = weiDai; } //Logarithmic growth can get quite flat beyond the first chunk. We divide input amounts by uint256 public constant MIN_LIQUIDITY = 1e12; mapping(address => bool) public tokenBurnable; mapping(address => bool) public validTokens; mapping(address => bool) public whiteListUsers; // can trade on tokens that are disabled modifier onlyLachesis { require(msg.sender == Lachesis); _; } modifier onlyValidToken(address token) { require( whiteListUsers[msg.sender] || validTokens[token] || (token != address(0) && token == Weth), "BEHODLER: token invalid" ); _; } modifier determineSender(address inputToken) { if (msg.value > 0) { require( inputToken == Weth, "BEHODLER: Eth only valid for Weth trades." ); inputSender = address(this); } else { inputSender = msg.sender; } _; } enum Slot {Swap, Add, Withdraw} modifier lock(Slot slot) { uint256 index = uint256(slot); require(unlocked[index], "BEHODLER: Reentrancy guard active."); unlocked[index] = false; _; unlocked[index] = true; } /* Let config.burnFee be b. Let F = 1-b Let input token be I and Output token be O _i is initial and _f is final. Eg. I_i is initial input token balance The swap equation, when simplified, is given by √F(√I_f - √I_i) = (√O_i - √O_f)/(F) However, the gradient of square root becomes untenable when the value of tokens diverge too much. The gradient favours the addition of low value tokens disportionately. A gradient that favours tokens equally is given by a log. The lowest gas implementation is base 2. The new swap equation is thus log(I_f) - log(I_i) = log(O_i) - log(O_f) Technical note on ETH handling: we don't duplicate functions for accepting Eth as an input. Instead we wrap on receipt and apply a reentrancy guard. The determineSender modifier fixes an isse in Behodler 1 which required the user to approve both sending and receiving Eth because of the nature of Weth deposit and withdraw functionality. */ function swap( address inputToken, address outputToken, uint256 inputAmount, uint256 outputAmount ) external payable determineSender(inputToken) onlyValidToken(inputToken) lock(Slot.Swap) returns (bool success) { uint256 initialInputBalance = inputToken.tokenBalance(); if (inputToken == Weth) { if (IERC20(Weth).balanceOf(msg.sender) >= inputAmount) { Weth.transferIn(msg.sender, inputAmount); } else { require( msg.value == inputAmount, "BEHODLER: Insufficient Ether sent" ); IWETH10(Weth).deposit{value: msg.value}(); } } else { inputToken.transferIn(inputSender, inputAmount); } uint256 netInputAmount = inputAmount.sub(burnToken(inputToken, inputAmount)); uint256 initialOutputBalance = outputToken.tokenBalance(); require( outputAmount.mul(100).div(initialOutputBalance) <= safetyParameters.maxLiquidityExit, "BEHODLER: liquidity withdrawal too large." ); uint256 finalInputBalance = initialInputBalance.add(netInputAmount); uint256 finalOutputBalance = initialOutputBalance.sub(outputAmount); //new scope to avoid stack too deep errors. { //if the input balance after adding input liquidity is 1073741824 bigger than the initial balance, we revert. uint256 inputRatio = (initialInputBalance << safetyParameters.swapPrecisionFactor) .div(finalInputBalance); uint256 outputRatio = (finalOutputBalance << safetyParameters.swapPrecisionFactor) .div(initialOutputBalance); require( inputRatio != 0 && inputRatio == outputRatio, "BEHODLER: swap invariant." ); } require( finalOutputBalance >= MIN_LIQUIDITY, "BEHODLER: min liquidity." ); if (outputToken == Weth) { address payable sender = msg.sender; IWETH10(Weth).withdrawTo(sender, outputAmount); } else { outputToken.transferOut(msg.sender, outputAmount); } emit Swap( msg.sender, inputToken, outputToken, inputAmount, outputAmount ); success = true; } /* ΔSCX = log(FinalBalance) - log(InitialBalance) The choice of base for the log isn't relevant from a mathematical point of view but from a computational point of view, base 2 is the cheapest for obvious reasons. "What I told you was true, from a certain point of view." - Obi-Wan Kenobi */ function addLiquidity(address inputToken, uint256 amount) external payable determineSender(inputToken) onlyValidToken(inputToken) lock(Slot.Add) returns (uint256 deltaSCX) { uint256 initialBalance = uint256(inputToken.shiftedBalance(MIN_LIQUIDITY).fromUInt()); if (inputToken == Weth) { if (IERC20(Weth).balanceOf(msg.sender) >= amount) { Weth.transferIn(msg.sender, amount); } else { require( msg.value == amount, "BEHODLER: Insufficient Ether sent" ); IWETH10(Weth).deposit{value: msg.value}(); } } else { inputToken.transferIn(inputSender, amount); } uint256 netInputAmount = uint256( amount .sub(burnToken(inputToken, amount)) .div(MIN_LIQUIDITY) .fromUInt() ); uint256 finalBalance = uint256(initialBalance.add(netInputAmount)); require( uint256(finalBalance) >= MIN_LIQUIDITY, "BEHODLER: min liquidity." ); deltaSCX = uint256( finalBalance.log_2() - (initialBalance > 1 ? initialBalance.log_2() : 0) ); mint(msg.sender, deltaSCX); emit LiquidityAdded(msg.sender, inputToken, amount, deltaSCX); } /* ΔSCX = log(InitialBalance) - log(FinalBalance) tokensToRelease = InitialBalance -FinalBalance =>FinalBalance = InitialBalance - tokensToRelease Then apply logs and deduct SCX from msg.sender The choice of base for the log isn't relevant from a mathematical point of view but from a computational point of view, base 2 is the cheapest for obvious reasons. "From my point of view, the Jedi are evil" - Darth Vader */ function withdrawLiquidity(address outputToken, uint256 tokensToRelease) external payable determineSender(outputToken) onlyValidToken(outputToken) lock(Slot.Withdraw) returns (uint256 deltaSCX) { uint256 initialBalance = outputToken.tokenBalance(); uint256 finalBalance = initialBalance.sub(tokensToRelease); require(finalBalance > MIN_LIQUIDITY, "BEHODLER: min liquidity"); require( tokensToRelease.mul(100).div(initialBalance) <= safetyParameters.maxLiquidityExit, "BEHODLER: liquidity withdrawal too large." ); uint256 logInitial = initialBalance.log_2(); uint256 logFinal = finalBalance.log_2(); deltaSCX = logInitial - (finalBalance > 1 ? logFinal : 0); uint256 scxBalance = balances[msg.sender]; if (deltaSCX > scxBalance) { //rounding errors in scx creation and destruction. Err on the side of holders uint256 difference = deltaSCX - scxBalance; if ((difference * 10000) / deltaSCX == 0) deltaSCX = scxBalance; } burn(msg.sender, deltaSCX); if (outputToken == Weth) { address payable sender = msg.sender; IWETH10(Weth).withdrawTo(sender, tokensToRelease); } else { outputToken.transferOut(msg.sender, tokensToRelease); } emit LiquidityWithdrawn( msg.sender, outputToken, tokensToRelease, deltaSCX ); } /* ΔSCX = log(InitialBalance) - log(FinalBalance) tokensToRelease = InitialBalance -FinalBalance =>FinalBalance = InitialBalance - tokensToRelease Then apply logs and deduct SCX from msg.sender The choice of base for the log isn't relevant from a mathematical point of view but from a computational point of view, base 2 is the cheapest for obvious reasons. "From my point of view, the Jedi are evil" - Darth Vader */ function withdrawLiquidityFindSCX( address outputToken, uint256 tokensToRelease, uint256 scx, uint256 passes ) external view returns (uint256) { uint256 upperBoundary = outputToken.tokenBalance(); uint256 lowerBoundary = 0; for (uint256 i = 0; i < passes; i++) { uint256 initialBalance = outputToken.tokenBalance(); uint256 finalBalance = initialBalance.sub(tokensToRelease); uint256 logInitial = initialBalance.log_2(); uint256 logFinal = finalBalance.log_2(); int256 deltaSCX = int256(logInitial - (finalBalance > 1 ? logFinal : 0)); int256 difference = int256(scx) - deltaSCX; // if (difference**2 < 1000000) return tokensToRelease; if (difference == 0) return tokensToRelease; if (difference < 0) { // too many tokens requested upperBoundary = tokensToRelease - 1; } else { //too few tokens requested lowerBoundary = tokensToRelease + 1; } tokensToRelease = ((upperBoundary - lowerBoundary) / 2) + lowerBoundary; //bitshift tokensToRelease = tokensToRelease > initialBalance ? initialBalance : tokensToRelease; } return tokensToRelease; } //TODO: possibly comply with the flash loan standard https://eips.ethereum.org/EIPS/eip-3156 // - however, the more I reflect on this, the less keen I am due to gas and simplicity //example: a user must hold 10% of SCX total supply or user must hold an NFT //The initial arbiter will have no constraints. //The flashloan system on behodler is inverted. Instead of being able to borrow any individual token, //the borrower asks for SCX. Theoretically you can borrow more SCX than currently exists so long //as you can think of a clever way to pay it back. //Note: Borrower doesn't have to send scarcity back, they just need to have high enough balance. function grantFlashLoan(uint256 amount, address flashLoanContract) external { require( arbiter.canBorrow(msg.sender), "BEHODLER: cannot borrow flashloan" ); balances[flashLoanContract] = balances[flashLoanContract].add(amount); FlashLoanReceiver(flashLoanContract).execute(msg.sender); balances[flashLoanContract] = balances[flashLoanContract].sub( amount, "BEHODLER: Flashloan repayment failed" ); } //useful for when we want the ability to add tokens without trading. For instance, the initial liquidity queueing event. function setWhiteListUser(address user, bool whiteList) external onlyOwner { whiteListUsers[user] = whiteList; } function burnToken(address token, uint256 amount) private returns (uint256 burnt) { if (token == WD.weiDai) { burnt = applyBurnFee(token, amount, true); } else if (tokenBurnable[token]) burnt = applyBurnFee(token, amount, false); else if (token == WD.dai) { burnt = config.burnFee.mul(amount).div(1000); token.transferOut(WD.reserve, burnt); } else { burnt = config.burnFee.mul(amount).div(1000); token.transferOut(pyroTokenLiquidityReceiver, burnt); } } function setValidToken( address token, bool valid, bool burnable ) external onlyLachesis { validTokens[token] = valid; tokenBurnable[token] = burnable; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"scx","type":"uint256"}],"name":"LiquidityAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"scx","type":"uint256"}],"name":"LiquidityWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Mint","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":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"inputToken","type":"address"},{"indexed":false,"internalType":"address","name":"outputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"outputValue","type":"uint256"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"Lachesis","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_LIQUIDITY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"deltaSCX","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"arbiter","outputs":[{"internalType":"contract FlashLoanArbiter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"config","outputs":[{"internalType":"uint256","name":"transferFee","type":"uint256"},{"internalType":"uint256","name":"burnFee","type":"uint256"},{"internalType":"address","name":"feeDestination","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"transferFee","type":"uint256"},{"internalType":"uint256","name":"burnFee","type":"uint256"},{"internalType":"address","name":"feeDestination","type":"address"}],"name":"configureScarcity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getConfiguration","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxLiquidityExit","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"flashLoanContract","type":"address"}],"name":"grantFlashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"migrateMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"migrator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"weth","type":"address"},{"internalType":"address","name":"lachesis","type":"address"},{"internalType":"address","name":"flashLoanArbiter","type":"address"},{"internalType":"address","name":"_pyroTokenLiquidityReceiver","type":"address"},{"internalType":"address","name":"weidaiReserve","type":"address"},{"internalType":"address","name":"dai","type":"address"},{"internalType":"address","name":"weiDai","type":"address"}],"name":"seed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"m","type":"address"}],"name":"setMigrator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"swapPrecisionFactor","type":"uint8"},{"internalType":"uint8","name":"maxLiquidityExit","type":"uint8"}],"name":"setSafetParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"valid","type":"bool"},{"internalType":"bool","name":"burnable","type":"bool"}],"name":"setValidToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool","name":"whiteList","type":"bool"}],"name":"setWhiteListUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"outputAmount","type":"uint256"}],"name":"swap","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenBurnable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whiteListUsers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"tokensToRelease","type":"uint256"}],"name":"withdrawLiquidity","outputs":[{"internalType":"uint256","name":"deltaSCX","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"tokensToRelease","type":"uint256"},{"internalType":"uint256","name":"scx","type":"uint256"},{"internalType":"uint256","name":"passes","type":"uint256"}],"name":"withdrawLiquidityFindSCX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50600080546001600160a01b0319163390811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600b8054601e60ff199091161761ff001916615a0017905560005b60038160ff1610156100b557600160118260ff166003811061008957fe5b602081049091018054921515601f9092166101000a91820260ff9092021990921617905560010161006b565b5061334180620000c66000396000f3fe60806040526004361061020e5760003560e01c806370a0823111610118578063a9059cbb116100a0578063e22bcf841161006f578063e22bcf8414610823578063e2fc9d0014610856578063f2fde38b14610899578063fe029156146108cc578063fe25e00a146109085761020e565b8063a9059cbb14610743578063d2cb01001461077c578063dd62ed3e146107b5578063e12fb1b9146107f05761020e565b80637b12a62c116100e75780637b12a62c146106bc5780637cd07e47146106d15780638da5cb5b146106e657806395d89b41146106fb578063a451a2c1146107105761020e565b806370a082311461061a578063715018a61461064d57806372c3fdd91461066257806379502c55146106a75761020e565b806323cf31181161019b57806342966c681161016a57806342966c68146104ee5780635668870014610518578063572861bc146105445780636bd50cef146105795780636d3405f1146105b55761020e565b806323cf311814610440578063313ce56714610473578063349849a31461049e5780633f40d3a3146104b35761020e565b806307d44e1a116101e257806307d44e1a14610355578063095ea7b31461038657806318160ddd146103d357806321b77d63146103e857806323b872dd146103fd5761020e565b80627ed4fe146102135780630319f4c61461025457806306d47de91461028d57806306fdde03146102cb575b600080fd5b34801561021f57600080fd5b506102526004803603606081101561023657600080fd5b50803590602081013590604001356001600160a01b031661091d565b005b34801561026057600080fd5b506102526004803603604081101561027757600080fd5b50803590602001356001600160a01b03166109a9565b6102b9600480360360408110156102a357600080fd5b506001600160a01b038135169060200135610b47565b60408051918252519081900360200190f35b3480156102d757600080fd5b506102e0611047565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561031a578181015183820152602001610302565b50505050905090810190601f1680156103475780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561036157600080fd5b5061036a611069565b604080516001600160a01b039092168252519081900360200190f35b34801561039257600080fd5b506103bf600480360360408110156103a957600080fd5b506001600160a01b038135169060200135611078565b604080519115158252519081900360200190f35b3480156103df57600080fd5b506102b961108f565b3480156103f457600080fd5b506102b9611095565b34801561040957600080fd5b506103bf6004803603606081101561042057600080fd5b506001600160a01b0381358116916020810135909116906040013561109e565b34801561044c57600080fd5b506102526004803603602081101561046357600080fd5b50356001600160a01b0316611107565b34801561047f57600080fd5b50610488611176565b6040805160ff9092168252519081900360200190f35b3480156104aa57600080fd5b5061036a61117b565b3480156104bf57600080fd5b50610252600480360360408110156104d657600080fd5b506001600160a01b038135169060200135151561118a565b3480156104fa57600080fd5b506103bf6004803603602081101561051157600080fd5b5035611202565b6102b96004803603604081101561052e57600080fd5b506001600160a01b038135169060200135611216565b34801561055057600080fd5b506102526004803603604081101561056757600080fd5b5060ff813581169160200135166117d2565b34801561058557600080fd5b5061058e611844565b6040805193845260208401929092526001600160a01b031682820152519081900360600190f35b3480156105c157600080fd5b50610252600480360360e08110156105d857600080fd5b506001600160a01b038135811691602081013582169160408201358116916060810135821691608082013581169160a081013582169160c0909101351661185b565b34801561062657600080fd5b506102b96004803603602081101561063d57600080fd5b50356001600160a01b0316611926565b34801561065957600080fd5b50610252611941565b34801561066e57600080fd5b506102b96004803603608081101561068557600080fd5b506001600160a01b0381351690602081013590604081013590606001356119d8565b3480156106b357600080fd5b5061058e611bac565b3480156106c857600080fd5b50610488611bc1565b3480156106dd57600080fd5b5061036a611bcf565b3480156106f257600080fd5b5061036a611bde565b34801561070757600080fd5b506102e0611bed565b34801561071c57600080fd5b506103bf6004803603602081101561073357600080fd5b50356001600160a01b0316611c0a565b34801561074f57600080fd5b506103bf6004803603604081101561076657600080fd5b506001600160a01b038135169060200135611c1f565b34801561078857600080fd5b506102526004803603604081101561079f57600080fd5b506001600160a01b038135169060200135611c2c565b3480156107c157600080fd5b506102b9600480360360408110156107d857600080fd5b506001600160a01b0381358116916020013516611c83565b3480156107fc57600080fd5b506103bf6004803603602081101561081357600080fd5b50356001600160a01b0316611cae565b34801561082f57600080fd5b506103bf6004803603602081101561084657600080fd5b50356001600160a01b0316611cc3565b34801561086257600080fd5b506102526004803603606081101561087957600080fd5b506001600160a01b03813516906020810135151590604001351515611cd8565b3480156108a557600080fd5b50610252600480360360208110156108bc57600080fd5b50356001600160a01b0316611d31565b6103bf600480360360808110156108e257600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611e1e565b34801561091457600080fd5b5061036a61265b565b6000546001600160a01b0316331461096a576040805162461bcd60e51b815260206004820181905260248201526000805160206131ee833981519152604482015290519081900360640190fd5b6006546005546103e891011061097f57600080fd5b600592909255600655600780546001600160a01b0319166001600160a01b03909216919091179055565b600f546040805163039ff21960e21b815233600482015290516001600160a01b0390921691630e7fc864916024808201926020929091908290030181600087803b1580156109f657600080fd5b505af1158015610a0a573d6000803e3d6000fd5b505050506040513d6020811015610a2057600080fd5b5051610a5d5760405162461bcd60e51b81526004018080602001828103825260218152602001806132306021913960400191505060405180910390fd5b6001600160a01b038116600090815260016020526040902054610a80908361266a565b6001600160a01b0382166000818152600160205260408082209390935582516325b2724960e11b815233600482015292519192634b64e492926024808301939282900301818387803b158015610ad557600080fd5b505af1158015610ae9573d6000803e3d6000fd5b50505050610b2a82604051806060016040528060248152602001613275602491396001600160a01b03841660009081526001602052604090205491906126cb565b6001600160a01b0390911660009081526001602052604090205550565b6000823415610bb357600c546001600160a01b03828116911614610b9c5760405162461bcd60e51b815260040180806020018281038252602981526020018061317c6029913960400191505060405180910390fd5b601080546001600160a01b03191630179055610bc6565b601080546001600160a01b031916331790555b33600090815260146020526040902054849060ff1680610bfe57506001600160a01b03811660009081526013602052604090205460ff165b80610c2957506001600160a01b03811615801590610c295750600c546001600160a01b038281169116145b610c74576040805162461bcd60e51b815260206004820152601760248201527610915213d11311548e881d1bdad95b881a5b9d985b1a59604a1b604482015290519081900360640190fd5b601154600290819062010000900460ff16610cc05760405162461bcd60e51b815260040180806020018281038252602281526020018061320e6022913960400191505060405180910390fd5b600060118260038110610ccf57fe5b602091828204019190066101000a81548160ff0219169083151502179055506000876001600160a01b03167316feda2b82ba55d32ff936b9283a10797227050063eedc966a90916040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610d5357600080fd5b505af4158015610d67573d6000803e3d6000fd5b505050506040513d6020811015610d7d57600080fd5b505190506000610d8d8289612762565b905064e8d4a510008111610de8576040805162461bcd60e51b815260206004820152601760248201527f4245484f444c45523a206d696e206c6971756964697479000000000000000000604482015290519081900360640190fd5b600b54610100900460ff16610e0883610e028b60646127a4565b906127fd565b1115610e455760405162461bcd60e51b81526004018080602001828103825260298152602001806132996029913960400191505060405180910390fd5b6000610e508361283f565b90506000610e5d8361283f565b905060018311610e6e576000610e70565b805b336000908152600160205260409020549083039950808a1115610ea857808a038a612710820281610e9d57fe5b04610ea657819a505b505b610eb2338b612916565b600c546001600160a01b038d811691161415610f3b57600c546040805163040b850f60e31b81523360048201819052602482018f9052915191926001600160a01b03169163205c28789160448082019260009290919082900301818387803b158015610f1d57600080fd5b505af1158015610f31573d6000803e3d6000fd5b5050505050610fbb565b6040805163078d3b7960e01b81526001600160a01b038e166004820152336024820152604481018d905290517316feda2b82ba55d32ff936b9283a1079722705009163078d3b79916064808301926000929190829003018186803b158015610fa257600080fd5b505af4158015610fb6573d6000803e3d6000fd5b505050505b604080513381526001600160a01b038e1660208201528082018d9052606081018c905290517fba0b893b2f314a229997e335266881b5ac6b290bd350d2c23cc57160b77882b89181900360800190a1505050505060016011826003811061101e57fe5b602091828204019190066101000a81548160ff0219169083151502179055505050505092915050565b604080518082019091526008815267536361726369747960c01b602082015290565b600d546001600160a01b031681565b60006110853384846129d1565b5060015b92915050565b60035490565b64e8d4a5100081565b60006110ab848484612abd565b6110fd84336110f8856040518060600160405280602881526020016131c6602891396001600160a01b038a16600090815260026020908152604080832033845290915290205491906126cb565b6129d1565b5060019392505050565b6000546001600160a01b03163314611154576040805162461bcd60e51b815260206004820181905260248201526000805160206131ee833981519152604482015290519081900360640190fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b601290565b600c546001600160a01b031681565b6000546001600160a01b031633146111d7576040805162461bcd60e51b815260206004820181905260248201526000805160206131ee833981519152604482015290519081900360640190fd5b6001600160a01b03919091166000908152601460205260409020805460ff1916911515919091179055565b600061120e3383612916565b506001919050565b600082341561128257600c546001600160a01b0382811691161461126b5760405162461bcd60e51b815260040180806020018281038252602981526020018061317c6029913960400191505060405180910390fd5b601080546001600160a01b03191630179055611295565b601080546001600160a01b031916331790555b33600090815260146020526040902054849060ff16806112cd57506001600160a01b03811660009081526013602052604090205460ff165b806112f857506001600160a01b038116158015906112f85750600c546001600160a01b038281169116145b611343576040805162461bcd60e51b815260206004820152601760248201527610915213d11311548e881d1bdad95b881a5b9d985b1a59604a1b604482015290519081900360640190fd5b6011546001908190610100900460ff1661138e5760405162461bcd60e51b815260040180806020018281038252602281526020018061320e6022913960400191505060405180910390fd5b60006011826003811061139d57fe5b602091828204019190066101000a81548160ff0219169083151502179055506000611462886001600160a01b03167316feda2b82ba55d32ff936b9283a107972270500637fed018f909164e8d4a510006040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b15801561143157600080fd5b505af4158015611445573d6000803e3d6000fd5b505050506040513d602081101561145b57600080fd5b5051612cf8565b600c54600f9190910b91506001600160a01b038981169116141561162f57600c54604080516370a0823160e01b8152336004820152905189926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156114ca57600080fd5b505afa1580156114de573d6000803e3d6000fd5b505050506040513d60208110156114f457600080fd5b50511061158257600c546040805163e4652f4960e01b81526001600160a01b03909216600483015233602483015260448201899052517316feda2b82ba55d32ff936b9283a1079722705009163e4652f49916064808301926000929190829003018186803b15801561156557600080fd5b505af4158015611579573d6000803e3d6000fd5b5050505061162a565b8634146115c05760405162461bcd60e51b81526004018080602001828103825260218152602001806132c26021913960400191505060405180910390fd5b600c60009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561161057600080fd5b505af1158015611624573d6000803e3d6000fd5b50505050505b6116b4565b6010546040805163e4652f4960e01b81526001600160a01b038b81166004830152909216602483015260448201899052517316feda2b82ba55d32ff936b9283a1079722705009163e4652f49916064808301926000929190829003018186803b15801561169b57600080fd5b505af41580156116af573d6000803e3d6000fd5b505050505b60006116db6116d664e8d4a51000610e026116cf8d8d612d16565b8c90612762565b612cf8565b600f0b905060006116ec838361266a565b905064e8d4a51000811015611743576040805162461bcd60e51b81526020600482015260186024820152772122a427a22622a91d1036b4b7103634b8bab4b234ba3c9760411b604482015290519081900360640190fd5b6001831161175257600061175b565b61175b8361283f565b6117648261283f565b0397506117713389612eca565b604080513381526001600160a01b038c1660208201528082018b9052606081018a905290517f36f3b2e1a21c19137dd82ec243b0708a1d26b3d1fa1dc49c44c4c366a58781389181900360800190a150505060016011826003811061101e57fe5b6000546001600160a01b0316331461181f576040805162461bcd60e51b815260206004820181905260248201526000805160206131ee833981519152604482015290519081900360640190fd5b600b805460ff9283166101000261ff00199490931660ff199091161792909216179055565b6005546006546007546001600160a01b0316909192565b6000546001600160a01b031633146118a8576040805162461bcd60e51b815260206004820181905260248201526000805160206131ee833981519152604482015290519081900360640190fd5b600c80546001600160a01b03199081166001600160a01b03998a1617909155600d8054821697891697909717909655600f8054871695881695909517909455600e8054861693871693909317909255600980548516918616919091179055600880548416918516919091179055600a80549092169216919091179055565b6001600160a01b031660009081526001602052604090205490565b6000546001600160a01b0316331461198e576040805162461bcd60e51b815260206004820181905260248201526000805160206131ee833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6040805163776e4b3560e11b81526001600160a01b0386166004820152905160009182917316feda2b82ba55d32ff936b9283a1079722705009163eedc966a916024808301926020929190829003018186803b158015611a3757600080fd5b505af4158015611a4b573d6000803e3d6000fd5b505050506040513d6020811015611a6157600080fd5b505190506000805b84811015611b9d576040805163776e4b3560e11b81526001600160a01b038a16600482015290516000917316feda2b82ba55d32ff936b9283a1079722705009163eedc966a91602480820192602092909190829003018186803b158015611acf57600080fd5b505af4158015611ae3573d6000803e3d6000fd5b505050506040513d6020811015611af957600080fd5b505190506000611b09828a612762565b90506000611b168361283f565b90506000611b238361283f565b9050600060018411611b36576000611b38565b815b83039050808b0380611b55578c9950505050505050505050611ba4565b6000811215611b695760018d039850611b70565b8c60010197505b876002818b0304019c50858d11611b87578c611b89565b855b9c505060019095019450611a699350505050565b5085925050505b949350505050565b6005546006546007546001600160a01b031683565b600b54610100900460ff1690565b6004546001600160a01b031681565b6000546001600160a01b031690565b6040805180820190915260038152620a686b60eb1b602082015290565b60126020526000908152604090205460ff1681565b6000611085338484612abd565b6004546001600160a01b03163314611c755760405162461bcd60e51b81526004018080602001828103825260218152602001806130c56021913960400191505060405180910390fd5b611c7f8282612eca565b5050565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b60136020526000908152604090205460ff1681565b60146020526000908152604090205460ff1681565b600d546001600160a01b03163314611cef57600080fd5b6001600160a01b039092166000908152601360209081526040808320805494151560ff1995861617905560129091529020805492151592909116919091179055565b6000546001600160a01b03163314611d7e576040805162461bcd60e51b815260206004820181905260248201526000805160206131ee833981519152604482015290519081900360640190fd5b6001600160a01b038116611dc35760405162461bcd60e51b81526004018080602001828103825260268152602001806130e66026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000843415611e8a57600c546001600160a01b03828116911614611e735760405162461bcd60e51b815260040180806020018281038252602981526020018061317c6029913960400191505060405180910390fd5b601080546001600160a01b03191630179055611e9d565b601080546001600160a01b031916331790555b33600090815260146020526040902054869060ff1680611ed557506001600160a01b03811660009081526013602052604090205460ff165b80611f0057506001600160a01b03811615801590611f005750600c546001600160a01b038281169116145b611f4b576040805162461bcd60e51b815260206004820152601760248201527610915213d11311548e881d1bdad95b881a5b9d985b1a59604a1b604482015290519081900360640190fd5b601154600090819060ff16611f915760405162461bcd60e51b815260040180806020018281038252602281526020018061320e6022913960400191505060405180910390fd5b600060118260038110611fa057fe5b602091828204019190066101000a81548160ff0219169083151502179055506000896001600160a01b03167316feda2b82ba55d32ff936b9283a10797227050063eedc966a90916040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561202457600080fd5b505af4158015612038573d6000803e3d6000fd5b505050506040513d602081101561204e57600080fd5b5051600c549091506001600160a01b038b81169116141561221857600c54604080516370a0823160e01b815233600482015290518a926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156120b357600080fd5b505afa1580156120c7573d6000803e3d6000fd5b505050506040513d60208110156120dd57600080fd5b50511061216b57600c546040805163e4652f4960e01b81526001600160a01b039092166004830152336024830152604482018a9052517316feda2b82ba55d32ff936b9283a1079722705009163e4652f49916064808301926000929190829003018186803b15801561214e57600080fd5b505af4158015612162573d6000803e3d6000fd5b50505050612213565b8734146121a95760405162461bcd60e51b81526004018080602001828103825260218152602001806132c26021913960400191505060405180910390fd5b600c60009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156121f957600080fd5b505af115801561220d573d6000803e3d6000fd5b50505050505b61229d565b6010546040805163e4652f4960e01b81526001600160a01b038d811660048301529092166024830152604482018a9052517316feda2b82ba55d32ff936b9283a1079722705009163e4652f49916064808301926000929190829003018186803b15801561228457600080fd5b505af4158015612298573d6000803e3d6000fd5b505050505b60006122b36122ac8c8b612d16565b8a90612762565b6040805163776e4b3560e11b81526001600160a01b038d16600482015290519192506000917316feda2b82ba55d32ff936b9283a1079722705009163eedc966a916024808301926020929190829003018186803b15801561231357600080fd5b505af4158015612327573d6000803e3d6000fd5b505050506040513d602081101561233d57600080fd5b5051600b54909150610100900460ff1661235c82610e028c60646127a4565b11156123995760405162461bcd60e51b81526004018080602001828103825260298152602001806132996029913960400191505060405180910390fd5b60006123a5848461266a565b905060006123b3838c612762565b600b549091506000906123cc9060ff1687901b846127fd565b600b549091506000906123e59060ff1684901b866127fd565b905081158015906123f557508082145b612446576040805162461bcd60e51b815260206004820152601960248201527f4245484f444c45523a207377617020696e76617269616e742e00000000000000604482015290519081900360640190fd5b505064e8d4a5100081101561249d576040805162461bcd60e51b81526020600482015260186024820152772122a427a22622a91d1036b4b7103634b8bab4b234ba3c9760411b604482015290519081900360640190fd5b600c546001600160a01b038e81169116141561252657600c546040805163040b850f60e31b81523360048201819052602482018f9052915191926001600160a01b03169163205c28789160448082019260009290919082900301818387803b15801561250857600080fd5b505af115801561251c573d6000803e3d6000fd5b50505050506125a6565b6040805163078d3b7960e01b81526001600160a01b038f166004820152336024820152604481018d905290517316feda2b82ba55d32ff936b9283a1079722705009163078d3b79916064808301926000929190829003018186803b15801561258d57600080fd5b505af41580156125a1573d6000803e3d6000fd5b505050505b7fcd3829a3813dc3cdd188fd3d01dcf3268c16be2fdd2dd21d0665418816e46062338f8f8f8f60405180866001600160a01b03168152602001856001600160a01b03168152602001846001600160a01b031681526020018381526020018281526020019550505050505060405180910390a160019950505050505060016011826003811061263057fe5b602091828204019190066101000a81548160ff02191690831515021790555050505050949350505050565b600f546001600160a01b031681565b6000828201838110156126c4576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000818484111561275a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561271f578181015183820152602001612707565b50505050905090810190601f16801561274c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60006126c483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506126cb565b6000826127b357506000611089565b828202828482816127c057fe5b04146126c45760405162461bcd60e51b81526004018080602001828103825260218152602001806131a56021913960400191505060405180910390fd5b60006126c483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612f62565b600080821161284d57600080fd5b600082680100000000000000008110612868576040918201911c5b640100000000811061287c576020918201911c5b62010000811061288e576010918201911c5b610100811061289f576008918201911c5b601081106128af576004918201911c5b600481106128bf576002918201911c5b600281106128ce576001820191505b603f19820160401b607f83900385901b6780000000000000005b801561290b5790800260ff81901c8281029390930192607f011c9060011c6128e8565b509095945050505050565b604080518082018252601c81527f53434152434954593a20696e73756666696369656e742066756e6473000000006020808301919091526001600160a01b0385166000908152600190915291909120546129719183906126cb565b6001600160a01b0383166000908152600160205260409020556003546129979082612762565b6003556040805182815290517fb90306ad06b2a6ff86ddc9327db583062895ef6540e62dc50add009db5b356eb9181900360200190a15050565b6001600160a01b038316612a165760405162461bcd60e51b81526004018080602001828103825260248152602001806132516024913960400191505060405180910390fd5b6001600160a01b038216612a5b5760405162461bcd60e51b815260040180806020018281038252602281526020018061310c6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260026020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b038316612b025760405162461bcd60e51b815260040180806020018281038252602881526020018061312e6028913960400191505060405180910390fd5b6001600160a01b038216612b475760405162461bcd60e51b81526004018080602001828103825260268152602001806131566026913960400191505060405180910390fd5b600554600090612b5f906103e890610e0290856127a4565b90506000612b816103e8610e02856005600101546127a490919063ffffffff16565b600354909150612b919082612762565b6003556040805182815290517fb90306ad06b2a6ff86ddc9327db583062895ef6540e62dc50add009db5b356eb9181900360200190a16007546001600160a01b0316600090815260016020526040902054612bec908361266a565b6007546001600160a01b0316600090815260016020908152604091829020929092558051606081019091526029808252612c4b92869291906132e3908301396001600160a01b03881660009081526001602052604090205491906126cb565b6001600160a01b038616600090815260016020526040902055612c9a612c7b612c74848461266a565b8590612762565b6001600160a01b0386166000908152600160205260409020549061266a565b6001600160a01b0380861660008181526001602090815260409182902094909455805187815290519193928916927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35050505050565b6000677fffffffffffffff821115612d0f57600080fd5b5060401b90565b600a546000906001600160a01b0384811691161415612d4257612d3b83836001612fc7565b9050611089565b6001600160a01b03831660009081526012602052604090205460ff1615612d6f57612d3b83836000612fc7565b6008546001600160a01b0384811691161415612e2757600654612d9a906103e890610e0290856127a4565b6009546040805163078d3b7960e01b81526001600160a01b038781166004830152909216602483015260448201839052519192507316feda2b82ba55d32ff936b9283a1079722705009163078d3b7991606480820192600092909190829003018186803b158015612e0a57600080fd5b505af4158015612e1e573d6000803e3d6000fd5b50505050611089565b600654612e3c906103e890610e0290856127a4565b600e546040805163078d3b7960e01b81526001600160a01b038781166004830152909216602483015260448201839052519192507316feda2b82ba55d32ff936b9283a1079722705009163078d3b7991606480820192600092909190829003018186803b158015612eac57600080fd5b505af4158015612ec0573d6000803e3d6000fd5b5050505092915050565b6001600160a01b038216600090815260016020526040902054612eed908261266a565b6001600160a01b038316600090815260016020526040902055600354612f13908261266a565b600355604080513381526001600160a01b038416602082015280820183905290517fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f89181900360600190a15050565b60008183612fb15760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561271f578181015183820152602001612707565b506000838581612fbd57fe5b0495945050505050565b600080612fe86103e8610e02866005600101546127a490919063ffffffff16565b905084831561305c5760408051632770a7eb60e21b81523060048201526024810184905290516001600160a01b03831691639dc29fac91604480830192600092919082900301818387803b15801561303f57600080fd5b505af1158015613053573d6000803e3d6000fd5b505050506130bb565b806001600160a01b03166342966c68836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156130a257600080fd5b505af11580156130b6573d6000803e3d6000fd5b505050505b5094935050505056fe53434152434954593a204d6967726174696f6e20636f6e7472616374206f6e6c794f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737353636172636974793a207472616e736665722066726f6d20746865207a65726f206164647265737353636172636974793a207472616e7366657220746f20746865207a65726f20616464726573734245484f444c45523a20457468206f6e6c792076616c696420666f722057657468207472616465732e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65724245484f444c45523a205265656e7472616e6379206775617264206163746976652e4245484f444c45523a2063616e6e6f7420626f72726f7720666c6173686c6f616e45524332303a20617070726f76652066726f6d20746865207a65726f20616464726573734245484f444c45523a20466c6173686c6f616e2072657061796d656e74206661696c65644245484f444c45523a206c6971756964697479207769746864726177616c20746f6f206c617267652e4245484f444c45523a20496e73756666696369656e742045746865722073656e7453636172636974793a207472616e7366657220616d6f756e7420657863656564732062616c616e6365a26469706673582212202eae5d00a097c4cf4e518c6465785fb17c52e3c15f4e042422b3b658d94b9fc264736f6c63430007060033Deployed Bytecode
0x60806040526004361061020e5760003560e01c806370a0823111610118578063a9059cbb116100a0578063e22bcf841161006f578063e22bcf8414610823578063e2fc9d0014610856578063f2fde38b14610899578063fe029156146108cc578063fe25e00a146109085761020e565b8063a9059cbb14610743578063d2cb01001461077c578063dd62ed3e146107b5578063e12fb1b9146107f05761020e565b80637b12a62c116100e75780637b12a62c146106bc5780637cd07e47146106d15780638da5cb5b146106e657806395d89b41146106fb578063a451a2c1146107105761020e565b806370a082311461061a578063715018a61461064d57806372c3fdd91461066257806379502c55146106a75761020e565b806323cf31181161019b57806342966c681161016a57806342966c68146104ee5780635668870014610518578063572861bc146105445780636bd50cef146105795780636d3405f1146105b55761020e565b806323cf311814610440578063313ce56714610473578063349849a31461049e5780633f40d3a3146104b35761020e565b806307d44e1a116101e257806307d44e1a14610355578063095ea7b31461038657806318160ddd146103d357806321b77d63146103e857806323b872dd146103fd5761020e565b80627ed4fe146102135780630319f4c61461025457806306d47de91461028d57806306fdde03146102cb575b600080fd5b34801561021f57600080fd5b506102526004803603606081101561023657600080fd5b50803590602081013590604001356001600160a01b031661091d565b005b34801561026057600080fd5b506102526004803603604081101561027757600080fd5b50803590602001356001600160a01b03166109a9565b6102b9600480360360408110156102a357600080fd5b506001600160a01b038135169060200135610b47565b60408051918252519081900360200190f35b3480156102d757600080fd5b506102e0611047565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561031a578181015183820152602001610302565b50505050905090810190601f1680156103475780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561036157600080fd5b5061036a611069565b604080516001600160a01b039092168252519081900360200190f35b34801561039257600080fd5b506103bf600480360360408110156103a957600080fd5b506001600160a01b038135169060200135611078565b604080519115158252519081900360200190f35b3480156103df57600080fd5b506102b961108f565b3480156103f457600080fd5b506102b9611095565b34801561040957600080fd5b506103bf6004803603606081101561042057600080fd5b506001600160a01b0381358116916020810135909116906040013561109e565b34801561044c57600080fd5b506102526004803603602081101561046357600080fd5b50356001600160a01b0316611107565b34801561047f57600080fd5b50610488611176565b6040805160ff9092168252519081900360200190f35b3480156104aa57600080fd5b5061036a61117b565b3480156104bf57600080fd5b50610252600480360360408110156104d657600080fd5b506001600160a01b038135169060200135151561118a565b3480156104fa57600080fd5b506103bf6004803603602081101561051157600080fd5b5035611202565b6102b96004803603604081101561052e57600080fd5b506001600160a01b038135169060200135611216565b34801561055057600080fd5b506102526004803603604081101561056757600080fd5b5060ff813581169160200135166117d2565b34801561058557600080fd5b5061058e611844565b6040805193845260208401929092526001600160a01b031682820152519081900360600190f35b3480156105c157600080fd5b50610252600480360360e08110156105d857600080fd5b506001600160a01b038135811691602081013582169160408201358116916060810135821691608082013581169160a081013582169160c0909101351661185b565b34801561062657600080fd5b506102b96004803603602081101561063d57600080fd5b50356001600160a01b0316611926565b34801561065957600080fd5b50610252611941565b34801561066e57600080fd5b506102b96004803603608081101561068557600080fd5b506001600160a01b0381351690602081013590604081013590606001356119d8565b3480156106b357600080fd5b5061058e611bac565b3480156106c857600080fd5b50610488611bc1565b3480156106dd57600080fd5b5061036a611bcf565b3480156106f257600080fd5b5061036a611bde565b34801561070757600080fd5b506102e0611bed565b34801561071c57600080fd5b506103bf6004803603602081101561073357600080fd5b50356001600160a01b0316611c0a565b34801561074f57600080fd5b506103bf6004803603604081101561076657600080fd5b506001600160a01b038135169060200135611c1f565b34801561078857600080fd5b506102526004803603604081101561079f57600080fd5b506001600160a01b038135169060200135611c2c565b3480156107c157600080fd5b506102b9600480360360408110156107d857600080fd5b506001600160a01b0381358116916020013516611c83565b3480156107fc57600080fd5b506103bf6004803603602081101561081357600080fd5b50356001600160a01b0316611cae565b34801561082f57600080fd5b506103bf6004803603602081101561084657600080fd5b50356001600160a01b0316611cc3565b34801561086257600080fd5b506102526004803603606081101561087957600080fd5b506001600160a01b03813516906020810135151590604001351515611cd8565b3480156108a557600080fd5b50610252600480360360208110156108bc57600080fd5b50356001600160a01b0316611d31565b6103bf600480360360808110156108e257600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611e1e565b34801561091457600080fd5b5061036a61265b565b6000546001600160a01b0316331461096a576040805162461bcd60e51b815260206004820181905260248201526000805160206131ee833981519152604482015290519081900360640190fd5b6006546005546103e891011061097f57600080fd5b600592909255600655600780546001600160a01b0319166001600160a01b03909216919091179055565b600f546040805163039ff21960e21b815233600482015290516001600160a01b0390921691630e7fc864916024808201926020929091908290030181600087803b1580156109f657600080fd5b505af1158015610a0a573d6000803e3d6000fd5b505050506040513d6020811015610a2057600080fd5b5051610a5d5760405162461bcd60e51b81526004018080602001828103825260218152602001806132306021913960400191505060405180910390fd5b6001600160a01b038116600090815260016020526040902054610a80908361266a565b6001600160a01b0382166000818152600160205260408082209390935582516325b2724960e11b815233600482015292519192634b64e492926024808301939282900301818387803b158015610ad557600080fd5b505af1158015610ae9573d6000803e3d6000fd5b50505050610b2a82604051806060016040528060248152602001613275602491396001600160a01b03841660009081526001602052604090205491906126cb565b6001600160a01b0390911660009081526001602052604090205550565b6000823415610bb357600c546001600160a01b03828116911614610b9c5760405162461bcd60e51b815260040180806020018281038252602981526020018061317c6029913960400191505060405180910390fd5b601080546001600160a01b03191630179055610bc6565b601080546001600160a01b031916331790555b33600090815260146020526040902054849060ff1680610bfe57506001600160a01b03811660009081526013602052604090205460ff165b80610c2957506001600160a01b03811615801590610c295750600c546001600160a01b038281169116145b610c74576040805162461bcd60e51b815260206004820152601760248201527610915213d11311548e881d1bdad95b881a5b9d985b1a59604a1b604482015290519081900360640190fd5b601154600290819062010000900460ff16610cc05760405162461bcd60e51b815260040180806020018281038252602281526020018061320e6022913960400191505060405180910390fd5b600060118260038110610ccf57fe5b602091828204019190066101000a81548160ff0219169083151502179055506000876001600160a01b03167316feda2b82ba55d32ff936b9283a10797227050063eedc966a90916040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610d5357600080fd5b505af4158015610d67573d6000803e3d6000fd5b505050506040513d6020811015610d7d57600080fd5b505190506000610d8d8289612762565b905064e8d4a510008111610de8576040805162461bcd60e51b815260206004820152601760248201527f4245484f444c45523a206d696e206c6971756964697479000000000000000000604482015290519081900360640190fd5b600b54610100900460ff16610e0883610e028b60646127a4565b906127fd565b1115610e455760405162461bcd60e51b81526004018080602001828103825260298152602001806132996029913960400191505060405180910390fd5b6000610e508361283f565b90506000610e5d8361283f565b905060018311610e6e576000610e70565b805b336000908152600160205260409020549083039950808a1115610ea857808a038a612710820281610e9d57fe5b04610ea657819a505b505b610eb2338b612916565b600c546001600160a01b038d811691161415610f3b57600c546040805163040b850f60e31b81523360048201819052602482018f9052915191926001600160a01b03169163205c28789160448082019260009290919082900301818387803b158015610f1d57600080fd5b505af1158015610f31573d6000803e3d6000fd5b5050505050610fbb565b6040805163078d3b7960e01b81526001600160a01b038e166004820152336024820152604481018d905290517316feda2b82ba55d32ff936b9283a1079722705009163078d3b79916064808301926000929190829003018186803b158015610fa257600080fd5b505af4158015610fb6573d6000803e3d6000fd5b505050505b604080513381526001600160a01b038e1660208201528082018d9052606081018c905290517fba0b893b2f314a229997e335266881b5ac6b290bd350d2c23cc57160b77882b89181900360800190a1505050505060016011826003811061101e57fe5b602091828204019190066101000a81548160ff0219169083151502179055505050505092915050565b604080518082019091526008815267536361726369747960c01b602082015290565b600d546001600160a01b031681565b60006110853384846129d1565b5060015b92915050565b60035490565b64e8d4a5100081565b60006110ab848484612abd565b6110fd84336110f8856040518060600160405280602881526020016131c6602891396001600160a01b038a16600090815260026020908152604080832033845290915290205491906126cb565b6129d1565b5060019392505050565b6000546001600160a01b03163314611154576040805162461bcd60e51b815260206004820181905260248201526000805160206131ee833981519152604482015290519081900360640190fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b601290565b600c546001600160a01b031681565b6000546001600160a01b031633146111d7576040805162461bcd60e51b815260206004820181905260248201526000805160206131ee833981519152604482015290519081900360640190fd5b6001600160a01b03919091166000908152601460205260409020805460ff1916911515919091179055565b600061120e3383612916565b506001919050565b600082341561128257600c546001600160a01b0382811691161461126b5760405162461bcd60e51b815260040180806020018281038252602981526020018061317c6029913960400191505060405180910390fd5b601080546001600160a01b03191630179055611295565b601080546001600160a01b031916331790555b33600090815260146020526040902054849060ff16806112cd57506001600160a01b03811660009081526013602052604090205460ff165b806112f857506001600160a01b038116158015906112f85750600c546001600160a01b038281169116145b611343576040805162461bcd60e51b815260206004820152601760248201527610915213d11311548e881d1bdad95b881a5b9d985b1a59604a1b604482015290519081900360640190fd5b6011546001908190610100900460ff1661138e5760405162461bcd60e51b815260040180806020018281038252602281526020018061320e6022913960400191505060405180910390fd5b60006011826003811061139d57fe5b602091828204019190066101000a81548160ff0219169083151502179055506000611462886001600160a01b03167316feda2b82ba55d32ff936b9283a107972270500637fed018f909164e8d4a510006040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b15801561143157600080fd5b505af4158015611445573d6000803e3d6000fd5b505050506040513d602081101561145b57600080fd5b5051612cf8565b600c54600f9190910b91506001600160a01b038981169116141561162f57600c54604080516370a0823160e01b8152336004820152905189926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156114ca57600080fd5b505afa1580156114de573d6000803e3d6000fd5b505050506040513d60208110156114f457600080fd5b50511061158257600c546040805163e4652f4960e01b81526001600160a01b03909216600483015233602483015260448201899052517316feda2b82ba55d32ff936b9283a1079722705009163e4652f49916064808301926000929190829003018186803b15801561156557600080fd5b505af4158015611579573d6000803e3d6000fd5b5050505061162a565b8634146115c05760405162461bcd60e51b81526004018080602001828103825260218152602001806132c26021913960400191505060405180910390fd5b600c60009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561161057600080fd5b505af1158015611624573d6000803e3d6000fd5b50505050505b6116b4565b6010546040805163e4652f4960e01b81526001600160a01b038b81166004830152909216602483015260448201899052517316feda2b82ba55d32ff936b9283a1079722705009163e4652f49916064808301926000929190829003018186803b15801561169b57600080fd5b505af41580156116af573d6000803e3d6000fd5b505050505b60006116db6116d664e8d4a51000610e026116cf8d8d612d16565b8c90612762565b612cf8565b600f0b905060006116ec838361266a565b905064e8d4a51000811015611743576040805162461bcd60e51b81526020600482015260186024820152772122a427a22622a91d1036b4b7103634b8bab4b234ba3c9760411b604482015290519081900360640190fd5b6001831161175257600061175b565b61175b8361283f565b6117648261283f565b0397506117713389612eca565b604080513381526001600160a01b038c1660208201528082018b9052606081018a905290517f36f3b2e1a21c19137dd82ec243b0708a1d26b3d1fa1dc49c44c4c366a58781389181900360800190a150505060016011826003811061101e57fe5b6000546001600160a01b0316331461181f576040805162461bcd60e51b815260206004820181905260248201526000805160206131ee833981519152604482015290519081900360640190fd5b600b805460ff9283166101000261ff00199490931660ff199091161792909216179055565b6005546006546007546001600160a01b0316909192565b6000546001600160a01b031633146118a8576040805162461bcd60e51b815260206004820181905260248201526000805160206131ee833981519152604482015290519081900360640190fd5b600c80546001600160a01b03199081166001600160a01b03998a1617909155600d8054821697891697909717909655600f8054871695881695909517909455600e8054861693871693909317909255600980548516918616919091179055600880548416918516919091179055600a80549092169216919091179055565b6001600160a01b031660009081526001602052604090205490565b6000546001600160a01b0316331461198e576040805162461bcd60e51b815260206004820181905260248201526000805160206131ee833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6040805163776e4b3560e11b81526001600160a01b0386166004820152905160009182917316feda2b82ba55d32ff936b9283a1079722705009163eedc966a916024808301926020929190829003018186803b158015611a3757600080fd5b505af4158015611a4b573d6000803e3d6000fd5b505050506040513d6020811015611a6157600080fd5b505190506000805b84811015611b9d576040805163776e4b3560e11b81526001600160a01b038a16600482015290516000917316feda2b82ba55d32ff936b9283a1079722705009163eedc966a91602480820192602092909190829003018186803b158015611acf57600080fd5b505af4158015611ae3573d6000803e3d6000fd5b505050506040513d6020811015611af957600080fd5b505190506000611b09828a612762565b90506000611b168361283f565b90506000611b238361283f565b9050600060018411611b36576000611b38565b815b83039050808b0380611b55578c9950505050505050505050611ba4565b6000811215611b695760018d039850611b70565b8c60010197505b876002818b0304019c50858d11611b87578c611b89565b855b9c505060019095019450611a699350505050565b5085925050505b949350505050565b6005546006546007546001600160a01b031683565b600b54610100900460ff1690565b6004546001600160a01b031681565b6000546001600160a01b031690565b6040805180820190915260038152620a686b60eb1b602082015290565b60126020526000908152604090205460ff1681565b6000611085338484612abd565b6004546001600160a01b03163314611c755760405162461bcd60e51b81526004018080602001828103825260218152602001806130c56021913960400191505060405180910390fd5b611c7f8282612eca565b5050565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b60136020526000908152604090205460ff1681565b60146020526000908152604090205460ff1681565b600d546001600160a01b03163314611cef57600080fd5b6001600160a01b039092166000908152601360209081526040808320805494151560ff1995861617905560129091529020805492151592909116919091179055565b6000546001600160a01b03163314611d7e576040805162461bcd60e51b815260206004820181905260248201526000805160206131ee833981519152604482015290519081900360640190fd5b6001600160a01b038116611dc35760405162461bcd60e51b81526004018080602001828103825260268152602001806130e66026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000843415611e8a57600c546001600160a01b03828116911614611e735760405162461bcd60e51b815260040180806020018281038252602981526020018061317c6029913960400191505060405180910390fd5b601080546001600160a01b03191630179055611e9d565b601080546001600160a01b031916331790555b33600090815260146020526040902054869060ff1680611ed557506001600160a01b03811660009081526013602052604090205460ff165b80611f0057506001600160a01b03811615801590611f005750600c546001600160a01b038281169116145b611f4b576040805162461bcd60e51b815260206004820152601760248201527610915213d11311548e881d1bdad95b881a5b9d985b1a59604a1b604482015290519081900360640190fd5b601154600090819060ff16611f915760405162461bcd60e51b815260040180806020018281038252602281526020018061320e6022913960400191505060405180910390fd5b600060118260038110611fa057fe5b602091828204019190066101000a81548160ff0219169083151502179055506000896001600160a01b03167316feda2b82ba55d32ff936b9283a10797227050063eedc966a90916040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561202457600080fd5b505af4158015612038573d6000803e3d6000fd5b505050506040513d602081101561204e57600080fd5b5051600c549091506001600160a01b038b81169116141561221857600c54604080516370a0823160e01b815233600482015290518a926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156120b357600080fd5b505afa1580156120c7573d6000803e3d6000fd5b505050506040513d60208110156120dd57600080fd5b50511061216b57600c546040805163e4652f4960e01b81526001600160a01b039092166004830152336024830152604482018a9052517316feda2b82ba55d32ff936b9283a1079722705009163e4652f49916064808301926000929190829003018186803b15801561214e57600080fd5b505af4158015612162573d6000803e3d6000fd5b50505050612213565b8734146121a95760405162461bcd60e51b81526004018080602001828103825260218152602001806132c26021913960400191505060405180910390fd5b600c60009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156121f957600080fd5b505af115801561220d573d6000803e3d6000fd5b50505050505b61229d565b6010546040805163e4652f4960e01b81526001600160a01b038d811660048301529092166024830152604482018a9052517316feda2b82ba55d32ff936b9283a1079722705009163e4652f49916064808301926000929190829003018186803b15801561228457600080fd5b505af4158015612298573d6000803e3d6000fd5b505050505b60006122b36122ac8c8b612d16565b8a90612762565b6040805163776e4b3560e11b81526001600160a01b038d16600482015290519192506000917316feda2b82ba55d32ff936b9283a1079722705009163eedc966a916024808301926020929190829003018186803b15801561231357600080fd5b505af4158015612327573d6000803e3d6000fd5b505050506040513d602081101561233d57600080fd5b5051600b54909150610100900460ff1661235c82610e028c60646127a4565b11156123995760405162461bcd60e51b81526004018080602001828103825260298152602001806132996029913960400191505060405180910390fd5b60006123a5848461266a565b905060006123b3838c612762565b600b549091506000906123cc9060ff1687901b846127fd565b600b549091506000906123e59060ff1684901b866127fd565b905081158015906123f557508082145b612446576040805162461bcd60e51b815260206004820152601960248201527f4245484f444c45523a207377617020696e76617269616e742e00000000000000604482015290519081900360640190fd5b505064e8d4a5100081101561249d576040805162461bcd60e51b81526020600482015260186024820152772122a427a22622a91d1036b4b7103634b8bab4b234ba3c9760411b604482015290519081900360640190fd5b600c546001600160a01b038e81169116141561252657600c546040805163040b850f60e31b81523360048201819052602482018f9052915191926001600160a01b03169163205c28789160448082019260009290919082900301818387803b15801561250857600080fd5b505af115801561251c573d6000803e3d6000fd5b50505050506125a6565b6040805163078d3b7960e01b81526001600160a01b038f166004820152336024820152604481018d905290517316feda2b82ba55d32ff936b9283a1079722705009163078d3b79916064808301926000929190829003018186803b15801561258d57600080fd5b505af41580156125a1573d6000803e3d6000fd5b505050505b7fcd3829a3813dc3cdd188fd3d01dcf3268c16be2fdd2dd21d0665418816e46062338f8f8f8f60405180866001600160a01b03168152602001856001600160a01b03168152602001846001600160a01b031681526020018381526020018281526020019550505050505060405180910390a160019950505050505060016011826003811061263057fe5b602091828204019190066101000a81548160ff02191690831515021790555050505050949350505050565b600f546001600160a01b031681565b6000828201838110156126c4576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000818484111561275a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561271f578181015183820152602001612707565b50505050905090810190601f16801561274c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60006126c483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506126cb565b6000826127b357506000611089565b828202828482816127c057fe5b04146126c45760405162461bcd60e51b81526004018080602001828103825260218152602001806131a56021913960400191505060405180910390fd5b60006126c483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612f62565b600080821161284d57600080fd5b600082680100000000000000008110612868576040918201911c5b640100000000811061287c576020918201911c5b62010000811061288e576010918201911c5b610100811061289f576008918201911c5b601081106128af576004918201911c5b600481106128bf576002918201911c5b600281106128ce576001820191505b603f19820160401b607f83900385901b6780000000000000005b801561290b5790800260ff81901c8281029390930192607f011c9060011c6128e8565b509095945050505050565b604080518082018252601c81527f53434152434954593a20696e73756666696369656e742066756e6473000000006020808301919091526001600160a01b0385166000908152600190915291909120546129719183906126cb565b6001600160a01b0383166000908152600160205260409020556003546129979082612762565b6003556040805182815290517fb90306ad06b2a6ff86ddc9327db583062895ef6540e62dc50add009db5b356eb9181900360200190a15050565b6001600160a01b038316612a165760405162461bcd60e51b81526004018080602001828103825260248152602001806132516024913960400191505060405180910390fd5b6001600160a01b038216612a5b5760405162461bcd60e51b815260040180806020018281038252602281526020018061310c6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260026020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b038316612b025760405162461bcd60e51b815260040180806020018281038252602881526020018061312e6028913960400191505060405180910390fd5b6001600160a01b038216612b475760405162461bcd60e51b81526004018080602001828103825260268152602001806131566026913960400191505060405180910390fd5b600554600090612b5f906103e890610e0290856127a4565b90506000612b816103e8610e02856005600101546127a490919063ffffffff16565b600354909150612b919082612762565b6003556040805182815290517fb90306ad06b2a6ff86ddc9327db583062895ef6540e62dc50add009db5b356eb9181900360200190a16007546001600160a01b0316600090815260016020526040902054612bec908361266a565b6007546001600160a01b0316600090815260016020908152604091829020929092558051606081019091526029808252612c4b92869291906132e3908301396001600160a01b03881660009081526001602052604090205491906126cb565b6001600160a01b038616600090815260016020526040902055612c9a612c7b612c74848461266a565b8590612762565b6001600160a01b0386166000908152600160205260409020549061266a565b6001600160a01b0380861660008181526001602090815260409182902094909455805187815290519193928916927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35050505050565b6000677fffffffffffffff821115612d0f57600080fd5b5060401b90565b600a546000906001600160a01b0384811691161415612d4257612d3b83836001612fc7565b9050611089565b6001600160a01b03831660009081526012602052604090205460ff1615612d6f57612d3b83836000612fc7565b6008546001600160a01b0384811691161415612e2757600654612d9a906103e890610e0290856127a4565b6009546040805163078d3b7960e01b81526001600160a01b038781166004830152909216602483015260448201839052519192507316feda2b82ba55d32ff936b9283a1079722705009163078d3b7991606480820192600092909190829003018186803b158015612e0a57600080fd5b505af4158015612e1e573d6000803e3d6000fd5b50505050611089565b600654612e3c906103e890610e0290856127a4565b600e546040805163078d3b7960e01b81526001600160a01b038781166004830152909216602483015260448201839052519192507316feda2b82ba55d32ff936b9283a1079722705009163078d3b7991606480820192600092909190829003018186803b158015612eac57600080fd5b505af4158015612ec0573d6000803e3d6000fd5b5050505092915050565b6001600160a01b038216600090815260016020526040902054612eed908261266a565b6001600160a01b038316600090815260016020526040902055600354612f13908261266a565b600355604080513381526001600160a01b038416602082015280820183905290517fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f89181900360600190a15050565b60008183612fb15760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561271f578181015183820152602001612707565b506000838581612fbd57fe5b0495945050505050565b600080612fe86103e8610e02866005600101546127a490919063ffffffff16565b905084831561305c5760408051632770a7eb60e21b81523060048201526024810184905290516001600160a01b03831691639dc29fac91604480830192600092919082900301818387803b15801561303f57600080fd5b505af1158015613053573d6000803e3d6000fd5b505050506130bb565b806001600160a01b03166342966c68836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156130a257600080fd5b505af11580156130b6573d6000803e3d6000fd5b505050505b5094935050505056fe53434152434954593a204d6967726174696f6e20636f6e7472616374206f6e6c794f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737353636172636974793a207472616e736665722066726f6d20746865207a65726f206164647265737353636172636974793a207472616e7366657220746f20746865207a65726f20616464726573734245484f444c45523a20457468206f6e6c792076616c696420666f722057657468207472616465732e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65724245484f444c45523a205265656e7472616e6379206775617264206163746976652e4245484f444c45523a2063616e6e6f7420626f72726f7720666c6173686c6f616e45524332303a20617070726f76652066726f6d20746865207a65726f20616464726573734245484f444c45523a20466c6173686c6f616e2072657061796d656e74206661696c65644245484f444c45523a206c6971756964697479207769746864726177616c20746f6f206c617267652e4245484f444c45523a20496e73756666696369656e742045746865722073656e7453636172636974793a207472616e7366657220616d6f756e7420657863656564732062616c616e6365a26469706673582212202eae5d00a097c4cf4e518c6465785fb17c52e3c15f4e042422b3b658d94b9fc264736f6c63430007060033
Deployed Bytecode Sourcemap
46126:15513:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35819:337;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35819:337:0;;;;;;;;;;;-1:-1:-1;;;;;35819:337:0;;:::i;:::-;;60021:526;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;60021:526:0;;;;;;-1:-1:-1;;;;;60021:526:0;;:::i;55749:1606::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;55749:1606:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;36503:88;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47090:23;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;47090:23:0;;;;;;;;;;;;;;37465:193;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;37465:193:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;36785:102;;;;;;;;;;;;;:::i;48496:44::-;;;;;;;;;;;;;:::i;37666:444::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;37666:444:0;;;;;;;;;;;;;;;;;:::i;36415:80::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36415:80:0;-1:-1:-1;;;;;36415:80:0;;:::i;36692:85::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;47064:19;;;;;;;;;;;;;:::i;60681:126::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;60681:126:0;;;;;;;;;;:::i;38118:117::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38118:117:0;;:::i;53732:1512::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;53732:1512:0;;;;;;;;:::i;47474:263::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47474:263:0;;;;;;;;;;;:::i;36164:243::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;36164:243:0;;;;;;;;;;;;;;47871:521;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;47871:521:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;36895:161::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36895:161:0;-1:-1:-1;;;;;36895:161:0;;:::i;1639:148::-;;;;;;;;;;;;;:::i;57860:1461::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;57860:1461:0;;;;;;;;;;;;;;;;;;:::i;35786:24::-;;;;;;;;;;;;;:::i;47745:118::-;;;;;;;;;;;;;:::i;35525:23::-;;;;;;;;;;;;;:::i;999:79::-;;;;;;;;;;;;;:::i;36599:85::-;;;;;;;;;;;;;:::i;48549:45::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48549:45:0;-1:-1:-1;;;;;48549:45:0;;:::i;37064:199::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;37064:199:0;;;;;;;;:::i;38750:182::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;38750:182:0;;;;;;;;:::i;37271:186::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;37271:186:0;;;;;;;;;;:::i;48601:43::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48601:43:0;-1:-1:-1;;;;;48601:43:0;;:::i;48651:46::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48651:46:0;-1:-1:-1;;;;;48651:46:0;;:::i;61428:208::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;61428:208:0;;;;;;;;;;;;;;;;;:::i;1942:244::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1942:244:0;-1:-1:-1;;;;;1942:244:0;;:::i;50746:2636::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;50746:2636:0;;;;;;;;;;;;;;;;;;;;;;:::i;47161:31::-;;;;;;;;;;;;;:::i;35819:337::-;1211:6;;-1:-1:-1;;;;;1211:6:0;1221:10;1211:20;1203:65;;;;;-1:-1:-1;;;1203:65:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1203:65:0;;;;;;;;;;;;;;;35999:14;;:6:::1;35978:18:::0;36016:4:::1;35978:35:::0;::::1;:42;35970:51;;;::::0;::::1;;36032:6;:32:::0;;;;36075:14;:24;36110:21;:38;;-1:-1:-1;;;;;;36110:38:0::1;-1:-1:-1::0;;;;;36110:38:0;;::::1;::::0;;;::::1;::::0;;35819:337::o;60021:526::-;60144:7;;:29;;;-1:-1:-1;;;60144:29:0;;60162:10;60144:29;;;;;;-1:-1:-1;;;;;60144:7:0;;;;:17;;:29;;;;;;;;;;;;;;;:7;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;60144:29:0;60122:112;;;;-1:-1:-1;;;60122:112:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;60275:27:0;;;;;;:8;:27;;;;;;:39;;60307:6;60275:31;:39::i;:::-;-1:-1:-1;;;;;60245:27:0;;;;;;:8;:27;;;;;;:69;;;;60325:56;;-1:-1:-1;;;60325:56:0;;60370:10;60325:56;;;;;;60245:27;;60325:44;;:56;;;;;60245:27;60325:56;;;;;60245:27;;60325:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60423:116;60469:6;60423:116;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;60423:27:0;;;;;;:8;:27;;;;;;;:116;:31;:116::i;:::-;-1:-1:-1;;;;;60393:27:0;;;;;;;:8;:27;;;;;:146;-1:-1:-1;60021:526:0:o;55749:1606::-;55979:16;55882:11;49174:9;:13;49170:266;;49244:4;;-1:-1:-1;;;;;49230:18:0;;;49244:4;;49230:18;49204:121;;;;-1:-1:-1;;;49204:121:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49340:11;:27;;-1:-1:-1;;;;;;49340:27:0;49362:4;49340:27;;;49170:266;;;49400:11;:24;;-1:-1:-1;;;;;;49400:24:0;49414:10;49400:24;;;49170:266;48926:10:::1;48911:26;::::0;;;:14:::1;:26;::::0;;;;;55919:11;;48911:26:::1;;::::0;:65:::1;;-1:-1:-1::0;;;;;;48958:18:0;::::1;;::::0;;;:11:::1;:18;::::0;;;;;::::1;;48911:65;:124;;;-1:-1:-1::0;;;;;;48998:19:0;::::1;::::0;;::::1;::::0;:36:::1;;-1:-1:-1::0;49030:4:0::1;::::0;-1:-1:-1;;;;;49021:13:0;;::::1;49030:4:::0;::::1;49021:13;48998:36;48889:197;;;::::0;;-1:-1:-1;;;48889:197:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;48889:197:0;;;;;;;;;;;;;::::1;;49586:8:::2;:15:::0;55946:13:::2;::::0;;;49586:15;;::::2;;;49578:62;;;;-1:-1:-1::0;;;49578:62:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49669:5;49651:8;49660:5;49651:15;;;;;;;;;;;;;;;;:23;;;;;;;;;;;;;;;;;;56013:22:::3;56038:11;-1:-1:-1::0;;;;;56038:24:0::3;;;;;:26;;;;;;;;;;;;;-1:-1:-1::0;;;;;56038:26:0::3;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;::::0;::::3;;-1:-1:-1::0;56038:26:0;;-1:-1:-1;56075:20:0::3;56098:35;56038:26:::0;56117:15;56098:18:::3;:35::i;:::-;56075:58;;48536:4;56152:12;:28;56144:64;;;::::0;;-1:-1:-1;;;56144:64:0;;::::3;;::::0;::::3;::::0;::::3;::::0;;;;::::3;::::0;;;;;;;;;;;;;::::3;;56306:16;:33:::0;::::3;::::0;::::3;;;56241:44;56270:14:::0;56241:24:::3;:15:::0;56261:3:::3;56241:19;:24::i;:::-;:28:::0;::::3;:44::i;:::-;:98;;56219:189;;;;-1:-1:-1::0;;;56219:189:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56421:18;56442:22;:14;:20;:22::i;:::-;56421:43;;56475:16;56494:20;:12;:18;:20::i;:::-;56475:39;;56567:1;56552:12;:16;:31;;56582:1;56552:31;;;56571:8;56552:31;56625:10;56595:18;56616:20:::0;;;:8:::3;:20;::::0;;;;;56538:46;;::::3;::::0;-1:-1:-1;56653:21:0;;::::3;56649:265;;;56803:21:::0;;::::3;:8:::0;56857:5:::3;56844:18:::0;::::3;56803:8:::0;56843:31:::3;;;;;56839:63;;56892:10;56881:21;;56839:63;56649:265;;56924:26;56929:10;56941:8;56924:4;:26::i;:::-;56982:4;::::0;-1:-1:-1;;;;;56967:19:0;;::::3;56982:4:::0;::::3;56967:19;56963:236;;;57061:4;::::0;57053:49:::3;::::0;;-1:-1:-1;;;57053:49:0;;57028:10:::3;57053:49;::::0;::::3;::::0;;;;;;;;;;;57028:10;;-1:-1:-1;;;;;57061:4:0::3;::::0;57053:24:::3;::::0;:49;;;;;57003:22:::3;::::0;57053:49;;;;;;;;57003:22;57061:4;57053:49;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;56963:236;;;;57135:52;::::0;;-1:-1:-1;;;57135:52:0;;-1:-1:-1;;;;;57135:23:0;::::3;:52;::::0;::::3;::::0;57159:10:::3;57135:52:::0;;;;;;;;;;;;:23:::3;::::0;::::3;::::0;:52;;;;;-1:-1:-1;;57135:52:0;;;;;;;:23;:52;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;56963:236;57214:133;::::0;;57247:10:::3;57214:133:::0;;-1:-1:-1;;;;;57214:133:0;::::3;;::::0;::::3;::::0;;;;;;;;;;;;;;;::::3;::::0;;;;;;;::::3;49685:1;;;;;49715:4:::2;49697:8;49706:5;49697:15;;;;;;;;;;;;;;;;:22;;;;;;;;;;;;;;;;;;49097:1;;49446::::1;55749:1606:::0;;;;;:::o;36503:88::-;36566:17;;;;;;;;;;;;-1:-1:-1;;;36566:17:0;;;;36503:88;:::o;47090:23::-;;;-1:-1:-1;;;;;47090:23:0;;:::o;37465:193::-;37569:4;37591:37;37600:10;37612:7;37621:6;37591:8;:37::i;:::-;-1:-1:-1;37646:4:0;37465:193;;;;;:::o;36785:102::-;36867:12;;36785:102;:::o;48496:44::-;48536:4;48496:44;:::o;37666:444::-;37800:4;37817:36;37827:6;37835:9;37846:6;37817:9;:36::i;:::-;37864:216;37887:6;37908:10;37933:136;37987:6;37933:136;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;37933:19:0;;;;;;:11;:19;;;;;;;;37953:10;37933:31;;;;;;;;;:136;:35;:136::i;:::-;37864:8;:216::i;:::-;-1:-1:-1;38098:4:0;37666:444;;;;;:::o;36415:80::-;1211:6;;-1:-1:-1;;;;;1211:6:0;1221:10;1211:20;1203:65;;;;;-1:-1:-1;;;1203:65:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1203:65:0;;;;;;;;;;;;;;;36475:8:::1;:12:::0;;-1:-1:-1;;;;;;36475:12:0::1;-1:-1:-1::0;;;;;36475:12:0;;;::::1;::::0;;;::::1;::::0;;36415:80::o;36692:85::-;36767:2;36692:85;:::o;47064:19::-;;;-1:-1:-1;;;;;47064:19:0;;:::o;60681:126::-;1211:6;;-1:-1:-1;;;;;1211:6:0;1221:10;1211:20;1203:65;;;;;-1:-1:-1;;;1203:65:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1203:65:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;60767:20:0;;;::::1;;::::0;;;:14:::1;:20;::::0;;;;:32;;-1:-1:-1;;60767:32:0::1;::::0;::::1;;::::0;;;::::1;::::0;;60681:126::o;38118:117::-;38165:4;38182:23;38187:10;38199:5;38182:4;:23::i;:::-;-1:-1:-1;38223:4:0;38118:117;;;:::o;53732:1512::-;53940:16;53850:10;49174:9;:13;49170:266;;49244:4;;-1:-1:-1;;;;;49230:18:0;;;49244:4;;49230:18;49204:121;;;;-1:-1:-1;;;49204:121:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49340:11;:27;;-1:-1:-1;;;;;;49340:27:0;49362:4;49340:27;;;49170:266;;;49400:11;:24;;-1:-1:-1;;;;;;49400:24:0;49414:10;49400:24;;;49170:266;48926:10:::1;48911:26;::::0;;;:14:::1;:26;::::0;;;;;53886:10;;48911:26:::1;;::::0;:65:::1;;-1:-1:-1::0;;;;;;48958:18:0;::::1;;::::0;;;:11:::1;:18;::::0;;;;;::::1;;48911:65;:124;;;-1:-1:-1::0;;;;;;48998:19:0;::::1;::::0;;::::1;::::0;:36:::1;;-1:-1:-1::0;49030:4:0::1;::::0;-1:-1:-1;;;;;49021:13:0;;::::1;49030:4:::0;::::1;49021:13;48998:36;48889:197;;;::::0;;-1:-1:-1;;;48889:197:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;48889:197:0;;;;;;;;;;;;;::::1;;49586:8:::2;:15:::0;53912:8:::2;::::0;;;49586:15:::2;::::0;::::2;;;49578:62;;;;-1:-1:-1::0;;;49578:62:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49669:5;49651:8;49660:5;49651:15;;;;;;;;;;;;;;;;:23;;;;;;;;;;;;;;;;;;53974:22:::3;54020:51;:10;-1:-1:-1::0;;;;;54020:25:0::3;;;;;48536:4;54020:40;;;;;;;;;;;;;-1:-1:-1::0;;;;;54020:40:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;::::0;::::3;;-1:-1:-1::0;54020:40:0;:49:::3;:51::i;:::-;54101:4;::::0;54012:60:::3;::::0;;;::::3;::::0;-1:-1:-1;;;;;;54087:18:0;;::::3;54101:4:::0;::::3;54087:18;54083:472;;;54133:4;::::0;54126:34:::3;::::0;;-1:-1:-1;;;54126:34:0;;54149:10:::3;54126:34;::::0;::::3;::::0;;;54164:6;;-1:-1:-1;;;;;54133:4:0::3;::::0;54126:22:::3;::::0;:34;;;;;::::3;::::0;;;;;;;;54133:4;54126:34;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;::::0;::::3;;-1:-1:-1::0;54126:34:0;:44:::3;54122:347;;54191:4;::::0;:35:::3;::::0;;-1:-1:-1;;;54191:35:0;;-1:-1:-1;;;;;54191:4:0;;::::3;:35;::::0;::::3;::::0;54207:10:::3;54191:35:::0;;;;;;;;;;;:15:::3;::::0;::::3;::::0;:35;;;;;:4:::3;::::0;:35;;;;;;;:15;:35;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;54122:347;;;54310:6;54297:9;:19;54267:126;;;;-1:-1:-1::0;;;54267:126:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54420:4;;;;;;;;;-1:-1:-1::0;;;;;54420:4:0::3;-1:-1:-1::0;;;;;54412:21:0::3;;54441:9;54412:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;54122:347;54083:472;;;54523:11;::::0;54501:42:::3;::::0;;-1:-1:-1;;;54501:42:0;;-1:-1:-1;;;;;54501:21:0;;::::3;:42;::::0;::::3;::::0;54523:11;;::::3;54501:42:::0;;;;;;;;;;;:21:::3;::::0;::::3;::::0;:42;;;;;-1:-1:-1;;54501:42:0;;;;;;;:21;:42;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;54083:472;54565:22;54629:137;:104;48536:4;54629:63;54662:29;54672:10;54684:6;54662:9;:29::i;:::-;54629:6:::0;;:32:::3;:63::i;:104::-;:135;:137::i;:::-;54603:178;;::::0;-1:-1:-1;54794:20:0::3;54825:34;:14:::0;54603:178;54825:18:::3;:34::i;:::-;54794:66;;48536:4;54901:12;54893:38;;54871:112;;;::::0;;-1:-1:-1;;;54871:112:0;;::::3;;::::0;::::3;::::0;::::3;::::0;;;;-1:-1:-1;;;54871:112:0;;;;;;;;;;;;;::::3;;55085:1;55068:14;:18;:47;;55114:1;55068:47;;;55089:22;:14;:20;:22::i;:::-;55027:20;:12;:18;:20::i;:::-;:89;54994:133;;55138:26;55143:10;55155:8;55138:4;:26::i;:::-;55180:56;::::0;;55195:10:::3;55180:56:::0;;-1:-1:-1;;;;;55180:56:0;::::3;;::::0;::::3;::::0;;;;;;;;;;;;;;;::::3;::::0;;;;;;;::::3;49685:1;;;49715:4:::2;49697:8;49706:5;49697:15;;;;;;47474:263:::0;1211:6;;-1:-1:-1;;;;;1211:6:0;1221:10;1211:20;1203:65;;;;;-1:-1:-1;;;1203:65:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1203:65:0;;;;;;;;;;;;;;;47608:16:::1;:58:::0;;::::1;47677:52:::0;;::::1;47608:58;47677:52;-1:-1:-1::0;;47608:58:0;;;::::1;-1:-1:-1::0;;47608:58:0;;::::1;;47677:52:::0;;;::::1;;::::0;;47474:263::o;36164:243::-;36341:6;:18;36361:14;;36377:21;;-1:-1:-1;;;;;36377:21:0;36164:243;;;:::o;47871:521::-;1211:6;;-1:-1:-1;;;;;1211:6:0;1221:10;1211:20;1203:65;;;;;-1:-1:-1;;;1203:65:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1203:65:0;;;;;;;;;;;;;;;48132:4:::1;:11:::0;;-1:-1:-1;;;;;;48132:11:0;;::::1;-1:-1:-1::0;;;;;48132:11:0;;::::1;;::::0;;;48154:8:::1;:19:::0;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;48184:7:::1;:44:::0;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;48239:26:::1;:56:::0;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;48306:10;:26;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;:2:::1;48343:12:::0;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;48366:9;:18;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;47871:521::o;36895:161::-;-1:-1:-1;;;;;37031:17:0;36999:7;37031:17;;;:8;:17;;;;;;;36895:161::o;1639:148::-;1211:6;;-1:-1:-1;;;;;1211:6:0;1221:10;1211:20;1203:65;;;;;-1:-1:-1;;;1203:65:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1203:65:0;;;;;;;;;;;;;;;1746:1:::1;1730:6:::0;;1709:40:::1;::::0;-1:-1:-1;;;;;1730:6:0;;::::1;::::0;1709:40:::1;::::0;1746:1;;1709:40:::1;1777:1;1760:19:::0;;-1:-1:-1;;;;;;1760:19:0::1;::::0;;1639:148::o;57860:1461::-;58079:26;;;-1:-1:-1;;;58079:26:0;;-1:-1:-1;;;;;58079:24:0;;:26;;;;;;58035:7;;;;58079:24;;;;:26;;;;;;;;;;;;;;:24;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58079:26:0;;-1:-1:-1;58116:21:0;;58154:1127;58178:6;58174:1;:10;58154:1127;;;58231:26;;;-1:-1:-1;;;58231:26:0;;-1:-1:-1;;;;;58231:24:0;;:26;;;;;;58206:22;;58231:24;;;;:26;;;;;;;;;;;;;;;:24;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58231:26:0;;-1:-1:-1;58272:20:0;58295:35;58231:26;58314:15;58295:18;:35::i;:::-;58272:58;;58347:18;58368:22;:14;:20;:22::i;:::-;58347:43;;58405:16;58424:20;:12;:18;:20::i;:::-;58405:39;;58461:15;58532:1;58517:12;:16;:31;;58547:1;58517:31;;;58536:8;58517:31;58503:46;;;-1:-1:-1;58585:22:0;;;58695:15;58691:43;;58719:15;58712:22;;;;;;;;;;;;;58691:43;58766:1;58753:10;:14;58749:256;;;58868:1;58850:15;:19;58834:35;;58749:256;;;58970:15;58988:1;58970:19;58954:35;;58749:256;59111:13;59089:1;59056:29;;;59055:35;59054:70;59019:105;;59186:14;59168:15;:32;:101;;59254:15;59168:101;;;59220:14;59168:101;59150:119;-1:-1:-1;;58186:3:0;;;;;-1:-1:-1;58154:1127:0;;-1:-1:-1;;;;58154:1127:0;;;59298:15;59291:22;;;;57860:1461;;;;;;;:::o;35786:24::-;;;;;;;-1:-1:-1;;;;;35786:24:0;;:::o;47745:118::-;47822:16;:33;;;;;;;47745:118::o;35525:23::-;;;-1:-1:-1;;;;;35525:23:0;;:::o;999:79::-;1037:7;1064:6;-1:-1:-1;;;;;1064:6:0;999:79;:::o;36599:85::-;36664:12;;;;;;;;;;;;-1:-1:-1;;;36664:12:0;;;;36599:85;:::o;48549:45::-;;;;;;;;;;;;;;;:::o;37064:199::-;37171:4;37193:40;37203:10;37215:9;37226:6;37193:9;:40::i;38750:182::-;38845:8;;-1:-1:-1;;;;;38845:8:0;38831:10;:22;38823:68;;;;-1:-1:-1;;;38823:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38902:22;38907:9;38918:5;38902:4;:22::i;:::-;38750:182;;:::o;37271:186::-;-1:-1:-1;;;;;37422:18:0;;;37390:7;37422:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;37271:186::o;48601:43::-;;;;;;;;;;;;;;;:::o;48651:46::-;;;;;;;;;;;;;;;:::o;61428:208::-;48802:8;;-1:-1:-1;;;;;48802:8:0;48788:10;:22;48780:31;;;;;;-1:-1:-1;;;;;61560:18:0;;::::1;;::::0;;;:11:::1;:18;::::0;;;;;;;:26;;;::::1;;-1:-1:-1::0;;61560:26:0;;::::1;;::::0;;61597:13:::1;:20:::0;;;;;:31;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;61428:208::o;1942:244::-;1211:6;;-1:-1:-1;;;;;1211:6:0;1221:10;1211:20;1203:65;;;;;-1:-1:-1;;;1203:65:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1203:65:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;2031:22:0;::::1;2023:73;;;;-1:-1:-1::0;;;2023:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2133:6;::::0;;2112:38:::1;::::0;-1:-1:-1;;;;;2112:38:0;;::::1;::::0;2133:6;::::1;::::0;2112:38:::1;::::0;::::1;2161:6;:17:::0;;-1:-1:-1;;;;;;2161:17:0::1;-1:-1:-1::0;;;;;2161:17:0;;;::::1;::::0;;;::::1;::::0;;1942:244::o;50746:2636::-;51038:12;50947:10;49174:9;:13;49170:266;;49244:4;;-1:-1:-1;;;;;49230:18:0;;;49244:4;;49230:18;49204:121;;;;-1:-1:-1;;;49204:121:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49340:11;:27;;-1:-1:-1;;;;;;49340:27:0;49362:4;49340:27;;;49170:266;;;49400:11;:24;;-1:-1:-1;;;;;;49400:24:0;49414:10;49400:24;;;49170:266;48926:10:::1;48911:26;::::0;;;:14:::1;:26;::::0;;;;;50983:10;;48911:26:::1;;::::0;:65:::1;;-1:-1:-1::0;;;;;;48958:18:0;::::1;;::::0;;;:11:::1;:18;::::0;;;;;::::1;;48911:65;:124;;;-1:-1:-1::0;;;;;;48998:19:0;::::1;::::0;;::::1;::::0;:36:::1;;-1:-1:-1::0;49030:4:0::1;::::0;-1:-1:-1;;;;;49021:13:0;;::::1;49030:4:::0;::::1;49021:13;48998:36;48889:197;;;::::0;;-1:-1:-1;;;48889:197:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;48889:197:0;;;;;;;;;;;;;::::1;;49586:8:::2;:15:::0;51009:9:::2;::::0;;;49586:15:::2;;49578:62;;;;-1:-1:-1::0;;;49578:62:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49669:5;49651:8;49660:5;49651:15;;;;;;;;;;;;;;;;:23;;;;;;;;;;;;;;;;;;51068:27:::3;51098:10;-1:-1:-1::0;;;;;51098:23:0::3;;;;;:25;;;;;;;;;;;;;-1:-1:-1::0;;;;;51098:25:0::3;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;::::0;::::3;;-1:-1:-1::0;51098:25:0;51152:4:::3;::::0;51098:25;;-1:-1:-1;;;;;;51138:18:0;;::::3;51152:4:::0;::::3;51138:18;51134:492;;;51184:4;::::0;51177:34:::3;::::0;;-1:-1:-1;;;51177:34:0;;51200:10:::3;51177:34;::::0;::::3;::::0;;;51215:11;;-1:-1:-1;;;;;51184:4:0::3;::::0;51177:22:::3;::::0;:34;;;;;::::3;::::0;;;;;;;;51184:4;51177:34;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;::::0;::::3;;-1:-1:-1::0;51177:34:0;:49:::3;51173:362;;51247:4;::::0;:40:::3;::::0;;-1:-1:-1;;;51247:40:0;;-1:-1:-1;;;;;51247:4:0;;::::3;:40;::::0;::::3;::::0;51263:10:::3;51247:40:::0;;;;;;;;;;;:15:::3;::::0;::::3;::::0;:40;;;;;:4:::3;::::0;:40;;;;;;;:15;:40;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;51173:362;;;51371:11;51358:9;:24;51328:131;;;;-1:-1:-1::0;;;51328:131:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51486:4;;;;;;;;;-1:-1:-1::0;;;;;51486:4:0::3;-1:-1:-1::0;;;;;51478:21:0::3;;51507:9;51478:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;51173:362;51134:492;;;51589:11;::::0;51567:47:::3;::::0;;-1:-1:-1;;;51567:47:0;;-1:-1:-1;;;;;51567:21:0;;::::3;:47;::::0;::::3;::::0;51589:11;;::::3;51567:47:::0;;;;;;;;;;;:21:::3;::::0;::::3;::::0;:47;;;;;-1:-1:-1;;51567:47:0;;;;;;;:21;:47;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;51134:492;51638:22;51676:51;51692:34;51702:10;51714:11;51692:9;:34::i;:::-;51676:11:::0;;:15:::3;:51::i;:::-;51769:26;::::0;;-1:-1:-1;;;51769:26:0;;-1:-1:-1;;;;;51769:24:0;::::3;:26;::::0;::::3;::::0;;;51638:89;;-1:-1:-1;51738:28:0::3;::::0;51769:24:::3;::::0;::::3;::::0;:26;;;;;::::3;::::0;;;;;;;;:24;:26;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;::::0;::::3;;-1:-1:-1::0;51769:26:0;51896:16:::3;:33:::0;51769:26;;-1:-1:-1;51896:33:0::3;::::0;::::3;;;51828:47;51769:26:::0;51828:21:::3;:12:::0;51845:3:::3;51828:16;:21::i;:47::-;:101;;51806:192;;;;-1:-1:-1::0;;;51806:192:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52009:25;52037:39;:19:::0;52061:14;52037:23:::3;:39::i;:::-;52009:67:::0;-1:-1:-1;52087:26:0::3;52116:38;:20:::0;52141:12;52116:24:::3;:38::i;:::-;52420:16;:36:::0;52087:67;;-1:-1:-1;52358:18:0::3;::::0;52396:106:::3;::::0;52420:36:::3;;52397:59:::0;;::::3;52484:17:::0;52396:87:::3;:106::i;:::-;52579:16;:36:::0;52358:144;;-1:-1:-1;52517:19:0::3;::::0;52556:108:::3;::::0;52579:36:::3;;52557:58:::0;;::::3;52643:20:::0;52556:86:::3;:108::i;:::-;52517:147:::0;-1:-1:-1;52707:15:0;;;::::3;::::0;:44:::3;;;52740:11;52726:10;:25;52707:44;52681:131;;;::::0;;-1:-1:-1;;;52681:131:0;;::::3;;::::0;::::3;::::0;::::3;::::0;;;;::::3;::::0;;;;;;;;;;;;;::::3;;49685:1;;48536:4;52858:18;:35;;52836:109;;;::::0;;-1:-1:-1;;;52836:109:0;;::::3;;::::0;::::3;::::0;::::3;::::0;;;;-1:-1:-1;;;52836:109:0;;;;;;;;;;;;;::::3;;52977:4;::::0;-1:-1:-1;;;;;52962:19:0;;::::3;52977:4:::0;::::3;52962:19;52958:230;;;53056:4;::::0;53048:46:::3;::::0;;-1:-1:-1;;;53048:46:0;;53023:10:::3;53048:46;::::0;::::3;::::0;;;;;;;;;;;53023:10;;-1:-1:-1;;;;;53056:4:0::3;::::0;53048:24:::3;::::0;:46;;;;;52998:22:::3;::::0;53048:46;;;;;;;;52998:22;53056:4;53048:46;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;52958:230;;;;53127:49;::::0;;-1:-1:-1;;;53127:49:0;;-1:-1:-1;;;;;53127:23:0;::::3;:49;::::0;::::3;::::0;53151:10:::3;53127:49:::0;;;;;;;;;;;;:23:::3;::::0;::::3;::::0;:49;;;;;-1:-1:-1;;53127:49:0;;;;;;;:23;:49;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;52958:230;53205:144;53224:10;53249;53274:11;53300;53326:12;53205:144;;;;-1:-1:-1::0;;;;;53205:144:0::3;;;;;;-1:-1:-1::0;;;;;53205:144:0::3;;;;;;-1:-1:-1::0;;;;;53205:144:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53370:4;53360:14;;49685:1;;;;;49715:4:::2;49697:8;49706:5;49697:15;;;;;;;;;;;;;;;;:22;;;;;;;;;;;;;;;;;;49097:1;;49446::::1;50746:2636:::0;;;;;;;:::o;47161:31::-;;;-1:-1:-1;;;;;47161:31:0;;:::o;3035:181::-;3093:7;3125:5;;;3149:6;;;;3141:46;;;;;-1:-1:-1;;;3141:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;3207:1;3035:181;-1:-1:-1;;;3035:181:0:o;3938:192::-;4024:7;4060:12;4052:6;;;;4044:29;;;;-1:-1:-1;;;4044:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;4096:5:0;;;3938:192::o;3499:136::-;3557:7;3584:43;3588:1;3591;3584:43;;;;;;;;;;;;;;;;;:3;:43::i;4389:471::-;4447:7;4692:6;4688:47;;-1:-1:-1;4722:1:0;4715:8;;4688:47;4759:5;;;4763:1;4759;:5;:1;4783:5;;;;;:10;4775:56;;;;-1:-1:-1;;;4775:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5336:132;5394:7;5421:39;5425:1;5428;5421:39;;;;;;;;;;;;;;;;;:3;:39::i;43364:1073::-;43413:7;43445:1;43441;:5;43433:14;;;;;;43460:11;43499:1;43521:19;43515:25;;43511:91;;43564:2;43581:9;;;;43557;43511:91;43622:11;43616:2;:17;43612:83;;43657:2;43674:9;;;;43650;43612:83;43715:7;43709:2;:13;43705:79;;43746:2;43763:9;;;;43739;43705:79;43804:5;43798:2;:11;43794:75;;43833:1;43849:8;;;;43826;43794:75;43889:4;43883:2;:10;43879:74;;43917:1;43933:8;;;;43910;43879:74;43973:3;43967:2;:9;43963:73;;44000:1;44016:8;;;;43993;43963:73;44056:3;44050:2;:9;44046:23;;44068:1;44061:8;;;;44046:23;-1:-1:-1;;44131:8:0;;44144:2;44130:16;44192:3;:9;;;44170:32;;;44232:18;44213:191;44252:7;;44213:191;;44287:8;;;44328:3;44322:9;;;44385:7;;;44375:17;;;;;44353:3;:7;44346:14;;44269:1;44261:9;44213:191;;;-1:-1:-1;44423:6:0;;43364:1073;-1:-1:-1;;;;;43364:1073:0:o;38243:264::-;38327:96;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;38327:16:0;;-1:-1:-1;38327:16:0;;;:8;:16;;;;;;;;:96;;38362:5;;38327:20;:96::i;:::-;-1:-1:-1;;;;;38308:16:0;;;;;;:8;:16;;;;;:115;38449:12;;:23;;38466:5;38449:16;:23::i;:::-;38434:12;:38;38488:11;;;;;;;;;;;;;;;;;38243:264;;:::o;38940:380::-;-1:-1:-1;;;;;39076:19:0;;39068:68;;;;-1:-1:-1;;;39068:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;39155:21:0;;39147:68;;;;-1:-1:-1;;;39147:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;39228:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;39280:32;;;;;;;;;;;;;;;;;38940:380;;;:::o;39388:1051::-;-1:-1:-1;;;;;39542:20:0;;39520:110;;;;-1:-1:-1;;;39520:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;39663:23:0;;39641:111;;;;-1:-1:-1;;;39641:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39788:6;:18;39765:20;;39788:40;;39823:4;;39788:30;;39811:6;39788:22;:30::i;:40::-;39765:63;;39839:21;39863:36;39894:4;39863:26;39882:6;39863;:14;;;:18;;:26;;;;:::i;:36::-;39925:12;;39839:60;;-1:-1:-1;39925:31:0;;39839:60;39925:16;:31::i;:::-;39910:12;:46;39972:19;;;;;;;;;;;;;;;;;40047:21;;-1:-1:-1;;;;;40047:21:0;40038:31;;;;:8;:31;;;;;;:73;;40088:12;40038:35;:73::i;:::-;40013:21;;-1:-1:-1;;;;;40013:21:0;40004:31;;;;:8;:31;;;;;;;;;:107;;;;40143:110;;;;;;;;;;;;;;40178:6;;40143:110;;;;;;;-1:-1:-1;;;;;40143:16:0;;;;;;:8;:16;;;;;;;:110;:20;:110::i;:::-;-1:-1:-1;;;;;40124:16:0;;;;;;:8;:16;;;;;:129;40288:92;40326:43;40337:31;:12;40354:13;40337:16;:31::i;:::-;40326:6;;:10;:43::i;:::-;-1:-1:-1;;;;;40288:19:0;;;;;;:8;:19;;;;;;;:23;:92::i;:::-;-1:-1:-1;;;;;40266:19:0;;;;;;;:8;:19;;;;;;;;;:114;;;;40396:35;;;;;;;40266:19;;40396:35;;;;;;;;;;;;;39388:1051;;;;;:::o;42577:144::-;42629:6;42661:18;42656:1;:23;;42648:32;;;;;;-1:-1:-1;42710:2:0;42705:7;;42577:144::o;60815:605::-;60944:9;;60900:13;;-1:-1:-1;;;;;60935:18:0;;;60944:9;;60935:18;60931:482;;;60978:33;60991:5;60998:6;61006:4;60978:12;:33::i;:::-;60970:41;;60931:482;;;-1:-1:-1;;;;;61033:20:0;;;;;;:13;:20;;;;;;;;61029:384;;;61076:34;61089:5;61096:6;61104:5;61076:12;:34::i;61029:384::-;61139:2;:6;-1:-1:-1;;;;;61130:15:0;;;61139:6;;61130:15;61126:287;;;61170:14;;:36;;61201:4;;61170:26;;61189:6;61170:18;:26::i;:36::-;61239:10;;61221:36;;;-1:-1:-1;;;61221:36:0;;-1:-1:-1;;;;;61221:17:0;;;:36;;;;61239:10;;;61221:36;;;;;;;;;;;;;-1:-1:-1;61221:17:0;;;;:36;;;;;-1:-1:-1;;61221:36:0;;;;;;;;:17;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61126:287;;;61298:14;;:36;;61329:4;;61298:26;;61317:6;61298:18;:26::i;:36::-;61367:26;;61349:52;;;-1:-1:-1;;;61349:52:0;;-1:-1:-1;;;;;61349:17:0;;;:52;;;;61367:26;;;61349:52;;;;;;;;;;;;;-1:-1:-1;61349:17:0;;;;:52;;;;;-1:-1:-1;;61349:52:0;;;;;;;;:17;:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60815:605;;;;:::o;38515:227::-;-1:-1:-1;;;;;38605:19:0;;;;;;:8;:19;;;;;;:30;;38629:5;38605:23;:30::i;:::-;-1:-1:-1;;;;;38583:19:0;;;;;;:8;:19;;;;;:52;38661:12;;:23;;38678:5;38661:16;:23::i;:::-;38646:12;:38;38700:34;;;38705:10;38700:34;;-1:-1:-1;;;;;38700:34:0;;;;;;;;;;;;;;;;;;;;;;;38515:227;;:::o;5964:278::-;6050:7;6085:12;6078:5;6070:28;;;;-1:-1:-1;;;6070:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6109:9;6125:1;6121;:5;;;;;;;5964:278;-1:-1:-1;;;;;5964:278:0:o;40447:414::-;40551:7;40576:18;40597:36;40628:4;40597:26;40616:6;40597;:14;;;:18;;:26;;;;:::i;:36::-;40576:57;-1:-1:-1;40671:5:0;40688:136;;;;40718:38;;;-1:-1:-1;;;40718:38:0;;40738:4;40718:38;;;;;;;;;;;;-1:-1:-1;;;;;40718:11:0;;;;;:38;;;;;-1:-1:-1;;40718:38:0;;;;;;;-1:-1:-1;40718:11:0;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40688:136;;;40789:6;-1:-1:-1;;;;;40789:11:0;;40801:10;40789:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40688:136;-1:-1:-1;40843:10:0;40447:414;-1:-1:-1;;;;40447:414:0:o
Swarm Source
ipfs://2eae5d00a097c4cf4e518c6465785fb17c52e3c15f4e042422b3b658d94b9fc2
Loading...LoadingLoading...Loading
Loading...Loading
Loading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingOVERVIEW
Behodler is a liquidity protocol centered around an AMM powered by token bonding. Scarcity is the token issued by the bonding curves and acts as both a medium of exchange and a liquidity token.
Multichain Portfolio | 30 Chains
Chain Token Portfolio % Price Amount Value ETH Ether (ETH)60.88% $3,342.48 2.2474 $7,511.74 ETH 4.96% $0.999538 611.9365 $611.65 ETH 4.80% $11.05 53.5961 $592.18 ETH 4.13% $21.27 23.9774 $510 ETH 3.97% $0.12063 4,061.163 $489.9 ETH 3.64% $1,133.05 0.3961 $448.85 ETH 3.55% $0.021253 20,589.9467 $437.6 ETH 3.54% $1.14 383.5011 $436.62 ETH 3.39% $0.056195 7,445.7253 $418.41 ETH 3.22% $1,547.44 0.2564 $396.83 ETH 2.86% $0.089749 3,925.1964 $352.28 ETH 1.07% $0.240636 547.4504 $131.74 Loading...Loading[ Download: CSV Export ][ Download: CSV Export ]A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.
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 FullInlinerNonExpressionSplitArgumentEvaluationOrder (low-severity), MissingSideEffectsOnSelectorAccess (low-severity), AbiReencodingHeadOverflowWithStaticArrayCleanup (medium-severity), DirtyBytesArrayToStorage (low-severity), DataLocationChangeInInternalOverride (very low-severity), NestedCalldataArrayAbiReencodingSizeValidation (very low-severity), SignedImmutables (very low-severity), ABIDecodeTwoDimensionalArrayMemory (very low-severity), KeccakCaching (medium-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.