Contract Address Details

0x3730Bdc5DDF4286A8778dcB19dA638db1Da981Ad

DaoViewer Last Balance Update: Block #18545367
Created by 0x5befa2–df5471 at 0x57db10–a9594e

Balance

0 Fuse

Fetching tokens...

Contract name:
DaoViewer




Optimization enabled
true
Compiler version
v0.8.6+commit.11564f7e




Optimization runs
200
EVM Version
default




Verified at
2022-04-12 02:32:53.693249Z

Contract source code

// File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.5.0
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `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);
/**
* @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);
}
// File @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol@v4.5.0
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
/**
* @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);
}
// File contracts/interfaces/IFactory.sol
pragma solidity ^0.8.6;
interface IFactory {
function getDaos() external view returns (address[] memory);
function shop() external view returns (address);
function monthlyCost() external view returns (uint256);
function subscriptions(address _dao) external view returns (uint256);
function containsDao(address _dao) external view returns (bool);
}
// File contracts/interfaces/IDao.sol
pragma solidity ^0.8.6;
interface IDao {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function lp() external view returns (address);
function burnLp(
address _recipient,
uint256 _share,
address[] memory _tokens,
address[] memory _adapters,
address[] memory _pools
) external returns (bool);
function setLp(address _lp) external returns (bool);
function quorum() external view returns (uint8);
function executedTx(bytes32 _txHash) external view returns (bool);
function mintable() external view returns (bool);
function burnable() external view returns (bool);
function numberOfPermitted() external view returns (uint256);
function numberOfAdapters() external view returns (uint256);
function executePermitted(
address _target,
bytes calldata _data,
uint256 _value
) external returns (bool);
}
// File contracts/interfaces/ILP.sol
pragma solidity ^0.8.6;
interface ILP {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function mint(address _to, uint256 _amount) external returns (bool);
function mintable() external view returns (bool);
function burnable() external view returns (bool);
function mintableStatusFrozen() external view returns (bool);
function burnableStatusFrozen() external view returns (bool);
function burn(
uint256 _amount,
address[] memory _tokens,
address[] memory _adapters,
address[] memory _pools
) external returns (bool);
}
// File contracts/interfaces/IShop.sol
pragma solidity ^0.8.6;
interface IShop {
struct PublicOffer {
bool isActive;
address currency;
uint256 rate;
}
function publicOffers(address _dao)
external
view
returns (PublicOffer memory);
struct PrivateOffer {
bool isActive;
address recipient;
address currency;
uint256 currencyAmount;
uint256 lpAmount;
}
function privateOffers(address _dao, uint256 _index)
external
view
returns (PrivateOffer memory);
function numberOfPrivateOffers(address _dao)
external
view
returns (uint256);
function buyPrivateOffer(address _dao, uint256 _id) external returns (bool);
}
// File contracts/viewers/DaoViewer.sol
pragma solidity ^0.8.6;
contract DaoViewer {
struct DaoInfo {
address dao;
string daoName;
string daoSymbol;
address lp;
string lpName;
string lpSymbol;
}
function getDao(address _dao) public view returns (DaoInfo memory) {
address lp = IDao(_dao).lp();
if (lp == address(0)) {
return
DaoInfo({
dao: _dao,
daoName: IDao(_dao).name(),
daoSymbol: IDao(_dao).symbol(),
lp: address(0),
lpName: "",
lpSymbol: ""
});
}
return
DaoInfo({
dao: _dao,
daoName: IDao(_dao).name(),
daoSymbol: IDao(_dao).symbol(),
lp: lp,
lpName: ILP(lp).name(),
lpSymbol: ILP(lp).symbol()
});
}
function getDaos(address _factory) public view returns (DaoInfo[] memory) {
address[] memory _daosRaw = IFactory(_factory).getDaos();
DaoInfo[] memory _daos = new DaoInfo[](_daosRaw.length);
if (_daosRaw.length == 0) {
return new DaoInfo[](0);
} else {
for (uint256 i = 0; i < _daosRaw.length; i++) {
_daos[i] = getDao(_daosRaw[i]);
}
return _daos;
}
}
function userDaos(address _user, address _factory)
external
view
returns (DaoInfo[] memory)
{
DaoInfo[] memory _daos = getDaos(_factory);
if (_daos.length == 0) {
return new DaoInfo[](0);
} else {
DaoInfo[] memory _userDaos = new DaoInfo[](_daos.length);
for (uint256 i = 0; i < _daos.length; i++) {
if (IERC20Metadata(_daos[i].dao).balanceOf(_user) > 0) {
_userDaos[i] = _daos[i];
}
}
return _userDaos;
}
}
function getShare(address _dao, address[] memory _users)
external
view
returns (
uint256 share,
uint256 totalSupply,
uint8 quorum
)
{
quorum = IDao(_dao).quorum();
totalSupply = IERC20Metadata(_dao).totalSupply();
if (_users.length == 0) {
return (0, totalSupply, quorum);
}
share = 0;
for (uint256 i = 0; i < _users.length; i++) {
share += IERC20Metadata(_dao).balanceOf(_users[i]);
}
return (share, totalSupply, quorum);
}
function getShares(address _dao, address[][] memory _users)
external
view
returns (
uint256[] memory shares,
uint256 totalSupply,
uint8 quorum
)
{
quorum = IDao(_dao).quorum();
totalSupply = IERC20Metadata(_dao).totalSupply();
shares = new uint256[](_users.length);
for (uint256 i = 0; i < _users.length; i++) {
if (_users[i].length == 0) {
shares[i] = 0;
} else {
uint256 share = 0;
for (uint256 j = 0; j < _users[i].length; j++) {
share += IERC20Metadata(_dao).balanceOf(_users[i][j]);
}
shares[i] = share;
}
}
return (shares, totalSupply, quorum);
}
function balances(address[] memory users, address[] memory tokens)
external
view
returns (uint256[] memory)
{
uint256[] memory addrBalances = new uint256[](
tokens.length * users.length
);
for (uint256 i = 0; i < users.length; i++) {
for (uint256 j = 0; j < tokens.length; j++) {
uint256 addrIdx = j + tokens.length * i;
if (tokens[j] != address(0x0)) {
addrBalances[addrIdx] = IERC20Metadata(tokens[j]).balanceOf(
users[i]
);
} else {
addrBalances[addrIdx] = users[i].balance;
}
}
}
return addrBalances;
}
function getHashStatuses(address _dao, bytes32[] memory _txHashes)
external
view
returns (bool[] memory)
{
bool[] memory hashStatuses = new bool[](_txHashes.length);
for (uint256 i = 0; i < _txHashes.length; i++) {
hashStatuses[i] = IDao(_dao).executedTx(_txHashes[i]);
}
return hashStatuses;
}
struct DaoConfiguration {
bool gtMintable;
bool gtBurnable;
address lpAddress;
bool lpMintable;
bool lpBurnable;
bool lpMintableStatusFrozen;
bool lpBurnableStatusFrozen;
uint256 permittedLength;
uint256 adaptersLength;
uint256 monthlyCost;
uint256 numberOfPrivateOffers;
}
function getDaoConfiguration(address _factory, address _dao)
external
view
returns (DaoConfiguration memory)
{
address lp = IDao(_dao).lp();
if (lp == address(0)) {
return
DaoConfiguration({
gtMintable: IDao(_dao).mintable(),
gtBurnable: IDao(_dao).burnable(),
lpAddress: address(0),
lpMintable: false,
lpBurnable: false,
lpMintableStatusFrozen: false,
lpBurnableStatusFrozen: false,
permittedLength: IDao(_dao).numberOfPermitted(),
adaptersLength: IDao(_dao).numberOfAdapters(),
monthlyCost: IFactory(_factory).monthlyCost(),
numberOfPrivateOffers: 0
});
} else {
return
DaoConfiguration({
gtMintable: IDao(_dao).mintable(),
gtBurnable: IDao(_dao).burnable(),
lpAddress: lp,
lpMintable: ILP(lp).mintable(),
lpBurnable: ILP(lp).burnable(),
lpMintableStatusFrozen: ILP(lp).mintableStatusFrozen(),
lpBurnableStatusFrozen: ILP(lp).burnableStatusFrozen(),
permittedLength: IDao(_dao).numberOfPermitted(),
adaptersLength: IDao(_dao).numberOfAdapters(),
monthlyCost: IFactory(_factory).monthlyCost(),
numberOfPrivateOffers: IShop(IFactory(_factory).shop())
.numberOfPrivateOffers(_dao)
});
}
}
function getInvestInfo(address _factory)
external
view
returns (
DaoInfo[] memory,
IShop.PublicOffer[] memory,
string[] memory,
uint8[] memory,
uint256[] memory
)
{
DaoInfo[] memory daos = getDaos(_factory);
uint256 daosLength = daos.length;
if (daosLength == 0) {
return (
new DaoInfo[](0),
new IShop.PublicOffer[](0),
new string[](0),
new uint8[](0),
new uint256[](0)
);
}
IShop.PublicOffer[] memory publicOffers = new IShop.PublicOffer[](
daosLength
);
for (uint256 i = 0; i < daosLength; i++) {
publicOffers[i] = IShop(IFactory(_factory).shop()).publicOffers(
daos[i].dao
);
}
string[] memory symbols = new string[](daosLength);
uint8[] memory decimals = new uint8[](daosLength);
for (uint256 i = 0; i < daosLength; i++) {
if (publicOffers[i].currency != address(0)) {
try IERC20Metadata(publicOffers[i].currency).symbol() returns (
string memory s
) {
symbols[i] = s;
} catch {}
try
IERC20Metadata(publicOffers[i].currency).decimals()
returns (uint8 d) {
decimals[i] = d;
} catch {}
}
}
uint256[] memory numberOfPrivateOffers = new uint256[](daosLength);
for (uint256 i = 0; i < daosLength; i++) {
numberOfPrivateOffers[i] = IShop(IFactory(_factory).shop())
.numberOfPrivateOffers(daos[i].dao);
}
return (daos, publicOffers, symbols, decimals, numberOfPrivateOffers);
}
function getPrivateOffersInfo(address _factory)
external
view
returns (
DaoInfo[] memory,
uint256[] memory,
IShop.PrivateOffer[] memory,
string[] memory,
uint8[] memory
)
{
DaoInfo[] memory daos = getDaos(_factory);
uint256 daosLength = daos.length;
if (daosLength == 0) {
return (
new DaoInfo[](0),
new uint256[](0),
new IShop.PrivateOffer[](0),
new string[](0),
new uint8[](0)
);
}
uint256[] memory totalPrivateOffers = new uint256[](daosLength);
uint256 privateOffersLength = 0;
IShop shop = IShop(IFactory(_factory).shop());
for (uint256 i = 0; i < daosLength; i++) {
uint256 numberOfPrivateOffers = shop.numberOfPrivateOffers(
daos[i].dao
);
totalPrivateOffers[i] = numberOfPrivateOffers;
privateOffersLength += numberOfPrivateOffers;
}
IShop.PrivateOffer[] memory privateOffers = new IShop.PrivateOffer[](
privateOffersLength
);
string[] memory symbols = new string[](privateOffersLength);
uint8[] memory decimals = new uint8[](privateOffersLength);
uint256 indexCounter = 0;
for (uint256 i = 0; i < daosLength; i++) {
for (uint256 j = 0; j < totalPrivateOffers[i]; j++) {
IShop.PrivateOffer memory privateOffer = shop.privateOffers(
daos[i].dao,
j
);
privateOffers[indexCounter] = privateOffer;
try IERC20Metadata(privateOffer.currency).symbol() returns (
string memory s
) {
symbols[indexCounter] = s;
} catch {}
try IERC20Metadata(privateOffer.currency).decimals() returns (
uint8 d
) {
decimals[indexCounter] = d;
} catch {}
indexCounter++;
}
}
return (daos, totalPrivateOffers, privateOffers, symbols, decimals);
}
}

Contract ABI

[{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"balances","inputs":[{"type":"address[]","name":"users","internalType":"address[]"},{"type":"address[]","name":"tokens","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct DaoViewer.DaoInfo","components":[{"type":"address","name":"dao","internalType":"address"},{"type":"string","name":"daoName","internalType":"string"},{"type":"string","name":"daoSymbol","internalType":"string"},{"type":"address","name":"lp","internalType":"address"},{"type":"string","name":"lpName","internalType":"string"},{"type":"string","name":"lpSymbol","internalType":"string"}]}],"name":"getDao","inputs":[{"type":"address","name":"_dao","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct DaoViewer.DaoConfiguration","components":[{"type":"bool","name":"gtMintable","internalType":"bool"},{"type":"bool","name":"gtBurnable","internalType":"bool"},{"type":"address","name":"lpAddress","internalType":"address"},{"type":"bool","name":"lpMintable","internalType":"bool"},{"type":"bool","name":"lpBurnable","internalType":"bool"},{"type":"bool","name":"lpMintableStatusFrozen","internalType":"bool"},{"type":"bool","name":"lpBurnableStatusFrozen","internalType":"bool"},{"type":"uint256","name":"permittedLength","internalType":"uint256"},{"type":"uint256","name":"adaptersLength","internalType":"uint256"},{"type":"uint256","name":"monthlyCost","internalType":"uint256"},{"type":"uint256","name":"numberOfPrivateOffers","internalType":"uint256"}]}],"name":"getDaoConfiguration","inputs":[{"type":"address","name":"_factory","internalType":"address"},{"type":"address","name":"_dao","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct DaoViewer.DaoInfo[]","components":[{"type":"address","name":"dao","internalType":"address"},{"type":"string","name":"daoName","internalType":"string"},{"type":"string","name":"daoSymbol","internalType":"string"},{"type":"address","name":"lp","internalType":"address"},{"type":"string","name":"lpName","internalType":"string"},{"type":"string","name":"lpSymbol","internalType":"string"}]}],"name":"getDaos","inputs":[{"type":"address","name":"_factory","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool[]","name":"","internalType":"bool[]"}],"name":"getHashStatuses","inputs":[{"type":"address","name":"_dao","internalType":"address"},{"type":"bytes32[]","name":"_txHashes","internalType":"bytes32[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct DaoViewer.DaoInfo[]","components":[{"type":"address","name":"dao","internalType":"address"},{"type":"string","name":"daoName","internalType":"string"},{"type":"string","name":"daoSymbol","internalType":"string"},{"type":"address","name":"lp","internalType":"address"},{"type":"string","name":"lpName","internalType":"string"},{"type":"string","name":"lpSymbol","internalType":"string"}]},{"type":"tuple[]","name":"","internalType":"struct IShop.PublicOffer[]","components":[{"type":"bool","name":"isActive","internalType":"bool"},{"type":"address","name":"currency","internalType":"address"},{"type":"uint256","name":"rate","internalType":"uint256"}]},{"type":"string[]","name":"","internalType":"string[]"},{"type":"uint8[]","name":"","internalType":"uint8[]"},{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getInvestInfo","inputs":[{"type":"address","name":"_factory","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct DaoViewer.DaoInfo[]","components":[{"type":"address","name":"dao","internalType":"address"},{"type":"string","name":"daoName","internalType":"string"},{"type":"string","name":"daoSymbol","internalType":"string"},{"type":"address","name":"lp","internalType":"address"},{"type":"string","name":"lpName","internalType":"string"},{"type":"string","name":"lpSymbol","internalType":"string"}]},{"type":"uint256[]","name":"","internalType":"uint256[]"},{"type":"tuple[]","name":"","internalType":"struct IShop.PrivateOffer[]","components":[{"type":"bool","name":"isActive","internalType":"bool"},{"type":"address","name":"recipient","internalType":"address"},{"type":"address","name":"currency","internalType":"address"},{"type":"uint256","name":"currencyAmount","internalType":"uint256"},{"type":"uint256","name":"lpAmount","internalType":"uint256"}]},{"type":"string[]","name":"","internalType":"string[]"},{"type":"uint8[]","name":"","internalType":"uint8[]"}],"name":"getPrivateOffersInfo","inputs":[{"type":"address","name":"_factory","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"share","internalType":"uint256"},{"type":"uint256","name":"totalSupply","internalType":"uint256"},{"type":"uint8","name":"quorum","internalType":"uint8"}],"name":"getShare","inputs":[{"type":"address","name":"_dao","internalType":"address"},{"type":"address[]","name":"_users","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"shares","internalType":"uint256[]"},{"type":"uint256","name":"totalSupply","internalType":"uint256"},{"type":"uint8","name":"quorum","internalType":"uint8"}],"name":"getShares","inputs":[{"type":"address","name":"_dao","internalType":"address"},{"type":"address[][]","name":"_users","internalType":"address[][]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct DaoViewer.DaoInfo[]","components":[{"type":"address","name":"dao","internalType":"address"},{"type":"string","name":"daoName","internalType":"string"},{"type":"string","name":"daoSymbol","internalType":"string"},{"type":"address","name":"lp","internalType":"address"},{"type":"string","name":"lpName","internalType":"string"},{"type":"string","name":"lpSymbol","internalType":"string"}]}],"name":"userDaos","inputs":[{"type":"address","name":"_user","internalType":"address"},{"type":"address","name":"_factory","internalType":"address"}]}]
            

Deployed ByteCode

0x608060405234801561001057600080fd5b506004361061009e5760003560e01c8063a2c581ce11610066578063a2c581ce14610152578063bac26de814610172578063c6b0dbb214610196578063e02f3866146101ba578063f0002ea9146101da57600080fd5b80630b3841d0146100a357806318986db9146100ce57806354f76993146100ee57806380b8ed491461010e5780638b6b6ebf1461013f575b600080fd5b6100b66100b13660046127e6565b6101fa565b6040516100c593929190612fc8565b60405180910390f35b6100e16100dc36600461271d565b6104bc565b6040516100c59190612e2d565b6101016100fc36600461271d565b610638565b6040516100c591906130b0565b61012161011c366004612797565b610a14565b60408051938452602084019290925260ff16908201526060016100c5565b6100e161014d36600461275e565b610be4565b61016561016036600461275e565b610d94565b6040516100c59190612ff4565b61018561018036600461271d565b611653565b6040516100c5959493929190612ef5565b6101a96101a436600461271d565b611c98565b6040516100c5959493929190612e40565b6101cd6101c83660046128b1565b612321565b6040516100c59190612de7565b6101ed6101e83660046129fd565b612441565b6040516100c59190612fb5565b6060600080846001600160a01b0316631703a0186040518163ffffffff1660e01b815260040160206040518083038186803b15801561023857600080fd5b505afa15801561024c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102709190612c01565b9050846001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156102ab57600080fd5b505afa1580156102bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e39190612be8565b915083516001600160401b038111156102fe576102fe6131c4565b604051908082528060200260200182016040528015610327578160200160208202803683370190505b50925060005b84518110156104b357848181518110610348576103486131ae565b6020026020010151516000141561037e57600084828151811061036d5761036d6131ae565b6020026020010181815250506104a1565b6000805b868381518110610394576103946131ae565b60200260200101515181101561047f57876001600160a01b03166370a082318885815181106103c5576103c56131ae565b602002602001015183815181106103de576103de6131ae565b60200260200101516040518263ffffffff1660e01b815260040161041191906001600160a01b0391909116815260200190565b60206040518083038186803b15801561042957600080fd5b505afa15801561043d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104619190612be8565b61046b9083613116565b9150806104778161317d565b915050610382565b5080858381518110610493576104936131ae565b602002602001018181525050505b806104ab8161317d565b91505061032d565b505b9250925092565b60606000826001600160a01b031663a1d36ce76040518163ffffffff1660e01b815260040160006040518083038186803b1580156104f957600080fd5b505afa15801561050d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610535919081019061295d565b9050600081516001600160401b03811115610552576105526131c4565b60405190808252806020026020018201604052801561058b57816020015b610578612645565b8152602001906001900390816105705790505b5090508151600014156105d25760408051600080825260208201909252906105c9565b6105b6612645565b8152602001906001900390816105ae5790505b50949350505050565b60005b8251811015610630576106008382815181106105f3576105f36131ae565b6020026020010151610638565b828281518110610612576106126131ae565b602002602001018190525080806106289061317d565b9150506105d5565b509392505050565b610640612645565b6000826001600160a01b031663313c06a06040518163ffffffff1660e01b815260040160206040518083038186803b15801561067b57600080fd5b505afa15801561068f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b39190612741565b90506001600160a01b0381166107ff576040518060c00160405280846001600160a01b03168152602001846001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b15801561071657600080fd5b505afa15801561072a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107529190810190612a71565b8152602001846001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561079057600080fd5b505afa1580156107a4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107cc9190810190612a71565b81526000602080830182905260408051808301825283815281850152805191820190529081526060909101529392505050565b6040518060c00160405280846001600160a01b03168152602001846001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b15801561085257600080fd5b505afa158015610866573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261088e9190810190612a71565b8152602001846001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156108cc57600080fd5b505afa1580156108e0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109089190810190612a71565b8152602001826001600160a01b03168152602001826001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b15801561095557600080fd5b505afa158015610969573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109919190810190612a71565b8152602001826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156109cf57600080fd5b505afa1580156109e3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a0b9190810190612a71565b90529392505050565b6000806000846001600160a01b0316631703a0186040518163ffffffff1660e01b815260040160206040518083038186803b158015610a5257600080fd5b505afa158015610a66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8a9190612c01565b9050846001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ac557600080fd5b505afa158015610ad9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610afd9190612be8565b9150835160001415610b1257600092506104b5565b6000925060005b84518110156104b357856001600160a01b03166370a08231868381518110610b4357610b436131ae565b60200260200101516040518263ffffffff1660e01b8152600401610b7691906001600160a01b0391909116815260200190565b60206040518083038186803b158015610b8e57600080fd5b505afa158015610ba2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc69190612be8565b610bd09085613116565b935080610bdc8161317d565b915050610b19565b60606000610bf1836104bc565b9050805160001415610c37576040805160008082526020820190925290610c2e565b610c1b612645565b815260200190600190039081610c135790505b50915050610d8e565b600081516001600160401b03811115610c5257610c526131c4565b604051908082528060200260200182016040528015610c8b57816020015b610c78612645565b815260200190600190039081610c705790505b50905060005b8251811015610d84576000838281518110610cae57610cae6131ae565b6020908102919091010151516040516370a0823160e01b81526001600160a01b038981166004830152909116906370a082319060240160206040518083038186803b158015610cfc57600080fd5b505afa158015610d10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d349190612be8565b1115610d7257828181518110610d4c57610d4c6131ae565b6020026020010151828281518110610d6657610d666131ae565b60200260200101819052505b80610d7c8161317d565b915050610c91565b509150610d8e9050565b92915050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526000826001600160a01b031663313c06a06040518163ffffffff1660e01b815260040160206040518083038186803b158015610e2857600080fd5b505afa158015610e3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e609190612741565b90506001600160a01b03811661110f57604051806101600160405280846001600160a01b0316634bf365df6040518163ffffffff1660e01b815260040160206040518083038186803b158015610eb557600080fd5b505afa158015610ec9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eed9190612a56565b15158152602001846001600160a01b031663a07c7ce46040518163ffffffff1660e01b815260040160206040518083038186803b158015610f2d57600080fd5b505afa158015610f41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f659190612a56565b1515815260200160006001600160a01b03168152602001600015158152602001600015158152602001600015158152602001600015158152602001846001600160a01b03166356d6b2d06040518163ffffffff1660e01b815260040160206040518083038186803b158015610fd957600080fd5b505afa158015610fed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110119190612be8565b8152602001846001600160a01b0316634faa2e7b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561104f57600080fd5b505afa158015611063573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110879190612be8565b8152602001856001600160a01b0316636d61d1f56040518163ffffffff1660e01b815260040160206040518083038186803b1580156110c557600080fd5b505afa1580156110d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fd9190612be8565b81526020016000815250915050610d8e565b604051806101600160405280846001600160a01b0316634bf365df6040518163ffffffff1660e01b815260040160206040518083038186803b15801561115457600080fd5b505afa158015611168573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118c9190612a56565b15158152602001846001600160a01b031663a07c7ce46040518163ffffffff1660e01b815260040160206040518083038186803b1580156111cc57600080fd5b505afa1580156111e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112049190612a56565b15158152602001826001600160a01b03168152602001826001600160a01b0316634bf365df6040518163ffffffff1660e01b815260040160206040518083038186803b15801561125357600080fd5b505afa158015611267573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061128b9190612a56565b15158152602001826001600160a01b031663a07c7ce46040518163ffffffff1660e01b815260040160206040518083038186803b1580156112cb57600080fd5b505afa1580156112df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113039190612a56565b15158152602001826001600160a01b03166315ba0e656040518163ffffffff1660e01b815260040160206040518083038186803b15801561134357600080fd5b505afa158015611357573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137b9190612a56565b15158152602001826001600160a01b031663f7dab5176040518163ffffffff1660e01b815260040160206040518083038186803b1580156113bb57600080fd5b505afa1580156113cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f39190612a56565b15158152602001846001600160a01b03166356d6b2d06040518163ffffffff1660e01b815260040160206040518083038186803b15801561143357600080fd5b505afa158015611447573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146b9190612be8565b8152602001846001600160a01b0316634faa2e7b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156114a957600080fd5b505afa1580156114bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e19190612be8565b8152602001856001600160a01b0316636d61d1f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561151f57600080fd5b505afa158015611533573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115579190612be8565b8152602001856001600160a01b0316630881fa0d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561159557600080fd5b505afa1580156115a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115cd9190612741565b604051633c0f968d60e01b81526001600160a01b0387811660048301529190911690633c0f968d9060240160206040518083038186803b15801561161057600080fd5b505afa158015611624573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116489190612be8565b815250915050610d8e565b60608060608060606000611666876104bc565b8051909150806117565760408051600080825260208201909252906116a1565b61168e612645565b8152602001906001900390816116865790505b5060408051600080825260208201909252905b506040805160008082526020820190925290611706565b6040805160a0810182526000808252602080830182905292820181905260608201819052608082015282526000199092019101816116cb5790505b506040805160008082526020820190925290611732565b606081526020019060019003908161171d5790505b50604080516000808252602082019092529050965096509650965096505050611c8f565b6000816001600160401b03811115611770576117706131c4565b604051908082528060200260200182016040528015611799578160200160208202803683370190505b5090506000808a6001600160a01b0316630881fa0d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117d857600080fd5b505afa1580156117ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118109190612741565b905060005b84811015611903576000826001600160a01b0316633c0f968d888481518110611840576118406131ae565b6020908102919091010151516040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b15801561188b57600080fd5b505afa15801561189f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118c39190612be8565b9050808583815181106118d8576118d86131ae565b60209081029190910101526118ed8185613116565b93505080806118fb9061317d565b915050611815565b506000826001600160401b0381111561191e5761191e6131c4565b60405190808252806020026020018201604052801561197757816020015b6040805160a08101825260008082526020808301829052928201819052606082018190526080820152825260001990920191018161193c5790505b5090506000836001600160401b03811115611994576119946131c4565b6040519080825280602002602001820160405280156119c757816020015b60608152602001906001900390816119b25790505b5090506000846001600160401b038111156119e4576119e46131c4565b604051908082528060200260200182016040528015611a0d578160200160208202803683370190505b5090506000805b88811015611c7b5760005b888281518110611a3157611a316131ae565b6020026020010151811015611c68576000876001600160a01b031663b89234298d8581518110611a6357611a636131ae565b6020908102919091010151516040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024810185905260440160a06040518083038186803b158015611ab557600080fd5b505afa158015611ac9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aed9190612afb565b905080878581518110611b0257611b026131ae565b602002602001018190525080604001516001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611b4a57600080fd5b505afa925050508015611b7f57506040513d6000823e601f3d908101601f19168201604052611b7c9190810190612a71565b60015b611b8857611ba8565b80878681518110611b9b57611b9b6131ae565b6020026020010181905250505b80604001516001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611be557600080fd5b505afa925050508015611c15575060408051601f3d908101601f19168201909252611c1291810190612c01565b60015b611c1e57611c47565b80868681518110611c3157611c316131ae565b602002602001019060ff16908160ff1681525050505b83611c518161317d565b945050508080611c609061317d565b915050611a1f565b5080611c738161317d565b915050611a14565b50979c50949a509098509650919450505050505b91939590929450565b60608060608060606000611cab876104bc565b805190915080611d69576040805160008082526020820190925290611ce6565b611cd3612645565b815260200190600190039081611ccb5790505b5060408051600080825260208201909252906116b4565b6040805160608101825260008082526020808301829052928201528252600019909201910181611cfd5750506040805160008082526020820190925290611706565b6060815260200190600190039081611d3f5750506040805160008082526020820190925290611732565b6000816001600160401b03811115611d8357611d836131c4565b604051908082528060200260200182016040528015611dce57816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181611da15790505b50905060005b82811015611f2057896001600160a01b0316630881fa0d6040518163ffffffff1660e01b815260040160206040518083038186803b158015611e1557600080fd5b505afa158015611e29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4d9190612741565b6001600160a01b031663d249a978858381518110611e6d57611e6d6131ae565b6020908102919091010151516040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160606040518083038186803b158015611eb857600080fd5b505afa158015611ecc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef09190612b80565b828281518110611f0257611f026131ae565b60200260200101819052508080611f189061317d565b915050611dd4565b506000826001600160401b03811115611f3b57611f3b6131c4565b604051908082528060200260200182016040528015611f6e57816020015b6060815260200190600190039081611f595790505b5090506000836001600160401b03811115611f8b57611f8b6131c4565b604051908082528060200260200182016040528015611fb4578160200160208202803683370190505b50905060005b848110156121775760006001600160a01b0316848281518110611fdf57611fdf6131ae565b6020026020010151602001516001600160a01b0316146121655783818151811061200b5761200b6131ae565b6020026020010151602001516001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561204f57600080fd5b505afa92505050801561208457506040513d6000823e601f3d908101601f191682016040526120819190810190612a71565b60015b61208d576120ad565b808483815181106120a0576120a06131ae565b6020026020010181905250505b8381815181106120bf576120bf6131ae565b6020026020010151602001516001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561210357600080fd5b505afa925050508015612133575060408051601f3d908101601f1916820190925261213091810190612c01565b60015b61213c57612165565b8083838151811061214f5761214f6131ae565b602002602001019060ff16908160ff1681525050505b8061216f8161317d565b915050611fba565b506000846001600160401b03811115612192576121926131c4565b6040519080825280602002602001820160405280156121bb578160200160208202803683370190505b50905060005b8581101561230c578c6001600160a01b0316630881fa0d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561220257600080fd5b505afa158015612216573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223a9190612741565b6001600160a01b0316633c0f968d88838151811061225a5761225a6131ae565b6020908102919091010151516040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b1580156122a557600080fd5b505afa1580156122b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122dd9190612be8565b8282815181106122ef576122ef6131ae565b6020908102919091010152806123048161317d565b9150506121c1565b50949b929a5090985096509194509092505050565b6060600082516001600160401b0381111561233e5761233e6131c4565b604051908082528060200260200182016040528015612367578160200160208202803683370190505b50905060005b835181101561063057846001600160a01b031663cdb2c042858381518110612397576123976131ae565b60200260200101516040518263ffffffff1660e01b81526004016123bd91815260200190565b60206040518083038186803b1580156123d557600080fd5b505afa1580156123e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240d9190612a56565b82828151811061241f5761241f6131ae565b91151560209283029190910190910152806124398161317d565b91505061236d565b6060600083518351612453919061312e565b6001600160401b0381111561246a5761246a6131c4565b604051908082528060200260200182016040528015612493578160200160208202803683370190505b50905060005b84518110156106305760005b84518110156126325760008286516124bd919061312e565b6124c79083613116565b905060006001600160a01b03168683815181106124e6576124e66131ae565b60200260200101516001600160a01b0316146125dc5785828151811061250e5761250e6131ae565b60200260200101516001600160a01b03166370a08231888581518110612536576125366131ae565b60200260200101516040518263ffffffff1660e01b815260040161256991906001600160a01b0391909116815260200190565b60206040518083038186803b15801561258157600080fd5b505afa158015612595573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b99190612be8565b8482815181106125cb576125cb6131ae565b60200260200101818152505061261f565b8683815181106125ee576125ee6131ae565b60200260200101516001600160a01b031631848281518110612612576126126131ae565b6020026020010181815250505b508061262a8161317d565b9150506124a5565b508061263d8161317d565b915050612499565b6040518060c0016040528060006001600160a01b03168152602001606081526020016060815260200160006001600160a01b0316815260200160608152602001606081525090565b600082601f83011261269e57600080fd5b813560206126b36126ae836130f3565b6130c3565b80838252828201915082860187848660051b89010111156126d357600080fd5b60005b858110156126fb5781356126e9816131da565b845292840192908401906001016126d6565b5090979650505050505050565b8051801515811461271857600080fd5b919050565b60006020828403121561272f57600080fd5b813561273a816131da565b9392505050565b60006020828403121561275357600080fd5b815161273a816131da565b6000806040838503121561277157600080fd5b823561277c816131da565b9150602083013561278c816131da565b809150509250929050565b600080604083850312156127aa57600080fd5b82356127b5816131da565b915060208301356001600160401b038111156127d057600080fd5b6127dc8582860161268d565b9150509250929050565b600080604083850312156127f957600080fd5b8235612804816131da565b91506020838101356001600160401b038082111561282157600080fd5b818601915086601f83011261283557600080fd5b81356128436126ae826130f3565b8082825285820191508585018a878560051b880101111561286357600080fd5b6000805b8581101561289e5782358781111561287d578283fd5b61288b8e8b838c010161268d565b8652509388019391880191600101612867565b5050508096505050505050509250929050565b600080604083850312156128c457600080fd5b82356128cf816131da565b91506020838101356001600160401b038111156128eb57600080fd5b8401601f810186136128fc57600080fd5b803561290a6126ae826130f3565b80828252848201915084840189868560051b870101111561292a57600080fd5b600094505b8385101561294d57803583526001949094019391850191850161292f565b5080955050505050509250929050565b6000602080838503121561297057600080fd5b82516001600160401b0381111561298657600080fd5b8301601f8101851361299757600080fd5b80516129a56126ae826130f3565b80828252848201915084840188868560051b87010111156129c557600080fd5b600094505b838510156129f15780516129dd816131da565b8352600194909401939185019185016129ca565b50979650505050505050565b60008060408385031215612a1057600080fd5b82356001600160401b0380821115612a2757600080fd5b612a338683870161268d565b93506020850135915080821115612a4957600080fd5b506127dc8582860161268d565b600060208284031215612a6857600080fd5b61273a82612708565b600060208284031215612a8357600080fd5b81516001600160401b0380821115612a9a57600080fd5b818401915084601f830112612aae57600080fd5b815181811115612ac057612ac06131c4565b612ad3601f8201601f19166020016130c3565b9150808252856020828501011115612aea57600080fd5b6105c981602084016020860161314d565b600060a08284031215612b0d57600080fd5b60405160a081018181106001600160401b0382111715612b2f57612b2f6131c4565b604052612b3b83612708565b81526020830151612b4b816131da565b60208201526040830151612b5e816131da565b6040820152606083810151908201526080928301519281019290925250919050565b600060608284031215612b9257600080fd5b604051606081018181106001600160401b0382111715612bb457612bb46131c4565b604052612bc083612708565b81526020830151612bd0816131da565b60208201526040928301519281019290925250919050565b600060208284031215612bfa57600080fd5b5051919050565b600060208284031215612c1357600080fd5b815160ff8116811461273a57600080fd5b600081518084526020808501808196508360051b8101915082860160005b85811015612c6c578284038952612c5a848351612d2f565b98850198935090840190600101612c42565b5091979650505050505050565b600081518084526020808501808196508360051b8101915082860160005b85811015612c6c578284038952612caf848351612d5b565b98850198935090840190600101612c97565b600081518084526020808501945080840160005b83811015612cf157815187529582019590820190600101612cd5565b509495945050505050565b600081518084526020808501945080840160005b83811015612cf157815160ff1687529582019590820190600101612d10565b60008151808452612d4781602086016020860161314d565b601f01601f19169290920160200192915050565b600060018060a01b03808351168452602083015160c06020860152612d8360c0860182612d2f565b905060408401518582036040870152612d9c8282612d2f565b915050816060850151166060860152608084015191508481036080860152612dc48183612d2f565b91505060a083015184820360a0860152612dde8282612d2f565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e21578351151583529284019291840191600101612e03565b50909695505050505050565b60208152600061273a6020830184612c79565b60a081526000612e5360a0830188612c79565b82810360208481019190915287518083528882019282019060005b81811015612eab578451805115158452848101516001600160a01b0316858501526040908101519084015293830193606090920191600101612e6e565b50508481036040860152612ebf8189612c24565b925050508281036060840152612ed58186612cfc565b90508281036080840152612ee98185612cc1565b98975050505050505050565b600060a0808352612f0881840189612c79565b602084820381860152612f1b828a612cc1565b91506040858303818701528289518085528385019150838b01945060005b81811015612f89578551805115158452858101516001600160a01b039081168786015285820151168585015260608082015190850152608090810151908401529484019491860191600101612f39565b50508681036060880152612f9d818a612c24565b9450505050508281036080840152612ee98185612cfc565b60208152600061273a6020830184612cc1565b606081526000612fdb6060830186612cc1565b905083602083015260ff83166040830152949350505050565b81511515815261016081016020830151613012602084018215159052565b50604083015161302d60408401826001600160a01b03169052565b506060830151613041606084018215159052565b506080830151613055608084018215159052565b5060a083015161306960a084018215159052565b5060c083015161307d60c084018215159052565b5060e083810151908301526101008084015190830152610120808401519083015261014092830151929091019190915290565b60208152600061273a6020830184612d5b565b604051601f8201601f191681016001600160401b03811182821017156130eb576130eb6131c4565b604052919050565b60006001600160401b0382111561310c5761310c6131c4565b5060051b60200190565b6000821982111561312957613129613198565b500190565b600081600019048311821515161561314857613148613198565b500290565b60005b83811015613168578181015183820152602001613150565b83811115613177576000848401525b50505050565b600060001982141561319157613191613198565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146131ef57600080fd5b5056fea264697066735822122008bf68d84b696e1a539e45b1de15de04cad9de11fae71663291edc80d3c4154a64736f6c63430008060033