Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 13023606 | 1091 days ago | IN | 0 ETH | 0.08953589 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
FeeExtractAndDistribute_ETH
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-08-14 */ /** * Copyright 2017-2021, bZeroX, LLC <https://bzx.network/>. All Rights Reserved. * Licensed under the Apache License, Version 2.0. */ pragma solidity 0.6.12; pragma experimental ABIEncoderV2; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "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 Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } /** * @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, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @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) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @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) { 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, reverting 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) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * 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); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * 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); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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; } } /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } /// @title A proxy interface for The Protocol /// @author bZeroX /// @notice This is just an interface, not to be deployed itself. /// @dev This interface is to be used for the protocol interactions. interface IBZx { ////// Protocol ////// /// @dev adds or replaces existing proxy module /// @param target target proxy module address function replaceContract(address target) external; /// @dev updates all proxy modules addreses and function signatures. /// sigsArr and targetsArr should be of equal length /// @param sigsArr array of function signatures /// @param targetsArr array of target proxy module addresses function setTargets( string[] calldata sigsArr, address[] calldata targetsArr ) external; /// @dev returns protocol module address given a function signature /// @return module address function getTarget(string calldata sig) external view returns (address); ////// Protocol Settings ////// /// @dev sets price feed contract address. The contract on the addres should implement IPriceFeeds interface /// @param newContract module address for the IPriceFeeds implementation function setPriceFeedContract(address newContract) external; /// @dev sets swaps contract address. The contract on the addres should implement ISwapsImpl interface /// @param newContract module address for the ISwapsImpl implementation function setSwapsImplContract(address newContract) external; /// @dev sets loan pool with assets. Accepts two arrays of equal length /// @param pools array of address of pools /// @param assets array of addresses of assets function setLoanPool(address[] calldata pools, address[] calldata assets) external; /// @dev updates list of supported tokens, it can be use also to disable or enable particualr token /// @param addrs array of address of pools /// @param toggles array of addresses of assets /// @param withApprovals resets tokens to unlimited approval with the swaps integration (kyber, etc.) function setSupportedTokens( address[] calldata addrs, bool[] calldata toggles, bool withApprovals ) external; /// @dev sets lending fee with WEI_PERCENT_PRECISION /// @param newValue lending fee percent function setLendingFeePercent(uint256 newValue) external; /// @dev sets trading fee with WEI_PERCENT_PRECISION /// @param newValue trading fee percent function setTradingFeePercent(uint256 newValue) external; /// @dev sets borrowing fee with WEI_PERCENT_PRECISION /// @param newValue borrowing fee percent function setBorrowingFeePercent(uint256 newValue) external; /// @dev sets affiliate fee with WEI_PERCENT_PRECISION /// @param newValue affiliate fee percent function setAffiliateFeePercent(uint256 newValue) external; /// @dev sets liquidation inncetive percent per loan per token. This is the profit percent /// that liquidator gets in the process of liquidating. /// @param loanTokens array list of loan tokens /// @param collateralTokens array list of collateral tokens /// @param amounts array list of liquidation inncetive amount function setLiquidationIncentivePercent( address[] calldata loanTokens, address[] calldata collateralTokens, uint256[] calldata amounts ) external; /// @dev sets max swap rate slippage percent. /// @param newAmount max swap rate slippage percent. function setMaxDisagreement(uint256 newAmount) external; /// TODO function setSourceBufferPercent(uint256 newAmount) external; /// @dev sets maximum supported swap size in ETH /// @param newAmount max swap size in ETH. function setMaxSwapSize(uint256 newAmount) external; /// @dev sets fee controller address /// @param newController address of the new fees controller function setFeesController(address newController) external; /// @dev withdraws lending fees to receiver. Only can be called by feesController address /// @param tokens array of token addresses. /// @param receiver fees receiver address /// @return amounts array of amounts withdrawn function withdrawFees( address[] calldata tokens, address receiver, FeeClaimType feeType ) external returns (uint256[] memory amounts); /// @dev withdraw protocol token (BZRX) from vesting contract vBZRX /// @param receiver address of BZRX tokens claimed /// @param amount of BZRX token to be claimed. max is claimed if amount is greater than balance. /// @return rewardToken reward token address /// @return withdrawAmount amount function withdrawProtocolToken(address receiver, uint256 amount) external returns (address rewardToken, uint256 withdrawAmount); /// @dev depozit protocol token (BZRX) /// @param amount address of BZRX tokens to deposit function depositProtocolToken(uint256 amount) external; function grantRewards(address[] calldata users, uint256[] calldata amounts) external returns (uint256 totalAmount); // NOTE: this doesn't sanitize inputs -> inaccurate values may be returned if there are duplicates tokens input function queryFees(address[] calldata tokens, FeeClaimType feeType) external view returns (uint256[] memory amountsHeld, uint256[] memory amountsPaid); function priceFeeds() external view returns (address); function swapsImpl() external view returns (address); function logicTargets(bytes4) external view returns (address); function loans(bytes32) external view returns (Loan memory); function loanParams(bytes32) external view returns (LoanParams memory); // we don't use this yet // function lenderOrders(address, bytes32) external returns (Order memory); // function borrowerOrders(address, bytes32) external returns (Order memory); function delegatedManagers(bytes32, address) external view returns (bool); function lenderInterest(address, address) external view returns (LenderInterest memory); function loanInterest(bytes32) external view returns (LoanInterest memory); function feesController() external view returns (address); function lendingFeePercent() external view returns (uint256); function lendingFeeTokensHeld(address) external view returns (uint256); function lendingFeeTokensPaid(address) external view returns (uint256); function borrowingFeePercent() external view returns (uint256); function borrowingFeeTokensHeld(address) external view returns (uint256); function borrowingFeeTokensPaid(address) external view returns (uint256); function protocolTokenHeld() external view returns (uint256); function protocolTokenPaid() external view returns (uint256); function affiliateFeePercent() external view returns (uint256); function liquidationIncentivePercent(address, address) external view returns (uint256); function loanPoolToUnderlying(address) external view returns (address); function underlyingToLoanPool(address) external view returns (address); function supportedTokens(address) external view returns (bool); function maxDisagreement() external view returns (uint256); function sourceBufferPercent() external view returns (uint256); function maxSwapSize() external view returns (uint256); /// @dev get list of loan pools in the system. Ordering is not guaranteed /// @param start start index /// @param count number of pools to return /// @return loanPoolsList array of loan pools function getLoanPoolsList(uint256 start, uint256 count) external view returns (address[] memory loanPoolsList); /// @dev checks whether addreess is a loan pool address /// @return boolean function isLoanPool(address loanPool) external view returns (bool); ////// Loan Settings ////// /// @dev creates new loan param settings /// @param loanParamsList array of LoanParams /// @return loanParamsIdList array of loan ids created function setupLoanParams(LoanParams[] calldata loanParamsList) external returns (bytes32[] memory loanParamsIdList); /// @dev Deactivates LoanParams for future loans. Active loans using it are unaffected. /// @param loanParamsIdList array of loan ids function disableLoanParams(bytes32[] calldata loanParamsIdList) external; /// @dev gets array of LoanParams by given ids /// @param loanParamsIdList array of loan ids /// @return loanParamsList array of LoanParams function getLoanParams(bytes32[] calldata loanParamsIdList) external view returns (LoanParams[] memory loanParamsList); /// @dev Enumerates LoanParams in the system by owner /// @param owner of the loan params /// @param start number of loans to return /// @param count total number of the items /// @return loanParamsList array of LoanParams function getLoanParamsList( address owner, uint256 start, uint256 count ) external view returns (bytes32[] memory loanParamsList); /// @dev returns total loan principal for token address /// @param lender address /// @param loanToken address /// @return total principal of the loan function getTotalPrincipal(address lender, address loanToken) external view returns (uint256); ////// Loan Openings ////// /// @dev This is THE function that borrows or trades on the protocol /// @param loanParamsId id of the LoanParam created beforehand by setupLoanParams function /// @param loanId id of existing loan, if 0, start a new loan /// @param isTorqueLoan boolean whether it is toreque or non torque loan /// @param initialMargin in WEI_PERCENT_PRECISION /// @param sentAddresses array of size 4: /// lender: must match loan if loanId provided /// borrower: must match loan if loanId provided /// receiver: receiver of funds (address(0) assumes borrower address) /// manager: delegated manager of loan unless address(0) /// @param sentValues array of size 5: /// newRate: new loan interest rate /// newPrincipal: new loan size (borrowAmount + any borrowed interest) /// torqueInterest: new amount of interest to escrow for Torque loan (determines initial loan length) /// loanTokenReceived: total loanToken deposit (amount not sent to borrower in the case of Torque loans) /// collateralTokenReceived: total collateralToken deposit /// @param loanDataBytes required when sending ether /// @return principal of the loan and collateral amount function borrowOrTradeFromPool( bytes32 loanParamsId, bytes32 loanId, bool isTorqueLoan, uint256 initialMargin, address[4] calldata sentAddresses, uint256[5] calldata sentValues, bytes calldata loanDataBytes ) external payable returns (LoanOpenData memory); /// @dev sets/disables/enables the delegated manager for the loan /// @param loanId id of the loan /// @param delegated delegated manager address /// @param toggle boolean set enabled or disabled function setDelegatedManager( bytes32 loanId, address delegated, bool toggle ) external; /// @dev estimates margin exposure for simulated position /// @param loanToken address of the loan token /// @param collateralToken address of collateral token /// @param loanTokenSent amout of loan token sent /// @param collateralTokenSent amount of collateral token sent /// @param interestRate yearly interest rate /// @param newPrincipal principal amount of the loan /// @return estimated margin exposure amount function getEstimatedMarginExposure( address loanToken, address collateralToken, uint256 loanTokenSent, uint256 collateralTokenSent, uint256 interestRate, uint256 newPrincipal ) external view returns (uint256); /// @dev calculates required collateral for simulated position /// @param loanToken address of loan token /// @param collateralToken address of collateral token /// @param newPrincipal principal amount of the loan /// @param marginAmount margin amount of the loan /// @param isTorqueLoan boolean torque or non torque loan /// @return collateralAmountRequired amount required function getRequiredCollateral( address loanToken, address collateralToken, uint256 newPrincipal, uint256 marginAmount, bool isTorqueLoan ) external view returns (uint256 collateralAmountRequired); function getRequiredCollateralByParams( bytes32 loanParamsId, uint256 newPrincipal ) external view returns (uint256 collateralAmountRequired); /// @dev calculates borrow amount for simulated position /// @param loanToken address of loan token /// @param collateralToken address of collateral token /// @param collateralTokenAmount amount of collateral token sent /// @param marginAmount margin amount /// @param isTorqueLoan boolean torque or non torque loan /// @return borrowAmount possible borrow amount function getBorrowAmount( address loanToken, address collateralToken, uint256 collateralTokenAmount, uint256 marginAmount, bool isTorqueLoan ) external view returns (uint256 borrowAmount); function getBorrowAmountByParams( bytes32 loanParamsId, uint256 collateralTokenAmount ) external view returns (uint256 borrowAmount); ////// Loan Closings ////// /// @dev liquidates unhealty loans /// @param loanId id of the loan /// @param receiver address receiving liquidated loan collateral /// @param closeAmount amount to close denominated in loanToken /// @return loanCloseAmount amount of the collateral token of the loan /// @return seizedAmount sezied amount in the collateral token /// @return seizedToken loan token address function liquidate( bytes32 loanId, address receiver, uint256 closeAmount ) external payable returns ( uint256 loanCloseAmount, uint256 seizedAmount, address seizedToken ); /// @dev rollover loan /// @param loanId id of the loan /// @param loanDataBytes reserved for future use. function rollover(bytes32 loanId, bytes calldata loanDataBytes) external returns (address rebateToken, uint256 gasRebate); /// @dev close position with loan token deposit /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param depositAmount amount of loan token to deposit /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithDeposit( bytes32 loanId, address receiver, uint256 depositAmount // denominated in loanToken ) external payable returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); /// @dev close position with swap /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param swapAmount amount of loan token to swap /// @param returnTokenIsCollateral boolean whether to return tokens is collateral /// @param loanDataBytes reserved for future use /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithSwap( bytes32 loanId, address receiver, uint256 swapAmount, // denominated in collateralToken bool returnTokenIsCollateral, // true: withdraws collateralToken, false: withdraws loanToken bytes calldata loanDataBytes ) external returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); ////// Loan Closings With Gas Token ////// /// @dev liquidates unhealty loans by using Gas token /// @param loanId id of the loan /// @param receiver address receiving liquidated loan collateral /// @param gasTokenUser user address of the GAS token /// @param closeAmount amount to close denominated in loanToken /// @return loanCloseAmount loan close amount /// @return seizedAmount loan token withdraw amount /// @return seizedToken loan token address function liquidateWithGasToken( bytes32 loanId, address receiver, address gasTokenUser, uint256 closeAmount // denominated in loanToken ) external payable returns ( uint256 loanCloseAmount, uint256 seizedAmount, address seizedToken ); /// @dev rollover loan /// @param loanId id of the loan /// @param gasTokenUser user address of the GAS token function rolloverWithGasToken( bytes32 loanId, address gasTokenUser, bytes calldata /*loanDataBytes*/ ) external returns (address rebateToken, uint256 gasRebate); /// @dev close position with loan token deposit /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param gasTokenUser user address of the GAS token /// @param depositAmount amount of loan token to deposit denominated in loanToken /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithDepositWithGasToken( bytes32 loanId, address receiver, address gasTokenUser, uint256 depositAmount ) external payable returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); /// @dev close position with swap /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param gasTokenUser user address of the GAS token /// @param swapAmount amount of loan token to swap denominated in collateralToken /// @param returnTokenIsCollateral true: withdraws collateralToken, false: withdraws loanToken /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithSwapWithGasToken( bytes32 loanId, address receiver, address gasTokenUser, uint256 swapAmount, bool returnTokenIsCollateral, bytes calldata loanDataBytes ) external returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); ////// Loan Maintenance ////// /// @dev deposit collateral to existing loan /// @param loanId existing loan id /// @param depositAmount amount to deposit which must match msg.value if ether is sent function depositCollateral(bytes32 loanId, uint256 depositAmount) external payable; /// @dev withdraw collateral from existing loan /// @param loanId existing lona id /// @param receiver address of withdrawn tokens /// @param withdrawAmount amount to withdraw /// @return actualWithdrawAmount actual amount withdrawn function withdrawCollateral( bytes32 loanId, address receiver, uint256 withdrawAmount ) external returns (uint256 actualWithdrawAmount); /// @dev withdraw accrued interest rate for a loan given token address /// @param loanToken loan token address function withdrawAccruedInterest(address loanToken) external; /// @dev extends loan duration by depositing more collateral /// @param loanId id of the existing loan /// @param depositAmount amount to deposit /// @param useCollateral boolean whether to extend using collateral or deposit amount /// @return secondsExtended by that number of seconds loan duration was extended function extendLoanDuration( bytes32 loanId, uint256 depositAmount, bool useCollateral, bytes calldata // for future use /*loanDataBytes*/ ) external payable returns (uint256 secondsExtended); /// @dev reduces loan duration by withdrawing collateral /// @param loanId id of the existing loan /// @param receiver address to receive tokens /// @param withdrawAmount amount to withdraw /// @return secondsReduced by that number of seconds loan duration was extended function reduceLoanDuration( bytes32 loanId, address receiver, uint256 withdrawAmount ) external returns (uint256 secondsReduced); function setDepositAmount( bytes32 loanId, uint256 depositValueAsLoanToken, uint256 depositValueAsCollateralToken ) external; function claimRewards(address receiver) external returns (uint256 claimAmount); function transferLoan(bytes32 loanId, address newOwner) external; function rewardsBalanceOf(address user) external view returns (uint256 rewardsBalance); /// @dev Gets current lender interest data totals for all loans with a specific oracle and interest token /// @param lender The lender address /// @param loanToken The loan token address /// @return interestPaid The total amount of interest that has been paid to a lender so far /// @return interestPaidDate The date of the last interest pay out, or 0 if no interest has been withdrawn yet /// @return interestOwedPerDay The amount of interest the lender is earning per day /// @return interestUnPaid The total amount of interest the lender is owned and not yet withdrawn /// @return interestFeePercent The fee retained by the protocol before interest is paid to the lender /// @return principalTotal The total amount of outstading principal the lender has loaned function getLenderInterestData(address lender, address loanToken) external view returns ( uint256 interestPaid, uint256 interestPaidDate, uint256 interestOwedPerDay, uint256 interestUnPaid, uint256 interestFeePercent, uint256 principalTotal ); /// @dev Gets current interest data for a loan /// @param loanId A unique id representing the loan /// @return loanToken The loan token that interest is paid in /// @return interestOwedPerDay The amount of interest the borrower is paying per day /// @return interestDepositTotal The total amount of interest the borrower has deposited /// @return interestDepositRemaining The amount of deposited interest that is not yet owed to a lender function getLoanInterestData(bytes32 loanId) external view returns ( address loanToken, uint256 interestOwedPerDay, uint256 interestDepositTotal, uint256 interestDepositRemaining ); /// @dev gets list of loans of particular user address /// @param user address of the loans /// @param start of the index /// @param count number of loans to return /// @param loanType type of the loan: All(0), Margin(1), NonMargin(2) /// @param isLender whether to list lender loans or borrower loans /// @param unsafeOnly booleat if true return only unsafe loans that are open for liquidation /// @return loansData LoanReturnData array of loans function getUserLoans( address user, uint256 start, uint256 count, LoanType loanType, bool isLender, bool unsafeOnly ) external view returns (LoanReturnData[] memory loansData); function getUserLoansCount(address user, bool isLender) external view returns (uint256); /// @dev gets existing loan /// @param loanId id of existing loan /// @return loanData array of loans function getLoan(bytes32 loanId) external view returns (LoanReturnData memory loanData); /// @dev get current active loans in the system /// @param start of the index /// @param count number of loans to return /// @param unsafeOnly boolean if true return unsafe loan only (open for liquidation) function getActiveLoans( uint256 start, uint256 count, bool unsafeOnly ) external view returns (LoanReturnData[] memory loansData); /// @dev get current active loans in the system /// @param start of the index /// @param count number of loans to return /// @param unsafeOnly boolean if true return unsafe loan only (open for liquidation) /// @param isLiquidatable boolean if true return liquidatable loans only function getActiveLoansAdvanced( uint256 start, uint256 count, bool unsafeOnly, bool isLiquidatable ) external view returns (LoanReturnData[] memory loansData); function getActiveLoansCount() external view returns (uint256); ////// Swap External ////// /// @dev swap thru external integration /// @param sourceToken source token address /// @param destToken destintaion token address /// @param receiver address to receive tokens /// @param returnToSender TODO /// @param sourceTokenAmount source token amount /// @param requiredDestTokenAmount destination token amount /// @param swapData TODO /// @return destTokenAmountReceived destination token received /// @return sourceTokenAmountUsed source token amount used function swapExternal( address sourceToken, address destToken, address receiver, address returnToSender, uint256 sourceTokenAmount, uint256 requiredDestTokenAmount, bytes calldata swapData ) external payable returns ( uint256 destTokenAmountReceived, uint256 sourceTokenAmountUsed ); /// @dev swap thru external integration using GAS /// @param sourceToken source token address /// @param destToken destintaion token address /// @param receiver address to receive tokens /// @param returnToSender TODO /// @param gasTokenUser user address of the GAS token /// @param sourceTokenAmount source token amount /// @param requiredDestTokenAmount destination token amount /// @param swapData TODO /// @return destTokenAmountReceived destination token received /// @return sourceTokenAmountUsed source token amount used function swapExternalWithGasToken( address sourceToken, address destToken, address receiver, address returnToSender, address gasTokenUser, uint256 sourceTokenAmount, uint256 requiredDestTokenAmount, bytes calldata swapData ) external payable returns ( uint256 destTokenAmountReceived, uint256 sourceTokenAmountUsed ); /// @dev calculate simulated return of swap /// @param sourceToken source token address /// @param destToken destination token address /// @param sourceTokenAmount source token amount /// @return amoun denominated in destination token function getSwapExpectedReturn( address sourceToken, address destToken, uint256 sourceTokenAmount ) external view returns (uint256); function owner() external view returns (address); function transferOwnership(address newOwner) external; struct LoanParams { bytes32 id; bool active; address owner; address loanToken; address collateralToken; uint256 minInitialMargin; uint256 maintenanceMargin; uint256 maxLoanTerm; } struct LoanOpenData { bytes32 loanId; uint256 principal; uint256 collateral; } enum LoanType { All, Margin, NonMargin } struct LoanReturnData { bytes32 loanId; uint96 endTimestamp; address loanToken; address collateralToken; uint256 principal; uint256 collateral; uint256 interestOwedPerDay; uint256 interestDepositRemaining; uint256 startRate; uint256 startMargin; uint256 maintenanceMargin; uint256 currentMargin; uint256 maxLoanTerm; uint256 maxLiquidatable; uint256 maxSeizable; uint256 depositValueAsLoanToken; uint256 depositValueAsCollateralToken; } enum FeeClaimType { All, Lending, Trading, Borrowing } struct Loan { bytes32 id; // id of the loan bytes32 loanParamsId; // the linked loan params id bytes32 pendingTradesId; // the linked pending trades id uint256 principal; // total borrowed amount outstanding uint256 collateral; // total collateral escrowed for the loan uint256 startTimestamp; // loan start time uint256 endTimestamp; // for active loans, this is the expected loan end time, for in-active loans, is the actual (past) end time uint256 startMargin; // initial margin when the loan opened uint256 startRate; // reference rate when the loan opened for converting collateralToken to loanToken address borrower; // borrower of this loan address lender; // lender of this loan bool active; // if false, the loan has been fully closed } struct LenderInterest { uint256 principalTotal; // total borrowed amount outstanding of asset uint256 owedPerDay; // interest owed per day for all loans of asset uint256 owedTotal; // total interest owed for all loans of asset (assuming they go to full term) uint256 paidTotal; // total interest paid so far for asset uint256 updatedTimestamp; // last update } struct LoanInterest { uint256 owedPerDay; // interest owed per day for loan uint256 depositTotal; // total escrowed interest for loan uint256 updatedTimestamp; // last update } } interface IERC20Burnable is IERC20 { function burn(uint256 amount) external; } contract Upgradeable is Ownable { address public implementation; } interface IWeth { function deposit() external payable; function withdraw(uint256 wad) external; } interface IWethERC20 is IWeth, IERC20 {} interface IUniswapV2Router { // 0x38ed1739 function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline) external returns (uint256[] memory amounts); // 0x8803dbee function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline) external returns (uint256[] memory amounts); // 0x1f00ca74 function getAmountsIn( uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); // 0xd06ca61f function getAmountsOut( uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); } interface IMasterChefPartial { function addExternalReward( uint256 _amount) external; function addAltReward() external payable; event AddExternalReward( address indexed sender, uint256 indexed pid, uint256 amount ); event AddAltReward( address indexed sender, uint256 indexed pid, uint256 amount ); } interface IPriceFeeds { function queryRate( address sourceToken, address destToken) external view returns (uint256 rate, uint256 precision); function queryReturn( address sourceToken, address destToken, uint256 sourceAmount) external view returns (uint256 destAmount); } interface IStakingPartial { function pendingSushiRewards(address _user) external view returns (uint256); function getCurrentFeeTokens() external view returns (address[] memory); function maxUniswapDisagreement() external view returns (uint256); //Temporary, will remove it after migrationn function stakingRewards(address) external view returns (uint256); function isPaused() external view returns (bool); function fundsWallet() external view returns (address); function callerRewardDivisor() external view returns (uint256); function maxCurveDisagreement() external view returns (uint256); function rewardPercent() external view returns (uint256); function addRewards(uint256 newBZRX, uint256 newStableCoin) external; function stake( address[] calldata tokens, uint256[] calldata values ) external; function stake( address[] calldata tokens, uint256[] calldata values, bool claimSushi ) external; function unstake( address[] calldata tokens, uint256[] calldata values ) external; function unstake( address[] memory tokens, uint256[] memory values, bool claimSushi ) external; function earned(address account) external view returns ( uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned, uint256 bzrxRewardsVesting, uint256 stableCoinRewardsVesting ); function getVariableWeights() external view returns (uint256 vBZRXWeight, uint256 iBZRXWeight, uint256 LPTokenWeight); function balanceOfByAsset( address token, address account) external view returns (uint256 balance); function balanceOfByAssets( address account) external view returns ( uint256 bzrxBalance, uint256 iBZRXBalance, uint256 vBZRXBalance, uint256 LPTokenBalance, uint256 LPTokenBalanceOld ); function balanceOfStored( address account) external view returns (uint256 vestedBalance, uint256 vestingBalance); function totalSupplyStored() external view returns (uint256 supply); function vestedBalanceForAmount( uint256 tokenBalance, uint256 lastUpdate, uint256 vestingEndTime) external view returns (uint256 vested); function votingBalanceOf( address account, uint256 proposalId) external view returns (uint256 totalVotes); function votingBalanceOfNow( address account) external view returns (uint256 totalVotes); function _setProposalVals( address account, uint256 proposalId) external returns (uint256); function exit() external; function addAltRewards(address token, uint256 amount) external; function pendingAltRewards(address token, address _user) external view returns (uint256); } interface ICurve3Pool { function add_liquidity( uint256[3] calldata amounts, uint256 min_mint_amount) external; function get_virtual_price() external view returns (uint256); } contract FeeExtractAndDistribute_ETH is Upgradeable { using SafeMath for uint256; using SafeERC20 for IERC20; IStakingPartial public constant STAKING = IStakingPartial(0xe95Ebce2B02Ee07dEF5Ed6B53289801F7Fc137A4); address public constant BZRX = 0x56d811088235F11C8920698a204A5010a788f4b3; address public constant vBZRX = 0xB72B31907C1C95F3650b64b2469e08EdACeE5e8F; address public constant iBZRX = 0x18240BD9C07fA6156Ce3F3f61921cC82b2619157; address public constant LPToken = 0xa30911e072A0C88D55B5D0A0984B66b0D04569d0; // sushiswap address public constant LPTokenOld = 0xe26A220a341EAca116bDa64cF9D5638A935ae629; // balancer IERC20 public constant curve3Crv = IERC20(0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490); address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F; address public constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; address public constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7; address public constant SUSHI = 0x6B3595068778DD592e39A122f4f5a5cF09C90fE2; IUniswapV2Router public constant uniswapRouter = IUniswapV2Router(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F); // sushiswap ICurve3Pool public constant curve3pool = ICurve3Pool(0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7); IBZx public constant bZx = IBZx(0xD8Ee69652E4e4838f2531732a46d1f7F584F0b7f); mapping(address => address[]) public swapPaths; mapping(address => uint256) public stakingRewards; event ExtractAndDistribute(); event WithdrawFees( address indexed sender ); event DistributeFees( address indexed sender, uint256 bzrxRewards, uint256 stableCoinRewards ); event ConvertFees( address indexed sender, uint256 bzrxOutput, uint256 stableCoinOutput ); modifier onlyEOA() { require(msg.sender == tx.origin, "unauthorized"); _; } modifier checkPause() { require(!STAKING.isPaused() || msg.sender == owner(), "paused"); _; } // Fee Conversion Logic // function sweepFees() public // sweepFeesByAsset() does checkPause returns (uint256 bzrxRewards, uint256 crv3Rewards) { return sweepFeesByAsset(STAKING.getCurrentFeeTokens()); } function sweepFeesByAsset(address[] memory assets) public checkPause onlyEOA returns (uint256 bzrxRewards, uint256 crv3Rewards) { uint256[] memory amounts = _withdrawFees(assets); _convertFees(assets, amounts); (bzrxRewards, crv3Rewards) = _distributeFees(); } function _withdrawFees(address[] memory assets) internal returns (uint256[] memory) { uint256[] memory amounts = bZx.withdrawFees(assets, address(this), IBZx.FeeClaimType.All); for (uint256 i = 0; i < assets.length; i++) { stakingRewards[assets[i]] = stakingRewards[assets[i]].add(amounts[i]); } emit WithdrawFees( msg.sender ); return amounts; } function _convertFees( address[] memory assets, uint256[] memory amounts) internal returns (uint256 bzrxOutput, uint256 crv3Output) { require(assets.length == amounts.length, "count mismatch"); IPriceFeeds priceFeeds = IPriceFeeds(bZx.priceFeeds()); (uint256 bzrxRate,) = priceFeeds.queryRate( BZRX, WETH ); uint256 maxDisagreement = STAKING.maxUniswapDisagreement(); address asset; uint256 daiAmount; uint256 usdcAmount; uint256 usdtAmount; for (uint256 i = 0; i < assets.length; i++) { asset = assets[i]; if (asset == BZRX) { continue; } else if (asset == DAI) { daiAmount = daiAmount.add(amounts[i]); continue; } else if (asset == USDC) { usdcAmount = usdcAmount.add(amounts[i]); continue; } else if (asset == USDT) { usdtAmount = usdtAmount.add(amounts[i]); continue; } if (amounts[i] != 0) { bzrxOutput += _convertFeeWithUniswap(asset, amounts[i], priceFeeds, bzrxRate, maxDisagreement); } } if (bzrxOutput != 0) { stakingRewards[BZRX] = stakingRewards[BZRX].add(bzrxOutput); } if (daiAmount != 0 || usdcAmount != 0 || usdtAmount != 0) { crv3Output = _convertFeesWithCurve( daiAmount, usdcAmount, usdtAmount ); stakingRewards[address(curve3Crv)] = stakingRewards[address(curve3Crv)].add(crv3Output); } emit ConvertFees( msg.sender, bzrxOutput, crv3Output ); } function _distributeFees() internal returns (uint256 bzrxRewards, uint256 crv3Rewards) { bzrxRewards = stakingRewards[BZRX]; crv3Rewards = stakingRewards[address(curve3Crv)]; if (bzrxRewards != 0 || crv3Rewards != 0) { address _fundsWallet = STAKING.fundsWallet(); uint256 rewardAmount; uint256 callerReward; if (bzrxRewards != 0) { stakingRewards[BZRX] = 0; rewardAmount = bzrxRewards .mul(STAKING.rewardPercent()) .div(1e20); IERC20(BZRX).transfer( _fundsWallet, bzrxRewards - rewardAmount ); bzrxRewards = rewardAmount; callerReward = bzrxRewards / STAKING.callerRewardDivisor(); IERC20(BZRX).transfer( msg.sender, callerReward ); bzrxRewards = bzrxRewards .sub(callerReward); } if (crv3Rewards != 0) { stakingRewards[address(curve3Crv)] = 0; rewardAmount = crv3Rewards .mul(STAKING.rewardPercent()) .div(1e20); curve3Crv.transfer( _fundsWallet, crv3Rewards - rewardAmount ); crv3Rewards = rewardAmount; callerReward = crv3Rewards / STAKING.callerRewardDivisor(); curve3Crv.transfer( msg.sender, callerReward ); crv3Rewards = crv3Rewards .sub(callerReward); } STAKING.addRewards(bzrxRewards, crv3Rewards); } emit DistributeFees( msg.sender, bzrxRewards, crv3Rewards ); } function _convertFeeWithUniswap( address asset, uint256 amount, IPriceFeeds priceFeeds, uint256 bzrxRate, uint256 maxDisagreement) internal returns (uint256 returnAmount) { uint256 stakingReward = stakingRewards[asset]; if (stakingReward != 0) { if (amount > stakingReward) { amount = stakingReward; } stakingRewards[asset] = stakingReward.sub(amount); uint256[] memory amounts = uniswapRouter.swapExactTokensForTokens( amount, 1, // amountOutMin swapPaths[asset], address(this), block.timestamp ); returnAmount = amounts[amounts.length - 1]; // will revert if disagreement found _checkUniDisagreement( asset, amount, returnAmount, priceFeeds, bzrxRate, maxDisagreement ); } } function _convertFeesWithCurve( uint256 daiAmount, uint256 usdcAmount, uint256 usdtAmount) internal returns (uint256 returnAmount) { uint256[3] memory curveAmounts; uint256 curveTotal; uint256 stakingReward; if (daiAmount != 0) { stakingReward = stakingRewards[DAI]; if (stakingReward != 0) { if (daiAmount > stakingReward) { daiAmount = stakingReward; } stakingRewards[DAI] = stakingReward.sub(daiAmount); curveAmounts[0] = daiAmount; curveTotal = daiAmount; } } if (usdcAmount != 0) { stakingReward = stakingRewards[USDC]; if (stakingReward != 0) { if (usdcAmount > stakingReward) { usdcAmount = stakingReward; } stakingRewards[USDC] = stakingReward.sub(usdcAmount); curveAmounts[1] = usdcAmount; curveTotal = curveTotal.add(usdcAmount.mul(1e12)); // normalize to 18 decimals } } if (usdtAmount != 0) { stakingReward = stakingRewards[USDT]; if (stakingReward != 0) { if (usdtAmount > stakingReward) { usdtAmount = stakingReward; } stakingRewards[USDT] = stakingReward.sub(usdtAmount); curveAmounts[2] = usdtAmount; curveTotal = curveTotal.add(usdtAmount.mul(1e12)); // normalize to 18 decimals } } uint256 beforeBalance = curve3Crv.balanceOf(address(this)); curve3pool.add_liquidity(curveAmounts, 0); returnAmount = curve3Crv.balanceOf(address(this)) - beforeBalance; // will revert if disagreement found _checkCurveDisagreement( curveTotal, returnAmount, STAKING.maxCurveDisagreement() ); } function _checkUniDisagreement( address asset, uint256 assetAmount, uint256 bzrxAmount, IPriceFeeds priceFeeds, uint256 bzrxRate, uint256 maxDisagreement) internal view { (uint256 rate, uint256 precision) = priceFeeds.queryRate( asset, WETH ); rate = rate .mul(1e36) .div(precision) .div(bzrxRate); uint256 sourceToDestSwapRate = bzrxAmount .mul(1e18) .div(assetAmount); uint256 spreadValue = sourceToDestSwapRate > rate ? sourceToDestSwapRate - rate : rate - sourceToDestSwapRate; if (spreadValue != 0) { spreadValue = spreadValue .mul(1e20) .div(sourceToDestSwapRate); require( spreadValue <= maxDisagreement, "uniswap price disagreement" ); } } function _checkCurveDisagreement( uint256 sendAmount, // deposit tokens uint256 actualReturn, // returned lp token uint256 maxDisagreement) internal view { uint256 expectedReturn = sendAmount .mul(1e18) .div(curve3pool.get_virtual_price()); uint256 spreadValue = actualReturn > expectedReturn ? actualReturn - expectedReturn : expectedReturn - actualReturn; if (spreadValue != 0) { spreadValue = spreadValue .mul(1e20) .div(actualReturn); require( spreadValue <= maxDisagreement, "curve price disagreement" ); } } function setApprovals() external onlyOwner { IERC20(DAI).safeApprove(address(curve3pool), uint256(-1)); IERC20(USDC).safeApprove(address(curve3pool), uint256(-1)); IERC20(USDT).safeApprove(address(curve3pool), uint256(-1)); IERC20(BZRX).safeApprove(address(STAKING), uint256(-1)); curve3Crv.safeApprove(address(STAKING), uint256(-1)); } // path should start with the asset to swap and end with BZRX // only one path allowed per asset // ex: asset -> WETH -> BZRX function setPaths( address[][] calldata paths) external onlyOwner { address[] memory path; for (uint256 i = 0; i < paths.length; i++) { path = paths[i]; require(path.length >= 2 && path[0] != path[path.length - 1] && path[path.length - 1] == BZRX, "invalid path" ); // check that the path exists uint256[] memory amountsOut = uniswapRouter.getAmountsOut(1e10, path); require(amountsOut[amountsOut.length - 1] != 0, "path does not exist"); swapPaths[path[0]] = path; IERC20(path[0]).safeApprove(address(uniswapRouter), 0); IERC20(path[0]).safeApprove(address(uniswapRouter), uint256(-1)); } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"bzrxOutput","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableCoinOutput","type":"uint256"}],"name":"ConvertFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"bzrxRewards","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableCoinRewards","type":"uint256"}],"name":"DistributeFees","type":"event"},{"anonymous":false,"inputs":[],"name":"ExtractAndDistribute","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"WithdrawFees","type":"event"},{"inputs":[],"name":"BZRX","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAI","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LPToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LPTokenOld","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING","outputs":[{"internalType":"contract IStakingPartial","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUSHI","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDC","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bZx","outputs":[{"internalType":"contract IBZx","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curve3Crv","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curve3pool","outputs":[{"internalType":"contract ICurve3Pool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"iBZRX","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setApprovals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[][]","name":"paths","type":"address[][]"}],"name":"setPaths","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"swapPaths","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sweepFees","outputs":[{"internalType":"uint256","name":"bzrxRewards","type":"uint256"},{"internalType":"uint256","name":"crv3Rewards","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"}],"name":"sweepFeesByAsset","outputs":[{"internalType":"uint256","name":"bzrxRewards","type":"uint256"},{"internalType":"uint256","name":"crv3Rewards","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapRouter","outputs":[{"internalType":"contract IUniswapV2Router","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vBZRX","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50600061001b61006a565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35061006e565b3390565b612dfc806200007e6000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80638757b15b116100de578063ad5c464811610097578063db8bb3a111610071578063db8bb3a114610274578063e0bab4c414610287578063f2fde38b1461028f578063f30127a5146102a257610173565b8063ad5c46481461025c578063c54e44eb14610264578063d113b95c1461026c57610173565b80638757b15b1461022c57806389a302711461023457806389ffc7811461023c5780638da5cb5b1461024457806397610f301461024c578063ab560e101461025457610173565b80635c60da1b116101305780635c60da1b146101e35780635d727d04146101eb578063633e94701461020c578063715018a614610214578063735de9f71461021c578063802971a61461022457610173565b8063011cee361461017857806317a1d012146101965780633d0b00241461019e578063499d7f96146101a6578063547d0738146101c65780635877b3dd146101ce575b600080fd5b6101806102aa565b60405161018d919061274f565b60405180910390f35b6101806102c2565b6101806102da565b6101b96101b4366004612415565b6102f2565b60405161018d9190612c03565b610180610304565b6101e16101dc3660046125a2565b61031c565b005b610180610611565b6101fe6101f9366004612478565b610620565b60405161018d929190612c7f565b61018061072d565b6101e1610745565b6101806107ce565b6101806107e6565b6101e16107fe565b61018061093c565b610180610954565b61018061096c565b61018061097b565b61018061098d565b6101806109a5565b6101806109bd565b6101fe6109d5565b61018061028236600461244d565b610a66565b610180610a9b565b6101e161029d366004612415565b610ab3565b610180610b73565b73a30911e072a0c88d55b5d0a0984b66b0d04569d081565b73bebc44782c7db0a1a60cb6fe97d0b483032ff1c781565b73e26a220a341eaca116bda64cf9d5638a935ae62981565b60036020526000908152604090205481565b73b72b31907c1c95f3650b64b2469e08edacee5e8f81565b610324610b8b565b6001600160a01b031661033561096c565b6001600160a01b0316146103645760405162461bcd60e51b815260040161035b90612a73565b60405180910390fd5b606060005b8281101561060b5783838281811061037d57fe5b905060200281019061038f9190612c8d565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050825192945050506002118015906104125750816001835103815181106103e057fe5b60200260200101516001600160a01b0316826000815181106103fe57fe5b60200260200101516001600160a01b031614155b801561045a57507356d811088235f11c8920698a204a5010a788f4b36001600160a01b03168260018451038151811061044757fe5b60200260200101516001600160a01b0316145b6104765760405162461bcd60e51b815260040161035b906129e6565b60405163d06ca61f60e01b815260609073d9e1ce17f2641f24ae83637ab66a2cca9c378b9f9063d06ca61f906104b7906402540be40090879060040161280a565b60006040518083038186803b1580156104cf57600080fd5b505afa1580156104e3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261050b9190810190612611565b90508060018251038151811061051d57fe5b6020026020010151600014156105455760405162461bcd60e51b815260040161035b90612b29565b82600260008560008151811061055757fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000209080519060200190610592929190612368565b506105da73d9e1ce17f2641f24ae83637ab66a2cca9c378b9f6000856000815181106105ba57fe5b60200260200101516001600160a01b0316610b8f9092919063ffffffff16565b61060273d9e1ce17f2641f24ae83637ab66a2cca9c378b9f600019856000815181106105ba57fe5b50600101610369565b50505050565b6001546001600160a01b031681565b600080600080516020612d678339815191526001600160a01b031663b187bd266040518163ffffffff1660e01b815260040160206040518083038186803b15801561066a57600080fd5b505afa15801561067e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a29190612695565b15806106c657506106b161096c565b6001600160a01b0316336001600160a01b0316145b6106e25760405162461bcd60e51b815260040161035b90612b56565b3332146107015760405162461bcd60e51b815260040161035b90612a4d565b606061070c84610c8e565b90506107188482610dff565b50506107226112be565b909590945092505050565b73d8ee69652e4e4838f2531732a46d1f7f584f0b7f81565b61074d610b8b565b6001600160a01b031661075e61096c565b6001600160a01b0316146107845760405162461bcd60e51b815260040161035b90612a73565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b73d9e1ce17f2641f24ae83637ab66a2cca9c378b9f81565b7318240bd9c07fa6156ce3f3f61921cc82b261915781565b610806610b8b565b6001600160a01b031661081761096c565b6001600160a01b03161461083d5760405162461bcd60e51b815260040161035b90612a73565b610872736b175474e89094c44da98b954eedeac495271d0f73bebc44782c7db0a1a60cb6fe97d0b483032ff1c7600019610b8f565b6108a773a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873bebc44782c7db0a1a60cb6fe97d0b483032ff1c7600019610b8f565b6108dc73dac17f958d2ee523a2206206994597c13d831ec773bebc44782c7db0a1a60cb6fe97d0b483032ff1c7600019610b8f565b61090b7356d811088235f11c8920698a204a5010a788f4b3600080516020612d67833981519152600019610b8f565b61093a736c3f90f043a72fa612cbac8115ee7e52bde6e490600080516020612d67833981519152600019610b8f565b565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b736c3f90f043a72fa612cbac8115ee7e52bde6e49081565b6000546001600160a01b031690565b600080516020612d6783398151915281565b736b3595068778dd592e39a122f4f5a5cf09c90fe281565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b73dac17f958d2ee523a2206206994597c13d831ec781565b600080610a5e600080516020612d678339815191526001600160a01b031663d3d204316040518163ffffffff1660e01b815260040160006040518083038186803b158015610a2257600080fd5b505afa158015610a36573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526101f99190810190612515565b915091509091565b60026020528160005260406000208181548110610a7f57fe5b6000918252602090912001546001600160a01b03169150829050565b736b175474e89094c44da98b954eedeac495271d0f81565b610abb610b8b565b6001600160a01b0316610acc61096c565b6001600160a01b031614610af25760405162461bcd60e51b815260040161035b90612a73565b6001600160a01b038116610b185760405162461bcd60e51b815260040161035b90612856565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b7356d811088235f11c8920698a204a5010a788f4b381565b3390565b801580610c175750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90610bc5903090869060040161277c565b60206040518083038186803b158015610bdd57600080fd5b505afa158015610bf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1591906126b5565b155b610c335760405162461bcd60e51b815260040161035b90612b76565b610c898363095ea7b360e01b8484604051602401610c52929190612763565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611955565b505050565b604051633360d3df60e01b8152606090819073d8ee69652e4e4838f2531732a46d1f7f584f0b7f90633360d3df90610ccf9086903090600090600401612796565b600060405180830381600087803b158015610ce957600080fd5b505af1158015610cfd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d259190810190612611565b905060005b8351811015610dcd57610d91828281518110610d4257fe5b602002602001015160036000878581518110610d5a57fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020546119e490919063ffffffff16565b60036000868481518110610da157fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002055600101610d2a565b5060405133907fd3719f04262b628e1d01a6ed24707f542cda51f144b5271149c7d0419436d00c90600090a292915050565b6000808251845114610e235760405162461bcd60e51b815260040161035b9061290a565b600073d8ee69652e4e4838f2531732a46d1f7f584f0b7f6001600160a01b03166378d849ed6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e7257600080fd5b505afa158015610e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eaa9190612431565b90506000816001600160a01b03166329d5277c7356d811088235f11c8920698a204a5010a788f4b373c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26040518363ffffffff1660e01b8152600401610f0492919061277c565b604080518083038186803b158015610f1b57600080fd5b505afa158015610f2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5391906126cd565b5090506000600080516020612d678339815191526001600160a01b03166359d998056040518163ffffffff1660e01b815260040160206040518083038186803b158015610f9f57600080fd5b505afa158015610fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd791906126b5565b905060008060008060005b8b51811015611172578b8181518110610ff757fe5b602002602001015194507356d811088235f11c8920698a204a5010a788f4b36001600160a01b0316856001600160a01b031614156110345761116a565b6001600160a01b038516736b175474e89094c44da98b954eedeac495271d0f14156110865761107f8b828151811061106857fe5b6020026020010151856119e490919063ffffffff16565b935061116a565b6001600160a01b03851673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4814156110d8576110d18b82815181106110ba57fe5b6020026020010151846119e490919063ffffffff16565b925061116a565b6001600160a01b03851673dac17f958d2ee523a2206206994597c13d831ec7141561112a576111238b828151811061110c57fe5b6020026020010151836119e490919063ffffffff16565b915061116a565b8a818151811061113657fe5b602002602001015160001461116a57611165858c838151811061115557fe5b60200260200101518a8a8a611a12565b8a0199505b600101610fe2565b5088156111de577356d811088235f11c8920698a204a5010a788f4b36000526003602052600080516020612da7833981519152546111b0908a6119e4565b7356d811088235f11c8920698a204a5010a788f4b36000526003602052600080516020612da7833981519152555b821515806111eb57508115155b806111f557508015155b1561126d57611205838383611b39565b736c3f90f043a72fa612cbac8115ee7e52bde6e4906000526003602052600080516020612d878339815191525490985061123f90896119e4565b736c3f90f043a72fa612cbac8115ee7e52bde6e4906000526003602052600080516020612d87833981519152555b336001600160a01b03167f4532d391b3bfa0cfb0b4e8b6d8c2c972a12ddb43658ed59378f340da2082ee5e8a8a6040516112a8929190612c7f565b60405180910390a2505050505050509250929050565b6003602052600080516020612da783398151915254736c3f90f043a72fa612cbac8115ee7e52bde6e490600052600080516020612d87833981519152548115158061130857508015155b1561190e576000600080516020612d678339815191526001600160a01b0316632194f3a26040518163ffffffff1660e01b815260040160206040518083038186803b15801561135657600080fd5b505afa15801561136a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138e9190612431565b9050600080841561161f577356d811088235f11c8920698a204a5010a788f4b3600090815260036020908152600080516020612da7833981519152919091556040805163d030205160e01b815290516114669268056bc75e2d631000009261146092600080516020612d678339815191529263d03020519260048082019391829003018186803b15801561142157600080fd5b505afa158015611435573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145991906126b5565b8890611f8a565b90611fc4565b60405163a9059cbb60e01b81529092507356d811088235f11c8920698a204a5010a788f4b39063a9059cbb906114a4908690868a0390600401612763565b602060405180830381600087803b1580156114be57600080fd5b505af11580156114d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f69190612695565b50819450600080516020612d678339815191526001600160a01b03166302dd19d96040518163ffffffff1660e01b815260040160206040518083038186803b15801561154157600080fd5b505afa158015611555573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157991906126b5565b858161158157fe5b60405163a9059cbb60e01b815291900491507356d811088235f11c8920698a204a5010a788f4b39063a9059cbb906115bf9033908590600401612763565b602060405180830381600087803b1580156115d957600080fd5b505af11580156115ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116119190612695565b5061161c8582611ff6565b94505b83156118a557736c3f90f043a72fa612cbac8115ee7e52bde6e490600090815260036020908152600080516020612d87833981519152919091556040805163d030205160e01b815290516116ec9268056bc75e2d631000009261146092600080516020612d678339815191529263d03020519260048082019391829003018186803b1580156116ad57600080fd5b505afa1580156116c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116e591906126b5565b8790611f8a565b60405163a9059cbb60e01b8152909250736c3f90f043a72fa612cbac8115ee7e52bde6e4909063a9059cbb9061172a90869086890390600401612763565b602060405180830381600087803b15801561174457600080fd5b505af1158015611758573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177c9190612695565b50819350600080516020612d678339815191526001600160a01b03166302dd19d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156117c757600080fd5b505afa1580156117db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ff91906126b5565b848161180757fe5b60405163a9059cbb60e01b81529190049150736c3f90f043a72fa612cbac8115ee7e52bde6e4909063a9059cbb906118459033908590600401612763565b602060405180830381600087803b15801561185f57600080fd5b505af1158015611873573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118979190612695565b506118a28482611ff6565b93505b60405163fc41aa0960e01b8152600080516020612d678339815191529063fc41aa09906118d89088908890600401612c7f565b600060405180830381600087803b1580156118f257600080fd5b505af1158015611906573d6000803e3d6000fd5b505050505050505b336001600160a01b03167f0d01c94d0df28276fb43f8bfa77a79b387742823fa1189417aca8b82afff77018383604051611949929190612c7f565b60405180910390a29091565b60606119aa826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661201e9092919063ffffffff16565b805190915015610c8957808060200190518101906119c89190612695565b610c895760405162461bcd60e51b815260040161035b90612adf565b600082820183811015611a095760405162461bcd60e51b815260040161035b906128d3565b90505b92915050565b6001600160a01b0385166000908152600360205260408120548015611b2f5780861115611a3d578095505b611a478187611ff6565b6001600160a01b0388166000908152600360209081526040808320939093556002905281902090516338ed173960e01b815260609173d9e1ce17f2641f24ae83637ab66a2cca9c378b9f916338ed173991611aad918b9160019130904290600401612c0c565b600060405180830381600087803b158015611ac757600080fd5b505af1158015611adb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b039190810190612611565b905080600182510381518110611b1557fe5b60200260200101519250611b2d888885898989612037565b505b5095945050505050565b6000611b436123cd565b6000808615611bee5750736b175474e89094c44da98b954eedeac495271d0f60005260036020527f441e47f386d1abf8865df2cb7ba5c4249e128119a8946908f73d644d268dacef548015611bee5780871115611b9e578096505b611ba88188611ff6565b736b175474e89094c44da98b954eedeac495271d0f60005260036020527f441e47f386d1abf8865df2cb7ba5c4249e128119a8946908f73d644d268dacef558683528691505b8515611cb4575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860005260036020527f37c5eec85d84da1cf053e48828b531c27553684966639a8ba393ecfe725880fd548015611cb45780861115611c46578095505b611c508187611ff6565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860005260036020527f37c5eec85d84da1cf053e48828b531c27553684966639a8ba393ecfe725880fd55858360016020020152611cb1611caa8764e8d4a51000611f8a565b83906119e4565b91505b8415611d71575073dac17f958d2ee523a2206206994597c13d831ec760005260036020527f82a5f3f697c19feba90e97eb50cf7817270ec4e8adf5c43afb6668e726e6e671548015611d715780851115611d0c578094505b611d168186611ff6565b73dac17f958d2ee523a2206206994597c13d831ec760005260036020527f82a5f3f697c19feba90e97eb50cf7817270ec4e8adf5c43afb6668e726e6e6715560408301859052611d6e611caa8664e8d4a51000611f8a565b91505b6040516370a0823160e01b8152600090736c3f90f043a72fa612cbac8115ee7e52bde6e490906370a0823190611dab90309060040161274f565b60206040518083038186803b158015611dc357600080fd5b505afa158015611dd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dfb91906126b5565b604051634515cef360e01b815290915073bebc44782c7db0a1a60cb6fe97d0b483032ff1c790634515cef390611e389087906000906004016127d2565b600060405180830381600087803b158015611e5257600080fd5b505af1158015611e66573d6000803e3d6000fd5b50506040516370a0823160e01b8152839250736c3f90f043a72fa612cbac8115ee7e52bde6e49091506370a0823190611ea390309060040161274f565b60206040518083038186803b158015611ebb57600080fd5b505afa158015611ecf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef391906126b5565b039450611f7f8386600080516020612d678339815191526001600160a01b03166353a8f1ec6040518163ffffffff1660e01b815260040160206040518083038186803b158015611f4257600080fd5b505afa158015611f56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7a91906126b5565b61216d565b505050509392505050565b600082611f9957506000611a0c565b82820282848281611fa657fe5b0414611a095760405162461bcd60e51b815260040161035b90612a0c565b6000808211611fe55760405162461bcd60e51b815260040161035b906129af565b818381611fee57fe5b049392505050565b6000828211156120185760405162461bcd60e51b815260040161035b90612932565b50900390565b606061202d8484600085612268565b90505b9392505050565b600080846001600160a01b03166329d5277c8973c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26040518363ffffffff1660e01b815260040161207c92919061277c565b604080518083038186803b15801561209357600080fd5b505afa1580156120a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120cb91906126cd565b90925090506120ef846114608381866ec097ce7bc90715b34b9f1000000000611f8a565b915060006121098861146089670de0b6b3a7640000611f8a565b9050600083821161211c57818403612120565b8382035b905080156121615761213f826114608368056bc75e2d63100000611f8a565b9050848111156121615760405162461bcd60e51b815260040161035b90612bcc565b50505050505050505050565b600061220973bebc44782c7db0a1a60cb6fe97d0b483032ff1c76001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b1580156121bf57600080fd5b505afa1580156121d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f791906126b5565b61146086670de0b6b3a7640000611f8a565b9050600081841161221c57838203612220565b8184035b905080156122615761223f846114608368056bc75e2d63100000611f8a565b9050828111156122615760405162461bcd60e51b815260040161035b9061289c565b5050505050565b60608247101561228a5760405162461bcd60e51b815260040161035b90612969565b61229385612329565b6122af5760405162461bcd60e51b815260040161035b90612aa8565b60006060866001600160a01b031685876040516122cc9190612733565b60006040518083038185875af1925050503d8060008114612309576040519150601f19603f3d011682016040523d82523d6000602084013e61230e565b606091505b509150915061231e82828661232f565b979650505050505050565b3b151590565b6060831561233e575081612030565b82511561234e5782518084602001fd5b8160405162461bcd60e51b815260040161035b9190612823565b8280548282559060005260206000209081019282156123bd579160200282015b828111156123bd57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612388565b506123c99291506123eb565b5090565b60405180606001604052806003906020820280368337509192915050565b5b808211156123c95780546001600160a01b03191681556001016123ec565b8035611a0c81612d4e565b600060208284031215612426578081fd5b8135611a0981612d4e565b600060208284031215612442578081fd5b8151611a0981612d4e565b6000806040838503121561245f578081fd5b823561246a81612d4e565b946020939093013593505050565b6000602080838503121561248a578182fd5b823567ffffffffffffffff8111156124a0578283fd5b8301601f810185136124b0578283fd5b80356124c36124be82612d02565b612cdb565b81815283810190838501858402850186018910156124df578687fd5b8694505b83851015612509576124f5898261240a565b8352600194909401939185019185016124e3565b50979650505050505050565b60006020808385031215612527578182fd5b825167ffffffffffffffff81111561253d578283fd5b8301601f8101851361254d578283fd5b805161255b6124be82612d02565b8181528381019083850185840285018601891015612577578687fd5b8694505b8385101561250957805161258e81612d4e565b83526001949094019391850191850161257b565b600080602083850312156125b4578182fd5b823567ffffffffffffffff808211156125cb578384fd5b818501915085601f8301126125de578384fd5b8135818111156125ec578485fd5b86602080830285010111156125ff578485fd5b60209290920196919550909350505050565b60006020808385031215612623578182fd5b825167ffffffffffffffff811115612639578283fd5b8301601f81018513612649578283fd5b80516126576124be82612d02565b8181528381019083850185840285018601891015612673578687fd5b8694505b83851015612509578051835260019490940193918501918501612677565b6000602082840312156126a6578081fd5b81518015158114611a09578182fd5b6000602082840312156126c6578081fd5b5051919050565b600080604083850312156126df578182fd5b505080516020909101519092909150565b6000815180845260208085019450808401835b838110156127285781516001600160a01b031687529582019590820190600101612703565b509495945050505050565b60008251612745818460208701612d22565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6000606082526127a960608301866126f0565b6001600160a01b03851660208401529050600483106127c457fe5b826040830152949350505050565b60808101818460005b60038110156127fa5781518352602092830192909101906001016127db565b5050508260608301529392505050565b60008382526040602083015261202d60408301846126f0565b6000602082528251806020840152612842816040850160208701612d22565b601f01601f19169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526018908201527f63757276652070726963652064697361677265656d656e740000000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600e908201526d0c6deeadce840dad2e6dac2e8c6d60931b604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252600c908201526b0d2dcecc2d8d2c840e0c2e8d60a31b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252600c908201526b1d5b985d5d1a1bdc9a5e995960a21b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601390820152721c185d1a08191bd95cc81b9bdd08195e1a5cdd606a1b604082015260600190565b6020808252600690820152651c185d5cd95960d21b604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b6020808252601a908201527f756e69737761702070726963652064697361677265656d656e74000000000000604082015260600190565b90815260200190565b600060a082018783526020878185015260a0604085015281875480845260c0860191508885528285209350845b81811015612c5e5784546001600160a01b031683526001948501949284019201612c39565b50506001600160a01b03969096166060850152505050608001529392505050565b918252602082015260400190565b6000808335601e19843603018112612ca3578283fd5b83018035915067ffffffffffffffff821115612cbd578283fd5b6020908101925081023603821315612cd457600080fd5b9250929050565b60405181810167ffffffffffffffff81118282101715612cfa57600080fd5b604052919050565b600067ffffffffffffffff821115612d18578081fd5b5060209081020190565b60005b83811015612d3d578181015183820152602001612d25565b8381111561060b5750506000910152565b6001600160a01b0381168114612d6357600080fd5b5056fe000000000000000000000000e95ebce2b02ee07def5ed6b53289801f7fc137a4eac489d5fce2cac016ee12cfecd5eeb23412aa5d77cdb3e1d0fab0572adba7b226822d1429e81ba812c5218f96710c8923c00dbf3bebc27a2dcc389411621671a2646970667358221220309072ca0fbd312dd432286aa784eb9b19590f784ec864de8a350ab1a034cbc564736f6c634300060c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101735760003560e01c80638757b15b116100de578063ad5c464811610097578063db8bb3a111610071578063db8bb3a114610274578063e0bab4c414610287578063f2fde38b1461028f578063f30127a5146102a257610173565b8063ad5c46481461025c578063c54e44eb14610264578063d113b95c1461026c57610173565b80638757b15b1461022c57806389a302711461023457806389ffc7811461023c5780638da5cb5b1461024457806397610f301461024c578063ab560e101461025457610173565b80635c60da1b116101305780635c60da1b146101e35780635d727d04146101eb578063633e94701461020c578063715018a614610214578063735de9f71461021c578063802971a61461022457610173565b8063011cee361461017857806317a1d012146101965780633d0b00241461019e578063499d7f96146101a6578063547d0738146101c65780635877b3dd146101ce575b600080fd5b6101806102aa565b60405161018d919061274f565b60405180910390f35b6101806102c2565b6101806102da565b6101b96101b4366004612415565b6102f2565b60405161018d9190612c03565b610180610304565b6101e16101dc3660046125a2565b61031c565b005b610180610611565b6101fe6101f9366004612478565b610620565b60405161018d929190612c7f565b61018061072d565b6101e1610745565b6101806107ce565b6101806107e6565b6101e16107fe565b61018061093c565b610180610954565b61018061096c565b61018061097b565b61018061098d565b6101806109a5565b6101806109bd565b6101fe6109d5565b61018061028236600461244d565b610a66565b610180610a9b565b6101e161029d366004612415565b610ab3565b610180610b73565b73a30911e072a0c88d55b5d0a0984b66b0d04569d081565b73bebc44782c7db0a1a60cb6fe97d0b483032ff1c781565b73e26a220a341eaca116bda64cf9d5638a935ae62981565b60036020526000908152604090205481565b73b72b31907c1c95f3650b64b2469e08edacee5e8f81565b610324610b8b565b6001600160a01b031661033561096c565b6001600160a01b0316146103645760405162461bcd60e51b815260040161035b90612a73565b60405180910390fd5b606060005b8281101561060b5783838281811061037d57fe5b905060200281019061038f9190612c8d565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050825192945050506002118015906104125750816001835103815181106103e057fe5b60200260200101516001600160a01b0316826000815181106103fe57fe5b60200260200101516001600160a01b031614155b801561045a57507356d811088235f11c8920698a204a5010a788f4b36001600160a01b03168260018451038151811061044757fe5b60200260200101516001600160a01b0316145b6104765760405162461bcd60e51b815260040161035b906129e6565b60405163d06ca61f60e01b815260609073d9e1ce17f2641f24ae83637ab66a2cca9c378b9f9063d06ca61f906104b7906402540be40090879060040161280a565b60006040518083038186803b1580156104cf57600080fd5b505afa1580156104e3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261050b9190810190612611565b90508060018251038151811061051d57fe5b6020026020010151600014156105455760405162461bcd60e51b815260040161035b90612b29565b82600260008560008151811061055757fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000209080519060200190610592929190612368565b506105da73d9e1ce17f2641f24ae83637ab66a2cca9c378b9f6000856000815181106105ba57fe5b60200260200101516001600160a01b0316610b8f9092919063ffffffff16565b61060273d9e1ce17f2641f24ae83637ab66a2cca9c378b9f600019856000815181106105ba57fe5b50600101610369565b50505050565b6001546001600160a01b031681565b600080600080516020612d678339815191526001600160a01b031663b187bd266040518163ffffffff1660e01b815260040160206040518083038186803b15801561066a57600080fd5b505afa15801561067e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a29190612695565b15806106c657506106b161096c565b6001600160a01b0316336001600160a01b0316145b6106e25760405162461bcd60e51b815260040161035b90612b56565b3332146107015760405162461bcd60e51b815260040161035b90612a4d565b606061070c84610c8e565b90506107188482610dff565b50506107226112be565b909590945092505050565b73d8ee69652e4e4838f2531732a46d1f7f584f0b7f81565b61074d610b8b565b6001600160a01b031661075e61096c565b6001600160a01b0316146107845760405162461bcd60e51b815260040161035b90612a73565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b73d9e1ce17f2641f24ae83637ab66a2cca9c378b9f81565b7318240bd9c07fa6156ce3f3f61921cc82b261915781565b610806610b8b565b6001600160a01b031661081761096c565b6001600160a01b03161461083d5760405162461bcd60e51b815260040161035b90612a73565b610872736b175474e89094c44da98b954eedeac495271d0f73bebc44782c7db0a1a60cb6fe97d0b483032ff1c7600019610b8f565b6108a773a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873bebc44782c7db0a1a60cb6fe97d0b483032ff1c7600019610b8f565b6108dc73dac17f958d2ee523a2206206994597c13d831ec773bebc44782c7db0a1a60cb6fe97d0b483032ff1c7600019610b8f565b61090b7356d811088235f11c8920698a204a5010a788f4b3600080516020612d67833981519152600019610b8f565b61093a736c3f90f043a72fa612cbac8115ee7e52bde6e490600080516020612d67833981519152600019610b8f565b565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b736c3f90f043a72fa612cbac8115ee7e52bde6e49081565b6000546001600160a01b031690565b600080516020612d6783398151915281565b736b3595068778dd592e39a122f4f5a5cf09c90fe281565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b73dac17f958d2ee523a2206206994597c13d831ec781565b600080610a5e600080516020612d678339815191526001600160a01b031663d3d204316040518163ffffffff1660e01b815260040160006040518083038186803b158015610a2257600080fd5b505afa158015610a36573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526101f99190810190612515565b915091509091565b60026020528160005260406000208181548110610a7f57fe5b6000918252602090912001546001600160a01b03169150829050565b736b175474e89094c44da98b954eedeac495271d0f81565b610abb610b8b565b6001600160a01b0316610acc61096c565b6001600160a01b031614610af25760405162461bcd60e51b815260040161035b90612a73565b6001600160a01b038116610b185760405162461bcd60e51b815260040161035b90612856565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b7356d811088235f11c8920698a204a5010a788f4b381565b3390565b801580610c175750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90610bc5903090869060040161277c565b60206040518083038186803b158015610bdd57600080fd5b505afa158015610bf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1591906126b5565b155b610c335760405162461bcd60e51b815260040161035b90612b76565b610c898363095ea7b360e01b8484604051602401610c52929190612763565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611955565b505050565b604051633360d3df60e01b8152606090819073d8ee69652e4e4838f2531732a46d1f7f584f0b7f90633360d3df90610ccf9086903090600090600401612796565b600060405180830381600087803b158015610ce957600080fd5b505af1158015610cfd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d259190810190612611565b905060005b8351811015610dcd57610d91828281518110610d4257fe5b602002602001015160036000878581518110610d5a57fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020546119e490919063ffffffff16565b60036000868481518110610da157fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002055600101610d2a565b5060405133907fd3719f04262b628e1d01a6ed24707f542cda51f144b5271149c7d0419436d00c90600090a292915050565b6000808251845114610e235760405162461bcd60e51b815260040161035b9061290a565b600073d8ee69652e4e4838f2531732a46d1f7f584f0b7f6001600160a01b03166378d849ed6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e7257600080fd5b505afa158015610e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eaa9190612431565b90506000816001600160a01b03166329d5277c7356d811088235f11c8920698a204a5010a788f4b373c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26040518363ffffffff1660e01b8152600401610f0492919061277c565b604080518083038186803b158015610f1b57600080fd5b505afa158015610f2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5391906126cd565b5090506000600080516020612d678339815191526001600160a01b03166359d998056040518163ffffffff1660e01b815260040160206040518083038186803b158015610f9f57600080fd5b505afa158015610fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd791906126b5565b905060008060008060005b8b51811015611172578b8181518110610ff757fe5b602002602001015194507356d811088235f11c8920698a204a5010a788f4b36001600160a01b0316856001600160a01b031614156110345761116a565b6001600160a01b038516736b175474e89094c44da98b954eedeac495271d0f14156110865761107f8b828151811061106857fe5b6020026020010151856119e490919063ffffffff16565b935061116a565b6001600160a01b03851673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4814156110d8576110d18b82815181106110ba57fe5b6020026020010151846119e490919063ffffffff16565b925061116a565b6001600160a01b03851673dac17f958d2ee523a2206206994597c13d831ec7141561112a576111238b828151811061110c57fe5b6020026020010151836119e490919063ffffffff16565b915061116a565b8a818151811061113657fe5b602002602001015160001461116a57611165858c838151811061115557fe5b60200260200101518a8a8a611a12565b8a0199505b600101610fe2565b5088156111de577356d811088235f11c8920698a204a5010a788f4b36000526003602052600080516020612da7833981519152546111b0908a6119e4565b7356d811088235f11c8920698a204a5010a788f4b36000526003602052600080516020612da7833981519152555b821515806111eb57508115155b806111f557508015155b1561126d57611205838383611b39565b736c3f90f043a72fa612cbac8115ee7e52bde6e4906000526003602052600080516020612d878339815191525490985061123f90896119e4565b736c3f90f043a72fa612cbac8115ee7e52bde6e4906000526003602052600080516020612d87833981519152555b336001600160a01b03167f4532d391b3bfa0cfb0b4e8b6d8c2c972a12ddb43658ed59378f340da2082ee5e8a8a6040516112a8929190612c7f565b60405180910390a2505050505050509250929050565b6003602052600080516020612da783398151915254736c3f90f043a72fa612cbac8115ee7e52bde6e490600052600080516020612d87833981519152548115158061130857508015155b1561190e576000600080516020612d678339815191526001600160a01b0316632194f3a26040518163ffffffff1660e01b815260040160206040518083038186803b15801561135657600080fd5b505afa15801561136a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138e9190612431565b9050600080841561161f577356d811088235f11c8920698a204a5010a788f4b3600090815260036020908152600080516020612da7833981519152919091556040805163d030205160e01b815290516114669268056bc75e2d631000009261146092600080516020612d678339815191529263d03020519260048082019391829003018186803b15801561142157600080fd5b505afa158015611435573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145991906126b5565b8890611f8a565b90611fc4565b60405163a9059cbb60e01b81529092507356d811088235f11c8920698a204a5010a788f4b39063a9059cbb906114a4908690868a0390600401612763565b602060405180830381600087803b1580156114be57600080fd5b505af11580156114d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f69190612695565b50819450600080516020612d678339815191526001600160a01b03166302dd19d96040518163ffffffff1660e01b815260040160206040518083038186803b15801561154157600080fd5b505afa158015611555573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157991906126b5565b858161158157fe5b60405163a9059cbb60e01b815291900491507356d811088235f11c8920698a204a5010a788f4b39063a9059cbb906115bf9033908590600401612763565b602060405180830381600087803b1580156115d957600080fd5b505af11580156115ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116119190612695565b5061161c8582611ff6565b94505b83156118a557736c3f90f043a72fa612cbac8115ee7e52bde6e490600090815260036020908152600080516020612d87833981519152919091556040805163d030205160e01b815290516116ec9268056bc75e2d631000009261146092600080516020612d678339815191529263d03020519260048082019391829003018186803b1580156116ad57600080fd5b505afa1580156116c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116e591906126b5565b8790611f8a565b60405163a9059cbb60e01b8152909250736c3f90f043a72fa612cbac8115ee7e52bde6e4909063a9059cbb9061172a90869086890390600401612763565b602060405180830381600087803b15801561174457600080fd5b505af1158015611758573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177c9190612695565b50819350600080516020612d678339815191526001600160a01b03166302dd19d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156117c757600080fd5b505afa1580156117db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ff91906126b5565b848161180757fe5b60405163a9059cbb60e01b81529190049150736c3f90f043a72fa612cbac8115ee7e52bde6e4909063a9059cbb906118459033908590600401612763565b602060405180830381600087803b15801561185f57600080fd5b505af1158015611873573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118979190612695565b506118a28482611ff6565b93505b60405163fc41aa0960e01b8152600080516020612d678339815191529063fc41aa09906118d89088908890600401612c7f565b600060405180830381600087803b1580156118f257600080fd5b505af1158015611906573d6000803e3d6000fd5b505050505050505b336001600160a01b03167f0d01c94d0df28276fb43f8bfa77a79b387742823fa1189417aca8b82afff77018383604051611949929190612c7f565b60405180910390a29091565b60606119aa826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661201e9092919063ffffffff16565b805190915015610c8957808060200190518101906119c89190612695565b610c895760405162461bcd60e51b815260040161035b90612adf565b600082820183811015611a095760405162461bcd60e51b815260040161035b906128d3565b90505b92915050565b6001600160a01b0385166000908152600360205260408120548015611b2f5780861115611a3d578095505b611a478187611ff6565b6001600160a01b0388166000908152600360209081526040808320939093556002905281902090516338ed173960e01b815260609173d9e1ce17f2641f24ae83637ab66a2cca9c378b9f916338ed173991611aad918b9160019130904290600401612c0c565b600060405180830381600087803b158015611ac757600080fd5b505af1158015611adb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b039190810190612611565b905080600182510381518110611b1557fe5b60200260200101519250611b2d888885898989612037565b505b5095945050505050565b6000611b436123cd565b6000808615611bee5750736b175474e89094c44da98b954eedeac495271d0f60005260036020527f441e47f386d1abf8865df2cb7ba5c4249e128119a8946908f73d644d268dacef548015611bee5780871115611b9e578096505b611ba88188611ff6565b736b175474e89094c44da98b954eedeac495271d0f60005260036020527f441e47f386d1abf8865df2cb7ba5c4249e128119a8946908f73d644d268dacef558683528691505b8515611cb4575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860005260036020527f37c5eec85d84da1cf053e48828b531c27553684966639a8ba393ecfe725880fd548015611cb45780861115611c46578095505b611c508187611ff6565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860005260036020527f37c5eec85d84da1cf053e48828b531c27553684966639a8ba393ecfe725880fd55858360016020020152611cb1611caa8764e8d4a51000611f8a565b83906119e4565b91505b8415611d71575073dac17f958d2ee523a2206206994597c13d831ec760005260036020527f82a5f3f697c19feba90e97eb50cf7817270ec4e8adf5c43afb6668e726e6e671548015611d715780851115611d0c578094505b611d168186611ff6565b73dac17f958d2ee523a2206206994597c13d831ec760005260036020527f82a5f3f697c19feba90e97eb50cf7817270ec4e8adf5c43afb6668e726e6e6715560408301859052611d6e611caa8664e8d4a51000611f8a565b91505b6040516370a0823160e01b8152600090736c3f90f043a72fa612cbac8115ee7e52bde6e490906370a0823190611dab90309060040161274f565b60206040518083038186803b158015611dc357600080fd5b505afa158015611dd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dfb91906126b5565b604051634515cef360e01b815290915073bebc44782c7db0a1a60cb6fe97d0b483032ff1c790634515cef390611e389087906000906004016127d2565b600060405180830381600087803b158015611e5257600080fd5b505af1158015611e66573d6000803e3d6000fd5b50506040516370a0823160e01b8152839250736c3f90f043a72fa612cbac8115ee7e52bde6e49091506370a0823190611ea390309060040161274f565b60206040518083038186803b158015611ebb57600080fd5b505afa158015611ecf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef391906126b5565b039450611f7f8386600080516020612d678339815191526001600160a01b03166353a8f1ec6040518163ffffffff1660e01b815260040160206040518083038186803b158015611f4257600080fd5b505afa158015611f56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7a91906126b5565b61216d565b505050509392505050565b600082611f9957506000611a0c565b82820282848281611fa657fe5b0414611a095760405162461bcd60e51b815260040161035b90612a0c565b6000808211611fe55760405162461bcd60e51b815260040161035b906129af565b818381611fee57fe5b049392505050565b6000828211156120185760405162461bcd60e51b815260040161035b90612932565b50900390565b606061202d8484600085612268565b90505b9392505050565b600080846001600160a01b03166329d5277c8973c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26040518363ffffffff1660e01b815260040161207c92919061277c565b604080518083038186803b15801561209357600080fd5b505afa1580156120a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120cb91906126cd565b90925090506120ef846114608381866ec097ce7bc90715b34b9f1000000000611f8a565b915060006121098861146089670de0b6b3a7640000611f8a565b9050600083821161211c57818403612120565b8382035b905080156121615761213f826114608368056bc75e2d63100000611f8a565b9050848111156121615760405162461bcd60e51b815260040161035b90612bcc565b50505050505050505050565b600061220973bebc44782c7db0a1a60cb6fe97d0b483032ff1c76001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b1580156121bf57600080fd5b505afa1580156121d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f791906126b5565b61146086670de0b6b3a7640000611f8a565b9050600081841161221c57838203612220565b8184035b905080156122615761223f846114608368056bc75e2d63100000611f8a565b9050828111156122615760405162461bcd60e51b815260040161035b9061289c565b5050505050565b60608247101561228a5760405162461bcd60e51b815260040161035b90612969565b61229385612329565b6122af5760405162461bcd60e51b815260040161035b90612aa8565b60006060866001600160a01b031685876040516122cc9190612733565b60006040518083038185875af1925050503d8060008114612309576040519150601f19603f3d011682016040523d82523d6000602084013e61230e565b606091505b509150915061231e82828661232f565b979650505050505050565b3b151590565b6060831561233e575081612030565b82511561234e5782518084602001fd5b8160405162461bcd60e51b815260040161035b9190612823565b8280548282559060005260206000209081019282156123bd579160200282015b828111156123bd57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612388565b506123c99291506123eb565b5090565b60405180606001604052806003906020820280368337509192915050565b5b808211156123c95780546001600160a01b03191681556001016123ec565b8035611a0c81612d4e565b600060208284031215612426578081fd5b8135611a0981612d4e565b600060208284031215612442578081fd5b8151611a0981612d4e565b6000806040838503121561245f578081fd5b823561246a81612d4e565b946020939093013593505050565b6000602080838503121561248a578182fd5b823567ffffffffffffffff8111156124a0578283fd5b8301601f810185136124b0578283fd5b80356124c36124be82612d02565b612cdb565b81815283810190838501858402850186018910156124df578687fd5b8694505b83851015612509576124f5898261240a565b8352600194909401939185019185016124e3565b50979650505050505050565b60006020808385031215612527578182fd5b825167ffffffffffffffff81111561253d578283fd5b8301601f8101851361254d578283fd5b805161255b6124be82612d02565b8181528381019083850185840285018601891015612577578687fd5b8694505b8385101561250957805161258e81612d4e565b83526001949094019391850191850161257b565b600080602083850312156125b4578182fd5b823567ffffffffffffffff808211156125cb578384fd5b818501915085601f8301126125de578384fd5b8135818111156125ec578485fd5b86602080830285010111156125ff578485fd5b60209290920196919550909350505050565b60006020808385031215612623578182fd5b825167ffffffffffffffff811115612639578283fd5b8301601f81018513612649578283fd5b80516126576124be82612d02565b8181528381019083850185840285018601891015612673578687fd5b8694505b83851015612509578051835260019490940193918501918501612677565b6000602082840312156126a6578081fd5b81518015158114611a09578182fd5b6000602082840312156126c6578081fd5b5051919050565b600080604083850312156126df578182fd5b505080516020909101519092909150565b6000815180845260208085019450808401835b838110156127285781516001600160a01b031687529582019590820190600101612703565b509495945050505050565b60008251612745818460208701612d22565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6000606082526127a960608301866126f0565b6001600160a01b03851660208401529050600483106127c457fe5b826040830152949350505050565b60808101818460005b60038110156127fa5781518352602092830192909101906001016127db565b5050508260608301529392505050565b60008382526040602083015261202d60408301846126f0565b6000602082528251806020840152612842816040850160208701612d22565b601f01601f19169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526018908201527f63757276652070726963652064697361677265656d656e740000000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600e908201526d0c6deeadce840dad2e6dac2e8c6d60931b604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252600c908201526b0d2dcecc2d8d2c840e0c2e8d60a31b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252600c908201526b1d5b985d5d1a1bdc9a5e995960a21b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601390820152721c185d1a08191bd95cc81b9bdd08195e1a5cdd606a1b604082015260600190565b6020808252600690820152651c185d5cd95960d21b604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b6020808252601a908201527f756e69737761702070726963652064697361677265656d656e74000000000000604082015260600190565b90815260200190565b600060a082018783526020878185015260a0604085015281875480845260c0860191508885528285209350845b81811015612c5e5784546001600160a01b031683526001948501949284019201612c39565b50506001600160a01b03969096166060850152505050608001529392505050565b918252602082015260400190565b6000808335601e19843603018112612ca3578283fd5b83018035915067ffffffffffffffff821115612cbd578283fd5b6020908101925081023603821315612cd457600080fd5b9250929050565b60405181810167ffffffffffffffff81118282101715612cfa57600080fd5b604052919050565b600067ffffffffffffffff821115612d18578081fd5b5060209081020190565b60005b83811015612d3d578181015183820152602001612d25565b8381111561060b5750506000910152565b6001600160a01b0381168114612d6357600080fd5b5056fe000000000000000000000000e95ebce2b02ee07def5ed6b53289801f7fc137a4eac489d5fce2cac016ee12cfecd5eeb23412aa5d77cdb3e1d0fab0572adba7b226822d1429e81ba812c5218f96710c8923c00dbf3bebc27a2dcc389411621671a2646970667358221220309072ca0fbd312dd432286aa784eb9b19590f784ec864de8a350ab1a034cbc564736f6c634300060c0033
Deployed Bytecode Sourcemap
62345:13552:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62824:76;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63643:96;;;:::i;62920:79::-;;;:::i;63883:49::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;62662:74::-;;;:::i;75075:819::-;;;;;;:::i;:::-;;:::i;:::-;;56544:29;;;:::i;64808:333::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;63746:75::-;;;:::i;2775:148::-;;;:::i;63514:109::-;;;:::i;62743:74::-;;;:::i;74515:411::-;;;:::i;63271:73::-;;;:::i;63018:85::-;;;:::i;2124:87::-;;;:::i;62472:101::-;;;:::i;63431:74::-;;;:::i;63112:73::-;;;:::i;63351:::-;;;:::i;64578:222::-;;;:::i;63830:46::-;;;;;;:::i;:::-;;:::i;63192:72::-;;;:::i;3078:244::-;;;;;;:::i;:::-;;:::i;62582:73::-;;;:::i;62824:76::-;62858:42;62824:76;:::o;63643:96::-;63696:42;63643:96;:::o;62920:79::-;62957:42;62920:79;:::o;63883:49::-;;;;;;;;;;;;;:::o;62662:74::-;62694:42;62662:74;:::o;75075:819::-;2355:12;:10;:12::i;:::-;-1:-1:-1;;;;;2344:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2344:23:0;;2336:68;;;;-1:-1:-1;;;2336:68:0;;;;;;;:::i;:::-;;;;;;;;;75184:21:::1;75221:9;75216:671;75236:16:::0;;::::1;75216:671;;;75281:5;;75287:1;75281:8;;;;;;;;;;;;;;;;;;:::i;:::-;75274:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;75312:11:0;;75274:15;;-1:-1:-1;;;75327:1:0::1;-1:-1:-1::0;75312:16:0;::::1;::::0;:65:::1;;;75356:4;75375:1;75361:4;:11;:15;75356:21;;;;;;;;;;;;;;-1:-1:-1::0;;;;;75345:32:0::1;:4;75350:1;75345:7;;;;;;;;;;;;;;-1:-1:-1::0;;;;;75345:32:0::1;;;75312:65;:111;;;;;62613:42;-1:-1:-1::0;;;;;75394:29:0::1;:4;75413:1;75399:4;:11;:15;75394:21;;;;;;;;;;;;;;-1:-1:-1::0;;;;;75394:29:0::1;;75312:111;75304:167;;;;-1:-1:-1::0;;;75304:167:0::1;;;;;;;:::i;:::-;75561:39;::::0;-1:-1:-1;;;75561:39:0;;75531:27:::1;::::0;63580:42:::1;::::0;75561:27:::1;::::0;:39:::1;::::0;75589:4:::1;::::0;75595;;75561:39:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;75561:39:0::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;75531:69;;75623:10;75654:1;75634:10;:17;:21;75623:33;;;;;;;;;;;;;;75660:1;75623:38;;75615:70;;;;-1:-1:-1::0;;;75615:70:0::1;;;;;;;:::i;:::-;75723:4;75702:9;:18;75712:4;75717:1;75712:7;;;;;;;;;;;;;;-1:-1:-1::0;;;;;75702:18:0::1;-1:-1:-1::0;;;;;75702:18:0::1;;;;;;;;;;;;:25;;;;;;;;;;;;:::i;:::-;;75742:54;63580:42;75794:1;75749:4;75754:1;75749:7;;;;;;;;;;;;;;-1:-1:-1::0;;;;;75742:27:0::1;;;:54;;;;;:::i;:::-;75811:64;63580:42;-1:-1:-1::0;;75818:4:0::1;75823:1;75818:7;;;;;;;75811:64;-1:-1:-1::0;75254:3:0::1;;75216:671;;;;2415:1;75075:819:::0;;:::o;56544:29::-;;;-1:-1:-1;;;;;56544:29:0;;:::o;64808:333::-;64930:19;64951;-1:-1:-1;;;;;;;;;;;;;;;;64458:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64457:19;:44;;;;64494:7;:5;:7::i;:::-;-1:-1:-1;;;;;64480:21:0;:10;-1:-1:-1;;;;;64480:21:0;;64457:44;64449:63;;;;-1:-1:-1;;;64449:63:0;;;;;;;:::i;:::-;64348:10:::1;64362:9;64348:23;64340:48;;;;-1:-1:-1::0;;;64340:48:0::1;;;;;;;:::i;:::-;64988:24:::2;65015:21;65029:6;65015:13;:21::i;:::-;64988:48;;65047:29;65060:6;65068:7;65047:12;:29::i;:::-;;;65116:17;:15;:17::i;:::-;65087:46:::0;;;;-1:-1:-1;64808:333:0;-1:-1:-1;;;64808:333:0:o;63746:75::-;63778:42;63746:75;:::o;2775:148::-;2355:12;:10;:12::i;:::-;-1:-1:-1;;;;;2344:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2344:23:0;;2336:68;;;;-1:-1:-1;;;2336:68:0;;;;;;;:::i;:::-;2882:1:::1;2866:6:::0;;2845:40:::1;::::0;-1:-1:-1;;;;;2866:6:0;;::::1;::::0;2845:40:::1;::::0;2882:1;;2845:40:::1;2913:1;2896:19:::0;;-1:-1:-1;;;;;;2896:19:0::1;::::0;;2775:148::o;63514:109::-;63580:42;63514:109;:::o;62743:74::-;62775:42;62743:74;:::o;74515:411::-;2355:12;:10;:12::i;:::-;-1:-1:-1;;;;;2344:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2344:23:0;;2336:68;;;;-1:-1:-1;;;2336:68:0;;;;;;;:::i;:::-;74592:57:::1;63222:42;63696;-1:-1:-1::0;;74592:23:0::1;:57::i;:::-;74660:58;63302:42;63696;-1:-1:-1::0;;74660:24:0::1;:58::i;:::-;74729;63382:42;63696;-1:-1:-1::0;;74729:24:0::1;:58::i;:::-;74800:55;62613:42;-1:-1:-1::0;;;;;;;;;;;;;74800:24:0::1;:55::i;:::-;74866:52;63060:42;-1:-1:-1::0;;;;;;;;;;;;;74866:21:0::1;:52::i;:::-;74515:411::o:0;63271:73::-;63302:42;63271:73;:::o;63018:85::-;63060:42;63018:85;:::o;2124:87::-;2170:7;2197:6;-1:-1:-1;;;;;2197:6:0;2124:87;:::o;62472:101::-;-1:-1:-1;;;;;;;;;;;62472:101:0;:::o;63431:74::-;63463:42;63431:74;:::o;63112:73::-;63143:42;63112:73;:::o;63351:::-;63382:42;63351:73;:::o;64578:222::-;64680:19;64701;64745:47;-1:-1:-1;;;;;;;;;;;;;;;;64762:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;64762:29:0;;;;;;;;;;;;:::i;64745:47::-;64738:54;;;;64578:222;;:::o;63830:46::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63830:46:0;;-1:-1:-1;63830:46:0;;-1:-1:-1;63830:46:0:o;63192:72::-;63222:42;63192:72;:::o;3078:244::-;2355:12;:10;:12::i;:::-;-1:-1:-1;;;;;2344:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2344:23:0;;2336:68;;;;-1:-1:-1;;;2336:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;3167:22:0;::::1;3159:73;;;;-1:-1:-1::0;;;3159:73:0::1;;;;;;;:::i;:::-;3269:6;::::0;;3248:38:::1;::::0;-1:-1:-1;;;;;3248:38:0;;::::1;::::0;3269:6;::::1;::::0;3248:38:::1;::::0;::::1;3297:6;:17:::0;;-1:-1:-1;;;;;;3297:17:0::1;-1:-1:-1::0;;;;;3297:17:0;;;::::1;::::0;;;::::1;::::0;;3078:244::o;62582:73::-;62613:42;62582:73;:::o;753:106::-;841:10;753:106;:::o;22571:622::-;22941:10;;;22940:62;;-1:-1:-1;22957:39:0;;-1:-1:-1;;;22957:39:0;;-1:-1:-1;;;;;22957:15:0;;;;;:39;;22981:4;;22988:7;;22957:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;22940:62;22932:152;;;;-1:-1:-1;;;22932:152:0;;;;;;;:::i;:::-;23095:90;23115:5;23145:22;;;23169:7;23178:5;23122:62;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;23122:62:0;;;;;;;;;;;;;;-1:-1:-1;;;;;23122:62:0;-1:-1:-1;;;;;;23122:62:0;;;;;;;;;;23095:19;:90::i;:::-;22571:622;;;:::o;65149:460::-;65294:62;;-1:-1:-1;;;65294:62:0;;65233:16;;;;63778:42;;65294:16;;:62;;65311:6;;65327:4;;65334:21;;65294:62;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;65294:62:0;;;;;;;;;;;;:::i;:::-;65267:89;;65374:9;65369:140;65393:6;:13;65389:1;:17;65369:140;;;65456:41;65486:7;65494:1;65486:10;;;;;;;;;;;;;;65456:14;:25;65471:6;65478:1;65471:9;;;;;;;;;;;;;;-1:-1:-1;;;;;65456:25:0;-1:-1:-1;;;;;65456:25:0;;;;;;;;;;;;;:29;;:41;;;;:::i;:::-;65428:14;:25;65443:6;65450:1;65443:9;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;65428:25:0;;;;;;;;;;;-1:-1:-1;65428:25:0;:69;65408:3;;65369:140;;;-1:-1:-1;65526:48:0;;65553:10;;65526:48;;;;;65594:7;65149:460;-1:-1:-1;;65149:460:0:o;65617:1881::-;65745:18;65765;65826:7;:14;65809:6;:13;:31;65801:58;;;;-1:-1:-1;;;65801:58:0;;;;;;;:::i;:::-;65872:22;63778:42;-1:-1:-1;;;;;65909:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65872:54;;65938:16;65959:10;-1:-1:-1;;;;;65959:20:0;;62613:42;63143;65959:69;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65937:91;;;66039:23;-1:-1:-1;;;;;;;;;;;;;;;;66065:30:0;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66039:58;;66110:13;66134:17;66162:18;66191;66225:9;66220:705;66244:6;:13;66240:1;:17;66220:705;;;66287:6;66294:1;66287:9;;;;;;;;;;;;;;66279:17;;62613:42;-1:-1:-1;;;;;66315:13:0;:5;-1:-1:-1;;;;;66315:13:0;;66311:437;;;66349:8;;66311:437;-1:-1:-1;;;;;66383:12:0;;63222:42;66383:12;66379:369;;;66428:25;66442:7;66450:1;66442:10;;;;;;;;;;;;;;66428:9;:13;;:25;;;;:::i;:::-;66416:37;;66472:8;;66379:369;-1:-1:-1;;;;;66506:13:0;;63302:42;66506:13;66502:246;;;66553:26;66568:7;66576:1;66568:10;;;;;;;;;;;;;;66553;:14;;:26;;;;:::i;:::-;66540:39;;66598:8;;66502:246;-1:-1:-1;;;;;66632:13:0;;63382:42;66632:13;66628:120;;;66679:26;66694:7;66702:1;66694:10;;;;;;;;;;;;;;66679;:14;;:26;;;;:::i;:::-;66666:39;;66724:8;;66628:120;66768:7;66776:1;66768:10;;;;;;;;;;;;;;66782:1;66768:15;66764:150;;66818:80;66841:5;66848:7;66856:1;66848:10;;;;;;;;;;;;;;66860;66872:8;66882:15;66818:22;:80::i;:::-;66804:94;;;;66764:150;66259:3;;66220:705;;;-1:-1:-1;66939:15:0;;66935:107;;62613:42;66994:20;;:14;:20;;-1:-1:-1;;;;;;;;;;;66994:20:0;:36;;67019:10;66994:24;:36::i;:::-;62613:42;66971:20;;:14;:20;;-1:-1:-1;;;;;;;;;;;66971:59:0;66935:107;67058:14;;;;:33;;-1:-1:-1;67076:15:0;;;67058:33;:52;;;-1:-1:-1;67095:15:0;;;67058:52;67054:322;;;67140:122;67180:9;67208:10;67237;67140:21;:122::i;:::-;63060:42;67314:34;;:14;:34;;-1:-1:-1;;;;;;;;;;;67314:34:0;67127:135;;-1:-1:-1;67314:50:0;;67127:135;67314:38;:50::i;:::-;63060:42;67277:34;;:14;:34;;-1:-1:-1;;;;;;;;;;;67277:87:0;67054:322;67419:10;-1:-1:-1;;;;;67393:97:0;;67444:10;67469;67393:97;;;;;;;:::i;:::-;;;;;;;;65617:1881;;;;;;;;;;;;:::o;67506:2006::-;67641:14;:20;;-1:-1:-1;;;;;;;;;;;67641:20:0;63060:42;67569:19;67686:34;-1:-1:-1;;;;;;;;;;;67686:34:0;67735:16;;;;:36;;-1:-1:-1;67755:16:0;;;67735:36;67731:1654;;;67788:20;-1:-1:-1;;;;;;;;;;;;;;;;67811:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;67788:44;-1:-1:-1;67847:20:0;;67921:16;;67917:687;;62613:42;67981:1;67958:20;;;:14;:20;;;;-1:-1:-1;;;;;;;;;;;67958:24:0;;;;:20;68054:23;;-1:-1:-1;;;68054:23:0;;;;68016:94;;68105:4;;68016:62;;-1:-1:-1;;;;;;;;;;;62530:42:0;68054:21;;:23;;;;;;;;;;;62530:42;68054:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68016:11;;:37;:62::i;:::-;:88;;:94::i;:::-;68129:124;;-1:-1:-1;;;68129:124:0;;68001:109;;-1:-1:-1;62613:42:0;;68129:21;;:124;;68173:12;;68208:26;;;;68129:124;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;68286:12;68272:26;;-1:-1:-1;;;;;;;;;;;;;;;;68348:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68334:11;:43;;;;;68396:108;;-1:-1:-1;;;68396:108:0;;68334:43;;;;-1:-1:-1;62613:42:0;;68396:21;;:108;;68440:10;;68334:43;;68396:108;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;68537:51:0;:11;68575:12;68537:37;:51::i;:::-;68523:65;;67917:687;68622:16;;68618:697;;63060:42;68696:1;68659:34;;;:14;:34;;;;-1:-1:-1;;;;;;;;;;;68659:38:0;;;;:34;68771:23;;-1:-1:-1;;;68771:23:0;;;;68733:94;;68822:4;;68733:62;;-1:-1:-1;;;;;;;;;;;62530:42:0;68771:21;;:23;;;;;;;;;;;62530:42;68771:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68733:11;;:37;:62::i;:94::-;68846:121;;-1:-1:-1;;;68846:121:0;;68718:109;;-1:-1:-1;63060:42:0;;68846:18;;:121;;68887:12;;68922:26;;;;68846:121;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;69000:12;68986:26;;-1:-1:-1;;;;;;;;;;;;;;;;69062:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;69048:11;:43;;;;;69110:105;;-1:-1:-1;;;69110:105:0;;69048:43;;;;-1:-1:-1;63060:42:0;;69110:18;;:105;;69151:10;;69048:43;;69110:105;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;69248:51:0;:11;69286:12;69248:37;:51::i;:::-;69234:65;;68618:697;69329:44;;-1:-1:-1;;;69329:44:0;;-1:-1:-1;;;;;;;;;;;62530:42:0;69329:18;;:44;;69348:11;;69361;;69329:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67731:1654;;;;69431:10;-1:-1:-1;;;;;69402:102:0;;69456:11;69482;69402:102;;;;;;;:::i;:::-;;;;;;;;67506:2006;;:::o;24217:761::-;24641:23;24667:69;24695:4;24667:69;;;;;;;;;;;;;;;;;24675:5;-1:-1:-1;;;;;24667:27:0;;;:69;;;;;:::i;:::-;24751:17;;24641:95;;-1:-1:-1;24751:21:0;24747:224;;24893:10;24882:30;;;;;;;;;;;;:::i;:::-;24874:85;;;;-1:-1:-1;;;24874:85:0;;;;;;;:::i;16686:179::-;16744:7;16776:5;;;16800:6;;;;16792:46;;;;-1:-1:-1;;;16792:46:0;;;;;;;:::i;:::-;16856:1;-1:-1:-1;16686:179:0;;;;;:::o;69520:1103::-;-1:-1:-1;;;;;69794:21:0;;69732:20;69794:21;;;:14;:21;;;;;;69830:18;;69826:790;;69878:13;69869:6;:22;69865:85;;;69921:13;69912:22;;69865:85;69988:25;:13;70006:6;69988:17;:25::i;:::-;-1:-1:-1;;;;;69964:21:0;;;;;;:14;:21;;;;;;;;:49;;;;70175:9;:16;;;;;70057:215;;-1:-1:-1;;;70057:215:0;;70030:24;;63580:42;;70057:38;;:215;;70114:6;;70139:1;;70218:4;;70242:15;;70057:215;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;70057:215:0;;;;;;;;;;;;:::i;:::-;70030:242;;70304:7;70329:1;70312:7;:14;:18;70304:27;;;;;;;;;;;;;;70289:42;;70398:206;70438:5;70462:6;70487:12;70518:10;70547:8;70574:15;70398:21;:206::i;:::-;69826:790;;69520:1103;;;;;;;;:::o;70631:2065::-;70785:20;70823:30;;:::i;:::-;70864:18;;70931:14;;70927:409;;-1:-1:-1;63222:42:0;70978:19;;:14;:19;;;;71016:18;;71012:313;;71071:13;71059:9;:25;71055:99;;;71121:13;71109:25;;71055:99;71194:28;:13;71212:9;71194:17;:28::i;:::-;63222:42;71172:19;;:14;:19;;;:50;71241:27;;;71259:9;;-1:-1:-1;71012:313:0;71350:15;;71346:471;;-1:-1:-1;63302:42:0;71398:20;;:14;:20;;;;71437:18;;71433:373;;71493:13;71480:10;:26;71476:101;;;71544:13;71531:26;;71476:101;71618:29;:13;71636:10;71618:17;:29::i;:::-;63302:42;71595:20;;:14;:20;;;:52;71684:10;71666:12;71679:1;71666:15;;;:28;71726:36;71741:20;:10;71756:4;71741:14;:20::i;:::-;71726:10;;:14;:36::i;:::-;71713:49;;71433:373;71831:15;;71827:471;;-1:-1:-1;63382:42:0;71879:20;;:14;:20;;;;71918:18;;71914:373;;71974:13;71961:10;:26;71957:101;;;72025:13;72012:26;;71957:101;72099:29;:13;72117:10;72099:17;:29::i;:::-;63382:42;72076:20;;:14;:20;;;:52;72147:15;;;:28;;;72207:36;72222:20;72165:10;72237:4;72222:14;:20::i;72207:36::-;72194:49;;71914:373;72334:34;;-1:-1:-1;;;72334:34:0;;72310:21;;63060:42;;72334:19;;:34;;72362:4;;72334:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72379:41;;-1:-1:-1;;;72379:41:0;;72310:58;;-1:-1:-1;63696:42:0;;72379:24;;:41;;72404:12;;72418:1;;72379:41;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;72448:34:0;;-1:-1:-1;;;72448:34:0;;72485:13;;-1:-1:-1;63060:42:0;;-1:-1:-1;72448:19:0;;:34;;72476:4;;72448:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:50;72433:65;;72557:131;72595:10;72620:12;-1:-1:-1;;;;;;;;;;;;;;;;72647:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72557:23;:131::i;:::-;70631:2065;;;;;;;;;:::o;17565:220::-;17623:7;17647:6;17643:20;;-1:-1:-1;17662:1:0;17655:8;;17643:20;17686:5;;;17690:1;17686;:5;:1;17710:5;;;;;:10;17702:56;;;;-1:-1:-1;;;17702:56:0;;;;;;;:::i;18263:153::-;18321:7;18353:1;18349;:5;18341:44;;;;-1:-1:-1;;;18341:44:0;;;;;;;:::i;:::-;18407:1;18403;:5;;;;;;;18263:153;-1:-1:-1;;;18263:153:0:o;17148:158::-;17206:7;17239:1;17234;:6;;17226:49;;;;-1:-1:-1;;;17226:49:0;;;;;;;:::i;:::-;-1:-1:-1;17293:5:0;;;17148:158::o;9641:195::-;9744:12;9776:52;9798:6;9806:4;9812:1;9815:12;9776:21;:52::i;:::-;9769:59;;9641:195;;;;;;:::o;72704:1026::-;72962:12;72976:17;72997:10;-1:-1:-1;;;;;72997:20:0;;73032:5;63143:42;72997:70;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72961:106;;-1:-1:-1;72961:106:0;-1:-1:-1;73087:85:0;73163:8;73087:57;72961:106;73087:57;72961:106;73110:4;73087:22;:28::i;:85::-;73080:92;-1:-1:-1;73185:28:0;73216:65;73269:11;73216:34;:10;73245:4;73216:28;:34::i;:65::-;73185:96;;73294:19;73339:4;73316:20;:27;:113;;73409:20;73402:4;:27;73316:113;;;73382:4;73359:20;:27;73316:113;73294:135;-1:-1:-1;73446:16:0;;73442:281;;73493:83;73555:20;73493:39;:11;73527:4;73493:33;:39::i;:83::-;73479:97;;73634:15;73619:11;:30;;73593:118;;;;-1:-1:-1;;;73593:118:0;;;;;;;:::i;:::-;72704:1026;;;;;;;;;;:::o;73738:769::-;73953:22;73978:84;63696:42;-1:-1:-1;;;;;74031:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73978:34;:10;74007:4;73978:28;:34::i;:84::-;73953:109;;74075:19;74112:14;74097:12;:29;:119;;74204:12;74187:14;:29;74097:119;;;74157:14;74142:12;:29;74097:119;74075:141;-1:-1:-1;74233:16:0;;74229:271;;74280:75;74342:12;74280:39;:11;74314:4;74280:33;:39::i;:75::-;74266:89;;74413:15;74398:11;:30;;74372:116;;;;-1:-1:-1;;;74372:116:0;;;;;;;:::i;:::-;73738:769;;;;;:::o;10693:530::-;10820:12;10878:5;10853:21;:30;;10845:81;;;;-1:-1:-1;;;10845:81:0;;;;;;;:::i;:::-;10945:18;10956:6;10945:10;:18::i;:::-;10937:60;;;;-1:-1:-1;;;10937:60:0;;;;;;;:::i;:::-;11071:12;11085:23;11112:6;-1:-1:-1;;;;;11112:11:0;11132:5;11140:4;11112:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11070:75;;;;11163:52;11181:7;11190:10;11202:12;11163:17;:52::i;:::-;11156:59;10693:530;-1:-1:-1;;;;;;;10693:530:0:o;6723:422::-;7090:20;7129:8;;;6723:422::o;13233:742::-;13348:12;13377:7;13373:595;;;-1:-1:-1;13408:10:0;13401:17;;13373:595;13522:17;;:21;13518:439;;13785:10;13779:17;13846:15;13833:10;13829:2;13825:19;13818:44;13733:148;13928:12;13921:20;;-1:-1:-1;;;13921:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;5:130;72:20;;97:33;72:20;97:33;:::i;3332:241::-;;3436:2;3424:9;3415:7;3411:23;3407:32;3404:2;;;-1:-1;;3442:12;3404:2;85:6;72:20;97:33;124:5;97:33;:::i;3580:263::-;;3695:2;3683:9;3674:7;3670:23;3666:32;3663:2;;;-1:-1;;3701:12;3663:2;226:6;220:13;238:33;265:5;238:33;:::i;3850:366::-;;;3971:2;3959:9;3950:7;3946:23;3942:32;3939:2;;;-1:-1;;3977:12;3939:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;4029:63;4129:2;4168:22;;;;3121:20;;-1:-1;;;3933:283::o;4223:377::-;;4352:2;;4340:9;4331:7;4327:23;4323:32;4320:2;;;-1:-1;;4358:12;4320:2;4416:17;4403:31;4454:18;4446:6;4443:30;4440:2;;;-1:-1;;4476:12;4440:2;4552:22;;411:4;399:17;;395:27;-1:-1;385:2;;-1:-1;;426:12;385:2;473:6;460:20;495:80;510:64;567:6;510:64;:::i;:::-;495:80;:::i;:::-;603:21;;;660:14;;;;635:17;;;749;;;740:27;;;;737:36;-1:-1;734:2;;;-1:-1;;776:12;734:2;-1:-1;802:10;;796:206;821:6;818:1;815:13;796:206;;;901:37;934:3;922:10;901:37;:::i;:::-;889:50;;843:1;836:9;;;;;953:14;;;;981;;796:206;;;-1:-1;4496:88;4314:286;-1:-1;;;;;;;4314:286::o;4607:392::-;;4747:2;;4735:9;4726:7;4722:23;4718:32;4715:2;;;-1:-1;;4753:12;4715:2;4804:17;4798:24;4842:18;4834:6;4831:30;4828:2;;;-1:-1;;4864:12;4828:2;4951:22;;1155:4;1143:17;;1139:27;-1:-1;1129:2;;-1:-1;;1170:12;1129:2;1210:6;1204:13;1232:80;1247:64;1304:6;1247:64;:::i;1232:80::-;1340:21;;;1397:14;;;;1372:17;;;1486;;;1477:27;;;;1474:36;-1:-1;1471:2;;;-1:-1;;1513:12;1471:2;-1:-1;1539:10;;1533:217;1558:6;1555:1;1552:13;1533:217;;;226:6;220:13;238:33;265:5;238:33;:::i;:::-;1626:61;;1580:1;1573:9;;;;;1701:14;;;;1729;;1533:217;;5006:451;;;5172:2;5160:9;5151:7;5147:23;5143:32;5140:2;;;-1:-1;;5178:12;5140:2;5236:17;5223:31;5274:18;;5266:6;5263:30;5260:2;;;-1:-1;;5296:12;5260:2;5424:6;5413:9;5409:22;;;1941:3;1934:4;1926:6;1922:17;1918:27;1908:2;;-1:-1;;1949:12;1908:2;1992:6;1979:20;5274:18;2011:6;2008:30;2005:2;;;-1:-1;;2041:12;2005:2;2136:3;5172:2;;2120:6;2116:17;2077:6;2102:32;;2099:41;2096:2;;;-1:-1;;2143:12;2096:2;5172;2073:17;;;;;5316:125;;-1:-1;5134:323;;-1:-1;;;;5134:323::o;5464:392::-;;5604:2;;5592:9;5583:7;5579:23;5575:32;5572:2;;;-1:-1;;5610:12;5572:2;5661:17;5655:24;5699:18;5691:6;5688:30;5685:2;;;-1:-1;;5721:12;5685:2;5808:22;;2310:4;2298:17;;2294:27;-1:-1;2284:2;;-1:-1;;2325:12;2284:2;2365:6;2359:13;2387:80;2402:64;2459:6;2402:64;:::i;2387:80::-;2495:21;;;2552:14;;;;2527:17;;;2641;;;2632:27;;;;2629:36;-1:-1;2626:2;;;-1:-1;;2668:12;2626:2;-1:-1;2694:10;;2688:217;2713:6;2710:1;2707:13;2688:217;;;3269:13;;2781:61;;2735:1;2728:9;;;;;2856:14;;;;2884;;2688:217;;5863:257;;5975:2;5963:9;5954:7;5950:23;5946:32;5943:2;;;-1:-1;;5981:12;5943:2;3000:6;2994:13;39188:5;35275:13;35268:21;39166:5;39163:32;39153:2;;-1:-1;;39199:12;6127:263;;6242:2;6230:9;6221:7;6217:23;6213:32;6210:2;;;-1:-1;;6248:12;6210:2;-1:-1;3269:13;;6204:186;-1:-1;6204:186::o;6397:399::-;;;6529:2;6517:9;6508:7;6504:23;6500:32;6497:2;;;-1:-1;;6535:12;6497:2;-1:-1;;3269:13;;6698:2;6748:22;;;3269:13;;;;;-1:-1;6491:305::o;7577:690::-;;7770:5;33408:12;34440:6;34435:3;34428:19;34477:4;;34472:3;34468:14;7782:93;;34477:4;7946:5;32978:14;-1:-1;7985:260;8010:6;8007:1;8004:13;7985:260;;;8071:13;;-1:-1;;;;;35045:54;7377:37;;6957:14;;;;34058;;;;4454:18;8025:9;7985:260;;;-1:-1;8251:10;;7701:566;-1:-1;;;;;7701:566::o;18057:271::-;;9884:5;33408:12;9995:52;10040:6;10035:3;10028:4;10021:5;10017:16;9995:52;:::i;:::-;10059:16;;;;;18191:137;-1:-1;;18191:137::o;18335:222::-;-1:-1;;;;;35045:54;;;;7377:37;;18462:2;18447:18;;18433:124::o;18564:349::-;-1:-1;;;;;35045:54;;;;7246:58;;18899:2;18884:18;;17888:37;18727:2;18712:18;;18698:215::o;18920:333::-;-1:-1;;;;;35045:54;;;7377:37;;35045:54;;19239:2;19224:18;;7377:37;19075:2;19060:18;;19046:207::o;19600:622::-;;19848:2;19869:17;19862:47;19923:108;19848:2;19837:9;19833:18;20017:6;19923:108;:::i;:::-;-1:-1;;;;;35045:54;;20110:2;20095:18;;7377:37;19915:116;-1:-1;38954:1;38944:12;;38934:2;;38960:9;38934:2;37388:41;20208:2;20197:9;20193:18;11030:65;19819:403;;;;;;:::o;20229:442::-;20438:3;20423:19;;20427:9;9419:21;20229:442;9446:258;33691:4;9468:1;9465:13;9446:258;;;9532:13;;17888:37;;7148:4;7139:14;;;;34058;;;;9493:1;9486:9;9446:258;;;9450:14;;;37528:24;20657:2;20646:9;20642:18;11186:58;20409:262;;;;;:::o;22015:517::-;;37528:24;11193:3;11186:58;22238:2;22374;22363:9;22359:18;22352:48;22414:108;22238:2;22227:9;22223:18;22508:6;22414:108;:::i;22539:310::-;;22686:2;22707:17;22700:47;11719:5;33408:12;34440:6;22686:2;22675:9;22671:18;34428:19;11813:52;11858:6;34468:14;22675:9;34468:14;22686:2;11839:5;11835:16;11813:52;:::i;:::-;38737:7;38721:14;-1:-1;;38717:28;11877:39;;;;34468:14;11877:39;;22657:192;-1:-1;;22657:192::o;22856:416::-;23056:2;23070:47;;;12153:2;23041:18;;;34428:19;12189:34;34468:14;;;12169:55;-1:-1;;;12244:12;;;12237:30;12286:12;;;23027:245::o;23279:416::-;23479:2;23493:47;;;12537:2;23464:18;;;34428:19;12573:26;34468:14;;;12553:47;12619:12;;;23450:245::o;23702:416::-;23902:2;23916:47;;;12870:2;23887:18;;;34428:19;12906:29;34468:14;;;12886:50;12955:12;;;23873:245::o;24125:416::-;24325:2;24339:47;;;13206:2;24310:18;;;34428:19;-1:-1;;;34468:14;;;13222:37;13278:12;;;24296:245::o;24548:416::-;24748:2;24762:47;;;13529:2;24733:18;;;34428:19;13565:32;34468:14;;;13545:53;13617:12;;;24719:245::o;24971:416::-;25171:2;25185:47;;;13868:2;25156:18;;;34428:19;13904:34;34468:14;;;13884:55;-1:-1;;;13959:12;;;13952:30;14001:12;;;25142:245::o;25394:416::-;25594:2;25608:47;;;14252:2;25579:18;;;34428:19;14288:28;34468:14;;;14268:49;14336:12;;;25565:245::o;25817:416::-;26017:2;26031:47;;;14587:2;26002:18;;;34428:19;-1:-1;;;34468:14;;;14603:35;14657:12;;;25988:245::o;26240:416::-;26440:2;26454:47;;;14908:2;26425:18;;;34428:19;14944:34;34468:14;;;14924:55;-1:-1;;;14999:12;;;14992:25;15036:12;;;26411:245::o;26663:416::-;26863:2;26877:47;;;15287:2;26848:18;;;34428:19;-1:-1;;;34468:14;;;15303:35;15357:12;;;26834:245::o;27086:416::-;27286:2;27300:47;;;27271:18;;;34428:19;15644:34;34468:14;;;15624:55;15698:12;;;27257:245::o;27509:416::-;27709:2;27723:47;;;15949:2;27694:18;;;34428:19;15985:31;34468:14;;;15965:52;16036:12;;;27680:245::o;27932:416::-;28132:2;28146:47;;;16287:2;28117:18;;;34428:19;16323:34;34468:14;;;16303:55;-1:-1;;;16378:12;;;16371:34;16424:12;;;28103:245::o;28355:416::-;28555:2;28569:47;;;16675:2;28540:18;;;34428:19;-1:-1;;;34468:14;;;16691:42;16752:12;;;28526:245::o;28778:416::-;28978:2;28992:47;;;17003:1;28963:18;;;34428:19;-1:-1;;;34468:14;;;17018:29;17066:12;;;28949:245::o;29201:416::-;29401:2;29415:47;;;17317:2;29386:18;;;34428:19;17353:34;34468:14;;;17333:55;-1:-1;;;17408:12;;;17401:46;17466:12;;;29372:245::o;29624:416::-;29824:2;29838:47;;;17717:2;29809:18;;;34428:19;17753:28;34468:14;;;17733:49;17801:12;;;29795:245::o;30047:222::-;17888:37;;;30174:2;30159:18;;30145:124::o;30276:826::-;;30570:3;30559:9;30555:19;17918:5;17895:3;17888:37;30743:2;11237:5;30743:2;30732:9;30728:18;11186:58;30570:3;30780:2;30769:9;30765:18;30758:48;30820:105;8493:5;33555:12;34440:6;34435:3;34428:19;34468:14;30559:9;34468:14;8505:93;;33141:3;-1:-1;33131:14;30743:2;-1:-1;33160:18;8678:21;;-1:-1;8705:288;8730:6;8727:1;8724:13;8705:288;;;38629:11;;-1:-1;;;;;35045:54;7377:37;;4454:18;34170:14;;;;6957;;;;8745:9;8705:288;;;-1:-1;;;;;;;35045:54;;;;31004:2;30989:18;;7377:37;-1:-1;;;31087:3;31072:19;17888:37;30812:113;30541:561;-1:-1;;;30541:561::o;31109:333::-;17888:37;;;31428:2;31413:18;;17888:37;31264:2;31249:18;;31235:207::o;31449:522::-;;;31600:11;31587:25;31651:48;;31675:8;31659:14;31655:29;31651:48;31631:18;31627:73;31617:2;;-1:-1;;31704:12;31617:2;31731:33;;31785:18;;;-1:-1;31823:18;31812:30;;31809:2;;;-1:-1;;31845:12;31809:2;31690:4;31873:13;;;;-1:-1;31925:17;;31659:14;31905:38;31895:49;;31892:2;;;31957:1;;31947:12;31892:2;31555:416;;;;;:::o;31978:256::-;32040:2;32034:9;32066:17;;;32141:18;32126:34;;32162:22;;;32123:62;32120:2;;;32198:1;;32188:12;32120:2;32040;32207:22;32018:216;;-1:-1;32018:216::o;32241:304::-;;32400:18;32392:6;32389:30;32386:2;;;-1:-1;;32422:12;32386:2;-1:-1;32467:4;32455:17;;;32520:15;;32323:222::o;38064:268::-;38129:1;38136:101;38150:6;38147:1;38144:13;38136:101;;;38217:11;;;38211:18;38198:11;;;38191:39;38172:2;38165:10;38136:101;;;38252:6;38249:1;38246:13;38243:2;;;-1:-1;;38129:1;38299:16;;38292:27;38113:219::o;38983:117::-;-1:-1;;;;;35045:54;;39042:35;;39032:2;;39091:1;;39081:12;39032:2;39026:74;:::o
Swarm Source
ipfs://309072ca0fbd312dd432286aa784eb9b19590f784ec864de8a350ab1a034cbc5
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.