Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
AbcModelCompounderSeeder
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "@openzeppelin/contracts/math/Math.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol"; import "./interfaces/IModelPair.sol"; import "./interfaces/IModelV2Pool.sol"; import "./interfaces/IAbcModelManager.sol"; contract AbcModelCompounderSeeder is ReentrancyGuardUpgradeable, OwnableUpgradeable { using SafeERC20 for IERC20; using SafeMath for uint256; /* ========== STATE VARIABLES ========== */ struct Reward { uint256 periodFinish; uint256 rewardRate; uint256 lastUpdateTime; uint256 rewardPerTokenStored; } struct PairInfo { address token0; address token1; } /* ========== CONSTANTS ========== */ uint160 internal constant MIN_SQRT_RATIO = 4295128739; uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342; /* ========== STORAGE ========== */ string public __NAME__; address public model; address public abcModel; address public abcModelCompounder; address public abcModelManager; address public abcModelPair; // Rewards address[] public rewardTokens; // Duration that rewards are streamed over uint256 public rewardsDuration; // reward token -> distributor -> is approved to add rewards mapping(address => mapping(address => bool)) public rewardDistributors; mapping(address => Reward) public rewardData; mapping(address => address[]) public routeForToken; mapping(address => address[]) public routeForModel; mapping(address => PairInfo) public pairInfo; mapping(address => bool) public isV2Pair; /* ========== EVENTS ========== */ event RewardAdded(address indexed token, uint256 amount); event RewardPaid( address indexed user, address indexed rewardToken, uint256 amount ); /* ========== CONSTRUCTOR ========== */ constructor() public {} function initialize( string memory name, address model_, address abcModel_, address abcModelPair_, address abcModelManager_ ) public initializer { __Ownable_init(); __ReentrancyGuard_init(); __NAME__ = name; rewardsDuration = 86400 * 7; model = model_; abcModel = abcModel_; abcModelPair = abcModelPair_; abcModelManager = abcModelManager_; } /* ========== ADMIN CONFIGURATION ========== */ function setAbcModelCompounder( address newAbcModelCompounder ) external onlyOwner { require(newAbcModelCompounder != address(0), "addr 0"); abcModelCompounder = newAbcModelCompounder; } function setAbcModelManager(address newAbcModelManager) external onlyOwner { require(newAbcModelManager != address(0), "addr 0"); abcModelManager = newAbcModelManager; } function setRewardRate(uint256 i, uint256 rewardRate) external onlyOwner { Reward storage rdata = rewardData[rewardTokens[i]]; rdata.rewardRate = rewardRate; } function setAbcModelPair(address newAbcModelPair) external onlyOwner { // require(newAbcModelPair != address(0), "addr 0"); abcModelPair = newAbcModelPair; _setRouteInfo(abcModelPair); } function setRouteForToken( address token, address[] calldata routes ) external onlyOwner { delete routeForToken[token]; uint256 len = routes.length; for (uint256 i; i < len; ++i) { _setRouteInfo(routes[i]); routeForToken[token].push(routes[i]); } } function setRouteForModel( address token, address[] calldata routes ) external onlyOwner { delete routeForModel[token]; uint256 len = routes.length; for (uint256 i; i < len; ++i) { _setRouteInfo(routes[i]); routeForModel[token].push(routes[i]); } } function setV2Pair(address pair, bool isV2) external onlyOwner { require( pairInfo[pair].token0 != address(0) && pairInfo[pair].token1 != address(0), "pair not set" ); isV2Pair[pair] = isV2; } // Add a new reward token to be distributed to stakers function addReward( address rewardToken, address distributor ) external onlyOwner { require(rewardData[rewardToken].lastUpdateTime == 0); rewardTokens.push(rewardToken); rewardData[rewardToken].lastUpdateTime = uint256(block.timestamp); rewardData[rewardToken].periodFinish = uint256(block.timestamp); rewardDistributors[rewardToken][distributor] = true; } // Modify approval for an address to call notifyRewardAmount function approveRewardDistributor( address rewardToken, address distributor, bool approved ) external onlyOwner { require(rewardData[rewardToken].lastUpdateTime > 0); rewardDistributors[rewardToken][distributor] = approved; } function isAbcModelPegged() external view returns (bool) { return _isAbcModelPegged(); } // claim all pending rewards function getReward() external { require(msg.sender == abcModelCompounder, "Not compounder"); uint256 len = rewardTokens.length; for (uint256 i; i < len; ++i) { Reward storage rdata = rewardData[rewardTokens[i]]; uint256 timePassed; if (block.timestamp >= rdata.periodFinish) { timePassed = rdata.periodFinish.sub(rdata.lastUpdateTime); } else { timePassed = block.timestamp.sub(rdata.lastUpdateTime); } uint256 reward = timePassed * rdata.rewardRate; if (rewardTokens[i] == abcModel) { IERC20(abcModel).transfer(abcModelCompounder, reward); } else if (!_isAbcModelPegged()) { uint256 amountOut = _swap(rewardTokens[i], reward, false); IERC20(abcModel).transfer(abcModelCompounder, amountOut); } else { uint256 amountOut = _swap(rewardTokens[i], reward, true); IERC20(model).safeApprove(abcModelManager, 0); IERC20(model).safeApprove(abcModelManager, amountOut); IAbcModelManager(abcModelManager).deposit(amountOut); IERC20(abcModel).transfer(abcModelCompounder, amountOut); } rdata.lastUpdateTime = Math.min( block.timestamp, rdata.periodFinish ); } } /* ========== RESTRICTED FUNCTIONS ========== */ function notifyRewardAmount(address rewardToken, uint256 reward) external { require(rewardDistributors[rewardToken][msg.sender]); require(reward > 0, "No reward"); _notifyReward(rewardToken, reward); // handle the transfer of reward tokens via `transferFrom` to reduce // the number of transactions required and ensure correctnes // of the reward amount IERC20(rewardToken).safeTransferFrom(msg.sender, address(this), reward); emit RewardAdded(rewardToken, reward); } // Added to support recovering LP Rewards from other systems such as BAL // to be distributed to holders function recoverERC20(address token, uint256 amount) external onlyOwner { IERC20(token).safeTransfer(owner(), amount); } function algebraSwapCallback( int256 amount0, int256 amount1, bytes calldata data ) external { _handleV2Callback(amount0, amount1, data); } function _notifyReward(address rewardsToken, uint256 reward) internal { Reward storage rdata = rewardData[rewardsToken]; if (block.timestamp >= rdata.periodFinish) { rdata.rewardRate = reward.div(rewardsDuration); } else { uint256 remaining = uint256(rdata.periodFinish).sub( block.timestamp ); uint256 leftover = remaining.mul(rdata.rewardRate); rdata.rewardRate = reward.add(leftover).div(rewardsDuration); } rdata.lastUpdateTime = block.timestamp; rdata.periodFinish = block.timestamp.add(rewardsDuration); } function _swap( address token, uint256 amountIn, bool isModelSwap ) internal returns (uint256 amountOut) { if (amountIn == 0) { return 0; } address[] memory routes; if (isModelSwap) { routes = routeForModel[token]; } else { routes = routeForToken[token]; } uint256 len = routes.length; for (uint256 i; i < len; ++i) { if (!isV2Pair[routes[i]]) { (amountOut, token) = _swapV1(routes[i], token, amountIn); } else { (amountOut, token) = _swapV2(routes[i], token, amountIn); } amountIn = amountOut; } if ( (isModelSwap && token != model) || (!isModelSwap && token != abcModel) ) { amountOut = _swap(token, amountIn, isModelSwap); } } function _swapV1( address pair, address token, uint256 amountIn ) internal returns (uint256 amountOut, address tokenOut) { PairInfo memory info = pairInfo[pair]; bool zeroToOne = info.token0 == token; amountOut = IModelPair(pair).getAmountOut(amountIn, token); IERC20(token).transfer(pair, amountIn); if (zeroToOne) { IModelPair(pair).swap(0, amountOut, address(this), ""); tokenOut = info.token1; } else { IModelPair(pair).swap(amountOut, 0, address(this), ""); tokenOut = info.token0; } } function _swapV2( address pair, address token, uint256 amountIn ) internal returns (uint256 amountOut, address tokenOut) { PairInfo memory info = pairInfo[pair]; bool zeroToOne = info.token0 == token; int256 amount = int256(amountIn); if (zeroToOne) { (, amount) = IModelV2Pool(pair).swap( address(this), zeroToOne, amount, MIN_SQRT_RATIO + 1, abi.encode(pair, token) ); tokenOut = info.token1; } else { (amount, ) = IModelV2Pool(pair).swap( address(this), zeroToOne, amount, MAX_SQRT_RATIO - 1, abi.encode(pair, token) ); tokenOut = info.token0; } amountOut = uint256(-amount); } function _isAbcModelPegged() internal view returns (bool) { if (abcModelPair == address(0)) { return true; } if (pairInfo[abcModelPair].token0 == abcModel) { return IModelPair(abcModelPair).reserve1() >= IModelPair(abcModelPair).reserve0(); } if (pairInfo[abcModelPair].token1 == abcModel) { return IModelPair(abcModelPair).reserve0() >= IModelPair(abcModelPair).reserve1(); } return true; } function _setRouteInfo(address pair) internal { pairInfo[pair] = PairInfo({ token0: IModelPair(pair).token0(), token1: IModelPair(pair).token1() }); } function _handleV2Callback( int256 amount0, int256 amount1, bytes calldata data ) internal { require(isV2Pair[msg.sender]); (address pair, address token) = abi.decode(data, (address, address)); bool zeroToOne = pairInfo[pair].token0 == token; IERC20(token).transfer(pair, uint256(zeroToOne ? amount0 : amount1)); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal initializer { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal initializer { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // solhint-disable-next-line compiler-version pragma solidity >=0.4.24 <0.8.0; import "../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../proxy/Initializable.sol"; /* * @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 ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } 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; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../proxy/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal initializer { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal initializer { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./IERC20.sol"; import "../../math/SafeMath.sol"; import "../../utils/Address.sol"; /** * @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"); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; interface IAbcModelManager { function disableRedeem() external; function getCurrentEpoch() external view returns (uint256); function deposit(uint256 _amount) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; interface IModelPair { function metadata() external view returns ( uint dec0, uint dec1, uint r0, uint r1, bool st, address t0, address t1 ); function claimFees() external returns (uint, uint); function tokens() external view returns (address, address); function transferFrom( address src, address dst, uint amount ) external returns (bool); function permit( address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s ) external; function swap( uint amount0Out, uint amount1Out, address to, bytes calldata data ) external; function burn(address to) external returns (uint amount0, uint amount1); function mint(address to) external returns (uint liquidity); function getReserves() external view returns (uint _reserve0, uint _reserve1, uint _blockTimestampLast); function getAmountOut(uint, address) external view returns (uint); function name() external view returns (string memory); function symbol() external view returns (string memory); function totalSupply() external view returns (uint); function decimals() external view returns (uint8); function claimable0(address _user) external view returns (uint); function claimable1(address _user) external view returns (uint); function isStable() external view returns (bool); function stable() external view returns (bool); function token0() external view returns (address); function reserve0() external view returns (uint256); function decimals0() external view returns (uint256); function token1() external view returns (address); function reserve1() external view returns (uint256); function decimals1() external view returns (uint256); function current( address tokenIn, uint256 amountIn ) external view returns (uint256 amountOut); }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; interface IModelV2Pool { function swap( address recipient, bool zeroForOne, int256 amountSpecified, uint160 sqrtPriceLimitX96, bytes calldata data ) external returns (int256 amount0, int256 amount1); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"rewardToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardPaid","type":"event"},{"inputs":[],"name":"__NAME__","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"abcModel","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"abcModelCompounder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"abcModelManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"abcModelPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"address","name":"distributor","type":"address"}],"name":"addReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int256","name":"amount0","type":"int256"},{"internalType":"int256","name":"amount1","type":"int256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"algebraSwapCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"address","name":"distributor","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"approveRewardDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"model_","type":"address"},{"internalType":"address","name":"abcModel_","type":"address"},{"internalType":"address","name":"abcModelPair_","type":"address"},{"internalType":"address","name":"abcModelManager_","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isAbcModelPegged","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isV2Pair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"model","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"uint256","name":"reward","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pairInfo","outputs":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardData","outputs":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"rewardDistributors","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"routeForModel","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"routeForToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAbcModelCompounder","type":"address"}],"name":"setAbcModelCompounder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAbcModelManager","type":"address"}],"name":"setAbcModelManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAbcModelPair","type":"address"}],"name":"setAbcModelPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"i","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"}],"name":"setRewardRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address[]","name":"routes","type":"address[]"}],"name":"setRouteForModel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address[]","name":"routes","type":"address[]"}],"name":"setRouteForToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"bool","name":"isV2","type":"bool"}],"name":"setV2Pair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50612f4b806100206000396000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c8063715018a61161010f578063cb3b4d1f116100a2578063e98d678711610071578063e98d6787146103eb578063f1819bb5146103fe578063f2fde38b14610413578063ff82698614610426576101f0565b8063cb3b4d1f146103b2578063d8cee8b6146103ba578063dc0a4229146103c2578063e5fd67e3146103e3576101f0565b80638da5cb5b116100de5780638da5cb5b14610371578063a677fc3114610379578063ac82d7671461038c578063b66503cf1461039f576101f0565b8063715018a6146103305780637bb7bed1146103385780638980f11f1461034b5780638d5622a01461035e576101f0565b80633d18b9121161018757806352b1c2e21161015657806352b1c2e2146102ef5780635f45ac8314610302578063672098af1461030a5780636724c9101461031d576101f0565b80633d18b9121461029e57806340b47e1a146102a657806348e5d9f8146102b95780634d2af2f8146102dc576101f0565b80633462e0a8116101c35780633462e0a81461024e578063386a95251461026157806339fc9713146102765780633a00009a14610296576101f0565b80630ad9d052146101f55780630b885ac314610213578063177787f4146102285780632c8958f61461023b575b600080fd5b6101fd610439565b60405161020a9190612a3c565b60405180910390f35b6102266102213660046128c1565b610448565b005b6101fd6102363660046127dc565b61054e565b610226610249366004612846565b610583565b61022661025c3660046129d3565b610595565b610269610616565b60405161020a9190612e8b565b6102896102843660046126d1565b61061c565b60405161020a9190612ae2565b61028961063c565b61022661064c565b6102266102b43660046126d1565b610a0a565b6102cc6102c7366004612661565b610af6565b60405161020a9493929190612eab565b6102266102ea366004612661565b610b1d565b6102266102fd36600461272d565b610ba4565b6101fd610cb1565b6101fd6103183660046127dc565b610cc0565b61022661032b3660046126e3565b610cd9565b610226610d77565b6101fd6103463660046129a3565b610e00565b6102266103593660046127dc565b610e27565b61022661036c366004612661565b610e82565b6101fd610eef565b61022661038736600461272d565b610efe565b61022661039a3660046127af565b610fea565b6102266103ad3660046127dc565b6110b5565b6101fd611169565b6101fd611178565b6103d56103d0366004612661565b611187565b60405161020a929190612a50565b6101fd6111ad565b6102266103f9366004612661565b6111bc565b610406611243565b60405161020a9190612b1b565b610226610421366004612661565b6112d1565b610289610434366004612661565b611392565b6098546001600160a01b031681565b600054610100900460ff168061046157506104616113a7565b8061046f575060005460ff16155b6104945760405162461bcd60e51b815260040161048b90612c85565b60405180910390fd5b600054610100900460ff161580156104bf576000805460ff1961ff0019909116610100171660011790555b6104c76113b8565b6104cf61144a565b85516104e290609790602089019061258e565b5062093a80609e55609880546001600160a01b038088166001600160a01b03199283161790925560998054878416908316179055609c8054868416908316179055609b8054928516929091169190911790558015610546576000805461ff00191690555b505050505050565b60a2602052816000526040600020818154811061056757fe5b6000918252602090912001546001600160a01b03169150829050565b61058f848484846114c0565b50505050565b61059d61159f565b6001600160a01b03166105ae610eef565b6001600160a01b0316146105d45760405162461bcd60e51b815260040161048b90612d37565b600060a06000609d85815481106105e757fe5b60009182526020808320909101546001600160a01b031683528201929092526040019020600101919091555050565b609e5481565b609f60209081526000928352604080842090915290825290205460ff1681565b60006106466115a3565b90505b90565b609a546001600160a01b031633146106765760405162461bcd60e51b815260040161048b90612e63565b609d5460005b81811015610a0657600060a06000609d848154811061069757fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120805490925042106106dd57600282015482546106d691611804565b90506106f0565b60028201546106ed904290611804565b90505b6001820154609954609d8054928402926001600160a01b03909216918690811061071657fe5b6000918252602090912001546001600160a01b031614156107bf57609954609a5460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb92610767929116908590600401612ac9565b602060405180830381600087803b15801561078157600080fd5b505af1158015610795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b99190612807565b506109e5565b6107c76115a3565b61088a5760006107f9609d86815481106107dd57fe5b60009182526020822001546001600160a01b0316908490611831565b609954609a5460405163a9059cbb60e01b81529293506001600160a01b039182169263a9059cbb926108319216908590600401612ac9565b602060405180830381600087803b15801561084b57600080fd5b505af115801561085f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108839190612807565b50506109e5565b60006108b9609d868154811061089c57fe5b6000918252602090912001546001600160a01b0316836001611831565b609b546098549192506108da916001600160a01b0390811691166000611a26565b609b546098546108f7916001600160a01b03918216911683611a26565b609b5460405163b6b55f2560e01b81526001600160a01b039091169063b6b55f2590610927908490600401612e8b565b600060405180830381600087803b15801561094157600080fd5b505af1158015610955573d6000803e3d6000fd5b5050609954609a5460405163a9059cbb60e01b81526001600160a01b03928316945063a9059cbb935061099092909116908590600401612ac9565b602060405180830381600087803b1580156109aa57600080fd5b505af11580156109be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e29190612807565b50505b6109f3428460000154611b25565b600290930192909255505060010161067c565b5050565b610a1261159f565b6001600160a01b0316610a23610eef565b6001600160a01b031614610a495760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b038216600090815260a0602052604090206002015415610a6f57600080fd5b609d805460018082019092557fd26e832454299e9fabb89e0e5fffdc046d4e14431bc1bf607ffb2e8a1ddecf7b0180546001600160a01b0319166001600160a01b03948516908117909155600090815260a06020908152604080832042600282018190559055609f825280832094909516825292909252919020805460ff19169091179055565b60a06020526000908152604090208054600182015460028301546003909301549192909184565b610b2561159f565b6001600160a01b0316610b36610eef565b6001600160a01b031614610b5c5760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b038116610b825760405162461bcd60e51b815260040161048b90612d6c565b609a80546001600160a01b0319166001600160a01b0392909216919091179055565b610bac61159f565b6001600160a01b0316610bbd610eef565b6001600160a01b031614610be35760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b038316600090815260a160205260408120610c049161260c565b8060005b81811015610caa57610c39848483818110610c1f57fe5b9050602002016020810190610c349190612661565b611b3b565b6001600160a01b038516600090815260a160205260409020848483818110610c5d57fe5b9050602002016020810190610c729190612661565b815460018082018455600093845260209093200180546001600160a01b0319166001600160a01b039290921691909117905501610c08565b5050505050565b609b546001600160a01b031681565b60a1602052816000526040600020818154811061056757fe5b610ce161159f565b6001600160a01b0316610cf2610eef565b6001600160a01b031614610d185760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b038316600090815260a06020526040902060020154610d3d57600080fd5b6001600160a01b039283166000908152609f6020908152604080832094909516825292909252919020805460ff1916911515919091179055565b610d7f61159f565b6001600160a01b0316610d90610eef565b6001600160a01b031614610db65760405162461bcd60e51b815260040161048b90612d37565b6065546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3606580546001600160a01b0319169055565b609d8181548110610e0d57fe5b6000918252602090912001546001600160a01b0316905081565b610e2f61159f565b6001600160a01b0316610e40610eef565b6001600160a01b031614610e665760405162461bcd60e51b815260040161048b90612d37565b610a06610e71610eef565b6001600160a01b0384169083611c85565b610e8a61159f565b6001600160a01b0316610e9b610eef565b6001600160a01b031614610ec15760405162461bcd60e51b815260040161048b90612d37565b609c80546001600160a01b0319166001600160a01b038381169190911791829055610eec9116611b3b565b50565b6065546001600160a01b031690565b610f0661159f565b6001600160a01b0316610f17610eef565b6001600160a01b031614610f3d5760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b038316600090815260a260205260408120610f5e9161260c565b8060005b81811015610caa57610f79848483818110610c1f57fe5b6001600160a01b038516600090815260a260205260409020848483818110610f9d57fe5b9050602002016020810190610fb29190612661565b815460018082018455600093845260209093200180546001600160a01b0319166001600160a01b039290921691909117905501610f62565b610ff261159f565b6001600160a01b0316611003610eef565b6001600160a01b0316146110295760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b03828116600090815260a36020526040902054161580159061106e57506001600160a01b03828116600090815260a360205260409020600101541615155b61108a5760405162461bcd60e51b815260040161048b90612bab565b6001600160a01b0391909116600090815260a460205260409020805460ff1916911515919091179055565b6001600160a01b0382166000908152609f6020908152604080832033845290915290205460ff166110e557600080fd5b600081116111055760405162461bcd60e51b815260040161048b90612cd3565b61110f8282611ca4565b6111246001600160a01b038316333084611d43565b816001600160a01b03167fac24935fd910bc682b5ccb1a07b718cadf8cf2f6d1404c4f3ddc3662dae40e298260405161115d9190612e8b565b60405180910390a25050565b6099546001600160a01b031681565b609a546001600160a01b031681565b60a360205260009081526040902080546001909101546001600160a01b03918216911682565b609c546001600160a01b031681565b6111c461159f565b6001600160a01b03166111d5610eef565b6001600160a01b0316146111fb5760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b0381166112215760405162461bcd60e51b815260040161048b90612d6c565b609b80546001600160a01b0319166001600160a01b0392909216919091179055565b6097805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156112c95780601f1061129e576101008083540402835291602001916112c9565b820191906000526020600020905b8154815290600101906020018083116112ac57829003601f168201915b505050505081565b6112d961159f565b6001600160a01b03166112ea610eef565b6001600160a01b0316146113105760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b0381166113365760405162461bcd60e51b815260040161048b90612b2e565b6065546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b60a46020526000908152604090205460ff1681565b60006113b230611d64565b15905090565b600054610100900460ff16806113d157506113d16113a7565b806113df575060005460ff16155b6113fb5760405162461bcd60e51b815260040161048b90612c85565b600054610100900460ff16158015611426576000805460ff1961ff0019909116610100171660011790555b61142e611d6a565b611436611deb565b8015610eec576000805461ff001916905550565b600054610100900460ff168061146357506114636113a7565b80611471575060005460ff16155b61148d5760405162461bcd60e51b815260040161048b90612c85565b600054610100900460ff161580156114b8576000805460ff1961ff0019909116610100171660011790555b611436611ec5565b33600090815260a4602052604090205460ff166114dc57600080fd5b6000806114eb83850185612699565b6001600160a01b03828116600090815260a36020526040902054929450909250828116911681149063a9059cbb84836115245788611526565b895b6040518363ffffffff1660e01b8152600401611543929190612ac9565b602060405180830381600087803b15801561155d57600080fd5b505af1158015611571573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115959190612807565b5050505050505050565b3390565b609c546000906001600160a01b03166115be57506001610649565b609954609c546001600160a01b03908116600090815260a360205260409020548116911614156116fd57609c60009054906101000a90046001600160a01b03166001600160a01b031663443cb4bc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561163657600080fd5b505afa15801561164a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166e91906129bb565b609c60009054906101000a90046001600160a01b03166001600160a01b0316635a76f25e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156116bc57600080fd5b505afa1580156116d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f491906129bb565b10159050610649565b609954609c546001600160a01b03908116600090815260a360205260409020600101548116911614156117fe57609c60009054906101000a90046001600160a01b03166001600160a01b0316635a76f25e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561177857600080fd5b505afa15801561178c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b091906129bb565b609c60009054906101000a90046001600160a01b03166001600160a01b031663443cb4bc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156116bc57600080fd5b50600190565b6000828211156118265760405162461bcd60e51b815260040161048b90612bd1565b508082035b92915050565b60008261184057506000611a1f565b606082156118bc576001600160a01b038516600090815260a26020908152604091829020805483518184028101840190945280845290918301828280156118b057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611892575b5050505050905061192c565b6001600160a01b038516600090815260a160209081526040918290208054835181840281018401909452808452909183018282801561192457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611906575b505050505090505b805160005b818110156119cb5760a4600084838151811061194957fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1661199b5761199283828151811061198357fe5b60200260200101518888611f4b565b975093506119be565b6119b98382815181106119aa57fe5b60200260200101518888612177565b975093505b9294508492600101611931565b508380156119e757506098546001600160a01b03878116911614155b80611a09575083158015611a0957506099546001600160a01b03878116911614155b15611a1c57611a19868686611831565b92505b50505b9392505050565b801580611aae5750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90611a5c9030908690600401612a50565b60206040518083038186803b158015611a7457600080fd5b505afa158015611a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aac91906129bb565b155b611aca5760405162461bcd60e51b815260040161048b90612e0d565b611b208363095ea7b360e01b8484604051602401611ae9929190612ac9565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261235d565b505050565b6000818310611b345781611a1f565b5090919050565b6040518060400160405280826001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015611b7f57600080fd5b505afa158015611b93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bb7919061267d565b6001600160a01b03168152602001826001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015611bfe57600080fd5b505afa158015611c12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c36919061267d565b6001600160a01b03908116909152918216600090815260a360209081526040909120825181549085166001600160a01b0319918216178255929091015160019091018054919093169116179055565b611b208363a9059cbb60e01b8484604051602401611ae9929190612ac9565b6001600160a01b038216600090815260a06020526040902080544210611cdc57609e54611cd29083906123ec565b6001820155611d28565b8054600090611ceb9042611804565b90506000611d0683600101548361241e90919063ffffffff16565b609e54909150611d2090611d1a8684612458565b906123ec565b600184015550505b4260028201819055609e54611d3d9190612458565b90555050565b61058f846323b872dd60e01b858585604051602401611ae993929190612a6a565b3b151590565b600054610100900460ff1680611d835750611d836113a7565b80611d91575060005460ff16155b611dad5760405162461bcd60e51b815260040161048b90612c85565b600054610100900460ff16158015611436576000805460ff1961ff0019909116610100171660011790558015610eec576000805461ff001916905550565b600054610100900460ff1680611e045750611e046113a7565b80611e12575060005460ff16155b611e2e5760405162461bcd60e51b815260040161048b90612c85565b600054610100900460ff16158015611e59576000805460ff1961ff0019909116610100171660011790555b6000611e6361159f565b606580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015610eec576000805461ff001916905550565b600054610100900460ff1680611ede5750611ede6113a7565b80611eec575060005460ff16155b611f085760405162461bcd60e51b815260040161048b90612c85565b600054610100900460ff16158015611f33576000805460ff1961ff0019909116610100171660011790555b600180558015610eec576000805461ff001916905550565b600080611f5661262a565b506001600160a01b03808616600081815260a36020908152604091829020825180840184528154861680825260019092015486169281019290925291516378a051ad60e11b815290938816909114919063f140a35a90611fbc9088908a90600401612e94565b60206040518083038186803b158015611fd457600080fd5b505afa158015611fe8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061200c91906129bb565b60405163a9059cbb60e01b81529094506001600160a01b0387169063a9059cbb9061203d908a908990600401612ac9565b602060405180830381600087803b15801561205757600080fd5b505af115801561206b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061208f9190612807565b5080156121055760405163022c0d9f60e01b81526001600160a01b0388169063022c0d9f906120c79060009088903090600401612aed565b600060405180830381600087803b1580156120e157600080fd5b505af11580156120f5573d6000803e3d6000fd5b505050508160200151925061216d565b60405163022c0d9f60e01b81526001600160a01b0388169063022c0d9f906121369087906000903090600401612aed565b600060405180830381600087803b15801561215057600080fd5b505af1158015612164573d6000803e3d6000fd5b50508351945050505b5050935093915050565b60008061218261262a565b506001600160a01b03808616600090815260a36020908152604091829020825180840190935280548416808452600190910154841691830191909152909186161484811561228857876001600160a01b031663128acb083084846401000276a36001018d8d6040516020016121f8929190612a50565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401612227959493929190612a8e565b6040805180830381600087803b15801561224057600080fd5b505af1158015612254573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122789190612823565b60208501519550915061234d9050565b876001600160a01b031663128acb08308484600173fffd8963efd1fc6a506488495d951d5263988d26038d8d6040516020016122c5929190612a50565b6040516020818303038152906040526040518663ffffffff1660e01b81526004016122f4959493929190612a8e565b6040805180830381600087803b15801561230d57600080fd5b505af1158015612321573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123459190612823565b508351945090505b6000039792965091945050505050565b60606123b2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661247d9092919063ffffffff16565b805190915015611b2057808060200190518101906123d09190612807565b611b205760405162461bcd60e51b815260040161048b90612dc3565b600080821161240d5760405162461bcd60e51b815260040161048b90612c4e565b81838161241657fe5b049392505050565b60008261242d5750600061182b565b8282028284828161243a57fe5b0414611a1f5760405162461bcd60e51b815260040161048b90612cf6565b600082820183811015611a1f5760405162461bcd60e51b815260040161048b90612b74565b606061248c8484600085612494565b949350505050565b6060824710156124b65760405162461bcd60e51b815260040161048b90612c08565b6124bf85611d64565b6124db5760405162461bcd60e51b815260040161048b90612d8c565b60006060866001600160a01b031685876040516124f89190612a20565b60006040518083038185875af1925050503d8060008114612535576040519150601f19603f3d011682016040523d82523d6000602084013e61253a565b606091505b509150915061254a828286612555565b979650505050505050565b60608315612564575081611a1f565b8251156125745782518084602001fd5b8160405162461bcd60e51b815260040161048b9190612b1b565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106125cf57805160ff19168380011785556125fc565b828001600101855582156125fc579182015b828111156125fc5782518255916020019190600101906125e1565b50612608929150612641565b5090565b5080546000825590600052602060002090810190610eec9190612641565b604080518082019091526000808252602082015290565b5b808211156126085760008155600101612642565b803561182b81612ef2565b600060208284031215612672578081fd5b8135611a1f81612ef2565b60006020828403121561268e578081fd5b8151611a1f81612ef2565b600080604083850312156126ab578081fd5b82356126b681612ef2565b915060208301356126c681612ef2565b809150509250929050565b600080604083850312156126ab578182fd5b6000806000606084860312156126f7578081fd5b833561270281612ef2565b9250602084013561271281612ef2565b9150604084013561272281612f07565b809150509250925092565b600080600060408486031215612741578283fd5b833561274c81612ef2565b9250602084013567ffffffffffffffff80821115612768578384fd5b818601915086601f83011261277b578384fd5b813581811115612789578485fd5b876020808302850101111561279c578485fd5b6020830194508093505050509250925092565b600080604083850312156127c1578182fd5b82356127cc81612ef2565b915060208301356126c681612f07565b600080604083850312156127ee578182fd5b82356127f981612ef2565b946020939093013593505050565b600060208284031215612818578081fd5b8151611a1f81612f07565b60008060408385031215612835578182fd5b505080516020909101519092909150565b6000806000806060858703121561285b578081fd5b8435935060208501359250604085013567ffffffffffffffff80821115612880578283fd5b818701915087601f830112612893578283fd5b8135818111156128a1578384fd5b8860208285010111156128b2578384fd5b95989497505060200194505050565b600080600080600060a086880312156128d8578081fd5b853567ffffffffffffffff808211156128ef578283fd5b818801915088601f830112612902578283fd5b813581811115612910578384fd5b6040516020601f8301601f1916820181018481118382101715612931578687fd5b60405282825284830181018c1015612947578586fd5b8281860182840137858184840101528199506129658c828d01612656565b985050505050506129798760408801612656565b92506129888760608801612656565b91506129978760808801612656565b90509295509295909350565b6000602082840312156129b4578081fd5b5035919050565b6000602082840312156129cc578081fd5b5051919050565b600080604083850312156129e5578182fd5b50508035926020909101359150565b60008151808452612a0c816020860160208601612ec6565b601f01601f19169290920160200192915050565b60008251612a32818460208701612ec6565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0386811682528515156020830152604082018590528316606082015260a06080820181905260009061254a908301846129f4565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b92835260208301919091526001600160a01b0316604082015260806060820181905260009082015260a00190565b600060208252611a1f60208301846129f4565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600c908201526b1c185a5c881b9bdd081cd95d60a21b604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b602080825260099082015268139bc81c995dd85c9960ba1b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526006908201526506164647220360d41b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b6020808252600e908201526d2737ba1031b7b6b837bab73232b960911b604082015260600190565b90815260200190565b9182526001600160a01b0316602082015260400190565b93845260208401929092526040830152606082015260800190565b60005b83811015612ee1578181015183820152602001612ec9565b8381111561058f5750506000910152565b6001600160a01b0381168114610eec57600080fd5b8015158114610eec57600080fdfea264697066735822122094f236b6c79079b0ca21bd1711f05f0955023cfcd11b9a9ae4d37075ae2bba2c64736f6c634300060c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101f05760003560e01c8063715018a61161010f578063cb3b4d1f116100a2578063e98d678711610071578063e98d6787146103eb578063f1819bb5146103fe578063f2fde38b14610413578063ff82698614610426576101f0565b8063cb3b4d1f146103b2578063d8cee8b6146103ba578063dc0a4229146103c2578063e5fd67e3146103e3576101f0565b80638da5cb5b116100de5780638da5cb5b14610371578063a677fc3114610379578063ac82d7671461038c578063b66503cf1461039f576101f0565b8063715018a6146103305780637bb7bed1146103385780638980f11f1461034b5780638d5622a01461035e576101f0565b80633d18b9121161018757806352b1c2e21161015657806352b1c2e2146102ef5780635f45ac8314610302578063672098af1461030a5780636724c9101461031d576101f0565b80633d18b9121461029e57806340b47e1a146102a657806348e5d9f8146102b95780634d2af2f8146102dc576101f0565b80633462e0a8116101c35780633462e0a81461024e578063386a95251461026157806339fc9713146102765780633a00009a14610296576101f0565b80630ad9d052146101f55780630b885ac314610213578063177787f4146102285780632c8958f61461023b575b600080fd5b6101fd610439565b60405161020a9190612a3c565b60405180910390f35b6102266102213660046128c1565b610448565b005b6101fd6102363660046127dc565b61054e565b610226610249366004612846565b610583565b61022661025c3660046129d3565b610595565b610269610616565b60405161020a9190612e8b565b6102896102843660046126d1565b61061c565b60405161020a9190612ae2565b61028961063c565b61022661064c565b6102266102b43660046126d1565b610a0a565b6102cc6102c7366004612661565b610af6565b60405161020a9493929190612eab565b6102266102ea366004612661565b610b1d565b6102266102fd36600461272d565b610ba4565b6101fd610cb1565b6101fd6103183660046127dc565b610cc0565b61022661032b3660046126e3565b610cd9565b610226610d77565b6101fd6103463660046129a3565b610e00565b6102266103593660046127dc565b610e27565b61022661036c366004612661565b610e82565b6101fd610eef565b61022661038736600461272d565b610efe565b61022661039a3660046127af565b610fea565b6102266103ad3660046127dc565b6110b5565b6101fd611169565b6101fd611178565b6103d56103d0366004612661565b611187565b60405161020a929190612a50565b6101fd6111ad565b6102266103f9366004612661565b6111bc565b610406611243565b60405161020a9190612b1b565b610226610421366004612661565b6112d1565b610289610434366004612661565b611392565b6098546001600160a01b031681565b600054610100900460ff168061046157506104616113a7565b8061046f575060005460ff16155b6104945760405162461bcd60e51b815260040161048b90612c85565b60405180910390fd5b600054610100900460ff161580156104bf576000805460ff1961ff0019909116610100171660011790555b6104c76113b8565b6104cf61144a565b85516104e290609790602089019061258e565b5062093a80609e55609880546001600160a01b038088166001600160a01b03199283161790925560998054878416908316179055609c8054868416908316179055609b8054928516929091169190911790558015610546576000805461ff00191690555b505050505050565b60a2602052816000526040600020818154811061056757fe5b6000918252602090912001546001600160a01b03169150829050565b61058f848484846114c0565b50505050565b61059d61159f565b6001600160a01b03166105ae610eef565b6001600160a01b0316146105d45760405162461bcd60e51b815260040161048b90612d37565b600060a06000609d85815481106105e757fe5b60009182526020808320909101546001600160a01b031683528201929092526040019020600101919091555050565b609e5481565b609f60209081526000928352604080842090915290825290205460ff1681565b60006106466115a3565b90505b90565b609a546001600160a01b031633146106765760405162461bcd60e51b815260040161048b90612e63565b609d5460005b81811015610a0657600060a06000609d848154811061069757fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120805490925042106106dd57600282015482546106d691611804565b90506106f0565b60028201546106ed904290611804565b90505b6001820154609954609d8054928402926001600160a01b03909216918690811061071657fe5b6000918252602090912001546001600160a01b031614156107bf57609954609a5460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb92610767929116908590600401612ac9565b602060405180830381600087803b15801561078157600080fd5b505af1158015610795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b99190612807565b506109e5565b6107c76115a3565b61088a5760006107f9609d86815481106107dd57fe5b60009182526020822001546001600160a01b0316908490611831565b609954609a5460405163a9059cbb60e01b81529293506001600160a01b039182169263a9059cbb926108319216908590600401612ac9565b602060405180830381600087803b15801561084b57600080fd5b505af115801561085f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108839190612807565b50506109e5565b60006108b9609d868154811061089c57fe5b6000918252602090912001546001600160a01b0316836001611831565b609b546098549192506108da916001600160a01b0390811691166000611a26565b609b546098546108f7916001600160a01b03918216911683611a26565b609b5460405163b6b55f2560e01b81526001600160a01b039091169063b6b55f2590610927908490600401612e8b565b600060405180830381600087803b15801561094157600080fd5b505af1158015610955573d6000803e3d6000fd5b5050609954609a5460405163a9059cbb60e01b81526001600160a01b03928316945063a9059cbb935061099092909116908590600401612ac9565b602060405180830381600087803b1580156109aa57600080fd5b505af11580156109be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e29190612807565b50505b6109f3428460000154611b25565b600290930192909255505060010161067c565b5050565b610a1261159f565b6001600160a01b0316610a23610eef565b6001600160a01b031614610a495760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b038216600090815260a0602052604090206002015415610a6f57600080fd5b609d805460018082019092557fd26e832454299e9fabb89e0e5fffdc046d4e14431bc1bf607ffb2e8a1ddecf7b0180546001600160a01b0319166001600160a01b03948516908117909155600090815260a06020908152604080832042600282018190559055609f825280832094909516825292909252919020805460ff19169091179055565b60a06020526000908152604090208054600182015460028301546003909301549192909184565b610b2561159f565b6001600160a01b0316610b36610eef565b6001600160a01b031614610b5c5760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b038116610b825760405162461bcd60e51b815260040161048b90612d6c565b609a80546001600160a01b0319166001600160a01b0392909216919091179055565b610bac61159f565b6001600160a01b0316610bbd610eef565b6001600160a01b031614610be35760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b038316600090815260a160205260408120610c049161260c565b8060005b81811015610caa57610c39848483818110610c1f57fe5b9050602002016020810190610c349190612661565b611b3b565b6001600160a01b038516600090815260a160205260409020848483818110610c5d57fe5b9050602002016020810190610c729190612661565b815460018082018455600093845260209093200180546001600160a01b0319166001600160a01b039290921691909117905501610c08565b5050505050565b609b546001600160a01b031681565b60a1602052816000526040600020818154811061056757fe5b610ce161159f565b6001600160a01b0316610cf2610eef565b6001600160a01b031614610d185760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b038316600090815260a06020526040902060020154610d3d57600080fd5b6001600160a01b039283166000908152609f6020908152604080832094909516825292909252919020805460ff1916911515919091179055565b610d7f61159f565b6001600160a01b0316610d90610eef565b6001600160a01b031614610db65760405162461bcd60e51b815260040161048b90612d37565b6065546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3606580546001600160a01b0319169055565b609d8181548110610e0d57fe5b6000918252602090912001546001600160a01b0316905081565b610e2f61159f565b6001600160a01b0316610e40610eef565b6001600160a01b031614610e665760405162461bcd60e51b815260040161048b90612d37565b610a06610e71610eef565b6001600160a01b0384169083611c85565b610e8a61159f565b6001600160a01b0316610e9b610eef565b6001600160a01b031614610ec15760405162461bcd60e51b815260040161048b90612d37565b609c80546001600160a01b0319166001600160a01b038381169190911791829055610eec9116611b3b565b50565b6065546001600160a01b031690565b610f0661159f565b6001600160a01b0316610f17610eef565b6001600160a01b031614610f3d5760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b038316600090815260a260205260408120610f5e9161260c565b8060005b81811015610caa57610f79848483818110610c1f57fe5b6001600160a01b038516600090815260a260205260409020848483818110610f9d57fe5b9050602002016020810190610fb29190612661565b815460018082018455600093845260209093200180546001600160a01b0319166001600160a01b039290921691909117905501610f62565b610ff261159f565b6001600160a01b0316611003610eef565b6001600160a01b0316146110295760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b03828116600090815260a36020526040902054161580159061106e57506001600160a01b03828116600090815260a360205260409020600101541615155b61108a5760405162461bcd60e51b815260040161048b90612bab565b6001600160a01b0391909116600090815260a460205260409020805460ff1916911515919091179055565b6001600160a01b0382166000908152609f6020908152604080832033845290915290205460ff166110e557600080fd5b600081116111055760405162461bcd60e51b815260040161048b90612cd3565b61110f8282611ca4565b6111246001600160a01b038316333084611d43565b816001600160a01b03167fac24935fd910bc682b5ccb1a07b718cadf8cf2f6d1404c4f3ddc3662dae40e298260405161115d9190612e8b565b60405180910390a25050565b6099546001600160a01b031681565b609a546001600160a01b031681565b60a360205260009081526040902080546001909101546001600160a01b03918216911682565b609c546001600160a01b031681565b6111c461159f565b6001600160a01b03166111d5610eef565b6001600160a01b0316146111fb5760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b0381166112215760405162461bcd60e51b815260040161048b90612d6c565b609b80546001600160a01b0319166001600160a01b0392909216919091179055565b6097805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156112c95780601f1061129e576101008083540402835291602001916112c9565b820191906000526020600020905b8154815290600101906020018083116112ac57829003601f168201915b505050505081565b6112d961159f565b6001600160a01b03166112ea610eef565b6001600160a01b0316146113105760405162461bcd60e51b815260040161048b90612d37565b6001600160a01b0381166113365760405162461bcd60e51b815260040161048b90612b2e565b6065546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b60a46020526000908152604090205460ff1681565b60006113b230611d64565b15905090565b600054610100900460ff16806113d157506113d16113a7565b806113df575060005460ff16155b6113fb5760405162461bcd60e51b815260040161048b90612c85565b600054610100900460ff16158015611426576000805460ff1961ff0019909116610100171660011790555b61142e611d6a565b611436611deb565b8015610eec576000805461ff001916905550565b600054610100900460ff168061146357506114636113a7565b80611471575060005460ff16155b61148d5760405162461bcd60e51b815260040161048b90612c85565b600054610100900460ff161580156114b8576000805460ff1961ff0019909116610100171660011790555b611436611ec5565b33600090815260a4602052604090205460ff166114dc57600080fd5b6000806114eb83850185612699565b6001600160a01b03828116600090815260a36020526040902054929450909250828116911681149063a9059cbb84836115245788611526565b895b6040518363ffffffff1660e01b8152600401611543929190612ac9565b602060405180830381600087803b15801561155d57600080fd5b505af1158015611571573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115959190612807565b5050505050505050565b3390565b609c546000906001600160a01b03166115be57506001610649565b609954609c546001600160a01b03908116600090815260a360205260409020548116911614156116fd57609c60009054906101000a90046001600160a01b03166001600160a01b031663443cb4bc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561163657600080fd5b505afa15801561164a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166e91906129bb565b609c60009054906101000a90046001600160a01b03166001600160a01b0316635a76f25e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156116bc57600080fd5b505afa1580156116d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f491906129bb565b10159050610649565b609954609c546001600160a01b03908116600090815260a360205260409020600101548116911614156117fe57609c60009054906101000a90046001600160a01b03166001600160a01b0316635a76f25e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561177857600080fd5b505afa15801561178c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b091906129bb565b609c60009054906101000a90046001600160a01b03166001600160a01b031663443cb4bc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156116bc57600080fd5b50600190565b6000828211156118265760405162461bcd60e51b815260040161048b90612bd1565b508082035b92915050565b60008261184057506000611a1f565b606082156118bc576001600160a01b038516600090815260a26020908152604091829020805483518184028101840190945280845290918301828280156118b057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611892575b5050505050905061192c565b6001600160a01b038516600090815260a160209081526040918290208054835181840281018401909452808452909183018282801561192457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611906575b505050505090505b805160005b818110156119cb5760a4600084838151811061194957fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1661199b5761199283828151811061198357fe5b60200260200101518888611f4b565b975093506119be565b6119b98382815181106119aa57fe5b60200260200101518888612177565b975093505b9294508492600101611931565b508380156119e757506098546001600160a01b03878116911614155b80611a09575083158015611a0957506099546001600160a01b03878116911614155b15611a1c57611a19868686611831565b92505b50505b9392505050565b801580611aae5750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90611a5c9030908690600401612a50565b60206040518083038186803b158015611a7457600080fd5b505afa158015611a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aac91906129bb565b155b611aca5760405162461bcd60e51b815260040161048b90612e0d565b611b208363095ea7b360e01b8484604051602401611ae9929190612ac9565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261235d565b505050565b6000818310611b345781611a1f565b5090919050565b6040518060400160405280826001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015611b7f57600080fd5b505afa158015611b93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bb7919061267d565b6001600160a01b03168152602001826001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015611bfe57600080fd5b505afa158015611c12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c36919061267d565b6001600160a01b03908116909152918216600090815260a360209081526040909120825181549085166001600160a01b0319918216178255929091015160019091018054919093169116179055565b611b208363a9059cbb60e01b8484604051602401611ae9929190612ac9565b6001600160a01b038216600090815260a06020526040902080544210611cdc57609e54611cd29083906123ec565b6001820155611d28565b8054600090611ceb9042611804565b90506000611d0683600101548361241e90919063ffffffff16565b609e54909150611d2090611d1a8684612458565b906123ec565b600184015550505b4260028201819055609e54611d3d9190612458565b90555050565b61058f846323b872dd60e01b858585604051602401611ae993929190612a6a565b3b151590565b600054610100900460ff1680611d835750611d836113a7565b80611d91575060005460ff16155b611dad5760405162461bcd60e51b815260040161048b90612c85565b600054610100900460ff16158015611436576000805460ff1961ff0019909116610100171660011790558015610eec576000805461ff001916905550565b600054610100900460ff1680611e045750611e046113a7565b80611e12575060005460ff16155b611e2e5760405162461bcd60e51b815260040161048b90612c85565b600054610100900460ff16158015611e59576000805460ff1961ff0019909116610100171660011790555b6000611e6361159f565b606580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015610eec576000805461ff001916905550565b600054610100900460ff1680611ede5750611ede6113a7565b80611eec575060005460ff16155b611f085760405162461bcd60e51b815260040161048b90612c85565b600054610100900460ff16158015611f33576000805460ff1961ff0019909116610100171660011790555b600180558015610eec576000805461ff001916905550565b600080611f5661262a565b506001600160a01b03808616600081815260a36020908152604091829020825180840184528154861680825260019092015486169281019290925291516378a051ad60e11b815290938816909114919063f140a35a90611fbc9088908a90600401612e94565b60206040518083038186803b158015611fd457600080fd5b505afa158015611fe8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061200c91906129bb565b60405163a9059cbb60e01b81529094506001600160a01b0387169063a9059cbb9061203d908a908990600401612ac9565b602060405180830381600087803b15801561205757600080fd5b505af115801561206b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061208f9190612807565b5080156121055760405163022c0d9f60e01b81526001600160a01b0388169063022c0d9f906120c79060009088903090600401612aed565b600060405180830381600087803b1580156120e157600080fd5b505af11580156120f5573d6000803e3d6000fd5b505050508160200151925061216d565b60405163022c0d9f60e01b81526001600160a01b0388169063022c0d9f906121369087906000903090600401612aed565b600060405180830381600087803b15801561215057600080fd5b505af1158015612164573d6000803e3d6000fd5b50508351945050505b5050935093915050565b60008061218261262a565b506001600160a01b03808616600090815260a36020908152604091829020825180840190935280548416808452600190910154841691830191909152909186161484811561228857876001600160a01b031663128acb083084846401000276a36001018d8d6040516020016121f8929190612a50565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401612227959493929190612a8e565b6040805180830381600087803b15801561224057600080fd5b505af1158015612254573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122789190612823565b60208501519550915061234d9050565b876001600160a01b031663128acb08308484600173fffd8963efd1fc6a506488495d951d5263988d26038d8d6040516020016122c5929190612a50565b6040516020818303038152906040526040518663ffffffff1660e01b81526004016122f4959493929190612a8e565b6040805180830381600087803b15801561230d57600080fd5b505af1158015612321573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123459190612823565b508351945090505b6000039792965091945050505050565b60606123b2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661247d9092919063ffffffff16565b805190915015611b2057808060200190518101906123d09190612807565b611b205760405162461bcd60e51b815260040161048b90612dc3565b600080821161240d5760405162461bcd60e51b815260040161048b90612c4e565b81838161241657fe5b049392505050565b60008261242d5750600061182b565b8282028284828161243a57fe5b0414611a1f5760405162461bcd60e51b815260040161048b90612cf6565b600082820183811015611a1f5760405162461bcd60e51b815260040161048b90612b74565b606061248c8484600085612494565b949350505050565b6060824710156124b65760405162461bcd60e51b815260040161048b90612c08565b6124bf85611d64565b6124db5760405162461bcd60e51b815260040161048b90612d8c565b60006060866001600160a01b031685876040516124f89190612a20565b60006040518083038185875af1925050503d8060008114612535576040519150601f19603f3d011682016040523d82523d6000602084013e61253a565b606091505b509150915061254a828286612555565b979650505050505050565b60608315612564575081611a1f565b8251156125745782518084602001fd5b8160405162461bcd60e51b815260040161048b9190612b1b565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106125cf57805160ff19168380011785556125fc565b828001600101855582156125fc579182015b828111156125fc5782518255916020019190600101906125e1565b50612608929150612641565b5090565b5080546000825590600052602060002090810190610eec9190612641565b604080518082019091526000808252602082015290565b5b808211156126085760008155600101612642565b803561182b81612ef2565b600060208284031215612672578081fd5b8135611a1f81612ef2565b60006020828403121561268e578081fd5b8151611a1f81612ef2565b600080604083850312156126ab578081fd5b82356126b681612ef2565b915060208301356126c681612ef2565b809150509250929050565b600080604083850312156126ab578182fd5b6000806000606084860312156126f7578081fd5b833561270281612ef2565b9250602084013561271281612ef2565b9150604084013561272281612f07565b809150509250925092565b600080600060408486031215612741578283fd5b833561274c81612ef2565b9250602084013567ffffffffffffffff80821115612768578384fd5b818601915086601f83011261277b578384fd5b813581811115612789578485fd5b876020808302850101111561279c578485fd5b6020830194508093505050509250925092565b600080604083850312156127c1578182fd5b82356127cc81612ef2565b915060208301356126c681612f07565b600080604083850312156127ee578182fd5b82356127f981612ef2565b946020939093013593505050565b600060208284031215612818578081fd5b8151611a1f81612f07565b60008060408385031215612835578182fd5b505080516020909101519092909150565b6000806000806060858703121561285b578081fd5b8435935060208501359250604085013567ffffffffffffffff80821115612880578283fd5b818701915087601f830112612893578283fd5b8135818111156128a1578384fd5b8860208285010111156128b2578384fd5b95989497505060200194505050565b600080600080600060a086880312156128d8578081fd5b853567ffffffffffffffff808211156128ef578283fd5b818801915088601f830112612902578283fd5b813581811115612910578384fd5b6040516020601f8301601f1916820181018481118382101715612931578687fd5b60405282825284830181018c1015612947578586fd5b8281860182840137858184840101528199506129658c828d01612656565b985050505050506129798760408801612656565b92506129888760608801612656565b91506129978760808801612656565b90509295509295909350565b6000602082840312156129b4578081fd5b5035919050565b6000602082840312156129cc578081fd5b5051919050565b600080604083850312156129e5578182fd5b50508035926020909101359150565b60008151808452612a0c816020860160208601612ec6565b601f01601f19169290920160200192915050565b60008251612a32818460208701612ec6565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0386811682528515156020830152604082018590528316606082015260a06080820181905260009061254a908301846129f4565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b92835260208301919091526001600160a01b0316604082015260806060820181905260009082015260a00190565b600060208252611a1f60208301846129f4565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600c908201526b1c185a5c881b9bdd081cd95d60a21b604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b602080825260099082015268139bc81c995dd85c9960ba1b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526006908201526506164647220360d41b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b6020808252600e908201526d2737ba1031b7b6b837bab73232b960911b604082015260600190565b90815260200190565b9182526001600160a01b0316602082015260400190565b93845260208401929092526040830152606082015260800190565b60005b83811015612ee1578181015183820152602001612ec9565b8381111561058f5750506000910152565b6001600160a01b0381168114610eec57600080fd5b8015158114610eec57600080fdfea264697066735822122094f236b6c79079b0ca21bd1711f05f0955023cfcd11b9a9ae4d37075ae2bba2c64736f6c634300060c0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.