Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 2237117 | 220 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Auction
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0
pragma solidity >=0.8.18;
import {Maths} from "../libraries/Maths.sol";
import {ITaker} from "../interfaces/ITaker.sol";
import {GPv2Order} from "../libraries/GPv2Order.sol";
import {Governance2Step} from "../utils/Governance2Step.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
interface ICowSettlement {
function domainSeparator() external view returns (bytes32);
}
/**
* @title Auction
* @author yearn.fi
* @notice General use dutch auction contract for token sales.
*/
contract Auction is Governance2Step, ReentrancyGuard {
using GPv2Order for GPv2Order.Data;
using SafeERC20 for ERC20;
/// @notice Emitted when a new auction is enabled
event AuctionEnabled(address indexed from, address indexed to);
/// @notice Emitted when an auction is disabled.
event AuctionDisabled(address indexed from, address indexed to);
/// @notice Emitted when auction has been kicked.
event AuctionKicked(address indexed from, uint256 available);
/// @notice Emitted when the starting price is updated.
event UpdatedStartingPrice(uint256 startingPrice);
/// @dev Store address and scaler in one slot.
struct TokenInfo {
address tokenAddress;
uint96 scaler;
}
/// @notice Store all the auction specific information.
struct AuctionInfo {
uint64 kicked;
uint64 scaler;
uint128 initialAvailable;
}
uint256 internal constant WAD = 1e18;
/// @notice Used for the price decay.
uint256 internal constant MINUTE_HALF_LIFE =
0.988514020352896135_356867505 * 1e27; // 0.5^(1/60)
address internal constant COW_SETTLEMENT =
0x9008D19f58AAbD9eD0D60971565AA8510560ab41;
address internal constant VAULT_RELAYER =
0xC92E8bdf79f0507f65a392b0ab4667716BFE0110;
bytes32 internal immutable COW_DOMAIN_SEPARATOR;
/// @notice Struct to hold the info for `want`.
TokenInfo internal wantInfo;
/// @notice The address that will receive the funds in the auction.
address public receiver;
/// @notice The amount to start the auction at.
uint256 public startingPrice;
/// @notice The time that each auction lasts.
uint256 public auctionLength;
/// @notice Mapping from `from` token to its struct.
mapping(address => AuctionInfo) public auctions;
/// @notice Array of all the enabled auction for this contract.
address[] public enabledAuctions;
constructor() Governance2Step(msg.sender) {
bytes32 domainSeparator;
if (COW_SETTLEMENT.code.length > 0) {
domainSeparator = ICowSettlement(COW_SETTLEMENT).domainSeparator();
} else {
domainSeparator = bytes32(0);
}
COW_DOMAIN_SEPARATOR = domainSeparator;
}
/**
* @notice Initializes the Auction contract with initial parameters.
* @param _want Address this auction is selling to.
* @param _receiver Address that will receive the funds from the auction.
* @param _governance Address of the contract governance.
* @param _auctionLength Duration of each auction in seconds.
* @param _startingPrice Starting price for each auction.
*/
function initialize(
address _want,
address _receiver,
address _governance,
uint256 _auctionLength,
uint256 _startingPrice
) public virtual {
require(auctionLength == 0, "initialized");
require(_want != address(0), "ZERO ADDRESS");
require(_auctionLength != 0, "length");
require(_startingPrice != 0, "starting price");
require(_receiver != address(0), "receiver");
// Cannot have more than 18 decimals.
uint256 decimals = ERC20(_want).decimals();
require(decimals <= 18, "unsupported decimals");
// Set variables
wantInfo = TokenInfo({
tokenAddress: _want,
scaler: uint96(WAD / 10 ** decimals)
});
receiver = _receiver;
governance = _governance;
auctionLength = _auctionLength;
startingPrice = _startingPrice;
emit UpdatedStartingPrice(_startingPrice);
}
/*//////////////////////////////////////////////////////////////
VIEW METHODS
//////////////////////////////////////////////////////////////*/
/**
* @notice Get the address of this auctions want token.
* @return . The want token.
*/
function want() public view virtual returns (address) {
return wantInfo.tokenAddress;
}
/**
* @notice Get the available amount for the auction.
* @param _from The address of the token to be auctioned.
* @return . The available amount for the auction.
*/
function available(address _from) public view virtual returns (uint256) {
if (!isActive(_from)) return 0;
return
Maths.min(
auctions[_from].initialAvailable,
ERC20(_from).balanceOf(address(this))
);
}
/**
* @notice Get the kicked timestamp for the auction.
* @param _from The address of the token to be auctioned.
* @return . The kicked timestamp for the auction.
*/
function kicked(address _from) external view virtual returns (uint256) {
return auctions[_from].kicked;
}
/**
* @notice Check if the auction is active.
* @param _from The address of the token to be auctioned.
* @return . Whether the auction is active.
*/
function isActive(address _from) public view virtual returns (bool) {
return auctions[_from].kicked + auctionLength >= block.timestamp;
}
/**
* @notice Get all the enabled auctions.
*/
function getAllEnabledAuctions()
external
view
virtual
returns (address[] memory)
{
return enabledAuctions;
}
/**
* @notice Get the pending amount available for the next auction.
* @dev Defaults to the auctions balance of the from token if no hook.
* @param _from The address of the token to be auctioned.
* @return uint256 The amount that can be kicked into the auction.
*/
function kickable(address _from) external view virtual returns (uint256) {
// If not enough time has passed then `kickable` is 0.
if (isActive(_from)) return 0;
// Use the full balance of this contract.
return ERC20(_from).balanceOf(address(this));
}
/**
* @notice Gets the amount of `want` needed to buy the available amount of `from`.
* @param _from The address of the token to be auctioned.
* @return . The amount of `want` needed to fulfill the take amount.
*/
function getAmountNeeded(
address _from
) external view virtual returns (uint256) {
return
_getAmountNeeded(
auctions[_from],
available(_from),
block.timestamp
);
}
/**
* @notice Gets the amount of `want` needed to buy a specific amount of `from`.
* @param _from The address of the token to be auctioned.
* @param _amountToTake The amount of `from` to take in the auction.
* @return . The amount of `want` needed to fulfill the take amount.
*/
function getAmountNeeded(
address _from,
uint256 _amountToTake
) external view virtual returns (uint256) {
return
_getAmountNeeded(auctions[_from], _amountToTake, block.timestamp);
}
/**
* @notice Gets the amount of `want` needed to buy a specific amount of `from` at a specific timestamp.
* @param _from The address of the token to be auctioned.
* @param _amountToTake The amount `from` to take in the auction.
* @param _timestamp The specific timestamp for calculating the amount needed.
* @return . The amount of `want` needed to fulfill the take amount.
*/
function getAmountNeeded(
address _from,
uint256 _amountToTake,
uint256 _timestamp
) external view virtual returns (uint256) {
return _getAmountNeeded(auctions[_from], _amountToTake, _timestamp);
}
/**
* @dev Return the amount of `want` needed to buy `_amountToTake`.
*/
function _getAmountNeeded(
AuctionInfo memory _auction,
uint256 _amountToTake,
uint256 _timestamp
) internal view virtual returns (uint256) {
return
// Scale _amountToTake to 1e18
(_amountToTake *
_auction.scaler *
// Price is always 1e18
_price(
_auction.kicked,
_auction.initialAvailable * _auction.scaler,
_timestamp
)) /
1e18 /
// Scale back down to want.
wantInfo.scaler;
}
/**
* @notice Gets the price of the auction at the current timestamp.
* @param _from The address of the token to be auctioned.
* @return . The price of the auction.
*/
function price(address _from) external view virtual returns (uint256) {
return price(_from, block.timestamp);
}
/**
* @notice Gets the price of the auction at a specific timestamp.
* @param _from The address of the token to be auctioned.
* @param _timestamp The specific timestamp for calculating the price.
* @return . The price of the auction.
*/
function price(
address _from,
uint256 _timestamp
) public view virtual returns (uint256) {
// Get unscaled price and scale it down.
return
_price(
auctions[_from].kicked,
auctions[_from].initialAvailable * auctions[_from].scaler,
_timestamp
) / wantInfo.scaler;
}
/**
* @dev Internal function to calculate the scaled price based on auction parameters.
* @param _kicked The timestamp the auction was kicked.
* @param _available The initial available amount scaled 1e18.
* @param _timestamp The specific timestamp for calculating the price.
* @return . The calculated price scaled to 1e18.
*/
function _price(
uint256 _kicked,
uint256 _available,
uint256 _timestamp
) internal view virtual returns (uint256) {
if (_available == 0) return 0;
uint256 secondsElapsed = _timestamp - _kicked;
if (secondsElapsed > auctionLength) return 0;
// Exponential step decay from https://github.com/ajna-finance/ajna-core/blob/master/src/libraries/helpers/PoolHelper.sol
uint256 hoursComponent = 1e27 >> (secondsElapsed / 3600);
uint256 minutesComponent = Maths.rpow(
MINUTE_HALF_LIFE,
(secondsElapsed % 3600) / 60
);
uint256 initialPrice = Maths.wdiv(startingPrice * 1e18, _available);
return
(initialPrice * Maths.rmul(hoursComponent, minutesComponent)) /
1e27;
}
/*//////////////////////////////////////////////////////////////
SETTERS
//////////////////////////////////////////////////////////////*/
/**
* @notice Enables a new auction.
* @param _from The address of the token to be auctioned.
*/
function enable(address _from) external virtual onlyGovernance {
address _want = want();
require(_from != address(0) && _from != _want, "ZERO ADDRESS");
require(auctions[_from].scaler == 0, "already enabled");
// Cannot have more than 18 decimals.
uint256 decimals = ERC20(_from).decimals();
require(decimals <= 18, "unsupported decimals");
// Store all needed info.
auctions[_from].scaler = uint64(WAD / 10 ** decimals);
ERC20(_from).safeApprove(VAULT_RELAYER, type(uint256).max);
// Add to the array.
enabledAuctions.push(_from);
emit AuctionEnabled(_from, _want);
}
/**
* @notice Disables an existing auction.
* @dev Only callable by governance.
* @param _from The address of the token being sold.
*/
function disable(address _from) external virtual {
disable(_from, 0);
}
/**
* @notice Disables an existing auction.
* @dev Only callable by governance.
* @param _from The address of the token being sold.
* @param _index The index the auctionId is at in the array.
*/
function disable(
address _from,
uint256 _index
) public virtual onlyGovernance {
// Make sure the auction was enabled.
require(auctions[_from].scaler != 0, "not enabled");
// Remove the struct.
delete auctions[_from];
ERC20(_from).safeApprove(VAULT_RELAYER, 0);
// Remove the auction ID from the array.
address[] memory _enabledAuctions = enabledAuctions;
if (_enabledAuctions[_index] != _from) {
// If the _index given is not the id find it.
for (uint256 i = 0; i < _enabledAuctions.length; ++i) {
if (_enabledAuctions[i] == _from) {
_index = i;
break;
}
}
}
// Move the id to the last spot if not there.
if (_index < _enabledAuctions.length - 1) {
_enabledAuctions[_index] = _enabledAuctions[
_enabledAuctions.length - 1
];
// Update the array.
enabledAuctions = _enabledAuctions;
}
// Pop the id off the array.
enabledAuctions.pop();
emit AuctionDisabled(_from, want());
}
/**
* @notice Sets the starting price for the auction.
* @param _startingPrice The new starting price for the auction.
*/
function setStartingPrice(
uint256 _startingPrice
) external virtual onlyGovernance {
require(_startingPrice != 0, "starting price");
// Don't change the price when an auction is active.
address[] memory _enabledAuctions = enabledAuctions;
for (uint256 i = 0; i < _enabledAuctions.length; ++i) {
require(!isActive(_enabledAuctions[i]), "active auction");
}
startingPrice = _startingPrice;
emit UpdatedStartingPrice(_startingPrice);
}
/*//////////////////////////////////////////////////////////////
PARTICIPATE IN AUCTION
//////////////////////////////////////////////////////////////*/
/**
* @notice Kicks off an auction, updating its status and making funds available for bidding.
* @param _from The address of the token to be auctioned.
* @return _available The available amount for bidding on in the auction.
*/
function kick(
address _from
) external virtual nonReentrant returns (uint256 _available) {
require(auctions[_from].scaler != 0, "not enabled");
require(
block.timestamp > auctions[_from].kicked + auctionLength,
"too soon"
);
// Just use current balance.
_available = ERC20(_from).balanceOf(address(this));
require(_available != 0, "nothing to kick");
// Update the auctions status.
auctions[_from].kicked = uint64(block.timestamp);
auctions[_from].initialAvailable = uint128(_available);
emit AuctionKicked(_from, _available);
}
/**
* @notice Take the token being sold in a live auction.
* @dev Defaults to taking the full amount and sending to the msg sender.
* @param _from The address of the token to be auctioned.
* @return . The amount of fromToken taken in the auction.
*/
function take(address _from) external virtual returns (uint256) {
return _take(_from, type(uint256).max, msg.sender, new bytes(0));
}
/**
* @notice Take the token being sold in a live auction with a specified maximum amount.
* @dev Will send the funds to the msg sender.
* @param _from The address of the token to be auctioned.
* @param _maxAmount The maximum amount of fromToken to take in the auction.
* @return . The amount of fromToken taken in the auction.
*/
function take(
address _from,
uint256 _maxAmount
) external virtual returns (uint256) {
return _take(_from, _maxAmount, msg.sender, new bytes(0));
}
/**
* @notice Take the token being sold in a live auction.
* @param _from The address of the token to be auctioned.
* @param _maxAmount The maximum amount of fromToken to take in the auction.
* @param _receiver The address that will receive the fromToken.
* @return _amountTaken The amount of fromToken taken in the auction.
*/
function take(
address _from,
uint256 _maxAmount,
address _receiver
) external virtual returns (uint256) {
return _take(_from, _maxAmount, _receiver, new bytes(0));
}
/**
* @notice Take the token being sold in a live auction.
* @param _from The address of the token to be auctioned.
* @param _maxAmount The maximum amount of fromToken to take in the auction.
* @param _receiver The address that will receive the fromToken.
* @param _data The data signify the callback should be used and sent with it.
* @return _amountTaken The amount of fromToken taken in the auction.
*/
function take(
address _from,
uint256 _maxAmount,
address _receiver,
bytes calldata _data
) external virtual returns (uint256) {
return _take(_from, _maxAmount, _receiver, _data);
}
/// @dev Implements the take of the auction.
function _take(
address _from,
uint256 _maxAmount,
address _receiver,
bytes memory _data
) internal virtual nonReentrant returns (uint256 _amountTaken) {
AuctionInfo memory auction = auctions[_from];
// Make sure the auction is active.
require(
auction.kicked + auctionLength >= block.timestamp,
"not kicked"
);
// Max amount that can be taken.
uint256 _available = available(_from);
_amountTaken = _available > _maxAmount ? _maxAmount : _available;
// Get the amount needed
uint256 needed = _getAmountNeeded(
auction,
_amountTaken,
block.timestamp
);
require(needed != 0, "zero needed");
// Send `from`.
ERC20(_from).safeTransfer(_receiver, _amountTaken);
// If the caller has specified data.
if (_data.length != 0) {
// Do the callback.
ITaker(_receiver).auctionTakeCallback(
_from,
msg.sender,
_amountTaken,
needed,
_data
);
}
// Cache the want address.
address _want = want();
// Pull `want`.
ERC20(_want).safeTransferFrom(msg.sender, receiver, needed);
}
/// @dev Validates a COW order signature.
function isValidSignature(
bytes32 _hash,
bytes calldata signature
) external view returns (bytes4) {
// Make sure `_take` has not already been entered.
require(!_reentrancyGuardEntered(), "ReentrancyGuard: reentrant call");
// Decode the signature to get the order.
GPv2Order.Data memory order = abi.decode(signature, (GPv2Order.Data));
AuctionInfo memory auction = auctions[address(order.sellToken)];
// Get the current amount needed for the auction.
uint256 paymentAmount = _getAmountNeeded(
auction,
order.sellAmount,
block.timestamp
);
// Verify the order details.
require(_hash == order.hash(COW_DOMAIN_SEPARATOR), "bad order");
require(paymentAmount != 0, "zero amount");
require(available(address(order.sellToken)) != 0, "zero available");
require(order.feeAmount == 0, "fee");
require(order.partiallyFillable, "partial fill");
require(order.validTo < auction.kicked + auctionLength, "expired");
require(order.appData == bytes32(0), "app data");
require(order.buyAmount >= paymentAmount, "bad price");
require(address(order.buyToken) == want(), "bad token");
require(order.receiver == receiver, "bad receiver");
require(order.sellAmount <= auction.initialAvailable, "bad amount");
// If all checks pass, return the magic value
return this.isValidSignature.selector;
}
/**
* @notice Allows the auction to be stopped if the full amount is taken.
* @param _from The address of the token to be auctioned.
*/
function settle(address _from) external virtual {
require(isActive(_from), "!active");
require(ERC20(_from).balanceOf(address(this)) == 0, "!empty");
auctions[_from].kicked = uint64(0);
}
function sweep(address _token) external virtual onlyGovernance {
ERC20(_token).safeTransfer(
msg.sender,
ERC20(_token).balanceOf(address(this))
);
}
}// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.18;
// Math library from https://github.com/ajna-finance/ajna-core/blob/master/src/libraries/internal/Maths.sol
/**
@title Maths library
@notice Internal library containing common maths.
*/
library Maths {
uint256 internal constant WAD = 1e18;
uint256 internal constant RAY = 1e27;
function wmul(uint256 x, uint256 y) internal pure returns (uint256) {
return (x * y + WAD / 2) / WAD;
}
function floorWmul(uint256 x, uint256 y) internal pure returns (uint256) {
return (x * y) / WAD;
}
function ceilWmul(uint256 x, uint256 y) internal pure returns (uint256) {
return (x * y + WAD - 1) / WAD;
}
function wdiv(uint256 x, uint256 y) internal pure returns (uint256) {
return (x * WAD + y / 2) / y;
}
function floorWdiv(uint256 x, uint256 y) internal pure returns (uint256) {
return (x * WAD) / y;
}
function ceilWdiv(uint256 x, uint256 y) internal pure returns (uint256) {
return (x * WAD + y - 1) / y;
}
function ceilDiv(uint256 x, uint256 y) internal pure returns (uint256) {
return (x + y - 1) / y;
}
function max(uint256 x, uint256 y) internal pure returns (uint256) {
return x >= y ? x : y;
}
function min(uint256 x, uint256 y) internal pure returns (uint256) {
return x <= y ? x : y;
}
function wad(uint256 x) internal pure returns (uint256) {
return x * WAD;
}
function rmul(uint256 x, uint256 y) internal pure returns (uint256) {
return (x * y + RAY / 2) / RAY;
}
function rpow(uint256 x, uint256 n) internal pure returns (uint256 z) {
z = n % 2 != 0 ? x : RAY;
for (n /= 2; n != 0; n /= 2) {
x = rmul(x, x);
if (n % 2 != 0) {
z = rmul(z, x);
}
}
}
/*************************/
/*** Integer Functions ***/
/*************************/
function maxInt(int256 x, int256 y) internal pure returns (int256) {
return x >= y ? x : y;
}
function minInt(int256 x, int256 y) internal pure returns (int256) {
return x <= y ? x : y;
}
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity >=0.8.18;
interface ITaker {
function auctionTakeCallback(
address _from,
address _sender,
uint256 _amountTaken,
uint256 _amountNeeded,
bytes calldata _data
) external;
}// SPDX-License-Identifier: LGPL-3.0-or-later
pragma solidity ^0.8.0;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
/// @title Gnosis Protocol v2 Order Library
/// @author Gnosis Developers
library GPv2Order {
/// @dev The complete data for a Gnosis Protocol order. This struct contains
/// all order parameters that are signed for submitting to GP.
struct Data {
ERC20 sellToken;
ERC20 buyToken;
address receiver;
uint256 sellAmount;
uint256 buyAmount;
uint32 validTo;
bytes32 appData;
uint256 feeAmount;
bytes32 kind;
bool partiallyFillable;
bytes32 sellTokenBalance;
bytes32 buyTokenBalance;
}
/// @dev The order EIP-712 type hash for the [`GPv2Order.Data`] struct.
///
/// This value is pre-computed from the following expression:
/// ```
/// keccak256(
/// "Order(" +
/// "address sellToken," +
/// "address buyToken," +
/// "address receiver," +
/// "uint256 sellAmount," +
/// "uint256 buyAmount," +
/// "uint32 validTo," +
/// "bytes32 appData," +
/// "uint256 feeAmount," +
/// "string kind," +
/// "bool partiallyFillable" +
/// "string sellTokenBalance" +
/// "string buyTokenBalance" +
/// ")"
/// )
/// ```
bytes32 internal constant TYPE_HASH =
hex"d5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e489";
/// @dev The marker value for a sell order for computing the order struct
/// hash. This allows the EIP-712 compatible wallets to display a
/// descriptive string for the order kind (instead of 0 or 1).
///
/// This value is pre-computed from the following expression:
/// ```
/// keccak256("sell")
/// ```
bytes32 internal constant KIND_SELL =
hex"f3b277728b3fee749481eb3e0b3b48980dbbab78658fc419025cb16eee346775";
/// @dev The OrderKind marker value for a buy order for computing the order
/// struct hash.
///
/// This value is pre-computed from the following expression:
/// ```
/// keccak256("buy")
/// ```
bytes32 internal constant KIND_BUY =
hex"6ed88e868af0a1983e3886d5f3e95a2fafbd6c3450bc229e27342283dc429ccc";
/// @dev The TokenBalance marker value for using direct ERC20 balances for
/// computing the order struct hash.
///
/// This value is pre-computed from the following expression:
/// ```
/// keccak256("erc20")
/// ```
bytes32 internal constant BALANCE_ERC20 =
hex"5a28e9363bb942b639270062aa6bb295f434bcdfc42c97267bf003f272060dc9";
/// @dev The TokenBalance marker value for using Balancer Vault external
/// balances (in order to re-use Vault ERC20 approvals) for computing the
/// order struct hash.
///
/// This value is pre-computed from the following expression:
/// ```
/// keccak256("external")
/// ```
bytes32 internal constant BALANCE_EXTERNAL =
hex"abee3b73373acd583a130924aad6dc38cfdc44ba0555ba94ce2ff63980ea0632";
/// @dev The TokenBalance marker value for using Balancer Vault internal
/// balances for computing the order struct hash.
///
/// This value is pre-computed from the following expression:
/// ```
/// keccak256("internal")
/// ```
bytes32 internal constant BALANCE_INTERNAL =
hex"4ac99ace14ee0a5ef932dc609df0943ab7ac16b7583634612f8dc35a4289a6ce";
/// @dev Marker address used to indicate that the receiver of the trade
/// proceeds should the owner of the order.
///
/// This is chosen to be `address(0)` for gas efficiency as it is expected
/// to be the most common case.
address internal constant RECEIVER_SAME_AS_OWNER = address(0);
/// @dev The byte length of an order unique identifier.
uint256 internal constant UID_LENGTH = 56;
/// @dev Returns the actual receiver for an order. This function checks
/// whether or not the [`receiver`] field uses the marker value to indicate
/// it is the same as the order owner.
///
/// @return receiver The actual receiver of trade proceeds.
function actualReceiver(
Data memory order,
address owner
) internal pure returns (address receiver) {
if (order.receiver == RECEIVER_SAME_AS_OWNER) {
receiver = owner;
} else {
receiver = order.receiver;
}
}
/// @dev Return the EIP-712 signing hash for the specified order.
///
/// @param order The order to compute the EIP-712 signing hash for.
/// @param domainSeparator The EIP-712 domain separator to use.
/// @return orderDigest The 32 byte EIP-712 struct hash.
function hash(
Data memory order,
bytes32 domainSeparator
) internal pure returns (bytes32 orderDigest) {
bytes32 structHash;
// NOTE: Compute the EIP-712 order struct hash in place. As suggested
// in the EIP proposal, noting that the order struct has 10 fields, and
// including the type hash `(12 + 1) * 32 = 416` bytes to hash.
// <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md#rationale-for-encodedata>
// solhint-disable-next-line no-inline-assembly
assembly {
let dataStart := sub(order, 32)
let temp := mload(dataStart)
mstore(dataStart, TYPE_HASH)
structHash := keccak256(dataStart, 416)
mstore(dataStart, temp)
}
// NOTE: Now that we have the struct hash, compute the EIP-712 signing
// hash using scratch memory past the free memory pointer. The signing
// hash is computed from `"\x19\x01" || domainSeparator || structHash`.
// <https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memory>
// <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md#specification>
// solhint-disable-next-line no-inline-assembly
assembly {
let freeMemoryPointer := mload(0x40)
mstore(freeMemoryPointer, "\x19\x01")
mstore(add(freeMemoryPointer, 2), domainSeparator)
mstore(add(freeMemoryPointer, 34), structHash)
orderDigest := keccak256(freeMemoryPointer, 66)
}
}
/// @dev Packs order UID parameters into the specified memory location. The
/// result is equivalent to `abi.encodePacked(...)` with the difference that
/// it allows re-using the memory for packing the order UID.
///
/// This function reverts if the order UID buffer is not the correct size.
///
/// @param orderUid The buffer pack the order UID parameters into.
/// @param orderDigest The EIP-712 struct digest derived from the order
/// parameters.
/// @param owner The address of the user who owns this order.
/// @param validTo The epoch time at which the order will stop being valid.
function packOrderUidParams(
bytes memory orderUid,
bytes32 orderDigest,
address owner,
uint32 validTo
) internal pure {
require(orderUid.length == UID_LENGTH, "GPv2: uid buffer overflow");
// NOTE: Write the order UID to the allocated memory buffer. The order
// parameters are written to memory in **reverse order** as memory
// operations write 32-bytes at a time and we want to use a packed
// encoding. This means, for example, that after writing the value of
// `owner` to bytes `20:52`, writing the `orderDigest` to bytes `0:32`
// will **overwrite** bytes `20:32`. This is desirable as addresses are
// only 20 bytes and `20:32` should be `0`s:
//
// | 1111111111222222222233333333334444444444555555
// byte | 01234567890123456789012345678901234567890123456789012345
// -------+---------------------------------------------------------
// field | [.........orderDigest..........][......owner.......][vT]
// -------+---------------------------------------------------------
// mstore | [000000000000000000000000000.vT]
// | [00000000000.......owner.......]
// | [.........orderDigest..........]
//
// Additionally, since Solidity `bytes memory` are length prefixed,
// 32 needs to be added to all the offsets.
//
// solhint-disable-next-line no-inline-assembly
assembly {
mstore(add(orderUid, 56), validTo)
mstore(add(orderUid, 52), owner)
mstore(add(orderUid, 32), orderDigest)
}
}
/// @dev Extracts specific order information from the standardized unique
/// order id of the protocol.
///
/// @param orderUid The unique identifier used to represent an order in
/// the protocol. This uid is the packed concatenation of the order digest,
/// the validTo order parameter and the address of the user who created the
/// order. It is used by the user to interface with the contract directly,
/// and not by calls that are triggered by the solvers.
/// @return orderDigest The EIP-712 signing digest derived from the order
/// parameters.
/// @return owner The address of the user who owns this order.
/// @return validTo The epoch time at which the order will stop being valid.
function extractOrderUidParams(
bytes calldata orderUid
)
internal
pure
returns (bytes32 orderDigest, address owner, uint32 validTo)
{
require(orderUid.length == UID_LENGTH, "GPv2: invalid uid");
// Use assembly to efficiently decode packed calldata.
// solhint-disable-next-line no-inline-assembly
assembly {
orderDigest := calldataload(orderUid.offset)
owner := shr(96, calldataload(add(orderUid.offset, 32)))
validTo := shr(224, calldataload(add(orderUid.offset, 52)))
}
}
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity >=0.8.18;
import {Governance} from "./Governance.sol";
contract Governance2Step is Governance {
/// @notice Emitted when the pending governance address is set.
event UpdatePendingGovernance(address indexed newPendingGovernance);
/// @notice Address that is set to take over governance.
address public pendingGovernance;
constructor(address _governance) Governance(_governance) {}
/**
* @notice Sets a new address as the `pendingGovernance` of the contract.
* @dev Throws if the caller is not current governance.
* @param _newGovernance The new governance address.
*/
function transferGovernance(
address _newGovernance
) external virtual override onlyGovernance {
require(_newGovernance != address(0), "ZERO ADDRESS");
pendingGovernance = _newGovernance;
emit UpdatePendingGovernance(_newGovernance);
}
/**
* @notice Allows the `pendingGovernance` to accept the role.
*/
function acceptGovernance() external virtual {
require(msg.sender == pendingGovernance, "!pending governance");
emit GovernanceTransferred(governance, msg.sender);
governance = msg.sender;
pendingGovernance = address(0);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.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 Address for address;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
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'
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));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @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");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @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).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// 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 cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @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 ReentrancyGuard {
// 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;
constructor() {
_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 making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity >=0.8.18;
contract Governance {
/// @notice Emitted when the governance address is updated.
event GovernanceTransferred(
address indexed previousGovernance,
address indexed newGovernance
);
modifier onlyGovernance() {
_checkGovernance();
_;
}
/// @notice Checks if the msg sender is the governance.
function _checkGovernance() internal view virtual {
require(governance == msg.sender, "!governance");
}
/// @notice Address that can set the default base fee and provider
address public governance;
constructor(address _governance) {
governance = _governance;
emit GovernanceTransferred(address(0), _governance);
}
/**
* @notice Sets a new address as the governance of the contract.
* @dev Throws if the caller is not current governance.
* @param _newGovernance The new governance address.
*/
function transferGovernance(
address _newGovernance
) external virtual onlyGovernance {
require(_newGovernance != address(0), "ZERO ADDRESS");
address oldGovernance = governance;
governance = _newGovernance;
emit GovernanceTransferred(oldGovernance, _newGovernance);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev 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 `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @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
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 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://consensys.net/diligence/blog/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.8.0/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");
(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 functionCallWithValue(target, data, 0, "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");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// 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
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}{
"remappings": [
"forge-std/=lib/forge-std/src/",
"@openzeppelin/=lib/openzeppelin-contracts/",
"@tokenized-strategy/=lib/tokenized-strategy/src/",
"@yearn-vaults/=lib/yearn-vaults-v3/contracts/",
"ds-test/=lib/forge-std/lib/ds-test/src/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"AuctionDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"AuctionEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"available","type":"uint256"}],"name":"AuctionKicked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernance","type":"address"},{"indexed":true,"internalType":"address","name":"newGovernance","type":"address"}],"name":"GovernanceTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newPendingGovernance","type":"address"}],"name":"UpdatePendingGovernance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"startingPrice","type":"uint256"}],"name":"UpdatedStartingPrice","type":"event"},{"inputs":[],"name":"acceptGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"auctionLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"auctions","outputs":[{"internalType":"uint64","name":"kicked","type":"uint64"},{"internalType":"uint64","name":"scaler","type":"uint64"},{"internalType":"uint128","name":"initialAvailable","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"}],"name":"available","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"}],"name":"disable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"disable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"}],"name":"enable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"enabledAuctions","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllEnabledAuctions","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"}],"name":"getAmountNeeded","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_amountToTake","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getAmountNeeded","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_amountToTake","type":"uint256"}],"name":"getAmountNeeded","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_want","type":"address"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"address","name":"_governance","type":"address"},{"internalType":"uint256","name":"_auctionLength","type":"uint256"},{"internalType":"uint256","name":"_startingPrice","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"}],"name":"isActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"}],"name":"kick","outputs":[{"internalType":"uint256","name":"_available","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"}],"name":"kickable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"}],"name":"kicked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGovernance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"}],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"receiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startingPrice","type":"uint256"}],"name":"setStartingPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"}],"name":"settle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startingPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"}],"name":"take","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_maxAmount","type":"uint256"}],"name":"take","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_maxAmount","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"take","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_maxAmount","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"take","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newGovernance","type":"address"}],"name":"transferGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"want","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60a06040523480156200001157600080fd5b50600080546001600160a01b031916339081178255604051909182918291907f5f56bee8cffbe9a78652a74a60705edede02af10b0bbb888ca44b79a0d42ce80908290a3505060016002556000739008d19f58aabd9ed0d60971565aa8510560ab413b15620000fb57739008d19f58aabd9ed0d60971565aa8510560ab416001600160a01b031663f698da256040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000f3919062000108565b9050620000ff565b5060005b60805262000122565b6000602082840312156200011b57600080fd5b5051919050565b608051612bf16200013e60003960006108dc0152612bf16000f3fe608060405234801561001057600080fd5b50600436106101fb5760003560e01c80635bfa1b681161011a578063aea91078116100ad578063d987b4441161007c578063d987b444146104c9578063e6c09edf146104dc578063f39c38a0146104ef578063f7260d3e14610502578063fe9f841e1461051557600080fd5b8063aea9107814610468578063b5eb317a1461047b578063d38bfff4146104ad578063d6fbf202146104c057600080fd5b806396c55175116100e957806396c551751461040c5780639f8a13d71461041f578063a6b63eb814610442578063ad9b80241461045557600080fd5b80635bfa1b68146103c057806366ae5880146103d35780636a256b29146103e65780638033d687146103f957600080fd5b806324d88f63116101925780634d44e663116101615780634d44e66314610374578063521802081461038757806358e4f8c31461039a5780635aa6e675146103ad57600080fd5b806324d88f6314610332578063325c25a214610345578063466772611461034e5780634aca94821461036157600080fd5b80631d59410a116101ce5780631d59410a1461027a5780631f1fcd51146102f057806321eac91214610315578063238efcbc1461032a57600080fd5b806301681a62146102005780630f73b4f41461021557806310098ad5146102285780631626ba7e1461024e575b600080fd5b61021361020e3660046124ea565b610528565b005b610213610223366004612507565b6105b2565b61023b6102363660046124ea565b610718565b6040519081526020015b60405180910390f35b61026161025c366004612568565b6107c8565b6040516001600160e01b03199091168152602001610245565b6102c16102883660046124ea565b6007602052600090815260409020546001600160401b0380821691600160401b810490911690600160801b90046001600160801b031683565b604080516001600160401b0394851681529390921660208401526001600160801b031690820152606001610245565b6003546001600160a01b03165b6040516001600160a01b039091168152602001610245565b61031d610c32565b60405161024591906125b3565b610213610c94565b61023b6103403660046124ea565b610d3c565b61023b60065481565b6102fd61035c366004612507565b610da5565b61023b61036f3660046124ea565b610dcf565b61023b6103823660046124ea565b610e4f565b61023b610395366004612600565b610e8b565b61023b6103a836600461262c565b610e99565b6000546102fd906001600160a01b031681565b6102136103ce3660046124ea565b610f02565b61023b6103e1366004612661565b611185565b6102136103f43660046124ea565b6111d3565b61023b6104073660046126d3565b6112d8565b61023b61041a3660046124ea565b6112e6565b61043261042d3660046124ea565b6114fe565b6040519015158152602001610245565b610213610450366004612715565b611539565b61023b610463366004612600565b6117e2565b61023b6104763660046124ea565b61185c565b61023b6104893660046124ea565b6001600160a01b03166000908152600760205260409020546001600160401b031690565b6102136104bb3660046124ea565b611868565b61023b60055481565b61023b6104d7366004612600565b6118e0565b6102136104ea3660046124ea565b611941565b6001546102fd906001600160a01b031681565b6004546102fd906001600160a01b031681565b610213610523366004612600565b611948565b610530611bd5565b6040516370a0823160e01b81523060048201526105af9033906001600160a01b038416906370a0823190602401602060405180830381865afa15801561057a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059e9190612770565b6001600160a01b0384169190611c1f565b50565b6105ba611bd5565b806000036106005760405162461bcd60e51b815260206004820152600e60248201526d7374617274696e6720707269636560901b60448201526064015b60405180910390fd5b6000600880548060200260200160405190810160405280929190818152602001828054801561065857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161063a575b5050505050905060005b81518110156106db5761068d82828151811061068057610680612789565b60200260200101516114fe565b156106cb5760405162461bcd60e51b815260206004820152600e60248201526d30b1ba34bb329030bab1ba34b7b760911b60448201526064016105f7565b6106d4816127b5565b9050610662565b5060058290556040518281527f9a662b9b8a431c26da8dea3d6a011bf4959a20ddbc3dfe618abfc3898d2c901f9060200160405180910390a15050565b6000610723826114fe565b61072f57506000919050565b6001600160a01b038216600081815260076020526040908190205490516370a0823160e01b81523060048201526107c292600160801b9092046001600160801b031691906370a0823190602401602060405180830381865afa158015610799573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107bd9190612770565b611c87565b92915050565b60006107d5600280541490565b156108225760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016105f7565b600061083083850185612832565b80516001600160a01b0316600090815260076020908152604080832081516060808201845291546001600160401b038082168352600160401b82041694820194909452600160801b9093046001600160801b0316918301919091528301519293509161089e90839042611c9e565b601f19840180517fd5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e48982526101a08220915260405161190160f01b81527f0000000000000000000000000000000000000000000000000000000000000000600282015260228101919091526042902090915087146109495760405162461bcd60e51b81526020600482015260096024820152683130b21037b93232b960b91b60448201526064016105f7565b806000036109875760405162461bcd60e51b815260206004820152600b60248201526a1e995c9bc8185b5bdd5b9d60aa1b60448201526064016105f7565b825161099290610718565b6000036109d25760405162461bcd60e51b815260206004820152600e60248201526d7a65726f20617661696c61626c6560901b60448201526064016105f7565b60e083015115610a0a5760405162461bcd60e51b815260206004820152600360248201526266656560e81b60448201526064016105f7565b826101200151610a4b5760405162461bcd60e51b815260206004820152600c60248201526b1c185c9d1a585b08199a5b1b60a21b60448201526064016105f7565b6006548251610a6391906001600160401b03166128f0565b8360a0015163ffffffff1610610aa55760405162461bcd60e51b8152602060048201526007602482015266195e1c1a5c995960ca1b60448201526064016105f7565b60c083015115610ae25760405162461bcd60e51b8152602060048201526008602482015267617070206461746160c01b60448201526064016105f7565b8083608001511015610b225760405162461bcd60e51b815260206004820152600960248201526862616420707269636560b81b60448201526064016105f7565b6003546001600160a01b03166001600160a01b031683602001516001600160a01b031614610b7e5760405162461bcd60e51b81526020600482015260096024820152683130b2103a37b5b2b760b91b60448201526064016105f7565b60045460408401516001600160a01b03908116911614610bcf5760405162461bcd60e51b815260206004820152600c60248201526b3130b2103932b1b2b4bb32b960a11b60448201526064016105f7565b81604001516001600160801b031683606001511115610c1d5760405162461bcd60e51b815260206004820152600a60248201526918985908185b5bdd5b9d60b21b60448201526064016105f7565b50630b135d3f60e11b925050505b9392505050565b60606008805480602002602001604051908101604052809291908181526020018280548015610c8a57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610c6c575b5050505050905090565b6001546001600160a01b03163314610ce45760405162461bcd60e51b81526020600482015260136024820152722170656e64696e6720676f7665726e616e636560681b60448201526064016105f7565b6000805460405133926001600160a01b03909216917f5f56bee8cffbe9a78652a74a60705edede02af10b0bbb888ca44b79a0d42ce8091a3600080546001600160a01b03199081163317909155600180549091169055565b6001600160a01b0381166000908152600760209081526040808320815160608101835290546001600160401b038082168352600160401b82041693820193909352600160801b9092046001600160801b0316908201526107c290610d9f84610718565b42611c9e565b60088181548110610db557600080fd5b6000918252602090912001546001600160a01b0316905081565b6000610dda826114fe565b15610de757506000919050565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610e2b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c29190612770565b60006107c28260001933845b6040519080825280601f01601f191660200182016040528015610e85576020820181803683370190505b50611d2b565b6000610c2b83833384610e5b565b6001600160a01b0383166000908152600760209081526040808320815160608101835290546001600160401b038082168352600160401b82041693820193909352600160801b9092046001600160801b031690820152610efa908484611c9e565b949350505050565b610f0a611bd5565b6000610f1e6003546001600160a01b031690565b90506001600160a01b03821615801590610f4a5750806001600160a01b0316826001600160a01b031614155b610f665760405162461bcd60e51b81526004016105f790612903565b6001600160a01b038216600090815260076020526040902054600160401b90046001600160401b031615610fce5760405162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e48195b98589b1959608a1b60448201526064016105f7565b6000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561100e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190612929565b60ff169050601281111561107f5760405162461bcd60e51b8152602060048201526014602482015273756e737570706f7274656420646563696d616c7360601b60448201526064016105f7565b61108a81600a612a30565b61109c90670de0b6b3a7640000612a52565b6001600160a01b038416600081815260076020526040902080546001600160401b0393909316600160401b026fffffffffffffffff000000000000000019909316929092179091556111059073c92e8bdf79f0507f65a392b0ab4667716bfe0110600019611f09565b6008805460018101825560009182527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b038681169182179092556040519185169290917fed6bfe4670b251246a8da2ece7f7b4f47fd7761ae0b2843a64d1ae1ee90fef4d9190a3505050565b60006111c986868686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d2b92505050565b9695505050505050565b6111dc816114fe565b6112125760405162461bcd60e51b81526020600482015260076024820152662161637469766560c81b60448201526064016105f7565b6040516370a0823160e01b81523060048201526001600160a01b038216906370a0823190602401602060405180830381865afa158015611256573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127a9190612770565b156112b05760405162461bcd60e51b815260206004820152600660248201526521656d70747960d01b60448201526064016105f7565b6001600160a01b03166000908152600760205260409020805467ffffffffffffffff19169055565b6000610efa84848484610e5b565b60006112f061201e565b6001600160a01b038216600090815260076020526040812054600160401b90046001600160401b031690036113555760405162461bcd60e51b815260206004820152600b60248201526a1b9bdd08195b98589b195960aa1b60448201526064016105f7565b6006546001600160a01b03831660009081526007602052604090205461138491906001600160401b03166128f0565b42116113bd5760405162461bcd60e51b81526020600482015260086024820152673a37b79039b7b7b760c11b60448201526064016105f7565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015611401573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114259190612770565b9050806000036114695760405162461bcd60e51b815260206004820152600f60248201526e6e6f7468696e6720746f206b69636b60881b60448201526064016105f7565b6001600160a01b0382166000818152600760205260409081902080546001600160801b038516600160801b026fffffffffffffffff00000000000000009091166001600160401b03421617179055517fb3831db58b36bd77258a9cc9589b88fab5d52f7a1814e6f17faec14b149fe084906114e79084815260200190565b60405180910390a26114f96001600255565b919050565b6006546001600160a01b0382166000908152600760205260408120549091429161153191906001600160401b03166128f0565b101592915050565b600654156115775760405162461bcd60e51b815260206004820152600b60248201526a1a5b9a5d1a585b1a5e995960aa1b60448201526064016105f7565b6001600160a01b03851661159d5760405162461bcd60e51b81526004016105f790612903565b816000036115d65760405162461bcd60e51b81526020600482015260066024820152650d8cadccee8d60d31b60448201526064016105f7565b806000036116175760405162461bcd60e51b815260206004820152600e60248201526d7374617274696e6720707269636560901b60448201526064016105f7565b6001600160a01b0384166116585760405162461bcd60e51b81526020600482015260086024820152673932b1b2b4bb32b960c11b60448201526064016105f7565b6000856001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bc9190612929565b60ff16905060128111156117095760405162461bcd60e51b8152602060048201526014602482015273756e737570706f7274656420646563696d616c7360601b60448201526064016105f7565b6040518060400160405280876001600160a01b0316815260200182600a6117309190612a30565b61174290670de0b6b3a7640000612a52565b6001600160601b03908116909152815160209092015116600160a01b026001600160a01b0391821617600355600480548783166001600160a01b0319918216179091556000805492871692909116919091179055600683905560058290556040517f9a662b9b8a431c26da8dea3d6a011bf4959a20ddbc3dfe618abfc3898d2c901f906117d29084815260200190565b60405180910390a1505050505050565b6003546001600160a01b0383166000908152600760205260408120549091600160a01b90046001600160601b031690611852906001600160401b038082169161184391600160401b82041690600160801b90046001600160801b0316612a66565b6001600160801b031685612075565b610c2b9190612a52565b60006107c282426117e2565b611870611bd5565b6001600160a01b0381166118965760405162461bcd60e51b81526004016105f790612903565b600180546001600160a01b0319166001600160a01b0383169081179091556040517fa443b483867b0f9db5b03913474dd21935ac5ba70fa6c94e3423ba9be157c44b90600090a250565b6001600160a01b0382166000908152600760209081526040808320815160608101835290546001600160401b038082168352600160401b82041693820193909352600160801b9092046001600160801b031690820152610c2b908342611c9e565b6105af8160005b611950611bd5565b6001600160a01b038216600090815260076020526040812054600160401b90046001600160401b031690036119b55760405162461bcd60e51b815260206004820152600b60248201526a1b9bdd08195b98589b195960aa1b60448201526064016105f7565b6001600160a01b03821660008181526007602052604081208190556119f0919073c92e8bdf79f0507f65a392b0ab4667716bfe011090611f09565b60006008805480602002602001604051908101604052809291908181526020018280548015611a4857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611a2a575b50505050509050826001600160a01b0316818381518110611a6b57611a6b612789565b60200260200101516001600160a01b031614611ad95760005b8151811015611ad757836001600160a01b0316828281518110611aa957611aa9612789565b60200260200101516001600160a01b031603611ac757809250611ad7565b611ad0816127b5565b9050611a84565b505b60018151611ae79190612a91565b821015611b52578060018251611afd9190612a91565b81518110611b0d57611b0d612789565b6020026020010151818381518110611b2757611b27612789565b6001600160a01b039092166020928302919091018201528151611b509160089190840190612450565b505b6008805480611b6357611b63612aa4565b600082815260209020600019908201810180546001600160a01b03191690550190556003546001600160a01b03166001600160a01b0316836001600160a01b03167f9c0e126ec038aaa740cee67f64da5b77aeaeb18634ddfb0b6c683a867490fb4160405160405180910390a3505050565b6000546001600160a01b03163314611c1d5760405162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b60448201526064016105f7565b565b6040516001600160a01b038316602482015260448101829052611c8290849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612153565b505050565b600081831115611c975781610c2b565b5090919050565b600354835160208501516040860151600093600160a01b90046001600160601b031692670de0b6b3a764000092611cf5926001600160401b0392831692611ce6921690612a66565b6001600160801b031686612075565b6020870151611d0d906001600160401b031687612aba565b611d179190612aba565b611d219190612a52565b610efa9190612a52565b6000611d3561201e565b6001600160a01b038516600090815260076020908152604091829020825160608101845290546001600160401b03808216808452600160401b830490911693830193909352600160801b90046001600160801b0316928101929092526006544291611da091906128f0565b1015611ddb5760405162461bcd60e51b815260206004820152600a6024820152691b9bdd081ada58dad95960b21b60448201526064016105f7565b6000611de687610718565b9050858111611df55780611df7565b855b92506000611e06838542611c9e565b905080600003611e465760405162461bcd60e51b815260206004820152600b60248201526a1e995c9bc81b995959195960aa1b60448201526064016105f7565b611e5a6001600160a01b0389168786611c1f565b845115611ec857604051631fcef5bf60e21b81526001600160a01b03871690637f3bd6fc90611e95908b903390899087908c90600401612b21565b600060405180830381600087803b158015611eaf57600080fd5b505af1158015611ec3573d6000803e3d6000fd5b505050505b6000611edc6003546001600160a01b031690565b600454909150611efb906001600160a01b038084169133911685612228565b50505050610efa6001600255565b801580611f835750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611f5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f819190612770565b155b611fee5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016105f7565b6040516001600160a01b038316602482015260448101829052611c8290849063095ea7b360e01b90606401611c4b565b600280540361206f5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016105f7565b60028055565b60008260000361208757506000610c2b565b60006120938584612a91565b90506006548111156120a9576000915050610c2b565b60006120b7610e1083612a52565b6b033b2e3c9fd0803ce8000000901c905060006120f76b0331adfc6b81cf95c39de3b1603c6120e8610e1087612b5b565b6120f29190612a52565b612266565b9050600061211a600554670de0b6b3a76400006121149190612aba565b886122df565b90506b033b2e3c9fd0803ce80000006121338484612309565b61213d9083612aba565b6121479190612a52565b98975050505050505050565b60006121a8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661232d9092919063ffffffff16565b90508051600014806121c95750808060200190518101906121c99190612b6f565b611c825760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105f7565b6040516001600160a01b03808516602483015283166044820152606481018290526122609085906323b872dd60e01b90608401611c4b565b50505050565b6000612273600283612b5b565b60000361228c576b033b2e3c9fd0803ce800000061228e565b825b905061229b600283612a52565b91505b81156107c2576122ae8384612309565b92506122bb600283612b5b565b156122cd576122ca8184612309565b90505b6122d8600283612a52565b915061229e565b6000816122ed600282612a52565b6122ff670de0b6b3a764000086612aba565b61185291906128f0565b60006b033b2e3c9fd0803ce8000000612323600282612a52565b6122ff8486612aba565b6060610efa848460008585600080866001600160a01b031685876040516123549190612b8c565b60006040518083038185875af1925050503d8060008114612391576040519150601f19603f3d011682016040523d82523d6000602084013e612396565b606091505b50915091506123a7878383876123b2565b979650505050505050565b6060831561242157825160000361241a576001600160a01b0385163b61241a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105f7565b5081610efa565b610efa83838151156124365781518083602001fd5b8060405162461bcd60e51b81526004016105f79190612ba8565b8280548282559060005260206000209081019282156124a5579160200282015b828111156124a557825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612470565b506124b19291506124b5565b5090565b5b808211156124b157600081556001016124b6565b6001600160a01b03811681146105af57600080fd5b80356114f9816124ca565b6000602082840312156124fc57600080fd5b8135610c2b816124ca565b60006020828403121561251957600080fd5b5035919050565b60008083601f84011261253257600080fd5b5081356001600160401b0381111561254957600080fd5b60208301915083602082850101111561256157600080fd5b9250929050565b60008060006040848603121561257d57600080fd5b8335925060208401356001600160401b0381111561259a57600080fd5b6125a686828701612520565b9497909650939450505050565b6020808252825182820181905260009190848201906040850190845b818110156125f45783516001600160a01b0316835292840192918401916001016125cf565b50909695505050505050565b6000806040838503121561261357600080fd5b823561261e816124ca565b946020939093013593505050565b60008060006060848603121561264157600080fd5b833561264c816124ca565b95602085013595506040909401359392505050565b60008060008060006080868803121561267957600080fd5b8535612684816124ca565b945060208601359350604086013561269b816124ca565b925060608601356001600160401b038111156126b657600080fd5b6126c288828901612520565b969995985093965092949392505050565b6000806000606084860312156126e857600080fd5b83356126f3816124ca565b925060208401359150604084013561270a816124ca565b809150509250925092565b600080600080600060a0868803121561272d57600080fd5b8535612738816124ca565b94506020860135612748816124ca565b93506040860135612758816124ca565b94979396509394606081013594506080013592915050565b60006020828403121561278257600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016127c7576127c761279f565b5060010190565b60405161018081016001600160401b03811182821017156127ff57634e487b7160e01b600052604160045260246000fd5b60405290565b803563ffffffff811681146114f957600080fd5b80151581146105af57600080fd5b80356114f981612819565b6000610180828403121561284557600080fd5b61284d6127ce565b612856836124df565b8152612864602084016124df565b6020820152612875604084016124df565b6040820152606083013560608201526080830135608082015261289a60a08401612805565b60a082015260c083013560c082015260e083013560e08201526101008084013581830152506101206128cd818501612827565b908201526101408381013590820152610160928301359281019290925250919050565b808201808211156107c2576107c261279f565b6020808252600c908201526b5a45524f204144445245535360a01b604082015260600190565b60006020828403121561293b57600080fd5b815160ff81168114610c2b57600080fd5b600181815b8085111561298757816000190482111561296d5761296d61279f565b8085161561297a57918102915b93841c9390800290612951565b509250929050565b60008261299e575060016107c2565b816129ab575060006107c2565b81600181146129c157600281146129cb576129e7565b60019150506107c2565b60ff8411156129dc576129dc61279f565b50506001821b6107c2565b5060208310610133831016604e8410600b8410161715612a0a575081810a6107c2565b612a14838361294c565b8060001904821115612a2857612a2861279f565b029392505050565b6000610c2b838361298f565b634e487b7160e01b600052601260045260246000fd5b600082612a6157612a61612a3c565b500490565b6001600160801b03818116838216028082169190828114612a8957612a8961279f565b505092915050565b818103818111156107c2576107c261279f565b634e487b7160e01b600052603160045260246000fd5b80820281158282048414176107c2576107c261279f565b60005b83811015612aec578181015183820152602001612ad4565b50506000910152565b60008151808452612b0d816020860160208601612ad1565b601f01601f19169290920160200192915050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190526000906123a790830184612af5565b600082612b6a57612b6a612a3c565b500690565b600060208284031215612b8157600080fd5b8151610c2b81612819565b60008251612b9e818460208701612ad1565b9190910192915050565b602081526000610c2b6020830184612af556fea26469706673582212203e88b6f9221d47f719cd268428bdf751f24ce9ea82369bcdf35339b41cbb242264736f6c63430008120033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101fb5760003560e01c80635bfa1b681161011a578063aea91078116100ad578063d987b4441161007c578063d987b444146104c9578063e6c09edf146104dc578063f39c38a0146104ef578063f7260d3e14610502578063fe9f841e1461051557600080fd5b8063aea9107814610468578063b5eb317a1461047b578063d38bfff4146104ad578063d6fbf202146104c057600080fd5b806396c55175116100e957806396c551751461040c5780639f8a13d71461041f578063a6b63eb814610442578063ad9b80241461045557600080fd5b80635bfa1b68146103c057806366ae5880146103d35780636a256b29146103e65780638033d687146103f957600080fd5b806324d88f63116101925780634d44e663116101615780634d44e66314610374578063521802081461038757806358e4f8c31461039a5780635aa6e675146103ad57600080fd5b806324d88f6314610332578063325c25a214610345578063466772611461034e5780634aca94821461036157600080fd5b80631d59410a116101ce5780631d59410a1461027a5780631f1fcd51146102f057806321eac91214610315578063238efcbc1461032a57600080fd5b806301681a62146102005780630f73b4f41461021557806310098ad5146102285780631626ba7e1461024e575b600080fd5b61021361020e3660046124ea565b610528565b005b610213610223366004612507565b6105b2565b61023b6102363660046124ea565b610718565b6040519081526020015b60405180910390f35b61026161025c366004612568565b6107c8565b6040516001600160e01b03199091168152602001610245565b6102c16102883660046124ea565b6007602052600090815260409020546001600160401b0380821691600160401b810490911690600160801b90046001600160801b031683565b604080516001600160401b0394851681529390921660208401526001600160801b031690820152606001610245565b6003546001600160a01b03165b6040516001600160a01b039091168152602001610245565b61031d610c32565b60405161024591906125b3565b610213610c94565b61023b6103403660046124ea565b610d3c565b61023b60065481565b6102fd61035c366004612507565b610da5565b61023b61036f3660046124ea565b610dcf565b61023b6103823660046124ea565b610e4f565b61023b610395366004612600565b610e8b565b61023b6103a836600461262c565b610e99565b6000546102fd906001600160a01b031681565b6102136103ce3660046124ea565b610f02565b61023b6103e1366004612661565b611185565b6102136103f43660046124ea565b6111d3565b61023b6104073660046126d3565b6112d8565b61023b61041a3660046124ea565b6112e6565b61043261042d3660046124ea565b6114fe565b6040519015158152602001610245565b610213610450366004612715565b611539565b61023b610463366004612600565b6117e2565b61023b6104763660046124ea565b61185c565b61023b6104893660046124ea565b6001600160a01b03166000908152600760205260409020546001600160401b031690565b6102136104bb3660046124ea565b611868565b61023b60055481565b61023b6104d7366004612600565b6118e0565b6102136104ea3660046124ea565b611941565b6001546102fd906001600160a01b031681565b6004546102fd906001600160a01b031681565b610213610523366004612600565b611948565b610530611bd5565b6040516370a0823160e01b81523060048201526105af9033906001600160a01b038416906370a0823190602401602060405180830381865afa15801561057a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059e9190612770565b6001600160a01b0384169190611c1f565b50565b6105ba611bd5565b806000036106005760405162461bcd60e51b815260206004820152600e60248201526d7374617274696e6720707269636560901b60448201526064015b60405180910390fd5b6000600880548060200260200160405190810160405280929190818152602001828054801561065857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161063a575b5050505050905060005b81518110156106db5761068d82828151811061068057610680612789565b60200260200101516114fe565b156106cb5760405162461bcd60e51b815260206004820152600e60248201526d30b1ba34bb329030bab1ba34b7b760911b60448201526064016105f7565b6106d4816127b5565b9050610662565b5060058290556040518281527f9a662b9b8a431c26da8dea3d6a011bf4959a20ddbc3dfe618abfc3898d2c901f9060200160405180910390a15050565b6000610723826114fe565b61072f57506000919050565b6001600160a01b038216600081815260076020526040908190205490516370a0823160e01b81523060048201526107c292600160801b9092046001600160801b031691906370a0823190602401602060405180830381865afa158015610799573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107bd9190612770565b611c87565b92915050565b60006107d5600280541490565b156108225760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016105f7565b600061083083850185612832565b80516001600160a01b0316600090815260076020908152604080832081516060808201845291546001600160401b038082168352600160401b82041694820194909452600160801b9093046001600160801b0316918301919091528301519293509161089e90839042611c9e565b601f19840180517fd5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e48982526101a08220915260405161190160f01b81527f0000000000000000000000000000000000000000000000000000000000000000600282015260228101919091526042902090915087146109495760405162461bcd60e51b81526020600482015260096024820152683130b21037b93232b960b91b60448201526064016105f7565b806000036109875760405162461bcd60e51b815260206004820152600b60248201526a1e995c9bc8185b5bdd5b9d60aa1b60448201526064016105f7565b825161099290610718565b6000036109d25760405162461bcd60e51b815260206004820152600e60248201526d7a65726f20617661696c61626c6560901b60448201526064016105f7565b60e083015115610a0a5760405162461bcd60e51b815260206004820152600360248201526266656560e81b60448201526064016105f7565b826101200151610a4b5760405162461bcd60e51b815260206004820152600c60248201526b1c185c9d1a585b08199a5b1b60a21b60448201526064016105f7565b6006548251610a6391906001600160401b03166128f0565b8360a0015163ffffffff1610610aa55760405162461bcd60e51b8152602060048201526007602482015266195e1c1a5c995960ca1b60448201526064016105f7565b60c083015115610ae25760405162461bcd60e51b8152602060048201526008602482015267617070206461746160c01b60448201526064016105f7565b8083608001511015610b225760405162461bcd60e51b815260206004820152600960248201526862616420707269636560b81b60448201526064016105f7565b6003546001600160a01b03166001600160a01b031683602001516001600160a01b031614610b7e5760405162461bcd60e51b81526020600482015260096024820152683130b2103a37b5b2b760b91b60448201526064016105f7565b60045460408401516001600160a01b03908116911614610bcf5760405162461bcd60e51b815260206004820152600c60248201526b3130b2103932b1b2b4bb32b960a11b60448201526064016105f7565b81604001516001600160801b031683606001511115610c1d5760405162461bcd60e51b815260206004820152600a60248201526918985908185b5bdd5b9d60b21b60448201526064016105f7565b50630b135d3f60e11b925050505b9392505050565b60606008805480602002602001604051908101604052809291908181526020018280548015610c8a57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610c6c575b5050505050905090565b6001546001600160a01b03163314610ce45760405162461bcd60e51b81526020600482015260136024820152722170656e64696e6720676f7665726e616e636560681b60448201526064016105f7565b6000805460405133926001600160a01b03909216917f5f56bee8cffbe9a78652a74a60705edede02af10b0bbb888ca44b79a0d42ce8091a3600080546001600160a01b03199081163317909155600180549091169055565b6001600160a01b0381166000908152600760209081526040808320815160608101835290546001600160401b038082168352600160401b82041693820193909352600160801b9092046001600160801b0316908201526107c290610d9f84610718565b42611c9e565b60088181548110610db557600080fd5b6000918252602090912001546001600160a01b0316905081565b6000610dda826114fe565b15610de757506000919050565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610e2b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c29190612770565b60006107c28260001933845b6040519080825280601f01601f191660200182016040528015610e85576020820181803683370190505b50611d2b565b6000610c2b83833384610e5b565b6001600160a01b0383166000908152600760209081526040808320815160608101835290546001600160401b038082168352600160401b82041693820193909352600160801b9092046001600160801b031690820152610efa908484611c9e565b949350505050565b610f0a611bd5565b6000610f1e6003546001600160a01b031690565b90506001600160a01b03821615801590610f4a5750806001600160a01b0316826001600160a01b031614155b610f665760405162461bcd60e51b81526004016105f790612903565b6001600160a01b038216600090815260076020526040902054600160401b90046001600160401b031615610fce5760405162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e48195b98589b1959608a1b60448201526064016105f7565b6000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561100e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190612929565b60ff169050601281111561107f5760405162461bcd60e51b8152602060048201526014602482015273756e737570706f7274656420646563696d616c7360601b60448201526064016105f7565b61108a81600a612a30565b61109c90670de0b6b3a7640000612a52565b6001600160a01b038416600081815260076020526040902080546001600160401b0393909316600160401b026fffffffffffffffff000000000000000019909316929092179091556111059073c92e8bdf79f0507f65a392b0ab4667716bfe0110600019611f09565b6008805460018101825560009182527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b038681169182179092556040519185169290917fed6bfe4670b251246a8da2ece7f7b4f47fd7761ae0b2843a64d1ae1ee90fef4d9190a3505050565b60006111c986868686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d2b92505050565b9695505050505050565b6111dc816114fe565b6112125760405162461bcd60e51b81526020600482015260076024820152662161637469766560c81b60448201526064016105f7565b6040516370a0823160e01b81523060048201526001600160a01b038216906370a0823190602401602060405180830381865afa158015611256573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127a9190612770565b156112b05760405162461bcd60e51b815260206004820152600660248201526521656d70747960d01b60448201526064016105f7565b6001600160a01b03166000908152600760205260409020805467ffffffffffffffff19169055565b6000610efa84848484610e5b565b60006112f061201e565b6001600160a01b038216600090815260076020526040812054600160401b90046001600160401b031690036113555760405162461bcd60e51b815260206004820152600b60248201526a1b9bdd08195b98589b195960aa1b60448201526064016105f7565b6006546001600160a01b03831660009081526007602052604090205461138491906001600160401b03166128f0565b42116113bd5760405162461bcd60e51b81526020600482015260086024820152673a37b79039b7b7b760c11b60448201526064016105f7565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015611401573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114259190612770565b9050806000036114695760405162461bcd60e51b815260206004820152600f60248201526e6e6f7468696e6720746f206b69636b60881b60448201526064016105f7565b6001600160a01b0382166000818152600760205260409081902080546001600160801b038516600160801b026fffffffffffffffff00000000000000009091166001600160401b03421617179055517fb3831db58b36bd77258a9cc9589b88fab5d52f7a1814e6f17faec14b149fe084906114e79084815260200190565b60405180910390a26114f96001600255565b919050565b6006546001600160a01b0382166000908152600760205260408120549091429161153191906001600160401b03166128f0565b101592915050565b600654156115775760405162461bcd60e51b815260206004820152600b60248201526a1a5b9a5d1a585b1a5e995960aa1b60448201526064016105f7565b6001600160a01b03851661159d5760405162461bcd60e51b81526004016105f790612903565b816000036115d65760405162461bcd60e51b81526020600482015260066024820152650d8cadccee8d60d31b60448201526064016105f7565b806000036116175760405162461bcd60e51b815260206004820152600e60248201526d7374617274696e6720707269636560901b60448201526064016105f7565b6001600160a01b0384166116585760405162461bcd60e51b81526020600482015260086024820152673932b1b2b4bb32b960c11b60448201526064016105f7565b6000856001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bc9190612929565b60ff16905060128111156117095760405162461bcd60e51b8152602060048201526014602482015273756e737570706f7274656420646563696d616c7360601b60448201526064016105f7565b6040518060400160405280876001600160a01b0316815260200182600a6117309190612a30565b61174290670de0b6b3a7640000612a52565b6001600160601b03908116909152815160209092015116600160a01b026001600160a01b0391821617600355600480548783166001600160a01b0319918216179091556000805492871692909116919091179055600683905560058290556040517f9a662b9b8a431c26da8dea3d6a011bf4959a20ddbc3dfe618abfc3898d2c901f906117d29084815260200190565b60405180910390a1505050505050565b6003546001600160a01b0383166000908152600760205260408120549091600160a01b90046001600160601b031690611852906001600160401b038082169161184391600160401b82041690600160801b90046001600160801b0316612a66565b6001600160801b031685612075565b610c2b9190612a52565b60006107c282426117e2565b611870611bd5565b6001600160a01b0381166118965760405162461bcd60e51b81526004016105f790612903565b600180546001600160a01b0319166001600160a01b0383169081179091556040517fa443b483867b0f9db5b03913474dd21935ac5ba70fa6c94e3423ba9be157c44b90600090a250565b6001600160a01b0382166000908152600760209081526040808320815160608101835290546001600160401b038082168352600160401b82041693820193909352600160801b9092046001600160801b031690820152610c2b908342611c9e565b6105af8160005b611950611bd5565b6001600160a01b038216600090815260076020526040812054600160401b90046001600160401b031690036119b55760405162461bcd60e51b815260206004820152600b60248201526a1b9bdd08195b98589b195960aa1b60448201526064016105f7565b6001600160a01b03821660008181526007602052604081208190556119f0919073c92e8bdf79f0507f65a392b0ab4667716bfe011090611f09565b60006008805480602002602001604051908101604052809291908181526020018280548015611a4857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611a2a575b50505050509050826001600160a01b0316818381518110611a6b57611a6b612789565b60200260200101516001600160a01b031614611ad95760005b8151811015611ad757836001600160a01b0316828281518110611aa957611aa9612789565b60200260200101516001600160a01b031603611ac757809250611ad7565b611ad0816127b5565b9050611a84565b505b60018151611ae79190612a91565b821015611b52578060018251611afd9190612a91565b81518110611b0d57611b0d612789565b6020026020010151818381518110611b2757611b27612789565b6001600160a01b039092166020928302919091018201528151611b509160089190840190612450565b505b6008805480611b6357611b63612aa4565b600082815260209020600019908201810180546001600160a01b03191690550190556003546001600160a01b03166001600160a01b0316836001600160a01b03167f9c0e126ec038aaa740cee67f64da5b77aeaeb18634ddfb0b6c683a867490fb4160405160405180910390a3505050565b6000546001600160a01b03163314611c1d5760405162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b60448201526064016105f7565b565b6040516001600160a01b038316602482015260448101829052611c8290849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612153565b505050565b600081831115611c975781610c2b565b5090919050565b600354835160208501516040860151600093600160a01b90046001600160601b031692670de0b6b3a764000092611cf5926001600160401b0392831692611ce6921690612a66565b6001600160801b031686612075565b6020870151611d0d906001600160401b031687612aba565b611d179190612aba565b611d219190612a52565b610efa9190612a52565b6000611d3561201e565b6001600160a01b038516600090815260076020908152604091829020825160608101845290546001600160401b03808216808452600160401b830490911693830193909352600160801b90046001600160801b0316928101929092526006544291611da091906128f0565b1015611ddb5760405162461bcd60e51b815260206004820152600a6024820152691b9bdd081ada58dad95960b21b60448201526064016105f7565b6000611de687610718565b9050858111611df55780611df7565b855b92506000611e06838542611c9e565b905080600003611e465760405162461bcd60e51b815260206004820152600b60248201526a1e995c9bc81b995959195960aa1b60448201526064016105f7565b611e5a6001600160a01b0389168786611c1f565b845115611ec857604051631fcef5bf60e21b81526001600160a01b03871690637f3bd6fc90611e95908b903390899087908c90600401612b21565b600060405180830381600087803b158015611eaf57600080fd5b505af1158015611ec3573d6000803e3d6000fd5b505050505b6000611edc6003546001600160a01b031690565b600454909150611efb906001600160a01b038084169133911685612228565b50505050610efa6001600255565b801580611f835750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611f5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f819190612770565b155b611fee5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016105f7565b6040516001600160a01b038316602482015260448101829052611c8290849063095ea7b360e01b90606401611c4b565b600280540361206f5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016105f7565b60028055565b60008260000361208757506000610c2b565b60006120938584612a91565b90506006548111156120a9576000915050610c2b565b60006120b7610e1083612a52565b6b033b2e3c9fd0803ce8000000901c905060006120f76b0331adfc6b81cf95c39de3b1603c6120e8610e1087612b5b565b6120f29190612a52565b612266565b9050600061211a600554670de0b6b3a76400006121149190612aba565b886122df565b90506b033b2e3c9fd0803ce80000006121338484612309565b61213d9083612aba565b6121479190612a52565b98975050505050505050565b60006121a8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661232d9092919063ffffffff16565b90508051600014806121c95750808060200190518101906121c99190612b6f565b611c825760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105f7565b6040516001600160a01b03808516602483015283166044820152606481018290526122609085906323b872dd60e01b90608401611c4b565b50505050565b6000612273600283612b5b565b60000361228c576b033b2e3c9fd0803ce800000061228e565b825b905061229b600283612a52565b91505b81156107c2576122ae8384612309565b92506122bb600283612b5b565b156122cd576122ca8184612309565b90505b6122d8600283612a52565b915061229e565b6000816122ed600282612a52565b6122ff670de0b6b3a764000086612aba565b61185291906128f0565b60006b033b2e3c9fd0803ce8000000612323600282612a52565b6122ff8486612aba565b6060610efa848460008585600080866001600160a01b031685876040516123549190612b8c565b60006040518083038185875af1925050503d8060008114612391576040519150601f19603f3d011682016040523d82523d6000602084013e612396565b606091505b50915091506123a7878383876123b2565b979650505050505050565b6060831561242157825160000361241a576001600160a01b0385163b61241a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105f7565b5081610efa565b610efa83838151156124365781518083602001fd5b8060405162461bcd60e51b81526004016105f79190612ba8565b8280548282559060005260206000209081019282156124a5579160200282015b828111156124a557825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612470565b506124b19291506124b5565b5090565b5b808211156124b157600081556001016124b6565b6001600160a01b03811681146105af57600080fd5b80356114f9816124ca565b6000602082840312156124fc57600080fd5b8135610c2b816124ca565b60006020828403121561251957600080fd5b5035919050565b60008083601f84011261253257600080fd5b5081356001600160401b0381111561254957600080fd5b60208301915083602082850101111561256157600080fd5b9250929050565b60008060006040848603121561257d57600080fd5b8335925060208401356001600160401b0381111561259a57600080fd5b6125a686828701612520565b9497909650939450505050565b6020808252825182820181905260009190848201906040850190845b818110156125f45783516001600160a01b0316835292840192918401916001016125cf565b50909695505050505050565b6000806040838503121561261357600080fd5b823561261e816124ca565b946020939093013593505050565b60008060006060848603121561264157600080fd5b833561264c816124ca565b95602085013595506040909401359392505050565b60008060008060006080868803121561267957600080fd5b8535612684816124ca565b945060208601359350604086013561269b816124ca565b925060608601356001600160401b038111156126b657600080fd5b6126c288828901612520565b969995985093965092949392505050565b6000806000606084860312156126e857600080fd5b83356126f3816124ca565b925060208401359150604084013561270a816124ca565b809150509250925092565b600080600080600060a0868803121561272d57600080fd5b8535612738816124ca565b94506020860135612748816124ca565b93506040860135612758816124ca565b94979396509394606081013594506080013592915050565b60006020828403121561278257600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016127c7576127c761279f565b5060010190565b60405161018081016001600160401b03811182821017156127ff57634e487b7160e01b600052604160045260246000fd5b60405290565b803563ffffffff811681146114f957600080fd5b80151581146105af57600080fd5b80356114f981612819565b6000610180828403121561284557600080fd5b61284d6127ce565b612856836124df565b8152612864602084016124df565b6020820152612875604084016124df565b6040820152606083013560608201526080830135608082015261289a60a08401612805565b60a082015260c083013560c082015260e083013560e08201526101008084013581830152506101206128cd818501612827565b908201526101408381013590820152610160928301359281019290925250919050565b808201808211156107c2576107c261279f565b6020808252600c908201526b5a45524f204144445245535360a01b604082015260600190565b60006020828403121561293b57600080fd5b815160ff81168114610c2b57600080fd5b600181815b8085111561298757816000190482111561296d5761296d61279f565b8085161561297a57918102915b93841c9390800290612951565b509250929050565b60008261299e575060016107c2565b816129ab575060006107c2565b81600181146129c157600281146129cb576129e7565b60019150506107c2565b60ff8411156129dc576129dc61279f565b50506001821b6107c2565b5060208310610133831016604e8410600b8410161715612a0a575081810a6107c2565b612a14838361294c565b8060001904821115612a2857612a2861279f565b029392505050565b6000610c2b838361298f565b634e487b7160e01b600052601260045260246000fd5b600082612a6157612a61612a3c565b500490565b6001600160801b03818116838216028082169190828114612a8957612a8961279f565b505092915050565b818103818111156107c2576107c261279f565b634e487b7160e01b600052603160045260246000fd5b80820281158282048414176107c2576107c261279f565b60005b83811015612aec578181015183820152602001612ad4565b50506000910152565b60008151808452612b0d816020860160208601612ad1565b601f01601f19169290920160200192915050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190526000906123a790830184612af5565b600082612b6a57612b6a612a3c565b500690565b600060208284031215612b8157600080fd5b8151610c2b81612819565b60008251612b9e818460208701612ad1565b9190910192915050565b602081526000610c2b6020830184612af556fea26469706673582212203e88b6f9221d47f719cd268428bdf751f24ce9ea82369bcdf35339b41cbb242264736f6c63430008120033
Deployed Bytecode Sourcemap
723:20694:8:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21223:192;;;;;;:::i;:::-;;:::i;:::-;;14024:520;;;;;;:::i;:::-;;:::i;4959:277::-;;;;;;:::i;:::-;;:::i;:::-;;;872:25:14;;;860:2;845:18;4959:277:8;;;;;;;;19324:1516;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;1904:33:14;;;1886:52;;1874:2;1859:18;19324:1516:8;1742:202:14;2509:47:8;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;2509:47:8;;;;-1:-1:-1;;;2509:47:8;;;;;;-1:-1:-1;;;2509:47:8;;-1:-1:-1;;;;;2509:47:8;;;;;;;-1:-1:-1;;;;;2202:15:14;;;2184:34;;2254:15;;;;2249:2;2234:18;;2227:43;-1:-1:-1;;;;;2306:47:14;2286:18;;;2279:75;2135:2;2120:18;2509:47:8;1949:411:14;4664:99:8;4735:8;:21;-1:-1:-1;;;;;4735:21:8;4664:99;;;-1:-1:-1;;;;;2529:32:14;;;2511:51;;2499:2;2484:18;4664:99:8;2365:203:14;5944:157:8;;;:::i;:::-;;;;;;;:::i;1037:260:13:-;;;:::i;6932::8:-;;;;;;:::i;:::-;;:::i;2417:28::-;;;;;;2631:32;;;;;;:::i;:::-;;:::i;6401:287::-;;;;;;:::i;:::-;;:::i;15925:145::-;;;;;;:::i;:::-;;:::i;16441:180::-;;;;;;:::i;:::-;;:::i;8150:237::-;;;;;;:::i;:::-;;:::i;607:25:12:-;;;;;-1:-1:-1;;;;;607:25:12;;;11528:673:8;;;;;;:::i;:::-;;:::i;17646:229::-;;;;;;:::i;:::-;;:::i;21001:216::-;;;;;;:::i;:::-;;:::i;16989:206::-;;;;;;:::i;:::-;;:::i;14987:653::-;;;;;;:::i;:::-;;:::i;5728:149::-;;;;;;:::i;:::-;;:::i;:::-;;;5329:14:14;;5322:22;5304:41;;5292:2;5277:18;5728:149:8;5164:187:14;3415:957:8;;;;;;:::i;:::-;;:::i;9675:376::-;;;;;;:::i;:::-;;:::i;9280:123::-;;;;;;:::i;:::-;;:::i;5432:117::-;;;;;;:::i;:::-;-1:-1:-1;;;;;5520:15:8;5494:7;5520:15;;;:8;:15;;;;;:22;-1:-1:-1;;;;;5520:22:8;;5432:117;673:276:13;;;;;;:::i;:::-;;:::i;2332:28:8:-;;;;;;7506:226;;;;;;:::i;:::-;;:::i;12366:83::-;;;;;;:::i;:::-;;:::i;358:32:13:-;;;;;-1:-1:-1;;;;;358:32:13;;;2250:23:8;;;;;-1:-1:-1;;;;;2250:23:8;;;12679:1198;;;;;;:::i;:::-;;:::i;21223:192::-;313:18:12;:16;:18::i;:::-;21360:38:8::1;::::0;-1:-1:-1;;;21360:38:8;;21392:4:::1;21360:38;::::0;::::1;2511:51:14::0;21296:112:8::1;::::0;21336:10:::1;::::0;-1:-1:-1;;;;;21360:23:8;::::1;::::0;::::1;::::0;2484:18:14;;21360:38:8::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;21296:26:8;::::1;::::0;:112;:26:::1;:112::i;:::-;21223:192:::0;:::o;14024:520::-;313:18:12;:16;:18::i;:::-;14138:14:8::1;14156:1;14138:19:::0;14130:46:::1;;;::::0;-1:-1:-1;;;14130:46:8;;6419:2:14;14130:46:8::1;::::0;::::1;6401:21:14::0;6458:2;6438:18;;;6431:30;-1:-1:-1;;;6477:18:14;;;6470:44;6531:18;;14130:46:8::1;;;;;;;;;14248:33;14284:15;14248:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;14248:51:8::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;;;;;;;;14314:9;14309:136;14333:16;:23;14329:1;:27;14309:136;;;14386:29;14395:16;14412:1;14395:19;;;;;;;;:::i;:::-;;;;;;;14386:8;:29::i;:::-;14385:30;14377:57;;;::::0;-1:-1:-1;;;14377:57:8;;6894:2:14;14377:57:8::1;::::0;::::1;6876:21:14::0;6933:2;6913:18;;;6906:30;-1:-1:-1;;;6952:18:14;;;6945:44;7006:18;;14377:57:8::1;6692:338:14::0;14377:57:8::1;14358:3;::::0;::::1;:::i;:::-;;;14309:136;;;-1:-1:-1::0;14455:13:8::1;:30:::0;;;14501:36:::1;::::0;872:25:14;;;14501:36:8::1;::::0;860:2:14;845:18;14501:36:8::1;;;;;;;14120:424;14024:520:::0;:::o;4959:277::-;5022:7;5046:15;5055:5;5046:8;:15::i;:::-;5041:30;;-1:-1:-1;5070:1:8;;4959:277;-1:-1:-1;4959:277:8:o;5041:30::-;-1:-1:-1;;;;;5128:15:8;;;;;;:8;:15;;;;;;;:32;5178:37;;-1:-1:-1;;;5178:37:8;;5209:4;5178:37;;;2511:51:14;5101:128:8;;-1:-1:-1;;;5128:32:8;;;-1:-1:-1;;;;;5128:32:8;;:15;5178:22;;2484:18:14;;5178:37:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5101:9;:128::i;:::-;5082:147;4959:277;-1:-1:-1;;4959:277:8:o;19324:1516::-;19436:6;19522:25;1759:1:0;3098:7;;:19;;3017:107;19522:25:8;19521:26;19513:70;;;;-1:-1:-1;;;19513:70:8;;7509:2:14;19513:70:8;;;7491:21:14;7548:2;7528:18;;;7521:30;7587:33;7567:18;;;7560:61;7638:18;;19513:70:8;7307:355:14;19513:70:8;19644:27;19674:39;;;;19685:9;19674:39;:::i;:::-;19770:15;;-1:-1:-1;;;;;19753:34:8;19724:26;19753:34;;;:8;:34;;;;;;;;19724:63;;;;;;;;;;-1:-1:-1;;;;;19724:63:8;;;;;-1:-1:-1;;;19724:63:8;;;;;;;;;;-1:-1:-1;;;19724:63:8;;;-1:-1:-1;;;;;19724:63:8;;;;;;;;19931:16;;;19770:15;;-1:-1:-1;19724:63:8;19880:106;;19724:63;;19961:15;19880:16;:106::i;:::-;-1:-1:-1;;5423:14:10;;5462:16;;5509:9;5491:28;;5567:3;5546:25;;5584:23;;6165:4;6159:11;-1:-1:-1;;;6183:37:10;;20062:20:8;6263:1:10;6240:25;;6233:50;6326:2;6303:26;;6296:46;;;;6399:2;6370:32;;19856:130:8;;-1:-1:-1;20042:5:8;:41;20034:63;;;;-1:-1:-1;;;20034:63:8;;9887:2:14;20034:63:8;;;9869:21:14;9926:1;9906:18;;;9899:29;-1:-1:-1;;;9944:18:14;;;9937:39;9993:18;;20034:63:8;9685:332:14;20034:63:8;20115:13;20132:1;20115:18;20107:42;;;;-1:-1:-1;;;20107:42:8;;10224:2:14;20107:42:8;;;10206:21:14;10263:2;10243:18;;;10236:30;-1:-1:-1;;;10282:18:14;;;10275:41;10333:18;;20107:42:8;10022:335:14;20107:42:8;20185:15;;20167:35;;:9;:35::i;:::-;20206:1;20167:40;20159:67;;;;-1:-1:-1;;;20159:67:8;;10564:2:14;20159:67:8;;;10546:21:14;10603:2;10583:18;;;10576:30;-1:-1:-1;;;10622:18:14;;;10615:44;10676:18;;20159:67:8;10362:338:14;20159:67:8;20244:15;;;;:20;20236:36;;;;-1:-1:-1;;;20236:36:8;;10907:2:14;20236:36:8;;;10889:21:14;10946:1;10926:18;;;10919:29;-1:-1:-1;;;10964:18:14;;;10957:33;11007:18;;20236:36:8;10705:326:14;20236:36:8;20290:5;:23;;;20282:48;;;;-1:-1:-1;;;20282:48:8;;11238:2:14;20282:48:8;;;11220:21:14;11277:2;11257:18;;;11250:30;-1:-1:-1;;;11296:18:14;;;11289:42;11348:18;;20282:48:8;11036:336:14;20282:48:8;20381:13;;20364:14;;:30;;20381:13;-1:-1:-1;;;;;20364:30:8;;:::i;:::-;20348:5;:13;;;:46;;;20340:66;;;;-1:-1:-1;;;20340:66:8;;11709:2:14;20340:66:8;;;11691:21:14;11748:1;11728:18;;;11721:29;-1:-1:-1;;;11766:18:14;;;11759:37;11813:18;;20340:66:8;11507:330:14;20340:66:8;20424:13;;;;:27;20416:48;;;;-1:-1:-1;;;20416:48:8;;12044:2:14;20416:48:8;;;12026:21:14;12083:1;12063:18;;;12056:29;-1:-1:-1;;;12101:18:14;;;12094:38;12149:18;;20416:48:8;11842:331:14;20416:48:8;20501:13;20482:5;:15;;;:32;;20474:54;;;;-1:-1:-1;;;20474:54:8;;12380:2:14;20474:54:8;;;12362:21:14;12419:1;12399:18;;;12392:29;-1:-1:-1;;;12437:18:14;;;12430:39;12486:18;;20474:54:8;12178:332:14;20474:54:8;4735:8;:21;-1:-1:-1;;;;;4735:21:8;-1:-1:-1;;;;;20546:33:8;20554:5;:14;;;-1:-1:-1;;;;;20546:33:8;;20538:55;;;;-1:-1:-1;;;20538:55:8;;12717:2:14;20538:55:8;;;12699:21:14;12756:1;12736:18;;;12729:29;-1:-1:-1;;;12774:18:14;;;12767:39;12823:18;;20538:55:8;12515:332:14;20538:55:8;20629:8;;20611:14;;;;-1:-1:-1;;;;;20611:26:8;;;20629:8;;20611:26;20603:51;;;;-1:-1:-1;;;20603:51:8;;13054:2:14;20603:51:8;;;13036:21:14;13093:2;13073:18;;;13066:30;-1:-1:-1;;;13112:18:14;;;13105:42;13164:18;;20603:51:8;12852:336:14;20603:51:8;20692:7;:24;;;-1:-1:-1;;;;;20672:44:8;:5;:16;;;:44;;20664:67;;;;-1:-1:-1;;;20664:67:8;;13395:2:14;20664:67:8;;;13377:21:14;13434:2;13414:18;;;13407:30;-1:-1:-1;;;13453:18:14;;;13446:40;13503:18;;20664:67:8;13193:334:14;20664:67:8;-1:-1:-1;;;;20803:30:8;-1:-1:-1;;;19324:1516:8;;;;;;:::o;5944:157::-;6040:16;6079:15;6072:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;6072:22:8;;;;;;;;;;;;;;;;;;;;;;;5944:157;:::o;1037:260:13:-;1114:17;;-1:-1:-1;;;;;1114:17:13;1100:10;:31;1092:63;;;;-1:-1:-1;;;1092:63:13;;13734:2:14;1092:63:13;;;13716:21:14;13773:2;13753:18;;;13746:30;-1:-1:-1;;;13792:18:14;;;13785:49;13851:18;;1092:63:13;13532:343:14;1092:63:13;1193:10;;;1171:45;;1205:10;;-1:-1:-1;;;;;1193:10:13;;;;1171:45;;;1227:10;:23;;-1:-1:-1;;;;;;1227:23:13;;;1240:10;1227:23;;;;;1260:30;;;;;;;1037:260::o;6932::8:-;-1:-1:-1;;;;;7089:15:8;;7017:7;7089:15;;;:8;:15;;;;;;;;7055:130;;;;;;;;;-1:-1:-1;;;;;7055:130:8;;;;;-1:-1:-1;;;7055:130:8;;;;;;;;;;-1:-1:-1;;;7055:130:8;;;-1:-1:-1;;;;;7055:130:8;;;;;;;7122:16;7089:15;7122:9;:16::i;:::-;7156:15;7055:16;:130::i;2631:32::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2631:32:8;;-1:-1:-1;2631:32:8;:::o;6401:287::-;6465:7;6551:15;6560:5;6551:8;:15::i;:::-;6547:29;;;-1:-1:-1;6575:1:8;;6401:287;-1:-1:-1;6401:287:8:o;6547:29::-;6644:37;;-1:-1:-1;;;6644:37:8;;6675:4;6644:37;;;2511:51:14;-1:-1:-1;;;;;6644:22:8;;;;;2484:18:14;;6644:37:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;15925:145::-;15980:7;16006:57;16012:5;-1:-1:-1;;16038:10:8;15980:7;16050:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16050:12:8;;16006:5;:57::i;16441:180::-;16538:7;16564:50;16570:5;16577:10;16589;16538:7;16601:12;;8150:237;-1:-1:-1;;;;;8337:15:8;;8294:7;8337:15;;;:8;:15;;;;;;;;8320:60;;;;;;;;;-1:-1:-1;;;;;8320:60:8;;;;;-1:-1:-1;;;8320:60:8;;;;;;;;;;-1:-1:-1;;;8320:60:8;;;-1:-1:-1;;;;;8320:60:8;;;;;;;8354:13;8369:10;8320:16;:60::i;:::-;8313:67;8150:237;-1:-1:-1;;;;8150:237:8:o;11528:673::-;313:18:12;:16;:18::i;:::-;11601:13:8::1;11617:6;4735:8:::0;:21;-1:-1:-1;;;;;4735:21:8;;4664:99;11617:6:::1;11601:22:::0;-1:-1:-1;;;;;;11641:19:8;::::1;::::0;;::::1;::::0;:37:::1;;;11673:5;-1:-1:-1::0;;;;;11664:14:8::1;:5;-1:-1:-1::0;;;;;11664:14:8::1;;;11641:37;11633:62;;;;-1:-1:-1::0;;;11633:62:8::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;11713:15:8;::::1;;::::0;;;:8:::1;:15;::::0;;;;:22;-1:-1:-1;;;11713:22:8;::::1;-1:-1:-1::0;;;;;11713:22:8::1;:27:::0;11705:55:::1;;;::::0;-1:-1:-1;;;11705:55:8;;14423:2:14;11705:55:8::1;::::0;::::1;14405:21:14::0;14462:2;14442:18;;;14435:30;-1:-1:-1;;;14481:18:14;;;14474:45;14536:18;;11705:55:8::1;14221:339:14::0;11705:55:8::1;11817:16;11842:5;-1:-1:-1::0;;;;;11836:21:8::1;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11817:42;;;;11889:2;11877:8;:14;;11869:47;;;::::0;-1:-1:-1;;;11869:47:8;;15045:2:14;11869:47:8::1;::::0;::::1;15027:21:14::0;15084:2;15064:18;;;15057:30;-1:-1:-1;;;15103:18:14;;;15096:50;15163:18;;11869:47:8::1;14843:344:14::0;11869:47:8::1;11999:14;12005:8:::0;11999:2:::1;:14;:::i;:::-;11993:20;::::0;1675:4:::1;11993:20;:::i;:::-;-1:-1:-1::0;;;;;11961:15:8;::::1;;::::0;;;:8:::1;:15;::::0;;;;:53;;-1:-1:-1;;;;;11961:53:8;;;::::1;-1:-1:-1::0;;;11961:53:8::1;-1:-1:-1::0;;11961:53:8;;::::1;::::0;;;::::1;::::0;;;12025:58:::1;::::0;1989:42:::1;-1:-1:-1::0;;12025:24:8::1;:58::i;:::-;12123:15;:27:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;12123:27:8;;;;::::1;::::0;;-1:-1:-1;;;;;;12123:27:8::1;-1:-1:-1::0;;;;;12123:27:8;;::::1;::::0;;::::1;::::0;;;12166:28:::1;::::0;;;::::1;::::0;12123:27;;12166:28:::1;::::0;-1:-1:-1;12166:28:8::1;11591:610;;11528:673:::0;:::o;17646:229::-;17800:7;17826:42;17832:5;17839:10;17851:9;17862:5;;17826:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17826:5:8;;-1:-1:-1;;;17826:42:8:i;:::-;17819:49;17646:229;-1:-1:-1;;;;;;17646:229:8:o;21001:216::-;21067:15;21076:5;21067:8;:15::i;:::-;21059:35;;;;-1:-1:-1;;;21059:35:8;;17025:2:14;21059:35:8;;;17007:21:14;17064:1;17044:18;;;17037:29;-1:-1:-1;;;17082:18:14;;;17075:37;17129:18;;21059:35:8;16823:330:14;21059:35:8;21112:37;;-1:-1:-1;;;21112:37:8;;21143:4;21112:37;;;2511:51:14;-1:-1:-1;;;;;21112:22:8;;;;;2484:18:14;;21112:37:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:42;21104:61;;;;-1:-1:-1;;;21104:61:8;;17360:2:14;21104:61:8;;;17342:21:14;17399:1;17379:18;;;17372:29;-1:-1:-1;;;17417:18:14;;;17410:36;17463:18;;21104:61:8;17158:329:14;21104:61:8;-1:-1:-1;;;;;21176:15:8;21208:1;21176:15;;;:8;:15;;;;;:34;;-1:-1:-1;;21176:34:8;;;21001:216::o;16989:206::-;17113:7;17139:49;17145:5;17152:10;17164:9;17113:7;17175:12;;14987:653;15069:18;2261:21:0;:19;:21::i;:::-;-1:-1:-1;;;;;15107:15:8;::::1;;::::0;;;:8:::1;:15;::::0;;;;:22;-1:-1:-1;;;15107:22:8;::::1;-1:-1:-1::0;;;;;15107:22:8::1;:27:::0;;15099:51:::1;;;::::0;-1:-1:-1;;;15099:51:8;;17694:2:14;15099:51:8::1;::::0;::::1;17676:21:14::0;17733:2;17713:18;;;17706:30;-1:-1:-1;;;17752:18:14;;;17745:41;17803:18;;15099:51:8::1;17492:335:14::0;15099:51:8::1;15224:13;::::0;-1:-1:-1;;;;;15199:15:8;::::1;;::::0;;;:8:::1;:15;::::0;;;;:22;:38:::1;::::0;15224:13;-1:-1:-1;;;;;15199:22:8::1;:38;:::i;:::-;15181:15;:56;15160:111;;;::::0;-1:-1:-1;;;15160:111:8;;18034:2:14;15160:111:8::1;::::0;::::1;18016:21:14::0;18073:1;18053:18;;;18046:29;-1:-1:-1;;;18091:18:14;;;18084:38;18139:18;;15160:111:8::1;17832:331:14::0;15160:111:8::1;15332:37;::::0;-1:-1:-1;;;15332:37:8;;15363:4:::1;15332:37;::::0;::::1;2511:51:14::0;-1:-1:-1;;;;;15332:22:8;::::1;::::0;::::1;::::0;2484:18:14;;15332:37:8::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15319:50;;15388:10;15402:1;15388:15:::0;15380:43:::1;;;::::0;-1:-1:-1;;;15380:43:8;;18370:2:14;15380:43:8::1;::::0;::::1;18352:21:14::0;18409:2;18389:18;;;18382:30;-1:-1:-1;;;18428:18:14;;;18421:45;18483:18;;15380:43:8::1;18168:339:14::0;15380:43:8::1;-1:-1:-1::0;;;;;15473:15:8;::::1;;::::0;;;:8:::1;:15;::::0;;;;;;:48;;-1:-1:-1;;;;;15531:54:8;::::1;-1:-1:-1::0;;;15531:54:8::1;::::0;;;;-1:-1:-1;;;;;15505:15:8::1;15473:48;15531:54:::0;::::1;::::0;;15601:32;::::1;::::0;::::1;::::0;15574:10;872:25:14;;860:2;845:18;;726:177;15601:32:8::1;;;;;;;;2303:20:0::0;1716:1;2809:7;:22;2629:209;2303:20;14987:653:8;;;:::o;5728:149::-;5838:13;;-1:-1:-1;;;;;5813:15:8;;5790:4;5813:15;;;:8;:15;;;;;:22;5790:4;;5855:15;;5813:38;;5838:13;-1:-1:-1;;;;;5813:22:8;:38;:::i;:::-;:57;;;5728:149;-1:-1:-1;;5728:149:8:o;3415:957::-;3617:13;;:18;3609:42;;;;-1:-1:-1;;;3609:42:8;;18714:2:14;3609:42:8;;;18696:21:14;18753:2;18733:18;;;18726:30;-1:-1:-1;;;18772:18:14;;;18765:41;18823:18;;3609:42:8;18512:335:14;3609:42:8;-1:-1:-1;;;;;3669:19:8;;3661:44;;;;-1:-1:-1;;;3661:44:8;;;;;;;:::i;:::-;3723:14;3741:1;3723:19;3715:38;;;;-1:-1:-1;;;3715:38:8;;19054:2:14;3715:38:8;;;19036:21:14;19093:1;19073:18;;;19066:29;-1:-1:-1;;;19111:18:14;;;19104:36;19157:18;;3715:38:8;18852:329:14;3715:38:8;3771:14;3789:1;3771:19;3763:46;;;;-1:-1:-1;;;3763:46:8;;6419:2:14;3763:46:8;;;6401:21:14;6458:2;6438:18;;;6431:30;-1:-1:-1;;;6477:18:14;;;6470:44;6531:18;;3763:46:8;6217:338:14;3763:46:8;-1:-1:-1;;;;;3827:23:8;;3819:44;;;;-1:-1:-1;;;3819:44:8;;19388:2:14;3819:44:8;;;19370:21:14;19427:1;19407:18;;;19400:29;-1:-1:-1;;;19445:18:14;;;19438:38;19493:18;;3819:44:8;19186:331:14;3819:44:8;3919:16;3944:5;-1:-1:-1;;;;;3938:21:8;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3919:42;;;;3991:2;3979:8;:14;;3971:47;;;;-1:-1:-1;;;3971:47:8;;15045:2:14;3971:47:8;;;15027:21:14;15084:2;15064:18;;;15057:30;-1:-1:-1;;;15103:18:14;;;15096:50;15163:18;;3971:47:8;14843:344:14;3971:47:8;4065:104;;;;;;;;4103:5;-1:-1:-1;;;;;4065:104:8;;;;;4149:8;4143:2;:14;;;;:::i;:::-;4137:20;;1675:4;4137:20;:::i;:::-;-1:-1:-1;;;;;4065:104:8;;;;;;4054:115;;;;;;;;-1:-1:-1;;;4054:115:8;-1:-1:-1;;;;;4054:115:8;;;;:8;:115;4180:8;:20;;;;;-1:-1:-1;;;;;;4180:20:8;;;;;;;4054:115;4210:24;;;;;;;;;;;;;;;4244:13;:30;;;4284:13;:30;;;4329:36;;;;;;4300:14;872:25:14;;860:2;845:18;;726:177;4329:36:8;;;;;;;;3599:773;3415:957;;;;;:::o;9675:376::-;10029:8;:15;-1:-1:-1;;;;;9887:15:8;;9776:7;9887:15;;;:8;:15;;;;;:22;9776:7;;-1:-1:-1;;;10029:15:8;;-1:-1:-1;;;;;10029:15:8;;9863:163;;-1:-1:-1;;;;;9887:22:8;;;;9927:57;;-1:-1:-1;;;9962:22:8;;;;-1:-1:-1;;;9927:32:8;;-1:-1:-1;;;;;9927:32:8;:57;:::i;:::-;-1:-1:-1;;;;;9863:163:8;10002:10;9863:6;:163::i;:::-;:181;;;;:::i;9280:123::-;9341:7;9367:29;9373:5;9380:15;9367:5;:29::i;673:276:13:-;313:18:12;:16;:18::i;:::-;-1:-1:-1;;;;;798:28:13;::::1;790:53;;;;-1:-1:-1::0;;;790:53:13::1;;;;;;;:::i;:::-;853:17;:34:::0;;-1:-1:-1;;;;;;853:34:13::1;-1:-1:-1::0;;;;;853:34:13;::::1;::::0;;::::1;::::0;;;903:39:::1;::::0;::::1;::::0;-1:-1:-1;;903:39:13::1;673:276:::0;:::o;7506:226:8:-;-1:-1:-1;;;;;7677:15:8;;7622:7;7677:15;;;:8;:15;;;;;;;;7660:65;;;;;;;;;-1:-1:-1;;;;;7660:65:8;;;;;-1:-1:-1;;;7660:65:8;;;;;;;;;;-1:-1:-1;;;7660:65:8;;;-1:-1:-1;;;;;7660:65:8;;;;;;;7694:13;7709:15;7660:16;:65::i;12366:83::-;12425:17;12433:5;12440:1;12679:1198;313:18:12;:16;:18::i;:::-;-1:-1:-1;;;;;12843:15:8;::::1;;::::0;;;:8:::1;:15;::::0;;;;:22;-1:-1:-1;;;12843:22:8;::::1;-1:-1:-1::0;;;;;12843:22:8::1;:27:::0;;12835:51:::1;;;::::0;-1:-1:-1;;;12835:51:8;;17694:2:14;12835:51:8::1;::::0;::::1;17676:21:14::0;17733:2;17713:18;;;17706:30;-1:-1:-1;;;17752:18:14;;;17745:41;17803:18;;12835:51:8::1;17492:335:14::0;12835:51:8::1;-1:-1:-1::0;;;;;12934:15:8;::::1;;::::0;;;:8:::1;:15;::::0;;;;12927:22;;;12960:42:::1;::::0;12934:15;1989:42:::1;::::0;12960:24:::1;:42::i;:::-;13062:33;13098:15;13062:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;13062:51:8::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;;;;;;;;13155:5;-1:-1:-1::0;;;;;13127:33:8::1;:16;13144:6;13127:24;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;13127:33:8::1;;13123:319;;13239:9;13234:198;13258:16;:23;13254:1;:27;13234:198;;;13333:5;-1:-1:-1::0;;;;;13310:28:8::1;:16;13327:1;13310:19;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;13310:28:8::1;::::0;13306:112:::1;;13371:1;13362:10;;13394:5;;13306:112;13283:3;::::0;::::1;:::i;:::-;;;13234:198;;;;13123:319;13545:1;13519:16;:23;:27;;;;:::i;:::-;13510:6;:36;13506:250;;;13589:16;13649:1;13623:16;:23;:27;;;;:::i;:::-;13589:75;;;;;;;;:::i;:::-;;;;;;;13562:16;13579:6;13562:24;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;13562:102:8;;::::1;:24;::::0;;::::1;::::0;;;;;;:102;13711:34;;::::1;::::0;:15:::1;::::0;:34;;::::1;::::0;::::1;:::i;:::-;;13506:250;13803:15;:21;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;-1:-1:-1;;13803:21:8;;;;;;;-1:-1:-1;;;;;;13803:21:8::1;::::0;;;;;4735:8;:21;-1:-1:-1;;;;;4735:21:8;-1:-1:-1;;;;;13840:30:8::1;13856:5;-1:-1:-1::0;;;;;13840:30:8::1;;;;;;;;;;;12779:1098;12679:1198:::0;;:::o;415:115:12:-;483:10;;-1:-1:-1;;;;;483:10:12;497;483:24;475:48;;;;-1:-1:-1;;;475:48:12;;20268:2:14;475:48:12;;;20250:21:14;20307:2;20287:18;;;20280:30;-1:-1:-1;;;20326:18:14;;;20319:41;20377:18;;475:48:12;20066:335:14;475:48:12;415:115::o;941:175:5:-;1050:58;;-1:-1:-1;;;;;20598:32:14;;1050:58:5;;;20580:51:14;20647:18;;;20640:34;;;1023:86:5;;1043:5;;-1:-1:-1;;;1073:23:5;20553:18:14;;1050:58:5;;;;-1:-1:-1;;1050:58:5;;;;;;;;;;;;;;-1:-1:-1;;;;;1050:58:5;-1:-1:-1;;;;;;1050:58:5;;;;;;;;;;1023:19;:86::i;:::-;941:175;;;:::o;1321:105:11:-;1379:7;1410:1;1405;:6;;:14;;1418:1;1405:14;;;-1:-1:-1;1414:1:11;;1321:105;-1:-1:-1;1321:105:11:o;8480:602:8:-;9060:8;:15;8855;;8920;;;;8892:25;;;;8639:7;;-1:-1:-1;;;9060:15:8;;-1:-1:-1;;;;;9060:15:8;;9001:4;;8827:158;;-1:-1:-1;;;;;8827:158:8;;;;8892:43;;;;;:::i;:::-;-1:-1:-1;;;;;8827:158:8;8957:10;8827:6;:158::i;:::-;8753:15;;;;8721:47;;-1:-1:-1;;;;;8721:47:8;:13;:47;:::i;:::-;:264;;;;:::i;:::-;8720:285;;;;:::i;:::-;:355;;;;:::i;17930:1342::-;18096:20;2261:21:0;:19;:21::i;:::-;-1:-1:-1;;;;;18157:15:8;::::1;18128:26;18157:15:::0;;;:8:::1;:15;::::0;;;;;;;;18128:44;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;18128:44:8;;::::1;::::0;;;-1:-1:-1;;;18128:44:8;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;-1:-1:-1;;;18128:44:8;::::1;-1:-1:-1::0;;;;;18128:44:8::1;::::0;;;;;;;18264:13:::1;::::0;18281:15:::1;::::0;18247:30:::1;::::0;18264:13;18247:30:::1;:::i;:::-;:49;;18226:106;;;::::0;-1:-1:-1;;;18226:106:8;;21060:2:14;18226:106:8::1;::::0;::::1;21042:21:14::0;21099:2;21079:18;;;21072:30;-1:-1:-1;;;21118:18:14;;;21111:40;21168:18;;18226:106:8::1;20858:334:14::0;18226:106:8::1;18384:18;18405:16;18415:5;18405:9;:16::i;:::-;18384:37;;18459:10;18446;:23;:49;;18485:10;18446:49;;;18472:10;18446:49;18431:64;;18539:14;18556:102;18586:7;18607:12;18633:15;18556:16;:102::i;:::-;18539:119;;18677:6;18687:1;18677:11:::0;18669:35:::1;;;::::0;-1:-1:-1;;;18669:35:8;;21399:2:14;18669:35:8::1;::::0;::::1;21381:21:14::0;21438:2;21418:18;;;21411:30;-1:-1:-1;;;21457:18:14;;;21450:41;21508:18;;18669:35:8::1;21197:335:14::0;18669:35:8::1;18739:50;-1:-1:-1::0;;;;;18739:25:8;::::1;18765:9:::0;18776:12;18739:25:::1;:50::i;:::-;18849:12:::0;;:17;18845:259:::1;;18914:179;::::0;-1:-1:-1;;;18914:179:8;;-1:-1:-1;;;;;18914:37:8;::::1;::::0;::::1;::::0;:179:::1;::::0;18969:5;;18992:10:::1;::::0;19020:12;;19050:6;;19074:5;;18914:179:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;18845:259;19149:13;19165:6;4735:8:::0;:21;-1:-1:-1;;;;;4735:21:8;;4664:99;19165:6:::1;19248:8;::::0;19149:22;;-1:-1:-1;19206:59:8::1;::::0;-1:-1:-1;;;;;19206:29:8;;::::1;::::0;19236:10:::1;::::0;19248:8:::1;19258:6:::0;19206:29:::1;:59::i;:::-;18118:1154;;;;2303:20:0::0;1716:1;2809:7;:22;2629:209;1818:573:5;2143:10;;;2142:62;;-1:-1:-1;2159:39:5;;-1:-1:-1;;;2159:39:5;;2183:4;2159:39;;;22844:34:14;-1:-1:-1;;;;;22914:15:14;;;22894:18;;;22887:43;2159:15:5;;;;;22779:18:14;;2159:39:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;2142:62;2121:163;;;;-1:-1:-1;;;2121:163:5;;23143:2:14;2121:163:5;;;23125:21:14;23182:2;23162:18;;;23155:30;23221:34;23201:18;;;23194:62;-1:-1:-1;;;23272:18:14;;;23265:52;23334:19;;2121:163:5;22941:418:14;2121:163:5;2321:62;;-1:-1:-1;;;;;20598:32:14;;2321:62:5;;;20580:51:14;20647:18;;;20640:34;;;2294:90:5;;2314:5;;-1:-1:-1;;;2344:22:5;20553:18:14;;2321:62:5;20406:274:14;2336:287:0;1759:1;2468:7;;:19;2460:63;;;;-1:-1:-1;;;2460:63:0;;7509:2:14;2460:63:0;;;7491:21:14;7548:2;7528:18;;;7521:30;7587:33;7567:18;;;7560:61;7638:18;;2460:63:0;7307:355:14;2460:63:0;1759:1;2598:18;;2336:287::o;10418:813:8:-;10552:7;10575:10;10589:1;10575:15;10571:29;;-1:-1:-1;10599:1:8;10592:8;;10571:29;10611:22;10636:20;10649:7;10636:10;:20;:::i;:::-;10611:45;;10688:13;;10671:14;:30;10667:44;;;10710:1;10703:8;;;;;10667:44;10852:22;10886:21;10903:4;10886:14;:21;:::i;:::-;10877:4;:31;;;-1:-1:-1;10918:24:8;10945:92;1781:37;11025:2;11000:21;11017:4;11000:14;:21;:::i;:::-;10999:28;;;;:::i;:::-;10945:10;:92::i;:::-;10918:119;;11047:20;11070:44;11081:13;;11097:4;11081:20;;;;:::i;:::-;11103:10;11070;:44::i;:::-;11047:67;;11220:4;11160:44;11171:14;11187:16;11160:10;:44::i;:::-;11145:59;;:12;:59;:::i;:::-;11144:80;;;;:::i;:::-;11125:99;10418:813;-1:-1:-1;;;;;;;;10418:813:8:o;5196:642:5:-;5615:23;5641:69;5669:4;5641:69;;;;;;;;;;;;;;;;;5649:5;-1:-1:-1;;;;;5641:27:5;;;:69;;;;;:::i;:::-;5615:95;;5728:10;:17;5749:1;5728:22;:56;;;;5765:10;5754:30;;;;;;;;;;;;:::i;:::-;5720:111;;;;-1:-1:-1;;;5720:111:5;;23933:2:14;5720:111:5;;;23915:21:14;23972:2;23952:18;;;23945:30;24011:34;23991:18;;;23984:62;-1:-1:-1;;;24062:18:14;;;24055:40;24112:19;;5720:111:5;23731:406:14;1355:203:5;1482:68;;-1:-1:-1;;;;;24400:15:14;;;1482:68:5;;;24382:34:14;24452:15;;24432:18;;;24425:43;24484:18;;;24477:34;;;1455:96:5;;1475:5;;-1:-1:-1;;;1505:27:5;24317:18:14;;1482:68:5;24142:375:14;1455:96:5;1355:203;;;;:::o;1646:266:11:-;1705:9;1730:5;1734:1;1730;:5;:::i;:::-;1739:1;1730:10;:20;;363:4;1730:20;;;1743:1;1730:20;1726:24;-1:-1:-1;1766:6:11;1771:1;1766:6;;:::i;:::-;;;1761:145;1774:6;;1761:145;;1808:10;1813:1;1816;1808:4;:10::i;:::-;1804:14;-1:-1:-1;1837:5:11;1841:1;1837;:5;:::i;:::-;:10;1833:63;;1871:10;1876:1;1879;1871:4;:10::i;:::-;1867:14;;1833:63;1782:6;1787:1;1782:6;;:::i;:::-;;;1761:145;;736:113;795:7;841:1;832:5;836:1;841;832:5;:::i;:::-;822:7;321:4;822:1;:7;:::i;:::-;:15;;;;:::i;1525:115::-;1584:7;363:4;1619:7;1625:1;363:4;1619:7;:::i;:::-;1611:5;1615:1;1611;:5;:::i;4108:223:6:-;4241:12;4272:52;4294:6;4302:4;4308:1;4311:12;4241;5446;5460:23;5487:6;-1:-1:-1;;;;;5487:11:6;5506:5;5513:4;5487:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5445:73;;;;5535:69;5562:6;5570:7;5579:10;5591:12;5535:26;:69::i;:::-;5528:76;5165:446;-1:-1:-1;;;;;;;5165:446:6:o;7671:628::-;7851:12;7879:7;7875:418;;;7906:10;:17;7927:1;7906:22;7902:286;;-1:-1:-1;;;;;1702:19:6;;;8113:60;;;;-1:-1:-1;;;8113:60:6;;25423:2:14;8113:60:6;;;25405:21:14;25462:2;25442:18;;;25435:30;25501:31;25481:18;;;25474:59;25550:18;;8113:60:6;25221:353:14;8113:60:6;-1:-1:-1;8208:10:6;8201:17;;7875:418;8249:33;8257:10;8269:12;8980:17;;:21;8976:379;;9208:10;9202:17;9264:15;9251:10;9247:2;9243:19;9236:44;8976:379;9331:12;9324:20;;-1:-1:-1;;;9324:20:6;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:14;-1:-1:-1;;;;;89:31:14;;79:42;;69:70;;135:1;132;125:12;150:134;218:20;;247:31;218:20;247:31;:::i;289:247::-;348:6;401:2;389:9;380:7;376:23;372:32;369:52;;;417:1;414;407:12;369:52;456:9;443:23;475:31;500:5;475:31;:::i;541:180::-;600:6;653:2;641:9;632:7;628:23;624:32;621:52;;;669:1;666;659:12;621:52;-1:-1:-1;692:23:14;;541:180;-1:-1:-1;541:180:14:o;908:347::-;959:8;969:6;1023:3;1016:4;1008:6;1004:17;1000:27;990:55;;1041:1;1038;1031:12;990:55;-1:-1:-1;1064:20:14;;-1:-1:-1;;;;;1096:30:14;;1093:50;;;1139:1;1136;1129:12;1093:50;1176:4;1168:6;1164:17;1152:29;;1228:3;1221:4;1212:6;1204;1200:19;1196:30;1193:39;1190:59;;;1245:1;1242;1235:12;1190:59;908:347;;;;;:::o;1260:477::-;1339:6;1347;1355;1408:2;1396:9;1387:7;1383:23;1379:32;1376:52;;;1424:1;1421;1414:12;1376:52;1460:9;1447:23;1437:33;;1521:2;1510:9;1506:18;1493:32;-1:-1:-1;;;;;1540:6:14;1537:30;1534:50;;;1580:1;1577;1570:12;1534:50;1619:58;1669:7;1660:6;1649:9;1645:22;1619:58;:::i;:::-;1260:477;;1696:8;;-1:-1:-1;1593:84:14;;-1:-1:-1;;;;1260:477:14:o;2573:658::-;2744:2;2796:21;;;2866:13;;2769:18;;;2888:22;;;2715:4;;2744:2;2967:15;;;;2941:2;2926:18;;;2715:4;3010:195;3024:6;3021:1;3018:13;3010:195;;;3089:13;;-1:-1:-1;;;;;3085:39:14;3073:52;;3180:15;;;;3145:12;;;;3121:1;3039:9;3010:195;;;-1:-1:-1;3222:3:14;;2573:658;-1:-1:-1;;;;;;2573:658:14:o;3236:315::-;3304:6;3312;3365:2;3353:9;3344:7;3340:23;3336:32;3333:52;;;3381:1;3378;3371:12;3333:52;3420:9;3407:23;3439:31;3464:5;3439:31;:::i;:::-;3489:5;3541:2;3526:18;;;;3513:32;;-1:-1:-1;;;3236:315:14:o;3556:383::-;3633:6;3641;3649;3702:2;3690:9;3681:7;3677:23;3673:32;3670:52;;;3718:1;3715;3708:12;3670:52;3757:9;3744:23;3776:31;3801:5;3776:31;:::i;:::-;3826:5;3878:2;3863:18;;3850:32;;-1:-1:-1;3929:2:14;3914:18;;;3901:32;;3556:383;-1:-1:-1;;;3556:383:14:o;3944:754::-;4041:6;4049;4057;4065;4073;4126:3;4114:9;4105:7;4101:23;4097:33;4094:53;;;4143:1;4140;4133:12;4094:53;4182:9;4169:23;4201:31;4226:5;4201:31;:::i;:::-;4251:5;-1:-1:-1;4303:2:14;4288:18;;4275:32;;-1:-1:-1;4359:2:14;4344:18;;4331:32;4372:33;4331:32;4372:33;:::i;:::-;4424:7;-1:-1:-1;4482:2:14;4467:18;;4454:32;-1:-1:-1;;;;;4498:30:14;;4495:50;;;4541:1;4538;4531:12;4495:50;4580:58;4630:7;4621:6;4610:9;4606:22;4580:58;:::i;:::-;3944:754;;;;-1:-1:-1;3944:754:14;;-1:-1:-1;4657:8:14;;4554:84;3944:754;-1:-1:-1;;;3944:754:14:o;4703:456::-;4780:6;4788;4796;4849:2;4837:9;4828:7;4824:23;4820:32;4817:52;;;4865:1;4862;4855:12;4817:52;4904:9;4891:23;4923:31;4948:5;4923:31;:::i;:::-;4973:5;-1:-1:-1;5025:2:14;5010:18;;4997:32;;-1:-1:-1;5081:2:14;5066:18;;5053:32;5094:33;5053:32;5094:33;:::i;:::-;5146:7;5136:17;;;4703:456;;;;;:::o;5356:667::-;5451:6;5459;5467;5475;5483;5536:3;5524:9;5515:7;5511:23;5507:33;5504:53;;;5553:1;5550;5543:12;5504:53;5592:9;5579:23;5611:31;5636:5;5611:31;:::i;:::-;5661:5;-1:-1:-1;5718:2:14;5703:18;;5690:32;5731:33;5690:32;5731:33;:::i;:::-;5783:7;-1:-1:-1;5842:2:14;5827:18;;5814:32;5855:33;5814:32;5855:33;:::i;:::-;5356:667;;;;-1:-1:-1;5907:7:14;;5961:2;5946:18;;5933:32;;-1:-1:-1;6012:3:14;5997:19;5984:33;;5356:667;-1:-1:-1;;5356:667:14:o;6028:184::-;6098:6;6151:2;6139:9;6130:7;6126:23;6122:32;6119:52;;;6167:1;6164;6157:12;6119:52;-1:-1:-1;6190:16:14;;6028:184;-1:-1:-1;6028:184:14:o;6560:127::-;6621:10;6616:3;6612:20;6609:1;6602:31;6652:4;6649:1;6642:15;6676:4;6673:1;6666:15;7035:127;7096:10;7091:3;7087:20;7084:1;7077:31;7127:4;7124:1;7117:15;7151:4;7148:1;7141:15;7167:135;7206:3;7227:17;;;7224:43;;7247:18;;:::i;:::-;-1:-1:-1;7294:1:14;7283:13;;7167:135::o;7799:344::-;7866:2;7860:9;7908:3;7896:16;;-1:-1:-1;;;;;7927:34:14;;7963:22;;;7924:62;7921:185;;;8028:10;8023:3;8019:20;8016:1;8009:31;8063:4;8060:1;8053:15;8091:4;8088:1;8081:15;7921:185;8122:2;8115:22;7799:344;:::o;8148:163::-;8215:20;;8275:10;8264:22;;8254:33;;8244:61;;8301:1;8298;8291:12;8316:118;8402:5;8395:13;8388:21;8381:5;8378:32;8368:60;;8424:1;8421;8414:12;8439:128;8504:20;;8533:28;8504:20;8533:28;:::i;8572:1108::-;8653:6;8706:3;8694:9;8685:7;8681:23;8677:33;8674:53;;;8723:1;8720;8713:12;8674:53;8749:17;;:::i;:::-;8789:29;8808:9;8789:29;:::i;:::-;8782:5;8775:44;8851:38;8885:2;8874:9;8870:18;8851:38;:::i;:::-;8846:2;8839:5;8835:14;8828:62;8922:38;8956:2;8945:9;8941:18;8922:38;:::i;:::-;8917:2;8910:5;8906:14;8899:62;9021:2;9010:9;9006:18;8993:32;8988:2;8981:5;8977:14;8970:56;9087:3;9076:9;9072:19;9059:33;9053:3;9046:5;9042:15;9035:58;9126:38;9159:3;9148:9;9144:19;9126:38;:::i;:::-;9120:3;9113:5;9109:15;9102:63;9226:3;9215:9;9211:19;9198:33;9192:3;9185:5;9181:15;9174:58;9293:3;9282:9;9278:19;9265:33;9259:3;9252:5;9248:15;9241:58;9318:3;9381:2;9370:9;9366:18;9353:32;9348:2;9341:5;9337:14;9330:56;;9405:3;9440:35;9471:2;9460:9;9456:18;9440:35;:::i;:::-;9424:14;;;9417:59;9495:3;9543:18;;;9530:32;9514:14;;;9507:56;9582:3;9630:18;;;9617:32;9601:14;;;9594:56;;;;-1:-1:-1;9428:5:14;8572:1108;-1:-1:-1;8572:1108:14:o;11377:125::-;11442:9;;;11463:10;;;11460:36;;;11476:18;;:::i;13880:336::-;14082:2;14064:21;;;14121:2;14101:18;;;14094:30;-1:-1:-1;;;14155:2:14;14140:18;;14133:42;14207:2;14192:18;;13880:336::o;14565:273::-;14633:6;14686:2;14674:9;14665:7;14661:23;14657:32;14654:52;;;14702:1;14699;14692:12;14654:52;14734:9;14728:16;14784:4;14777:5;14773:16;14766:5;14763:27;14753:55;;14804:1;14801;14794:12;15192:422;15281:1;15324:5;15281:1;15338:270;15359:7;15349:8;15346:21;15338:270;;;15418:4;15414:1;15410:6;15406:17;15400:4;15397:27;15394:53;;;15427:18;;:::i;:::-;15477:7;15467:8;15463:22;15460:55;;;15497:16;;;;15460:55;15576:22;;;;15536:15;;;;15338:270;;;15342:3;15192:422;;;;;:::o;15619:806::-;15668:5;15698:8;15688:80;;-1:-1:-1;15739:1:14;15753:5;;15688:80;15787:4;15777:76;;-1:-1:-1;15824:1:14;15838:5;;15777:76;15869:4;15887:1;15882:59;;;;15955:1;15950:130;;;;15862:218;;15882:59;15912:1;15903:10;;15926:5;;;15950:130;15987:3;15977:8;15974:17;15971:43;;;15994:18;;:::i;:::-;-1:-1:-1;;16050:1:14;16036:16;;16065:5;;15862:218;;16164:2;16154:8;16151:16;16145:3;16139:4;16136:13;16132:36;16126:2;16116:8;16113:16;16108:2;16102:4;16099:12;16095:35;16092:77;16089:159;;;-1:-1:-1;16201:19:14;;;16233:5;;16089:159;16280:34;16305:8;16299:4;16280:34;:::i;:::-;16350:6;16346:1;16342:6;16338:19;16329:7;16326:32;16323:58;;;16361:18;;:::i;:::-;16399:20;;15619:806;-1:-1:-1;;;15619:806:14:o;16430:131::-;16490:5;16519:36;16546:8;16540:4;16519:36;:::i;16566:127::-;16627:10;16622:3;16618:20;16615:1;16608:31;16658:4;16655:1;16648:15;16682:4;16679:1;16672:15;16698:120;16738:1;16764;16754:35;;16769:18;;:::i;:::-;-1:-1:-1;16803:9:14;;16698:120::o;19522:274::-;-1:-1:-1;;;;;19660:10:14;;;19672;;;19656:27;19703:20;;;;19594:34;19742:24;;;19732:58;;19770:18;;:::i;:::-;19732:58;;19522:274;;;;:::o;19801:128::-;19868:9;;;19889:11;;;19886:37;;;19903:18;;:::i;19934:127::-;19995:10;19990:3;19986:20;19983:1;19976:31;20026:4;20023:1;20016:15;20050:4;20047:1;20040:15;20685:168;20758:9;;;20789;;20806:15;;;20800:22;;20786:37;20776:71;;20827:18;;:::i;21537:250::-;21622:1;21632:113;21646:6;21643:1;21640:13;21632:113;;;21722:11;;;21716:18;21703:11;;;21696:39;21668:2;21661:10;21632:113;;;-1:-1:-1;;21779:1:14;21761:16;;21754:27;21537:250::o;21792:270::-;21833:3;21871:5;21865:12;21898:6;21893:3;21886:19;21914:76;21983:6;21976:4;21971:3;21967:14;21960:4;21953:5;21949:16;21914:76;:::i;:::-;22044:2;22023:15;-1:-1:-1;;22019:29:14;22010:39;;;;22051:4;22006:50;;21792:270;-1:-1:-1;;21792:270:14:o;22067:560::-;-1:-1:-1;;;;;22364:15:14;;;22346:34;;22416:15;;22411:2;22396:18;;22389:43;22463:2;22448:18;;22441:34;;;22506:2;22491:18;;22484:34;;;22326:3;22549;22534:19;;22527:32;;;22289:4;;22576:45;;22601:19;;22593:6;22576:45;:::i;23364:112::-;23396:1;23422;23412:35;;23427:18;;:::i;:::-;-1:-1:-1;23461:9:14;;23364:112::o;23481:245::-;23548:6;23601:2;23589:9;23580:7;23576:23;23572:32;23569:52;;;23617:1;23614;23607:12;23569:52;23649:9;23643:16;23668:28;23690:5;23668:28;:::i;24929:287::-;25058:3;25096:6;25090:13;25112:66;25171:6;25166:3;25159:4;25151:6;25147:17;25112:66;:::i;:::-;25194:16;;;;;24929:287;-1:-1:-1;;24929:287:14:o;25579:219::-;25728:2;25717:9;25710:21;25691:4;25748:44;25788:2;25777:9;25773:18;25765:6;25748:44;:::i
Swarm Source
ipfs://3e88b6f9221d47f719cd268428bdf751f24ce9ea82369bcdf35339b41cbb2422
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.