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 | 12819649 | 1123 days ago | IN | 0 ETH | 0.05427201 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
BzxLiquidateV2
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-07-13 */ pragma solidity ^0.6.12; pragma experimental ABIEncoderV2; /// SPDX-License-Identifier: MIT /* * @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. */ 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 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 Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } /** * @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 in 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"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } /** * @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 Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20 { using SafeMath for uint256; using Address for address; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for {name} and {symbol}, initializes {decimals} with * a default value of 18. * * To select a different value for {decimals}, use {_setupDecimals}. * * All three of these values are immutable: they can only be set once during * construction. */ constructor (string memory name, string memory symbol) public { _name = name; _symbol = symbol; _decimals = 18; } /** * @dev Returns the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is * called. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view returns (uint8) { return _decimals; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}; * * Requirements: * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Sets {decimals} to a value other than the default one of 18. * * WARNING: This function should only be called from the constructor. Most * applications that interact with token contracts will not expect * {decimals} to ever change, and may work incorrectly if it does. */ function _setupDecimals(uint8 decimals_) internal { _decimals = decimals_; } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } } /** * @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); function owner() external view returns (address); ////// 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); // protocol holds WMATIC, 100k matic will be held as native function withdraw(address receiver, uint256 amount) external returns (uint256 withdrawAmount); function deposit() external payable; ////// 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); 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 IToken { function flashBorrow( uint256 borrowAmount, address borrower, address target, string calldata signature, bytes calldata data ) external payable returns (bytes memory); } interface ISwapsImpl { function dexSwap( address sourceTokenAddress, address destTokenAddress, address receiverAddress, address returnToSenderAddress, uint256 minSourceTokenAmount, uint256 maxSourceTokenAmount, uint256 requiredDestTokenAmount) external returns (uint256 destTokenAmountReceived, uint256 sourceTokenAmountUsed); function dexExpectedRate( address sourceTokenAddress, address destTokenAddress, uint256 sourceTokenAmount) external view returns (uint256); } interface IKyber { function swapTokenToToken( IERC20 src, uint256 srcAmount, IERC20 dest, uint256 minConversionRate ) external returns (uint256); function getExpectedRate( IERC20 src, IERC20 dest, uint256 srcQty ) external view returns (uint256 expectedRate, uint256 slippageRate); } interface KeeperCompatibleInterface { /** * @notice method that is simulated by the keepers to see if any work actually * needs to be performed. This method does does not actually need to be * executable, and since it is only ever simulated it can consume lots of gas. * @dev To ensure that it is never called, you may want to add the * cannotExecute modifier from KeeperBase to your implementation of this * method. * @param checkData specified in the upkeep registration so it is always the * same for a registered upkeep. This can easily be broken down into specific * arguments using `abi.decode`, so multiple upkeeps can be registered on the * same contract and easily differentiated by the contract. * @return upkeepNeeded boolean to indicate whether the keeper should call * performUpkeep or not. * @return performData bytes that the keeper should call performUpkeep with, if * upkeep is needed. If you would like to encode data to decode later, try * `abi.encode`. */ function checkUpkeep(bytes calldata checkData) external returns (bool upkeepNeeded, bytes memory performData); /** * @notice method that is actually executed by the keepers, via the registry. * The data returned by the checkUpkeep simulation will be passed into * this method to actually be executed. * @dev The input to this method should not be trusted, and the caller of the * method should not even be restricted to any single registry. Anyone should * be able call it, and the input should be validated, there is no guarantee * that the data passed in is the performData returned from checkUpkeep. This * could happen due to malicious keepers, racing keepers, or simply a state * change while the performUpkeep transaction is waiting for confirmation. * Always validate the data passed in. * @param performData is the data which was passed back from the checkData * simulation. If it is encoded, it can easily be decoded into other types by * calling `abi.decode`. This data should not be trusted, and should be * validated against the contract's current state. */ function performUpkeep(bytes calldata performData) external; } interface IKeep3rV1 { function isKeeper(address) external returns (bool); function worked(address keeper) external; } interface IWeth { function deposit() external payable; function withdraw(uint256 wad) external; } contract BzxLiquidateV2 is Ownable, KeeperCompatibleInterface { using SafeERC20 for IERC20; IBZx public constant BZX = IBZx(0xD8Ee69652E4e4838f2531732a46d1f7F584F0b7f); IKyber public constant KYBER_PROXY = IKyber(0x9AAb3f75489902f3a48495025729a0AF77d4b11e); IKeep3rV1 public constant KP3R = IKeep3rV1(0x1cEB5cB57C4D4E2b2433641b95Dd330A33185A44); IWeth public constant WETH = IWeth(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); modifier upkeep() { require( KP3R.isKeeper(msg.sender), "::isKeeper: keeper is not registered" ); _; KP3R.worked(msg.sender); } fallback() external payable {} receive() external payable {} function liquidateInternal( bytes32 loanId, address loanToken, address collateralToken, uint256 maxLiquidatable, address flashLoanToken, bool allowLoss, bool checkBeforeExecuting ) internal returns (address, uint256) { if (checkBeforeExecuting) { IBZx.LoanReturnData memory loan = BZX.getLoan(loanId); require( loan.maxLiquidatable > 0 && loan.maxSeizable > 0, "healty loan" ); } bytes memory b = IToken(flashLoanToken).flashBorrow( maxLiquidatable, address(this), address(this), "", abi.encodeWithSelector( this.executeOperation.selector, //"executeOperation(bytes32,address,address,uint256,address,bool,address)", loanId, loanToken, collateralToken, maxLiquidatable, flashLoanToken, allowLoss, msg.sender ) ); (, , , uint256 profitAmount) = abi.decode( b, (uint256, uint256, address, uint256) ); return (loanToken, profitAmount); } function liquidate( bytes32 loanId, address loanToken, address collateralToken, uint256 maxLiquidatable, address flashLoanToken ) external upkeep returns (address, uint256) { return liquidateInternal( loanId, loanToken, collateralToken, maxLiquidatable, flashLoanToken, false, false ); } function liquidateCheckBeforeExecuting( bytes32 loanId, address loanToken, address collateralToken, uint256 maxLiquidatable, address flashLoanToken ) external upkeep returns (address, uint256) { return liquidateInternal( loanId, loanToken, collateralToken, maxLiquidatable, flashLoanToken, false, true ); } function liquidatePublic( bytes32 loanId, address loanToken, address collateralToken, uint256 maxLiquidatable, address flashLoanToken ) external returns (address, uint256) { return liquidateInternal( loanId, loanToken, collateralToken, maxLiquidatable, flashLoanToken, false, false ); } function liquidateAllowLoss( bytes32 loanId, address loanToken, address collateralToken, uint256 maxLiquidatable, address flashLoanToken, bool checkBeforeExecuting ) external onlyOwner returns (address, uint256) { return liquidateInternal( loanId, loanToken, collateralToken, maxLiquidatable, flashLoanToken, true, checkBeforeExecuting ); } function executeOperation( bytes32 loanId, address loanToken, address collateralToken, uint256 maxLiquidatable, address iToken, bool allowLoss, address gasTokenUser ) external returns (bytes memory) { (uint256 _liquidatedLoanAmount, uint256 _liquidatedCollateral, ) = BZX .liquidate(loanId, address(this), uint256(-1)); if (collateralToken == address(WETH) && address(this).balance != 0) { WETH.deposit{value: address(this).balance}(); } // his is testnet // (uint256 _realLiquidatedLoanAmount,) = ISwapsImpl(BZX.swapsImpl()).dexSwap( // collateralToken, // loanToken, // address(this), // address(this), // _liquidatedCollateral, // _liquidatedCollateral, // 0 // ); uint256 _realLiquidatedLoanAmount = KYBER_PROXY.swapTokenToToken( IERC20(collateralToken), _liquidatedCollateral, IERC20(loanToken), 0 ); if (!allowLoss) { require( _realLiquidatedLoanAmount > _liquidatedLoanAmount, "no profit" ); } // repay flash loan IERC20(loanToken).safeTransfer(iToken, maxLiquidatable); return abi.encode( loanToken, uint256(_realLiquidatedLoanAmount - _liquidatedLoanAmount) ); } function wrapEther() public onlyOwner { if (address(this).balance != 0) { WETH.deposit{value: address(this).balance}(); } } function withdrawIERC20(IERC20 token) public onlyOwner { token.safeTransfer(msg.sender, token.balanceOf(address(this))); } function infiniteApproveIERC20(IERC20[] calldata tokens) public onlyOwner { for (uint256 i = 0; i < tokens.length; i++) { if (tokens[i].allowance(address(this), address(BZX)) != 0) { tokens[i].safeApprove(address(BZX), 0); } tokens[i].safeApprove(address(BZX), uint256(-1)); if (tokens[i].allowance(address(this), address(KYBER_PROXY)) != 0) { tokens[i].safeApprove(address(KYBER_PROXY), 0); } tokens[i].safeApprove(address(KYBER_PROXY), uint256(-1)); } } // chainlink registry mainnet 0x109A81F1E0A35D4c1D0cae8aCc6597cd54b47Bc6 // chainlink registry kovan 0xAaaD7966EBE0663b8C9C6f683FB9c3e66E03467F // link token mainnet 0x514910771AF9Ca656af840dff83E8264EcF986CA // link token kovan 0xa36085F69e2889c224210F603D836748e7dC0088 function infiniteApproveLinkRegistry(address registry, IERC20 token) public onlyOwner { if (token.allowance(address(this), registry) != 0) { token.safeApprove(registry, 0); } token.safeApprove(registry, uint256(-1)); } // event Logger(string name, uint256 value); // event LoggerAddress(string name, address value); // event LoggerBytes32(string name, bytes32 value); struct LoanReturnDataMinimal { bytes32 loanId; // id of the loan address loanToken; // loan token address address collateralToken; // collateral token address uint256 maxLiquidatable; // is the collateral you can get liquidating uint256 maxSeizable; // is the loan you available for liquidation address iToken; // iToken for liquidation } function getLiquidatableLoans(uint256 start, uint256 count) public view returns (LoanReturnDataMinimal[] memory liquidatableLoans) { IBZx.LoanReturnData[] memory loans; loans = BZX.getActiveLoansAdvanced(start, count, true, true); liquidatableLoans = new LoanReturnDataMinimal[](loans.length); for (uint256 i = 0; i < loans.length; i++) { liquidatableLoans[i] = LoanReturnDataMinimal( loans[i].loanId, loans[i].loanToken, loans[i].collateralToken, loans[i].maxLiquidatable, loans[i].maxSeizable, BZX.underlyingToLoanPool(loans[i].loanToken) ); } // assembly { // mstore(liquidatableLoans, counter) // } } // function isProfitalbe(IBZx.LoanReturnData memory loan) // public // pure // returns (bool) // { // return // loan.currentMargin > 0 && // loan.principal > 0 && // loan.collateral > 0 && // loan.maxLiquidatable > 0 && // loan.maxSeizable > 0; // } function checkUpkeep(bytes calldata checkData) external override returns (bool upkeepNeeded, bytes memory performData) { (uint256 start, uint256 count) = abi.decode( checkData, (uint256, uint256) ); LoanReturnDataMinimal[] memory liquidatableLoans = getLiquidatableLoans( start, count ); return (liquidatableLoans.length > 0, abi.encode(liquidatableLoans)); } function encode(uint256 start, uint256 count) external pure returns (bytes memory checkData) { return abi.encode(start, count); } function performUpkeep(bytes calldata performData) external override { LoanReturnDataMinimal[] memory loans = abi.decode( performData, (LoanReturnDataMinimal[]) ); require(loans.length > 0, "Cannot execute"); // liquidation uses approximately 1.6m gas lets round to 2m. current ethereum gasLimit ~12.5m // we agreed to liquidate just one in single performUpkeep call address(this).call( abi.encodeWithSelector( this.liquidatePublic.selector, loans[1].loanId, loans[1].loanToken, loans[1].collateralToken, loans[1].maxLiquidatable, loans[1].iToken ) ); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"BZX","outputs":[{"internalType":"contract IBZx","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"KP3R","outputs":[{"internalType":"contract IKeep3rV1","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"KYBER_PROXY","outputs":[{"internalType":"contract IKyber","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IWeth","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"checkData","type":"bytes"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"encode","outputs":[{"internalType":"bytes","name":"checkData","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"loanId","type":"bytes32"},{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"maxLiquidatable","type":"uint256"},{"internalType":"address","name":"iToken","type":"address"},{"internalType":"bool","name":"allowLoss","type":"bool"},{"internalType":"address","name":"gasTokenUser","type":"address"}],"name":"executeOperation","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"getLiquidatableLoans","outputs":[{"components":[{"internalType":"bytes32","name":"loanId","type":"bytes32"},{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"maxLiquidatable","type":"uint256"},{"internalType":"uint256","name":"maxSeizable","type":"uint256"},{"internalType":"address","name":"iToken","type":"address"}],"internalType":"struct BzxLiquidateV2.LoanReturnDataMinimal[]","name":"liquidatableLoans","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"}],"name":"infiniteApproveIERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"registry","type":"address"},{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"infiniteApproveLinkRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"loanId","type":"bytes32"},{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"maxLiquidatable","type":"uint256"},{"internalType":"address","name":"flashLoanToken","type":"address"}],"name":"liquidate","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"loanId","type":"bytes32"},{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"maxLiquidatable","type":"uint256"},{"internalType":"address","name":"flashLoanToken","type":"address"},{"internalType":"bool","name":"checkBeforeExecuting","type":"bool"}],"name":"liquidateAllowLoss","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"loanId","type":"bytes32"},{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"maxLiquidatable","type":"uint256"},{"internalType":"address","name":"flashLoanToken","type":"address"}],"name":"liquidateCheckBeforeExecuting","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"loanId","type":"bytes32"},{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"maxLiquidatable","type":"uint256"},{"internalType":"address","name":"flashLoanToken","type":"address"}],"name":"liquidatePublic","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"performData","type":"bytes"}],"name":"performUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"withdrawIERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wrapEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b50600061001b61006a565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35061006e565b3390565b6124568061007d6000396000f3fe6080604052600436106101235760003560e01c8063888ae177116100a0578063bcb7f95e11610064578063bcb7f95e146102fe578063c0452f0a1461031e578063c10142291461034b578063dc0aa2af1461036b578063f2fde38b1461038b5761012a565b8063888ae177146102745780638da5cb5b14610294578063949ef0c6146102a9578063ad5c4648146102c9578063af383f2b146102de5761012a565b80636e04ff0d116100e75780636e04ff0d146101ce5780636f1296d2146101fc578063715018a6146102115780637f49a8d314610226578063850336dd146102545761012a565b806305e0b9a01461012c5780631b5c1120146101575780631ddfa252146101845780634585e33b146101995780634fb7db3f146101b95761012a565b3661012a57005b005b34801561013857600080fd5b506101416103ab565b60405161014e9190611f53565b60405180910390f35b34801561016357600080fd5b50610177610172366004611e74565b6103c3565b60405161014e9190611f9a565b34801561019057600080fd5b50610141610647565b3480156101a557600080fd5b5061012a6101b4366004611d59565b61065f565b3480156101c557600080fd5b506101416107c4565b3480156101da57600080fd5b506101ee6101e9366004611d59565b6107dc565b60405161014e929190612020565b34801561020857600080fd5b5061012a610833565b34801561021d57600080fd5b5061012a6108d9565b34801561023257600080fd5b50610246610241366004611c67565b610958565b60405161014e929190611f81565b34801561026057600080fd5b5061024661026f366004611c09565b6109af565b34801561028057600080fd5b5061024661028f366004611c09565b610ae0565b3480156102a057600080fd5b50610141610b01565b3480156102b557600080fd5b506102466102c4366004611c09565b610b10565b3480156102d557600080fd5b50610141610bcb565b3480156102ea57600080fd5b5061012a6102f93660046119b6565b610be3565b34801561030a57600080fd5b5061012a610319366004611977565b610cca565b34801561032a57600080fd5b5061033e610339366004611cd6565b610d93565b60405161014e91906120cc565b34801561035757600080fd5b5061012a6103663660046119ee565b610fc9565b34801561037757600080fd5b5061033e610386366004611e74565b611243565b34801561039757600080fd5b5061012a6103a6366004611977565b611270565b731ceb5cb57c4d4e2b2433641b95dd330a33185a4481565b60405163c43b962f60e01b8152606090819073d8ee69652e4e4838f2531732a46d1f7f584f0b7f9063c43b962f9061040690879087906001908190600401612367565b60006040518083038186803b15801561041e57600080fd5b505afa158015610432573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261045a9190810190611b5c565b9050805167ffffffffffffffff8111801561047457600080fd5b506040519080825280602002602001820160405280156104ae57816020015b61049b611788565b8152602001906001900390816104935790505b50915060005b815181101561063f576040518060c001604052808383815181106104d457fe5b60200260200101516000015181526020018383815181106104f157fe5b6020026020010151604001516001600160a01b0316815260200183838151811061051757fe5b6020026020010151606001516001600160a01b0316815260200183838151811061053d57fe5b60200260200101516101a00151815260200183838151811061055b57fe5b60200260200101516101c00151815260200173d8ee69652e4e4838f2531732a46d1f7f584f0b7f6001600160a01b031663218b39c685858151811061059c57fe5b6020026020010151604001516040518263ffffffff1660e01b81526004016105c49190611f53565b60206040518083038186803b1580156105dc57600080fd5b505afa1580156105f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610614919061199a565b6001600160a01b031681525083828151811061062c57fe5b60209081029190910101526001016104b4565b505092915050565b73d8ee69652e4e4838f2531732a46d1f7f584f0b7f81565b606061066d82840184611a5d565b905060008151116106995760405162461bcd60e51b81526004016106909061214f565b60405180910390fd5b306001600160a01b031663888ae17760e01b826001815181106106b857fe5b602002602001015160000151836001815181106106d157fe5b602002602001015160200151846001815181106106ea57fe5b6020026020010151604001518560018151811061070357fe5b6020026020010151606001518660018151811061071c57fe5b602002602001015160a0015160405160240161073c959493929190612063565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161077a9190611f37565b6000604051808303816000865af19150503d80600081146107b7576040519150601f19603f3d011682016040523d82523d6000602084013e6107bc565b606091505b505050505050565b739aab3f75489902f3a48495025729a0af77d4b11e81565b6000606081806107ee85870187611e74565b9150915060606107fe83836103c3565b90506000815111816040516020016108169190611f9a565b604051602081830303815290604052945094505050509250929050565b61083b611326565b6000546001600160a01b039081169116146108685760405162461bcd60e51b815260040161069090612177565b47156108d75773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b1580156108bd57600080fd5b505af11580156108d1573d6000803e3d6000fd5b50505050505b565b6108e1611326565b6000546001600160a01b0390811691161461090e5760405162461bcd60e51b815260040161069090612177565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b600080610963611326565b6000546001600160a01b039081169116146109905760405162461bcd60e51b815260040161069090612177565b6109a0888888888860018961132a565b91509150965096945050505050565b6040516335d2155560e11b81526000908190731ceb5cb57c4d4e2b2433641b95dd330a33185a4490636ba42aaa906109eb903390600401611f53565b602060405180830381600087803b158015610a0557600080fd5b505af1158015610a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3d9190611bed565b610a595760405162461bcd60e51b8152600401610690906121ac565b610a69878787878760008061132a565b915091506040516317fbade560e21b8152731ceb5cb57c4d4e2b2433641b95dd330a33185a4490635feeb79490610aa4903390600401611f53565b600060405180830381600087803b158015610abe57600080fd5b505af1158015610ad2573d6000803e3d6000fd5b505050509550959350505050565b600080610af3878787878760008061132a565b915091509550959350505050565b6000546001600160a01b031690565b6040516335d2155560e11b81526000908190731ceb5cb57c4d4e2b2433641b95dd330a33185a4490636ba42aaa90610b4c903390600401611f53565b602060405180830381600087803b158015610b6657600080fd5b505af1158015610b7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9e9190611bed565b610bba5760405162461bcd60e51b8152600401610690906121ac565b610a6987878787876000600161132a565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b610beb611326565b6000546001600160a01b03908116911614610c185760405162461bcd60e51b815260040161069090612177565b604051636eb1769f60e11b81526001600160a01b0382169063dd62ed3e90610c469030908690600401611f67565b60206040518083038186803b158015610c5e57600080fd5b505afa158015610c72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c969190611e5c565b15610cb057610cb06001600160a01b0382168360006114ff565b610cc66001600160a01b038216836000196114ff565b5050565b610cd2611326565b6000546001600160a01b03908116911614610cff5760405162461bcd60e51b815260040161069090612177565b610d9033826001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610d2f9190611f53565b60206040518083038186803b158015610d4757600080fd5b505afa158015610d5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7f9190611e5c565b6001600160a01b03841691906115f9565b50565b60405163e4f3e73960e01b8152606090600090819073d8ee69652e4e4838f2531732a46d1f7f584f0b7f9063e4f3e73990610dd8908d90309060001990600401612044565b606060405180830381600087803b158015610df257600080fd5b505af1158015610e06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2a9190611e95565b5090925090506001600160a01b03881673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2148015610e5b57504715155b15610ec95773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b158015610eaf57600080fd5b505af1158015610ec3573d6000803e3d6000fd5b50505050505b604051637409e2eb60e01b8152600090739aab3f75489902f3a48495025729a0af77d4b11e90637409e2eb90610f09908c9086908f9087906004016120df565b602060405180830381600087803b158015610f2357600080fd5b505af1158015610f37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5b9190611e5c565b905085610f8157828111610f815760405162461bcd60e51b81526004016106909061224c565b610f956001600160a01b038b16888a6115f9565b89838203604051602001610faa929190611f81565b6040516020818303038152906040529350505050979650505050505050565b610fd1611326565b6000546001600160a01b03908116911614610ffe5760405162461bcd60e51b815260040161069090612177565b60005b8181101561123e5782828281811061101557fe5b905060200201602081019061102a9190611977565b6001600160a01b031663dd62ed3e3073d8ee69652e4e4838f2531732a46d1f7f584f0b7f6040518363ffffffff1660e01b815260040161106b929190611f67565b60206040518083038186803b15801561108357600080fd5b505afa158015611097573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110bb9190611e5c565b1561110b5761110b73d8ee69652e4e4838f2531732a46d1f7f584f0b7f60008585858181106110e657fe5b90506020020160208101906110fb9190611977565b6001600160a01b031691906114ff565b61113273d8ee69652e4e4838f2531732a46d1f7f584f0b7f6000198585858181106110e657fe5b82828281811061113e57fe5b90506020020160208101906111539190611977565b6001600160a01b031663dd62ed3e30739aab3f75489902f3a48495025729a0af77d4b11e6040518363ffffffff1660e01b8152600401611194929190611f67565b60206040518083038186803b1580156111ac57600080fd5b505afa1580156111c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e49190611e5c565b1561120f5761120f739aab3f75489902f3a48495025729a0af77d4b11e60008585858181106110e657fe5b611236739aab3f75489902f3a48495025729a0af77d4b11e6000198585858181106110e657fe5b600101611001565b505050565b60608282604051602001611258929190612359565b60405160208183030381529060405290505b92915050565b611278611326565b6000546001600160a01b039081169116146112a55760405162461bcd60e51b815260040161069090612177565b6001600160a01b0381166112cb5760405162461bcd60e51b815260040161069090612109565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b60008082156113fd5761133b6117bd565b604051638932f5f760e01b815273d8ee69652e4e4838f2531732a46d1f7f584f0b7f90638932f5f790611372908d9060040161203b565b6102206040518083038186803b15801561138b57600080fd5b505afa15801561139f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c39190611e40565b90506000816101a001511180156113df57506000816101c00151115b6113fb5760405162461bcd60e51b8152600401610690906121f0565b505b6060856001600160a01b031663c5bf0e9d88303063c0452f0a60e01b8f8f8f8f8f8f33604051602401611436979695949392919061208f565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199485161790525160e087901b909216825261147e9493929160040161230f565b600060405180830381600087803b15801561149857600080fd5b505af11580156114ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114d49190810190611db4565b90506000818060200190518101906114ec9190611ecd565b9c9e9c9d50505050505050505050505050565b8015806115875750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e906115359030908690600401611f67565b60206040518083038186803b15801561154d57600080fd5b505afa158015611561573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115859190611e5c565b155b6115a35760405162461bcd60e51b8152600401610690906122b9565b61123e8363095ea7b360e01b84846040516024016115c2929190611f81565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611618565b61123e8363a9059cbb60e01b84846040516024016115c2929190611f81565b606061166d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166116a79092919063ffffffff16565b80519091501561123e578080602001905181019061168b9190611bed565b61123e5760405162461bcd60e51b81526004016106909061226f565b60606116b684846000856116be565b949350505050565b60606116c985611782565b6116e55760405162461bcd60e51b815260040161069090612215565b60006060866001600160a01b031685876040516117029190611f37565b60006040518083038185875af1925050503d806000811461173f576040519150601f19603f3d011682016040523d82523d6000602084013e611744565b606091505b509150915081156117585791506116b69050565b8051156117685780518082602001fd5b8360405162461bcd60e51b815260040161069091906120cc565b3b151590565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6040518061022001604052806000801916815260200160006bffffffffffffffffffffffff16815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b805161126a816123fd565b6000610220808385031215611882578182fd5b61188b81612386565b9150508151815261189f836020840161195b565b60208201526118b18360408401611864565b60408201526118c38360608401611864565b60608201526080828101519082015260a0808301519082015260c0808301519082015260e08083015190820152610100808301519082015261012080830151908201526101408083015190820152610160808301519082015261018080830151908201526101a080830151908201526101c080830151908201526101e080830151908201526102009182015191810191909152919050565b80516bffffffffffffffffffffffff8116811461126a57600080fd5b600060208284031215611988578081fd5b8135611993816123fd565b9392505050565b6000602082840312156119ab578081fd5b8151611993816123fd565b600080604083850312156119c8578081fd5b82356119d3816123fd565b915060208301356119e3816123fd565b809150509250929050565b60008060208385031215611a00578182fd5b823567ffffffffffffffff80821115611a17578384fd5b818501915085601f830112611a2a578384fd5b813581811115611a38578485fd5b8660208083028501011115611a4b578485fd5b60209290920196919550909350505050565b60006020808385031215611a6f578182fd5b823567ffffffffffffffff811115611a85578283fd5b8301601f81018513611a95578283fd5b8035611aa8611aa3826123ad565b612386565b8181528381019083850160c0808502860187018a1015611ac6578788fd5b8795505b84861015611b4e5780828b031215611ae0578788fd5b611ae981612386565b8235815287830135611afa816123fd565b81890152604083810135611b0d816123fd565b90820152606083810135908201526080808401359082015260a080840135611b34816123fd565b908201528452600195909501949286019290810190611aca565b509098975050505050505050565b60006020808385031215611b6e578182fd5b825167ffffffffffffffff811115611b84578283fd5b8301601f81018513611b94578283fd5b8051611ba2611aa3826123ad565b81815283810190838501610220808502860187018a1015611bc1578788fd5b8795505b84861015611b4e57611bd78a8361186f565b8452600195909501949286019290810190611bc5565b600060208284031215611bfe578081fd5b815161199381612412565b600080600080600060a08688031215611c20578081fd5b853594506020860135611c32816123fd565b93506040860135611c42816123fd565b9250606086013591506080860135611c59816123fd565b809150509295509295909350565b60008060008060008060c08789031215611c7f578384fd5b863595506020870135611c91816123fd565b94506040870135611ca1816123fd565b9350606087013592506080870135611cb8816123fd565b915060a0870135611cc881612412565b809150509295509295509295565b600080600080600080600060e0888a031215611cf0578485fd5b873596506020880135611d02816123fd565b95506040880135611d12816123fd565b9450606088013593506080880135611d29816123fd565b925060a0880135611d3981612412565b915060c0880135611d49816123fd565b8091505092959891949750929550565b60008060208385031215611d6b578182fd5b823567ffffffffffffffff80821115611d82578384fd5b818501915085601f830112611d95578384fd5b813581811115611da3578485fd5b866020828501011115611a4b578485fd5b600060208284031215611dc5578081fd5b815167ffffffffffffffff80821115611ddc578283fd5b818401915084601f830112611def578283fd5b815181811115611dfd578384fd5b611e10601f8201601f1916602001612386565b9150808252856020828501011115611e26578384fd5b611e378160208401602086016123cd565b50949350505050565b60006102208284031215611e52578081fd5b611993838361186f565b600060208284031215611e6d578081fd5b5051919050565b60008060408385031215611e86578182fd5b50508035926020909101359150565b600080600060608486031215611ea9578081fd5b83519250602084015191506040840151611ec2816123fd565b809150509250925092565b60008060008060808587031215611ee2578182fd5b84519350602085015192506040850151611efb816123fd565b6060959095015193969295505050565b60008151808452611f238160208601602086016123cd565b601f01601f19169290920160200192915050565b60008251611f498184602087016123cd565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b602080825282518282018190526000919060409081850190868401855b8281101561201357815180518552868101516001600160a01b039081168887015286820151811687870152606080830151908701526080808301519087015260a091820151169085015260c09093019290850190600101611fb7565b5091979650505050505050565b60008315158252604060208301526116b66040830184611f0b565b90815260200190565b9283526001600160a01b03919091166020830152604082015260600190565b9485526001600160a01b0393841660208601529183166040850152606084015216608082015260a00190565b9687526001600160a01b0395861660208801529385166040870152606086019290925283166080850152151560a08401521660c082015260e00190565b6000602082526119936020830184611f0b565b6001600160a01b039485168152602081019390935292166040820152606081019190915260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600e908201526d43616e6e6f74206578656375746560901b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526024908201527f3a3a69734b65657065723a206b6565706572206973206e6f7420726567697374604082015263195c995960e21b606082015260800190565b6020808252600b908201526a3432b0b63a3c903637b0b760a91b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600990820152681b9bc81c1c9bd99a5d60ba1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b8481526001600160a01b0384811660208301528316604082015260a060608201819052600090820181905260c06080830181905261234f90830184611f0b565b9695505050505050565b918252602082015260400190565b9384526020840192909252151560408301521515606082015260800190565b60405181810167ffffffffffffffff811182821017156123a557600080fd5b604052919050565b600067ffffffffffffffff8211156123c3578081fd5b5060209081020190565b60005b838110156123e85781810151838201526020016123d0565b838111156123f7576000848401525b50505050565b6001600160a01b0381168114610d9057600080fd5b8015158114610d9057600080fdfea26469706673582212206016df3671fb01a3c3dbbef364ee859b4eba37d08bbeda5aabb644e8ff0e2fac64736f6c634300060c0033
Deployed Bytecode
0x6080604052600436106101235760003560e01c8063888ae177116100a0578063bcb7f95e11610064578063bcb7f95e146102fe578063c0452f0a1461031e578063c10142291461034b578063dc0aa2af1461036b578063f2fde38b1461038b5761012a565b8063888ae177146102745780638da5cb5b14610294578063949ef0c6146102a9578063ad5c4648146102c9578063af383f2b146102de5761012a565b80636e04ff0d116100e75780636e04ff0d146101ce5780636f1296d2146101fc578063715018a6146102115780637f49a8d314610226578063850336dd146102545761012a565b806305e0b9a01461012c5780631b5c1120146101575780631ddfa252146101845780634585e33b146101995780634fb7db3f146101b95761012a565b3661012a57005b005b34801561013857600080fd5b506101416103ab565b60405161014e9190611f53565b60405180910390f35b34801561016357600080fd5b50610177610172366004611e74565b6103c3565b60405161014e9190611f9a565b34801561019057600080fd5b50610141610647565b3480156101a557600080fd5b5061012a6101b4366004611d59565b61065f565b3480156101c557600080fd5b506101416107c4565b3480156101da57600080fd5b506101ee6101e9366004611d59565b6107dc565b60405161014e929190612020565b34801561020857600080fd5b5061012a610833565b34801561021d57600080fd5b5061012a6108d9565b34801561023257600080fd5b50610246610241366004611c67565b610958565b60405161014e929190611f81565b34801561026057600080fd5b5061024661026f366004611c09565b6109af565b34801561028057600080fd5b5061024661028f366004611c09565b610ae0565b3480156102a057600080fd5b50610141610b01565b3480156102b557600080fd5b506102466102c4366004611c09565b610b10565b3480156102d557600080fd5b50610141610bcb565b3480156102ea57600080fd5b5061012a6102f93660046119b6565b610be3565b34801561030a57600080fd5b5061012a610319366004611977565b610cca565b34801561032a57600080fd5b5061033e610339366004611cd6565b610d93565b60405161014e91906120cc565b34801561035757600080fd5b5061012a6103663660046119ee565b610fc9565b34801561037757600080fd5b5061033e610386366004611e74565b611243565b34801561039757600080fd5b5061012a6103a6366004611977565b611270565b731ceb5cb57c4d4e2b2433641b95dd330a33185a4481565b60405163c43b962f60e01b8152606090819073d8ee69652e4e4838f2531732a46d1f7f584f0b7f9063c43b962f9061040690879087906001908190600401612367565b60006040518083038186803b15801561041e57600080fd5b505afa158015610432573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261045a9190810190611b5c565b9050805167ffffffffffffffff8111801561047457600080fd5b506040519080825280602002602001820160405280156104ae57816020015b61049b611788565b8152602001906001900390816104935790505b50915060005b815181101561063f576040518060c001604052808383815181106104d457fe5b60200260200101516000015181526020018383815181106104f157fe5b6020026020010151604001516001600160a01b0316815260200183838151811061051757fe5b6020026020010151606001516001600160a01b0316815260200183838151811061053d57fe5b60200260200101516101a00151815260200183838151811061055b57fe5b60200260200101516101c00151815260200173d8ee69652e4e4838f2531732a46d1f7f584f0b7f6001600160a01b031663218b39c685858151811061059c57fe5b6020026020010151604001516040518263ffffffff1660e01b81526004016105c49190611f53565b60206040518083038186803b1580156105dc57600080fd5b505afa1580156105f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610614919061199a565b6001600160a01b031681525083828151811061062c57fe5b60209081029190910101526001016104b4565b505092915050565b73d8ee69652e4e4838f2531732a46d1f7f584f0b7f81565b606061066d82840184611a5d565b905060008151116106995760405162461bcd60e51b81526004016106909061214f565b60405180910390fd5b306001600160a01b031663888ae17760e01b826001815181106106b857fe5b602002602001015160000151836001815181106106d157fe5b602002602001015160200151846001815181106106ea57fe5b6020026020010151604001518560018151811061070357fe5b6020026020010151606001518660018151811061071c57fe5b602002602001015160a0015160405160240161073c959493929190612063565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161077a9190611f37565b6000604051808303816000865af19150503d80600081146107b7576040519150601f19603f3d011682016040523d82523d6000602084013e6107bc565b606091505b505050505050565b739aab3f75489902f3a48495025729a0af77d4b11e81565b6000606081806107ee85870187611e74565b9150915060606107fe83836103c3565b90506000815111816040516020016108169190611f9a565b604051602081830303815290604052945094505050509250929050565b61083b611326565b6000546001600160a01b039081169116146108685760405162461bcd60e51b815260040161069090612177565b47156108d75773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b1580156108bd57600080fd5b505af11580156108d1573d6000803e3d6000fd5b50505050505b565b6108e1611326565b6000546001600160a01b0390811691161461090e5760405162461bcd60e51b815260040161069090612177565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b600080610963611326565b6000546001600160a01b039081169116146109905760405162461bcd60e51b815260040161069090612177565b6109a0888888888860018961132a565b91509150965096945050505050565b6040516335d2155560e11b81526000908190731ceb5cb57c4d4e2b2433641b95dd330a33185a4490636ba42aaa906109eb903390600401611f53565b602060405180830381600087803b158015610a0557600080fd5b505af1158015610a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3d9190611bed565b610a595760405162461bcd60e51b8152600401610690906121ac565b610a69878787878760008061132a565b915091506040516317fbade560e21b8152731ceb5cb57c4d4e2b2433641b95dd330a33185a4490635feeb79490610aa4903390600401611f53565b600060405180830381600087803b158015610abe57600080fd5b505af1158015610ad2573d6000803e3d6000fd5b505050509550959350505050565b600080610af3878787878760008061132a565b915091509550959350505050565b6000546001600160a01b031690565b6040516335d2155560e11b81526000908190731ceb5cb57c4d4e2b2433641b95dd330a33185a4490636ba42aaa90610b4c903390600401611f53565b602060405180830381600087803b158015610b6657600080fd5b505af1158015610b7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9e9190611bed565b610bba5760405162461bcd60e51b8152600401610690906121ac565b610a6987878787876000600161132a565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b610beb611326565b6000546001600160a01b03908116911614610c185760405162461bcd60e51b815260040161069090612177565b604051636eb1769f60e11b81526001600160a01b0382169063dd62ed3e90610c469030908690600401611f67565b60206040518083038186803b158015610c5e57600080fd5b505afa158015610c72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c969190611e5c565b15610cb057610cb06001600160a01b0382168360006114ff565b610cc66001600160a01b038216836000196114ff565b5050565b610cd2611326565b6000546001600160a01b03908116911614610cff5760405162461bcd60e51b815260040161069090612177565b610d9033826001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610d2f9190611f53565b60206040518083038186803b158015610d4757600080fd5b505afa158015610d5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7f9190611e5c565b6001600160a01b03841691906115f9565b50565b60405163e4f3e73960e01b8152606090600090819073d8ee69652e4e4838f2531732a46d1f7f584f0b7f9063e4f3e73990610dd8908d90309060001990600401612044565b606060405180830381600087803b158015610df257600080fd5b505af1158015610e06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2a9190611e95565b5090925090506001600160a01b03881673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2148015610e5b57504715155b15610ec95773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b158015610eaf57600080fd5b505af1158015610ec3573d6000803e3d6000fd5b50505050505b604051637409e2eb60e01b8152600090739aab3f75489902f3a48495025729a0af77d4b11e90637409e2eb90610f09908c9086908f9087906004016120df565b602060405180830381600087803b158015610f2357600080fd5b505af1158015610f37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5b9190611e5c565b905085610f8157828111610f815760405162461bcd60e51b81526004016106909061224c565b610f956001600160a01b038b16888a6115f9565b89838203604051602001610faa929190611f81565b6040516020818303038152906040529350505050979650505050505050565b610fd1611326565b6000546001600160a01b03908116911614610ffe5760405162461bcd60e51b815260040161069090612177565b60005b8181101561123e5782828281811061101557fe5b905060200201602081019061102a9190611977565b6001600160a01b031663dd62ed3e3073d8ee69652e4e4838f2531732a46d1f7f584f0b7f6040518363ffffffff1660e01b815260040161106b929190611f67565b60206040518083038186803b15801561108357600080fd5b505afa158015611097573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110bb9190611e5c565b1561110b5761110b73d8ee69652e4e4838f2531732a46d1f7f584f0b7f60008585858181106110e657fe5b90506020020160208101906110fb9190611977565b6001600160a01b031691906114ff565b61113273d8ee69652e4e4838f2531732a46d1f7f584f0b7f6000198585858181106110e657fe5b82828281811061113e57fe5b90506020020160208101906111539190611977565b6001600160a01b031663dd62ed3e30739aab3f75489902f3a48495025729a0af77d4b11e6040518363ffffffff1660e01b8152600401611194929190611f67565b60206040518083038186803b1580156111ac57600080fd5b505afa1580156111c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e49190611e5c565b1561120f5761120f739aab3f75489902f3a48495025729a0af77d4b11e60008585858181106110e657fe5b611236739aab3f75489902f3a48495025729a0af77d4b11e6000198585858181106110e657fe5b600101611001565b505050565b60608282604051602001611258929190612359565b60405160208183030381529060405290505b92915050565b611278611326565b6000546001600160a01b039081169116146112a55760405162461bcd60e51b815260040161069090612177565b6001600160a01b0381166112cb5760405162461bcd60e51b815260040161069090612109565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b60008082156113fd5761133b6117bd565b604051638932f5f760e01b815273d8ee69652e4e4838f2531732a46d1f7f584f0b7f90638932f5f790611372908d9060040161203b565b6102206040518083038186803b15801561138b57600080fd5b505afa15801561139f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c39190611e40565b90506000816101a001511180156113df57506000816101c00151115b6113fb5760405162461bcd60e51b8152600401610690906121f0565b505b6060856001600160a01b031663c5bf0e9d88303063c0452f0a60e01b8f8f8f8f8f8f33604051602401611436979695949392919061208f565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199485161790525160e087901b909216825261147e9493929160040161230f565b600060405180830381600087803b15801561149857600080fd5b505af11580156114ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114d49190810190611db4565b90506000818060200190518101906114ec9190611ecd565b9c9e9c9d50505050505050505050505050565b8015806115875750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e906115359030908690600401611f67565b60206040518083038186803b15801561154d57600080fd5b505afa158015611561573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115859190611e5c565b155b6115a35760405162461bcd60e51b8152600401610690906122b9565b61123e8363095ea7b360e01b84846040516024016115c2929190611f81565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611618565b61123e8363a9059cbb60e01b84846040516024016115c2929190611f81565b606061166d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166116a79092919063ffffffff16565b80519091501561123e578080602001905181019061168b9190611bed565b61123e5760405162461bcd60e51b81526004016106909061226f565b60606116b684846000856116be565b949350505050565b60606116c985611782565b6116e55760405162461bcd60e51b815260040161069090612215565b60006060866001600160a01b031685876040516117029190611f37565b60006040518083038185875af1925050503d806000811461173f576040519150601f19603f3d011682016040523d82523d6000602084013e611744565b606091505b509150915081156117585791506116b69050565b8051156117685780518082602001fd5b8360405162461bcd60e51b815260040161069091906120cc565b3b151590565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6040518061022001604052806000801916815260200160006bffffffffffffffffffffffff16815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b805161126a816123fd565b6000610220808385031215611882578182fd5b61188b81612386565b9150508151815261189f836020840161195b565b60208201526118b18360408401611864565b60408201526118c38360608401611864565b60608201526080828101519082015260a0808301519082015260c0808301519082015260e08083015190820152610100808301519082015261012080830151908201526101408083015190820152610160808301519082015261018080830151908201526101a080830151908201526101c080830151908201526101e080830151908201526102009182015191810191909152919050565b80516bffffffffffffffffffffffff8116811461126a57600080fd5b600060208284031215611988578081fd5b8135611993816123fd565b9392505050565b6000602082840312156119ab578081fd5b8151611993816123fd565b600080604083850312156119c8578081fd5b82356119d3816123fd565b915060208301356119e3816123fd565b809150509250929050565b60008060208385031215611a00578182fd5b823567ffffffffffffffff80821115611a17578384fd5b818501915085601f830112611a2a578384fd5b813581811115611a38578485fd5b8660208083028501011115611a4b578485fd5b60209290920196919550909350505050565b60006020808385031215611a6f578182fd5b823567ffffffffffffffff811115611a85578283fd5b8301601f81018513611a95578283fd5b8035611aa8611aa3826123ad565b612386565b8181528381019083850160c0808502860187018a1015611ac6578788fd5b8795505b84861015611b4e5780828b031215611ae0578788fd5b611ae981612386565b8235815287830135611afa816123fd565b81890152604083810135611b0d816123fd565b90820152606083810135908201526080808401359082015260a080840135611b34816123fd565b908201528452600195909501949286019290810190611aca565b509098975050505050505050565b60006020808385031215611b6e578182fd5b825167ffffffffffffffff811115611b84578283fd5b8301601f81018513611b94578283fd5b8051611ba2611aa3826123ad565b81815283810190838501610220808502860187018a1015611bc1578788fd5b8795505b84861015611b4e57611bd78a8361186f565b8452600195909501949286019290810190611bc5565b600060208284031215611bfe578081fd5b815161199381612412565b600080600080600060a08688031215611c20578081fd5b853594506020860135611c32816123fd565b93506040860135611c42816123fd565b9250606086013591506080860135611c59816123fd565b809150509295509295909350565b60008060008060008060c08789031215611c7f578384fd5b863595506020870135611c91816123fd565b94506040870135611ca1816123fd565b9350606087013592506080870135611cb8816123fd565b915060a0870135611cc881612412565b809150509295509295509295565b600080600080600080600060e0888a031215611cf0578485fd5b873596506020880135611d02816123fd565b95506040880135611d12816123fd565b9450606088013593506080880135611d29816123fd565b925060a0880135611d3981612412565b915060c0880135611d49816123fd565b8091505092959891949750929550565b60008060208385031215611d6b578182fd5b823567ffffffffffffffff80821115611d82578384fd5b818501915085601f830112611d95578384fd5b813581811115611da3578485fd5b866020828501011115611a4b578485fd5b600060208284031215611dc5578081fd5b815167ffffffffffffffff80821115611ddc578283fd5b818401915084601f830112611def578283fd5b815181811115611dfd578384fd5b611e10601f8201601f1916602001612386565b9150808252856020828501011115611e26578384fd5b611e378160208401602086016123cd565b50949350505050565b60006102208284031215611e52578081fd5b611993838361186f565b600060208284031215611e6d578081fd5b5051919050565b60008060408385031215611e86578182fd5b50508035926020909101359150565b600080600060608486031215611ea9578081fd5b83519250602084015191506040840151611ec2816123fd565b809150509250925092565b60008060008060808587031215611ee2578182fd5b84519350602085015192506040850151611efb816123fd565b6060959095015193969295505050565b60008151808452611f238160208601602086016123cd565b601f01601f19169290920160200192915050565b60008251611f498184602087016123cd565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b602080825282518282018190526000919060409081850190868401855b8281101561201357815180518552868101516001600160a01b039081168887015286820151811687870152606080830151908701526080808301519087015260a091820151169085015260c09093019290850190600101611fb7565b5091979650505050505050565b60008315158252604060208301526116b66040830184611f0b565b90815260200190565b9283526001600160a01b03919091166020830152604082015260600190565b9485526001600160a01b0393841660208601529183166040850152606084015216608082015260a00190565b9687526001600160a01b0395861660208801529385166040870152606086019290925283166080850152151560a08401521660c082015260e00190565b6000602082526119936020830184611f0b565b6001600160a01b039485168152602081019390935292166040820152606081019190915260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600e908201526d43616e6e6f74206578656375746560901b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526024908201527f3a3a69734b65657065723a206b6565706572206973206e6f7420726567697374604082015263195c995960e21b606082015260800190565b6020808252600b908201526a3432b0b63a3c903637b0b760a91b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600990820152681b9bc81c1c9bd99a5d60ba1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b8481526001600160a01b0384811660208301528316604082015260a060608201819052600090820181905260c06080830181905261234f90830184611f0b565b9695505050505050565b918252602082015260400190565b9384526020840192909252151560408301521515606082015260800190565b60405181810167ffffffffffffffff811182821017156123a557600080fd5b604052919050565b600067ffffffffffffffff8211156123c3578081fd5b5060209081020190565b60005b838110156123e85781810151838201526020016123d0565b838111156123f7576000848401525b50505050565b6001600160a01b0381168114610d9057600080fd5b8015158114610d9057600080fdfea26469706673582212206016df3671fb01a3c3dbbef364ee859b4eba37d08bbeda5aabb644e8ff0e2fac64736f6c634300060c0033
Deployed Bytecode Sourcemap
67148:10487:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67439:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74936:847;;;;;;;;;;-1:-1:-1;74936:847:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;67250:75::-;;;;;;;;;;;;;:::i;76845:787::-;;;;;;;;;;-1:-1:-1;76845:787:0;;;;;:::i;:::-;;:::i;67334:96::-;;;;;;;;;;;;;:::i;76159:495::-;;;;;;;;;;-1:-1:-1;76159:495:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;72868:159::-;;;;;;;;;;;;;:::i;2648:148::-;;;;;;;;;;;;;:::i;70740:558::-;;;;;;;;;;-1:-1:-1;70740:558:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;69210:496::-;;;;;;;;;;-1:-1:-1;69210:496:0;;;;;:::i;:::-;;:::i;70237:495::-;;;;;;;;;;-1:-1:-1;70237:495:0;;;;;:::i;:::-;;:::i;2006:79::-;;;;;;;;;;;;;:::i;69714:515::-;;;;;;;;;;-1:-1:-1;69714:515:0;;;;;:::i;:::-;;:::i;67543:87::-;;;;;;;;;;;;;:::i;74071:286::-;;;;;;;;;;-1:-1:-1;74071:286:0;;;;;:::i;:::-;;:::i;73035:136::-;;;;;;;;;;-1:-1:-1;73035:136:0;;;;;:::i;:::-;;:::i;71306:1554::-;;;;;;;;;;-1:-1:-1;71306:1554:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;73179:592::-;;;;;;;;;;-1:-1:-1;73179:592:0;;;;;:::i;:::-;;:::i;76662:175::-;;;;;;;;;;-1:-1:-1;76662:175:0;;;;;:::i;:::-;;:::i;2951:244::-;;;;;;;;;;-1:-1:-1;2951:244:0;;;;;:::i;:::-;;:::i;67439:95::-;67491:42;67439:95;:::o;74936:847::-;75163:52;;-1:-1:-1;;;75163:52:0;;75044:48;;;;67282:42;;75163:26;;:52;;75190:5;;75197;;75204:4;;;;75163:52;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;75163:52:0;;;;;;;;;;;;:::i;:::-;75155:60;;75274:5;:12;75246:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;75226:61;;75305:9;75300:388;75324:5;:12;75320:1;:16;75300:388;;;75381:295;;;;;;;;75421:5;75427:1;75421:8;;;;;;;;;;;;;;:15;;;75381:295;;;;75455:5;75461:1;75455:8;;;;;;;;;;;;;;:18;;;-1:-1:-1;;;;;75381:295:0;;;;;75492:5;75498:1;75492:8;;;;;;;;;;;;;;:24;;;-1:-1:-1;;;;;75381:295:0;;;;;75535:5;75541:1;75535:8;;;;;;;;;;;;;;:24;;;75381:295;;;;75578:5;75584:1;75578:8;;;;;;;;;;;;;;:20;;;75381:295;;;;67282:42;-1:-1:-1;;;;;75617:24:0;;75642:5;75648:1;75642:8;;;;;;;;;;;;;;:18;;;75617:44;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;75381:295:0;;;;75358:17;75376:1;75358:20;;;;;;;;;;;;;;;;;:318;75338:3;;75300:388;;;;74936:847;;;;;:::o;67250:75::-;67282:42;67250:75;:::o;76845:787::-;76925:36;76964:87;;;;76989:11;76964:87;:::i;:::-;76925:126;;77085:1;77070:5;:12;:16;77062:43;;;;-1:-1:-1;;;77062:43:0;;;;;;;:::i;:::-;;;;;;;;;77302:4;-1:-1:-1;;;;;77294:18:0;77368:29;;;77416:5;77422:1;77416:8;;;;;;;;;;;;;;:15;;;77450:5;77456:1;77450:8;;;;;;;;;;;;;;:18;;;77487:5;77493:1;77487:8;;;;;;;;;;;;;;:24;;;77530:5;77536:1;77530:8;;;;;;;;;;;;;;:24;;;77573:5;77579:1;77573:8;;;;;;;;;;;;;;:15;;;77327:276;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;77327:276:0;;;;;;;;;;;;;;-1:-1:-1;;;;;77327:276:0;-1:-1:-1;;;;;;77327:276:0;;;;;;;;;;77294:320;;;;77327:276;77294:320;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76845:787;;;:::o;67334:96::-;67387:42;67334:96;:::o;76159:495::-;76260:17;76279:24;76260:17;;76354:78;;;;76379:9;76354:78;:::i;:::-;76321:111;;;;76443:48;76494:71;76529:5;76549;76494:20;:71::i;:::-;76443:122;;76613:1;76586:17;:24;:28;76627:17;76616:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;76578:68;;;;;;;76159:495;;;;;:::o;72868:159::-;2228:12;:10;:12::i;:::-;2218:6;;-1:-1:-1;;;;;2218:6:0;;;:22;;;2210:67;;;;-1:-1:-1;;;2210:67:0;;;;;;;:::i;:::-;72921:21:::1;:26:::0;72917:103:::1;;67587:42;-1:-1:-1::0;;;;;72964:12:0::1;;72984:21;72964:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;72917:103;72868:159::o:0;2648:148::-;2228:12;:10;:12::i;:::-;2218:6;;-1:-1:-1;;;;;2218:6:0;;;:22;;;2210:67;;;;-1:-1:-1;;;2210:67:0;;;;;;;:::i;:::-;2755:1:::1;2739:6:::0;;2718:40:::1;::::0;-1:-1:-1;;;;;2739:6:0;;::::1;::::0;2718:40:::1;::::0;2755:1;;2718:40:::1;2786:1;2769:19:::0;;-1:-1:-1;;;;;;2769:19:0::1;::::0;;2648:148::o;70740:558::-;70993:7;71002;2228:12;:10;:12::i;:::-;2218:6;;-1:-1:-1;;;;;2218:6:0;;;:22;;;2210:67;;;;-1:-1:-1;;;2210:67:0;;;;;;;:::i;:::-;71042:248:::1;71078:6;71103:9;71131:15;71165;71199:14;71232:4;71255:20;71042:17;:248::i;:::-;71022:268;;;;70740:558:::0;;;;;;;;;:::o;69210:496::-;67690:25;;-1:-1:-1;;;67690:25:0;;69415:7;;;;67491:42;;67690:13;;:25;;67704:10;;67690:25;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;67668:111;;;;-1:-1:-1;;;67668:111:0;;;;;;;:::i;:::-;69464:234:::1;69500:6;69525:9;69553:15;69587;69621:14;69654:5;69678::::0;69464:17:::1;:234::i;:::-;69444:254;;;;67802:23:::0;;-1:-1:-1;;;67802:23:0;;67491:42;;67802:11;;:23;;67814:10;;67802:23;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69210:496;;;;;;;;:::o;70237:495::-;70441:7;70450;70490:234;70526:6;70551:9;70579:15;70613;70647:14;70680:5;70704;70490:17;:234::i;:::-;70470:254;;;;70237:495;;;;;;;;:::o;2006:79::-;2044:7;2071:6;-1:-1:-1;;;;;2071:6:0;2006:79;:::o;69714:515::-;67690:25;;-1:-1:-1;;;67690:25:0;;69939:7;;;;67491:42;;67690:13;;:25;;67704:10;;67690:25;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;67668:111;;;;-1:-1:-1;;;67668:111:0;;;;;;;:::i;:::-;69988:233:::1;70024:6;70049:9;70077:15;70111;70145:14;70178:5;70202:4;69988:17;:233::i;67543:87::-:0;67587:42;67543:87;:::o;74071:286::-;2228:12;:10;:12::i;:::-;2218:6;;-1:-1:-1;;;;;2218:6:0;;;:22;;;2210:67;;;;-1:-1:-1;;;2210:67:0;;;;;;;:::i;:::-;74195:40:::1;::::0;-1:-1:-1;;;74195:40:0;;-1:-1:-1;;;;;74195:15:0;::::1;::::0;::::1;::::0;:40:::1;::::0;74219:4:::1;::::0;74226:8;;74195:40:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:45:::0;74191:108:::1;;74257:30;-1:-1:-1::0;;;;;74257:17:0;::::1;74275:8:::0;74285:1:::1;74257:17;:30::i;:::-;74309:40;-1:-1:-1::0;;;;;74309:17:0;::::1;74327:8:::0;-1:-1:-1;;74309:17:0::1;:40::i;:::-;74071:286:::0;;:::o;73035:136::-;2228:12;:10;:12::i;:::-;2218:6;;-1:-1:-1;;;;;2218:6:0;;;:22;;;2210:67;;;;-1:-1:-1;;;2210:67:0;;;;;;;:::i;:::-;73101:62:::1;73120:10;73132:5;-1:-1:-1::0;;;;;73132:15:0::1;;73156:4;73132:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;73101:18:0;::::1;::::0;:62;:18:::1;:62::i;:::-;73035:136:::0;:::o;71306:1554::-;71651:59;;-1:-1:-1;;;71651:59:0;;71559:12;;71585:29;;;;67282:42;;71651:23;;:59;;71675:6;;71691:4;;-1:-1:-1;;71706:2:0;71651:59;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;71584:126:0;;-1:-1:-1;71584:126:0;-1:-1:-1;;;;;;71727:32:0;;67587:42;71727:32;:62;;;;-1:-1:-1;71763:21:0;:26;;71727:62;71723:139;;;67587:42;-1:-1:-1;;;;;71806:12:0;;71826:21;71806:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71723:139;72256:161;;-1:-1:-1;;;72256:161:0;;72220:33;;67387:42;;72256:28;;:161;;72306:15;;72337:21;;72380:9;;72220:33;;72256:161;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72220:197;;72435:9;72430:163;;72515:21;72487:25;:49;72461:120;;;;-1:-1:-1;;;72461:120:0;;;;;;;:::i;:::-;72634:55;-1:-1:-1;;;;;72634:30:0;;72665:6;72673:15;72634:30;:55::i;:::-;72751:9;72815:21;72787:25;:49;72722:130;;;;;;;;;:::i;:::-;;;;;;;;;;;;;72702:150;;;;;71306:1554;;;;;;;;;:::o;73179:592::-;2228:12;:10;:12::i;:::-;2218:6;;-1:-1:-1;;;;;2218:6:0;;;:22;;;2210:67;;;;-1:-1:-1;;;2210:67:0;;;;;;;:::i;:::-;73269:9:::1;73264:500;73284:17:::0;;::::1;73264:500;;;73327:6;;73334:1;73327:9;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;73327:19:0::1;;73355:4;67282:42;73327:48;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53:::0;73323:132:::1;;73401:38;67282:42;73437:1;73401:6;;73408:1;73401:9;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;73401:21:0::1;::::0;:38;:21:::1;:38::i;:::-;73469:48;67282:42;-1:-1:-1::0;;73469:6:0::1;;73476:1;73469:9;;;;;;:48;73538:6;;73545:1;73538:9;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;73538:19:0::1;;73566:4;67387:42;73538:56;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:61:::0;73534:148:::1;;73620:46;67387:42;73664:1;73620:6;;73627:1;73620:9;;;;;;:46;73696:56;67387:42;-1:-1:-1::0;;73696:6:0::1;;73703:1;73696:9;;;;;;:56;73303:3;;73264:500;;;;73179:592:::0;;:::o;76662:175::-;76758:22;76816:5;76823;76805:24;;;;;;;;;:::i;:::-;;;;;;;;;;;;;76798:31;;76662:175;;;;;:::o;2951:244::-;2228:12;:10;:12::i;:::-;2218:6;;-1:-1:-1;;;;;2218:6:0;;;:22;;;2210:67;;;;-1:-1:-1;;;2210:67:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;3040:22:0;::::1;3032:73;;;;-1:-1:-1::0;;;3032:73:0::1;;;;;;;:::i;:::-;3142:6;::::0;;3121:38:::1;::::0;-1:-1:-1;;;;;3121:38:0;;::::1;::::0;3142:6;::::1;::::0;3121:38:::1;::::0;::::1;3170:6;:17:::0;;-1:-1:-1;;;;;;3170:17:0::1;-1:-1:-1::0;;;;;3170:17:0;;;::::1;::::0;;;::::1;::::0;;2951:244::o;644:106::-;732:10;644:106;:::o;67916:1286::-;68183:7;68192;68216:20;68212:242;;;68253:31;;:::i;:::-;68287:19;;-1:-1:-1;;;68287:19:0;;67282:42;;68287:11;;:19;;68299:6;;68287:19;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68253:53;;68370:1;68347:4;:20;;;:24;:48;;;;;68394:1;68375:4;:16;;;:20;68347:48;68321:121;;;;-1:-1:-1;;;68321:121:0;;;;;;;:::i;:::-;68212:242;;68466:14;68490;-1:-1:-1;;;;;68483:34:0;;68532:15;68570:4;68598;68676:30;;;68801:6;68826:9;68854:15;68888;68922:14;68955:9;68983:10;68635:373;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;68635:373:0;;;;;;;;;;;;;;-1:-1:-1;;;;;68635:373:0;-1:-1:-1;;;;;;68635:373:0;;;;;;68483:536;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;68483:536:0;;;;;;;;;;;;:::i;:::-;68466:553;;69039:20;69088:1;69063:88;;;;;;;;;;;;:::i;:::-;69170:9;;69032:119;;-1:-1:-1;;;;;;;;;;;;;67916:1286:0:o;29303:622::-;29673:10;;;29672:62;;-1:-1:-1;29689:39:0;;-1:-1:-1;;;29689:39:0;;-1:-1:-1;;;;;29689:15:0;;;;;:39;;29713:4;;29720:7;;29689:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;29672:62;29664:152;;;;-1:-1:-1;;;29664:152:0;;;;;;;:::i;:::-;29827:90;29847:5;29877:22;;;29901:7;29910:5;29854:62;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;29854:62:0;;;;;;;;;;;;;;-1:-1:-1;;;;;29854:62:0;-1:-1:-1;;;;;;29854:62:0;;;;;;;;;;29827:19;:90::i;28644:177::-;28727:86;28747:5;28777:23;;;28802:2;28806:5;28754:58;;;;;;;;;:::i;30949:761::-;31373:23;31399:69;31427:4;31399:69;;;;;;;;;;;;;;;;;31407:5;-1:-1:-1;;;;;31399:27:0;;;:69;;;;;:::i;:::-;31483:17;;31373:95;;-1:-1:-1;31483:21:0;31479:224;;31625:10;31614:30;;;;;;;;;;;;:::i;:::-;31606:85;;;;-1:-1:-1;;;31606:85:0;;;;;;;:::i;12101:196::-;12204:12;12236:53;12259:6;12267:4;12273:1;12276:12;12236:22;:53::i;:::-;12229:60;12101:196;-1:-1:-1;;;;12101:196:0:o;13478:979::-;13608:12;13641:18;13652:6;13641:10;:18::i;:::-;13633:60;;;;-1:-1:-1;;;13633:60:0;;;;;;;:::i;:::-;13767:12;13781:23;13808:6;-1:-1:-1;;;;;13808:11:0;13828:8;13839:4;13808:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13766:78;;;;13859:7;13855:595;;;13890:10;-1:-1:-1;13883:17:0;;-1:-1:-1;13883:17:0;13855:595;14004:17;;:21;14000:439;;14267:10;14261:17;14328:15;14315:10;14311:2;14307:19;14300:44;14215:148;14410:12;14403:20;;-1:-1:-1;;;14403:20:0;;;;;;;;:::i;9183:422::-;9550:20;9589:8;;;9183:422::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;142:134::-;220:13;;238:33;220:13;238:33;:::i;5298:3040::-;;5430:6;;5418:9;5413:3;5409:19;5405:32;5402:2;;;-1:-1;;5440:12;5402:2;5468:22;5430:6;5468:22;:::i;:::-;5459:31;;;5606:22;3074:13;5556:16;5549:86;5737:59;5792:3;5704:2;5772:9;5768:22;5737:59;:::i;:::-;5704:2;5723:5;5719:16;5712:85;5896:60;5952:3;5863:2;5932:9;5928:22;5896:60;:::i;:::-;5863:2;5882:5;5878:16;5871:86;6062:60;6118:3;6029:2;6098:9;6094:22;6062:60;:::i;:::-;6029:2;6044:16;;6037:86;6189:3;6255:22;;;8560:13;6205:16;;;6198:86;6351:3;6417:22;;;8560:13;6367:16;;;6360:86;6521:3;6587:22;;;8560:13;6537:16;;;6530:86;6697:3;6763:22;;;8560:13;6713:16;;;6706:86;6858:3;6926:22;;;8560:13;6874:18;;;6867:88;7023:3;7091:22;;;8560:13;7039:18;;;7032:88;7194:3;7262:22;;;8560:13;7210:18;;;7203:88;7361:3;7429:22;;;8560:13;7377:18;;;7370:88;7526:3;7594:22;;;8560:13;7542:18;;;7535:88;7695:3;7763:22;;;8560:13;7711:18;;;7704:88;7860:3;7928:22;;;8560:13;7876:18;;;7869:88;8037:3;8105:22;;;8560:13;8053:18;;;8046:88;8220:3;8288:22;;;8560:13;8236:18;;;8229:88;;;;6048:5;5396:2942;-1:-1;5396:2942::o;8623:132::-;8700:13;;42996:26;42985:38;;46196:34;;46186:2;;46244:1;;46234:12;8762:241;;8866:2;8854:9;8845:7;8841:23;8837:32;8834:2;;;-1:-1;;8872:12;8834:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;8924:63;8828:175;-1:-1;;;8828:175::o;9010:263::-;;9125:2;9113:9;9104:7;9100:23;9096:32;9093:2;;;-1:-1;;9131:12;9093:2;226:6;220:13;238:33;265:5;238:33;:::i;9280:394::-;;;9415:2;9403:9;9394:7;9390:23;9386:32;9383:2;;;-1:-1;;9421:12;9383:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;9473:63;-1:-1;9573:2;9626:22;;4027:20;4052:47;4027:20;4052:47;:::i;:::-;9581:77;;;;9377:297;;;;;:::o;9681:425::-;;;9834:2;9822:9;9813:7;9809:23;9805:32;9802:2;;;-1:-1;;9840:12;9802:2;9898:17;9885:31;9936:18;;9928:6;9925:30;9922:2;;;-1:-1;;9958:12;9922:2;10073:6;10062:9;10058:22;;;610:3;603:4;595:6;591:17;587:27;577:2;;-1:-1;;618:12;577:2;661:6;648:20;9936:18;680:6;677:30;674:2;;;-1:-1;;710:12;674:2;805:3;9834:2;;789:6;785:17;746:6;771:32;;768:41;765:2;;;-1:-1;;812:12;765:2;9834;742:17;;;;;9978:112;;-1:-1;9796:310;;-1:-1;;;;9796:310::o;10113:455::-;;10281:2;;10269:9;10260:7;10256:23;10252:32;10249:2;;;-1:-1;;10287:12;10249:2;10345:17;10332:31;10383:18;10375:6;10372:30;10369:2;;;-1:-1;;10405:12;10369:2;10520:22;;1043:4;1031:17;;1027:27;-1:-1;1017:2;;-1:-1;;1058:12;1017:2;1105:6;1092:20;1127:119;1142:103;1238:6;1142:103;:::i;:::-;1127:119;:::i;:::-;1274:21;;;1331:14;;;;1306:17;;;1432:4;1420:17;;;1411:27;;;;1408:36;-1:-1;1405:2;;;-1:-1;;1447:12;1405:2;-1:-1;1473:10;;1467:245;1492:6;1489:1;1486:13;1467:245;;;1432:4;4277:9;4272:3;4268:19;4264:30;4261:2;;;-1:-1;;4297:12;4261:2;4325:20;1432:4;4325:20;:::i;:::-;2939:6;2926:20;4411:16;4404:75;10281:2;4603:9;4599:22;72:20;97:33;124:5;97:33;:::i;:::-;4560:16;;;4553:75;4700:2;4754:22;;;72:20;97:33;72:20;97:33;:::i;:::-;4715:16;;;4708:75;4855:2;4909:22;;;8412:20;4870:16;;;4863:75;5006:3;5061:22;;;8412:20;5022:16;;;5015:75;5153:3;5208:22;;;72:20;97:33;72:20;97:33;:::i;:::-;5169:16;;;5162:75;1560:89;;1514:1;1507:9;;;;;1663:14;;;;1691;;;;1467:245;;;-1:-1;10425:127;;10243:325;-1:-1;;;;;;;;10243:325::o;10575:456::-;;10747:2;;10735:9;10726:7;10722:23;10718:32;10715:2;;;-1:-1;;10753:12;10715:2;10804:17;10798:24;10842:18;10834:6;10831:30;10828:2;;;-1:-1;;10864:12;10828:2;10983:22;;1916:4;1904:17;;1900:27;-1:-1;1890:2;;-1:-1;;1931:12;1890:2;1971:6;1965:13;1993:112;2008:96;2097:6;2008:96;:::i;1993:112::-;2133:21;;;2190:14;;;;2165:17;;;2291:6;2279:19;;;2270:29;;;;2267:38;-1:-1;2264:2;;;-1:-1;;2308:12;2264:2;-1:-1;2334:10;;2328:251;2353:6;2350:1;2347:13;2328:251;;;2433:80;2509:3;2497:10;2433:80;:::i;:::-;2421:93;;2375:1;2368:9;;;;;2528:14;;;;2556:16;;;;2328:251;;11038:257;;11150:2;11138:9;11129:7;11125:23;11121:32;11118:2;;;-1:-1;;11156:12;11118:2;2805:6;2799:13;2817:30;2841:5;2817:30;:::i;11302:743::-;;;;;;11474:3;11462:9;11453:7;11449:23;11445:33;11442:2;;;-1:-1;;11481:12;11442:2;2939:6;2926:20;11533:63;;11633:2;11676:9;11672:22;72:20;97:33;124:5;97:33;:::i;:::-;11641:63;-1:-1;11741:2;11780:22;;72:20;97:33;72:20;97:33;:::i;:::-;11749:63;-1:-1;11849:2;11888:22;;8412:20;;-1:-1;11957:3;11997:22;;72:20;97:33;72:20;97:33;:::i;:::-;11966:63;;;;11436:609;;;;;;;;:::o;12052:863::-;;;;;;;12238:3;12226:9;12217:7;12213:23;12209:33;12206:2;;;-1:-1;;12245:12;12206:2;2939:6;2926:20;12297:63;;12397:2;12440:9;12436:22;72:20;97:33;124:5;97:33;:::i;:::-;12405:63;-1:-1;12505:2;12544:22;;72:20;97:33;72:20;97:33;:::i;:::-;12513:63;-1:-1;12613:2;12652:22;;8412:20;;-1:-1;12721:3;12761:22;;72:20;97:33;72:20;97:33;:::i;:::-;12730:63;-1:-1;12830:3;12867:22;;2657:20;2682:30;2657:20;2682:30;:::i;:::-;12839:60;;;;12200:715;;;;;;;;:::o;12922:989::-;;;;;;;;13125:3;13113:9;13104:7;13100:23;13096:33;13093:2;;;-1:-1;;13132:12;13093:2;2939:6;2926:20;13184:63;;13284:2;13327:9;13323:22;72:20;97:33;124:5;97:33;:::i;:::-;13292:63;-1:-1;13392:2;13431:22;;72:20;97:33;72:20;97:33;:::i;:::-;13400:63;-1:-1;13500:2;13539:22;;8412:20;;-1:-1;13608:3;13648:22;;72:20;97:33;72:20;97:33;:::i;:::-;13617:63;-1:-1;13717:3;13754:22;;2657:20;2682:30;2657:20;2682:30;:::i;:::-;13726:60;-1:-1;13823:3;13863:22;;72:20;97:33;72:20;97:33;:::i;:::-;13832:63;;;;13087:824;;;;;;;;;;:::o;13918:365::-;;;14041:2;14029:9;14020:7;14016:23;14012:32;14009:2;;;-1:-1;;14047:12;14009:2;14105:17;14092:31;14143:18;;14135:6;14132:30;14129:2;;;-1:-1;;14165:12;14129:2;14250:6;14239:9;14235:22;;;3265:3;3258:4;3250:6;3246:17;3242:27;3232:2;;-1:-1;;3273:12;3232:2;3316:6;3303:20;14143:18;3335:6;3332:30;3329:2;;;-1:-1;;3365:12;3329:2;3460:3;14041:2;3440:17;3401:6;3426:32;;3423:41;3420:2;;;-1:-1;;3467:12;14290:360;;14414:2;14402:9;14393:7;14389:23;14385:32;14382:2;;;-1:-1;;14420:12;14382:2;14471:17;14465:24;14509:18;;14501:6;14498:30;14495:2;;;-1:-1;;14531:12;14495:2;14617:6;14606:9;14602:22;;;3608:3;3601:4;3593:6;3589:17;3585:27;3575:2;;-1:-1;;3616:12;3575:2;3656:6;3650:13;14509:18;40524:6;40521:30;40518:2;;;-1:-1;;40554:12;40518:2;3678:64;40627:9;40608:17;;-1:-1;;40604:33;14414:2;40685:15;3678:64;:::i;:::-;3669:73;;3762:6;3755:5;3748:21;3866:3;14414:2;3857:6;3790;3848:16;;3845:25;3842:2;;;-1:-1;;3873:12;3842:2;3893:39;3925:6;14414:2;3824:5;3820:16;14414:2;3790:6;3786:17;3893:39;:::i;:::-;-1:-1;14551:83;14376:274;-1:-1;;;;14376:274::o;14933:328::-;;15080:3;15068:9;15059:7;15055:23;15051:33;15048:2;;;-1:-1;;15087:12;15048:2;15149:96;15237:7;15213:22;15149:96;:::i;15268:263::-;;15383:2;15371:9;15362:7;15358:23;15354:32;15351:2;;;-1:-1;;15389:12;15351:2;-1:-1;8560:13;;15345:186;-1:-1;15345:186::o;15538:366::-;;;15659:2;15647:9;15638:7;15634:23;15630:32;15627:2;;;-1:-1;;15665:12;15627:2;-1:-1;;8412:20;;;15817:2;15856:22;;;8412:20;;-1:-1;15621:283::o;15911:535::-;;;;16060:2;16048:9;16039:7;16035:23;16031:32;16028:2;;;-1:-1;;16066:12;16028:2;8566:6;8560:13;16118:74;;16229:2;16283:9;16279:22;8560:13;16237:74;;16348:2;16402:9;16398:22;220:13;238:33;265:5;238:33;:::i;:::-;16356:74;;;;16022:424;;;;;:::o;16453:688::-;;;;;16627:3;16615:9;16606:7;16602:23;16598:33;16595:2;;;-1:-1;;16634:12;16595:2;8566:6;8560:13;16686:74;;16797:2;16851:9;16847:22;8560:13;16805:74;;16916:2;16978:9;16974:22;369:13;387:41;422:5;387:41;:::i;:::-;17043:2;17093:22;;;;8560:13;16589:552;;;;-1:-1;;;16589:552::o;19463:343::-;;19605:5;41056:12;41678:6;41673:3;41666:19;19698:52;19743:6;41715:4;41710:3;41706:14;41715:4;19724:5;19720:16;19698:52;:::i;:::-;40627:9;45319:14;-1:-1;;45315:28;19762:39;;;;41715:4;19762:39;;19553:253;-1:-1;;19553:253::o;26438:271::-;;19973:5;41056:12;20084:52;20129:6;20124:3;20117:4;20110:5;20106:16;20084:52;:::i;:::-;20148:16;;;;;26572:137;-1:-1;;26572:137::o;26716:222::-;-1:-1;;;;;42779:54;;;;17722:45;;26843:2;26828:18;;26814:124::o;27190:349::-;-1:-1;;;;;42779:54;;;17565:58;;42779:54;;27525:2;27510:18;;17722:45;27353:2;27338:18;;27324:215::o;27886:333::-;-1:-1;;;;;42779:54;;;;17722:45;;28205:2;28190:18;;19294:37;28041:2;28026:18;;28012:207::o;28226:526::-;28481:2;28495:47;;;41056:12;;28466:18;;;41666:19;;;28226:526;;28481:2;41706:14;;;;;;40871;;;28226:526;18715:377;18740:6;18737:1;18734:13;18715:377;;;18801:13;;25282:23;;19294:37;;25447:16;;;25441:23;-1:-1;;;;;42779:54;;;25518:14;;;17722:45;25612:16;;;25606:23;42779:54;;25683:14;;;17722:45;25788:4;25777:16;;;25771:23;25848:14;;;19294:37;25949:4;25938:16;;;25932:23;26009:14;;;19294:37;42790:42;26094:16;;;26088:23;42779:54;26165:14;;;17722:45;17467:4;17458:14;;;;41482;;;;42996:26;18755:9;18715:377;;;-1:-1;28548:194;;28452:300;-1:-1;;;;;;;28452:300::o;28759:405::-;;19214:5;42500:13;42493:21;19194:3;19187:34;28926:2;29038;29027:9;29023:18;29016:48;29078:76;28926:2;28915:9;28911:18;29140:6;29078:76;:::i;29171:222::-;19294:37;;;29298:2;29283:18;;29269:124::o;29400:460::-;19294:37;;;-1:-1;;;;;42779:54;;;;29763:2;29748:18;;17565:58;29846:2;29831:18;;19294:37;29591:2;29576:18;;29562:298::o;29867:668::-;19294:37;;;-1:-1;;;;;42779:54;;;30271:2;30256:18;;17722:45;42779:54;;;30354:2;30339:18;;17722:45;30437:2;30422:18;;19294:37;42779:54;30520:3;30505:19;;17722:45;30106:3;30091:19;;30077:458::o;30542:912::-;19294:37;;;-1:-1;;;;;42779:54;;;31012:2;30997:18;;17722:45;42779:54;;;31095:2;31080:18;;17722:45;31178:2;31163:18;;19294:37;;;;42779:54;;31261:3;31246:19;;17722:45;42500:13;42493:21;42790:42;31324:19;;19187:34;42779:54;31439:3;31424:19;;17722:45;30847:3;30832:19;;30818:636::o;31461:306::-;;31606:2;31627:17;31620:47;31681:76;31606:2;31595:9;31591:18;31743:6;31681:76;:::i;32029:628::-;-1:-1;;;;;42779:54;;;20260:63;;32455:2;32440:18;;19294:37;;;;42779:54;;32552:2;32537:18;;20260:63;32643:2;32628:18;;21068:58;;;;32276:3;32261:19;;32247:410::o;33762:416::-;33962:2;33976:47;;;21717:2;33947:18;;;41666:19;21753:34;41706:14;;;21733:55;-1:-1;;;21808:12;;;21801:30;21850:12;;;33933:245::o;34185:416::-;34385:2;34399:47;;;22101:2;34370:18;;;41666:19;-1:-1;;;41706:14;;;22117:37;22173:12;;;34356:245::o;34608:416::-;34808:2;34822:47;;;34793:18;;;41666:19;22460:34;41706:14;;;22440:55;22514:12;;;34779:245::o;35031:416::-;35231:2;35245:47;;;22765:2;35216:18;;;41666:19;22801:34;41706:14;;;22781:55;-1:-1;;;22856:12;;;22849:28;22896:12;;;35202:245::o;35454:416::-;35654:2;35668:47;;;23147:2;35639:18;;;41666:19;-1:-1;;;41706:14;;;23163:34;23216:12;;;35625:245::o;35877:416::-;36077:2;36091:47;;;23738:2;36062:18;;;41666:19;23774:31;41706:14;;;23754:52;23825:12;;;36048:245::o;36300:416::-;36500:2;36514:47;;;24076:1;36485:18;;;41666:19;-1:-1;;;41706:14;;;24091:32;24142:12;;;36471:245::o;36723:416::-;36923:2;36937:47;;;24393:2;36908:18;;;41666:19;24429:34;41706:14;;;24409:55;-1:-1;;;24484:12;;;24477:34;24530:12;;;36894:245::o;37146:416::-;37346:2;37360:47;;;24781:2;37331:18;;;41666:19;24817:34;41706:14;;;24797:55;-1:-1;;;24872:12;;;24865:46;24930:12;;;37317:245::o;37569:978::-;19294:37;;;-1:-1;;;;;42779:54;;;38088:2;38073:18;;17565:58;42779:54;;38179:2;38164:18;;17565:58;42790:42;38216:2;38201:18;;38194:48;;;37569:978;37900:19;;;41666;;;41706:14;38420:3;38405:19;;38398:49;;;38461:76;;41706:14;;38523:6;38461:76;:::i;:::-;38453:84;37886:661;-1:-1;;;;;;37886:661::o;38554:333::-;19294:37;;;38873:2;38858:18;;19294:37;38709:2;38694:18;;38680:207::o;38894:532::-;19294:37;;;39258:2;39243:18;;19294:37;;;;42500:13;42493:21;39335:2;39320:18;;19187:34;42500:13;42493:21;39412:2;39397:18;;19187:34;39093:3;39078:19;;39064:362::o;39433:256::-;39495:2;39489:9;39521:17;;;39596:18;39581:34;;39617:22;;;39578:62;39575:2;;;39653:1;;39643:12;39575:2;39495;39662:22;39473:216;;-1:-1;39473:216::o;39696:343::-;;39894:18;39886:6;39883:30;39880:2;;;-1:-1;;39916:12;39880:2;-1:-1;39961:4;39949:17;;;40014:15;;39817:222::o;44975:268::-;45040:1;45047:101;45061:6;45058:1;45055:13;45047:101;;;45128:11;;;45122:18;45109:11;;;45102:39;45083:2;45076:10;45047:101;;;45163:6;45160:1;45157:13;45154:2;;;45040:1;45219:6;45214:3;45210:16;45203:27;45154:2;;45024:219;;;:::o;45356:117::-;-1:-1;;;;;42779:54;;45415:35;;45405:2;;45464:1;;45454:12;45620:111;45701:5;42500:13;42493:21;45679:5;45676:32;45666:2;;45722:1;;45712:12
Swarm Source
ipfs://6016df3671fb01a3c3dbbef364ee859b4eba37d08bbeda5aabb644e8ff0e2fac
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.