Source Code
Overview
POL Balance
POL Value
$0.00Cross-Chain Transactions
Loading...
Loading
Contract Name:
PoolLogic
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 20 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2021 dHEDGE DAO
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;
import {IERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol";
import {SafeMathUpgradeable} from "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";
import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import {IERC721ReceiverUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol";
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import {IFlashLoanReceiver} from "./interfaces/aave/IFlashLoanReceiver.sol";
import {IAaveLendingPoolAssetGuard} from "./interfaces/guards/IAaveLendingPoolAssetGuard.sol";
import {IAssetGuard} from "./interfaces/guards/IAssetGuard.sol";
import {IERC721VerifyingGuard} from "./interfaces/guards/IERC721VerifyingGuard.sol";
import {IGuard} from "./interfaces/guards/IGuard.sol";
import {ITxTrackingGuard} from "./interfaces/guards/ITxTrackingGuard.sol";
import {IGovernance} from "./interfaces/IGovernance.sol";
import {IHasDaoInfo} from "./interfaces/IHasDaoInfo.sol";
import {IHasFeeInfo} from "./interfaces/IHasFeeInfo.sol";
import {IHasGuardInfo} from "./interfaces/IHasGuardInfo.sol";
import {IHasOwnable} from "./interfaces/IHasOwnable.sol";
import {IHasPausable} from "./interfaces/IHasPausable.sol";
import {IHasSupportedAsset} from "./interfaces/IHasSupportedAsset.sol";
import {IManaged} from "./interfaces/IManaged.sol";
import {IPoolFactory} from "./interfaces/IPoolFactory.sol";
import {IPoolManagerLogic} from "./interfaces/IPoolManagerLogic.sol";
import {AddressHelper} from "./utils/AddressHelper.sol";
/// @notice Logic implementation for pool
contract PoolLogic is ERC20Upgradeable, ReentrancyGuardUpgradeable, IERC721ReceiverUpgradeable, IFlashLoanReceiver {
using SafeMathUpgradeable for uint256;
using AddressHelper for address;
struct FundSummary {
string name;
uint256 totalSupply;
uint256 totalFundValue;
address manager;
string managerName;
uint256 creationTime;
bool privatePool;
uint256 performanceFeeNumerator;
uint256 managerFeeNumerator;
uint256 managerFeeDenominator;
uint256 exitFeeNumerator;
uint256 exitFeeDenominator;
uint256 entryFeeNumerator;
}
struct TxToExecute {
address to;
bytes data;
}
struct WithdrawnAsset {
address asset;
uint256 amount;
bool externalWithdrawProcessed;
}
struct WithdrawProcessing {
uint256 portionBalance;
uint256 expectedWithdrawValue;
}
event Deposit(
address fundAddress,
address investor,
address assetDeposited,
uint256 amountDeposited,
uint256 valueDeposited,
uint256 fundTokensReceived,
uint256 totalInvestorFundTokens,
uint256 fundValue,
uint256 totalSupply,
uint256 time
);
event Withdrawal(
address fundAddress,
address investor,
uint256 valueWithdrawn,
uint256 fundTokensWithdrawn,
uint256 totalInvestorFundTokens,
uint256 fundValue,
uint256 totalSupply,
WithdrawnAsset[] withdrawnAssets,
uint256 time
);
event TransactionExecuted(address pool, address manager, uint16 transactionType, uint256 time);
event PoolPrivacyUpdated(bool isPoolPrivate);
event ManagerFeeMinted(
address pool,
address manager,
uint256 available,
uint256 daoFee,
uint256 managerFee,
uint256 tokenPriceAtLastFeeMint
);
event PoolManagerLogicSet(address poolManagerLogic, address from);
bool public privatePool;
address public creator;
uint256 public creationTime;
address public factory;
uint256 public tokenPriceAtLastFeeMint;
mapping(address => uint256) public lastDeposit;
address public poolManagerLogic;
mapping(address => uint256) public lastWhitelistTransfer;
uint256 public lastFeeMintTime;
mapping(address => uint256) public lastExitCooldown;
modifier whenNotFactoryPaused() {
require(!IHasPausable(factory).isPaused(), "contracts paused");
_;
}
modifier whenNotPaused() {
require(!IHasPausable(factory).pausedPools(address(this)), "pool paused");
_;
}
/// @notice Initialize the pool
/// @param _factory address of the factory
/// @param _privatePool true if the pool is private, false otherwise
/// @param _fundName name of the fund
/// @param _fundSymbol symbol of the fund
function initialize(
address _factory,
bool _privatePool,
string memory _fundName,
string memory _fundSymbol
) external initializer {
__ERC20_init(_fundName, _fundSymbol);
__ReentrancyGuard_init();
factory = _factory;
privatePool = _privatePool;
creator = msg.sender;
creationTime = block.timestamp;
lastFeeMintTime = block.timestamp;
tokenPriceAtLastFeeMint = 10 ** 18;
}
/// @notice Before token transfer hook
/// @param from address of the token owner
/// @param to address of the token receiver
/// @param amount amount of tokens to transfer
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {
super._beforeTokenTransfer(from, to, amount);
// Minting
if (from == address(0)) {
return;
}
// If the pool is private, either the recipient has to be a pool member or the transaction should be burning the fund tokens.
// The latter is required in case a user deposited into the pool when the pool was public and then the pool was made private
// in which case the user should be able to withdraw their funds.
require(!privatePool || _isMemberAllowed(to) || to == address(0), "only members");
if (IPoolFactory(factory).receiverWhitelist(to) == true) {
return;
}
require(getExitRemainingCooldown(from) == 0, "cooldown active");
}
/// @notice Set the pool privacy
/// @param _privatePool true if the pool is private, false otherwise
function setPoolPrivate(bool _privatePool) external {
require(msg.sender == _manager(), "only manager");
privatePool = _privatePool;
emit PoolPrivacyUpdated(_privatePool);
_emitFactoryEvent();
}
/// @notice Deposit funds into the pool
/// @param _asset Address of the token
/// @param _amount Amount of tokens to deposit
/// @return liquidityMinted Amount of liquidity minted
function deposit(address _asset, uint256 _amount) external returns (uint256 liquidityMinted) {
return _depositFor(msg.sender, _asset, _amount, _exitCooldown());
}
function depositFor(address _recipient, address _asset, uint256 _amount) external returns (uint256 liquidityMinted) {
return _depositFor(_recipient, _asset, _amount, _exitCooldown());
}
function depositForWithCustomCooldown(
address _recipient,
address _asset,
uint256 _amount,
uint256 _cooldown
) external returns (uint256 liquidityMinted) {
require(IPoolFactory(factory).customCooldownWhitelist(msg.sender), "only allowed");
require(_cooldown >= 5 minutes && _cooldown <= _exitCooldown(), "invalid cooldown");
return _depositFor(_recipient, _asset, _amount, _cooldown);
}
function _depositFor(
address _recipient,
address _asset,
uint256 _amount,
uint256 _cooldown
) private nonReentrant whenNotFactoryPaused whenNotPaused returns (uint256 liquidityMinted) {
require(_recipient == _manager() || !privatePool || _isMemberAllowed(_recipient), "only members");
require(IPoolManagerLogic(poolManagerLogic).isDepositAsset(_asset), "invalid deposit asset");
// Checks that the `_asset` is not a ERC721 token.
// As per ERC721 spec, a compliant contract must implement the ERC165 interface.
// The interface id for IERC721 is 0x80ac58cd as per <https://ethtools.com/interface-database/ERC721>
// Also, the `supportsInterface` function should only consume at most 30_000 gas as per ERC165 standard.
{
// If the asset supports IERC165, then it should not support IERC721.
(bool success, bytes memory data) = _asset.staticcall{gas: 30_000}(
abi.encodeWithSelector(IERC165Upgradeable.supportsInterface.selector, bytes4(0x80ac58cd))
);
// Either the call to `supportsInterface` should revert or the IERC721 interface should not be supported.
require(!success || !abi.decode(data, (bool)), "NFTs not supported");
}
uint256 fundValue = _mintManagerFee();
uint256 totalSupplyBefore = totalSupply();
_asset.tryAssemblyCall(
abi.encodeWithSelector(IERC20Upgradeable.transferFrom.selector, msg.sender, address(this), _amount)
);
uint256 usdAmount = _assetValue(_asset, _amount);
// Scoping to avoid stack too deep errors.
{
if (totalSupplyBefore > 0) {
liquidityMinted = usdAmount.mul(totalSupplyBefore).div(fundValue);
} else {
liquidityMinted = usdAmount;
}
(, , uint256 entryFeeNumerator, , uint256 denominator) = _managerFees();
if (entryFeeNumerator > 0) {
uint256 entryFee = liquidityMinted.mul(entryFeeNumerator).div(denominator);
// Note: From here on, `liquidityMinted` will refer to the fund tokens minted with entry fee accounted for.
liquidityMinted = liquidityMinted.sub(entryFee);
_mint(_manager(), entryFee);
}
// Note: We are making it impossible for someone to mint liquidity < 100_000.
// This is so that we can mitigate the inflation attack.
require(liquidityMinted >= 100_000, "invalid liquidityMinted");
// As the `_mint` function doesn't hand over the execution control to the caller, we can safely
// call it before calculating cooldown and other effects.
_mint(_recipient, liquidityMinted);
}
lastExitCooldown[_recipient] = _calculateCooldown(
balanceOf(_recipient),
liquidityMinted,
_cooldown,
lastExitCooldown[_recipient],
lastDeposit[_recipient],
block.timestamp
);
lastDeposit[_recipient] = block.timestamp;
uint256 balance = balanceOf(_recipient);
uint256 fundValueAfter = fundValue.add(usdAmount);
{
uint256 totalSupplyAfter = totalSupply();
require(
balance.mul(_tokenPrice(fundValueAfter, totalSupplyAfter)).div(10 ** 18) >=
IPoolManagerLogic(poolManagerLogic).minDepositUSD(),
"need min deposit"
);
emit Deposit(
address(this),
_recipient,
_asset,
_amount,
usdAmount,
liquidityMinted,
balance,
fundValueAfter,
totalSupplyAfter,
block.timestamp
);
}
_emitFactoryEvent();
}
/// @notice Not recommended to use. Use `withdrawSafe` instead
/// @dev Kept for backward compatibility
function withdraw(uint256 _fundTokenAmount) external {
_withdrawTo(msg.sender, _fundTokenAmount, 10_000);
}
/// @notice Not recommended to use. Use `withdrawSafe` instead
/// @dev Kept for backward compatibility
function withdrawTo(address _recipient, uint256 _fundTokenAmount) external {
_withdrawTo(_recipient, _fundTokenAmount, 10_000);
}
/// @notice Most recent function to be used for withdrawing assets from the vault
/// @dev This is for vaults that can have slippage on withdrawal, eg. portfolio has Aave positions with debt
function withdrawSafe(uint256 _fundTokenAmount, uint256 _slippageTolerance) external {
_withdrawTo(msg.sender, _fundTokenAmount, _slippageTolerance);
}
/// @notice Most recent function to be used for withdrawing assets from the vault to a specific address
/// @dev This is for vaults that can have slippage on withdrawal, eg. portfolio has Aave positions with debt
function withdrawToSafe(address _recipient, uint256 _fundTokenAmount, uint256 _slippageTolerance) external {
_withdrawTo(_recipient, _fundTokenAmount, _slippageTolerance);
}
/// @notice Withdraw assets based on the fund token amount
/// @param _recipient The address to withdraw to
/// @param _fundTokenAmount Amount of fund tokens to withdraw
/// @param _slippageTolerance Slippage tolerance, 10_000 = 100%, 100 = 1%, 10 = 0.1%, 1 = 0.01%
function _withdrawTo(
address _recipient,
uint256 _fundTokenAmount,
uint256 _slippageTolerance
) internal nonReentrant whenNotFactoryPaused whenNotPaused {
require(lastDeposit[msg.sender] < block.timestamp, "can withdraw soon");
require(balanceOf(msg.sender) >= _fundTokenAmount, "not enough balance");
require(_slippageTolerance <= 10_000, "invalid tolerance");
// Scoping to avoid "stack-too-deep" errors.
{
// Calculating how much pool token supply will be left after withdrawal and
// whether or not this satisfies the min supply (100_000) check.
// If the user is redeeming all the shares then this check passes.
// Otherwise, they might have to reduce the amount to be withdrawn.
uint256 supplyAfter = totalSupply().sub(_fundTokenAmount);
require(supplyAfter >= 100_000 || supplyAfter == 0, "below supply threshold");
}
// calculate the manager fee
uint256 fundValue = _mintManagerFee();
{
// Scope to avoid stack too deep error
(, , , uint256 exitFeeNumerator, uint256 denominator) = _managerFees();
if (exitFeeNumerator > 0) {
uint256 exitFee = _fundTokenAmount.mul(exitFeeNumerator).div(denominator);
_fundTokenAmount = _fundTokenAmount.sub(exitFee);
require(transfer(_manager(), exitFee), "exit fee transfer failed");
}
}
// calculate the proportion
uint256 portion = _fundTokenAmount.mul(10 ** 18).div(totalSupply());
// first return funded tokens
_burn(msg.sender, _fundTokenAmount);
if (totalSupply() == 0) {
tokenPriceAtLastFeeMint = 1e18;
}
// TODO: Combining into one line to fix stack too deep,
// need to refactor some variables into struct in order to have more variables
IHasSupportedAsset.Asset[] memory _supportedAssets = IHasSupportedAsset(poolManagerLogic).getSupportedAssets();
WithdrawnAsset[] memory withdrawnAssets = new WithdrawnAsset[](_supportedAssets.length);
uint256 index = 0;
for (uint256 i = 0; i < _supportedAssets.length; i++) {
(address asset, uint256 portionOfAssetBalance, bool externalWithdrawProcessed) = _withdrawProcessing(
_supportedAssets[i].asset,
_recipient,
portion,
_slippageTolerance
);
if (portionOfAssetBalance > 0) {
require(asset != address(0), "need withdraw asset");
// Ignoring return value for transfer as want to transfer no matter what happened
asset.tryAssemblyCall(
abi.encodeWithSelector(IERC20Upgradeable.transfer.selector, _recipient, portionOfAssetBalance)
);
}
if (externalWithdrawProcessed || portionOfAssetBalance > 0) {
withdrawnAssets[index] = WithdrawnAsset({
asset: asset,
amount: portionOfAssetBalance,
externalWithdrawProcessed: externalWithdrawProcessed
});
index++;
}
}
// Reduce length for withdrawnAssets to remove the empty items
uint256 reduceLength = _supportedAssets.length.sub(index);
assembly {
mstore(withdrawnAssets, sub(mload(withdrawnAssets), reduceLength))
}
uint256 valueWithdrawn = portion.mul(fundValue).div(10 ** 18);
emit Withdrawal(
address(this),
msg.sender,
valueWithdrawn,
_fundTokenAmount,
balanceOf(msg.sender),
fundValue.sub(valueWithdrawn),
totalSupply(),
withdrawnAssets,
block.timestamp
);
_emitFactoryEvent();
}
/// @notice Perform any additional processing on withdrawal of asset
/// @dev Checks for staked tokens and withdraws them to the investor account
/// @param asset Asset for withdrawal processing
/// @param to Investor account to send withdrawed tokens to
/// @param portion Portion of investor withdrawal of the total dHedge pool
/// @param slippageTolerance Slippage tolerance for withdrawal
/// @return withdrawAsset Asset to be withdrawed
/// @return withdrawBalance Asset balance amount to be withdrawed
/// @return externalWithdrawProcessed A boolean for success or fail transaction
function _withdrawProcessing(
address asset,
address to,
uint256 portion,
uint256 slippageTolerance
)
internal
returns (
address, // withdrawAsset
uint256, // withdrawBalance
bool externalWithdrawProcessed
)
{
// Withdraw any external tokens (eg. staked tokens in other contracts)
address guard = IHasGuardInfo(factory).getAssetGuard(asset);
require(guard != address(0), "invalid guard");
WithdrawProcessing memory params;
params.portionBalance = IAssetGuard(guard).getBalance(address(this), asset).mul(portion).div(10 ** 18);
// Value of the portion of the asset to be withdrawn
params.expectedWithdrawValue = _assetValue(asset, params.portionBalance);
(address withdrawAsset, uint256 withdrawBalance, IAssetGuard.MultiTransaction[] memory transactions) = IAssetGuard(
guard
).withdrawProcessing(address(this), asset, portion, to);
uint256 txCount = transactions.length;
if (txCount > 0) {
uint256 assetBalanceBefore;
if (withdrawAsset != address(0)) {
assetBalanceBefore = IERC20Upgradeable(withdrawAsset).balanceOf(address(this));
}
// In case of withdraw from aave position with debt, this loop is where flash loan starts and finishes its execution
for (uint256 i = 0; i < txCount; i++) {
externalWithdrawProcessed = transactions[i].to.tryAssemblyCall(transactions[i].txData);
}
// In case of withdraw from aave position with debt, remaining withdrawAsset gets added here
if (withdrawAsset != address(0)) {
// get any balance increase after withdraw processing and add it to the withdraw balance
uint256 assetBalanceAfter = IERC20Upgradeable(withdrawAsset).balanceOf(address(this));
withdrawBalance = withdrawBalance.add(assetBalanceAfter.sub(assetBalanceBefore));
}
}
// solhint-disable-next-line avoid-low-level-calls
(bool hasFunction, bytes memory answer) = guard.call(abi.encodeWithSignature("isSlippageCheckingGuard()"));
// check slippage after asset's withdraw processing if required in its guard (eg. Aave)
if (hasFunction && abi.decode(answer, (bool)) && withdrawAsset != address(0)) {
// Ensure that actual value of tokens transferred is not less than the expected value, corrected by allowed tolerance
require(
_assetValue(withdrawAsset, withdrawBalance) >=
params.expectedWithdrawValue.mul(10_000 - slippageTolerance).div(10_000),
"high withdraw slippage"
);
}
return (withdrawAsset, withdrawBalance, externalWithdrawProcessed);
}
/// @notice Private function to let pool talk to other protocol
/// @dev execute transaction for the pool
/// @param to The destination address for pool to talk to
/// @param data The data that going to send in the transaction
/// @return success A boolean for success or fail transaction
function _execTransaction(
address to,
bytes memory data
) private nonReentrant whenNotFactoryPaused returns (bool success) {
require(to != address(0), "invalid address");
address contractGuard = IHasGuardInfo(factory).getContractGuard(to);
address assetGuard;
address guard;
uint16 txType;
bool isPublic;
if (contractGuard != address(0)) {
guard = contractGuard;
(txType, isPublic) = IGuard(contractGuard).txGuard(poolManagerLogic, to, data);
}
// invalid contract guard call, try asset guard
if (txType == 0) {
// no contract guard configured, get asset guard
assetGuard = IHasGuardInfo(factory).getAssetGuard(to);
if (assetGuard == address(0)) {
// If there is no contractGuard and no assetGuard then use the ERC20Guard for the transaction,
// which will only allow a valid approve transaction
address governanceAddress = IPoolFactory(factory).governanceAddress();
assetGuard = IGovernance(governanceAddress).assetGuards(0); // get ERC20Guard (assetType 0)
} else {
// if asset is configured, ensure that it's enabled in the pool
require(IHasSupportedAsset(poolManagerLogic).isSupportedAsset(to), "asset disabled");
}
guard = assetGuard;
(txType, isPublic) = IGuard(assetGuard).txGuard(poolManagerLogic, to, data);
}
require(txType > 0, "invalid transaction");
require(isPublic || msg.sender == _manager() || msg.sender == _trader(), "only manager, trader, public");
success = to.tryAssemblyCall(data);
// call afterTxGuard to track transactions
// to make it compatible with previous version, we use low-level call before calling afterTxGuard() function
// the low level call will return `false` if its execution reverts
// solhint-disable-next-line avoid-low-level-calls
(bool hasFunction, bytes memory returnData) = guard.call(abi.encodeWithSignature("isTxTrackingGuard()"));
if (hasFunction && abi.decode(returnData, (bool))) {
ITxTrackingGuard(guard).afterTxGuard(poolManagerLogic, to, data);
}
emit TransactionExecuted(address(this), _manager(), txType, block.timestamp);
_emitFactoryEvent();
}
/// @notice Exposed function to let pool talk to other protocol
/// @dev Execute single transaction for the pool
/// @param to The destination address for pool to talk to
/// @param data The data that going to send in the transaction
/// @return success A boolean for success or fail transaction
function execTransaction(address to, bytes calldata data) external returns (bool success) {
return _execTransaction(to, data);
}
/// @notice Exposed function to let pool talk to other protocol
/// @dev Execute multiple transactions for the pool
/// @param txs Array of structs, each consisting of address and data
function execTransactions(TxToExecute[] calldata txs) external {
for (uint256 i = 0; i < txs.length; i++) {
require(_execTransaction(txs[i].to, txs[i].data), "tx failed");
}
}
/// @notice Get fund summary of the pool
/// @return Fund summary of the pool
function getFundSummary() external view returns (FundSummary memory) {
(
uint256 performanceFeeNumerator,
uint256 managementFeeNumerator,
uint256 entryFeeNumerator,
uint256 exitFeeNumerator,
uint256 denominator
) = _managerFees();
return
FundSummary(
name(),
totalSupply(),
_totalValue(),
_manager(),
IManaged(poolManagerLogic).managerName(),
creationTime,
privatePool,
performanceFeeNumerator,
managementFeeNumerator,
denominator,
exitFeeNumerator,
denominator,
entryFeeNumerator
);
}
/// @notice Get price of the asset adjusted for any unminted manager fees
/// @param price A price of the asset
function tokenPrice() external view returns (uint256 price) {
uint256 fundValue = _totalValue();
uint256 tokenSupply = totalSupply().add(calculateAvailableManagerFee(fundValue));
price = _tokenPrice(fundValue, tokenSupply);
}
function tokenPriceWithoutManagerFee() external view returns (uint256 price) {
price = _tokenPrice(_totalValue(), totalSupply());
}
/// @notice Get price of the asset internal call
/// @param _fundValue The total fund value of the pool
/// @param _tokenSupply The total token supply of the pool
/// @return price A price of the asset
function _tokenPrice(uint256 _fundValue, uint256 _tokenSupply) internal pure returns (uint256 price) {
if (_tokenSupply == 0 || _fundValue == 0) return 0;
price = _fundValue.mul(10 ** 18).div(_tokenSupply);
}
/// @notice Get available manager fee of the pool
/// @dev Can be used on the frontend by passing in fund value
/// @param fundValue The total fund value of the pool
/// @return fee available manager fee of the pool
function calculateAvailableManagerFee(uint256 fundValue) public view returns (uint256 fee) {
(uint256 performanceFeeNumerator, uint256 managementFeeNumerator, , , uint256 denominator) = _managerFees();
(uint256 performanceFee, uint256 streamingFee) = _availableManagerFee(
fundValue,
totalSupply(),
performanceFeeNumerator,
managementFeeNumerator,
denominator
);
return performanceFee.add(streamingFee);
}
/// @notice Get available manager fee of the pool internal call
/// @param _fundValue The total fund value of the pool
/// @param _tokenSupply The total token supply of the pool
/// @param _performanceFeeNumerator The manager fee numerator
/// @param _managerFeeNumerator The streaming fee numerator
/// @param _feeDenominator The fee denominator
/// @return performanceFee The performance fee generated by the pool
/// @return streamingFee The streaming fee generated by the pool
function _availableManagerFee(
uint256 _fundValue,
uint256 _tokenSupply,
uint256 _performanceFeeNumerator,
uint256 _managerFeeNumerator,
uint256 _feeDenominator
) internal view returns (uint256 performanceFee, uint256 streamingFee) {
if (_tokenSupply == 0 || _fundValue == 0) return (0, 0);
uint256 currentTokenPrice = _fundValue.mul(10 ** 18).div(_tokenSupply);
if (currentTokenPrice > tokenPriceAtLastFeeMint) {
uint256 feeUsdAmount = (
(currentTokenPrice.sub(tokenPriceAtLastFeeMint)).mul(_performanceFeeNumerator).mul(_tokenSupply)
).div(_feeDenominator.mul(1e18));
performanceFee = feeUsdAmount.mul(_tokenSupply).div(_fundValue.sub(feeUsdAmount));
}
// this timestamp for old pools would be zero at the first time
if (lastFeeMintTime != 0) {
uint256 timeChange = block.timestamp.sub(lastFeeMintTime);
streamingFee = _tokenSupply.mul(timeChange).mul(_managerFeeNumerator).div(_feeDenominator).div(365 days);
}
}
/// @notice Mint the manager fee of the pool
function mintManagerFee() external whenNotFactoryPaused whenNotPaused {
_mintManagerFee();
}
/// @notice Get mint manager fee of the pool internal call
/// @return fundValue The total fund value of the pool
function _mintManagerFee() internal returns (uint256 fundValue) {
fundValue = IPoolManagerLogic(poolManagerLogic).totalFundValueMutable();
uint256 tokenSupply = totalSupply();
(uint256 performanceFeeNumerator, uint256 managementFeeNumerator, , , uint256 denominator) = _managerFees();
(uint256 performanceFee, uint256 streamingFee) = _availableManagerFee(
fundValue,
tokenSupply,
performanceFeeNumerator,
managementFeeNumerator,
denominator
);
uint256 available = performanceFee.add(streamingFee);
(uint256 daoFeeNumerator, uint256 daoFeeDenominator) = IHasDaoInfo(factory).getDaoFee();
uint256 daoFee = available.mul(daoFeeNumerator).div(daoFeeDenominator);
uint256 managerFee = available.sub(daoFee);
uint256 currentTokenPrice = _tokenPrice(fundValue, tokenSupply);
if (tokenPriceAtLastFeeMint < currentTokenPrice) {
tokenPriceAtLastFeeMint = currentTokenPrice;
}
// If the `streamingFee` is 0 then updating `lastFeeMintTime` can result in reduced streaming fee revenue.
// This is due to rounding down when calculating `streamingFee` in `_availableManagerFee`.
if (streamingFee > 0) lastFeeMintTime = block.timestamp;
if (daoFee > 0) _mint(IHasDaoInfo(factory).daoAddress(), daoFee);
if (managerFee > 0) _mint(_manager(), managerFee);
emit ManagerFeeMinted(address(this), _manager(), available, daoFee, managerFee, tokenPriceAtLastFeeMint);
_emitFactoryEvent();
}
/// @notice Calculate lockup cooldown applied to the investor after pool deposit
/// @param currentBalance Investor's current pool tokens balance
/// @param liquidityMinted Liquidity to be minted to investor after pool deposit
/// @param newCooldown New cooldown lockup time
/// @param lastCooldown Last cooldown lockup time applied to investor
/// @param lastDepositTime Timestamp when last pool deposit happened
/// @param blockTimestamp Timestamp of a block
/// @return cooldown New lockup cooldown to be applied to investor address
function _calculateCooldown(
uint256 currentBalance,
uint256 liquidityMinted,
uint256 newCooldown,
uint256 lastCooldown,
uint256 lastDepositTime,
uint256 blockTimestamp
) internal pure returns (uint256 cooldown) {
// Get timestamp when current cooldown ends
uint256 cooldownEndsAt = lastDepositTime.add(lastCooldown);
// Current exit remaining cooldown
uint256 remainingCooldown = cooldownEndsAt < blockTimestamp ? 0 : cooldownEndsAt.sub(blockTimestamp);
// If it's first deposit with zero liquidity, no cooldown should be applied
if (currentBalance == 0 && liquidityMinted == 0) {
cooldown = 0;
// If it's first deposit, new cooldown should be applied
} else if (currentBalance == 0) {
cooldown = newCooldown;
// If zero liquidity or new cooldown reduces remaining cooldown, apply remaining
} else if (liquidityMinted == 0 || newCooldown < remainingCooldown) {
cooldown = remainingCooldown;
// For the rest cases calculate cooldown based on current balance and liquidity minted
} else {
// If the user already owns liquidity, the additional lockup should be in proportion to their existing liquidity.
// Calculated as newCooldown * liquidityMinted / currentBalance
// Aggregate additional and remaining cooldowns
uint256 aggregatedCooldown = newCooldown.mul(liquidityMinted).div(currentBalance).add(remainingCooldown);
// Resulting value is capped at new cooldown time (shouldn't be bigger) and falls back to one second in case of zero
cooldown = aggregatedCooldown > newCooldown
? newCooldown
: aggregatedCooldown != 0
? aggregatedCooldown
: 1;
}
}
/// @notice Get exit remaining time of the pool
/// @return remaining The remaining exit time of the pool
function getExitRemainingCooldown(address sender) public view returns (uint256 remaining) {
uint256 cooldownFinished = lastDeposit[sender].add(lastExitCooldown[sender]);
if (cooldownFinished < block.timestamp) return 0;
remaining = cooldownFinished.sub(block.timestamp);
}
/// @notice Set address for pool manager logic
function setPoolManagerLogic(address _poolManagerLogic) external {
require(_poolManagerLogic != address(0), "invalid address");
require(msg.sender == factory || msg.sender == IHasOwnable(factory).owner(), "only owner, factory");
poolManagerLogic = _poolManagerLogic;
emit PoolManagerLogicSet(_poolManagerLogic, msg.sender);
}
function _manager() internal view returns (address manager) {
manager = IManaged(poolManagerLogic).manager();
}
function _trader() internal view returns (address trader) {
trader = IManaged(poolManagerLogic).trader();
}
function _exitCooldown() internal view returns (uint256 cooldown) {
cooldown = IHasFeeInfo(factory).getExitCooldown();
}
function _totalValue() internal view returns (uint256 totalValue) {
totalValue = IPoolManagerLogic(poolManagerLogic).totalFundValue();
}
function _assetValue(address _asset, uint256 _amount) internal view returns (uint256 assetValue) {
assetValue = IPoolManagerLogic(poolManagerLogic).assetValue(_asset, _amount);
}
function _managerFees()
internal
view
returns (uint256 performance, uint256 management, uint256 entry, uint256 exit, uint256 denominator)
{
(performance, management, entry, exit, denominator) = IPoolManagerLogic(poolManagerLogic).getFee();
}
function _isMemberAllowed(address _member) internal view returns (bool allowed) {
allowed = IPoolManagerLogic(poolManagerLogic).isMemberAllowed(_member);
}
/// @inheritdoc IFlashLoanReceiver
function executeOperation(
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata premiums,
address initiator,
bytes calldata params
) external override returns (bool success) {
require(initiator == address(this), "only pool flash loan origin");
address aaveLendingPoolAssetGuard = IHasGuardInfo(factory).getAssetGuard(msg.sender);
require(
aaveLendingPoolAssetGuard != address(0) &&
msg.sender == IAaveLendingPoolAssetGuard(aaveLendingPoolAssetGuard).aaveLendingPool(),
"invalid lending pool"
);
uint256 withdrawAssetBalanceBefore = IERC20Upgradeable(assets[0]).balanceOf(address(this));
IAssetGuard.MultiTransaction[] memory transactions = IAaveLendingPoolAssetGuard(aaveLendingPoolAssetGuard)
.flashloanProcessing(address(this), assets[0], amounts[0], premiums[0], params);
for (uint256 i; i < transactions.length; ++i) {
success = transactions[i].to.tryAssemblyCall(transactions[i].txData);
}
// Liquidation of collateral not enough to pay off debt, flashloan repayment stealing pool's asset
require(withdrawAssetBalanceBefore <= IERC20Upgradeable(assets[0]).balanceOf(address(this)), "high slippage");
}
/// @notice Emits an event through the factory, so we can just listen to the factory offchain
function _emitFactoryEvent() internal {
IPoolFactory(factory).emitPoolEvent();
}
/// @notice Support safeTransfers from ERC721 asset contracts
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external override returns (bytes4 magicSelector) {
address contractGuard = IHasGuardInfo(factory).getContractGuard(operator);
// Only guarded contract can initiate ERC721 transfers
require(contractGuard != address(0), "only guarded address");
require(IERC721VerifyingGuard(contractGuard).verifyERC721(operator, from, tokenId, data), "not verified");
magicSelector = IERC721ReceiverUpgradeable.onERC721Received.selector;
}
uint256[47] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165Upgradeable {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMathUpgradeable {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}// SPDX-License-Identifier: MIT
// solhint-disable-next-line compiler-version
pragma solidity >=0.4.24 <0.8.0;
import "../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Modifier to protect an initializer function from being invoked twice.
*/
modifier initializer() {
require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized");
bool isTopLevelCall = !_initializing;
if (isTopLevelCall) {
_initializing = true;
_initialized = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
}
}
/// @dev Returns true if and only if the function is running in the constructor
function _isConstructor() private view returns (bool) {
return !AddressUpgradeable.isContract(address(this));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "../../utils/ContextUpgradeable.sol";
import "./IERC20Upgradeable.sol";
import "../../math/SafeMathUpgradeable.sol";
import "../../proxy/Initializable.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin guidelines: functions revert instead
* of returning `false` on failure. This behavior is nonetheless conventional
* and does not conflict with the expectations of ERC20 applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable {
using SafeMathUpgradeable for uint256;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
uint8 private _decimals;
/**
* @dev Sets the values for {name} and {symbol}, initializes {decimals} with
* a default value of 18.
*
* To select a different value for {decimals}, use {_setupDecimals}.
*
* All three of these values are immutable: they can only be set once during
* construction.
*/
function __ERC20_init(string memory name_, string memory symbol_) internal initializer {
__Context_init_unchained();
__ERC20_init_unchained(name_, symbol_);
}
function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer {
_name = name_;
_symbol = symbol_;
_decimals = 18;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5,05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
* called.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return _decimals;
}
/**
* @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:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* Requirements:
*
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
/**
* @dev Moves tokens `amount` from `sender` to `recipient`.
*
* This is internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `to` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Sets {decimals} to a value other than the default one of 18.
*
* WARNING: This function should only be called from the constructor. Most
* applications that interact with token contracts will not expect
* {decimals} to ever change, and may work incorrectly if it does.
*/
function _setupDecimals(uint8 decimals_) internal virtual {
_decimals = decimals_;
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be to transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
uint256[44] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20Upgradeable {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721ReceiverUpgradeable {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
*/
function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../proxy/Initializable.sol";
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal initializer {
__Context_init_unchained();
}
function __Context_init_unchained() internal initializer {
}
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "../proxy/Initializable.sol";
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuardUpgradeable is Initializable {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
function __ReentrancyGuard_init() internal initializer {
__ReentrancyGuard_init_unchained();
}
function __ReentrancyGuard_init_unchained() internal initializer {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
uint256[49] private __gap;
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.7.6;
/**
* @title IFlashLoanReceiver interface
* @notice Interface for the Aave fee IFlashLoanReceiver.
* @author Aave
* @dev implement this interface to develop a flashloan-compatible flashLoanReceiver contract
**/
interface IFlashLoanReceiver {
function executeOperation(
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata premiums,
address initiator,
bytes calldata params
) external returns (bool);
}//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2024 dHEDGE DAO
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;
import {IAssetGuard} from "./IAssetGuard.sol";
interface IAaveLendingPoolAssetGuard {
function flashloanProcessing(
address pool,
address repayAsset,
uint256 repayAmount,
uint256 premium,
bytes calldata params
) external view returns (IAssetGuard.MultiTransaction[] memory transactions);
function aaveLendingPool() external view returns (address lendingPool);
}//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2021 dHEDGE DAO
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;
import "../IHasSupportedAsset.sol";
interface IAssetGuard {
struct MultiTransaction {
address to;
bytes txData;
}
function withdrawProcessing(
address pool,
address asset,
uint256 withdrawPortion,
address to
) external returns (address, uint256, MultiTransaction[] memory transactions);
function getBalance(address pool, address asset) external view returns (uint256 balance);
function getDecimals(address asset) external view returns (uint256 decimals);
function removeAssetCheck(address poolLogic, address asset) external view;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IERC721VerifyingGuard {
function verifyERC721(
address operator,
address from,
uint256 tokenId,
bytes calldata
) external returns (bool verified);
}//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2021 dHEDGE DAO
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IGuard {
event ExchangeFrom(address fundAddress, address sourceAsset, uint256 sourceAmount, address dstAsset, uint256 time);
event ExchangeTo(address fundAddress, address sourceAsset, address dstAsset, uint256 dstAmount, uint256 time);
function txGuard(
address poolManagerLogic,
address to,
bytes calldata data
) external returns (uint16 txType, bool isPublic); // TODO: eventually update `txType` to be of enum type as per ITransactionTypes
}//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2021 dHEDGE DAO
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "./IGuard.sol";
interface ITxTrackingGuard is IGuard {
function isTxTrackingGuard() external view returns (bool);
function afterTxGuard(address poolManagerLogic, address to, bytes calldata data) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IGovernance {
function contractGuards(address target) external view returns (address guard);
function assetGuards(uint16 assetType) external view returns (address guard);
function nameToDestination(bytes32 name) external view returns (address);
}//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2021 dHEDGE DAO
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IHasDaoInfo {
function getDaoFee() external view returns (uint256, uint256);
function daoAddress() external view returns (address);
}//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2021 dHEDGE DAO
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IHasFeeInfo {
// Manager fee
function getMaximumFee() external view returns (uint256, uint256, uint256, uint256, uint256);
function maximumPerformanceFeeNumeratorChange() external view returns (uint256);
function performanceFeeNumeratorChangeDelay() external view returns (uint256);
function getExitCooldown() external view returns (uint256);
}//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2021 dHEDGE DAO
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IHasGuardInfo {
// Get guard
function getContractGuard(address extContract) external view returns (address);
// Get asset guard
function getAssetGuard(address extContract) external view returns (address);
// Get mapped addresses from Governance
function getAddress(bytes32 name) external view returns (address);
}//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2021 dHEDGE DAO
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IHasOwnable {
function owner() external view returns (address);
}//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2021 dHEDGE DAO
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IHasPausable {
function isPaused() external view returns (bool);
function pausedPools(address pool) external view returns (bool);
}//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2021 dHEDGE DAO
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;
interface IHasSupportedAsset {
struct Asset {
address asset;
bool isDeposit;
}
function getSupportedAssets() external view returns (Asset[] memory);
function isSupportedAsset(address asset) external view returns (bool);
}//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2021 dHEDGE DAO
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IManaged {
function manager() external view returns (address);
function trader() external view returns (address);
function managerName() external view returns (string memory);
}//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2021 dHEDGE DAO
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IPoolFactory {
function governanceAddress() external view returns (address);
function isPool(address pool) external view returns (bool);
function customCooldownWhitelist(address from) external view returns (bool);
function receiverWhitelist(address to) external view returns (bool);
function emitPoolEvent() external;
function emitPoolManagerEvent() external;
}//
// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2021 dHEDGE DAO
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IPoolManagerLogic {
function poolLogic() external view returns (address);
function isDepositAsset(address asset) external view returns (bool);
function validateAsset(address asset) external view returns (bool);
function assetValue(address asset) external view returns (uint256);
function assetValue(address asset, uint256 amount) external view returns (uint256);
function assetBalance(address asset) external view returns (uint256 balance);
function factory() external view returns (address);
function setPoolLogic(address fundAddress) external returns (bool);
function totalFundValue() external view returns (uint256);
function totalFundValueMutable() external returns (uint256);
function isMemberAllowed(address member) external view returns (bool);
function getFee() external view returns (uint256, uint256, uint256, uint256, uint256);
function minDepositUSD() external view returns (uint256);
}// __ __ __ ________ _______ ______ ________
// / |/ | / |/ |/ \ / \ / |
// ____$$ |$$ | $$ |$$$$$$$$/ $$$$$$$ |/$$$$$$ |$$$$$$$$/
// / $$ |$$ |__$$ |$$ |__ $$ | $$ |$$ | _$$/ $$ |__
// /$$$$$$$ |$$ $$ |$$ | $$ | $$ |$$ |/ |$$ |
// $$ | $$ |$$$$$$$$ |$$$$$/ $$ | $$ |$$ |$$$$ |$$$$$/
// $$ \__$$ |$$ | $$ |$$ |_____ $$ |__$$ |$$ \__$$ |$$ |_____
// $$ $$ |$$ | $$ |$$ |$$ $$/ $$ $$/ $$ |
// $$$$$$$/ $$/ $$/ $$$$$$$$/ $$$$$$$/ $$$$$$/ $$$$$$$$/
//
// dHEDGE DAO - https://dhedge.org
//
// Copyright (c) 2021 dHEDGE DAO
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//
// SPDX-License-Identifier: MIT
// import "./BytesLib.sol";
pragma solidity 0.7.6;
/**
* @title A library for Address utils.
*/
library AddressHelper {
/**
* @notice try a contract call via assembly
* @param to the contract address
* @param data the call data
* @return success if the contract call is successful or not
*/
function tryAssemblyCall(address to, bytes memory data) internal returns (bool success) {
assembly {
success := call(gas(), to, 0, add(data, 0x20), mload(data), 0, 0)
switch iszero(success)
case 1 {
let size := returndatasize()
returndatacopy(0x00, 0x00, size)
revert(0x00, size)
}
}
}
/**
* @notice try a contract delegatecall via assembly
* @param to the contract address
* @param data the call data
* @return success if the contract call is successful or not
*/
function tryAssemblyDelegateCall(address to, bytes memory data) internal returns (bool success) {
assembly {
success := delegatecall(gas(), to, add(data, 0x20), mload(data), 0, 0)
switch iszero(success)
case 1 {
let size := returndatasize()
returndatacopy(0x00, 0x00, size)
revert(0x00, size)
}
}
}
// /**
// * @notice try a contract call
// * @param to the contract address
// * @param data the call data
// * @return success if the contract call is successful or not
// */
// function tryCall(address to, bytes memory data) internal returns (bool) {
// (bool success, bytes memory res) = to.call(data);
// // Get the revert message of the call and revert with it if the call failed
// require(success, _getRevertMsg(res));
// return success;
// }
// /**
// * @dev Get the revert message from a call
// * @notice This is needed in order to get the human-readable revert message from a call
// * @param response Response of the call
// * @return Revert message string
// */
// function _getRevertMsg(bytes memory response) internal pure returns (string memory) {
// // If the response length is less than 68, then the transaction failed silently (without a revert message)
// if (response.length < 68) return "Transaction reverted silently";
// bytes memory revertData = response.slice(4, response.length - 4); // Remove the selector which is the first 4 bytes
// return abi.decode(revertData, (string)); // All that remains is the revert string
// }
}{
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"optimizer": {
"enabled": true,
"runs": 20
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"fundAddress","type":"address"},{"indexed":false,"internalType":"address","name":"investor","type":"address"},{"indexed":false,"internalType":"address","name":"assetDeposited","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountDeposited","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"valueDeposited","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fundTokensReceived","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalInvestorFundTokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fundValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"address","name":"manager","type":"address"},{"indexed":false,"internalType":"uint256","name":"available","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"daoFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"managerFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenPriceAtLastFeeMint","type":"uint256"}],"name":"ManagerFeeMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"poolManagerLogic","type":"address"},{"indexed":false,"internalType":"address","name":"from","type":"address"}],"name":"PoolManagerLogicSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isPoolPrivate","type":"bool"}],"name":"PoolPrivacyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"address","name":"manager","type":"address"},{"indexed":false,"internalType":"uint16","name":"transactionType","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"TransactionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"fundAddress","type":"address"},{"indexed":false,"internalType":"address","name":"investor","type":"address"},{"indexed":false,"internalType":"uint256","name":"valueWithdrawn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fundTokensWithdrawn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalInvestorFundTokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fundValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalSupply","type":"uint256"},{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"externalWithdrawProcessed","type":"bool"}],"indexed":false,"internalType":"struct PoolLogic.WithdrawnAsset[]","name":"withdrawnAssets","type":"tuple[]"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"Withdrawal","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fundValue","type":"uint256"}],"name":"calculateAvailableManagerFee","outputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creationTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"liquidityMinted","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositFor","outputs":[{"internalType":"uint256","name":"liquidityMinted","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_cooldown","type":"uint256"}],"name":"depositForWithCustomCooldown","outputs":[{"internalType":"uint256","name":"liquidityMinted","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"execTransaction","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct PoolLogic.TxToExecute[]","name":"txs","type":"tuple[]"}],"name":"execTransactions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"premiums","type":"uint256[]"},{"internalType":"address","name":"initiator","type":"address"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"executeOperation","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"getExitRemainingCooldown","outputs":[{"internalType":"uint256","name":"remaining","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFundSummary","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"totalFundValue","type":"uint256"},{"internalType":"address","name":"manager","type":"address"},{"internalType":"string","name":"managerName","type":"string"},{"internalType":"uint256","name":"creationTime","type":"uint256"},{"internalType":"bool","name":"privatePool","type":"bool"},{"internalType":"uint256","name":"performanceFeeNumerator","type":"uint256"},{"internalType":"uint256","name":"managerFeeNumerator","type":"uint256"},{"internalType":"uint256","name":"managerFeeDenominator","type":"uint256"},{"internalType":"uint256","name":"exitFeeNumerator","type":"uint256"},{"internalType":"uint256","name":"exitFeeDenominator","type":"uint256"},{"internalType":"uint256","name":"entryFeeNumerator","type":"uint256"}],"internalType":"struct PoolLogic.FundSummary","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"bool","name":"_privatePool","type":"bool"},{"internalType":"string","name":"_fundName","type":"string"},{"internalType":"string","name":"_fundSymbol","type":"string"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastExitCooldown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastFeeMintTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastWhitelistTransfer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintManagerFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"magicSelector","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"poolManagerLogic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"privatePool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_poolManagerLogic","type":"address"}],"name":"setPoolManagerLogic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_privatePool","type":"bool"}],"name":"setPoolPrivate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenPrice","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenPriceAtLastFeeMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenPriceWithoutManagerFee","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fundTokenAmount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fundTokenAmount","type":"uint256"},{"internalType":"uint256","name":"_slippageTolerance","type":"uint256"}],"name":"withdrawSafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_fundTokenAmount","type":"uint256"}],"name":"withdrawTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_fundTokenAmount","type":"uint256"},{"internalType":"uint256","name":"_slippageTolerance","type":"uint256"}],"name":"withdrawToSafe","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50615682806100206000396000f3fe608060405234801561001057600080fd5b50600436106101f35760003560e01c80637714f39d116101165780637714f39d1461038d5780637ae7cfb5146103955780637ff9b596146103a8578063920f5c84146103b057806394138e97146103c357806395d89b41146103d6578063a457c2d7146103de578063a77134e4146103f1578063a9059cbb146103f9578063a971a9131461040c578063aee883341461041f578063b3db428b14610432578063b8ea2b6e14610445578063c45a015514610458578063cc3c6df614610460578063d8270dce14610468578063dd62ed3e14610470578063de6eb13314610483578063df8164cf14610496578063df8ff12f146104a9578063e4262edd146104b1576101f3565b806302d05d3f146101f857806306fdde0314610216578063095ea7b31461022b578063150b7a021461024b57806318160ddd1461026b5780631c5918d2146102805780631e50a4a614610295578063205c28781461029d57806323b872dd146102b257806329d16ee8146102c55780632e1a7d4d146102d8578063313ce567146102eb57806339509351146103005780633babaad51461031357806347e7ef24146103265780635426f81d1461033957806359b5e75e1461034c57806370a08231146103545780637481de6614610367578063750226de1461037a575b600080fd5b6102006104c4565b60405161020d9190614a8d565b60405180910390f35b61021e6104d8565b60405161020d9190614d5b565b61023e6102393660046145cf565b61056e565b60405161020d9190614d2c565b61025e610259366004614443565b61058c565b60405161020d9190614d37565b6102736106f7565b60405161020d9190615359565b6102886106fd565b60405161020d9190615282565b61020061083c565b6102b06102ab3660046145cf565b61084b565b005b61023e6102c0366004614403565b61085c565b6102736102d3366004614393565b6108e4565b6102b06102e6366004614955565b6108f6565b6102f3610906565b60405161020d9190615362565b61023e61030e3660046145cf565b61090f565b6102b06103213660046148a4565b61095d565b6102736103343660046145cf565b6109e3565b6102b06103473660046144f8565b6109f8565b61023e610aff565b610273610362366004614393565b610b08565b610273610375366004614393565b610b27565b6102b0610388366004614393565b610b39565b610273610c82565b61023e6103a336600461457d565b610c88565b610273610cd2565b61023e6103be366004614685565b610d0e565b6102736103d1366004614955565b611113565b61021e61115a565b61023e6103ec3660046145cf565b6111bb565b610273611223565b61023e6104073660046145cf565b611242565b6102b061041a366004614865565b611256565b61027361042d366004614393565b61131f565b610273610440366004614403565b611331565b610273610453366004614393565b611341565b61020061138f565b6102b061139e565b6102736114e6565b61027361047e3660046143cb565b6114ec565b6102736104913660046144b3565b611517565b6102b06104a4366004614985565b6115fe565b610273611609565b6102b06104bf366004614651565b61160f565b60975461010090046001600160a01b031681565b60368054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105645780601f1061053957610100808354040283529160200191610564565b820191906000526020600020905b81548152906001019060200180831161054757829003601f168201915b5050505050905090565b600061058261057b61161a565b848461161e565b5060015b92915050565b609954604051634f8419b960e01b815260009182916001600160a01b0390911690634f8419b9906105c1908a90600401614a8d565b60206040518083038186803b1580156105d957600080fd5b505afa1580156105ed573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061191906143af565b90506001600160a01b0381166106425760405162461bcd60e51b8152600401610639906151f4565b60405180910390fd5b6040516306baeff360e11b81526001600160a01b03821690630d75dfe690610676908a908a908a908a908a90600401614c62565b602060405180830381600087803b15801561069057600080fd5b505af11580156106a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106c891906148c0565b6106e45760405162461bcd60e51b815260040161063990614dcb565b50630a85bd0160e11b9695505050505050565b60355490565b610705614067565b600080600080600061071561170a565b94509450945094509450604051806101a001604052806107336104d8565b81526020016107406106f7565b815260200161074d6117a9565b815260200161075a611826565b6001600160a01b03168152602001609c60009054906101000a90046001600160a01b03166001600160a01b031663fed4416a6040518163ffffffff1660e01b815260040160006040518083038186803b1580156107b657600080fd5b505afa1580156107ca573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107f291908101906148dc565b8152609854602082015260975460ff16151560408201526060810196909652608086019490945260a0850181905260c085019190915260e084015261010090920191909152905090565b609c546001600160a01b031681565b61085882826127106118a3565b5050565b6000610869848484611e4d565b6108d98461087561161a565b6108d485604051806060016040528060288152602001615576602891396001600160a01b038a166000908152603460205260408120906108b361161a565b6001600160a01b031681526020810191909152604001600020549190611f98565b61161e565b5060015b9392505050565b609b6020526000908152604090205481565b61090333826127106118a3565b50565b60385460ff1690565b600061058261091c61161a565b846108d4856034600061092d61161a565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549061202f565b610965611826565b6001600160a01b0316336001600160a01b0316146109955760405162461bcd60e51b815260040161063990614efd565b6097805460ff19168215151790556040517f8d75e9ede4188432084b863d70b3416010c97547dfeb4fc17734d2e997ee0f39906109d3908390614d2c565b60405180910390a1610903612087565b60006108dd3384846109f36120f1565b612136565b600054610100900460ff1680610a115750610a11612770565b80610a1f575060005460ff16155b610a5a5760405162461bcd60e51b815260040180806020018281038252602e815260200180615527602e913960400191505060405180910390fd5b600054610100900460ff16158015610a85576000805460ff1961ff0019909116610100171660011790555b610a8f8383612781565b610a97612836565b609980546001600160a01b0319166001600160a01b0387161790556097805460ff191685151517610100600160a81b0319166101003302179055426098819055609e55670de0b6b3a7640000609a558015610af8576000805461ff00191690555b5050505050565b60975460ff1681565b6001600160a01b0381166000908152603360205260409020545b919050565b609f6020526000908152604090205481565b6001600160a01b038116610b5f5760405162461bcd60e51b815260040161063990614f84565b6099546001600160a01b0316331480610c0e5750609960009054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610bc157600080fd5b505afa158015610bd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf991906143af565b6001600160a01b0316336001600160a01b0316145b610c2a5760405162461bcd60e51b815260040161063990614e4b565b609c80546001600160a01b0319166001600160a01b0383161790556040517f63fb64c359a4cae97e1bf003c1ab11390b5f0e18cc5b3d67b90bd61c0f5c52fd90610c779083903390614ac5565b60405180910390a150565b609a5481565b6000610cca8484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506128df92505050565b949350505050565b600080610cdd6117a9565b90506000610cfb610ced83611113565b610cf56106f7565b9061202f565b9050610d078282612fed565b9250505090565b60006001600160a01b0384163014610d385760405162461bcd60e51b815260040161063990614f4f565b609954604051633f30232f60e21b81526000916001600160a01b03169063fcc08cbc90610d69903390600401614a8d565b60206040518083038186803b158015610d8157600080fd5b505afa158015610d95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db991906143af565b90506001600160a01b03811615801590610e545750806001600160a01b031663e9d337b86040518163ffffffff1660e01b815260040160206040518083038186803b158015610e0757600080fd5b505afa158015610e1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e3f91906143af565b6001600160a01b0316336001600160a01b0316145b610e705760405162461bcd60e51b815260040161063990615254565b60008b8b6000818110610e7f57fe5b9050602002016020810190610e949190614393565b6001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610ebf9190614a8d565b60206040518083038186803b158015610ed757600080fd5b505afa158015610eeb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0f919061496d565b90506000826001600160a01b031663989dccf8308f8f6000818110610f3057fe5b9050602002016020810190610f459190614393565b8e8e6000818110610f5257fe5b905060200201358d8d6000818110610f6657fe5b905060200201358b8b6040518763ffffffff1660e01b8152600401610f9096959493929190614c96565b60006040518083038186803b158015610fa857600080fd5b505afa158015610fbc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610fe49190810190614833565b905060005b81518110156110465761103c82828151811061100157fe5b60200260200101516020015183838151811061101957fe5b6020026020010151600001516001600160a01b031661301d90919063ffffffff16565b9450600101610fe9565b508c8c600081811061105457fe5b90506020020160208101906110699190614393565b6001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016110949190614a8d565b60206040518083038186803b1580156110ac57600080fd5b505afa1580156110c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e4919061496d565b8211156111035760405162461bcd60e51b8152600401610639906150a3565b5050509998505050505050505050565b60008060008061112161170a565b9450505092509250600080611140876111386106f7565b878787613050565b909250905061114f828261202f565b979650505050505050565b60378054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105645780601f1061053957610100808354040283529160200191610564565b60006105826111c861161a565b846108d48560405180606001604052806025815260200161562860259139603460006111f261161a565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190611f98565b600061123d6112306117a9565b6112386106f7565b612fed565b905090565b600061058261124f61161a565b8484611e4d565b60005b8181101561131a576112f683838381811061127057fe5b905060200281019061128291906153b4565b611290906020810190614393565b84848481811061129c57fe5b90506020028101906112ae91906153b4565b6112bc906020810190615370565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506128df92505050565b6113125760405162461bcd60e51b815260040161063990614fd3565b600101611259565b505050565b609d6020526000908152604090205481565b6000610cca8484846109f36120f1565b6001600160a01b0381166000908152609f6020908152604080832054609b9092528220548291611371919061202f565b905042811015611385576000915050610b22565b6108dd8142613132565b6099546001600160a01b031681565b609960009054906101000a90046001600160a01b03166001600160a01b031663b187bd266040518163ffffffff1660e01b815260040160206040518083038186803b1580156113ec57600080fd5b505afa158015611400573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142491906148c0565b156114415760405162461bcd60e51b815260040161063990615154565b60995460405163cdf04c0760e01b81526001600160a01b039091169063cdf04c0790611471903090600401614a8d565b60206040518083038186803b15801561148957600080fd5b505afa15801561149d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c191906148c0565b156114de5760405162461bcd60e51b8152600401610639906151a5565b61090361318f565b60985481565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b609954604051632927233b60e01b81526000916001600160a01b031690632927233b90611548903390600401614a8d565b60206040518083038186803b15801561156057600080fd5b505afa158015611574573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159891906148c0565b6115b45760405162461bcd60e51b815260040161063990614fad565b61012c82101580156115cd57506115c96120f1565b8211155b6115e95760405162461bcd60e51b815260040161063990614ff6565b6115f585858585612136565b95945050505050565b6108583383836118a3565b609e5481565b61131a8383836118a3565b3390565b6001600160a01b0383166116635760405162461bcd60e51b81526004018080602001828103825260248152602001806156046024913960400191505060405180910390fd5b6001600160a01b0382166116a85760405162461bcd60e51b81526004018080602001828103825260228152602001806154df6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260346020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6000806000806000609c60009054906101000a90046001600160a01b03166001600160a01b031663ced72f876040518163ffffffff1660e01b815260040160a06040518083038186803b15801561176057600080fd5b505afa158015611774573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061179891906149c9565b939992985090965094509092509050565b609c5460408051632b583ff360e21b815290516000926001600160a01b03169163ad60ffcc916004808301926020929190829003018186803b1580156117ee57600080fd5b505afa158015611802573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123d919061496d565b609c546040805163481c6a7560e01b815290516000926001600160a01b03169163481c6a75916004808301926020929190829003018186803b15801561186b57600080fd5b505afa15801561187f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123d91906143af565b600260655414156118e9576040805162461bcd60e51b815260206004820152601f602482015260008051602061549d833981519152604482015290519081900360640190fd5b6002606555609954604080516358c3de9360e11b815290516001600160a01b039092169163b187bd2691600480820192602092909190829003018186803b15801561193357600080fd5b505afa158015611947573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196b91906148c0565b156119885760405162461bcd60e51b815260040161063990615154565b60995460405163cdf04c0760e01b81526001600160a01b039091169063cdf04c07906119b8903090600401614a8d565b60206040518083038186803b1580156119d057600080fd5b505afa1580156119e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0891906148c0565b15611a255760405162461bcd60e51b8152600401610639906151a5565b336000908152609b60205260409020544211611a535760405162461bcd60e51b8152600401610639906150f9565b81611a5d33610b08565b1015611a7b5760405162461bcd60e51b815260040161063990614f23565b612710811115611a9d5760405162461bcd60e51b815260040161063990615048565b6000611ab183611aab6106f7565b90613132565b9050620186a081101580611ac3575080155b611adf5760405162461bcd60e51b815260040161063990615073565b506000611aea61318f565b9050600080611af761170a565b945094505050506000821115611b5a576000611b1d82611b17888661341e565b90613477565b9050611b298682613132565b9550611b3c611b36611826565b82611242565b611b585760405162461bcd60e51b815260040161063990615222565b505b50506000611b7b611b696106f7565b611b1786670de0b6b3a764000061341e565b9050611b8733856134db565b611b8f6106f7565b611ba057670de0b6b3a7640000609a555b609c546040805163e5406dbf60e01b815290516000926001600160a01b03169163e5406dbf9160048083019286929190829003018186803b158015611be457600080fd5b505afa158015611bf8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c20919081019061475a565b9050600081516001600160401b0381118015611c3b57600080fd5b50604051908082528060200260200182016040528015611c7557816020015b611c626140da565b815260200190600190039081611c5a5790505b5090506000805b8351811015611da2576000806000611cad878581518110611c9957fe5b6020026020010151600001518d8a8d6135c5565b919450925090508115611d42576001600160a01b038316611ce05760405162461bcd60e51b815260040161063990614df1565b611d4063a9059cbb60e01b8d84604051602401611cfe929190614d13565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526001600160a01b0385169061301d565b505b8080611d4e5750600082115b15611d97576040518060600160405280846001600160a01b03168152602001838152602001821515815250868681518110611d8557fe5b60209081029190910101526001909401935b505050600101611c7c565b508251600090611db29083613132565b8351819003845290506000611dd3670de0b6b3a7640000611b17888a61341e565b90507ffad3d7f9ed107ffa7fc8ce8baa521effc3650ec48a4d1dd36bdb9c4b91db12953033838c611e0333610b08565b611e0d8d88613132565b611e156106f7565b8b42604051611e2c99989796959493929190614adf565b60405180910390a1611e3c612087565b505060016065555050505050505050565b6001600160a01b038316611e925760405162461bcd60e51b81526004018080602001828103825260258152602001806155df6025913960400191505060405180910390fd5b6001600160a01b038216611ed75760405162461bcd60e51b815260040180806020018281038252602381526020018061547a6023913960400191505060405180910390fd5b611ee2838383613a55565b611f1f81604051806060016040528060268152602001615501602691396001600160a01b0386166000908152603360205260409020549190611f98565b6001600160a01b038085166000908152603360205260408082209390935590841681522054611f4e908261202f565b6001600160a01b03808416600081815260336020908152604091829020949094558051858152905191939287169260008051602061559e83398151915292918290030190a3505050565b600081848411156120275760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611fec578181015183820152602001611fd4565b50505050905090810190601f1680156120195780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000828201838110156108dd576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b609960009054906101000a90046001600160a01b03166001600160a01b03166325c4121b6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156120d757600080fd5b505af11580156120eb573d6000803e3d6000fd5b50505050565b609954604080516308a0361160e31b815290516000926001600160a01b031691634501b088916004808301926020929190829003018186803b1580156117ee57600080fd5b60006002606554141561217e576040805162461bcd60e51b815260206004820152601f602482015260008051602061549d833981519152604482015290519081900360640190fd5b6002606555609954604080516358c3de9360e11b815290516001600160a01b039092169163b187bd2691600480820192602092909190829003018186803b1580156121c857600080fd5b505afa1580156121dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220091906148c0565b1561221d5760405162461bcd60e51b815260040161063990615154565b60995460405163cdf04c0760e01b81526001600160a01b039091169063cdf04c079061224d903090600401614a8d565b60206040518083038186803b15801561226557600080fd5b505afa158015612279573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229d91906148c0565b156122ba5760405162461bcd60e51b8152600401610639906151a5565b6122c2611826565b6001600160a01b0316856001600160a01b031614806122e4575060975460ff16155b806122f357506122f385613b6c565b61230f5760405162461bcd60e51b815260040161063990614ed7565b609c5460405163bdbef07d60e01b81526001600160a01b039091169063bdbef07d9061233f908790600401614a8d565b60206040518083038186803b15801561235757600080fd5b505afa15801561236b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238f91906148c0565b6123ab5760405162461bcd60e51b8152600401610639906150ca565b600080856001600160a01b03166175306301ffc9a760e01b6380ac58cd60e01b6040516024016123db9190614d37565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516124199190614a71565b6000604051808303818686fa925050503d8060008114612455576040519150601f19603f3d011682016040523d82523d6000602084013e61245a565b606091505b509150915081158061247d57508080602001905181019061247b91906148c0565b155b6124995760405162461bcd60e51b815260040161063990614d9f565b505060006124a561318f565b905060006124b16106f7565b90506125156323b872dd60e01b3330886040516024016124d393929190614aa1565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526001600160a01b0388169061301d565b5060006125228787613bed565b9050811561253f5761253883611b17838561341e565b9350612543565b8093505b60008061254e61170a565b94505093505050600082111561258f57600061256e82611b17898661341e565b905061257a8782613132565b965061258d612587611826565b82613c70565b505b620186a08610156125b25760405162461bcd60e51b815260040161063990614d6e565b6125bc8a87613c70565b50506125f96125ca89610b08565b6001600160a01b038a166000908152609f6020908152604080832054609b909252909120548791899142613d50565b6001600160a01b0389166000908152609f6020908152604080832093909355609b905290812042905561262b89610b08565b90506000612639858461202f565b905060006126456106f7565b9050609c60009054906101000a90046001600160a01b03166001600160a01b03166350b721a76040518163ffffffff1660e01b815260040160206040518083038186803b15801561269557600080fd5b505afa1580156126a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126cd919061496d565b6126ed670de0b6b3a7640000611b176126e68686612fed565b879061341e565b101561270b5760405162461bcd60e51b8152600401610639906151ca565b7f97e6c213c123075e233a6f2323f33d8319141b993ab05e9e2f7eb2eda08cb944308c8c8c888c8989894260405161274c9a99989796959493929190614b88565b60405180910390a15061275d612087565b5050600160655550919695505050505050565b600061277b30613dfe565b15905090565b600054610100900460ff168061279a575061279a612770565b806127a8575060005460ff16155b6127e35760405162461bcd60e51b815260040180806020018281038252602e815260200180615527602e913960400191505060405180910390fd5b600054610100900460ff1615801561280e576000805460ff1961ff0019909116610100171660011790555b612816613e04565b6128208383613ea4565b801561131a576000805461ff0019169055505050565b600054610100900460ff168061284f575061284f612770565b8061285d575060005460ff16155b6128985760405162461bcd60e51b815260040180806020018281038252602e815260200180615527602e913960400191505060405180910390fd5b600054610100900460ff161580156128c3576000805460ff1961ff0019909116610100171660011790555b6128cb613f7c565b8015610903576000805461ff001916905550565b600060026065541415612927576040805162461bcd60e51b815260206004820152601f602482015260008051602061549d833981519152604482015290519081900360640190fd5b6002606555609954604080516358c3de9360e11b815290516001600160a01b039092169163b187bd2691600480820192602092909190829003018186803b15801561297157600080fd5b505afa158015612985573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129a991906148c0565b156129c65760405162461bcd60e51b815260040161063990615154565b6001600160a01b0383166129ec5760405162461bcd60e51b815260040161063990614f84565b609954604051634f8419b960e01b81526000916001600160a01b031690634f8419b990612a1d908790600401614a8d565b60206040518083038186803b158015612a3557600080fd5b505afa158015612a49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a6d91906143af565b905060008080806001600160a01b03851615612b1357609c54604051636179309d60e01b81528694506001600160a01b0380861692636179309d92612abc92909116908c908c90600401614bde565b6040805180830381600087803b158015612ad557600080fd5b505af1158015612ae9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b0d9190614921565b90925090505b61ffff8216612ddc57609954604051633f30232f60e21b81526001600160a01b039091169063fcc08cbc90612b4c908b90600401614a8d565b60206040518083038186803b158015612b6457600080fd5b505afa158015612b78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b9c91906143af565b93506001600160a01b038416612cb0576099546040805163795053d360e01b815290516000926001600160a01b03169163795053d3916004808301926020929190829003018186803b158015612bf157600080fd5b505afa158015612c05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c2991906143af565b60405162a950c360e81b81529091506001600160a01b0382169063a950c30090612c5890600090600401614d4c565b60206040518083038186803b158015612c7057600080fd5b505afa158015612c84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ca891906143af565b945050612d4c565b609c54604051634df48c7360e11b81526001600160a01b0390911690639be918e690612ce0908b90600401614a8d565b60206040518083038186803b158015612cf857600080fd5b505afa158015612d0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d3091906148c0565b612d4c5760405162461bcd60e51b815260040161063990615020565b609c54604051636179309d60e01b81528594506001600160a01b0380861692636179309d92612d8592909116908c908c90600401614bde565b6040805180830381600087803b158015612d9e57600080fd5b505af1158015612db2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dd69190614921565b90925090505b60008261ffff1611612e005760405162461bcd60e51b815260040161063990614e1e565b8080612e245750612e0f611826565b6001600160a01b0316336001600160a01b0316145b80612e475750612e32614022565b6001600160a01b0316336001600160a01b0316145b612e635760405162461bcd60e51b815260040161063990614ea1565b612e766001600160a01b0389168861301d565b60408051600481526024810182526020810180516001600160e01b0316637bf9811960e01b179052905191975060009182916001600160a01b03871691612ebd9190614a71565b6000604051808303816000865af19150503d8060008114612efa576040519150601f19603f3d011682016040523d82523d6000602084013e612eff565b606091505b5091509150818015612f20575080806020019051810190612f2091906148c0565b15612f8e57609c54604051637b364ee960e11b81526001600160a01b038781169263f66c9dd292612f5b92909116908e908e90600401614bde565b600060405180830381600087803b158015612f7557600080fd5b505af1158015612f89573d6000803e3d6000fd5b505050505b7f14464fb67b1871a79e726fa7af525f8fff56e9e5649d511e47f3a357ae31d20730612fb8611826565b8642604051612fca9493929190614c0a565b60405180910390a1612fda612087565b5050600160655550939695505050505050565b6000811580612ffa575082155b1561300757506000610586565b6108dd82611b1785670de0b6b3a764000061341e565b60008060008351602085016000875af1905080156001811461303e57613049565b3d806000803e806000fd5b5092915050565b60008085158061305e575086155b1561306e57506000905080613128565b600061308687611b178a670de0b6b3a764000061341e565b9050609a548111156130e95760006130cc6130a986670de0b6b3a764000061341e565b611b178a6130c68b6130c6609a548961313290919063ffffffff16565b9061341e565b90506130e56130db8a83613132565b611b17838b61341e565b9350505b609e5415613126576000613108609e544261313290919063ffffffff16565b90506131226301e13380611b1787818a6130c68e8861341e565b9250505b505b9550959350505050565b600082821115613189576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b609c54604080516335fd4a6360e11b815290516000926001600160a01b031691636bfa94c691600480830192602092919082900301818787803b1580156131d557600080fd5b505af11580156131e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061320d919061496d565b905060006132196106f7565b9050600080600061322861170a565b94505050925092506000806132408787878787613050565b90925090506000613251838361202f565b6099546040805163272b69b960e21b8152815193945060009384936001600160a01b031692639cada6e49260048082019391829003018186803b15801561329757600080fd5b505afa1580156132ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132cf91906149a6565b909250905060006132e482611b17868661341e565b905060006132f28583613132565b905060006133008d8d612fed565b905080609a54101561331257609a8190555b861561331d5742609e555b82156133a7576099546040805163084c71a360e21b815290516133a7926001600160a01b031691632131c68c916004808301926020929190829003018186803b15801561336957600080fd5b505afa15801561337d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133a191906143af565b84613c70565b81156133be576133be6133b8611826565b83613c70565b7f755a8059d66d8d243bc9f6913f429a811f154599d0538bb0b6a2ac23f23d2ccd306133e8611826565b609a546040516133ff9392918b9189918991614cdd565b60405180910390a161340f612087565b50505050505050505050505090565b60008261342d57506000610586565b8282028284828161343a57fe5b04146108dd5760405162461bcd60e51b81526004018080602001828103825260218152602001806155556021913960400191505060405180910390fd5b60008082116134ca576040805162461bcd60e51b815260206004820152601a602482015279536166654d6174683a206469766973696f6e206279207a65726f60301b604482015290519081900360640190fd5b8183816134d357fe5b049392505050565b6001600160a01b0382166135205760405162461bcd60e51b81526004018080602001828103825260218152602001806155be6021913960400191505060405180910390fd5b61352c82600083613a55565b613569816040518060600160405280602281526020016154bd602291396001600160a01b0385166000908152603360205260409020549190611f98565b6001600160a01b03831660009081526033602052604090205560355461358f9082613132565b6035556040805182815290516000916001600160a01b0385169160008051602061559e8339815191529181900360200190a35050565b609954604051633f30232f60e21b81526000918291829182916001600160a01b039091169063fcc08cbc906135fe908b90600401614a8d565b60206040518083038186803b15801561361657600080fd5b505afa15801561362a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061364e91906143af565b90506001600160a01b0381166136765760405162461bcd60e51b81526004016106399061517e565b61367e6140fa565b61370c670de0b6b3a7640000611b1789856001600160a01b031663d4fac45d308f6040518363ffffffff1660e01b81526004016136bc929190614ac5565b60206040518083038186803b1580156136d457600080fd5b505afa1580156136e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130c6919061496d565b80825261371a908a90613bed565b8160200181815250506000806000846001600160a01b0316636f8ae202308e8d8f6040518563ffffffff1660e01b815260040161375a9493929190614c37565b600060405180830381600087803b15801561377457600080fd5b505af1158015613788573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526137b091908101906145fa565b8051929550909350915080156139375760006001600160a01b03851615613850576040516370a0823160e01b81526001600160a01b038616906370a08231906137fd903090600401614a8d565b60206040518083038186803b15801561381557600080fd5b505afa158015613829573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061384d919061496d565b90505b60005b8281101561388c5761388284828151811061386a57fe5b60200260200101516020015185838151811061101957fe5b9850600101613853565b506001600160a01b03851615613935576040516370a0823160e01b81526000906001600160a01b038716906370a08231906138cb903090600401614a8d565b60206040518083038186803b1580156138e357600080fd5b505afa1580156138f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061391b919061496d565b905061393161392a8284613132565b869061202f565b9450505b505b60408051600481526024810182526020810180516001600160e01b0316631f32d1a360e11b179052905160009182916001600160a01b038a169161397a91614a71565b6000604051808303816000865af19150503d80600081146139b7576040519150601f19603f3d011682016040523d82523d6000602084013e6139bc565b606091505b50915091508180156139dd5750808060200190518101906139dd91906148c0565b80156139f157506001600160a01b03861615155b15613a3f57613a17612710611b178e612710038a6020015161341e90919063ffffffff16565b613a218787613bed565b1015613a3f5760405162461bcd60e51b815260040161063990615124565b5093985091965050505050509450945094915050565b613a6083838361131a565b6001600160a01b038316613a735761131a565b60975460ff161580613a895750613a8982613b6c565b80613a9b57506001600160a01b038216155b613ab75760405162461bcd60e51b815260040161063990614ed7565b609954604051637065accb60e11b81526001600160a01b039091169063e0cb599690613ae7908590600401614a8d565b60206040518083038186803b158015613aff57600080fd5b505afa158015613b13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b3791906148c0565b151560011415613b465761131a565b613b4f83611341565b1561131a5760405162461bcd60e51b815260040161063990614e78565b609c5460405163bbbf725b60e01b81526000916001600160a01b03169063bbbf725b90613b9d908590600401614a8d565b60206040518083038186803b158015613bb557600080fd5b505afa158015613bc9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058691906148c0565b609c546040516314e03fdd60e11b81526000916001600160a01b0316906329c07fba90613c209086908690600401614d13565b60206040518083038186803b158015613c3857600080fd5b505afa158015613c4c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108dd919061496d565b6001600160a01b038216613ccb576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b613cd760008383613a55565b603554613ce4908261202f565b6035556001600160a01b038216600090815260336020526040902054613d0a908261202f565b6001600160a01b038316600081815260336020908152604080832094909455835185815293519293919260008051602061559e8339815191529281900390910190a35050565b600080613d5d848661202f565b90506000838210613d7757613d728285613132565b613d7a565b60005b905088158015613d88575087155b15613d965760009250613df2565b88613da357869250613df2565b871580613daf57508087105b15613dbc57809250613df2565b6000613dd082610cf58c611b178c8e61341e565b9050878111613dec5780613de5576001613de7565b805b613dee565b875b9350505b50509695505050505050565b3b151590565b600054610100900460ff1680613e1d5750613e1d612770565b80613e2b575060005460ff16155b613e665760405162461bcd60e51b815260040180806020018281038252602e815260200180615527602e913960400191505060405180910390fd5b600054610100900460ff161580156128cb576000805460ff1961ff0019909116610100171660011790558015610903576000805461ff001916905550565b600054610100900460ff1680613ebd5750613ebd612770565b80613ecb575060005460ff16155b613f065760405162461bcd60e51b815260040180806020018281038252602e815260200180615527602e913960400191505060405180910390fd5b600054610100900460ff16158015613f31576000805460ff1961ff0019909116610100171660011790555b8251613f44906036906020860190614114565b508151613f58906037906020850190614114565b506038805460ff19166012179055801561131a576000805461ff0019169055505050565b600054610100900460ff1680613f955750613f95612770565b80613fa3575060005460ff16155b613fde5760405162461bcd60e51b815260040180806020018281038252602e815260200180615527602e913960400191505060405180910390fd5b600054610100900460ff16158015614009576000805460ff1961ff0019909116610100171660011790555b60016065558015610903576000805461ff001916905550565b609c5460408051631758078b60e01b815290516000926001600160a01b031691631758078b916004808301926020929190829003018186803b15801561186b57600080fd5b604051806101a0016040528060608152602001600081526020016000815260200160006001600160a01b0316815260200160608152602001600081526020016000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b604051806040016040528060008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261414a5760008555614190565b82601f1061416357805160ff1916838001178555614190565b82800160010185558215614190579182015b82811115614190578251825591602001919060010190614175565b5061419c9291506141a0565b5090565b5b8082111561419c57600081556001016141a1565b60006141c86141c384615409565b6153c9565b90508281528383830111156141dc57600080fd5b6108dd83602083018461542a565b60008083601f8401126141fb578182fd5b5081356001600160401b03811115614211578182fd5b602083019150836020808302850101111561422b57600080fd5b9250929050565b600082601f830112614242578081fd5b815160206142526141c3836153ec565b82815281810190858301855b858110156142fb5781518801604080601f19838d0301121561427e578889fd5b80518181016001600160401b03828210818311171561429957fe5b90835283890151906142aa82615456565b9082528383015190808211156142be578b8cfd5b508084019350508b603f8401126142d357898afd5b6142e38c898501518486016141b5565b8189015286525050928401929084019060010161425e565b5090979650505050505050565b60008083601f840112614319578182fd5b5081356001600160401b0381111561432f578182fd5b60208301915083602082850101111561422b57600080fd5b600082601f830112614357578081fd5b81356143656141c382615409565b818152846020838601011115614379578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156143a4578081fd5b81356108dd81615456565b6000602082840312156143c0578081fd5b81516108dd81615456565b600080604083850312156143dd578081fd5b82356143e881615456565b915060208301356143f881615456565b809150509250929050565b600080600060608486031215614417578081fd5b833561442281615456565b9250602084013561443281615456565b929592945050506040919091013590565b60008060008060006080868803121561445a578283fd5b853561446581615456565b9450602086013561447581615456565b93506040860135925060608601356001600160401b03811115614496578182fd5b6144a288828901614308565b969995985093965092949392505050565b600080600080608085870312156144c8578182fd5b84356144d381615456565b935060208501356144e381615456565b93969395505050506040820135916060013590565b6000806000806080858703121561450d578182fd5b843561451881615456565b935060208501356145288161546b565b925060408501356001600160401b0380821115614543578384fd5b61454f88838901614347565b93506060870135915080821115614564578283fd5b5061457187828801614347565b91505092959194509250565b600080600060408486031215614591578081fd5b833561459c81615456565b925060208401356001600160401b038111156145b6578182fd5b6145c286828701614308565b9497909650939450505050565b600080604083850312156145e1578182fd5b82356145ec81615456565b946020939093013593505050565b60008060006060848603121561460e578081fd5b835161461981615456565b6020850151604086015191945092506001600160401b0381111561463b578182fd5b61464786828701614232565b9150509250925092565b600080600060608486031215614665578081fd5b833561467081615456565b95602085013595506040909401359392505050565b600080600080600080600080600060a08a8c0312156146a2578687fd5b89356001600160401b03808211156146b8578889fd5b6146c48d838e016141ea565b909b50995060208c01359150808211156146dc578889fd5b6146e88d838e016141ea565b909950975060408c0135915080821115614700578586fd5b61470c8d838e016141ea565b909750955060608c0135915061472182615456565b90935060808b01359080821115614736578384fd5b506147438c828d01614308565b915080935050809150509295985092959850929598565b6000602080838503121561476c578182fd5b82516001600160401b0380821115614782578384fd5b818501915085601f830112614795578384fd5b81516147a36141c3826153ec565b818152848101908486016040808502870188018b10156147c1578889fd5b8896505b848710156148245780828c0312156147db578889fd5b805181810181811088821117156147ee57fe5b825282516147fb81615456565b81528289015161480a8161546b565b818a015284526001969096019592870192908101906147c5565b50909998505050505050505050565b600060208284031215614844578081fd5b81516001600160401b03811115614859578182fd5b610cca84828501614232565b60008060208385031215614877578182fd5b82356001600160401b0381111561488c578283fd5b614898858286016141ea565b90969095509350505050565b6000602082840312156148b5578081fd5b81356108dd8161546b565b6000602082840312156148d1578081fd5b81516108dd8161546b565b6000602082840312156148ed578081fd5b81516001600160401b03811115614902578182fd5b8201601f81018413614912578182fd5b610cca848251602084016141b5565b60008060408385031215614933578182fd5b825161ffff81168114614944578283fd5b60208401519092506143f88161546b565b600060208284031215614966578081fd5b5035919050565b60006020828403121561497e578081fd5b5051919050565b60008060408385031215614997578182fd5b50508035926020909101359150565b600080604083850312156149b8578182fd5b505080516020909101519092909150565b600080600080600060a086880312156149e0578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b6001600160a01b03169052565b15159052565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452614a5d81602086016020860161542a565b601f01601f19169290920160200192915050565b60008251614a8381846020870161542a565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0392831681529116602082015260400190565b600061012080830160018060a01b03808e1685526020818e168187015260408d8188015260608d818901528c60808901528b60a08901528a60c08901528560e0890152849550895180865261014089019650838b019550875b81811015614b6957865180518716895285810151868a01528401511515848901529682019695840195600101614b38565b505050505061010094909401949094529b9a5050505050505050505050565b6001600160a01b039a8b168152988a1660208a01529690981660408801526060870194909452608086019290925260a085015260c084015260e08301526101008201929092526101208101919091526101400190565b6001600160a01b038481168252831660208201526060604082018190526000906115f590830184614a45565b6001600160a01b03948516815292909316602083015261ffff166040820152606081019190915260800190565b6001600160a01b03948516815292841660208401526040830191909152909116606082015260800190565b6001600160a01b038681168252851660208201526040810184905260806060820181905260009061114f9083018486614a1b565b6001600160a01b03878116825286166020820152604081018590526060810184905260a060808201819052600090614cd19083018486614a1b565b98975050505050505050565b6001600160a01b03968716815294909516602085015260408401929092526060830152608082015260a081019190915260c00190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b6001600160e01b031991909116815260200190565b61ffff91909116815260200190565b6000602082526108dd6020830184614a45565b6020808252601790820152761a5b9d985b1a59081b1a5c5d5a591a5d1e535a5b9d1959604a1b604082015260600190565b6020808252601290820152711391951cc81b9bdd081cdd5c1c1bdc9d195960721b604082015260600190565b6020808252600c908201526b1b9bdd081d995c9a599a595960a21b604082015260600190565b6020808252601390820152721b995959081dda5d1a191c985dc8185cdcd95d606a1b604082015260600190565b60208082526013908201527234b73b30b634b2103a3930b739b0b1ba34b7b760691b604082015260600190565b6020808252601390820152726f6e6c79206f776e65722c20666163746f727960681b604082015260600190565b6020808252600f908201526e636f6f6c646f776e2061637469766560881b604082015260600190565b6020808252601c908201527b6f6e6c79206d616e616765722c207472616465722c207075626c696360201b604082015260600190565b6020808252600c908201526b6f6e6c79206d656d6265727360a01b604082015260600190565b6020808252600c908201526b37b7363c9036b0b730b3b2b960a11b604082015260600190565b6020808252601290820152716e6f7420656e6f7567682062616c616e636560701b604082015260600190565b6020808252601b908201527a37b7363c903837b7b610333630b9b4103637b0b71037b934b3b4b760291b604082015260600190565b6020808252600f908201526e696e76616c6964206164647265737360881b604082015260600190565b6020808252600c908201526b1bdb9b1e48185b1b1bddd95960a21b604082015260600190565b6020808252600990820152681d1e0819985a5b195960ba1b604082015260600190565b60208082526010908201526f34b73b30b634b21031b7b7b63237bbb760811b604082015260600190565b6020808252600e908201526d185cdcd95d08191a5cd8589b195960921b604082015260600190565b602080825260119082015270696e76616c696420746f6c6572616e636560781b604082015260600190565b60208082526016908201527518995b1bddc81cdd5c1c1b1e481d1a1c995cda1bdb1960521b604082015260600190565b6020808252600d908201526c6869676820736c69707061676560981b604082015260600190565b6020808252601590820152741a5b9d985b1a590819195c1bdcda5d08185cdcd95d605a1b604082015260600190565b60208082526011908201527031b0b7103bb4ba34323930bb9039b7b7b760791b604082015260600190565b6020808252601690820152756869676820776974686472617720736c69707061676560501b604082015260600190565b60208082526010908201526f18dbdb9d1c9858dd1cc81c185d5cd95960821b604082015260600190565b6020808252600d908201526c1a5b9d985b1a590819dd585c99609a1b604082015260600190565b6020808252600b908201526a1c1bdbdb081c185d5cd95960aa1b604082015260600190565b60208082526010908201526f1b995959081b5a5b8819195c1bdcda5d60821b604082015260600190565b6020808252601490820152736f6e6c792067756172646564206164647265737360601b604082015260600190565b602080825260189082015277195e1a5d08199959481d1c985b9cd9995c8819985a5b195960421b604082015260600190565b6020808252601490820152731a5b9d985b1a59081b195b991a5b99c81c1bdbdb60621b604082015260600190565b60006020825282516101a08060208501526152a16101c0850183614a45565b9150602085015160408501526040850151606085015260608501516152c96080860182614a08565b506080850151848303601f190160a08601526152e58382614a45565b92505060a085015160c085015260c085015161530460e0860182614a15565b5060e08501516101008581019190915285015161012080860191909152850151610140808601919091528501516101608086019190915285015161018080860191909152909401519390920192909252919050565b90815260200190565b60ff91909116815260200190565b6000808335601e19843603018112615386578283fd5b8301803591506001600160401b0382111561539f578283fd5b60200191503681900382131561422b57600080fd5b60008235603e19833603018112614a83578182fd5b6040518181016001600160401b03811182821017156153e457fe5b604052919050565b60006001600160401b038211156153ff57fe5b5060209081020190565b60006001600160401b0382111561541c57fe5b50601f01601f191660200190565b60005b8381101561544557818101518382015260200161542d565b838111156120eb5750506000910152565b6001600160a01b038116811461090357600080fd5b801515811461090357600080fdfe45524332303a207472616e7366657220746f20746865207a65726f20616464726573735265656e7472616e637947756172643a207265656e7472616e742063616c6c0045524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef45524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa264697066735822122084aedf8d3bb9633b047774744da3b8288b869864af7c59c53cd93d6216a0911764736f6c63430007060033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101f35760003560e01c80637714f39d116101165780637714f39d1461038d5780637ae7cfb5146103955780637ff9b596146103a8578063920f5c84146103b057806394138e97146103c357806395d89b41146103d6578063a457c2d7146103de578063a77134e4146103f1578063a9059cbb146103f9578063a971a9131461040c578063aee883341461041f578063b3db428b14610432578063b8ea2b6e14610445578063c45a015514610458578063cc3c6df614610460578063d8270dce14610468578063dd62ed3e14610470578063de6eb13314610483578063df8164cf14610496578063df8ff12f146104a9578063e4262edd146104b1576101f3565b806302d05d3f146101f857806306fdde0314610216578063095ea7b31461022b578063150b7a021461024b57806318160ddd1461026b5780631c5918d2146102805780631e50a4a614610295578063205c28781461029d57806323b872dd146102b257806329d16ee8146102c55780632e1a7d4d146102d8578063313ce567146102eb57806339509351146103005780633babaad51461031357806347e7ef24146103265780635426f81d1461033957806359b5e75e1461034c57806370a08231146103545780637481de6614610367578063750226de1461037a575b600080fd5b6102006104c4565b60405161020d9190614a8d565b60405180910390f35b61021e6104d8565b60405161020d9190614d5b565b61023e6102393660046145cf565b61056e565b60405161020d9190614d2c565b61025e610259366004614443565b61058c565b60405161020d9190614d37565b6102736106f7565b60405161020d9190615359565b6102886106fd565b60405161020d9190615282565b61020061083c565b6102b06102ab3660046145cf565b61084b565b005b61023e6102c0366004614403565b61085c565b6102736102d3366004614393565b6108e4565b6102b06102e6366004614955565b6108f6565b6102f3610906565b60405161020d9190615362565b61023e61030e3660046145cf565b61090f565b6102b06103213660046148a4565b61095d565b6102736103343660046145cf565b6109e3565b6102b06103473660046144f8565b6109f8565b61023e610aff565b610273610362366004614393565b610b08565b610273610375366004614393565b610b27565b6102b0610388366004614393565b610b39565b610273610c82565b61023e6103a336600461457d565b610c88565b610273610cd2565b61023e6103be366004614685565b610d0e565b6102736103d1366004614955565b611113565b61021e61115a565b61023e6103ec3660046145cf565b6111bb565b610273611223565b61023e6104073660046145cf565b611242565b6102b061041a366004614865565b611256565b61027361042d366004614393565b61131f565b610273610440366004614403565b611331565b610273610453366004614393565b611341565b61020061138f565b6102b061139e565b6102736114e6565b61027361047e3660046143cb565b6114ec565b6102736104913660046144b3565b611517565b6102b06104a4366004614985565b6115fe565b610273611609565b6102b06104bf366004614651565b61160f565b60975461010090046001600160a01b031681565b60368054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105645780601f1061053957610100808354040283529160200191610564565b820191906000526020600020905b81548152906001019060200180831161054757829003601f168201915b5050505050905090565b600061058261057b61161a565b848461161e565b5060015b92915050565b609954604051634f8419b960e01b815260009182916001600160a01b0390911690634f8419b9906105c1908a90600401614a8d565b60206040518083038186803b1580156105d957600080fd5b505afa1580156105ed573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061191906143af565b90506001600160a01b0381166106425760405162461bcd60e51b8152600401610639906151f4565b60405180910390fd5b6040516306baeff360e11b81526001600160a01b03821690630d75dfe690610676908a908a908a908a908a90600401614c62565b602060405180830381600087803b15801561069057600080fd5b505af11580156106a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106c891906148c0565b6106e45760405162461bcd60e51b815260040161063990614dcb565b50630a85bd0160e11b9695505050505050565b60355490565b610705614067565b600080600080600061071561170a565b94509450945094509450604051806101a001604052806107336104d8565b81526020016107406106f7565b815260200161074d6117a9565b815260200161075a611826565b6001600160a01b03168152602001609c60009054906101000a90046001600160a01b03166001600160a01b031663fed4416a6040518163ffffffff1660e01b815260040160006040518083038186803b1580156107b657600080fd5b505afa1580156107ca573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107f291908101906148dc565b8152609854602082015260975460ff16151560408201526060810196909652608086019490945260a0850181905260c085019190915260e084015261010090920191909152905090565b609c546001600160a01b031681565b61085882826127106118a3565b5050565b6000610869848484611e4d565b6108d98461087561161a565b6108d485604051806060016040528060288152602001615576602891396001600160a01b038a166000908152603460205260408120906108b361161a565b6001600160a01b031681526020810191909152604001600020549190611f98565b61161e565b5060015b9392505050565b609b6020526000908152604090205481565b61090333826127106118a3565b50565b60385460ff1690565b600061058261091c61161a565b846108d4856034600061092d61161a565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549061202f565b610965611826565b6001600160a01b0316336001600160a01b0316146109955760405162461bcd60e51b815260040161063990614efd565b6097805460ff19168215151790556040517f8d75e9ede4188432084b863d70b3416010c97547dfeb4fc17734d2e997ee0f39906109d3908390614d2c565b60405180910390a1610903612087565b60006108dd3384846109f36120f1565b612136565b600054610100900460ff1680610a115750610a11612770565b80610a1f575060005460ff16155b610a5a5760405162461bcd60e51b815260040180806020018281038252602e815260200180615527602e913960400191505060405180910390fd5b600054610100900460ff16158015610a85576000805460ff1961ff0019909116610100171660011790555b610a8f8383612781565b610a97612836565b609980546001600160a01b0319166001600160a01b0387161790556097805460ff191685151517610100600160a81b0319166101003302179055426098819055609e55670de0b6b3a7640000609a558015610af8576000805461ff00191690555b5050505050565b60975460ff1681565b6001600160a01b0381166000908152603360205260409020545b919050565b609f6020526000908152604090205481565b6001600160a01b038116610b5f5760405162461bcd60e51b815260040161063990614f84565b6099546001600160a01b0316331480610c0e5750609960009054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610bc157600080fd5b505afa158015610bd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf991906143af565b6001600160a01b0316336001600160a01b0316145b610c2a5760405162461bcd60e51b815260040161063990614e4b565b609c80546001600160a01b0319166001600160a01b0383161790556040517f63fb64c359a4cae97e1bf003c1ab11390b5f0e18cc5b3d67b90bd61c0f5c52fd90610c779083903390614ac5565b60405180910390a150565b609a5481565b6000610cca8484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506128df92505050565b949350505050565b600080610cdd6117a9565b90506000610cfb610ced83611113565b610cf56106f7565b9061202f565b9050610d078282612fed565b9250505090565b60006001600160a01b0384163014610d385760405162461bcd60e51b815260040161063990614f4f565b609954604051633f30232f60e21b81526000916001600160a01b03169063fcc08cbc90610d69903390600401614a8d565b60206040518083038186803b158015610d8157600080fd5b505afa158015610d95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db991906143af565b90506001600160a01b03811615801590610e545750806001600160a01b031663e9d337b86040518163ffffffff1660e01b815260040160206040518083038186803b158015610e0757600080fd5b505afa158015610e1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e3f91906143af565b6001600160a01b0316336001600160a01b0316145b610e705760405162461bcd60e51b815260040161063990615254565b60008b8b6000818110610e7f57fe5b9050602002016020810190610e949190614393565b6001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610ebf9190614a8d565b60206040518083038186803b158015610ed757600080fd5b505afa158015610eeb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0f919061496d565b90506000826001600160a01b031663989dccf8308f8f6000818110610f3057fe5b9050602002016020810190610f459190614393565b8e8e6000818110610f5257fe5b905060200201358d8d6000818110610f6657fe5b905060200201358b8b6040518763ffffffff1660e01b8152600401610f9096959493929190614c96565b60006040518083038186803b158015610fa857600080fd5b505afa158015610fbc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610fe49190810190614833565b905060005b81518110156110465761103c82828151811061100157fe5b60200260200101516020015183838151811061101957fe5b6020026020010151600001516001600160a01b031661301d90919063ffffffff16565b9450600101610fe9565b508c8c600081811061105457fe5b90506020020160208101906110699190614393565b6001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016110949190614a8d565b60206040518083038186803b1580156110ac57600080fd5b505afa1580156110c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e4919061496d565b8211156111035760405162461bcd60e51b8152600401610639906150a3565b5050509998505050505050505050565b60008060008061112161170a565b9450505092509250600080611140876111386106f7565b878787613050565b909250905061114f828261202f565b979650505050505050565b60378054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105645780601f1061053957610100808354040283529160200191610564565b60006105826111c861161a565b846108d48560405180606001604052806025815260200161562860259139603460006111f261161a565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190611f98565b600061123d6112306117a9565b6112386106f7565b612fed565b905090565b600061058261124f61161a565b8484611e4d565b60005b8181101561131a576112f683838381811061127057fe5b905060200281019061128291906153b4565b611290906020810190614393565b84848481811061129c57fe5b90506020028101906112ae91906153b4565b6112bc906020810190615370565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506128df92505050565b6113125760405162461bcd60e51b815260040161063990614fd3565b600101611259565b505050565b609d6020526000908152604090205481565b6000610cca8484846109f36120f1565b6001600160a01b0381166000908152609f6020908152604080832054609b9092528220548291611371919061202f565b905042811015611385576000915050610b22565b6108dd8142613132565b6099546001600160a01b031681565b609960009054906101000a90046001600160a01b03166001600160a01b031663b187bd266040518163ffffffff1660e01b815260040160206040518083038186803b1580156113ec57600080fd5b505afa158015611400573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142491906148c0565b156114415760405162461bcd60e51b815260040161063990615154565b60995460405163cdf04c0760e01b81526001600160a01b039091169063cdf04c0790611471903090600401614a8d565b60206040518083038186803b15801561148957600080fd5b505afa15801561149d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c191906148c0565b156114de5760405162461bcd60e51b8152600401610639906151a5565b61090361318f565b60985481565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b609954604051632927233b60e01b81526000916001600160a01b031690632927233b90611548903390600401614a8d565b60206040518083038186803b15801561156057600080fd5b505afa158015611574573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159891906148c0565b6115b45760405162461bcd60e51b815260040161063990614fad565b61012c82101580156115cd57506115c96120f1565b8211155b6115e95760405162461bcd60e51b815260040161063990614ff6565b6115f585858585612136565b95945050505050565b6108583383836118a3565b609e5481565b61131a8383836118a3565b3390565b6001600160a01b0383166116635760405162461bcd60e51b81526004018080602001828103825260248152602001806156046024913960400191505060405180910390fd5b6001600160a01b0382166116a85760405162461bcd60e51b81526004018080602001828103825260228152602001806154df6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260346020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6000806000806000609c60009054906101000a90046001600160a01b03166001600160a01b031663ced72f876040518163ffffffff1660e01b815260040160a06040518083038186803b15801561176057600080fd5b505afa158015611774573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061179891906149c9565b939992985090965094509092509050565b609c5460408051632b583ff360e21b815290516000926001600160a01b03169163ad60ffcc916004808301926020929190829003018186803b1580156117ee57600080fd5b505afa158015611802573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123d919061496d565b609c546040805163481c6a7560e01b815290516000926001600160a01b03169163481c6a75916004808301926020929190829003018186803b15801561186b57600080fd5b505afa15801561187f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123d91906143af565b600260655414156118e9576040805162461bcd60e51b815260206004820152601f602482015260008051602061549d833981519152604482015290519081900360640190fd5b6002606555609954604080516358c3de9360e11b815290516001600160a01b039092169163b187bd2691600480820192602092909190829003018186803b15801561193357600080fd5b505afa158015611947573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196b91906148c0565b156119885760405162461bcd60e51b815260040161063990615154565b60995460405163cdf04c0760e01b81526001600160a01b039091169063cdf04c07906119b8903090600401614a8d565b60206040518083038186803b1580156119d057600080fd5b505afa1580156119e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0891906148c0565b15611a255760405162461bcd60e51b8152600401610639906151a5565b336000908152609b60205260409020544211611a535760405162461bcd60e51b8152600401610639906150f9565b81611a5d33610b08565b1015611a7b5760405162461bcd60e51b815260040161063990614f23565b612710811115611a9d5760405162461bcd60e51b815260040161063990615048565b6000611ab183611aab6106f7565b90613132565b9050620186a081101580611ac3575080155b611adf5760405162461bcd60e51b815260040161063990615073565b506000611aea61318f565b9050600080611af761170a565b945094505050506000821115611b5a576000611b1d82611b17888661341e565b90613477565b9050611b298682613132565b9550611b3c611b36611826565b82611242565b611b585760405162461bcd60e51b815260040161063990615222565b505b50506000611b7b611b696106f7565b611b1786670de0b6b3a764000061341e565b9050611b8733856134db565b611b8f6106f7565b611ba057670de0b6b3a7640000609a555b609c546040805163e5406dbf60e01b815290516000926001600160a01b03169163e5406dbf9160048083019286929190829003018186803b158015611be457600080fd5b505afa158015611bf8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c20919081019061475a565b9050600081516001600160401b0381118015611c3b57600080fd5b50604051908082528060200260200182016040528015611c7557816020015b611c626140da565b815260200190600190039081611c5a5790505b5090506000805b8351811015611da2576000806000611cad878581518110611c9957fe5b6020026020010151600001518d8a8d6135c5565b919450925090508115611d42576001600160a01b038316611ce05760405162461bcd60e51b815260040161063990614df1565b611d4063a9059cbb60e01b8d84604051602401611cfe929190614d13565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526001600160a01b0385169061301d565b505b8080611d4e5750600082115b15611d97576040518060600160405280846001600160a01b03168152602001838152602001821515815250868681518110611d8557fe5b60209081029190910101526001909401935b505050600101611c7c565b508251600090611db29083613132565b8351819003845290506000611dd3670de0b6b3a7640000611b17888a61341e565b90507ffad3d7f9ed107ffa7fc8ce8baa521effc3650ec48a4d1dd36bdb9c4b91db12953033838c611e0333610b08565b611e0d8d88613132565b611e156106f7565b8b42604051611e2c99989796959493929190614adf565b60405180910390a1611e3c612087565b505060016065555050505050505050565b6001600160a01b038316611e925760405162461bcd60e51b81526004018080602001828103825260258152602001806155df6025913960400191505060405180910390fd5b6001600160a01b038216611ed75760405162461bcd60e51b815260040180806020018281038252602381526020018061547a6023913960400191505060405180910390fd5b611ee2838383613a55565b611f1f81604051806060016040528060268152602001615501602691396001600160a01b0386166000908152603360205260409020549190611f98565b6001600160a01b038085166000908152603360205260408082209390935590841681522054611f4e908261202f565b6001600160a01b03808416600081815260336020908152604091829020949094558051858152905191939287169260008051602061559e83398151915292918290030190a3505050565b600081848411156120275760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611fec578181015183820152602001611fd4565b50505050905090810190601f1680156120195780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000828201838110156108dd576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b609960009054906101000a90046001600160a01b03166001600160a01b03166325c4121b6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156120d757600080fd5b505af11580156120eb573d6000803e3d6000fd5b50505050565b609954604080516308a0361160e31b815290516000926001600160a01b031691634501b088916004808301926020929190829003018186803b1580156117ee57600080fd5b60006002606554141561217e576040805162461bcd60e51b815260206004820152601f602482015260008051602061549d833981519152604482015290519081900360640190fd5b6002606555609954604080516358c3de9360e11b815290516001600160a01b039092169163b187bd2691600480820192602092909190829003018186803b1580156121c857600080fd5b505afa1580156121dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220091906148c0565b1561221d5760405162461bcd60e51b815260040161063990615154565b60995460405163cdf04c0760e01b81526001600160a01b039091169063cdf04c079061224d903090600401614a8d565b60206040518083038186803b15801561226557600080fd5b505afa158015612279573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229d91906148c0565b156122ba5760405162461bcd60e51b8152600401610639906151a5565b6122c2611826565b6001600160a01b0316856001600160a01b031614806122e4575060975460ff16155b806122f357506122f385613b6c565b61230f5760405162461bcd60e51b815260040161063990614ed7565b609c5460405163bdbef07d60e01b81526001600160a01b039091169063bdbef07d9061233f908790600401614a8d565b60206040518083038186803b15801561235757600080fd5b505afa15801561236b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238f91906148c0565b6123ab5760405162461bcd60e51b8152600401610639906150ca565b600080856001600160a01b03166175306301ffc9a760e01b6380ac58cd60e01b6040516024016123db9190614d37565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516124199190614a71565b6000604051808303818686fa925050503d8060008114612455576040519150601f19603f3d011682016040523d82523d6000602084013e61245a565b606091505b509150915081158061247d57508080602001905181019061247b91906148c0565b155b6124995760405162461bcd60e51b815260040161063990614d9f565b505060006124a561318f565b905060006124b16106f7565b90506125156323b872dd60e01b3330886040516024016124d393929190614aa1565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526001600160a01b0388169061301d565b5060006125228787613bed565b9050811561253f5761253883611b17838561341e565b9350612543565b8093505b60008061254e61170a565b94505093505050600082111561258f57600061256e82611b17898661341e565b905061257a8782613132565b965061258d612587611826565b82613c70565b505b620186a08610156125b25760405162461bcd60e51b815260040161063990614d6e565b6125bc8a87613c70565b50506125f96125ca89610b08565b6001600160a01b038a166000908152609f6020908152604080832054609b909252909120548791899142613d50565b6001600160a01b0389166000908152609f6020908152604080832093909355609b905290812042905561262b89610b08565b90506000612639858461202f565b905060006126456106f7565b9050609c60009054906101000a90046001600160a01b03166001600160a01b03166350b721a76040518163ffffffff1660e01b815260040160206040518083038186803b15801561269557600080fd5b505afa1580156126a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126cd919061496d565b6126ed670de0b6b3a7640000611b176126e68686612fed565b879061341e565b101561270b5760405162461bcd60e51b8152600401610639906151ca565b7f97e6c213c123075e233a6f2323f33d8319141b993ab05e9e2f7eb2eda08cb944308c8c8c888c8989894260405161274c9a99989796959493929190614b88565b60405180910390a15061275d612087565b5050600160655550919695505050505050565b600061277b30613dfe565b15905090565b600054610100900460ff168061279a575061279a612770565b806127a8575060005460ff16155b6127e35760405162461bcd60e51b815260040180806020018281038252602e815260200180615527602e913960400191505060405180910390fd5b600054610100900460ff1615801561280e576000805460ff1961ff0019909116610100171660011790555b612816613e04565b6128208383613ea4565b801561131a576000805461ff0019169055505050565b600054610100900460ff168061284f575061284f612770565b8061285d575060005460ff16155b6128985760405162461bcd60e51b815260040180806020018281038252602e815260200180615527602e913960400191505060405180910390fd5b600054610100900460ff161580156128c3576000805460ff1961ff0019909116610100171660011790555b6128cb613f7c565b8015610903576000805461ff001916905550565b600060026065541415612927576040805162461bcd60e51b815260206004820152601f602482015260008051602061549d833981519152604482015290519081900360640190fd5b6002606555609954604080516358c3de9360e11b815290516001600160a01b039092169163b187bd2691600480820192602092909190829003018186803b15801561297157600080fd5b505afa158015612985573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129a991906148c0565b156129c65760405162461bcd60e51b815260040161063990615154565b6001600160a01b0383166129ec5760405162461bcd60e51b815260040161063990614f84565b609954604051634f8419b960e01b81526000916001600160a01b031690634f8419b990612a1d908790600401614a8d565b60206040518083038186803b158015612a3557600080fd5b505afa158015612a49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a6d91906143af565b905060008080806001600160a01b03851615612b1357609c54604051636179309d60e01b81528694506001600160a01b0380861692636179309d92612abc92909116908c908c90600401614bde565b6040805180830381600087803b158015612ad557600080fd5b505af1158015612ae9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b0d9190614921565b90925090505b61ffff8216612ddc57609954604051633f30232f60e21b81526001600160a01b039091169063fcc08cbc90612b4c908b90600401614a8d565b60206040518083038186803b158015612b6457600080fd5b505afa158015612b78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b9c91906143af565b93506001600160a01b038416612cb0576099546040805163795053d360e01b815290516000926001600160a01b03169163795053d3916004808301926020929190829003018186803b158015612bf157600080fd5b505afa158015612c05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c2991906143af565b60405162a950c360e81b81529091506001600160a01b0382169063a950c30090612c5890600090600401614d4c565b60206040518083038186803b158015612c7057600080fd5b505afa158015612c84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ca891906143af565b945050612d4c565b609c54604051634df48c7360e11b81526001600160a01b0390911690639be918e690612ce0908b90600401614a8d565b60206040518083038186803b158015612cf857600080fd5b505afa158015612d0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d3091906148c0565b612d4c5760405162461bcd60e51b815260040161063990615020565b609c54604051636179309d60e01b81528594506001600160a01b0380861692636179309d92612d8592909116908c908c90600401614bde565b6040805180830381600087803b158015612d9e57600080fd5b505af1158015612db2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dd69190614921565b90925090505b60008261ffff1611612e005760405162461bcd60e51b815260040161063990614e1e565b8080612e245750612e0f611826565b6001600160a01b0316336001600160a01b0316145b80612e475750612e32614022565b6001600160a01b0316336001600160a01b0316145b612e635760405162461bcd60e51b815260040161063990614ea1565b612e766001600160a01b0389168861301d565b60408051600481526024810182526020810180516001600160e01b0316637bf9811960e01b179052905191975060009182916001600160a01b03871691612ebd9190614a71565b6000604051808303816000865af19150503d8060008114612efa576040519150601f19603f3d011682016040523d82523d6000602084013e612eff565b606091505b5091509150818015612f20575080806020019051810190612f2091906148c0565b15612f8e57609c54604051637b364ee960e11b81526001600160a01b038781169263f66c9dd292612f5b92909116908e908e90600401614bde565b600060405180830381600087803b158015612f7557600080fd5b505af1158015612f89573d6000803e3d6000fd5b505050505b7f14464fb67b1871a79e726fa7af525f8fff56e9e5649d511e47f3a357ae31d20730612fb8611826565b8642604051612fca9493929190614c0a565b60405180910390a1612fda612087565b5050600160655550939695505050505050565b6000811580612ffa575082155b1561300757506000610586565b6108dd82611b1785670de0b6b3a764000061341e565b60008060008351602085016000875af1905080156001811461303e57613049565b3d806000803e806000fd5b5092915050565b60008085158061305e575086155b1561306e57506000905080613128565b600061308687611b178a670de0b6b3a764000061341e565b9050609a548111156130e95760006130cc6130a986670de0b6b3a764000061341e565b611b178a6130c68b6130c6609a548961313290919063ffffffff16565b9061341e565b90506130e56130db8a83613132565b611b17838b61341e565b9350505b609e5415613126576000613108609e544261313290919063ffffffff16565b90506131226301e13380611b1787818a6130c68e8861341e565b9250505b505b9550959350505050565b600082821115613189576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b609c54604080516335fd4a6360e11b815290516000926001600160a01b031691636bfa94c691600480830192602092919082900301818787803b1580156131d557600080fd5b505af11580156131e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061320d919061496d565b905060006132196106f7565b9050600080600061322861170a565b94505050925092506000806132408787878787613050565b90925090506000613251838361202f565b6099546040805163272b69b960e21b8152815193945060009384936001600160a01b031692639cada6e49260048082019391829003018186803b15801561329757600080fd5b505afa1580156132ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132cf91906149a6565b909250905060006132e482611b17868661341e565b905060006132f28583613132565b905060006133008d8d612fed565b905080609a54101561331257609a8190555b861561331d5742609e555b82156133a7576099546040805163084c71a360e21b815290516133a7926001600160a01b031691632131c68c916004808301926020929190829003018186803b15801561336957600080fd5b505afa15801561337d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133a191906143af565b84613c70565b81156133be576133be6133b8611826565b83613c70565b7f755a8059d66d8d243bc9f6913f429a811f154599d0538bb0b6a2ac23f23d2ccd306133e8611826565b609a546040516133ff9392918b9189918991614cdd565b60405180910390a161340f612087565b50505050505050505050505090565b60008261342d57506000610586565b8282028284828161343a57fe5b04146108dd5760405162461bcd60e51b81526004018080602001828103825260218152602001806155556021913960400191505060405180910390fd5b60008082116134ca576040805162461bcd60e51b815260206004820152601a602482015279536166654d6174683a206469766973696f6e206279207a65726f60301b604482015290519081900360640190fd5b8183816134d357fe5b049392505050565b6001600160a01b0382166135205760405162461bcd60e51b81526004018080602001828103825260218152602001806155be6021913960400191505060405180910390fd5b61352c82600083613a55565b613569816040518060600160405280602281526020016154bd602291396001600160a01b0385166000908152603360205260409020549190611f98565b6001600160a01b03831660009081526033602052604090205560355461358f9082613132565b6035556040805182815290516000916001600160a01b0385169160008051602061559e8339815191529181900360200190a35050565b609954604051633f30232f60e21b81526000918291829182916001600160a01b039091169063fcc08cbc906135fe908b90600401614a8d565b60206040518083038186803b15801561361657600080fd5b505afa15801561362a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061364e91906143af565b90506001600160a01b0381166136765760405162461bcd60e51b81526004016106399061517e565b61367e6140fa565b61370c670de0b6b3a7640000611b1789856001600160a01b031663d4fac45d308f6040518363ffffffff1660e01b81526004016136bc929190614ac5565b60206040518083038186803b1580156136d457600080fd5b505afa1580156136e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130c6919061496d565b80825261371a908a90613bed565b8160200181815250506000806000846001600160a01b0316636f8ae202308e8d8f6040518563ffffffff1660e01b815260040161375a9493929190614c37565b600060405180830381600087803b15801561377457600080fd5b505af1158015613788573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526137b091908101906145fa565b8051929550909350915080156139375760006001600160a01b03851615613850576040516370a0823160e01b81526001600160a01b038616906370a08231906137fd903090600401614a8d565b60206040518083038186803b15801561381557600080fd5b505afa158015613829573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061384d919061496d565b90505b60005b8281101561388c5761388284828151811061386a57fe5b60200260200101516020015185838151811061101957fe5b9850600101613853565b506001600160a01b03851615613935576040516370a0823160e01b81526000906001600160a01b038716906370a08231906138cb903090600401614a8d565b60206040518083038186803b1580156138e357600080fd5b505afa1580156138f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061391b919061496d565b905061393161392a8284613132565b869061202f565b9450505b505b60408051600481526024810182526020810180516001600160e01b0316631f32d1a360e11b179052905160009182916001600160a01b038a169161397a91614a71565b6000604051808303816000865af19150503d80600081146139b7576040519150601f19603f3d011682016040523d82523d6000602084013e6139bc565b606091505b50915091508180156139dd5750808060200190518101906139dd91906148c0565b80156139f157506001600160a01b03861615155b15613a3f57613a17612710611b178e612710038a6020015161341e90919063ffffffff16565b613a218787613bed565b1015613a3f5760405162461bcd60e51b815260040161063990615124565b5093985091965050505050509450945094915050565b613a6083838361131a565b6001600160a01b038316613a735761131a565b60975460ff161580613a895750613a8982613b6c565b80613a9b57506001600160a01b038216155b613ab75760405162461bcd60e51b815260040161063990614ed7565b609954604051637065accb60e11b81526001600160a01b039091169063e0cb599690613ae7908590600401614a8d565b60206040518083038186803b158015613aff57600080fd5b505afa158015613b13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b3791906148c0565b151560011415613b465761131a565b613b4f83611341565b1561131a5760405162461bcd60e51b815260040161063990614e78565b609c5460405163bbbf725b60e01b81526000916001600160a01b03169063bbbf725b90613b9d908590600401614a8d565b60206040518083038186803b158015613bb557600080fd5b505afa158015613bc9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058691906148c0565b609c546040516314e03fdd60e11b81526000916001600160a01b0316906329c07fba90613c209086908690600401614d13565b60206040518083038186803b158015613c3857600080fd5b505afa158015613c4c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108dd919061496d565b6001600160a01b038216613ccb576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b613cd760008383613a55565b603554613ce4908261202f565b6035556001600160a01b038216600090815260336020526040902054613d0a908261202f565b6001600160a01b038316600081815260336020908152604080832094909455835185815293519293919260008051602061559e8339815191529281900390910190a35050565b600080613d5d848661202f565b90506000838210613d7757613d728285613132565b613d7a565b60005b905088158015613d88575087155b15613d965760009250613df2565b88613da357869250613df2565b871580613daf57508087105b15613dbc57809250613df2565b6000613dd082610cf58c611b178c8e61341e565b9050878111613dec5780613de5576001613de7565b805b613dee565b875b9350505b50509695505050505050565b3b151590565b600054610100900460ff1680613e1d5750613e1d612770565b80613e2b575060005460ff16155b613e665760405162461bcd60e51b815260040180806020018281038252602e815260200180615527602e913960400191505060405180910390fd5b600054610100900460ff161580156128cb576000805460ff1961ff0019909116610100171660011790558015610903576000805461ff001916905550565b600054610100900460ff1680613ebd5750613ebd612770565b80613ecb575060005460ff16155b613f065760405162461bcd60e51b815260040180806020018281038252602e815260200180615527602e913960400191505060405180910390fd5b600054610100900460ff16158015613f31576000805460ff1961ff0019909116610100171660011790555b8251613f44906036906020860190614114565b508151613f58906037906020850190614114565b506038805460ff19166012179055801561131a576000805461ff0019169055505050565b600054610100900460ff1680613f955750613f95612770565b80613fa3575060005460ff16155b613fde5760405162461bcd60e51b815260040180806020018281038252602e815260200180615527602e913960400191505060405180910390fd5b600054610100900460ff16158015614009576000805460ff1961ff0019909116610100171660011790555b60016065558015610903576000805461ff001916905550565b609c5460408051631758078b60e01b815290516000926001600160a01b031691631758078b916004808301926020929190829003018186803b15801561186b57600080fd5b604051806101a0016040528060608152602001600081526020016000815260200160006001600160a01b0316815260200160608152602001600081526020016000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b604051806040016040528060008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261414a5760008555614190565b82601f1061416357805160ff1916838001178555614190565b82800160010185558215614190579182015b82811115614190578251825591602001919060010190614175565b5061419c9291506141a0565b5090565b5b8082111561419c57600081556001016141a1565b60006141c86141c384615409565b6153c9565b90508281528383830111156141dc57600080fd5b6108dd83602083018461542a565b60008083601f8401126141fb578182fd5b5081356001600160401b03811115614211578182fd5b602083019150836020808302850101111561422b57600080fd5b9250929050565b600082601f830112614242578081fd5b815160206142526141c3836153ec565b82815281810190858301855b858110156142fb5781518801604080601f19838d0301121561427e578889fd5b80518181016001600160401b03828210818311171561429957fe5b90835283890151906142aa82615456565b9082528383015190808211156142be578b8cfd5b508084019350508b603f8401126142d357898afd5b6142e38c898501518486016141b5565b8189015286525050928401929084019060010161425e565b5090979650505050505050565b60008083601f840112614319578182fd5b5081356001600160401b0381111561432f578182fd5b60208301915083602082850101111561422b57600080fd5b600082601f830112614357578081fd5b81356143656141c382615409565b818152846020838601011115614379578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156143a4578081fd5b81356108dd81615456565b6000602082840312156143c0578081fd5b81516108dd81615456565b600080604083850312156143dd578081fd5b82356143e881615456565b915060208301356143f881615456565b809150509250929050565b600080600060608486031215614417578081fd5b833561442281615456565b9250602084013561443281615456565b929592945050506040919091013590565b60008060008060006080868803121561445a578283fd5b853561446581615456565b9450602086013561447581615456565b93506040860135925060608601356001600160401b03811115614496578182fd5b6144a288828901614308565b969995985093965092949392505050565b600080600080608085870312156144c8578182fd5b84356144d381615456565b935060208501356144e381615456565b93969395505050506040820135916060013590565b6000806000806080858703121561450d578182fd5b843561451881615456565b935060208501356145288161546b565b925060408501356001600160401b0380821115614543578384fd5b61454f88838901614347565b93506060870135915080821115614564578283fd5b5061457187828801614347565b91505092959194509250565b600080600060408486031215614591578081fd5b833561459c81615456565b925060208401356001600160401b038111156145b6578182fd5b6145c286828701614308565b9497909650939450505050565b600080604083850312156145e1578182fd5b82356145ec81615456565b946020939093013593505050565b60008060006060848603121561460e578081fd5b835161461981615456565b6020850151604086015191945092506001600160401b0381111561463b578182fd5b61464786828701614232565b9150509250925092565b600080600060608486031215614665578081fd5b833561467081615456565b95602085013595506040909401359392505050565b600080600080600080600080600060a08a8c0312156146a2578687fd5b89356001600160401b03808211156146b8578889fd5b6146c48d838e016141ea565b909b50995060208c01359150808211156146dc578889fd5b6146e88d838e016141ea565b909950975060408c0135915080821115614700578586fd5b61470c8d838e016141ea565b909750955060608c0135915061472182615456565b90935060808b01359080821115614736578384fd5b506147438c828d01614308565b915080935050809150509295985092959850929598565b6000602080838503121561476c578182fd5b82516001600160401b0380821115614782578384fd5b818501915085601f830112614795578384fd5b81516147a36141c3826153ec565b818152848101908486016040808502870188018b10156147c1578889fd5b8896505b848710156148245780828c0312156147db578889fd5b805181810181811088821117156147ee57fe5b825282516147fb81615456565b81528289015161480a8161546b565b818a015284526001969096019592870192908101906147c5565b50909998505050505050505050565b600060208284031215614844578081fd5b81516001600160401b03811115614859578182fd5b610cca84828501614232565b60008060208385031215614877578182fd5b82356001600160401b0381111561488c578283fd5b614898858286016141ea565b90969095509350505050565b6000602082840312156148b5578081fd5b81356108dd8161546b565b6000602082840312156148d1578081fd5b81516108dd8161546b565b6000602082840312156148ed578081fd5b81516001600160401b03811115614902578182fd5b8201601f81018413614912578182fd5b610cca848251602084016141b5565b60008060408385031215614933578182fd5b825161ffff81168114614944578283fd5b60208401519092506143f88161546b565b600060208284031215614966578081fd5b5035919050565b60006020828403121561497e578081fd5b5051919050565b60008060408385031215614997578182fd5b50508035926020909101359150565b600080604083850312156149b8578182fd5b505080516020909101519092909150565b600080600080600060a086880312156149e0578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b6001600160a01b03169052565b15159052565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452614a5d81602086016020860161542a565b601f01601f19169290920160200192915050565b60008251614a8381846020870161542a565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0392831681529116602082015260400190565b600061012080830160018060a01b03808e1685526020818e168187015260408d8188015260608d818901528c60808901528b60a08901528a60c08901528560e0890152849550895180865261014089019650838b019550875b81811015614b6957865180518716895285810151868a01528401511515848901529682019695840195600101614b38565b505050505061010094909401949094529b9a5050505050505050505050565b6001600160a01b039a8b168152988a1660208a01529690981660408801526060870194909452608086019290925260a085015260c084015260e08301526101008201929092526101208101919091526101400190565b6001600160a01b038481168252831660208201526060604082018190526000906115f590830184614a45565b6001600160a01b03948516815292909316602083015261ffff166040820152606081019190915260800190565b6001600160a01b03948516815292841660208401526040830191909152909116606082015260800190565b6001600160a01b038681168252851660208201526040810184905260806060820181905260009061114f9083018486614a1b565b6001600160a01b03878116825286166020820152604081018590526060810184905260a060808201819052600090614cd19083018486614a1b565b98975050505050505050565b6001600160a01b03968716815294909516602085015260408401929092526060830152608082015260a081019190915260c00190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b6001600160e01b031991909116815260200190565b61ffff91909116815260200190565b6000602082526108dd6020830184614a45565b6020808252601790820152761a5b9d985b1a59081b1a5c5d5a591a5d1e535a5b9d1959604a1b604082015260600190565b6020808252601290820152711391951cc81b9bdd081cdd5c1c1bdc9d195960721b604082015260600190565b6020808252600c908201526b1b9bdd081d995c9a599a595960a21b604082015260600190565b6020808252601390820152721b995959081dda5d1a191c985dc8185cdcd95d606a1b604082015260600190565b60208082526013908201527234b73b30b634b2103a3930b739b0b1ba34b7b760691b604082015260600190565b6020808252601390820152726f6e6c79206f776e65722c20666163746f727960681b604082015260600190565b6020808252600f908201526e636f6f6c646f776e2061637469766560881b604082015260600190565b6020808252601c908201527b6f6e6c79206d616e616765722c207472616465722c207075626c696360201b604082015260600190565b6020808252600c908201526b6f6e6c79206d656d6265727360a01b604082015260600190565b6020808252600c908201526b37b7363c9036b0b730b3b2b960a11b604082015260600190565b6020808252601290820152716e6f7420656e6f7567682062616c616e636560701b604082015260600190565b6020808252601b908201527a37b7363c903837b7b610333630b9b4103637b0b71037b934b3b4b760291b604082015260600190565b6020808252600f908201526e696e76616c6964206164647265737360881b604082015260600190565b6020808252600c908201526b1bdb9b1e48185b1b1bddd95960a21b604082015260600190565b6020808252600990820152681d1e0819985a5b195960ba1b604082015260600190565b60208082526010908201526f34b73b30b634b21031b7b7b63237bbb760811b604082015260600190565b6020808252600e908201526d185cdcd95d08191a5cd8589b195960921b604082015260600190565b602080825260119082015270696e76616c696420746f6c6572616e636560781b604082015260600190565b60208082526016908201527518995b1bddc81cdd5c1c1b1e481d1a1c995cda1bdb1960521b604082015260600190565b6020808252600d908201526c6869676820736c69707061676560981b604082015260600190565b6020808252601590820152741a5b9d985b1a590819195c1bdcda5d08185cdcd95d605a1b604082015260600190565b60208082526011908201527031b0b7103bb4ba34323930bb9039b7b7b760791b604082015260600190565b6020808252601690820152756869676820776974686472617720736c69707061676560501b604082015260600190565b60208082526010908201526f18dbdb9d1c9858dd1cc81c185d5cd95960821b604082015260600190565b6020808252600d908201526c1a5b9d985b1a590819dd585c99609a1b604082015260600190565b6020808252600b908201526a1c1bdbdb081c185d5cd95960aa1b604082015260600190565b60208082526010908201526f1b995959081b5a5b8819195c1bdcda5d60821b604082015260600190565b6020808252601490820152736f6e6c792067756172646564206164647265737360601b604082015260600190565b602080825260189082015277195e1a5d08199959481d1c985b9cd9995c8819985a5b195960421b604082015260600190565b6020808252601490820152731a5b9d985b1a59081b195b991a5b99c81c1bdbdb60621b604082015260600190565b60006020825282516101a08060208501526152a16101c0850183614a45565b9150602085015160408501526040850151606085015260608501516152c96080860182614a08565b506080850151848303601f190160a08601526152e58382614a45565b92505060a085015160c085015260c085015161530460e0860182614a15565b5060e08501516101008581019190915285015161012080860191909152850151610140808601919091528501516101608086019190915285015161018080860191909152909401519390920192909252919050565b90815260200190565b60ff91909116815260200190565b6000808335601e19843603018112615386578283fd5b8301803591506001600160401b0382111561539f578283fd5b60200191503681900382131561422b57600080fd5b60008235603e19833603018112614a83578182fd5b6040518181016001600160401b03811182821017156153e457fe5b604052919050565b60006001600160401b038211156153ff57fe5b5060209081020190565b60006001600160401b0382111561541c57fe5b50601f01601f191660200190565b60005b8381101561544557818101518382015260200161542d565b838111156120eb5750506000910152565b6001600160a01b038116811461090357600080fd5b801515811461090357600080fdfe45524332303a207472616e7366657220746f20746865207a65726f20616464726573735265656e7472616e637947756172643a207265656e7472616e742063616c6c0045524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef45524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa264697066735822122084aedf8d3bb9633b047774744da3b8288b869864af7c59c53cd93d6216a0911764736f6c63430007060033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in POL
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.