Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
SettingsFacet
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-07-23 */ // Sources flattened with hardhat v2.12.6 https://hardhat.org // File contracts/interfaces/IMintFactory.sol // SPDX-License-Identifier: UNLICENSED // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. pragma solidity 0.8.17; interface IMintFactory { struct TaxHelper { string Name; address Address; uint Index; } function addTaxHelper(string calldata _name, address _address) external; function updateTaxHelper(uint _index, address _address) external; function getTaxHelperAddress(uint _index) external view returns(address); function getTaxHelpersDataByIndex(uint _index) external view returns(TaxHelper memory); function registerToken (address _tokenOwner, address _tokenAddress) external; function tokenIsRegistered(address _tokenAddress) external view returns (bool); function tokenGeneratorsLength() external view returns (uint256); function tokenGeneratorIsAllowed(address _tokenGenerator) external view returns (bool); function getFacetHelper() external view returns (address); function updateFacetHelper(address _newFacetHelperAddress) external; function getFeeHelper() external view returns (address); function updateFeeHelper(address _newFeeHelperAddress) external; function getLosslessController() external view returns (address); function updateLosslessController(address _newLosslessControllerAddress) external; } // File contracts/interfaces/ITaxHelper.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. interface ITaxHelper { function initiateBuyBackTax( address _token, address _wallet ) external returns (bool); function initiateLPTokenTax( address _token, address _wallet ) external returns (bool); function lpTokenHasReserves(address _lpToken) external view returns (bool); function createLPToken() external returns (address lpToken); function sync(address _lpToken) external; } // File contracts/interfaces/IERC20.sol // File @openzeppelin/contracts/token/ERC20/[email protected] /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File contracts/interfaces/ITaxToken.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. interface ITaxToken is IERC20 { function taxHelperIndex()external view returns(uint); function buyBackBurn(uint256 _amount) external; function owner() external view returns (address); function pairAddress() external view returns (address); function decimals() external view returns (uint8); } // File contracts/libraries/Context.sol // // File @openzeppelin/contracts/utils/[email protected] /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File contracts/libraries/Ownable.sol // // File @openzeppelin/contracts/access/[email protected] /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File contracts/BuyBackWallet.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. contract BuyBackWallet is Ownable{ ITaxToken public token; IMintFactory public factory; uint256 private threshold; event UpdatedThreshold(uint256 _newThreshold); event ETHtoTaxHelper(uint256 amount); constructor(address _factory, address _token, uint256 _newThreshold) { token = ITaxToken(_token); factory = IMintFactory(_factory); threshold = _newThreshold; emit UpdatedThreshold(_newThreshold); transferOwnership(_token); } function checkBuyBackTrigger() public view returns (bool) { return address(this).balance > threshold; } function getBalance() public view returns (uint256) { return address(this).balance; } function sendEthToTaxHelper() external returns (uint256) { uint index = token.taxHelperIndex(); require(msg.sender == factory.getTaxHelperAddress(index), "RA"); uint256 amount = address(this).balance; (bool sent,) = msg.sender.call{value: amount}(""); require(sent, "Failed to send Ether"); emit ETHtoTaxHelper(amount); return amount; } function updateThreshold(uint256 _newThreshold) external onlyOwner { threshold = _newThreshold; emit UpdatedThreshold(_newThreshold); } function getThreshold() external view returns (uint256) { return threshold; } receive() payable external { } } // File contracts/FacetHelper.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. contract FacetHelper is Ownable{ event AddedFacet(address _newFacet); event AddedSelector(address _facet, bytes4 _sig); event RemovedSelector(bytes4 _sig); event ResetStorage(); event UpdatedSettingsFacet(address _newAddress); event UpdatedLosslessFacet(address _newAddress); event UpdatedTaxFacet(address _newAddress); event UpdatedConstructorFacet(address _newAddress); event UpdatedWalletsFacet(address _newAddress); event UpdatedAntiBotFacet(address _newAddress); event UpdatedMulticallFacet(address _newAddress); struct Facets { address Settings; address Lossless; address Tax; address Constructor; address Wallets; address AntiBot; address Multicall; } struct FacetAddressAndPosition { address facetAddress; uint16 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array } struct FacetFunctionSelectors { bytes4[] functionSelectors; uint16 facetAddressPosition; // position of facetAddress in facetAddresses array } // maps function selector to the facet address and // the position of the selector in the facetFunctionSelectors.selectors array mapping(bytes4 => FacetAddressAndPosition) _selectorToFacetAndPosition; // maps facet addresses to function selectors mapping(address => FacetFunctionSelectors) _facetFunctionSelectors; // facet addresses address[] _facetAddresses; // Used to query if a contract implements an interface. // Used to implement ERC-165. mapping(bytes4 => bool) supportedInterfaces; Facets public facetsInfo; enum FacetCutAction {Add, Replace, Remove} // Add=0, Replace=1, Remove=2 struct FacetCut { address facetAddress; FacetCutAction action; bytes4[] functionSelectors; } struct Facet { address facetAddress; bytes4[] functionSelectors; } /// @notice Gets all facets and their selectors. /// @return facets_ Facet function facets() external view returns (Facet[] memory facets_) { uint256 numFacets = _facetAddresses.length; facets_ = new Facet[](numFacets); for (uint256 i; i < numFacets; i++) { address facetAddress_ = _facetAddresses[i]; facets_[i].facetAddress = facetAddress_; facets_[i].functionSelectors = _facetFunctionSelectors[facetAddress_].functionSelectors; } } /// @notice Gets all the function selectors provided by a facet. /// @param _facet The facet address. /// @return facetFunctionSelectors_ function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_) { facetFunctionSelectors_ = _facetFunctionSelectors[_facet].functionSelectors; } /// @notice Get all the facet addresses used by a diamond. /// @return facetAddresses_ function facetAddresses() external view returns (address[] memory facetAddresses_) { facetAddresses_ = _facetAddresses; } /// @notice Gets the facet that supports the given selector. /// @dev If facet is not found return address(0). /// @param _functionSelector The function selector. /// @return facetAddress_ The facet address. function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_) { facetAddress_ = _selectorToFacetAndPosition[_functionSelector].facetAddress; } // This implements ERC-165. function supportsInterface(bytes4 _interfaceId) external view returns (bool) { return supportedInterfaces[_interfaceId]; } event DiamondCut(FacetCut[] _diamondCut); function diamondCut( FacetCut[] memory _diamondCut ) public onlyOwner { for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) { FacetCutAction action = _diamondCut[facetIndex].action; if (action == FacetCutAction.Add) { addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors); } else if (action == FacetCutAction.Replace) { replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors); } else if (action == FacetCutAction.Remove) { removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors); } else { revert("LibDiamondCut: Incorrect FacetCutAction"); } } emit DiamondCut(_diamondCut); } function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut"); // uint16 selectorCount = uint16(diamondStorage().selectors.length); require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)"); uint16 selectorPosition = uint16(_facetFunctionSelectors[_facetAddress].functionSelectors.length); // add new facet address if it does not exist if (selectorPosition == 0) { enforceHasContractCode(_facetAddress, "LibDiamondCut: New facet has no code"); _facetFunctionSelectors[_facetAddress].facetAddressPosition = uint16(_facetAddresses.length); _facetAddresses.push(_facetAddress); } for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = _selectorToFacetAndPosition[selector].facetAddress; require(oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists"); _facetFunctionSelectors[_facetAddress].functionSelectors.push(selector); _selectorToFacetAndPosition[selector].facetAddress = _facetAddress; _selectorToFacetAndPosition[selector].functionSelectorPosition = selectorPosition; selectorPosition++; } } function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut"); require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)"); uint16 selectorPosition = uint16(_facetFunctionSelectors[_facetAddress].functionSelectors.length); // add new facet address if it does not exist if (selectorPosition == 0) { enforceHasContractCode(_facetAddress, "LibDiamondCut: New facet has no code"); _facetFunctionSelectors[_facetAddress].facetAddressPosition = uint16(_facetAddresses.length); _facetAddresses.push(_facetAddress); } for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = _selectorToFacetAndPosition[selector].facetAddress; require(oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function"); removeFunction(oldFacetAddress, selector); // add function _selectorToFacetAndPosition[selector].functionSelectorPosition = selectorPosition; _facetFunctionSelectors[_facetAddress].functionSelectors.push(selector); _selectorToFacetAndPosition[selector].facetAddress = _facetAddress; selectorPosition++; } } function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut"); // if function does not exist then do nothing and return require(_facetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)"); for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = _selectorToFacetAndPosition[selector].facetAddress; removeFunction(oldFacetAddress, selector); } } function removeFunction(address _facetAddress, bytes4 _selector) internal { require(_facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist"); // an immutable function is a function defined directly in a diamond require(_facetAddress != address(this), "LibDiamondCut: Can't remove immutable function"); // replace selector with last selector, then delete last selector uint256 selectorPosition = _selectorToFacetAndPosition[_selector].functionSelectorPosition; uint256 lastSelectorPosition = _facetFunctionSelectors[_facetAddress].functionSelectors.length - 1; // if not the same then replace _selector with lastSelector if (selectorPosition != lastSelectorPosition) { bytes4 lastSelector = _facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition]; _facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector; _selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint16(selectorPosition); } // delete the last selector _facetFunctionSelectors[_facetAddress].functionSelectors.pop(); delete _selectorToFacetAndPosition[_selector]; // if no more selectors for facet address then delete the facet address if (lastSelectorPosition == 0) { // replace facet address with last facet address and delete last facet address uint256 lastFacetAddressPosition = _facetAddresses.length - 1; uint256 facetAddressPosition = _facetFunctionSelectors[_facetAddress].facetAddressPosition; if (facetAddressPosition != lastFacetAddressPosition) { address lastFacetAddress = _facetAddresses[lastFacetAddressPosition]; _facetAddresses[facetAddressPosition] = lastFacetAddress; _facetFunctionSelectors[lastFacetAddress].facetAddressPosition = uint16(facetAddressPosition); } _facetAddresses.pop(); delete _facetFunctionSelectors[_facetAddress].facetAddressPosition; } } function enforceHasContractCode(address _contract, string memory _errorMessage) internal view { uint256 contractSize; assembly { contractSize := extcodesize(_contract) } require(contractSize > 0, _errorMessage); } // mapping(bytes4 => address) public selectorToFacet; // bytes4[] public selectorsList; // mapping(address => bool) public isFacet; // address[] public facetsList; // function addFacet(address _newFacet) public onlyOwner { // isFacet[_newFacet] = true; // facetsList.push(_newFacet); // emit AddedFacet(_newFacet); // } // function batchAddSelectors(address _facet, bytes4[] memory _sigs) public onlyOwner { // for(uint256 index; index < _sigs.length; index++) { // addSelector(_facet, _sigs[index]); // } // } // function addSelector(address _facet, bytes4 _sig) public onlyOwner { // require(selectorToFacet[_sig] == address(0)); // // require(isFacet[_facet]); // selectorToFacet[_sig] = _facet; // selectorsList.push(_sig); // emit AddedSelector(_facet, _sig); // } // Removing of the selectors occurs during resetFacetStorage(); // it is easier to reset and rebuild using the script when deploying and updating the facets // function removeSelector(bytes4 _sig) public onlyOwner { // selectorToFacet[_sig] = address(0); // emit RemovedSelector(_sig); // } // function getFacetAddressFromSelector(bytes4 _sig) public view returns (address) { // return selectorToFacet[_sig]; // } // function getFacetByIndex(uint256 _index) public view returns(address) { // return facetsList[_index]; // } // function resetFacetStorage() public onlyOwner { // for(uint i = 0; i < selectorsList.length; i++) { // bytes4 sig = selectorsList[i]; // selectorToFacet[sig] = address(0); // } // delete selectorsList; // for(uint i = 0; i < facetsList.length; i++) { // address facet = facetsList[i]; // isFacet[facet] = false; // } // delete facetsList; // emit ResetStorage(); // } // Facet getters and setters function getSettingsFacet() public view returns (address) { return facetsInfo.Settings; } function updateSettingsFacet(address _newSettingsAddress) public onlyOwner { facetsInfo.Settings = _newSettingsAddress; emit UpdatedSettingsFacet(_newSettingsAddress); } function getLosslessFacet() public view returns (address) { return facetsInfo.Lossless; } function updateLosslessFacet(address _newLosslessAddress) public onlyOwner { facetsInfo.Lossless = _newLosslessAddress; emit UpdatedLosslessFacet(_newLosslessAddress); } function getTaxFacet() public view returns (address) { return facetsInfo.Tax; } function updateTaxFacet(address _newTaxAddress) public onlyOwner { facetsInfo.Tax = _newTaxAddress; emit UpdatedTaxFacet(_newTaxAddress); } function getConstructorFacet() public view returns (address) { return facetsInfo.Constructor; } function updateConstructorFacet(address _newConstructorAddress) public onlyOwner { facetsInfo.Constructor = _newConstructorAddress; emit UpdatedConstructorFacet(_newConstructorAddress); } function getWalletsFacet() public view returns (address) { return facetsInfo.Wallets; } function updateWalletsFacet(address _newWalletsAddress) public onlyOwner { facetsInfo.Wallets = _newWalletsAddress; emit UpdatedWalletsFacet(_newWalletsAddress); } function getAntiBotFacet() public view returns (address) { return facetsInfo.AntiBot; } function updateAntiBotFacet(address _newAntiBotAddress) public onlyOwner { facetsInfo.AntiBot = _newAntiBotAddress; emit UpdatedAntiBotFacet(_newAntiBotAddress); } function getMulticallFacet() public view returns (address) { return facetsInfo.Multicall; } function updateMulticallFacet(address _newWalletsAddress) public onlyOwner { facetsInfo.Multicall = _newWalletsAddress; emit UpdatedMulticallFacet(_newWalletsAddress); } } // File contracts/interfaces/ILosslessController.sol // interface ILosslessController { function pause() external; function unpause() external; function setAdmin(address _newAdmin) external; function setRecoveryAdmin(address _newRecoveryAdmin) external; function beforeTransfer(address _sender, address _recipient, uint256 _amount) external; function beforeTransferFrom(address _msgSender, address _sender, address _recipient, uint256 _amount) external; function beforeApprove(address _sender, address _spender, uint256 _amount) external; function beforeIncreaseAllowance(address _msgSender, address _spender, uint256 _addedValue) external; function beforeDecreaseAllowance(address _msgSender, address _spender, uint256 _subtractedValue) external; function beforeMint(address _to, uint256 _amount) external; function beforeBurn(address _account, uint256 _amount) external; function afterTransfer(address _sender, address _recipient, uint256 _amount) external; event AdminChange(address indexed _newAdmin); event RecoveryAdminChange(address indexed _newAdmin); } // File contracts/facets/Storage.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. struct Storage { uint256 CONTRACT_VERSION; TaxSettings taxSettings; TaxSettings isLocked; Fees fees; CustomTax[] customTaxes; address transactionTaxWallet; uint256 customTaxLength; uint256 MaxTax; uint8 MaxCustom; uint256 DENOMINATOR; mapping (address => uint256) _rOwned; mapping (address => uint256) _tOwned; mapping (address => mapping (address => uint256)) _allowances; mapping (address => bool) _isExcluded; address[] _excluded; uint256 MAX; uint256 _tTotal; uint256 _rTotal; uint256 _tFeeTotal; mapping (address => bool) lpTokens; string _name; string _symbol; uint8 _decimals; address _creator; address factory; address buyBackWallet; address lpWallet; bool isPaused; bool isTaxed; mapping(address => bool) blacklist; mapping(address => bool) swapWhitelist; mapping(address => bool) maxBalanceWhitelist; mapping(address => bool) taxWhitelist; address pairAddress; uint256 taxHelperIndex; // AntiBot Variables bool marketInit; uint256 marketInitBlockTime; AntiBotSettings antiBotSettings; mapping (address => uint256) antiBotBalanceTracker; uint256 maxBalanceAfterBuy; SwapWhitelistingSettings swapWhitelistingSettings; // Lossless data and events address recoveryAdmin; address recoveryAdminCandidate; bytes32 recoveryAdminKeyHash; address admin; uint256 timelockPeriod; uint256 losslessTurnOffTimestamp; bool isLosslessTurnOffProposed; bool isLosslessOn; } struct TaxSettings { bool transactionTax; bool buyBackTax; bool holderTax; bool lpTax; bool canBlacklist; bool canMint; bool canPause; bool maxBalanceAfterBuy; } struct Fee { uint256 buy; uint256 sell; } struct Fees { Fee transactionTax; uint256 buyBackTax; uint256 holderTax; uint256 lpTax; } struct CustomTax { string name; Fee fee; address wallet; bool withdrawAsGas; } struct AntiBotSettings { uint256 startBlock; uint256 endDate; uint256 increment; uint256 initialMaxHold; bool isActive; } struct SwapWhitelistingSettings { uint256 endDate; bool isActive; } // File contracts/facets/AntiBot.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. contract AntiBotFacet is Ownable { Storage internal s; event UpdatedAntiBotIncrement(uint256 _updatedIncrement); event UpdatedAntiBotEndDate(uint256 _updatedEndDate); event UpdatedAntiBotInitialMaxHold(uint256 _updatedInitialMaxHold); event UpdatedAntiBotActiveStatus(bool _isActive); event UpdatedSwapWhitelistingEndDate(uint256 _updatedEndDate); event UpdatedSwapWhitelistingActiveStatus(bool _isActive); event UpdatedMaxBalanceAfterBuy(uint256 _newMaxBalance); event AddedMaxBalanceWhitelistAddress(address _address); event RemovedMaxBalanceWhitelistAddress(address _address); event AddedSwapWhitelistAddress(address _address); event RemovedSwapWhitelistAddress(address _address); // AntiBot function antiBotIsActiveModifier() view internal { require(s.antiBotSettings.isActive, "ABD"); } modifier antiBotIsActive() { antiBotIsActiveModifier(); _; } function setIncrement(uint256 _updatedIncrement) public onlyOwner antiBotIsActive { s.antiBotSettings.increment = _updatedIncrement; emit UpdatedAntiBotIncrement(_updatedIncrement); } function setEndDate( uint256 _updatedEndDate) public onlyOwner antiBotIsActive { require(_updatedEndDate <= 48, "ED"); s.antiBotSettings.endDate = _updatedEndDate; emit UpdatedAntiBotEndDate(_updatedEndDate); } function setInitialMaxHold( uint256 _updatedInitialMaxHold) public onlyOwner antiBotIsActive { s.antiBotSettings.initialMaxHold = _updatedInitialMaxHold; emit UpdatedAntiBotInitialMaxHold(_updatedInitialMaxHold); } function updateAntiBot(bool _isActive) public onlyOwner { require(!s.marketInit, "AMIE"); s.antiBotSettings.isActive = _isActive; emit UpdatedAntiBotActiveStatus(_isActive); } function antiBotCheck(uint256 amount, address receiver) public returns(bool) { // restrict it to being only called by registered tokens require(IMintFactory(s.factory).tokenIsRegistered(address(this))); require(s.marketInit, "AMIE"); if(block.timestamp > s.marketInitBlockTime + (s.antiBotSettings.endDate * 1 hours)) { s.antiBotSettings.isActive = false; return true; } s.antiBotBalanceTracker[receiver] += amount; uint256 userAntiBotBalance = s.antiBotBalanceTracker[receiver]; uint256 maxAntiBotBalance = ((block.number - s.antiBotSettings.startBlock) * s.antiBotSettings.increment) + s.antiBotSettings.initialMaxHold; require((userAntiBotBalance <= maxAntiBotBalance), "ABMSA"); return true; } // MaxBalanceAfterBuy function addMaxBalanceWhitelistedAddress(address _address) public onlyOwner { require(s.taxSettings.maxBalanceAfterBuy, "AMBABD"); s.maxBalanceWhitelist[_address] = true; emit AddedMaxBalanceWhitelistAddress(_address); } function removeMaxBalanceWhitelistedAddress(address _address) public onlyOwner { require(s.taxSettings.maxBalanceAfterBuy, "AMBABD"); s.maxBalanceWhitelist[_address] = false; emit RemovedMaxBalanceWhitelistAddress(_address); } function updateMaxBalanceWhitelistBatch(address[] calldata _updatedAddresses, bool _isMaxBalanceWhitelisted) public onlyOwner { require(s.taxSettings.maxBalanceAfterBuy, "AMBABD"); for(uint i = 0; i < _updatedAddresses.length; i++) { s.maxBalanceWhitelist[_updatedAddresses[i]] = _isMaxBalanceWhitelisted; if(_isMaxBalanceWhitelisted) { emit AddedMaxBalanceWhitelistAddress(_updatedAddresses[i]); } else { emit RemovedMaxBalanceWhitelistAddress(_updatedAddresses[i]); } } } function isMaxBalanceWhitelisted(address _address) public view returns (bool) { return s.maxBalanceWhitelist[_address]; } function updateMaxBalanceAfterBuy(uint256 _updatedMaxBalanceAfterBuy) public onlyOwner { require(s.taxSettings.maxBalanceAfterBuy, "AMBABD"); s.maxBalanceAfterBuy = _updatedMaxBalanceAfterBuy; emit UpdatedMaxBalanceAfterBuy(_updatedMaxBalanceAfterBuy); } function maxBalanceAfterBuyCheck(uint256 amount, address receiver) public view returns(bool) { if(s.maxBalanceWhitelist[receiver]) { return true; } require(s.taxSettings.maxBalanceAfterBuy); uint256 receiverBalance; if(s.taxSettings.holderTax) { receiverBalance = s._rOwned[receiver]; } else { receiverBalance = s._tOwned[receiver]; } receiverBalance += amount; require(receiverBalance <= s.maxBalanceAfterBuy, "MBAB"); return true; } // SwapWhitelist function addSwapWhitelistedAddress(address _address) public onlyOwner { require(s.swapWhitelistingSettings.isActive, "ASWD"); s.swapWhitelist[_address] = true; emit AddedSwapWhitelistAddress(_address); } function removeSwapWhitelistedAddress(address _address) public onlyOwner { require(s.swapWhitelistingSettings.isActive, "ASWD"); s.swapWhitelist[_address] = false; emit RemovedSwapWhitelistAddress(_address); } function updateSwapWhitelistBatch(address[] calldata _updatedAddresses, bool _isSwapWhitelisted) public onlyOwner { require(s.swapWhitelistingSettings.isActive, "ASWD"); for(uint i = 0; i < _updatedAddresses.length; i++) { s.swapWhitelist[_updatedAddresses[i]] = _isSwapWhitelisted; if(_isSwapWhitelisted) { emit AddedSwapWhitelistAddress(_updatedAddresses[i]); } else { emit RemovedSwapWhitelistAddress(_updatedAddresses[i]); } } } function isSwapWhitelisted(address _address) public view returns (bool) { return s.swapWhitelist[_address]; } function setSwapWhitelistEndDate( uint256 _updatedEndDate) public onlyOwner { require(s.swapWhitelistingSettings.isActive, "ASWD"); require(_updatedEndDate <= 48, "ED"); s.swapWhitelistingSettings.endDate = _updatedEndDate; emit UpdatedSwapWhitelistingEndDate(_updatedEndDate); } function updateSwapWhitelisting(bool _isActive) public onlyOwner { require(!s.marketInit, "AMIE"); s.swapWhitelistingSettings.isActive = _isActive; emit UpdatedSwapWhitelistingActiveStatus(_isActive); } function swapWhitelistingCheck(address receiver) public returns(bool) { require(s.marketInit, "AMIE"); if(block.timestamp > s.marketInitBlockTime + (s.swapWhitelistingSettings.endDate * 1 hours)) { s.swapWhitelistingSettings.isActive = false; return true; } require(s.swapWhitelist[receiver], "SWL"); return true; } } // File contracts/interfaces/IBuyBackWallet.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. interface IBuyBackWallet { function checkBuyBackTrigger() external view returns (bool); function getBalance() external view returns (uint256); function sendEthToTaxHelper() external returns(uint256); function updateThreshold(uint256 _newThreshold) external; function getThreshold() external view returns (uint256); } // File contracts/interfaces/IFacetHelper.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. interface IFacetHelper { struct Facet { address facetAddress; bytes4[] functionSelectors; } /// @notice Gets all facet addresses and their four byte function selectors. /// @return facets_ Facet function facets() external view returns (Facet[] memory facets_); /// @notice Gets all the function selectors supported by a specific facet. /// @param _facet The facet address. /// @return facetFunctionSelectors_ function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_); /// @notice Get all the facet addresses used by a diamond. /// @return facetAddresses_ function facetAddresses() external view returns (address[] memory facetAddresses_); /// @notice Gets the facet that supports the given selector. /// @dev If facet is not found return address(0). /// @param _functionSelector The function selector. /// @return facetAddress_ The facet address. function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_); // function addFacet(address _newFacet) external; // function addSelector(address _facet, bytes4 _sig) external; // function removeSelector(bytes4 _sig) external; function getFacetAddressFromSelector(bytes4 _sig) external view returns (address); function getSettingsFacet() external view returns (address); function updateSettingsFacet(address _newSettingsAddress) external; function getTaxFacet() external view returns (address); function updateTaxFacet(address _newTaxesAddress) external; function getLosslessFacet() external view returns (address); function updateLosslessFacet(address _newLosslessAddress) external; function getConstructorFacet() external view returns (address); function updateConstructorFacet(address _newConstructorAddress) external; function getWalletsFacet() external view returns (address); function updateWalletsFacet(address _newWalletsAddress) external; function getAntiBotFacet() external view returns (address); function updateAntiBotFacet(address _newWalletsAddress) external; function getMulticallFacet() external view returns (address); function updateMulticallFacet(address _newWalletsAddress) external; } // File contracts/interfaces/ILPWallet.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. interface ILPWallet { function checkLPTrigger() external view returns (bool); function getBalance() external view returns (uint256); function sendEthToTaxHelper() external returns(uint256); function transferBalanceToTaxHelper() external; function updateThreshold(uint256 _newThreshold) external; function getThreshold() external view returns (uint256); } // File contracts/interfaces/ISettings.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. interface ISettingsFacet { function getFacetAddressFromSelector(bytes4 _sig) external view returns (address); function createBuyBackWallet(address _factory, address _token) external returns (address); function createLPWallet(address _factory, address _token) external returns (address); } // File contracts/interfaces/IWallets.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. interface IWalletsFacet { function createBuyBackWallet(address _factory, address _token, uint256 _newThreshold) external returns (address); function createLPWallet(address _factory, address _token, uint256 _newThreshold) external returns (address); function updateBuyBackWalletThreshold(uint256 _newThreshold) external; function updateLPWalletThreshold(uint256 _newThreshold) external; } // File contracts/facets/Constructor.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. contract ConstructorFacet is Ownable { Storage internal s; event ExcludedAccount(address account); event AdminChanged(address indexed previousAdmin, address indexed newAdmin); event RecoveryAdminChanged(address indexed previousAdmin, address indexed newAdmin); event UpdatedCustomTaxes(CustomTax[] _customTaxes); event UpdatedTaxFees(Fees _updatedFees); event UpdatedTransactionTaxAddress(address _newAddress); event UpdatedLockedSettings(TaxSettings _updatedLocks); event UpdatedSettings(TaxSettings _updatedSettings); event UpdatedTaxHelperIndex(uint _newIndex); event UpdatedAntiBotSettings(AntiBotSettings _antiBotSettings); event UpdatedSwapWhitelistingSettings(SwapWhitelistingSettings _swapWhitelistingSettings); event UpdatedMaxBalanceAfterBuy(uint256 _newMaxBalance); event AddedLPToken(address _newLPToken); event TokenCreated(string name, string symbol, uint8 decimals, uint256 totalSupply, uint256 reflectionTotalSupply); event Transfer(address indexed from, address indexed to, uint256 value); struct ConstructorParams { string name_; string symbol_; uint8 decimals_; address creator_; uint256 tTotal_; uint256 _maxTax; TaxSettings _settings; TaxSettings _lockedSettings; Fees _fees; address _transactionTaxWallet; CustomTax[] _customTaxes; uint256 lpWalletThreshold; uint256 buyBackWalletThreshold; uint256 _taxHelperIndex; address admin_; address recoveryAdmin_; bool isLossless_; AntiBotSettings _antiBotSettings; uint256 _maxBalanceAfterBuy; SwapWhitelistingSettings _swapWhitelistingSettings; } function constructorHandler(ConstructorParams calldata params, address _factory) external { require(IMintFactory(_factory).tokenGeneratorIsAllowed(msg.sender), "RA"); require(params.creator_ != address(0), "ZA"); require(params._transactionTaxWallet != address(0), "ZA"); require(params.admin_ != address(0), "ZA"); require(params.recoveryAdmin_ != address(0), "ZA"); require(_factory != address(0), "ZA"); // Set inital values s.CONTRACT_VERSION = 1; s.customTaxLength = 0; s.MaxTax = 3000; s.MaxCustom = 10; s.MAX = ~uint256(0); s.isPaused = false; s.isTaxed = false; s.marketInit = false; s._name = params.name_; s._symbol = params.symbol_; s._decimals = params.decimals_; s._creator = params.creator_; s._isExcluded[params.creator_] = true; s._excluded.push(params.creator_); emit ExcludedAccount(s._creator); // Lossless s.isLosslessOn = params.isLossless_; s.admin = params.admin_; emit AdminChanged(address(0), s.admin); s.recoveryAdmin = params.recoveryAdmin_; emit RecoveryAdminChanged(address(0), s.recoveryAdmin); s.timelockPeriod = 7 days; address lossless = IMintFactory(_factory).getLosslessController(); s._isExcluded[lossless] = true; s._excluded.push(lossless); emit ExcludedAccount(lossless); // Tax Settings require(params._maxTax <= s.MaxTax, "MT"); s.MaxTax = params._maxTax; s.taxSettings = params._settings; emit UpdatedSettings(s.taxSettings); s.isLocked = params._lockedSettings; s.isLocked.holderTax = true; if(s.taxSettings.holderTax) { s.taxSettings.canMint = false; s.isLocked.canMint = true; } emit UpdatedLockedSettings(s.isLocked); s.fees = params._fees; emit UpdatedTaxFees(s.fees); require(params._customTaxes.length < s.MaxCustom + 1, "MCT"); for(uint i = 0; i < params._customTaxes.length; i++) { require(params._customTaxes[i].wallet != address(0)); s.customTaxes.push(params._customTaxes[i]); } emit UpdatedCustomTaxes(s.customTaxes); s.customTaxLength = params._customTaxes.length; s.transactionTaxWallet = params._transactionTaxWallet; emit UpdatedTransactionTaxAddress(s.transactionTaxWallet); // Factory, Wallets, Pair Address s.factory = _factory; s.taxHelperIndex = params._taxHelperIndex; emit UpdatedTaxHelperIndex(s.taxHelperIndex); address taxHelper = IMintFactory(s.factory).getTaxHelperAddress(s.taxHelperIndex); s.pairAddress = ITaxHelper(taxHelper).createLPToken(); addLPToken(s.pairAddress); address wallets = IFacetHelper(IMintFactory(s.factory).getFacetHelper()).getWalletsFacet(); s.buyBackWallet = IWalletsFacet(wallets).createBuyBackWallet(s.factory, address(this), params.buyBackWalletThreshold); s.lpWallet = IWalletsFacet(wallets).createLPWallet(s.factory, address(this), params.lpWalletThreshold); // Total Supply and other info s._rTotal = (s.MAX - (s.MAX % params.tTotal_)); s._rOwned[params.creator_] = s._rTotal; s.DENOMINATOR = 10000; s._isExcluded[taxHelper] = true; s._excluded.push(taxHelper); emit ExcludedAccount(taxHelper); require(checkMaxTax(true), "BF"); require(checkMaxTax(false), "SF"); transferOwnership(params.creator_); _mintInitial(params.creator_, params.tTotal_); // AntiBot Settings require(params._antiBotSettings.endDate <= 48, "ED"); require(params._swapWhitelistingSettings.endDate <= 48, "ED"); s.antiBotSettings = params._antiBotSettings; emit UpdatedAntiBotSettings(s.antiBotSettings); s.maxBalanceAfterBuy = params._maxBalanceAfterBuy; emit UpdatedMaxBalanceAfterBuy(s.maxBalanceAfterBuy); s.swapWhitelistingSettings = params._swapWhitelistingSettings; emit UpdatedSwapWhitelistingSettings(s.swapWhitelistingSettings); emit TokenCreated(s._name, s._symbol, s._decimals, s._tTotal, s._rTotal); } function _mintInitial(address account, uint256 amount) internal virtual { s._tTotal += amount; s._tOwned[account] += amount; emit Transfer(address(0), account, amount); } function checkMaxTax(bool isBuy) internal view returns (bool) { uint256 totalTaxes; if(isBuy) { totalTaxes += s.fees.transactionTax.buy; totalTaxes += s.fees.holderTax; for(uint i = 0; i < s.customTaxes.length; i++) { totalTaxes += s.customTaxes[i].fee.buy; } } else { totalTaxes += s.fees.transactionTax.sell; totalTaxes += s.fees.lpTax; totalTaxes += s.fees.holderTax; totalTaxes += s.fees.buyBackTax; for(uint i = 0; i < s.customTaxes.length; i++) { totalTaxes += s.customTaxes[i].fee.sell; } } if(totalTaxes <= s.MaxTax) { return true; } return false; } function addLPToken(address _newLPToken) internal { s.lpTokens[_newLPToken] = true; emit AddedLPToken(_newLPToken); } } // File contracts/facets/Lossless.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. contract LosslessFacet is Ownable { Storage internal s; event AdminChanged(address indexed previousAdmin, address indexed newAdmin); event RecoveryAdminChangeProposed(address indexed candidate); event RecoveryAdminChanged(address indexed previousAdmin, address indexed newAdmin); event LosslessTurnOffProposed(uint256 turnOffDate); event LosslessTurnedOff(); event LosslessTurnedOn(); function onlyRecoveryAdminCheck() internal view { require(_msgSender() == s.recoveryAdmin, "LRA"); } modifier onlyRecoveryAdmin() { onlyRecoveryAdminCheck(); _; } // --- LOSSLESS management --- function getAdmin() external view returns (address) { return s.admin; } function setLosslessAdmin(address newAdmin) external onlyRecoveryAdmin { require(newAdmin != address(0), "LZ"); emit AdminChanged(s.admin, newAdmin); s.admin = newAdmin; } function transferRecoveryAdminOwnership(address candidate, bytes32 keyHash) external onlyRecoveryAdmin { require(candidate != address(0), "LZ"); s.recoveryAdminCandidate = candidate; s.recoveryAdminKeyHash = keyHash; emit RecoveryAdminChangeProposed(candidate); } function acceptRecoveryAdminOwnership(bytes memory key) external { require(_msgSender() == s.recoveryAdminCandidate, "LC"); require(keccak256(key) == s.recoveryAdminKeyHash, "LIK"); emit RecoveryAdminChanged(s.recoveryAdmin, s.recoveryAdminCandidate); s.recoveryAdmin = s.recoveryAdminCandidate; } function proposeLosslessTurnOff() external onlyRecoveryAdmin { s.losslessTurnOffTimestamp = block.timestamp + s.timelockPeriod; s.isLosslessTurnOffProposed = true; emit LosslessTurnOffProposed(s.losslessTurnOffTimestamp); } function executeLosslessTurnOff() external onlyRecoveryAdmin { require(s.isLosslessTurnOffProposed, "LTNP"); require(s.losslessTurnOffTimestamp <= block.timestamp, "LTL"); s.isLosslessOn = false; s.isLosslessTurnOffProposed = false; emit LosslessTurnedOff(); } function executeLosslessTurnOn() external onlyRecoveryAdmin { s.isLosslessTurnOffProposed = false; s.isLosslessOn = true; emit LosslessTurnedOn(); } } // File contracts/facets/Multicall.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. contract MulticallFacet is Ownable { Storage internal s; event UpdatedSettings(TaxSettings _updatedSettings); event UpdatedLockedSettings(TaxSettings _updatedLocks); event UpdatedCustomTaxes(CustomTax[] _customTaxes); event UpdatedTaxFees(Fees _updatedFees); event UpdatedTransactionTaxAddress(address _newAddress); event UpdatedMaxBalanceAfterBuy(uint256 _newMaxBalance); event UpdatedBuyBackWalletThreshold(uint256 _newThreshold); event UpdatedLPWalletThreshold(uint256 _newThreshold); event UpdatedAntiBotIncrement(uint256 _updatedIncrement); event UpdatedAntiBotEndDate(uint256 _updatedEndDate); event UpdatedAntiBotInitialMaxHold(uint256 _updatedInitialMaxHold); event UpdatedAntiBotActiveStatus(bool _isActive); event UpdatedSwapWhitelistingEndDate(uint256 _updatedEndDate); event UpdatedSwapWhitelistingActiveStatus(bool _isActive); struct MulticallAdminUpdateParams { TaxSettings _taxSettings; TaxSettings _lockSettings; CustomTax[] _customTaxes; Fees _fees; address _transactionTaxWallet; uint256 _maxBalanceAfterBuy; uint256 _lpWalletThreshold; uint256 _buyBackWalletThreshold; } function multicallAdminUpdate(MulticallAdminUpdateParams calldata params) public onlyOwner { // Tax Settings if(!s.isLocked.transactionTax && s.taxSettings.transactionTax != params._taxSettings.transactionTax) { s.taxSettings.transactionTax = params._taxSettings.transactionTax; } if(!s.isLocked.holderTax && s.taxSettings.holderTax != params._taxSettings.holderTax && !params._taxSettings.canMint) { s.taxSettings.holderTax = params._taxSettings.holderTax; } if(!s.isLocked.buyBackTax && s.taxSettings.buyBackTax != params._taxSettings.buyBackTax) { s.taxSettings.buyBackTax = params._taxSettings.buyBackTax; } if(!s.isLocked.lpTax && s.taxSettings.lpTax != params._taxSettings.lpTax) { s.taxSettings.lpTax = params._taxSettings.lpTax; } if(!s.isLocked.canMint && s.taxSettings.canMint != params._taxSettings.canMint && !s.taxSettings.holderTax) { s.taxSettings.canMint = params._taxSettings.canMint; } if(!s.isLocked.canPause && s.taxSettings.canPause != params._taxSettings.canPause) { s.taxSettings.canPause = params._taxSettings.canPause; } if(!s.isLocked.canBlacklist && s.taxSettings.canBlacklist != params._taxSettings.canBlacklist) { s.taxSettings.canBlacklist = params._taxSettings.canBlacklist; } if(!s.isLocked.maxBalanceAfterBuy && s.taxSettings.maxBalanceAfterBuy != params._taxSettings.maxBalanceAfterBuy) { s.taxSettings.maxBalanceAfterBuy = params._taxSettings.maxBalanceAfterBuy; } emit UpdatedSettings(s.taxSettings); // Lock Settings if(!s.isLocked.transactionTax) { s.isLocked.transactionTax = params._lockSettings.transactionTax; } if(!s.isLocked.holderTax) { s.isLocked.holderTax = params._lockSettings.holderTax; } if(!s.isLocked.buyBackTax) { s.isLocked.buyBackTax = params._lockSettings.buyBackTax; } if(!s.isLocked.lpTax) { s.isLocked.lpTax = params._lockSettings.lpTax; } if(!s.isLocked.canMint) { s.isLocked.canMint = params._lockSettings.canMint; } if(!s.isLocked.canPause) { s.isLocked.canPause = params._lockSettings.canPause; } if(!s.isLocked.canBlacklist) { s.isLocked.canBlacklist = params._lockSettings.canBlacklist; } if(!s.isLocked.maxBalanceAfterBuy) { s.isLocked.maxBalanceAfterBuy = params._lockSettings.maxBalanceAfterBuy; } emit UpdatedLockedSettings(s.isLocked); // Custom Taxes require(params._customTaxes.length < s.MaxCustom + 1, "MCT"); delete s.customTaxes; for(uint i = 0; i < params._customTaxes.length; i++) { require(params._customTaxes[i].wallet != address(0), "ZA"); s.customTaxes.push(params._customTaxes[i]); } s.customTaxLength = params._customTaxes.length; emit UpdatedCustomTaxes(params._customTaxes); // Fees s.fees.transactionTax.buy = params._fees.transactionTax.buy; s.fees.transactionTax.sell = params._fees.transactionTax.sell; s.fees.buyBackTax = params._fees.buyBackTax; s.fees.holderTax = params._fees.holderTax; s.fees.lpTax = params._fees.lpTax; require(checkMaxTax(true), "BF"); require(checkMaxTax(false), "SF"); emit UpdatedTaxFees(params._fees); // transactionTax address require(params._transactionTaxWallet != address(0), "ZA"); s.transactionTaxWallet = params._transactionTaxWallet; emit UpdatedTransactionTaxAddress(params._transactionTaxWallet); // maxBalanceAfterBuy if(s.taxSettings.maxBalanceAfterBuy) { s.maxBalanceAfterBuy = params._maxBalanceAfterBuy; emit UpdatedMaxBalanceAfterBuy(params._maxBalanceAfterBuy); } // update wallet thresholds ILPWallet(s.lpWallet).updateThreshold(params._lpWalletThreshold); emit UpdatedLPWalletThreshold(params._lpWalletThreshold); IBuyBackWallet(s.buyBackWallet).updateThreshold(params._buyBackWalletThreshold); emit UpdatedBuyBackWalletThreshold(params._buyBackWalletThreshold); } function checkMaxTax(bool isBuy) internal view returns (bool) { uint256 totalTaxes; if(isBuy) { totalTaxes += s.fees.transactionTax.buy; totalTaxes += s.fees.holderTax; for(uint i = 0; i < s.customTaxes.length; i++) { totalTaxes += s.customTaxes[i].fee.buy; } } else { totalTaxes += s.fees.transactionTax.sell; totalTaxes += s.fees.lpTax; totalTaxes += s.fees.holderTax; totalTaxes += s.fees.buyBackTax; for(uint i = 0; i < s.customTaxes.length; i++) { totalTaxes += s.customTaxes[i].fee.sell; } } if(totalTaxes <= s.MaxTax) { return true; } return false; } struct AntiBotUpdateParams { AntiBotSettings _antiBotSettings; SwapWhitelistingSettings _swapWhitelistingSettings; } // Multicall AntiBot Update function multicallAntiBotUpdate(AntiBotUpdateParams calldata params) public onlyOwner { // AntiBot s.antiBotSettings.increment = params._antiBotSettings.increment; emit UpdatedAntiBotIncrement(s.antiBotSettings.increment); require(params._antiBotSettings.endDate <= 48, "ED"); s.antiBotSettings.endDate = params._antiBotSettings.endDate; emit UpdatedAntiBotEndDate(s.antiBotSettings.endDate); s.antiBotSettings.initialMaxHold = params._antiBotSettings.initialMaxHold; emit UpdatedAntiBotInitialMaxHold(s.antiBotSettings.initialMaxHold); if(!s.marketInit) { s.antiBotSettings.isActive = params._antiBotSettings.isActive; emit UpdatedAntiBotActiveStatus(s.antiBotSettings.isActive); } // SwapWhitelisting require(params._swapWhitelistingSettings.endDate <= 48, "ED"); s.swapWhitelistingSettings.endDate = params._swapWhitelistingSettings.endDate; emit UpdatedSwapWhitelistingEndDate(s.antiBotSettings.endDate); if(!s.marketInit) { s.swapWhitelistingSettings.isActive = params._swapWhitelistingSettings.isActive; emit UpdatedSwapWhitelistingActiveStatus(s.swapWhitelistingSettings.isActive); } } } // File contracts/interfaces/IFeeHelper.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. interface IFeeHelper { function getFee() view external returns(uint256); function getFeeDenominator() view external returns(uint256); function setFee(uint _fee) external; function getFeeAddress() view external returns(address); function setFeeAddress(address payable _feeAddress) external; function getGeneratorFee() view external returns(uint256); function setGeneratorFee(uint256 _fee) external; } // File contracts/LPWallet.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. contract LPWallet is Ownable{ ITaxToken public token; IMintFactory public factory; uint256 private threshold; event UpdatedThreshold(uint256 _newThreshold); event ETHtoTaxHelper(uint256 amount); event TransferBalancetoTaxHelper(uint256 tokenBalance); constructor(address _factory, address _token, uint256 _newThreshold) { token = ITaxToken(_token); factory = IMintFactory(_factory); threshold = _newThreshold; emit UpdatedThreshold(_newThreshold); transferOwnership(_token); } function checkLPTrigger() public view returns (bool) { return address(this).balance > threshold; } function getBalance() public view returns (uint256) { return address(this).balance; } function sendEthToTaxHelper() external returns (uint256) { uint index = token.taxHelperIndex(); require(msg.sender == factory.getTaxHelperAddress(index), "RA"); uint256 amount = address(this).balance; (bool sent,) = msg.sender.call{value: amount}(""); require(sent, "Failed to send Ether"); emit ETHtoTaxHelper(amount); return amount; } function transferBalanceToTaxHelper() external { uint index = token.taxHelperIndex(); require(msg.sender == factory.getTaxHelperAddress(index)); uint256 tokenBalance = token.balanceOf(address(this)); token.transfer(msg.sender, tokenBalance); emit TransferBalancetoTaxHelper(tokenBalance); } function updateThreshold(uint256 _newThreshold) external onlyOwner { threshold = _newThreshold; emit UpdatedThreshold(_newThreshold); } function getThreshold() external view returns (uint256) { return threshold; } receive() payable external { } } // File contracts/facets/Settings.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. contract SettingsFacet is Ownable { Storage internal s; event AddedLPToken(address _newLPToken); event RemovedLPToken(address _lpToken); event AddedBlacklistAddress(address _address); event RemovedBlacklistAddress(address _address); event ToggledPause(bool _isPaused); event UpdatedCustomTaxes(CustomTax[] _customTaxes); event UpdatedTaxFees(Fees _updatedFees); event UpdatedTransactionTaxAddress(address _newAddress); event UpdatedLockedSettings(TaxSettings _updatedLocks); event UpdatedSettings(TaxSettings _updatedSettings); event UpdatedPairAddress(address _newPairAddress); event UpdatedTaxHelperIndex(uint _newIndex); event ExcludedAccount(address account); event AddedTaxWhitelistAddress(address _address); event RemovedTaxWhitelistAddress(address _address); function canBlacklistRequire() internal view { require(s.taxSettings.canBlacklist, "NB"); } modifier canBlacklist { canBlacklistRequire(); _; } function addLPToken(address _newLPToken) public onlyOwner { s.lpTokens[_newLPToken] = true; emit AddedLPToken(_newLPToken); } function removeLPToken(address _lpToken) public onlyOwner { s.lpTokens[_lpToken] = false; emit RemovedLPToken(_lpToken); } function checkMaxTax(bool isBuy) internal view returns (bool) { uint256 totalTaxes; if(isBuy) { totalTaxes += s.fees.transactionTax.buy; totalTaxes += s.fees.holderTax; for(uint i = 0; i < s.customTaxes.length; i++) { totalTaxes += s.customTaxes[i].fee.buy; } } else { totalTaxes += s.fees.transactionTax.sell; totalTaxes += s.fees.lpTax; totalTaxes += s.fees.holderTax; totalTaxes += s.fees.buyBackTax; for(uint i = 0; i < s.customTaxes.length; i++) { totalTaxes += s.customTaxes[i].fee.sell; } } if(totalTaxes <= s.MaxTax) { return true; } return false; } function paused() public view returns (bool) { if(s.taxSettings.canPause == false) { return false; } return s.isPaused; } function togglePause() public onlyOwner returns (bool) { require(s.taxSettings.canPause, "NP"); s.isPaused = !s.isPaused; emit ToggledPause(s.isPaused); return s.isPaused; } function addBlacklistedAddress(address _address) public onlyOwner canBlacklist { IFeeHelper feeHelper = IFeeHelper(IMintFactory(s.factory).getFeeHelper()); address feeAddress = feeHelper.getFeeAddress(); require(_address != feeAddress); s.blacklist[_address] = true; emit AddedBlacklistAddress(_address); } function removeBlacklistedAddress(address _address) public onlyOwner canBlacklist { s.blacklist[_address] = false; emit RemovedBlacklistAddress(_address); } function updateBlacklistBatch(address[] calldata _updatedAddresses, bool _isBlacklisted) public onlyOwner canBlacklist { IFeeHelper feeHelper = IFeeHelper(IMintFactory(s.factory).getFeeHelper()); address feeAddress = feeHelper.getFeeAddress(); for(uint i = 0; i < _updatedAddresses.length; i++) { if(_updatedAddresses[i] != feeAddress) { s.blacklist[_updatedAddresses[i]] = _isBlacklisted; if(_isBlacklisted) { emit AddedBlacklistAddress(_updatedAddresses[i]); } else { emit RemovedBlacklistAddress(_updatedAddresses[i]); } } } } function isBlacklisted(address _address) public view returns (bool) { return s.blacklist[_address]; } function updateCustomTaxes(CustomTax[] calldata _customTaxes) public onlyOwner { require(_customTaxes.length < s.MaxCustom + 1, "MCT"); delete s.customTaxes; for(uint i = 0; i < _customTaxes.length; i++) { require(_customTaxes[i].wallet != address(0)); s.customTaxes.push(_customTaxes[i]); } s.customTaxLength = _customTaxes.length; require(checkMaxTax(true), "BF"); require(checkMaxTax(false), "SF"); emit UpdatedCustomTaxes(_customTaxes); } function updateTaxFees(Fees calldata _updatedFees) public onlyOwner { s.fees.transactionTax.buy = _updatedFees.transactionTax.buy; s.fees.transactionTax.sell = _updatedFees.transactionTax.sell; s.fees.buyBackTax = _updatedFees.buyBackTax; s.fees.holderTax = _updatedFees.holderTax; s.fees.lpTax = _updatedFees.lpTax; require(checkMaxTax(true), "BF"); require(checkMaxTax(false), "SF"); emit UpdatedTaxFees(_updatedFees); } function updateTransactionTaxAddress(address _newAddress) public onlyOwner { // confirm if this is updateable require(_newAddress != address(0)); s.transactionTaxWallet = _newAddress; emit UpdatedTransactionTaxAddress(_newAddress); } function lockSettings(TaxSettings calldata _updatedLocks) public onlyOwner { if(!s.isLocked.transactionTax) { s.isLocked.transactionTax = _updatedLocks.transactionTax; } if(!s.isLocked.holderTax) { s.isLocked.holderTax = _updatedLocks.holderTax; } if(!s.isLocked.buyBackTax) { s.isLocked.buyBackTax = _updatedLocks.buyBackTax; } if(!s.isLocked.lpTax) { s.isLocked.lpTax = _updatedLocks.lpTax; } if(!s.isLocked.canMint) { s.isLocked.canMint = _updatedLocks.canMint; } if(!s.isLocked.canPause) { s.isLocked.canPause = _updatedLocks.canPause; } if(!s.isLocked.canBlacklist) { s.isLocked.canBlacklist = _updatedLocks.canBlacklist; } if(!s.isLocked.maxBalanceAfterBuy) { s.isLocked.maxBalanceAfterBuy = _updatedLocks.maxBalanceAfterBuy; } emit UpdatedLockedSettings(s.isLocked); } function updateSettings(TaxSettings calldata _updatedSettings) public onlyOwner { if(!s.isLocked.transactionTax && s.taxSettings.transactionTax != _updatedSettings.transactionTax) { s.taxSettings.transactionTax = _updatedSettings.transactionTax; } if(!s.isLocked.holderTax && s.taxSettings.holderTax != _updatedSettings.holderTax && !_updatedSettings.canMint) { s.taxSettings.holderTax = _updatedSettings.holderTax; } if(!s.isLocked.buyBackTax && s.taxSettings.buyBackTax != _updatedSettings.buyBackTax) { s.taxSettings.buyBackTax = _updatedSettings.buyBackTax; } if(!s.isLocked.lpTax && s.taxSettings.lpTax != _updatedSettings.lpTax) { s.taxSettings.lpTax = _updatedSettings.lpTax; } if(!s.isLocked.canMint && s.taxSettings.canMint != _updatedSettings.canMint && !s.taxSettings.holderTax) { s.taxSettings.canMint = _updatedSettings.canMint; } if(!s.isLocked.canPause && s.taxSettings.canPause != _updatedSettings.canPause) { s.taxSettings.canPause = _updatedSettings.canPause; } if(!s.isLocked.canBlacklist && s.taxSettings.canBlacklist != _updatedSettings.canBlacklist) { s.taxSettings.canBlacklist = _updatedSettings.canBlacklist; } if(!s.isLocked.maxBalanceAfterBuy && s.taxSettings.maxBalanceAfterBuy != _updatedSettings.maxBalanceAfterBuy) { s.taxSettings.maxBalanceAfterBuy = _updatedSettings.maxBalanceAfterBuy; } emit UpdatedSettings(s.taxSettings); } function updatePairAddress(address _newPairAddress) public onlyOwner { s.pairAddress = _newPairAddress; s.lpTokens[_newPairAddress] = true; emit AddedLPToken(_newPairAddress); emit UpdatedPairAddress(_newPairAddress); } function updateTaxHelperIndex(uint8 _newIndex) public onlyOwner { s.taxHelperIndex = _newIndex; address taxHelper = IMintFactory(s.factory).getTaxHelperAddress(s.taxHelperIndex); s._isExcluded[taxHelper] = true; s._excluded.push(taxHelper); emit ExcludedAccount(taxHelper); emit UpdatedTaxHelperIndex(_newIndex); } function addTaxWhitelistedAddress(address _address) public onlyOwner { s.taxWhitelist[_address] = true; emit AddedTaxWhitelistAddress(_address); } function removeTaxWhitelistedAddress(address _address) public onlyOwner { s.taxWhitelist[_address] = false; emit RemovedTaxWhitelistAddress(_address); } function updateTaxWhitelistBatch(address[] calldata _updatedAddresses, bool _isTaxWhitelisted) public onlyOwner { for(uint i = 0; i < _updatedAddresses.length; i++) { s.taxWhitelist[_updatedAddresses[i]] = _isTaxWhitelisted; if(_isTaxWhitelisted) { emit AddedTaxWhitelistAddress(_updatedAddresses[i]); } else { emit RemovedTaxWhitelistAddress(_updatedAddresses[i]); } } } } // File contracts/libraries/FullMath.sol // /// @title Contains 512-bit math functions /// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision /// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits library FullMath { /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv function mulDiv( uint256 a, uint256 b, uint256 denominator ) internal pure returns (uint256 result) { // 512-bit multiply [prod1 prod0] = a * b // Compute the product mod 2**256 and mod 2**256 - 1 // then use the Chinese Remainder Theorem to reconstruct // the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2**256 + prod0 uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(a, b, not(0)) prod0 := mul(a, b) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division if (prod1 == 0) { require(denominator > 0); assembly { result := div(prod0, denominator) } return result; } // Make sure the result is less than 2**256. // Also prevents denominator == 0 require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0] // Compute remainder using mulmod uint256 remainder; assembly { remainder := mulmod(a, b, denominator) } // Subtract 256 bit number from 512 bit number assembly { prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator // Compute largest power of two divisor of denominator. // Always >= 1. unchecked { uint256 twos = (type(uint256).max - denominator + 1) & denominator; // Divide denominator by power of two assembly { denominator := div(denominator, twos) } // Divide [prod1 prod0] by the factors of two assembly { prod0 := div(prod0, twos) } // Shift in bits from prod1 into prod0. For this we need // to flip `twos` such that it is 2**256 / twos. // If twos is zero, then it becomes one assembly { twos := add(div(sub(0, twos), twos), 1) } prod0 |= prod1 * twos; // Invert denominator mod 2**256 // Now that denominator is an odd number, it has an inverse // modulo 2**256 such that denominator * inv = 1 mod 2**256. // Compute the inverse by starting with a seed that is correct // correct for four bits. That is, denominator * inv = 1 mod 2**4 uint256 inv = (3 * denominator) ^ 2; // Now use Newton-Raphson iteration to improve the precision. // Thanks to Hensel's lifting lemma, this also works in modular // arithmetic, doubling the correct bits in each step. inv *= 2 - denominator * inv; // inverse mod 2**8 inv *= 2 - denominator * inv; // inverse mod 2**16 inv *= 2 - denominator * inv; // inverse mod 2**32 inv *= 2 - denominator * inv; // inverse mod 2**64 inv *= 2 - denominator * inv; // inverse mod 2**128 inv *= 2 - denominator * inv; // inverse mod 2**256 // Because the division is now exact we can divide by multiplying // with the modular inverse of denominator. This will give us the // correct result modulo 2**256. Since the precoditions guarantee // that the outcome is less than 2**256, this is the final result. // We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inv; return result; } } /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result function mulDivRoundingUp( uint256 a, uint256 b, uint256 denominator ) internal pure returns (uint256 result) { result = mulDiv(a, b, denominator); if (mulmod(a, b, denominator) > 0) { require(result < type(uint256).max); result++; } } } // File contracts/facets/Tax.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. // This contract logs all tokens on the platform contract TaxFacet is Ownable { Storage internal s; event MarketInit(uint256 timestamp, uint256 blockNumber); event BuyBackTaxInitiated(address _sender, uint256 _fee, address _wallet, bool _isBuy); event TransactionTaxInitiated(address _sender, uint256 _fee, address _wallet, bool _isBuy); event LPTaxInitiated(address _sender, uint256 _fee, address _wallet, bool _isBuy); event CustomTaxInitiated(address _sender, uint256 _fee, address _wallet, bool _isBuy); event Transfer(address indexed from, address indexed to, uint256 value); event Reflect(uint256 tAmount, uint256 rAmount, uint256 rTotal_, uint256 teeTotal_); event ExcludedAccount(address account); event IncludedAccount(address account); function paused() internal view returns (bool) { return s.isPaused; } function isBlacklisted(address _address) internal view returns (bool) { return s.blacklist[_address]; } /// @notice Handles the taxes for the token. /// Calls the appropriate tax helper contract to handle /// LP and BuyBack tax logic /// @dev handles every tax within the tax facet. /// @param sender the one sending the transaction /// @param recipient the one receiving the transaction /// @param amount the amount of tokens being sent /// @return totalTaxAmount the total amount of the token taxed function handleTaxes(address sender, address recipient, uint256 amount) public virtual returns (uint256 totalTaxAmount) { // restrict it to being only called by registered tokens require(IMintFactory(s.factory).tokenIsRegistered(address(this))); bool isBuy = false; if(s.lpTokens[sender]) { isBuy = true; if(!s.marketInit) { s.marketInit = true; s.antiBotSettings.startBlock = block.number; s.marketInitBlockTime = block.timestamp; emit MarketInit(block.timestamp, block.number); } } if(!s.lpTokens[sender] && !s.lpTokens[recipient]) { return 0; } if(isBuy && s.taxWhitelist[recipient]) { return 0; } if(!isBuy && s.taxWhitelist[sender]) { return 0; } ITaxHelper TaxHelper = ITaxHelper(IMintFactory(s.factory).getTaxHelperAddress(s.taxHelperIndex)); if(sender == address(TaxHelper) || recipient == address(TaxHelper)) { return 0; } totalTaxAmount; uint256 fee; if(s.taxSettings.buyBackTax && !isBuy) { if(TaxHelper.lpTokenHasReserves(s.pairAddress)) { fee = amount * s.fees.buyBackTax / s.DENOMINATOR; } if(fee != 0) { _transfer(sender, address(TaxHelper), fee); TaxHelper.initiateBuyBackTax(address(this), address(s.buyBackWallet)); emit BuyBackTaxInitiated(sender, fee, address(s.buyBackWallet), isBuy); totalTaxAmount += fee; } fee = 0; } if(s.taxSettings.transactionTax) { if(isBuy) { fee = amount * s.fees.transactionTax.buy / s.DENOMINATOR; } else { fee = amount * s.fees.transactionTax.sell / s.DENOMINATOR; } if(fee != 0) { _transfer(sender, s.transactionTaxWallet, fee); emit TransactionTaxInitiated(sender, fee, s.transactionTaxWallet, isBuy); totalTaxAmount += fee; } fee = 0; } if(s.taxSettings.lpTax && !isBuy) { if(TaxHelper.lpTokenHasReserves(s.pairAddress)) { fee = amount * s.fees.lpTax / s.DENOMINATOR; } if(fee != 0) { _transfer(sender, address(TaxHelper), fee); TaxHelper.initiateLPTokenTax(address(this), address(s.lpWallet)); emit LPTaxInitiated(sender, fee, address(s.lpWallet), isBuy); totalTaxAmount += fee; } fee = 0; } if(s.customTaxes.length > 0) { for(uint8 i = 0; i < s.customTaxes.length; i++) { uint256 customFee; if(isBuy) { customFee = amount * s.customTaxes[i].fee.buy / s.DENOMINATOR; } else { customFee = amount * s.customTaxes[i].fee.sell / s.DENOMINATOR; } fee += customFee; if(fee != 0) { totalTaxAmount += fee; _transfer(sender, s.customTaxes[i].wallet, fee); emit CustomTaxInitiated(sender, fee, s.customTaxes[i].wallet, isBuy); fee = 0; } } } } /// @notice internal transfer method /// @dev includes checks for all features not handled by handleTaxes() /// @param sender the one sending the transaction /// @param recipient the one receiving the transaction /// @param amount the amount of tokens being sent function _transfer(address sender, address recipient, uint256 amount) public { // restrict it to being only called by registered tokens if(!IMintFactory(s.factory).tokenGeneratorIsAllowed(msg.sender)) { require(IMintFactory(s.factory).tokenIsRegistered(address(this))); } require(sender != address(0), "ETFZ"); require(recipient != address(0), "ETTZ"); require(amount > 0, "TGZ"); require(!paused(), "TP"); require(!isBlacklisted(sender), "SB"); require(!isBlacklisted(recipient), "RB"); require(!isBlacklisted(tx.origin), "SB"); _beforeTokenTransfer(sender, recipient, amount); // Reflection Transfers if(s.taxSettings.holderTax) { if (s._isExcluded[sender] && !s._isExcluded[recipient]) { _transferFromExcluded(sender, recipient, amount); } else if (!s._isExcluded[sender] && s._isExcluded[recipient]) { _transferToExcluded(sender, recipient, amount); } else if (!s._isExcluded[sender] && !s._isExcluded[recipient]) { _transferStandard(sender, recipient, amount); } else if (s._isExcluded[sender] && s._isExcluded[recipient]) { _transferBothExcluded(sender, recipient, amount); } else { _transferStandard(sender, recipient, amount); } } else { // Non Reflection Transfer uint256 senderBalance = s._tOwned[sender]; require(senderBalance >= amount, "ETA"); s._tOwned[sender] = senderBalance - amount; s._tOwned[recipient] += amount; emit Transfer(sender, recipient, amount); } } function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } // Reflection Functions function reflect(uint256 tAmount) public { address sender = _msgSender(); require(!s._isExcluded[sender], "EA"); (uint256 rAmount,,,,) = _getValues(tAmount); s._rOwned[sender] = s._rOwned[sender] - rAmount; s._rTotal = s._rTotal - rAmount; s._tFeeTotal = s._tFeeTotal + tAmount; emit Reflect(tAmount, rAmount, s._rTotal, s._tFeeTotal); ITaxHelper TaxHelper = ITaxHelper(IMintFactory(s.factory).getTaxHelperAddress(s.taxHelperIndex)); TaxHelper.sync(s.pairAddress); } function reflectionFromToken(uint256 tAmount, bool deductTransferFee) public view returns(uint256) { require(tAmount <= s._tTotal, "ALS"); if (!deductTransferFee) { (uint256 rAmount,,,,) = _getValues(tAmount); return rAmount; } else { (,uint256 rTransferAmount,,,) = _getValues(tAmount); return rTransferAmount; } } function tokenFromReflection(uint256 rAmount) public view returns(uint256) { require(rAmount <= s._rTotal, "ALR"); uint256 currentRate = _getRate(); return rAmount / currentRate; } function excludeAccount(address account) external onlyOwner { require(!s._isExcluded[account], "AE"); if(s._rOwned[account] > 0) { s._tOwned[account] = tokenFromReflection(s._rOwned[account]); } s._isExcluded[account] = true; s._excluded.push(account); emit ExcludedAccount(account); } function includeAccount(address account) external onlyOwner { require(s._isExcluded[account], "AI"); for (uint256 i = 0; i < s._excluded.length; i++) { if (s._excluded[i] == account) { s._excluded[i] = s._excluded[s._excluded.length - 1]; s._tOwned[account] = 0; s._isExcluded[account] = false; s._excluded.pop(); break; } } emit IncludedAccount(account); } function isExcluded(address account) external view returns(bool) { return s._isExcluded[account]; } function _transferStandard(address sender, address recipient, uint256 tAmount) private { (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount); s._rOwned[sender] = s._rOwned[sender] - rAmount; s._rOwned[recipient] = s._rOwned[recipient] + rTransferAmount; _reflectFee(rFee, tFee); emit Transfer(sender, recipient, tTransferAmount); } function _transferToExcluded(address sender, address recipient, uint256 tAmount) private { (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount); s._rOwned[sender] = s._rOwned[sender] - rAmount; s._tOwned[recipient] = s._tOwned[recipient] + tTransferAmount; s._rOwned[recipient] = s._rOwned[recipient] + rTransferAmount; _reflectFee(rFee, tFee); emit Transfer(sender, recipient, tTransferAmount); } function _transferFromExcluded(address sender, address recipient, uint256 tAmount) private { (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount); s._tOwned[sender] = s._tOwned[sender] - tAmount; s._rOwned[sender] = s._rOwned[sender] - rAmount; s._rOwned[recipient] = s._rOwned[recipient] + rTransferAmount; _reflectFee(rFee, tFee); emit Transfer(sender, recipient, tTransferAmount); } function _transferBothExcluded(address sender, address recipient, uint256 tAmount) private { (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount); s._tOwned[sender] = s._tOwned[sender] - tAmount; s._rOwned[sender] = s._rOwned[sender] - rAmount; s._tOwned[recipient] = s._tOwned[recipient] + tTransferAmount; s._rOwned[recipient] = s._rOwned[recipient] + rTransferAmount; _reflectFee(rFee, tFee); emit Transfer(sender, recipient, tTransferAmount); } function _reflectFee(uint256 rFee, uint256 tFee) private { s._rTotal = s._rTotal - rFee; s._tFeeTotal = s._tFeeTotal + tFee; } function _getValues(uint256 tAmount) private view returns (uint256, uint256, uint256, uint256, uint256) { (uint256 tTransferAmount, uint256 tFee) = _getTValues(tAmount); uint256 currentRate = _getRate(); (uint256 rAmount, uint256 rTransferAmount, uint256 rFee) = _getRValues(tAmount, tFee, currentRate); return (rAmount, rTransferAmount, rFee, tTransferAmount, tFee); } function _getTValues(uint256 tAmount) private view returns (uint256, uint256) { uint256 tFee = tAmount / s.fees.holderTax; uint256 tTransferAmount = tAmount - tFee; return (tTransferAmount, tFee); } function _getRValues(uint256 tAmount, uint256 tFee, uint256 currentRate) private pure returns (uint256, uint256, uint256) { uint256 rAmount = tAmount * currentRate; uint256 rFee = tFee * currentRate; uint256 rTransferAmount = rAmount - rFee; return (rAmount, rTransferAmount, rFee); } function _getRate() private view returns(uint256) { (uint256 rSupply, uint256 tSupply) = _getCurrentSupply(); return rSupply / tSupply; } function _getCurrentSupply() private view returns(uint256, uint256) { uint256 rSupply = s._rTotal; uint256 tSupply = s._tTotal; for (uint256 i = 0; i < s._excluded.length; i++) { if (s._rOwned[s._excluded[i]] > rSupply || s._tOwned[s._excluded[i]] > tSupply) return (s._rTotal, s._tTotal); rSupply = rSupply - s._rOwned[s._excluded[i]]; tSupply = tSupply - s._tOwned[s._excluded[i]]; } if (rSupply < s._rTotal / s._tTotal) return (s._rTotal, s._tTotal); return (rSupply, tSupply); } function burn(uint256 amount) public { address taxHelper = IMintFactory(s.factory).getTaxHelperAddress(s.taxHelperIndex); require(msg.sender == taxHelper || msg.sender == owner(), "RA"); _burn(owner(), amount); } /// @notice custom burn to handle reflection function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "EBZ"); if (s.isLosslessOn) { ILosslessController(IMintFactory(s.factory).getLosslessController()).beforeBurn(account, amount); } _beforeTokenTransfer(account, address(0), amount); if(s.taxSettings.holderTax && !s._isExcluded[account]) { (uint256 rAmount,,,,) = _getValues(amount); s._rOwned[account] = s._rOwned[account] - rAmount; s._rTotal = s._rTotal - rAmount; s._tFeeTotal = s._tFeeTotal + amount; } uint256 accountBalance = s._tOwned[account]; require(accountBalance >= amount, "EBB"); s._tOwned[account] = accountBalance - amount; s._tTotal -= amount; emit Transfer(account, address(0), amount); } } // File contracts/facets/Wallets.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. contract WalletsFacet is Ownable { Storage internal s; event CreatedBuyBackWallet(address _wallet); event CreatedLPWallet(address _wallet); event UpdatedBuyBackWalletThreshold(uint256 _newThreshold); event UpdatedLPWalletThreshold(uint256 _newThreshold); function createBuyBackWallet(address _factory, address _token, uint256 _newThreshold) external returns (address) { BuyBackWallet newBuyBackWallet = new BuyBackWallet(_factory, _token,_newThreshold); emit CreatedBuyBackWallet(address(newBuyBackWallet)); return address(newBuyBackWallet); } function createLPWallet(address _factory, address _token, uint256 _newThreshold) external returns (address) { LPWallet newLPWallet = new LPWallet(_factory, _token, _newThreshold); emit CreatedLPWallet(address(newLPWallet)); return address(newLPWallet); } function updateBuyBackWalletThreshold(uint256 _newThreshold) public onlyOwner { IBuyBackWallet(s.buyBackWallet).updateThreshold(_newThreshold); emit UpdatedBuyBackWalletThreshold(_newThreshold); } function updateLPWalletThreshold(uint256 _newThreshold) public onlyOwner { ILPWallet(s.lpWallet).updateThreshold(_newThreshold); emit UpdatedLPWalletThreshold(_newThreshold); } } // File contracts/FeeHelper.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. contract FeeHelper is Ownable{ struct Settings { uint256 GENERATOR_FEE; uint256 FEE; uint256 DENOMINATOR; address payable FEE_ADDRESS; } Settings public SETTINGS; constructor() { SETTINGS.GENERATOR_FEE = 0; SETTINGS.FEE = 100; SETTINGS.DENOMINATOR = 10000; SETTINGS.FEE_ADDRESS = payable(msg.sender); } function getGeneratorFee() external view returns(uint256) { return SETTINGS.GENERATOR_FEE; } function getFee() external view returns(uint256) { return SETTINGS.FEE; } function getFeeDenominator() external view returns(uint256) { return SETTINGS.DENOMINATOR; } function setGeneratorFee(uint256 _fee) external onlyOwner { SETTINGS.GENERATOR_FEE = _fee; } function setFee(uint _fee) external onlyOwner { SETTINGS.FEE = _fee; } function getFeeAddress() external view returns(address) { return SETTINGS.FEE_ADDRESS; } function setFeeAddress(address payable _feeAddress) external onlyOwner { SETTINGS.FEE_ADDRESS = _feeAddress; } } // File contracts/interfaces/IUniswapV2Router01.sol interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); } // File contracts/interfaces/ICamelotV2Router.sol interface ICamelotRouter is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, address referrer, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, address referrer, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, address referrer, uint deadline ) external; } // File contracts/interfaces/IUniswapV2Router02.sol interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; } // File contracts/libraries/ERC20.sol // // File @openzeppelin/contracts/token/ERC20/[email protected] /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20 { mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The defaut value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All three of these values are immutable: they can only be set once during * construction. */ constructor (string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual 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 this function is * overloaded; * * 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 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `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); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); _approve(sender, _msgSender(), currentAllowance - amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); _approve(_msgSender(), spender, currentAllowance - subtractedValue); 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); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); _balances[sender] = senderBalance - amount; _balances[recipient] += 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 += amount; _balances[account] += 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); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); _balances[account] = accountBalance - amount; _totalSupply -= 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 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 { } } // File contracts/libraries/Pausable.sol // // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } // File contracts/libraries/EnumerableSet.sol // // OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol) /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; assembly { result := store } return result; } } // File contracts/MintFactory.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. // This contract logs all tokens on the platform contract MintFactory is Ownable { using EnumerableSet for EnumerableSet.AddressSet; EnumerableSet.AddressSet private tokens; EnumerableSet.AddressSet private tokenGenerators; struct TaxHelper { string Name; address Address; uint256 Index; } mapping(uint => TaxHelper) private taxHelpersData; address[] private taxHelpers; mapping(address => address[]) private tokenOwners; address private FacetHelper; address private FeeHelper; address private LosslessController; event TokenRegistered(address tokenOwner, address tokenContract); event AllowTokenGenerator(address _address, bool _allow); event AddedTaxHelper(string _name, address _address, uint256 _index); event UpdatedTaxHelper(address _newAddress, uint256 _index); event UpdatedFacetHelper(address _newAddress); event UpdatedFeeHelper(address _newAddress); event UpdatedLosslessController(address _newAddress); function adminAllowTokenGenerator (address _address, bool _allow) public onlyOwner { if (_allow) { tokenGenerators.add(_address); } else { tokenGenerators.remove(_address); } emit AllowTokenGenerator(_address, _allow); } function addTaxHelper(string calldata _name, address _address) public onlyOwner { uint256 index = taxHelpers.length; TaxHelper memory newTaxHelper; newTaxHelper.Name = _name; newTaxHelper.Address = _address; newTaxHelper.Index = index; taxHelpersData[index] = newTaxHelper; taxHelpers.push(_address); emit AddedTaxHelper(_name, _address, index); } function updateTaxHelper(uint256 _index, address _address) public onlyOwner { taxHelpersData[_index].Address = _address; taxHelpers[_index] = _address; emit UpdatedTaxHelper(_address, _index); } function getTaxHelperAddress(uint256 _index) public view returns(address){ return taxHelpers[_index]; } function getTaxHelpersDataByIndex(uint256 _index) public view returns(TaxHelper memory) { return taxHelpersData[_index]; } /** * @notice called by a registered tokenGenerator upon token creation */ function registerToken (address _tokenOwner, address _tokenAddress) public { require(tokenGenerators.contains(msg.sender), 'FORBIDDEN'); tokens.add(_tokenAddress); tokenOwners[_tokenOwner].push(_tokenAddress); emit TokenRegistered(_tokenOwner, _tokenAddress); } /** * @notice gets a token at index registered under a user address * @return token addresses registered to the user address */ function getTokenByOwnerAtIndex(address _tokenOwner, uint256 _index) external view returns(address) { return tokenOwners[_tokenOwner][_index]; } /** * @notice gets the total of tokens registered under a user address * @return uint total of token addresses registered to the user address */ function getTokensLengthByOwner(address _tokenOwner) external view returns(uint256) { return tokenOwners[_tokenOwner].length; } /** * @notice Number of allowed tokenGenerators */ function tokenGeneratorsLength() external view returns (uint256) { return tokenGenerators.length(); } /** * @notice Gets the address of a registered tokenGenerator at specified index */ function tokenGeneratorAtIndex(uint256 _index) external view returns (address) { return tokenGenerators.at(_index); } /** * @notice returns true if user is allowed to generate tokens */ function tokenGeneratorIsAllowed(address _tokenGenerator) external view returns (bool) { return tokenGenerators.contains(_tokenGenerator); } /** * @notice returns true if the token address was generated by the Unicrypt token platform */ function tokenIsRegistered(address _tokenAddress) external view returns (bool) { return tokens.contains(_tokenAddress); } /** * @notice The length of all tokens on the platform */ function tokensLength() external view returns (uint256) { return tokens.length(); } /** * @notice gets a token at a specific index. Although using Enumerable Set, since tokens are only added and not removed, indexes will never change * @return the address of the token contract at index */ function tokenAtIndex(uint256 _index) external view returns (address) { return tokens.at(_index); } // Helpers and Controllers function getFacetHelper() public view returns (address) { return FacetHelper; } function updateFacetHelper(address _newFacetHelperAddress) public onlyOwner { require(_newFacetHelperAddress != address(0)); FacetHelper = _newFacetHelperAddress; emit UpdatedFacetHelper(_newFacetHelperAddress); } function getFeeHelper() public view returns (address) { return FeeHelper; } function updateFeeHelper(address _newFeeHelperAddress) public onlyOwner { require(_newFeeHelperAddress != address(0)); FeeHelper = _newFeeHelperAddress; emit UpdatedFeeHelper(_newFeeHelperAddress); } function getLosslessController() public view returns (address) { return LosslessController; } function updateLosslessController(address _newLosslessControllerAddress) public onlyOwner { require(_newLosslessControllerAddress != address(0)); LosslessController = _newLosslessControllerAddress; emit UpdatedLosslessController(_newLosslessControllerAddress); } } // File contracts/TaxToken.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. contract TaxToken is Ownable{ Storage internal s; event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); struct ConstructorParams { string name_; string symbol_; uint8 decimals_; address creator_; uint256 tTotal_; uint256 _maxTax; TaxSettings _settings; TaxSettings _lockedSettings; Fees _fees; address _transactionTaxWallet; CustomTax[] _customTaxes; uint256 lpWalletThreshold; uint256 buyBackWalletThreshold; uint256 _taxHelperIndex; address admin_; address recoveryAdmin_; bool isLossless_; AntiBotSettings _antiBotSettings; uint256 _maxBalanceAfterBuy; SwapWhitelistingSettings _swapWhitelistingSettings; } constructor( ConstructorParams memory params, address _factory ) { address constructorFacetAddress = IFacetHelper(IMintFactory(_factory).getFacetHelper()).getConstructorFacet(); (bool success, bytes memory result) = constructorFacetAddress.delegatecall(abi.encodeWithSignature("constructorHandler((string,string,uint8,address,uint256,uint256,(bool,bool,bool,bool,bool,bool,bool,bool),(bool,bool,bool,bool,bool,bool,bool,bool),((uint256,uint256),uint256,uint256,uint256),address,(string,(uint256,uint256),address,bool)[],uint256,uint256,uint256,address,address,bool,(uint256,uint256,uint256,uint256,bool),uint256,(uint256,bool)),address)", params, _factory)); if (!success) { if (result.length < 68) revert(); revert(abi.decode(result, (string))); } IFeeHelper feeHelper = IFeeHelper(IMintFactory(s.factory).getFeeHelper()); uint256 fee = FullMath.mulDiv(params.tTotal_, feeHelper.getFee(), feeHelper.getFeeDenominator()); address feeAddress = feeHelper.getFeeAddress(); _approve(params.creator_, msg.sender, fee); s.isTaxed = true; transferFrom(params.creator_, feeAddress, fee); } /// @notice this is the power behind Lossless function transferOutBlacklistedFunds(address[] calldata from) external { require(s.isLosslessOn); // added by us for extra protection require(_msgSender() == address(IMintFactory(s.factory).getLosslessController()), "LOL"); for (uint i = 0; i < from.length; i++) { _transfer(from[i], address(IMintFactory(s.factory).getLosslessController()), balanceOf(from[i])); } } /// @notice Checks whether an address is blacklisted /// @param _address the address to check /// @return bool is blacklisted or not function isBlacklisted(address _address) public view returns (bool) { return s.blacklist[_address]; } /// @notice Checks whether the contract has paused transactions /// @return bool is paused or not function paused() public view returns (bool) { if(s.taxSettings.canPause == false) { return false; } return s.isPaused; } /// @notice Handles the burning of token during the buyback tax process /// @dev must first receive the amount to be burned from the taxHelper contract (see initial transfer in function) /// @param _amount the amount to burn function buyBackBurn(uint256 _amount) external { address taxHelper = IMintFactory(s.factory).getTaxHelperAddress(s.taxHelperIndex); require(msg.sender == taxHelper, "RA"); _transfer(taxHelper, owner(), _amount); address taxFacetAddress = IFacetHelper(IMintFactory(s.factory).getFacetHelper()).getTaxFacet(); (bool success, bytes memory result) = taxFacetAddress.delegatecall(abi.encodeWithSignature("burn(uint256)", _amount)); if (!success) { if (result.length < 68) revert(); revert(abi.decode(result, (string))); } } /// @notice Handles the taxes for the token. /// @dev handles every tax within the tax facet. /// @param sender the one sending the transaction /// @param recipient the one receiving the transaction /// @param amount the amount of tokens being sent /// @return totalTaxAmount the total amount of the token taxed function handleTaxes(address sender, address recipient, uint256 amount) internal virtual returns (uint256 totalTaxAmount) { address taxFacetAddress = IFacetHelper(IMintFactory(s.factory).getFacetHelper()).getTaxFacet(); (bool success, bytes memory result) = taxFacetAddress.delegatecall(abi.encodeWithSignature("handleTaxes(address,address,uint256)", sender, recipient, amount)); if (!success) { if (result.length < 68) revert(); revert(abi.decode(result, (string))); } return abi.decode(result, (uint256)); } // Getters function name() public view returns (string memory) { return s._name; } function symbol() public view returns (string memory) { return s._symbol; } function decimals() public view returns (uint8) { return s._decimals; } function totalSupply() public view returns (uint256) { return s._tTotal; } function CONTRACT_VERSION() public view returns (uint256) { return s.CONTRACT_VERSION; } function taxSettings() public view returns (TaxSettings memory) { return s.taxSettings; } function isLocked() public view returns (TaxSettings memory) { return s.isLocked; } function fees() public view returns (Fees memory) { return s.fees; } function customTaxes(uint _index) public view returns (CustomTax memory) { return s.customTaxes[_index]; } function transactionTaxWallet() public view returns (address) { return s.transactionTaxWallet; } function customTaxLength() public view returns (uint256) { return s.customTaxLength; } function MaxTax() public view returns (uint256) { return s.MaxTax; } function MaxCustom() public view returns (uint8) { return s.MaxCustom; } function _allowances(address _address1, address _address2) public view returns (uint256) { return s._allowances[_address1][_address2]; } function _isExcluded(address _address) public view returns (bool) { return s._isExcluded[_address]; } function _tFeeTotal() public view returns (uint256) { return s._tFeeTotal; } function lpTokens(address _address) public view returns (bool) { return s.lpTokens[_address]; } function factory() public view returns (address) { return s.factory; } function buyBackWallet() public view returns (address) { return s.buyBackWallet; } function lpWallet() public view returns (address) { return s.lpWallet; } function pairAddress() public view returns (address) { return s.pairAddress; } function taxHelperIndex() public view returns (uint256) { return s.taxHelperIndex; } function marketInit() public view returns (bool) { return s.marketInit; } function marketInitBlockTime() public view returns (uint256) { return s.marketInitBlockTime; } function antiBotSettings() public view returns (AntiBotSettings memory) { return s.antiBotSettings; } function maxBalanceAfterBuy() public view returns (uint256) { return s.maxBalanceAfterBuy; } function swapWhitelistingSettings() public view returns (SwapWhitelistingSettings memory) { return s.swapWhitelistingSettings; } function recoveryAdmin() public view returns (address) { return s.recoveryAdmin; } function admin() public view returns (address) { return s.admin; } function timelockPeriod() public view returns (uint256) { return s.timelockPeriod; } function losslessTurnOffTimestamp() public view returns (uint256) { return s.losslessTurnOffTimestamp; } function isLosslessTurnOffProposed() public view returns (bool) { return s.isLosslessTurnOffProposed; } function isLosslessOn() public view returns (bool) { return s.isLosslessOn; } function lossless() public view returns (ILosslessController) { return ILosslessController(IMintFactory(s.factory).getLosslessController()); } // ERC20 Functions /// @dev modified to handle if the token has reflection active in it settings function balanceOf(address account) public view returns (uint256) { if(s.taxSettings.holderTax) { if (s._isExcluded[account]) return s._tOwned[account]; return tokenFromReflection(s._rOwned[account]); } return s._tOwned[account]; } // Reflection Functions // necessary to get reflection balance function tokenFromReflection(uint256 rAmount) public view returns(uint256) { require(rAmount <= s._rTotal, "ALR"); uint256 currentRate = _getRate(); return rAmount / currentRate; } function _getRate() public view returns(uint256) { (uint256 rSupply, uint256 tSupply) = _getCurrentSupply(); return rSupply / tSupply; } function _getCurrentSupply() public view returns(uint256, uint256) { uint256 rSupply = s._rTotal; uint256 tSupply = s._tTotal; for (uint256 i = 0; i < s._excluded.length; i++) { if (s._rOwned[s._excluded[i]] > rSupply || s._tOwned[s._excluded[i]] > tSupply) return (s._rTotal, s._tTotal); rSupply = rSupply - s._rOwned[s._excluded[i]]; tSupply = tSupply - s._tOwned[s._excluded[i]]; } if (rSupply < s._rTotal / s._tTotal) return (s._rTotal, s._tTotal); return (rSupply, tSupply); } // ERC20 Functions continued /// @dev modified slightly to add taxes function transfer(address recipient, uint256 amount) public returns (bool) { if(!s.isTaxed) { s.isTaxed = true; uint256 totalTaxAmount = handleTaxes(_msgSender(), recipient, amount); amount -= totalTaxAmount; } if (s.isLosslessOn) { ILosslessController(IMintFactory(s.factory).getLosslessController()).beforeTransfer(_msgSender(), recipient, amount); } _transfer(_msgSender(), recipient, amount); s.isTaxed = false; if (s.isLosslessOn) { ILosslessController(IMintFactory(s.factory).getLosslessController()).afterTransfer(_msgSender(), recipient, amount); } return true; } function allowance(address _owner, address spender) public view returns (uint256) { return s._allowances[_owner][spender]; } function approve(address spender, uint256 amount) public returns (bool) { _approve(_msgSender(), spender, amount); return true; } function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) { if(!s.isTaxed) { s.isTaxed = true; uint256 totalTaxAmount = handleTaxes(sender, recipient, amount); amount -= totalTaxAmount; } if (s.isLosslessOn) { ILosslessController(IMintFactory(s.factory).getLosslessController()).beforeTransferFrom(_msgSender(), sender, recipient, amount); } _transfer(sender, recipient, amount); uint256 currentAllowance = s._allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ETA"); _approve(sender, _msgSender(), s._allowances[sender][_msgSender()] - amount); s.isTaxed = false; if (s.isLosslessOn) { ILosslessController(IMintFactory(s.factory).getLosslessController()).afterTransfer(_msgSender(), recipient, amount); } return true; } function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { if (s.isLosslessOn) { ILosslessController(IMintFactory(s.factory).getLosslessController()).beforeIncreaseAllowance(_msgSender(), spender, addedValue); } _approve(_msgSender(), spender, s._allowances[_msgSender()][spender] + addedValue); return true; } function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { if (s.isLosslessOn) { ILosslessController(IMintFactory(s.factory).getLosslessController()).beforeDecreaseAllowance(_msgSender(), spender, subtractedValue); } uint256 currentAllowance = s._allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "EABZ"); _approve(_msgSender(), spender, currentAllowance - subtractedValue); return true; } function _approve(address _owner, address spender, uint256 amount) private { require(_owner != address(0), "EAFZ"); require(spender != address(0), "EATZ"); if (s.isLosslessOn) { ILosslessController(IMintFactory(s.factory).getLosslessController()).beforeApprove(_owner, spender, amount); } s._allowances[_owner][spender] = amount; emit Approval(_owner, spender, amount); } function _transfer(address sender, address recipient, uint256 amount) private { // AntiBot Checks address antiBotFacetAddress = IFacetHelper(IMintFactory(s.factory).getFacetHelper()).getAntiBotFacet(); if(s.marketInit && s.antiBotSettings.isActive && s.lpTokens[sender]) { (bool success, bytes memory result) = antiBotFacetAddress.delegatecall(abi.encodeWithSignature("antiBotCheck(uint256,address)", amount, recipient)); if (!success) { if (result.length < 68) revert(); revert(abi.decode(result, (string))); } } if(s.taxSettings.maxBalanceAfterBuy && s.lpTokens[sender]) { (bool success2, bytes memory result2) = antiBotFacetAddress.delegatecall(abi.encodeWithSignature("maxBalanceAfterBuyCheck(uint256,address)", amount, recipient)); if (!success2) { if (result2.length < 68) revert(); revert(abi.decode(result2, (string))); } } if(s.marketInit && s.swapWhitelistingSettings.isActive && s.lpTokens[sender]) { (bool success3, bytes memory result3) = antiBotFacetAddress.delegatecall(abi.encodeWithSignature("swapWhitelistingCheck(address)", recipient)); if (!success3) { if (result3.length < 68) revert(); revert(abi.decode(result3, (string))); } } address taxFacetAddress = IFacetHelper(IMintFactory(s.factory).getFacetHelper()).getTaxFacet(); (bool success4, bytes memory result4) = taxFacetAddress.delegatecall(abi.encodeWithSignature("_transfer(address,address,uint256)", sender, recipient, amount)); if (!success4) { if (result4.length < 68) revert(); revert(abi.decode(result4, (string))); } } function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } function mint(uint256 amount) public onlyOwner { _mint(msg.sender, amount); } /// @notice custom mint to handle fees function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "EMZ"); require(s.taxSettings.canMint, "NM"); require(!s.taxSettings.holderTax, "NM"); if (s.isLosslessOn) { ILosslessController(IMintFactory(s.factory).getLosslessController()).beforeMint(account, amount); } IFeeHelper feeHelper = IFeeHelper(IMintFactory(s.factory).getFeeHelper()); uint256 fee = FullMath.mulDiv(amount, feeHelper.getFee(), feeHelper.getFeeDenominator()); address feeAddress = feeHelper.getFeeAddress(); _beforeTokenTransfer(address(0), account, amount); s._tTotal += amount; s._tOwned[feeAddress] += fee; s._tOwned[account] += amount - fee; emit Transfer(address(0), feeAddress, fee); emit Transfer(address(0), account, amount - fee); } function burn(uint256 amount) public { address taxFacetAddress = IFacetHelper(IMintFactory(s.factory).getFacetHelper()).getTaxFacet(); (bool success, bytes memory result) = taxFacetAddress.delegatecall(abi.encodeWithSignature("burn(uint256)", amount)); if (!success) { if (result.length < 68) revert(); revert(abi.decode(result, (string))); } } /// @notice Handles all facet logic /// @dev Implements a customized version of the EIP-2535 Diamond Standard to add extra functionality to the contract /// https://github.com/mudgen/diamond-3 fallback() external { address facetHelper = IMintFactory(s.factory).getFacetHelper(); address facet = IFacetHelper(facetHelper).facetAddress(msg.sig); require(facet != address(0), "Function does not exist"); assembly { let ptr := mload(0x40) calldatacopy(ptr, 0, calldatasize()) let result := delegatecall( gas(), facet, ptr, calldatasize(), 0, 0 ) let size := returndatasize() returndatacopy(ptr, 0, size) switch result case 0 { revert(ptr, size) } default { return(ptr, size) } } } } // File contracts/MintGenerator.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. // This contract generates Token01 contracts and registers them in the TokenFactory. // Ideally you should not interact with this contract directly, and use the Unicrypt token app instead so warnings can be shown where necessary. contract MintGenerator is Ownable { uint256 public CONTRACT_VERSION = 1; IMintFactory public MINT_FACTORY; IFeeHelper public FEE_HELPER; constructor(address _mintFactory, address _feeHelper) { MINT_FACTORY = IMintFactory(_mintFactory); FEE_HELPER = IFeeHelper(_feeHelper); } /** * @notice Creates a new Token contract and registers it in the TokenFactory.sol. */ function createToken ( TaxToken.ConstructorParams calldata params ) public payable returns (address){ require(msg.value == FEE_HELPER.getGeneratorFee(), 'FEE NOT MET'); payable(FEE_HELPER.getFeeAddress()).transfer(FEE_HELPER.getGeneratorFee()); TaxToken newToken = new TaxToken(params, address(MINT_FACTORY)); MINT_FACTORY.registerToken(msg.sender, address(newToken)); return address(newToken); } } // File contracts/interfaces/IUniswapV2Factory.sol interface IUniswapV2Factory { event PairCreated(address indexed token0, address indexed token1, address pair, uint); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint) external view returns (address pair); function allPairsLength() external view returns (uint); function createPair(address tokenA, address tokenB) external returns (address pair); function setFeeTo(address) external; function setFeeToSetter(address) external; } // File contracts/interfaces/IUniswapV2Pair.sol interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; } // File contracts/TaxHelperCamelotV2.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. // add events contract TaxHelperCamelotV2 is Ownable{ ICamelotRouter router; IUniswapV2Factory factory; IMintFactory mintFactory; // event Buy event CreatedLPToken(address token0, address token1, address LPToken); constructor(address swapV2Router, address swapV2Factory, address _mintFactory) { router = ICamelotRouter(swapV2Router); factory = IUniswapV2Factory(swapV2Factory); mintFactory = IMintFactory(_mintFactory); } modifier isToken() { require(mintFactory.tokenIsRegistered(msg.sender), "RA"); _; } function initiateBuyBackTax(address _token, address _wallet) payable external isToken returns(bool) { ITaxToken token = ITaxToken(_token); uint256 _amount = token.balanceOf(address(this)); address[] memory addressPaths = new address[](2); addressPaths[0] = _token; addressPaths[1] = router.WETH(); token.approve(address(router), _amount); if(_amount > 0) { router.swapExactTokensForETHSupportingFeeOnTransferTokens(_amount, 0, addressPaths, _wallet, address(0), block.timestamp); } IBuyBackWallet buyBackWallet = IBuyBackWallet(_wallet); bool res = buyBackWallet.checkBuyBackTrigger(); if(res) { addressPaths[0] = router.WETH(); addressPaths[1] = _token; uint256 amountEth = buyBackWallet.sendEthToTaxHelper(); uint256 balanceBefore = token.balanceOf(address(this)); router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: amountEth}(0, addressPaths, address(this), address(0), block.timestamp); // burn baby burn! uint256 balanceAfter = token.balanceOf(address(this)); uint256 amountToBurn = balanceAfter - balanceBefore; token.approve(token.owner(), amountToBurn); token.buyBackBurn(amountToBurn); } return true; } function initiateLPTokenTax(address _token, address _wallet) external isToken returns (bool) { ITaxToken token = ITaxToken(_token); uint256 _amount = token.balanceOf(address(this)); address[] memory addressPaths = new address[](2); addressPaths[0] = _token; addressPaths[1] = router.WETH(); uint256 halfAmount = _amount / 2; uint256 otherHalf = _amount - halfAmount; token.transfer(_wallet, otherHalf); token.approve(address(router), halfAmount); if(halfAmount > 0) { router.swapExactTokensForETHSupportingFeeOnTransferTokens(halfAmount, 0, addressPaths, _wallet, address(0), block.timestamp); } ILPWallet lpWallet = ILPWallet(_wallet); bool res = lpWallet.checkLPTrigger(); if(res) { lpWallet.transferBalanceToTaxHelper(); uint256 amountEth = lpWallet.sendEthToTaxHelper(); uint256 tokenBalance = token.balanceOf(address(this)); token.approve(address(router), tokenBalance); router.addLiquidityETH{value: amountEth}(_token, tokenBalance, 0, 0, token.owner(), block.timestamp + 20 minutes); uint256 ethDust = address(this).balance; if(ethDust > 0) { (bool sent,) = _wallet.call{value: ethDust}(""); require(sent, "Failed to send Ether"); } uint256 tokenDust = token.balanceOf(address(this)); if(tokenDust > 0) { token.transfer(_wallet, tokenDust); } } return true; } function createLPToken() external returns(address lpToken) { // lpToken = factory.createPair(msg.sender, router.WETH()); // emit CreatedLPToken(msg.sender, router.WETH(), lpToken); // Camelot V2 fails upon LP creation during the constructor // return zaero address to be updated after creation. return address(0); } function lpTokenHasReserves(address _lpToken) public view returns (bool) { (uint112 reserve0, uint112 reserve1,) = IUniswapV2Pair(_lpToken).getReserves(); return reserve0 > 0 && reserve1 > 0; } function sync(address _lpToken) public { IUniswapV2Pair(_lpToken).sync(); } receive() payable external { } } // File contracts/TaxHelperUniswapV2.sol // // ALL RIGHTS RESERVED // Unicrypt by SDDTech reserves all rights on this code. You may NOT copy these contracts. // add events contract TaxHelperUniswapV2 is Ownable{ IUniswapV2Router02 router; IUniswapV2Factory factory; IMintFactory mintFactory; // event Buy event CreatedLPToken(address token0, address token1, address LPToken); constructor(address swapV2Router, address swapV2Factory, address _mintFactory) { router = IUniswapV2Router02(swapV2Router); factory = IUniswapV2Factory(swapV2Factory); mintFactory = IMintFactory(_mintFactory); } modifier isToken() { require(mintFactory.tokenIsRegistered(msg.sender), "RA"); _; } function initiateBuyBackTax(address _token, address _wallet) payable external isToken returns(bool) { ITaxToken token = ITaxToken(_token); uint256 _amount = token.balanceOf(address(this)); address[] memory addressPaths = new address[](2); addressPaths[0] = _token; addressPaths[1] = router.WETH(); token.approve(address(router), _amount); if(_amount > 0) { router.swapExactTokensForETHSupportingFeeOnTransferTokens(_amount, 0, addressPaths, _wallet, block.timestamp); } IBuyBackWallet buyBackWallet = IBuyBackWallet(_wallet); bool res = buyBackWallet.checkBuyBackTrigger(); if(res) { addressPaths[0] = router.WETH(); addressPaths[1] = _token; uint256 amountEth = buyBackWallet.sendEthToTaxHelper(); uint256 balanceBefore = token.balanceOf(address(this)); router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: amountEth}(0, addressPaths, address(this), block.timestamp); // burn baby burn! uint256 balanceAfter = token.balanceOf(address(this)); uint256 amountToBurn = balanceAfter - balanceBefore; token.approve(token.owner(), amountToBurn); token.buyBackBurn(amountToBurn); } return true; } function initiateLPTokenTax(address _token, address _wallet) external isToken returns (bool) { ITaxToken token = ITaxToken(_token); uint256 _amount = token.balanceOf(address(this)); address[] memory addressPaths = new address[](2); addressPaths[0] = _token; addressPaths[1] = router.WETH(); uint256 halfAmount = _amount / 2; uint256 otherHalf = _amount - halfAmount; token.transfer(_wallet, otherHalf); token.approve(address(router), halfAmount); if(halfAmount > 0) { router.swapExactTokensForETHSupportingFeeOnTransferTokens(halfAmount, 0, addressPaths, _wallet, block.timestamp); } ILPWallet lpWallet = ILPWallet(_wallet); bool res = lpWallet.checkLPTrigger(); if(res) { lpWallet.transferBalanceToTaxHelper(); uint256 amountEth = lpWallet.sendEthToTaxHelper(); uint256 tokenBalance = token.balanceOf(address(this)); token.approve(address(router), tokenBalance); router.addLiquidityETH{value: amountEth}(_token, tokenBalance, 0, 0, token.owner(), block.timestamp + 20 minutes); uint256 ethDust = address(this).balance; if(ethDust > 0) { (bool sent,) = _wallet.call{value: ethDust}(""); require(sent, "Failed to send Ether"); } uint256 tokenDust = token.balanceOf(address(this)); if(tokenDust > 0) { token.transfer(_wallet, tokenDust); } } return true; } function createLPToken() external returns(address lpToken) { lpToken = factory.createPair(msg.sender, router.WETH()); emit CreatedLPToken(msg.sender, router.WETH(), lpToken); } function lpTokenHasReserves(address _lpToken) public view returns (bool) { (uint112 reserve0, uint112 reserve1,) = IUniswapV2Pair(_lpToken).getReserves(); return reserve0 > 0 && reserve1 > 0; } function sync(address _lpToken) public { IUniswapV2Pair(_lpToken).sync(); } receive() payable external { } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_address","type":"address"}],"name":"AddedBlacklistAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_newLPToken","type":"address"}],"name":"AddedLPToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_address","type":"address"}],"name":"AddedTaxWhitelistAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"ExcludedAccount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_address","type":"address"}],"name":"RemovedBlacklistAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_lpToken","type":"address"}],"name":"RemovedLPToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_address","type":"address"}],"name":"RemovedTaxWhitelistAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"_isPaused","type":"bool"}],"name":"ToggledPause","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"components":[{"internalType":"uint256","name":"buy","type":"uint256"},{"internalType":"uint256","name":"sell","type":"uint256"}],"internalType":"struct Fee","name":"fee","type":"tuple"},{"internalType":"address","name":"wallet","type":"address"},{"internalType":"bool","name":"withdrawAsGas","type":"bool"}],"indexed":false,"internalType":"struct CustomTax[]","name":"_customTaxes","type":"tuple[]"}],"name":"UpdatedCustomTaxes","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"bool","name":"transactionTax","type":"bool"},{"internalType":"bool","name":"buyBackTax","type":"bool"},{"internalType":"bool","name":"holderTax","type":"bool"},{"internalType":"bool","name":"lpTax","type":"bool"},{"internalType":"bool","name":"canBlacklist","type":"bool"},{"internalType":"bool","name":"canMint","type":"bool"},{"internalType":"bool","name":"canPause","type":"bool"},{"internalType":"bool","name":"maxBalanceAfterBuy","type":"bool"}],"indexed":false,"internalType":"struct TaxSettings","name":"_updatedLocks","type":"tuple"}],"name":"UpdatedLockedSettings","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_newPairAddress","type":"address"}],"name":"UpdatedPairAddress","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"bool","name":"transactionTax","type":"bool"},{"internalType":"bool","name":"buyBackTax","type":"bool"},{"internalType":"bool","name":"holderTax","type":"bool"},{"internalType":"bool","name":"lpTax","type":"bool"},{"internalType":"bool","name":"canBlacklist","type":"bool"},{"internalType":"bool","name":"canMint","type":"bool"},{"internalType":"bool","name":"canPause","type":"bool"},{"internalType":"bool","name":"maxBalanceAfterBuy","type":"bool"}],"indexed":false,"internalType":"struct TaxSettings","name":"_updatedSettings","type":"tuple"}],"name":"UpdatedSettings","type":"event"},{"anonymous":false,"inputs":[{"components":[{"components":[{"internalType":"uint256","name":"buy","type":"uint256"},{"internalType":"uint256","name":"sell","type":"uint256"}],"internalType":"struct Fee","name":"transactionTax","type":"tuple"},{"internalType":"uint256","name":"buyBackTax","type":"uint256"},{"internalType":"uint256","name":"holderTax","type":"uint256"},{"internalType":"uint256","name":"lpTax","type":"uint256"}],"indexed":false,"internalType":"struct Fees","name":"_updatedFees","type":"tuple"}],"name":"UpdatedTaxFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_newIndex","type":"uint256"}],"name":"UpdatedTaxHelperIndex","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_newAddress","type":"address"}],"name":"UpdatedTransactionTaxAddress","type":"event"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"addBlacklistedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newLPToken","type":"address"}],"name":"addLPToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"addTaxWhitelistedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bool","name":"transactionTax","type":"bool"},{"internalType":"bool","name":"buyBackTax","type":"bool"},{"internalType":"bool","name":"holderTax","type":"bool"},{"internalType":"bool","name":"lpTax","type":"bool"},{"internalType":"bool","name":"canBlacklist","type":"bool"},{"internalType":"bool","name":"canMint","type":"bool"},{"internalType":"bool","name":"canPause","type":"bool"},{"internalType":"bool","name":"maxBalanceAfterBuy","type":"bool"}],"internalType":"struct TaxSettings","name":"_updatedLocks","type":"tuple"}],"name":"lockSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"removeBlacklistedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lpToken","type":"address"}],"name":"removeLPToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"removeTaxWhitelistedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"togglePause","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_updatedAddresses","type":"address[]"},{"internalType":"bool","name":"_isBlacklisted","type":"bool"}],"name":"updateBlacklistBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"components":[{"internalType":"uint256","name":"buy","type":"uint256"},{"internalType":"uint256","name":"sell","type":"uint256"}],"internalType":"struct Fee","name":"fee","type":"tuple"},{"internalType":"address","name":"wallet","type":"address"},{"internalType":"bool","name":"withdrawAsGas","type":"bool"}],"internalType":"struct CustomTax[]","name":"_customTaxes","type":"tuple[]"}],"name":"updateCustomTaxes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newPairAddress","type":"address"}],"name":"updatePairAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bool","name":"transactionTax","type":"bool"},{"internalType":"bool","name":"buyBackTax","type":"bool"},{"internalType":"bool","name":"holderTax","type":"bool"},{"internalType":"bool","name":"lpTax","type":"bool"},{"internalType":"bool","name":"canBlacklist","type":"bool"},{"internalType":"bool","name":"canMint","type":"bool"},{"internalType":"bool","name":"canPause","type":"bool"},{"internalType":"bool","name":"maxBalanceAfterBuy","type":"bool"}],"internalType":"struct TaxSettings","name":"_updatedSettings","type":"tuple"}],"name":"updateSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint256","name":"buy","type":"uint256"},{"internalType":"uint256","name":"sell","type":"uint256"}],"internalType":"struct Fee","name":"transactionTax","type":"tuple"},{"internalType":"uint256","name":"buyBackTax","type":"uint256"},{"internalType":"uint256","name":"holderTax","type":"uint256"},{"internalType":"uint256","name":"lpTax","type":"uint256"}],"internalType":"struct Fees","name":"_updatedFees","type":"tuple"}],"name":"updateTaxFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_newIndex","type":"uint8"}],"name":"updateTaxHelperIndex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_updatedAddresses","type":"address[]"},{"internalType":"bool","name":"_isTaxWhitelisted","type":"bool"}],"name":"updateTaxWhitelistBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"updateTransactionTaxAddress","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50600062000024620000c860201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350620000d0565b600033905090565b613f8b80620000e06000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c80638da5cb5b116100b8578063b214cc031161007c578063b214cc03146102d2578063b23e5c4c146102ee578063c4ae31681461030a578063c59b00b114610328578063f2fde38b14610344578063fe575a871461036057610137565b80638da5cb5b14610244578063938a1a13146102625780639f7ca08f1461027e578063a920281a1461029a578063b20ef60c146102b657610137565b806339b2233b116100ff57806339b2233b146101c857806353102b91146101e45780635427c10f146102005780635c975abb1461021c578063715018a61461023a57610137565b80630c82334c1461013c57806314d33bd2146101585780632b6ee6bf146101745780633328b7211461019057806334238d97146101ac575b600080fd5b61015660048036038101906101519190612a99565b610390565b005b610172600480360381019061016d9190612b0b565b610650565b005b61018e60048036038101906101899190612b97565b610972565b005b6101aa60048036038101906101a59190612b97565b610a82565b005b6101c660048036038101906101c19190612b97565b610b9b565b005b6101e260048036038101906101dd9190612c52565b610df8565b005b6101fe60048036038101906101f99190612b0b565b610fe4565b005b61021a60048036038101906102159190612b97565b6114f7565b005b61022461162a565b6040516102319190612cc1565b60405180910390f35b61024261166d565b005b61024c6117a7565b6040516102599190612ceb565b60405180910390f35b61027c60048036038101906102779190612b97565b6117d0565b005b61029860048036038101906102939190612c52565b6118e1565b005b6102b460048036038101906102af9190612d3f565b611c3d565b005b6102d060048036038101906102cb9190612b97565b611ea0565b005b6102ec60048036038101906102e79190612b97565b611fb0565b005b61030860048036038101906103039190612b97565b6120c0565b005b61031261224b565b60405161031f9190612cc1565b60405180910390f35b610342600480360381019061033d9190612d8b565b6123ae565b005b61035e60048036038101906103599190612b97565b612557565b005b61037a60048036038101906103759190612b97565b6126ff565b6040516103879190612cc1565b60405180910390f35b610398612758565b73ffffffffffffffffffffffffffffffffffffffff166103b66117a7565b73ffffffffffffffffffffffffffffffffffffffff161461040c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161040390612e15565b60405180910390fd5b600180600c0160009054906101000a900460ff1661042a9190612e64565b60ff168282905010610471576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046890612ee5565b60405180910390fd5b600160080160006104829190612930565b60005b8282905081101561057357600073ffffffffffffffffffffffffffffffffffffffff168383838181106104bb576104ba612f05565b5b90506020028101906104cd9190612f43565b60600160208101906104df9190612b97565b73ffffffffffffffffffffffffffffffffffffffff16036104ff57600080fd5b600160080183838381811061051757610516612f05565b5b90506020028101906105299190612f43565b9080600181540180825580915050600190039060005260206000209060040201600090919091909150818161055e91906135c6565b5050808061056b906135d4565b915050610485565b50818190506001600a018190555061058b6001612760565b6105ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105c190613668565b60405180910390fd5b6105d46000612760565b610613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060a906136d4565b60405180910390fd5b7f11451899fef1320fb1b1bb59b2c45bf6374de0c22ce42ebf925206295181733b82826040516106449291906139f2565b60405180910390a15050565b610658612758565b73ffffffffffffffffffffffffffffffffffffffff166106766117a7565b73ffffffffffffffffffffffffffffffffffffffff16146106cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c390612e15565b60405180910390fd5b600160020160000160009054906101000a900460ff16610719578060000160208101906106f99190613a16565b600160020160000160006101000a81548160ff0219169083151502179055505b600160020160000160029054906101000a900460ff16610766578060400160208101906107469190613a16565b600160020160000160026101000a81548160ff0219169083151502179055505b600160020160000160019054906101000a900460ff166107b3578060200160208101906107939190613a16565b600160020160000160016101000a81548160ff0219169083151502179055505b600160020160000160039054906101000a900460ff16610800578060600160208101906107e09190613a16565b600160020160000160036101000a81548160ff0219169083151502179055505b600160020160000160059054906101000a900460ff1661084d578060a001602081019061082d9190613a16565b600160020160000160056101000a81548160ff0219169083151502179055505b600160020160000160069054906101000a900460ff1661089a578060c001602081019061087a9190613a16565b600160020160000160066101000a81548160ff0219169083151502179055505b600160020160000160049054906101000a900460ff166108e7578060800160208101906108c79190613a16565b600160020160000160046101000a81548160ff0219169083151502179055505b600160020160000160079054906101000a900460ff16610934578060e00160208101906109149190613a16565b600160020160000160076101000a81548160ff0219169083151502179055505b7f95dc33a6081cc4fe450e590d7dcc02a30b6ff3737eff45435936607af75c51f860016002016040516109679190613c53565b60405180910390a150565b61097a612758565b73ffffffffffffffffffffffffffffffffffffffff166109986117a7565b73ffffffffffffffffffffffffffffffffffffffff16146109ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e590612e15565b60405180910390fd5b60018060210160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f40d4b9bc87da2e947c606f38632edec2fddbf8ed4867e32774a4bbda343af9bb81604051610a779190612ceb565b60405180910390a150565b610a8a612758565b73ffffffffffffffffffffffffffffffffffffffff16610aa86117a7565b73ffffffffffffffffffffffffffffffffffffffff1614610afe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af590612e15565b60405180910390fd5b610b066128da565b60006001601e0160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f12f691464042d7beb509bbc35a611346a8510ada8dec7b0573503c340bd0c3c081604051610b909190612ceb565b60405180910390a150565b610ba3612758565b73ffffffffffffffffffffffffffffffffffffffff16610bc16117a7565b73ffffffffffffffffffffffffffffffffffffffff1614610c17576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0e90612e15565b60405180910390fd5b610c1f6128da565b60006001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638ee9e0c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb59190613c84565b905060008173ffffffffffffffffffffffffffffffffffffffff16634e7ceacb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d289190613c84565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610d6257600080fd5b600180601e0160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fd7714baad2fb7f77ba046f59bfd2c6504c25a6f9b5405691de61a4a34de7d6cf83604051610deb9190612ceb565b60405180910390a1505050565b610e00612758565b73ffffffffffffffffffffffffffffffffffffffff16610e1e6117a7565b73ffffffffffffffffffffffffffffffffffffffff1614610e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6b90612e15565b60405180910390fd5b60005b83839050811015610fde578160016021016000868685818110610e9d57610e9c612f05565b5b9050602002016020810190610eb29190612b97565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508115610f6c577f40d4b9bc87da2e947c606f38632edec2fddbf8ed4867e32774a4bbda343af9bb848483818110610f3d57610f3c612f05565b5b9050602002016020810190610f529190612b97565b604051610f5f9190612ceb565b60405180910390a1610fcb565b7fba659cfe463e1998464c0e1db65ee30ace153cb6f40961703bf723c8ac39cabd848483818110610fa057610f9f612f05565b5b9050602002016020810190610fb59190612b97565b604051610fc29190612ceb565b60405180910390a15b8080610fd6906135d4565b915050610e77565b50505050565b610fec612758565b73ffffffffffffffffffffffffffffffffffffffff1661100a6117a7565b73ffffffffffffffffffffffffffffffffffffffff1614611060576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105790612e15565b60405180910390fd5b600160020160000160009054906101000a900460ff161580156110ad57508060000160208101906110919190613a16565b15156001800160000160009054906101000a900460ff16151514155b156110e4578060000160208101906110c59190613a16565b6001800160000160006101000a81548160ff0219169083151502179055505b600160020160000160029054906101000a900460ff1615801561113157508060400160208101906111159190613a16565b15156001800160000160029054906101000a900460ff16151514155b801561114d57508060a001602081019061114b9190613a16565b155b15611184578060400160208101906111659190613a16565b6001800160000160026101000a81548160ff0219169083151502179055505b600160020160000160019054906101000a900460ff161580156111d157508060200160208101906111b59190613a16565b15156001800160000160019054906101000a900460ff16151514155b15611208578060200160208101906111e99190613a16565b6001800160000160016101000a81548160ff0219169083151502179055505b600160020160000160039054906101000a900460ff1615801561125557508060600160208101906112399190613a16565b15156001800160000160039054906101000a900460ff16151514155b1561128c5780606001602081019061126d9190613a16565b6001800160000160036101000a81548160ff0219169083151502179055505b600160020160000160059054906101000a900460ff161580156112d957508060a00160208101906112bd9190613a16565b15156001800160000160059054906101000a900460ff16151514155b80156112f757506001800160000160029054906101000a900460ff16155b1561132e578060a001602081019061130f9190613a16565b6001800160000160056101000a81548160ff0219169083151502179055505b600160020160000160069054906101000a900460ff1615801561137b57508060c001602081019061135f9190613a16565b15156001800160000160069054906101000a900460ff16151514155b156113b2578060c00160208101906113939190613a16565b6001800160000160066101000a81548160ff0219169083151502179055505b600160020160000160049054906101000a900460ff161580156113ff57508060800160208101906113e39190613a16565b15156001800160000160049054906101000a900460ff16151514155b15611436578060800160208101906114179190613a16565b6001800160000160046101000a81548160ff0219169083151502179055505b600160020160000160079054906101000a900460ff1615801561148357508060e00160208101906114679190613a16565b15156001800160000160079054906101000a900460ff16151514155b156114ba578060e001602081019061149b9190613a16565b6001800160000160076101000a81548160ff0219169083151502179055505b7fd9a625070362dbd464f02dfff71047840f13ad9a5bcd08cad6861ef00aa00ea6600180016040516114ec9190613c53565b60405180910390a150565b6114ff612758565b73ffffffffffffffffffffffffffffffffffffffff1661151d6117a7565b73ffffffffffffffffffffffffffffffffffffffff1614611573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156a90612e15565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036115ac57600080fd5b80600160090160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f60e641ffb3f5890461a641f5017db46d67a0dc4c47420ef136f48c2173d29c428160405161161f9190612ceb565b60405180910390a150565b60008015156001800160000160069054906101000a900460ff16151503611654576000905061166a565b6001601d0160149054906101000a900460ff1690505b90565b611675612758565b73ffffffffffffffffffffffffffffffffffffffff166116936117a7565b73ffffffffffffffffffffffffffffffffffffffff16146116e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e090612e15565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6117d8612758565b73ffffffffffffffffffffffffffffffffffffffff166117f66117a7565b73ffffffffffffffffffffffffffffffffffffffff161461184c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161184390612e15565b60405180910390fd5b6000600160210160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fba659cfe463e1998464c0e1db65ee30ace153cb6f40961703bf723c8ac39cabd816040516118d69190612ceb565b60405180910390a150565b6118e9612758565b73ffffffffffffffffffffffffffffffffffffffff166119076117a7565b73ffffffffffffffffffffffffffffffffffffffff161461195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195490612e15565b60405180910390fd5b6119656128da565b60006001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638ee9e0c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fb9190613c84565b905060008173ffffffffffffffffffffffffffffffffffffffff16634e7ceacb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6e9190613c84565b905060005b85859050811015611c35578173ffffffffffffffffffffffffffffffffffffffff16868683818110611aa857611aa7612f05565b5b9050602002016020810190611abd9190612b97565b73ffffffffffffffffffffffffffffffffffffffff1614611c2257836001601e016000888885818110611af357611af2612f05565b5b9050602002016020810190611b089190612b97565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508315611bc2577fd7714baad2fb7f77ba046f59bfd2c6504c25a6f9b5405691de61a4a34de7d6cf868683818110611b9357611b92612f05565b5b9050602002016020810190611ba89190612b97565b604051611bb59190612ceb565b60405180910390a1611c21565b7f12f691464042d7beb509bbc35a611346a8510ada8dec7b0573503c340bd0c3c0868683818110611bf657611bf5612f05565b5b9050602002016020810190611c0b9190612b97565b604051611c189190612ceb565b60405180910390a15b5b8080611c2d906135d4565b915050611a73565b505050505050565b611c45612758565b73ffffffffffffffffffffffffffffffffffffffff16611c636117a7565b73ffffffffffffffffffffffffffffffffffffffff1614611cb9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cb090612e15565b60405180910390fd5b8060ff1660016023018190555060006001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633c5c45e06001602301546040518263ffffffff1660e01b8152600401611d2b9190613cc0565b602060405180830381865afa158015611d48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6c9190613c84565b905060018060110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001601201819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fc710c6a47b6d612950c6ba7bb3bcc014922135bea0db8a995f7c9ab677faaef181604051611e5d9190612ceb565b60405180910390a17ffc7f9b1e3646832c15a135b65259e45fbd0f714bc168d7030c3080d55290d2d782604051611e949190613d0c565b60405180910390a15050565b611ea8612758565b73ffffffffffffffffffffffffffffffffffffffff16611ec66117a7565b73ffffffffffffffffffffffffffffffffffffffff1614611f1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1390612e15565b60405180910390fd5b6000600160170160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507e2c99091d121ac3773924cae14e4d87c458fc30883118d24628523d1f05e15f81604051611fa59190612ceb565b60405180910390a150565b611fb8612758565b73ffffffffffffffffffffffffffffffffffffffff16611fd66117a7565b73ffffffffffffffffffffffffffffffffffffffff161461202c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202390612e15565b60405180910390fd5b60018060170160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f09dfc618f06503346485c245fd17349c0215786472c70d45c41636884ef12bd1816040516120b59190612ceb565b60405180910390a150565b6120c8612758565b73ffffffffffffffffffffffffffffffffffffffff166120e66117a7565b73ffffffffffffffffffffffffffffffffffffffff161461213c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213390612e15565b60405180910390fd5b80600160220160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018060170160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f09dfc618f06503346485c245fd17349c0215786472c70d45c41636884ef12bd1816040516122099190612ceb565b60405180910390a17ff711ddd313e8ef76c054467cf5efc25f4d6414b79ebf665fed1cb72a2835e872816040516122409190612ceb565b60405180910390a150565b6000612255612758565b73ffffffffffffffffffffffffffffffffffffffff166122736117a7565b73ffffffffffffffffffffffffffffffffffffffff16146122c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c090612e15565b60405180910390fd5b6001800160000160069054906101000a900460ff1661231d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231490613d73565b60405180910390fd5b6001601d0160149054906101000a900460ff16156001601d0160146101000a81548160ff0219169083151502179055507fc3f5d745748f493db37476221d672e672287253d80e16973f814922a870dc0e66001601d0160149054906101000a900460ff1660405161238e9190612cc1565b60405180910390a16001601d0160149054906101000a900460ff16905090565b6123b6612758565b73ffffffffffffffffffffffffffffffffffffffff166123d46117a7565b73ffffffffffffffffffffffffffffffffffffffff161461242a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161242190612e15565b60405180910390fd5b806000016000013560016003016000016000018190555080600001602001356001600301600001600101819055508060400135600160030160020181905550806060013560016003016003018190555080608001356001600301600401819055506124956001612760565b6124d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124cb90613668565b60405180910390fd5b6124de6000612760565b61251d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612514906136d4565b60405180910390fd5b7f1f5e6bb4bdee0aae4fc64232ef225b08355289f9927531a991852abcf9b1ae848160405161254c9190613e08565b60405180910390a150565b61255f612758565b73ffffffffffffffffffffffffffffffffffffffff1661257d6117a7565b73ffffffffffffffffffffffffffffffffffffffff16146125d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ca90612e15565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612642576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161263990613e95565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60006001601e0160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600033905090565b60008082156127fd57600160030160000160000154816127809190613eb5565b9050600160030160030154816127969190613eb5565b905060005b6001600801805490508110156127f757600160080181815481106127c2576127c1612f05565b5b906000526020600020906004020160010160000154826127e29190613eb5565b915080806127ef906135d4565b91505061279b565b506128b9565b600160030160000160010154816128149190613eb5565b90506001600301600401548161282a9190613eb5565b9050600160030160030154816128409190613eb5565b9050600160030160020154816128569190613eb5565b905060005b6001600801805490508110156128b7576001600801818154811061288257612881612f05565b5b906000526020600020906004020160010160010154826128a29190613eb5565b915080806128af906135d4565b91505061285b565b505b6001600b015481116128cf5760019150506128d5565b60009150505b919050565b6001800160000160049054906101000a900460ff1661292e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161292590613f35565b60405180910390fd5b565b50805460008255600402906000526020600020908101906129519190612954565b50565b5b808211156129c9576000808201600061296e91906129cd565b60018201600080820160009055600182016000905550506003820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556003820160146101000a81549060ff021916905550600401612955565b5090565b5080546129d990613037565b6000825580601f106129eb5750612a0a565b601f016020900490600052602060002090810190612a099190612a0d565b5b50565b5b80821115612a26576000816000905550600101612a0e565b5090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f840112612a5957612a58612a34565b5b8235905067ffffffffffffffff811115612a7657612a75612a39565b5b602083019150836020820283011115612a9257612a91612a3e565b5b9250929050565b60008060208385031215612ab057612aaf612a2a565b5b600083013567ffffffffffffffff811115612ace57612acd612a2f565b5b612ada85828601612a43565b92509250509250929050565b600080fd5b60006101008284031215612b0257612b01612ae6565b5b81905092915050565b60006101008284031215612b2257612b21612a2a565b5b6000612b3084828501612aeb565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612b6482612b39565b9050919050565b612b7481612b59565b8114612b7f57600080fd5b50565b600081359050612b9181612b6b565b92915050565b600060208284031215612bad57612bac612a2a565b5b6000612bbb84828501612b82565b91505092915050565b60008083601f840112612bda57612bd9612a34565b5b8235905067ffffffffffffffff811115612bf757612bf6612a39565b5b602083019150836020820283011115612c1357612c12612a3e565b5b9250929050565b60008115159050919050565b612c2f81612c1a565b8114612c3a57600080fd5b50565b600081359050612c4c81612c26565b92915050565b600080600060408486031215612c6b57612c6a612a2a565b5b600084013567ffffffffffffffff811115612c8957612c88612a2f565b5b612c9586828701612bc4565b93509350506020612ca886828701612c3d565b9150509250925092565b612cbb81612c1a565b82525050565b6000602082019050612cd66000830184612cb2565b92915050565b612ce581612b59565b82525050565b6000602082019050612d006000830184612cdc565b92915050565b600060ff82169050919050565b612d1c81612d06565b8114612d2757600080fd5b50565b600081359050612d3981612d13565b92915050565b600060208284031215612d5557612d54612a2a565b5b6000612d6384828501612d2a565b91505092915050565b600060a08284031215612d8257612d81612ae6565b5b81905092915050565b600060a08284031215612da157612da0612a2a565b5b6000612daf84828501612d6c565b91505092915050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612dff602083612db8565b9150612e0a82612dc9565b602082019050919050565b60006020820190508181036000830152612e2e81612df2565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612e6f82612d06565b9150612e7a83612d06565b9250828201905060ff811115612e9357612e92612e35565b5b92915050565b7f4d43540000000000000000000000000000000000000000000000000000000000600082015250565b6000612ecf600383612db8565b9150612eda82612e99565b602082019050919050565b60006020820190508181036000830152612efe81612ec2565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b60008235600160a003833603038112612f5f57612f5e612f34565b5b80830191505092915050565b60008083356001602003843603038112612f8857612f87612f34565b5b80840192508235915067ffffffffffffffff821115612faa57612fa9612f39565b5b602083019250600182023603831315612fc657612fc5612f3e565b5b509250929050565b600082905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061304f57607f821691505b60208210810361306257613061613008565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026130ca7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261308d565b6130d4868361308d565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600061311b613116613111846130ec565b6130f6565b6130ec565b9050919050565b6000819050919050565b61313583613100565b61314961314182613122565b84845461309a565b825550505050565b600090565b61315e613151565b61316981848461312c565b505050565b5b8181101561318d57613182600082613156565b60018101905061316f565b5050565b601f8211156131d2576131a381613068565b6131ac8461307d565b810160208510156131bb578190505b6131cf6131c78561307d565b83018261316e565b50505b505050565b600082821c905092915050565b60006131f5600019846008026131d7565b1980831691505092915050565b600061320e83836131e4565b9150826002028217905092915050565b6132288383612fce565b67ffffffffffffffff81111561324157613240612fd9565b5b61324b8254613037565b613256828285613191565b6000601f8311600181146132855760008415613273578287013590505b61327d8582613202565b8655506132e5565b601f19841661329386613068565b60005b828110156132bb57848901358255600182019150602085019450602081019050613296565b868310156132d857848901356132d4601f8916826131e4565b8355505b6001600288020188555050505b50505050505050565b6132f983838361321e565b505050565b613307816130ec565b811461331257600080fd5b50565b60008135613322816132fe565b80915050919050565b60008160001b9050919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6133648461332b565b9350801983169250808416831791505092915050565b61338382613100565b61339661338f82613122565b8354613338565b8255505050565b6000810160008301806133af81613315565b90506133bb818461337a565b5050506001810160208301806133d081613315565b90506133dc818461337a565b5050505050565b6133ed828261339d565b5050565b600081356133fe81612b6b565b80915050919050565b600073ffffffffffffffffffffffffffffffffffffffff6134278461332b565b9350801983169250808416831791505092915050565b600061345861345361344e84612b39565b6130f6565b612b39565b9050919050565b600061346a8261343d565b9050919050565b600061347c8261345f565b9050919050565b6000819050919050565b61349682613471565b6134a96134a282613483565b8354613407565b8255505050565b600081356134bd81612c26565b80915050919050565b60008160a01b9050919050565b600074ff00000000000000000000000000000000000000006134f4846134c6565b9350801983169250808416831791505092915050565b600061351582612c1a565b9050919050565b6000819050919050565b61352f8261350a565b61354261353b8261351c565b83546134d3565b8255505050565b600081016000830161355b8185612f6b565b6135668183866132ee565b5050505060018101602083018061357d81846133e3565b505050600381016060830180613592816133f1565b905061359e818461348d565b5050506003810160808301806135b3816134b0565b90506135bf8184613526565b5050505050565b6135d08282613549565b5050565b60006135df826130ec565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361361157613610612e35565b5b600182019050919050565b7f4246000000000000000000000000000000000000000000000000000000000000600082015250565b6000613652600283612db8565b915061365d8261361c565b602082019050919050565b6000602082019050818103600083015261368181613645565b9050919050565b7f5346000000000000000000000000000000000000000000000000000000000000600082015250565b60006136be600283612db8565b91506136c982613688565b602082019050919050565b600060208201905081810360008301526136ed816136b1565b9050919050565b600082825260208201905092915050565b6000819050919050565b600080fd5b600080fd5b600080fd5b6000808335600160200384360303811261373b5761373a613719565b5b83810192508235915060208301925067ffffffffffffffff8211156137635761376261370f565b5b60018202360383131561377957613778613714565b5b509250929050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b60006137be8385613781565b93506137cb838584613792565b6137d4836137a1565b840190509392505050565b600082905092915050565b6000813590506137f9816132fe565b92915050565b600061380e60208401846137ea565b905092915050565b61381f816130ec565b82525050565b6040820161383660008301836137ff565b6138436000850182613816565b5061385160208301836137ff565b61385e6020850182613816565b50505050565b60006138736020840184612b82565b905092915050565b61388481612b59565b82525050565b60006138996020840184612c3d565b905092915050565b6138aa81612c1a565b82525050565b600060a083016138c3600084018461371e565b85830360008701526138d68382846137b2565b925050506138e760208401846137df565b6138f46020860182613825565b506139026060840184613864565b61390f606086018261387b565b5061391d608084018461388a565b61392a60808601826138a1565b508091505092915050565b600061394183836138b0565b905092915050565b60008235600160a00383360303811261396557613964613719565b5b82810191505092915050565b6000602082019050919050565b600061398a83856136f4565b93508360208402850161399c84613705565b8060005b878110156139e05784840389526139b78284613949565b6139c18582613935565b94506139cc83613971565b925060208a019950506001810190506139a0565b50829750879450505050509392505050565b60006020820190508181036000830152613a0d81848661397e565b90509392505050565b600060208284031215613a2c57613a2b612a2a565b5b6000613a3a84828501612c3d565b91505092915050565b60008160001c9050919050565b600060ff82169050919050565b6000613a70613a6b83613a43565b613a50565b9050919050565b60008160081c9050919050565b6000613a97613a9283613a77565b613a50565b9050919050565b60008160101c9050919050565b6000613abe613ab983613a9e565b613a50565b9050919050565b60008160181c9050919050565b6000613ae5613ae083613ac5565b613a50565b9050919050565b60008160201c9050919050565b6000613b0c613b0783613aec565b613a50565b9050919050565b60008160281c9050919050565b6000613b33613b2e83613b13565b613a50565b9050919050565b60008160301c9050919050565b6000613b5a613b5583613b3a565b613a50565b9050919050565b60008160381c9050919050565b6000613b81613b7c83613b61565b613a50565b9050919050565b61010082016000808301549050613b9e81613a5d565b613bab60008601826138a1565b50613bb581613a84565b613bc260208601826138a1565b50613bcc81613aab565b613bd960408601826138a1565b50613be381613ad2565b613bf060608601826138a1565b50613bfa81613af9565b613c0760808601826138a1565b50613c1181613b20565b613c1e60a08601826138a1565b50613c2881613b47565b613c3560c08601826138a1565b50613c3f81613b6e565b613c4c60e08601826138a1565b5050505050565b600061010082019050613c696000830184613b88565b92915050565b600081519050613c7e81612b6b565b92915050565b600060208284031215613c9a57613c99612a2a565b5b6000613ca884828501613c6f565b91505092915050565b613cba816130ec565b82525050565b6000602082019050613cd56000830184613cb1565b92915050565b6000613cf6613cf1613cec84612d06565b6130f6565b6130ec565b9050919050565b613d0681613cdb565b82525050565b6000602082019050613d216000830184613cfd565b92915050565b7f4e50000000000000000000000000000000000000000000000000000000000000600082015250565b6000613d5d600283612db8565b9150613d6882613d27565b602082019050919050565b60006020820190508181036000830152613d8c81613d50565b9050919050565b60a08201613da460008301836137df565b613db16000850182613825565b50613dbf60408301836137ff565b613dcc6040850182613816565b50613dda60608301836137ff565b613de76060850182613816565b50613df560808301836137ff565b613e026080850182613816565b50505050565b600060a082019050613e1d6000830184613d93565b92915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613e7f602683612db8565b9150613e8a82613e23565b604082019050919050565b60006020820190508181036000830152613eae81613e72565b9050919050565b6000613ec0826130ec565b9150613ecb836130ec565b9250828201905080821115613ee357613ee2612e35565b5b92915050565b7f4e42000000000000000000000000000000000000000000000000000000000000600082015250565b6000613f1f600283612db8565b9150613f2a82613ee9565b602082019050919050565b60006020820190508181036000830152613f4e81613f12565b905091905056fea264697066735822122000e7446c45b2ec67e53d57c81ef33b0db698fe6805990c0c43c4753403dc778764736f6c63430008110033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101375760003560e01c80638da5cb5b116100b8578063b214cc031161007c578063b214cc03146102d2578063b23e5c4c146102ee578063c4ae31681461030a578063c59b00b114610328578063f2fde38b14610344578063fe575a871461036057610137565b80638da5cb5b14610244578063938a1a13146102625780639f7ca08f1461027e578063a920281a1461029a578063b20ef60c146102b657610137565b806339b2233b116100ff57806339b2233b146101c857806353102b91146101e45780635427c10f146102005780635c975abb1461021c578063715018a61461023a57610137565b80630c82334c1461013c57806314d33bd2146101585780632b6ee6bf146101745780633328b7211461019057806334238d97146101ac575b600080fd5b61015660048036038101906101519190612a99565b610390565b005b610172600480360381019061016d9190612b0b565b610650565b005b61018e60048036038101906101899190612b97565b610972565b005b6101aa60048036038101906101a59190612b97565b610a82565b005b6101c660048036038101906101c19190612b97565b610b9b565b005b6101e260048036038101906101dd9190612c52565b610df8565b005b6101fe60048036038101906101f99190612b0b565b610fe4565b005b61021a60048036038101906102159190612b97565b6114f7565b005b61022461162a565b6040516102319190612cc1565b60405180910390f35b61024261166d565b005b61024c6117a7565b6040516102599190612ceb565b60405180910390f35b61027c60048036038101906102779190612b97565b6117d0565b005b61029860048036038101906102939190612c52565b6118e1565b005b6102b460048036038101906102af9190612d3f565b611c3d565b005b6102d060048036038101906102cb9190612b97565b611ea0565b005b6102ec60048036038101906102e79190612b97565b611fb0565b005b61030860048036038101906103039190612b97565b6120c0565b005b61031261224b565b60405161031f9190612cc1565b60405180910390f35b610342600480360381019061033d9190612d8b565b6123ae565b005b61035e60048036038101906103599190612b97565b612557565b005b61037a60048036038101906103759190612b97565b6126ff565b6040516103879190612cc1565b60405180910390f35b610398612758565b73ffffffffffffffffffffffffffffffffffffffff166103b66117a7565b73ffffffffffffffffffffffffffffffffffffffff161461040c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161040390612e15565b60405180910390fd5b600180600c0160009054906101000a900460ff1661042a9190612e64565b60ff168282905010610471576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046890612ee5565b60405180910390fd5b600160080160006104829190612930565b60005b8282905081101561057357600073ffffffffffffffffffffffffffffffffffffffff168383838181106104bb576104ba612f05565b5b90506020028101906104cd9190612f43565b60600160208101906104df9190612b97565b73ffffffffffffffffffffffffffffffffffffffff16036104ff57600080fd5b600160080183838381811061051757610516612f05565b5b90506020028101906105299190612f43565b9080600181540180825580915050600190039060005260206000209060040201600090919091909150818161055e91906135c6565b5050808061056b906135d4565b915050610485565b50818190506001600a018190555061058b6001612760565b6105ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105c190613668565b60405180910390fd5b6105d46000612760565b610613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060a906136d4565b60405180910390fd5b7f11451899fef1320fb1b1bb59b2c45bf6374de0c22ce42ebf925206295181733b82826040516106449291906139f2565b60405180910390a15050565b610658612758565b73ffffffffffffffffffffffffffffffffffffffff166106766117a7565b73ffffffffffffffffffffffffffffffffffffffff16146106cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c390612e15565b60405180910390fd5b600160020160000160009054906101000a900460ff16610719578060000160208101906106f99190613a16565b600160020160000160006101000a81548160ff0219169083151502179055505b600160020160000160029054906101000a900460ff16610766578060400160208101906107469190613a16565b600160020160000160026101000a81548160ff0219169083151502179055505b600160020160000160019054906101000a900460ff166107b3578060200160208101906107939190613a16565b600160020160000160016101000a81548160ff0219169083151502179055505b600160020160000160039054906101000a900460ff16610800578060600160208101906107e09190613a16565b600160020160000160036101000a81548160ff0219169083151502179055505b600160020160000160059054906101000a900460ff1661084d578060a001602081019061082d9190613a16565b600160020160000160056101000a81548160ff0219169083151502179055505b600160020160000160069054906101000a900460ff1661089a578060c001602081019061087a9190613a16565b600160020160000160066101000a81548160ff0219169083151502179055505b600160020160000160049054906101000a900460ff166108e7578060800160208101906108c79190613a16565b600160020160000160046101000a81548160ff0219169083151502179055505b600160020160000160079054906101000a900460ff16610934578060e00160208101906109149190613a16565b600160020160000160076101000a81548160ff0219169083151502179055505b7f95dc33a6081cc4fe450e590d7dcc02a30b6ff3737eff45435936607af75c51f860016002016040516109679190613c53565b60405180910390a150565b61097a612758565b73ffffffffffffffffffffffffffffffffffffffff166109986117a7565b73ffffffffffffffffffffffffffffffffffffffff16146109ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e590612e15565b60405180910390fd5b60018060210160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f40d4b9bc87da2e947c606f38632edec2fddbf8ed4867e32774a4bbda343af9bb81604051610a779190612ceb565b60405180910390a150565b610a8a612758565b73ffffffffffffffffffffffffffffffffffffffff16610aa86117a7565b73ffffffffffffffffffffffffffffffffffffffff1614610afe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af590612e15565b60405180910390fd5b610b066128da565b60006001601e0160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f12f691464042d7beb509bbc35a611346a8510ada8dec7b0573503c340bd0c3c081604051610b909190612ceb565b60405180910390a150565b610ba3612758565b73ffffffffffffffffffffffffffffffffffffffff16610bc16117a7565b73ffffffffffffffffffffffffffffffffffffffff1614610c17576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0e90612e15565b60405180910390fd5b610c1f6128da565b60006001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638ee9e0c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb59190613c84565b905060008173ffffffffffffffffffffffffffffffffffffffff16634e7ceacb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d289190613c84565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610d6257600080fd5b600180601e0160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fd7714baad2fb7f77ba046f59bfd2c6504c25a6f9b5405691de61a4a34de7d6cf83604051610deb9190612ceb565b60405180910390a1505050565b610e00612758565b73ffffffffffffffffffffffffffffffffffffffff16610e1e6117a7565b73ffffffffffffffffffffffffffffffffffffffff1614610e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6b90612e15565b60405180910390fd5b60005b83839050811015610fde578160016021016000868685818110610e9d57610e9c612f05565b5b9050602002016020810190610eb29190612b97565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508115610f6c577f40d4b9bc87da2e947c606f38632edec2fddbf8ed4867e32774a4bbda343af9bb848483818110610f3d57610f3c612f05565b5b9050602002016020810190610f529190612b97565b604051610f5f9190612ceb565b60405180910390a1610fcb565b7fba659cfe463e1998464c0e1db65ee30ace153cb6f40961703bf723c8ac39cabd848483818110610fa057610f9f612f05565b5b9050602002016020810190610fb59190612b97565b604051610fc29190612ceb565b60405180910390a15b8080610fd6906135d4565b915050610e77565b50505050565b610fec612758565b73ffffffffffffffffffffffffffffffffffffffff1661100a6117a7565b73ffffffffffffffffffffffffffffffffffffffff1614611060576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105790612e15565b60405180910390fd5b600160020160000160009054906101000a900460ff161580156110ad57508060000160208101906110919190613a16565b15156001800160000160009054906101000a900460ff16151514155b156110e4578060000160208101906110c59190613a16565b6001800160000160006101000a81548160ff0219169083151502179055505b600160020160000160029054906101000a900460ff1615801561113157508060400160208101906111159190613a16565b15156001800160000160029054906101000a900460ff16151514155b801561114d57508060a001602081019061114b9190613a16565b155b15611184578060400160208101906111659190613a16565b6001800160000160026101000a81548160ff0219169083151502179055505b600160020160000160019054906101000a900460ff161580156111d157508060200160208101906111b59190613a16565b15156001800160000160019054906101000a900460ff16151514155b15611208578060200160208101906111e99190613a16565b6001800160000160016101000a81548160ff0219169083151502179055505b600160020160000160039054906101000a900460ff1615801561125557508060600160208101906112399190613a16565b15156001800160000160039054906101000a900460ff16151514155b1561128c5780606001602081019061126d9190613a16565b6001800160000160036101000a81548160ff0219169083151502179055505b600160020160000160059054906101000a900460ff161580156112d957508060a00160208101906112bd9190613a16565b15156001800160000160059054906101000a900460ff16151514155b80156112f757506001800160000160029054906101000a900460ff16155b1561132e578060a001602081019061130f9190613a16565b6001800160000160056101000a81548160ff0219169083151502179055505b600160020160000160069054906101000a900460ff1615801561137b57508060c001602081019061135f9190613a16565b15156001800160000160069054906101000a900460ff16151514155b156113b2578060c00160208101906113939190613a16565b6001800160000160066101000a81548160ff0219169083151502179055505b600160020160000160049054906101000a900460ff161580156113ff57508060800160208101906113e39190613a16565b15156001800160000160049054906101000a900460ff16151514155b15611436578060800160208101906114179190613a16565b6001800160000160046101000a81548160ff0219169083151502179055505b600160020160000160079054906101000a900460ff1615801561148357508060e00160208101906114679190613a16565b15156001800160000160079054906101000a900460ff16151514155b156114ba578060e001602081019061149b9190613a16565b6001800160000160076101000a81548160ff0219169083151502179055505b7fd9a625070362dbd464f02dfff71047840f13ad9a5bcd08cad6861ef00aa00ea6600180016040516114ec9190613c53565b60405180910390a150565b6114ff612758565b73ffffffffffffffffffffffffffffffffffffffff1661151d6117a7565b73ffffffffffffffffffffffffffffffffffffffff1614611573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156a90612e15565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036115ac57600080fd5b80600160090160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f60e641ffb3f5890461a641f5017db46d67a0dc4c47420ef136f48c2173d29c428160405161161f9190612ceb565b60405180910390a150565b60008015156001800160000160069054906101000a900460ff16151503611654576000905061166a565b6001601d0160149054906101000a900460ff1690505b90565b611675612758565b73ffffffffffffffffffffffffffffffffffffffff166116936117a7565b73ffffffffffffffffffffffffffffffffffffffff16146116e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e090612e15565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6117d8612758565b73ffffffffffffffffffffffffffffffffffffffff166117f66117a7565b73ffffffffffffffffffffffffffffffffffffffff161461184c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161184390612e15565b60405180910390fd5b6000600160210160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fba659cfe463e1998464c0e1db65ee30ace153cb6f40961703bf723c8ac39cabd816040516118d69190612ceb565b60405180910390a150565b6118e9612758565b73ffffffffffffffffffffffffffffffffffffffff166119076117a7565b73ffffffffffffffffffffffffffffffffffffffff161461195d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195490612e15565b60405180910390fd5b6119656128da565b60006001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638ee9e0c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fb9190613c84565b905060008173ffffffffffffffffffffffffffffffffffffffff16634e7ceacb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6e9190613c84565b905060005b85859050811015611c35578173ffffffffffffffffffffffffffffffffffffffff16868683818110611aa857611aa7612f05565b5b9050602002016020810190611abd9190612b97565b73ffffffffffffffffffffffffffffffffffffffff1614611c2257836001601e016000888885818110611af357611af2612f05565b5b9050602002016020810190611b089190612b97565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508315611bc2577fd7714baad2fb7f77ba046f59bfd2c6504c25a6f9b5405691de61a4a34de7d6cf868683818110611b9357611b92612f05565b5b9050602002016020810190611ba89190612b97565b604051611bb59190612ceb565b60405180910390a1611c21565b7f12f691464042d7beb509bbc35a611346a8510ada8dec7b0573503c340bd0c3c0868683818110611bf657611bf5612f05565b5b9050602002016020810190611c0b9190612b97565b604051611c189190612ceb565b60405180910390a15b5b8080611c2d906135d4565b915050611a73565b505050505050565b611c45612758565b73ffffffffffffffffffffffffffffffffffffffff16611c636117a7565b73ffffffffffffffffffffffffffffffffffffffff1614611cb9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cb090612e15565b60405180910390fd5b8060ff1660016023018190555060006001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633c5c45e06001602301546040518263ffffffff1660e01b8152600401611d2b9190613cc0565b602060405180830381865afa158015611d48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6c9190613c84565b905060018060110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001601201819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fc710c6a47b6d612950c6ba7bb3bcc014922135bea0db8a995f7c9ab677faaef181604051611e5d9190612ceb565b60405180910390a17ffc7f9b1e3646832c15a135b65259e45fbd0f714bc168d7030c3080d55290d2d782604051611e949190613d0c565b60405180910390a15050565b611ea8612758565b73ffffffffffffffffffffffffffffffffffffffff16611ec66117a7565b73ffffffffffffffffffffffffffffffffffffffff1614611f1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1390612e15565b60405180910390fd5b6000600160170160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507e2c99091d121ac3773924cae14e4d87c458fc30883118d24628523d1f05e15f81604051611fa59190612ceb565b60405180910390a150565b611fb8612758565b73ffffffffffffffffffffffffffffffffffffffff16611fd66117a7565b73ffffffffffffffffffffffffffffffffffffffff161461202c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202390612e15565b60405180910390fd5b60018060170160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f09dfc618f06503346485c245fd17349c0215786472c70d45c41636884ef12bd1816040516120b59190612ceb565b60405180910390a150565b6120c8612758565b73ffffffffffffffffffffffffffffffffffffffff166120e66117a7565b73ffffffffffffffffffffffffffffffffffffffff161461213c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213390612e15565b60405180910390fd5b80600160220160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018060170160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f09dfc618f06503346485c245fd17349c0215786472c70d45c41636884ef12bd1816040516122099190612ceb565b60405180910390a17ff711ddd313e8ef76c054467cf5efc25f4d6414b79ebf665fed1cb72a2835e872816040516122409190612ceb565b60405180910390a150565b6000612255612758565b73ffffffffffffffffffffffffffffffffffffffff166122736117a7565b73ffffffffffffffffffffffffffffffffffffffff16146122c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c090612e15565b60405180910390fd5b6001800160000160069054906101000a900460ff1661231d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231490613d73565b60405180910390fd5b6001601d0160149054906101000a900460ff16156001601d0160146101000a81548160ff0219169083151502179055507fc3f5d745748f493db37476221d672e672287253d80e16973f814922a870dc0e66001601d0160149054906101000a900460ff1660405161238e9190612cc1565b60405180910390a16001601d0160149054906101000a900460ff16905090565b6123b6612758565b73ffffffffffffffffffffffffffffffffffffffff166123d46117a7565b73ffffffffffffffffffffffffffffffffffffffff161461242a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161242190612e15565b60405180910390fd5b806000016000013560016003016000016000018190555080600001602001356001600301600001600101819055508060400135600160030160020181905550806060013560016003016003018190555080608001356001600301600401819055506124956001612760565b6124d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124cb90613668565b60405180910390fd5b6124de6000612760565b61251d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612514906136d4565b60405180910390fd5b7f1f5e6bb4bdee0aae4fc64232ef225b08355289f9927531a991852abcf9b1ae848160405161254c9190613e08565b60405180910390a150565b61255f612758565b73ffffffffffffffffffffffffffffffffffffffff1661257d6117a7565b73ffffffffffffffffffffffffffffffffffffffff16146125d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ca90612e15565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612642576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161263990613e95565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60006001601e0160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600033905090565b60008082156127fd57600160030160000160000154816127809190613eb5565b9050600160030160030154816127969190613eb5565b905060005b6001600801805490508110156127f757600160080181815481106127c2576127c1612f05565b5b906000526020600020906004020160010160000154826127e29190613eb5565b915080806127ef906135d4565b91505061279b565b506128b9565b600160030160000160010154816128149190613eb5565b90506001600301600401548161282a9190613eb5565b9050600160030160030154816128409190613eb5565b9050600160030160020154816128569190613eb5565b905060005b6001600801805490508110156128b7576001600801818154811061288257612881612f05565b5b906000526020600020906004020160010160010154826128a29190613eb5565b915080806128af906135d4565b91505061285b565b505b6001600b015481116128cf5760019150506128d5565b60009150505b919050565b6001800160000160049054906101000a900460ff1661292e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161292590613f35565b60405180910390fd5b565b50805460008255600402906000526020600020908101906129519190612954565b50565b5b808211156129c9576000808201600061296e91906129cd565b60018201600080820160009055600182016000905550506003820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556003820160146101000a81549060ff021916905550600401612955565b5090565b5080546129d990613037565b6000825580601f106129eb5750612a0a565b601f016020900490600052602060002090810190612a099190612a0d565b5b50565b5b80821115612a26576000816000905550600101612a0e565b5090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f840112612a5957612a58612a34565b5b8235905067ffffffffffffffff811115612a7657612a75612a39565b5b602083019150836020820283011115612a9257612a91612a3e565b5b9250929050565b60008060208385031215612ab057612aaf612a2a565b5b600083013567ffffffffffffffff811115612ace57612acd612a2f565b5b612ada85828601612a43565b92509250509250929050565b600080fd5b60006101008284031215612b0257612b01612ae6565b5b81905092915050565b60006101008284031215612b2257612b21612a2a565b5b6000612b3084828501612aeb565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612b6482612b39565b9050919050565b612b7481612b59565b8114612b7f57600080fd5b50565b600081359050612b9181612b6b565b92915050565b600060208284031215612bad57612bac612a2a565b5b6000612bbb84828501612b82565b91505092915050565b60008083601f840112612bda57612bd9612a34565b5b8235905067ffffffffffffffff811115612bf757612bf6612a39565b5b602083019150836020820283011115612c1357612c12612a3e565b5b9250929050565b60008115159050919050565b612c2f81612c1a565b8114612c3a57600080fd5b50565b600081359050612c4c81612c26565b92915050565b600080600060408486031215612c6b57612c6a612a2a565b5b600084013567ffffffffffffffff811115612c8957612c88612a2f565b5b612c9586828701612bc4565b93509350506020612ca886828701612c3d565b9150509250925092565b612cbb81612c1a565b82525050565b6000602082019050612cd66000830184612cb2565b92915050565b612ce581612b59565b82525050565b6000602082019050612d006000830184612cdc565b92915050565b600060ff82169050919050565b612d1c81612d06565b8114612d2757600080fd5b50565b600081359050612d3981612d13565b92915050565b600060208284031215612d5557612d54612a2a565b5b6000612d6384828501612d2a565b91505092915050565b600060a08284031215612d8257612d81612ae6565b5b81905092915050565b600060a08284031215612da157612da0612a2a565b5b6000612daf84828501612d6c565b91505092915050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612dff602083612db8565b9150612e0a82612dc9565b602082019050919050565b60006020820190508181036000830152612e2e81612df2565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612e6f82612d06565b9150612e7a83612d06565b9250828201905060ff811115612e9357612e92612e35565b5b92915050565b7f4d43540000000000000000000000000000000000000000000000000000000000600082015250565b6000612ecf600383612db8565b9150612eda82612e99565b602082019050919050565b60006020820190508181036000830152612efe81612ec2565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b60008235600160a003833603038112612f5f57612f5e612f34565b5b80830191505092915050565b60008083356001602003843603038112612f8857612f87612f34565b5b80840192508235915067ffffffffffffffff821115612faa57612fa9612f39565b5b602083019250600182023603831315612fc657612fc5612f3e565b5b509250929050565b600082905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061304f57607f821691505b60208210810361306257613061613008565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026130ca7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261308d565b6130d4868361308d565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600061311b613116613111846130ec565b6130f6565b6130ec565b9050919050565b6000819050919050565b61313583613100565b61314961314182613122565b84845461309a565b825550505050565b600090565b61315e613151565b61316981848461312c565b505050565b5b8181101561318d57613182600082613156565b60018101905061316f565b5050565b601f8211156131d2576131a381613068565b6131ac8461307d565b810160208510156131bb578190505b6131cf6131c78561307d565b83018261316e565b50505b505050565b600082821c905092915050565b60006131f5600019846008026131d7565b1980831691505092915050565b600061320e83836131e4565b9150826002028217905092915050565b6132288383612fce565b67ffffffffffffffff81111561324157613240612fd9565b5b61324b8254613037565b613256828285613191565b6000601f8311600181146132855760008415613273578287013590505b61327d8582613202565b8655506132e5565b601f19841661329386613068565b60005b828110156132bb57848901358255600182019150602085019450602081019050613296565b868310156132d857848901356132d4601f8916826131e4565b8355505b6001600288020188555050505b50505050505050565b6132f983838361321e565b505050565b613307816130ec565b811461331257600080fd5b50565b60008135613322816132fe565b80915050919050565b60008160001b9050919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6133648461332b565b9350801983169250808416831791505092915050565b61338382613100565b61339661338f82613122565b8354613338565b8255505050565b6000810160008301806133af81613315565b90506133bb818461337a565b5050506001810160208301806133d081613315565b90506133dc818461337a565b5050505050565b6133ed828261339d565b5050565b600081356133fe81612b6b565b80915050919050565b600073ffffffffffffffffffffffffffffffffffffffff6134278461332b565b9350801983169250808416831791505092915050565b600061345861345361344e84612b39565b6130f6565b612b39565b9050919050565b600061346a8261343d565b9050919050565b600061347c8261345f565b9050919050565b6000819050919050565b61349682613471565b6134a96134a282613483565b8354613407565b8255505050565b600081356134bd81612c26565b80915050919050565b60008160a01b9050919050565b600074ff00000000000000000000000000000000000000006134f4846134c6565b9350801983169250808416831791505092915050565b600061351582612c1a565b9050919050565b6000819050919050565b61352f8261350a565b61354261353b8261351c565b83546134d3565b8255505050565b600081016000830161355b8185612f6b565b6135668183866132ee565b5050505060018101602083018061357d81846133e3565b505050600381016060830180613592816133f1565b905061359e818461348d565b5050506003810160808301806135b3816134b0565b90506135bf8184613526565b5050505050565b6135d08282613549565b5050565b60006135df826130ec565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361361157613610612e35565b5b600182019050919050565b7f4246000000000000000000000000000000000000000000000000000000000000600082015250565b6000613652600283612db8565b915061365d8261361c565b602082019050919050565b6000602082019050818103600083015261368181613645565b9050919050565b7f5346000000000000000000000000000000000000000000000000000000000000600082015250565b60006136be600283612db8565b91506136c982613688565b602082019050919050565b600060208201905081810360008301526136ed816136b1565b9050919050565b600082825260208201905092915050565b6000819050919050565b600080fd5b600080fd5b600080fd5b6000808335600160200384360303811261373b5761373a613719565b5b83810192508235915060208301925067ffffffffffffffff8211156137635761376261370f565b5b60018202360383131561377957613778613714565b5b509250929050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b60006137be8385613781565b93506137cb838584613792565b6137d4836137a1565b840190509392505050565b600082905092915050565b6000813590506137f9816132fe565b92915050565b600061380e60208401846137ea565b905092915050565b61381f816130ec565b82525050565b6040820161383660008301836137ff565b6138436000850182613816565b5061385160208301836137ff565b61385e6020850182613816565b50505050565b60006138736020840184612b82565b905092915050565b61388481612b59565b82525050565b60006138996020840184612c3d565b905092915050565b6138aa81612c1a565b82525050565b600060a083016138c3600084018461371e565b85830360008701526138d68382846137b2565b925050506138e760208401846137df565b6138f46020860182613825565b506139026060840184613864565b61390f606086018261387b565b5061391d608084018461388a565b61392a60808601826138a1565b508091505092915050565b600061394183836138b0565b905092915050565b60008235600160a00383360303811261396557613964613719565b5b82810191505092915050565b6000602082019050919050565b600061398a83856136f4565b93508360208402850161399c84613705565b8060005b878110156139e05784840389526139b78284613949565b6139c18582613935565b94506139cc83613971565b925060208a019950506001810190506139a0565b50829750879450505050509392505050565b60006020820190508181036000830152613a0d81848661397e565b90509392505050565b600060208284031215613a2c57613a2b612a2a565b5b6000613a3a84828501612c3d565b91505092915050565b60008160001c9050919050565b600060ff82169050919050565b6000613a70613a6b83613a43565b613a50565b9050919050565b60008160081c9050919050565b6000613a97613a9283613a77565b613a50565b9050919050565b60008160101c9050919050565b6000613abe613ab983613a9e565b613a50565b9050919050565b60008160181c9050919050565b6000613ae5613ae083613ac5565b613a50565b9050919050565b60008160201c9050919050565b6000613b0c613b0783613aec565b613a50565b9050919050565b60008160281c9050919050565b6000613b33613b2e83613b13565b613a50565b9050919050565b60008160301c9050919050565b6000613b5a613b5583613b3a565b613a50565b9050919050565b60008160381c9050919050565b6000613b81613b7c83613b61565b613a50565b9050919050565b61010082016000808301549050613b9e81613a5d565b613bab60008601826138a1565b50613bb581613a84565b613bc260208601826138a1565b50613bcc81613aab565b613bd960408601826138a1565b50613be381613ad2565b613bf060608601826138a1565b50613bfa81613af9565b613c0760808601826138a1565b50613c1181613b20565b613c1e60a08601826138a1565b50613c2881613b47565b613c3560c08601826138a1565b50613c3f81613b6e565b613c4c60e08601826138a1565b5050505050565b600061010082019050613c696000830184613b88565b92915050565b600081519050613c7e81612b6b565b92915050565b600060208284031215613c9a57613c99612a2a565b5b6000613ca884828501613c6f565b91505092915050565b613cba816130ec565b82525050565b6000602082019050613cd56000830184613cb1565b92915050565b6000613cf6613cf1613cec84612d06565b6130f6565b6130ec565b9050919050565b613d0681613cdb565b82525050565b6000602082019050613d216000830184613cfd565b92915050565b7f4e50000000000000000000000000000000000000000000000000000000000000600082015250565b6000613d5d600283612db8565b9150613d6882613d27565b602082019050919050565b60006020820190508181036000830152613d8c81613d50565b9050919050565b60a08201613da460008301836137df565b613db16000850182613825565b50613dbf60408301836137ff565b613dcc6040850182613816565b50613dda60608301836137ff565b613de76060850182613816565b50613df560808301836137ff565b613e026080850182613816565b50505050565b600060a082019050613e1d6000830184613d93565b92915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613e7f602683612db8565b9150613e8a82613e23565b604082019050919050565b60006020820190508181036000830152613eae81613e72565b9050919050565b6000613ec0826130ec565b9150613ecb836130ec565b9250828201905080821115613ee357613ee2612e35565b5b92915050565b7f4e42000000000000000000000000000000000000000000000000000000000000600082015250565b6000613f1f600283612db8565b9150613f2a82613ee9565b602082019050919050565b60006020820190508181036000830152613f4e81613f12565b905091905056fea264697066735822122000e7446c45b2ec67e53d57c81ef33b0db698fe6805990c0c43c4753403dc778764736f6c63430008110033
Deployed Bytecode Sourcemap
62821:9477:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66777:549;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68131:1037;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71455:169;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;65753:179;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;65389:356;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71815:480;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69176:1622;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67849:274;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64993:166;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8314:148;;;:::i;:::-;;7663:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71632:175;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;65940:706;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71074:373;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64030:145;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63874:148;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70806:260;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;65167:214;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67334:507;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;8617:244;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66654:115;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66777:549;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;66911:1:::1;66897::::0;:11:::1;;;;;;;;;;;;:15;;;;:::i;:::-;66875:37;;:12;;:19;;:37;66867:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;66938:1;:13;;;66931:20;;;;:::i;:::-;66968:6;66964:168;66984:12;;:19;;66980:1;:23;66964:168;;;67067:1;67033:36;;:12;;67046:1;67033:15;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;:22;;;;;;;;;;:::i;:::-;:36;;::::0;67025:45:::1;;;::::0;::::1;;67085:1;:13;;67104:12;;67117:1;67104:15;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;67085:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;67005:3;;;;;:::i;:::-;;;;66964:168;;;;67162:12;;:19;;67142:1;:17;;:39;;;;67202:17;67214:4;67202:11;:17::i;:::-;67194:32;;;;;;;;;;;;:::i;:::-;;;;;;;;;67245:18;67257:5;67245:11;:18::i;:::-;67237:33;;;;;;;;;;;;:::i;:::-;;;;;;;;;67286:32;67305:12;;67286:32;;;;;;;:::i;:::-;;;;;;;;66777:549:::0;;:::o;68131:1037::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;68221:1:::1;:10;;:25;;;;;;;;;;;;68217:114;;68291:13;:28;;;;;;;;;;:::i;:::-;68263:1;:10;;:25;;;:56;;;;;;;;;;;;;;;;;;68217:114;68345:1;:10;;:20;;;;;;;;;;;;68341:99;;68405:13;:23;;;;;;;;;;:::i;:::-;68382:1;:10;;:20;;;:46;;;;;;;;;;;;;;;;;;68341:99;68454:1;:10;;:21;;;;;;;;;;;;68450:102;;68516:13;:24;;;;;;;;;;:::i;:::-;68492:1;:10;;:21;;;:48;;;;;;;;;;;;;;;;;;68450:102;68566:1;:10;;:16;;;;;;;;;;;;68562:87;;68618:13;:19;;;;;;;;;;:::i;:::-;68599:1;:10;;:16;;;:38;;;;;;;;;;;;;;;;;;68562:87;68663:1;:10;;:18;;;;;;;;;;;;68659:93;;68719:13;:21;;;;;;;;;;:::i;:::-;68698:1;:10;;:18;;;:42;;;;;;;;;;;;;;;;;;68659:93;68766:1;:10;;:19;;;;;;;;;;;;68762:96;;68824:13;:22;;;;;;;;;;:::i;:::-;68802:1;:10;;:19;;;:44;;;;;;;;;;;;;;;;;;68762:96;68872:1;:10;;:23;;;;;;;;;;;;68868:108;;68938:13;:26;;;;;;;;;;:::i;:::-;68912:1;:10;;:23;;;:52;;;;;;;;;;;;;;;;;;68868:108;68990:1;:10;;:29;;;;;;;;;;;;68986:126;;69068:13;:32;;;;;;;;;;:::i;:::-;69036:1;:10;;:29;;;:64;;;;;;;;;;;;;;;;;;68986:126;69127:33;69149:1;:10;;69127:33;;;;;;:::i;:::-;;;;;;;;68131:1037:::0;:::o;71455:169::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;71562:4:::1;71535:1:::0;:14:::1;;:24;71550:8;71535:24;;;;;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;71582:34;71607:8;71582:34;;;;;;:::i;:::-;;;;;;;;71455:169:::0;:::o;65753:179::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;63825:21:::1;:19;:21::i;:::-;65870:5:::2;65846:1;:11;;:21;65858:8;65846:21;;;;;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;65891:33;65915:8;65891:33;;;;;;:::i;:::-;;;;;;;;65753:179:::0;:::o;65389:356::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;63825:21:::1;:19;:21::i;:::-;65479:20:::2;65526:1;:9;;;;;;;;;;;;65513:36;;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65479:73;;65563:18;65584:9;:23;;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65563:46;;65640:10;65628:22;;:8;:22;;::::0;65620:31:::2;;;::::0;::::2;;65686:4;65662:1:::0;:11:::2;;:21;65674:8;65662:21;;;;;;;;;;;;;;;;:28;;;;;;;;;;;;;;;;;;65706:31;65728:8;65706:31;;;;;;:::i;:::-;;;;;;;;65468:277;;65389:356:::0;:::o;71815:480::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;71942:6:::1;71938:350;71958:17;;:24;;71954:1;:28;71938:350;;;72043:17;72004:1;:14;;:36;72019:17;;72037:1;72019:20;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;72004:36;;;;;;;;;;;;;;;;:56;;;;;;;;;;;;;;;;;;72078:17;72075:202;;;72121:46;72146:17;;72164:1;72146:20;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;72121:46;;;;;;:::i;:::-;;;;;;;;72075:202;;;72213:48;72240:17;;72258:1;72240:20;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;72213:48;;;;;;:::i;:::-;;;;;;;;72075:202;71984:3;;;;;:::i;:::-;;;;71938:350;;;;71815:480:::0;;;:::o;69176:1622::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;69271:1:::1;:10;;:25;;;;;;;;;;;;69270:26;:93;;;;;69332:16;:31;;;;;;;;;;:::i;:::-;69300:63;;:1;:13:::0;::::1;:28;;;;;;;;;;;;:63;;;;69270:93;69267:187;;;69411:16;:31;;;;;;;;;;:::i;:::-;69380:1;:13:::0;::::1;:28;;;:62;;;;;;;;;;;;;;;;;;69267:187;69468:1;:10;;:20;;;;;;;;;;;;69467:21;:78;;;;;69519:16;:26;;;;;;;;;;:::i;:::-;69492:53;;:1;:13:::0;::::1;:23;;;;;;;;;;;;:53;;;;69467:78;:107;;;;;69550:16;:24;;;;;;;;;;:::i;:::-;69549:25;69467:107;69464:191;;;69617:16;:26;;;;;;;;;;:::i;:::-;69591:1;:13:::0;::::1;:23;;;:52;;;;;;;;;;;;;;;;;;69464:191;69669:1;:10;;:21;;;;;;;;;;;;69668:22;:81;;;;;69722:16;:27;;;;;;;;;;:::i;:::-;69694:55;;:1;:13:::0;::::1;:24;;;;;;;;;;;;:55;;;;69668:81;69665:167;;;69793:16;:27;;;;;;;;;;:::i;:::-;69766:1;:13:::0;::::1;:24;;;:54;;;;;;;;;;;;;;;;;;69665:167;69846:1;:10;;:16;;;;;;;;;;;;69845:17;:66;;;;;69889:16;:22;;;;;;;;;;:::i;:::-;69866:45;;:1;:13:::0;::::1;:19;;;;;;;;;;;;:45;;;;69845:66;69842:142;;;69950:16;:22;;;;;;;;;;:::i;:::-;69928:1;:13:::0;::::1;:19;;;:44;;;;;;;;;;;;;;;;;;69842:142;69998:1;:10;;:18;;;;;;;;;;;;69997:19;:72;;;;;70045:16;:24;;;;;;;;;;:::i;:::-;70020:49;;:1;:13:::0;::::1;:21;;;;;;;;;;;;:49;;;;69997:72;:100;;;;;70074:1;:13:::0;::::1;:23;;;;;;;;;;;;70073:24;69997:100;69994:180;;;70138:16;:24;;;;;;;;;;:::i;:::-;70114:1;:13:::0;::::1;:21;;;:48;;;;;;;;;;;;;;;;;;69994:180;70188:1;:10;;:19;;;;;;;;;;;;70187:20;:75;;;;;70237:16;:25;;;;;;;;;;:::i;:::-;70211:51;;:1;:13:::0;::::1;:22;;;;;;;;;;;;:51;;;;70187:75;70184:157;;;70304:16;:25;;;;;;;;;;:::i;:::-;70279:1;:13:::0;::::1;:22;;;:50;;;;;;;;;;;;;;;;;;70184:157;70355:1;:10;;:23;;;;;;;;;;;;70354:24;:87;;;;;70412:16;:29;;;;;;;;;;:::i;:::-;70382:59;;:1;:13:::0;::::1;:26;;;;;;;;;;;;:59;;;;70354:87;70351:177;;;70487:16;:29;;;;;;;;;;:::i;:::-;70458:1;:13:::0;::::1;:26;;;:58;;;;;;;;;;;;;;;;;;70351:177;70542:1;:10;;:29;;;;;;;;;;;;70541:30;:105;;;;;70611:16;:35;;;;;;;;;;:::i;:::-;70575:71;;:1;:13:::0;::::1;:32;;;;;;;;;;;;:71;;;;70541:105;70538:207;;;70698:16;:35;;;;;;;;;;:::i;:::-;70663:1;:13:::0;::::1;:32;;;:70;;;;;;;;;;;;;;;;;;70538:207;70760:30;70776:1;:13:::0;::::1;70760:30;;;;;;:::i;:::-;;;;;;;;69176:1622:::0;:::o;67849:274::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;68008:1:::1;67985:25;;:11;:25;;::::0;67977:34:::1;;;::::0;::::1;;68047:11;68022:1;:22;;;:36;;;;;;;;;;;;;;;;;;68074:41;68103:11;68074:41;;;;;;:::i;:::-;;;;;;;;67849:274:::0;:::o;64993:166::-;65032:4;65078:5;65052:31;;:1;:13;;:22;;;;;;;;;;;;:31;;;65049:75;;65107:5;65100:12;;;;65049:75;65141:1;:10;;;;;;;;;;;;65134:17;;64993:166;;:::o;8314:148::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;8421:1:::1;8384:40;;8405:6;::::0;::::1;;;;;;;;8384:40;;;;;;;;;;;;8452:1;8435:6:::0;::::1;:19;;;;;;;;;;;;;;;;;;8314:148::o:0;7663:87::-;7709:7;7736:6;;;;;;;;;;;7729:13;;7663:87;:::o;71632:175::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;71742:5:::1;71715:1;:14;;:24;71730:8;71715:24;;;;;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;71763:36;71790:8;71763:36;;;;;;:::i;:::-;;;;;;;;71632:175:::0;:::o;65940:706::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;63825:21:::1;:19;:21::i;:::-;66070:20:::2;66117:1;:9;;;;;;;;;;;;66104:36;;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66070:73;;66154:18;66175:9;:23;;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66154:46;;66215:6;66211:428;66231:17;;:24;;66227:1;:28;66211:428;;;66304:10;66280:34;;:17;;66298:1;66280:20;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;:34;;;66277:351;;66371:14;66335:1;:11;;:33;66347:17;;66365:1;66347:20;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;66335:33;;;;;;;;;;;;;;;;:50;;;;;;;;;;;;;;;;;;66407:14;66404:209;;;66451:43;66473:17;;66491:1;66473:20;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;66451:43;;;;;;:::i;:::-;;;;;;;;66404:209;;;66548:45;66572:17;;66590:1;66572:20;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;66548:45;;;;;;:::i;:::-;;;;;;;;66404:209;66277:351;66257:3;;;;;:::i;:::-;;;;66211:428;;;;66059:587;;65940:706:::0;;;:::o;71074:373::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;71168:9:::1;71149:28;;:1;:16;;:28;;;;71188:17;71221:1;:9;;;;;;;;;;;;71208:43;;;71252:1;:16;;;71208:61;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71188:81;;71307:4;71280:1:::0;:13:::1;;:24;71294:9;71280:24;;;;;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;71322:1;:11;;71339:9;71322:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71365:26;71381:9;71365:26;;;;;;:::i;:::-;;;;;;;;71407:32;71429:9;71407:32;;;;;;:::i;:::-;;;;;;;;71138:309;71074:373:::0;:::o;64030:145::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;64122:5:::1;64099:1;:10;;:20;64110:8;64099:20;;;;;;;;;;;;;;;;:28;;;;;;;;;;;;;;;;;;64143:24;64158:8;64143:24;;;;;;:::i;:::-;;;;;;;;64030:145:::0;:::o;63874:148::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;63969:4:::1;63943:1:::0;:10:::1;;:23;63954:11;63943:23;;;;;;;;;;;;;;;;:30;;;;;;;;;;;;;;;;;;63989:25;64002:11;63989:25;;;;;;:::i;:::-;;;;;;;;63874:148:::0;:::o;70806:260::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;70902:15:::1;70886:1;:13;;;:31;;;;;;;;;;;;;;;;;;70958:4;70928:1:::0;:10:::1;;:27;70939:15;70928:27;;;;;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;70978:29;70991:15;70978:29;;;;;;:::i;:::-;;;;;;;;71023:35;71042:15;71023:35;;;;;;:::i;:::-;;;;;;;;70806:260:::0;:::o;65167:214::-;65216:4;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;65241:1:::1;:13:::0;::::1;:22;;;;;;;;;;;;65233:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;65295:1;:10;;;;;;;;;;;;65294:11;65281:1;:10;;;:24;;;;;;;;;;;;;;;;;;65321;65334:1;:10;;;;;;;;;;;;65321:24;;;;;;:::i;:::-;;;;;;;;65363:1;:10;;;;;;;;;;;;65356:17;;65167:214:::0;:::o;67334:507::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;67441:12:::1;:27;;:31;;;67413:1;:6;;:21;;:25;;:59;;;;67512:12;:27;;:32;;;67483:1;:6;;:21;;:26;;:61;;;;67577:12;:23;;;67557:1;:6;;:17;;:43;;;;67632:12;:22;;;67613:1;:6;;:16;;:41;;;;67682:12;:18;;;67667:1;:6;;:12;;:33;;;;67721:17;67733:4;67721:11;:17::i;:::-;67713:32;;;;;;;;;;;;:::i;:::-;;;;;;;;;67764:18;67776:5;67764:11;:18::i;:::-;67756:33;;;;;;;;;;;;:::i;:::-;;;;;;;;;67805:28;67820:12;67805:28;;;;;;:::i;:::-;;;;;;;;67334:507:::0;:::o;8617:244::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;8726:1:::1;8706:22;;:8;:22;;::::0;8698:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;8816:8;8787:38;;8808:6;::::0;::::1;;;;;;;;8787:38;;;;;;;;;;;;8845:8;8836:6;::::0;:17:::1;;;;;;;;;;;;;;;;;;8617:244:::0;:::o;66654:115::-;66716:4;66740:1;:11;;:21;66752:8;66740:21;;;;;;;;;;;;;;;;;;;;;;;;;66733:28;;66654:115;;;:::o;6192:98::-;6245:7;6272:10;6265:17;;6192:98;:::o;64183:802::-;64239:4;64256:18;64288:5;64285:595;;;64324:1;:6;;:21;;:25;;;64310:39;;;;;:::i;:::-;;;64378:1;:6;;:16;;;64364:30;;;;;:::i;:::-;;;64413:6;64409:120;64429:1;:13;;:20;;;;64425:1;:24;64409:120;;;64489:1;:13;;64503:1;64489:16;;;;;;;;:::i;:::-;;;;;;;;;;;;:20;;:24;;;64475:38;;;;;:::i;:::-;;;64451:3;;;;;:::i;:::-;;;;64409:120;;;;64285:595;;;64575:1;:6;;:21;;:26;;;64561:40;;;;;:::i;:::-;;;64630:1;:6;;:12;;;64616:26;;;;;:::i;:::-;;;64671:1;:6;;:16;;;64657:30;;;;;:::i;:::-;;;64716:1;:6;;:17;;;64702:31;;;;;:::i;:::-;;;64752:6;64748:121;64768:1;:13;;:20;;;;64764:1;:24;64748:121;;;64828:1;:13;;64842:1;64828:16;;;;;;;;:::i;:::-;;;;;;;;;;;;:20;;:25;;;64814:39;;;;;:::i;:::-;;;64790:3;;;;;:::i;:::-;;;;64748:121;;;;64285:595;64907:1;:8;;;64893:10;:22;64890:65;;64939:4;64932:11;;;;;64890:65;64972:5;64965:12;;;64183:802;;;;:::o;63679:105::-;63743:1;:13;;:26;;;;;;;;;;;;63735:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;63679:105::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;88:117:1:-;197:1;194;187:12;211:117;320:1;317;310:12;334:117;443:1;440;433:12;457:117;566:1;563;556:12;580:117;689:1;686;679:12;729:597;831:8;841:6;891:3;884:4;876:6;872:17;868:27;858:122;;899:79;;:::i;:::-;858:122;1012:6;999:20;989:30;;1042:18;1034:6;1031:30;1028:117;;;1064:79;;:::i;:::-;1028:117;1178:4;1170:6;1166:17;1154:29;;1232:3;1224:4;1216:6;1212:17;1202:8;1198:32;1195:41;1192:128;;;1239:79;;:::i;:::-;1192:128;729:597;;;;;:::o;1332:617::-;1447:6;1455;1504:2;1492:9;1483:7;1479:23;1475:32;1472:119;;;1510:79;;:::i;:::-;1472:119;1658:1;1647:9;1643:17;1630:31;1688:18;1680:6;1677:30;1674:117;;;1710:79;;:::i;:::-;1674:117;1823:109;1924:7;1915:6;1904:9;1900:22;1823:109;:::i;:::-;1805:127;;;;1601:341;1332:617;;;;;:::o;1955:117::-;2064:1;2061;2054:12;2104:236;2181:5;2222:3;2213:6;2208:3;2204:16;2200:26;2197:113;;;2229:79;;:::i;:::-;2197:113;2328:6;2319:15;;2104:236;;;;:::o;2346:392::-;2436:6;2485:3;2473:9;2464:7;2460:23;2456:33;2453:120;;;2492:79;;:::i;:::-;2453:120;2612:1;2637:84;2713:7;2704:6;2693:9;2689:22;2637:84;:::i;:::-;2627:94;;2583:148;2346:392;;;;:::o;2744:126::-;2781:7;2821:42;2814:5;2810:54;2799:65;;2744:126;;;:::o;2876:96::-;2913:7;2942:24;2960:5;2942:24;:::i;:::-;2931:35;;2876:96;;;:::o;2978:122::-;3051:24;3069:5;3051:24;:::i;:::-;3044:5;3041:35;3031:63;;3090:1;3087;3080:12;3031:63;2978:122;:::o;3106:139::-;3152:5;3190:6;3177:20;3168:29;;3206:33;3233:5;3206:33;:::i;:::-;3106:139;;;;:::o;3251:329::-;3310:6;3359:2;3347:9;3338:7;3334:23;3330:32;3327:119;;;3365:79;;:::i;:::-;3327:119;3485:1;3510:53;3555:7;3546:6;3535:9;3531:22;3510:53;:::i;:::-;3500:63;;3456:117;3251:329;;;;:::o;3603:568::-;3676:8;3686:6;3736:3;3729:4;3721:6;3717:17;3713:27;3703:122;;3744:79;;:::i;:::-;3703:122;3857:6;3844:20;3834:30;;3887:18;3879:6;3876:30;3873:117;;;3909:79;;:::i;:::-;3873:117;4023:4;4015:6;4011:17;3999:29;;4077:3;4069:4;4061:6;4057:17;4047:8;4043:32;4040:41;4037:128;;;4084:79;;:::i;:::-;4037:128;3603:568;;;;;:::o;4177:90::-;4211:7;4254:5;4247:13;4240:21;4229:32;;4177:90;;;:::o;4273:116::-;4343:21;4358:5;4343:21;:::i;:::-;4336:5;4333:32;4323:60;;4379:1;4376;4369:12;4323:60;4273:116;:::o;4395:133::-;4438:5;4476:6;4463:20;4454:29;;4492:30;4516:5;4492:30;:::i;:::-;4395:133;;;;:::o;4534:698::-;4626:6;4634;4642;4691:2;4679:9;4670:7;4666:23;4662:32;4659:119;;;4697:79;;:::i;:::-;4659:119;4845:1;4834:9;4830:17;4817:31;4875:18;4867:6;4864:30;4861:117;;;4897:79;;:::i;:::-;4861:117;5010:80;5082:7;5073:6;5062:9;5058:22;5010:80;:::i;:::-;4992:98;;;;4788:312;5139:2;5165:50;5207:7;5198:6;5187:9;5183:22;5165:50;:::i;:::-;5155:60;;5110:115;4534:698;;;;;:::o;5238:109::-;5319:21;5334:5;5319:21;:::i;:::-;5314:3;5307:34;5238:109;;:::o;5353:210::-;5440:4;5478:2;5467:9;5463:18;5455:26;;5491:65;5553:1;5542:9;5538:17;5529:6;5491:65;:::i;:::-;5353:210;;;;:::o;5569:118::-;5656:24;5674:5;5656:24;:::i;:::-;5651:3;5644:37;5569:118;;:::o;5693:222::-;5786:4;5824:2;5813:9;5809:18;5801:26;;5837:71;5905:1;5894:9;5890:17;5881:6;5837:71;:::i;:::-;5693:222;;;;:::o;5921:86::-;5956:7;5996:4;5989:5;5985:16;5974:27;;5921:86;;;:::o;6013:118::-;6084:22;6100:5;6084:22;:::i;:::-;6077:5;6074:33;6064:61;;6121:1;6118;6111:12;6064:61;6013:118;:::o;6137:135::-;6181:5;6219:6;6206:20;6197:29;;6235:31;6260:5;6235:31;:::i;:::-;6137:135;;;;:::o;6278:325::-;6335:6;6384:2;6372:9;6363:7;6359:23;6355:32;6352:119;;;6390:79;;:::i;:::-;6352:119;6510:1;6535:51;6578:7;6569:6;6558:9;6554:22;6535:51;:::i;:::-;6525:61;;6481:115;6278:325;;;;:::o;6628:229::-;6698:5;6739:3;6730:6;6725:3;6721:16;6717:26;6714:113;;;6746:79;;:::i;:::-;6714:113;6845:6;6836:15;;6628:229;;;;:::o;6863:378::-;6946:6;6995:3;6983:9;6974:7;6970:23;6966:33;6963:120;;;7002:79;;:::i;:::-;6963:120;7122:1;7147:77;7216:7;7207:6;7196:9;7192:22;7147:77;:::i;:::-;7137:87;;7093:141;6863:378;;;;:::o;7247:169::-;7331:11;7365:6;7360:3;7353:19;7405:4;7400:3;7396:14;7381:29;;7247:169;;;;:::o;7422:182::-;7562:34;7558:1;7550:6;7546:14;7539:58;7422:182;:::o;7610:366::-;7752:3;7773:67;7837:2;7832:3;7773:67;:::i;:::-;7766:74;;7849:93;7938:3;7849:93;:::i;:::-;7967:2;7962:3;7958:12;7951:19;;7610:366;;;:::o;7982:419::-;8148:4;8186:2;8175:9;8171:18;8163:26;;8235:9;8229:4;8225:20;8221:1;8210:9;8206:17;8199:47;8263:131;8389:4;8263:131;:::i;:::-;8255:139;;7982:419;;;:::o;8407:180::-;8455:77;8452:1;8445:88;8552:4;8549:1;8542:15;8576:4;8573:1;8566:15;8593:188;8631:3;8650:18;8666:1;8650:18;:::i;:::-;8645:23;;8682:18;8698:1;8682:18;:::i;:::-;8677:23;;8723:1;8720;8716:9;8709:16;;8746:4;8741:3;8738:13;8735:39;;;8754:18;;:::i;:::-;8735:39;8593:188;;;;:::o;8787:153::-;8927:5;8923:1;8915:6;8911:14;8904:29;8787:153;:::o;8946:365::-;9088:3;9109:66;9173:1;9168:3;9109:66;:::i;:::-;9102:73;;9184:93;9273:3;9184:93;:::i;:::-;9302:2;9297:3;9293:12;9286:19;;8946:365;;;:::o;9317:419::-;9483:4;9521:2;9510:9;9506:18;9498:26;;9570:9;9564:4;9560:20;9556:1;9545:9;9541:17;9534:47;9598:131;9724:4;9598:131;:::i;:::-;9590:139;;9317:419;;;:::o;9742:180::-;9790:77;9787:1;9780:88;9887:4;9884:1;9877:15;9911:4;9908:1;9901:15;9928:117;10037:1;10034;10027:12;10051:117;10160:1;10157;10150:12;10174:117;10283:1;10280;10273:12;10297:395;10392:4;10446:11;10433:25;10546:1;10540:4;10536:12;10525:8;10509:14;10505:29;10501:48;10481:18;10477:73;10467:168;;10554:79;;:::i;:::-;10467:168;10666:18;10656:8;10652:33;10644:41;;10397:295;10297:395;;;;:::o;10884:725::-;10962:4;10968:6;11024:11;11011:25;11124:1;11118:4;11114:12;11103:8;11087:14;11083:29;11079:48;11059:18;11055:73;11045:168;;11132:79;;:::i;:::-;11045:168;11244:18;11234:8;11230:33;11222:41;;11296:4;11283:18;11273:28;;11324:18;11316:6;11313:30;11310:117;;;11346:79;;:::i;:::-;11310:117;11454:2;11448:4;11444:13;11436:21;;11511:4;11503:6;11499:17;11483:14;11479:38;11473:4;11469:49;11466:136;;;11521:79;;:::i;:::-;11466:136;10975:634;10884:725;;;;;:::o;11615:97::-;11674:6;11702:3;11692:13;;11615:97;;;;:::o;11718:180::-;11766:77;11763:1;11756:88;11863:4;11860:1;11853:15;11887:4;11884:1;11877:15;11904:180;11952:77;11949:1;11942:88;12049:4;12046:1;12039:15;12073:4;12070:1;12063:15;12090:320;12134:6;12171:1;12165:4;12161:12;12151:22;;12218:1;12212:4;12208:12;12239:18;12229:81;;12295:4;12287:6;12283:17;12273:27;;12229:81;12357:2;12349:6;12346:14;12326:18;12323:38;12320:84;;12376:18;;:::i;:::-;12320:84;12141:269;12090:320;;;:::o;12416:141::-;12465:4;12488:3;12480:11;;12511:3;12508:1;12501:14;12545:4;12542:1;12532:18;12524:26;;12416:141;;;:::o;12563:93::-;12600:6;12647:2;12642;12635:5;12631:14;12627:23;12617:33;;12563:93;;;:::o;12662:107::-;12706:8;12756:5;12750:4;12746:16;12725:37;;12662:107;;;;:::o;12775:393::-;12844:6;12894:1;12882:10;12878:18;12917:97;12947:66;12936:9;12917:97;:::i;:::-;13035:39;13065:8;13054:9;13035:39;:::i;:::-;13023:51;;13107:4;13103:9;13096:5;13092:21;13083:30;;13156:4;13146:8;13142:19;13135:5;13132:30;13122:40;;12851:317;;12775:393;;;;;:::o;13174:77::-;13211:7;13240:5;13229:16;;13174:77;;;:::o;13257:60::-;13285:3;13306:5;13299:12;;13257:60;;;:::o;13323:142::-;13373:9;13406:53;13424:34;13433:24;13451:5;13433:24;:::i;:::-;13424:34;:::i;:::-;13406:53;:::i;:::-;13393:66;;13323:142;;;:::o;13471:75::-;13514:3;13535:5;13528:12;;13471:75;;;:::o;13552:269::-;13662:39;13693:7;13662:39;:::i;:::-;13723:91;13772:41;13796:16;13772:41;:::i;:::-;13764:6;13757:4;13751:11;13723:91;:::i;:::-;13717:4;13710:105;13628:193;13552:269;;;:::o;13827:73::-;13872:3;13827:73;:::o;13906:189::-;13983:32;;:::i;:::-;14024:65;14082:6;14074;14068:4;14024:65;:::i;:::-;13959:136;13906:189;;:::o;14101:186::-;14161:120;14178:3;14171:5;14168:14;14161:120;;;14232:39;14269:1;14262:5;14232:39;:::i;:::-;14205:1;14198:5;14194:13;14185:22;;14161:120;;;14101:186;;:::o;14293:543::-;14394:2;14389:3;14386:11;14383:446;;;14428:38;14460:5;14428:38;:::i;:::-;14512:29;14530:10;14512:29;:::i;:::-;14502:8;14498:44;14695:2;14683:10;14680:18;14677:49;;;14716:8;14701:23;;14677:49;14739:80;14795:22;14813:3;14795:22;:::i;:::-;14785:8;14781:37;14768:11;14739:80;:::i;:::-;14398:431;;14383:446;14293:543;;;:::o;14842:117::-;14896:8;14946:5;14940:4;14936:16;14915:37;;14842:117;;;;:::o;14965:169::-;15009:6;15042:51;15090:1;15086:6;15078:5;15075:1;15071:13;15042:51;:::i;:::-;15038:56;15123:4;15117;15113:15;15103:25;;15016:118;14965:169;;;;:::o;15139:295::-;15215:4;15361:29;15386:3;15380:4;15361:29;:::i;:::-;15353:37;;15423:3;15420:1;15416:11;15410:4;15407:21;15399:29;;15139:295;;;;:::o;15439:1403::-;15563:44;15603:3;15598;15563:44;:::i;:::-;15672:18;15664:6;15661:30;15658:56;;;15694:18;;:::i;:::-;15658:56;15738:38;15770:4;15764:11;15738:38;:::i;:::-;15823:67;15883:6;15875;15869:4;15823:67;:::i;:::-;15917:1;15946:2;15938:6;15935:14;15963:1;15958:632;;;;16634:1;16651:6;16648:84;;;16707:9;16702:3;16698:19;16685:33;16676:42;;16648:84;16758:67;16818:6;16811:5;16758:67;:::i;:::-;16752:4;16745:81;16607:229;15928:908;;15958:632;16010:4;16006:9;15998:6;15994:22;16044:37;16076:4;16044:37;:::i;:::-;16103:1;16117:215;16131:7;16128:1;16125:14;16117:215;;;16217:9;16212:3;16208:19;16195:33;16187:6;16180:49;16268:1;16260:6;16256:14;16246:24;;16315:2;16304:9;16300:18;16287:31;;16154:4;16151:1;16147:12;16142:17;;16117:215;;;16360:6;16351:7;16348:19;16345:186;;;16425:9;16420:3;16416:19;16403:33;16468:48;16510:4;16502:6;16498:17;16487:9;16468:48;:::i;:::-;16460:6;16453:64;16368:163;16345:186;16577:1;16573;16565:6;16561:14;16557:22;16551:4;16544:36;15965:625;;;15928:908;;15538:1304;;;15439:1403;;;:::o;16848:218::-;16963:97;17052:7;17043;17037:4;16963:97;:::i;:::-;16848:218;;;:::o;17072:122::-;17145:24;17163:5;17145:24;:::i;:::-;17138:5;17135:35;17125:63;;17184:1;17181;17174:12;17125:63;17072:122;:::o;17200:186::-;17245:11;17294:3;17281:17;17307:33;17334:5;17307:33;:::i;:::-;17374:5;17350:29;;17257:129;17200:186;;;:::o;17392:92::-;17424:8;17471:5;17468:1;17464:13;17443:34;;17392:92;;;:::o;17490:290::-;17548:6;17577:66;17664:22;17677:8;17664:22;:::i;:::-;17652:34;;17719:4;17715:9;17708:5;17704:21;17695:30;;17768:4;17758:8;17754:19;17747:5;17744:30;17734:40;;17555:225;17490:290;;;;:::o;17786:262::-;17896:39;17927:7;17896:39;:::i;:::-;17957:84;17999:41;18023:16;17999:41;:::i;:::-;17992:4;17986:11;17957:84;:::i;:::-;17951:4;17944:98;17862:186;17786:262;;:::o;18054:797::-;18222:1;18216:4;18212:12;18268:1;18261:5;18257:13;18318:12;18361:42;18389:13;18361:42;:::i;:::-;18344:59;;18417:78;18481:13;18469:10;18417:78;:::i;:::-;18179:327;;;18559:1;18553:4;18549:12;18605:2;18598:5;18594:14;18656:12;18699:42;18727:13;18699:42;:::i;:::-;18682:59;;18755:78;18819:13;18807:10;18755:78;:::i;:::-;18516:328;;;18054:797;;:::o;18857:240::-;18985:106;19083:7;19077:4;18985:106;:::i;:::-;18857:240;;:::o;19103:186::-;19148:11;19197:3;19184:17;19210:33;19237:5;19210:33;:::i;:::-;19277:5;19253:29;;19160:129;19103:186;;;:::o;19295:266::-;19353:6;19382:42;19445:22;19458:8;19445:22;:::i;:::-;19433:34;;19500:4;19496:9;19489:5;19485:21;19476:30;;19549:4;19539:8;19535:19;19528:5;19525:30;19515:40;;19360:201;19295:266;;;;:::o;19567:142::-;19617:9;19650:53;19668:34;19677:24;19695:5;19677:24;:::i;:::-;19668:34;:::i;:::-;19650:53;:::i;:::-;19637:66;;19567:142;;;:::o;19715:126::-;19765:9;19798:37;19829:5;19798:37;:::i;:::-;19785:50;;19715:126;;;:::o;19847:::-;19897:9;19930:37;19961:5;19930:37;:::i;:::-;19917:50;;19847:126;;;:::o;19979:75::-;20022:3;20043:5;20036:12;;19979:75;;;:::o;20060:262::-;20170:39;20201:7;20170:39;:::i;:::-;20231:84;20273:41;20297:16;20273:41;:::i;:::-;20266:4;20260:11;20231:84;:::i;:::-;20225:4;20218:98;20136:186;20060:262;;:::o;20328:180::-;20370:11;20419:3;20406:17;20432:30;20456:5;20432:30;:::i;:::-;20496:5;20472:29;;20382:126;20328:180;;;:::o;20514:96::-;20548:8;20597:5;20592:3;20588:15;20567:36;;20514:96;;;:::o;20616:270::-;20674:6;20703:44;20768:24;20783:8;20768:24;:::i;:::-;20756:36;;20825:4;20821:9;20814:5;20810:21;20801:30;;20874:4;20864:8;20860:19;20853:5;20850:30;20840:40;;20681:205;20616:270;;;;:::o;20892:104::-;20936:9;20969:21;20984:5;20969:21;:::i;:::-;20956:34;;20892:104;;;:::o;21002:72::-;21042:3;21063:5;21056:12;;21002:72;;;:::o;21080:248::-;21185:33;21210:7;21185:33;:::i;:::-;21240:81;21282:38;21303:16;21282:38;:::i;:::-;21275:4;21269:11;21240:81;:::i;:::-;21234:4;21227:95;21151:177;21080:248;;:::o;21334:1473::-;21514:1;21508:4;21504:12;21560:1;21553:5;21549:13;21625:63;21675:12;21668:5;21625:63;:::i;:::-;21702:112;21800:13;21785;21773:10;21702:112;:::i;:::-;21471:354;;;;21878:1;21872:4;21868:12;21924:2;21917:5;21913:14;21975:12;22001:119;22106:13;22094:10;22001:119;:::i;:::-;21835:296;;;22184:1;22178:4;22174:12;22230:2;22223:5;22219:14;22281:12;22324:42;22352:13;22324:42;:::i;:::-;22307:59;;22380:78;22444:13;22432:10;22380:78;:::i;:::-;22141:328;;;22522:1;22516:4;22512:12;22568:3;22561:5;22557:15;22620:12;22663:39;22688:13;22663:39;:::i;:::-;22646:56;;22716:73;22775:13;22763:10;22716:73;:::i;:::-;22479:321;;;21334:1473;;:::o;22813:264::-;22953:118;23063:7;23057:4;22953:118;:::i;:::-;22813:264;;:::o;23083:233::-;23122:3;23145:24;23163:5;23145:24;:::i;:::-;23136:33;;23191:66;23184:5;23181:77;23178:103;;23261:18;;:::i;:::-;23178:103;23308:1;23301:5;23297:13;23290:20;;23083:233;;;:::o;23322:152::-;23462:4;23458:1;23450:6;23446:14;23439:28;23322:152;:::o;23480:365::-;23622:3;23643:66;23707:1;23702:3;23643:66;:::i;:::-;23636:73;;23718:93;23807:3;23718:93;:::i;:::-;23836:2;23831:3;23827:12;23820:19;;23480:365;;;:::o;23851:419::-;24017:4;24055:2;24044:9;24040:18;24032:26;;24104:9;24098:4;24094:20;24090:1;24079:9;24075:17;24068:47;24132:131;24258:4;24132:131;:::i;:::-;24124:139;;23851:419;;;:::o;24276:152::-;24416:4;24412:1;24404:6;24400:14;24393:28;24276:152;:::o;24434:365::-;24576:3;24597:66;24661:1;24656:3;24597:66;:::i;:::-;24590:73;;24672:93;24761:3;24672:93;:::i;:::-;24790:2;24785:3;24781:12;24774:19;;24434:365;;;:::o;24805:419::-;24971:4;25009:2;24998:9;24994:18;24986:26;;25058:9;25052:4;25048:20;25044:1;25033:9;25029:17;25022:47;25086:131;25212:4;25086:131;:::i;:::-;25078:139;;24805:419;;;:::o;25230:211::-;25356:11;25390:6;25385:3;25378:19;25430:4;25425:3;25421:14;25406:29;;25230:211;;;;:::o;25447:131::-;25545:4;25568:3;25560:11;;25447:131;;;:::o;25584:117::-;25693:1;25690;25683:12;25707:117;25816:1;25813;25806:12;25830:117;25939:1;25936;25929:12;25953:712;26018:5;26025:6;26081:3;26068:17;26173:1;26167:4;26163:12;26152:8;26136:14;26132:29;26128:48;26108:18;26104:73;26094:168;;26181:79;;:::i;:::-;26094:168;26304:8;26284:18;26280:33;26271:42;;26346:5;26333:19;26323:29;;26381:4;26374:5;26370:16;26361:25;;26409:18;26401:6;26398:30;26395:117;;;26431:79;;:::i;:::-;26395:117;26567:4;26559:6;26555:17;26539:14;26535:38;26528:5;26524:50;26521:137;;;26577:79;;:::i;:::-;26521:137;26032:633;25953:712;;;;;:::o;26671:159::-;26745:11;26779:6;26774:3;26767:19;26819:4;26814:3;26810:14;26795:29;;26671:159;;;;:::o;26836:146::-;26933:6;26928:3;26923;26910:30;26974:1;26965:6;26960:3;26956:16;26949:27;26836:146;;;:::o;26988:102::-;27029:6;27080:2;27076:7;27071:2;27064:5;27060:14;27056:28;27046:38;;26988:102;;;:::o;27120:297::-;27208:3;27229:61;27283:6;27278:3;27229:61;:::i;:::-;27222:68;;27300:56;27349:6;27344:3;27337:5;27300:56;:::i;:::-;27381:29;27403:6;27381:29;:::i;:::-;27376:3;27372:39;27365:46;;27120:297;;;;;:::o;27423:109::-;27498:5;27523:3;27514:12;;27423:109;;;;:::o;27538:139::-;27584:5;27622:6;27609:20;27600:29;;27638:33;27665:5;27638:33;:::i;:::-;27538:139;;;;:::o;27683:122::-;27735:5;27760:39;27795:2;27790:3;27786:12;27781:3;27760:39;:::i;:::-;27751:48;;27683:122;;;;:::o;27811:108::-;27888:24;27906:5;27888:24;:::i;:::-;27883:3;27876:37;27811:108;;:::o;27957:544::-;28088:4;28083:3;28079:14;28157:50;28201:4;28194:5;28190:16;28183:5;28157:50;:::i;:::-;28220:63;28277:4;28272:3;28268:14;28254:12;28220:63;:::i;:::-;28103:190;28358:50;28402:4;28395:5;28391:16;28384:5;28358:50;:::i;:::-;28421:63;28478:4;28473:3;28469:14;28455:12;28421:63;:::i;:::-;28303:191;28057:444;27957:544;;:::o;28507:122::-;28559:5;28584:39;28619:2;28614:3;28610:12;28605:3;28584:39;:::i;:::-;28575:48;;28507:122;;;;:::o;28635:108::-;28712:24;28730:5;28712:24;:::i;:::-;28707:3;28700:37;28635:108;;:::o;28749:116::-;28798:5;28823:36;28855:2;28850:3;28846:12;28841:3;28823:36;:::i;:::-;28814:45;;28749:116;;;;:::o;28871:99::-;28942:21;28957:5;28942:21;:::i;:::-;28937:3;28930:34;28871:99;;:::o;29020:1168::-;29135:3;29171:4;29166:3;29162:14;29255:62;29311:4;29304:5;29300:16;29293:5;29255:62;:::i;:::-;29364:3;29358:4;29354:14;29347:4;29342:3;29338:14;29331:38;29390:89;29474:4;29460:12;29446;29390:89;:::i;:::-;29382:97;;29186:304;;29554:73;29621:4;29614:5;29610:16;29603:5;29554:73;:::i;:::-;29640:107;29741:4;29736:3;29732:14;29718:12;29640:107;:::i;:::-;29500:257;29824:50;29868:4;29861:5;29857:16;29850:5;29824:50;:::i;:::-;29887:63;29944:4;29939:3;29935:14;29921:12;29887:63;:::i;:::-;29767:193;30034:47;30075:4;30068:5;30064:16;30057:5;30034:47;:::i;:::-;30094:57;30145:4;30140:3;30136:14;30122:12;30094:57;:::i;:::-;29970:191;30178:4;30171:11;;29140:1048;29020:1168;;;;:::o;30194:268::-;30319:10;30354:102;30452:3;30444:6;30354:102;:::i;:::-;30340:116;;30194:268;;;;:::o;30468:376::-;30550:5;30605:3;30592:17;30697:1;30691:4;30687:12;30676:8;30660:14;30656:29;30652:48;30632:18;30628:73;30618:168;;30705:79;;:::i;:::-;30618:168;30828:8;30808:18;30804:33;30795:42;;30556:288;30468:376;;;;:::o;30850:144::-;30951:4;30983;30978:3;30974:14;30966:22;;30850:144;;;:::o;31048:1104::-;31233:3;31256:113;31362:6;31357:3;31256:113;:::i;:::-;31249:120;;31395:3;31440:4;31432:6;31428:17;31423:3;31419:27;31470:87;31551:5;31470:87;:::i;:::-;31580:7;31611:1;31596:511;31621:6;31618:1;31615:13;31596:511;;;31692:9;31686:4;31682:20;31677:3;31670:33;31737:71;31801:6;31792:7;31737:71;:::i;:::-;31829:120;31944:4;31929:13;31829:120;:::i;:::-;31821:128;;31972:91;32056:6;31972:91;:::i;:::-;31962:101;;32092:4;32087:3;32083:14;32076:21;;31656:451;31643:1;31640;31636:9;31631:14;;31596:511;;;31600:14;32123:4;32116:11;;32143:3;32136:10;;31238:914;;;;31048:1104;;;;;:::o;32158:505::-;32367:4;32405:2;32394:9;32390:18;32382:26;;32454:9;32448:4;32444:20;32440:1;32429:9;32425:17;32418:47;32482:174;32651:4;32642:6;32634;32482:174;:::i;:::-;32474:182;;32158:505;;;;;:::o;32669:323::-;32725:6;32774:2;32762:9;32753:7;32749:23;32745:32;32742:119;;;32780:79;;:::i;:::-;32742:119;32900:1;32925:50;32967:7;32958:6;32947:9;32943:22;32925:50;:::i;:::-;32915:60;;32871:114;32669:323;;;;:::o;32998:102::-;33040:8;33087:5;33084:1;33080:13;33059:34;;32998:102;;;:::o;33106:98::-;33153:7;33193:4;33186:5;33182:16;33171:27;;33106:98;;;:::o;33210:160::-;33276:5;33301:63;33329:34;33352:10;33329:34;:::i;:::-;33301:63;:::i;:::-;33292:72;;33210:160;;;:::o;33376:102::-;33418:8;33465:5;33462:1;33458:13;33437:34;;33376:102;;;:::o;33484:160::-;33550:5;33575:63;33603:34;33626:10;33603:34;:::i;:::-;33575:63;:::i;:::-;33566:72;;33484:160;;;:::o;33650:104::-;33693:8;33741:5;33737:2;33733:14;33712:35;;33650:104;;;:::o;33760:161::-;33826:5;33851:64;33879:35;33903:10;33879:35;:::i;:::-;33851:64;:::i;:::-;33842:73;;33760:161;;;:::o;33927:104::-;33970:8;34018:5;34014:2;34010:14;33989:35;;33927:104;;;:::o;34037:161::-;34103:5;34128:64;34156:35;34180:10;34156:35;:::i;:::-;34128:64;:::i;:::-;34119:73;;34037:161;;;:::o;34204:104::-;34247:8;34295:5;34291:2;34287:14;34266:35;;34204:104;;;:::o;34314:161::-;34380:5;34405:64;34433:35;34457:10;34433:35;:::i;:::-;34405:64;:::i;:::-;34396:73;;34314:161;;;:::o;34481:104::-;34524:8;34572:5;34568:2;34564:14;34543:35;;34481:104;;;:::o;34591:161::-;34657:5;34682:64;34710:35;34734:10;34710:35;:::i;:::-;34682:64;:::i;:::-;34673:73;;34591:161;;;:::o;34758:104::-;34801:8;34849:5;34845:2;34841:14;34820:35;;34758:104;;;:::o;34868:161::-;34934:5;34959:64;34987:35;35011:10;34987:35;:::i;:::-;34959:64;:::i;:::-;34950:73;;34868:161;;;:::o;35035:104::-;35078:8;35126:5;35122:2;35118:14;35097:35;;35035:104;;;:::o;35145:161::-;35211:5;35236:64;35264:35;35288:10;35264:35;:::i;:::-;35236:64;:::i;:::-;35227:73;;35145:161;;;:::o;35360:1868::-;35512:6;35507:3;35503:16;35545:1;35630:4;35623:5;35619:16;35613:23;35600:36;;35669:52;35711:9;35669:52;:::i;:::-;35734:57;35785:4;35780:3;35776:14;35762:12;35734:57;:::i;:::-;35556:245;35872:52;35914:9;35872:52;:::i;:::-;35937:57;35988:4;35983:3;35979:14;35965:12;35937:57;:::i;:::-;35811:193;36074:52;36116:9;36074:52;:::i;:::-;36139:57;36190:4;36185:3;36181:14;36167:12;36139:57;:::i;:::-;36014:192;36272:52;36314:9;36272:52;:::i;:::-;36337:57;36388:4;36383:3;36379:14;36365:12;36337:57;:::i;:::-;36216:188;36477:52;36519:9;36477:52;:::i;:::-;36542:57;36593:4;36588:3;36584:14;36570:12;36542:57;:::i;:::-;36414:195;36677:52;36719:9;36677:52;:::i;:::-;36742:57;36793:4;36788:3;36784:14;36770:12;36742:57;:::i;:::-;36619:190;36878:52;36920:9;36878:52;:::i;:::-;36943:57;36994:4;36989:3;36985:14;36971:12;36943:57;:::i;:::-;36819:191;37089:52;37131:9;37089:52;:::i;:::-;37154:57;37205:4;37200:3;37196:14;37182:12;37154:57;:::i;:::-;37020:201;35481:1747;;35360:1868;;:::o;37234:333::-;37382:4;37420:3;37409:9;37405:19;37397:27;;37434:126;37557:1;37546:9;37542:17;37533:6;37434:126;:::i;:::-;37234:333;;;;:::o;37573:143::-;37630:5;37661:6;37655:13;37646:22;;37677:33;37704:5;37677:33;:::i;:::-;37573:143;;;;:::o;37722:351::-;37792:6;37841:2;37829:9;37820:7;37816:23;37812:32;37809:119;;;37847:79;;:::i;:::-;37809:119;37967:1;37992:64;38048:7;38039:6;38028:9;38024:22;37992:64;:::i;:::-;37982:74;;37938:128;37722:351;;;;:::o;38079:118::-;38166:24;38184:5;38166:24;:::i;:::-;38161:3;38154:37;38079:118;;:::o;38203:222::-;38296:4;38334:2;38323:9;38319:18;38311:26;;38347:71;38415:1;38404:9;38400:17;38391:6;38347:71;:::i;:::-;38203:222;;;;:::o;38431:138::-;38479:9;38512:51;38530:32;38539:22;38555:5;38539:22;:::i;:::-;38530:32;:::i;:::-;38512:51;:::i;:::-;38499:64;;38431:138;;;:::o;38575:127::-;38660:35;38689:5;38660:35;:::i;:::-;38655:3;38648:48;38575:127;;:::o;38708:218::-;38799:4;38837:2;38826:9;38822:18;38814:26;;38850:69;38916:1;38905:9;38901:17;38892:6;38850:69;:::i;:::-;38708:218;;;;:::o;38932:152::-;39072:4;39068:1;39060:6;39056:14;39049:28;38932:152;:::o;39090:365::-;39232:3;39253:66;39317:1;39312:3;39253:66;:::i;:::-;39246:73;;39328:93;39417:3;39328:93;:::i;:::-;39446:2;39441:3;39437:12;39430:19;;39090:365;;;:::o;39461:419::-;39627:4;39665:2;39654:9;39650:18;39642:26;;39714:9;39708:4;39704:20;39700:1;39689:9;39685:17;39678:47;39742:131;39868:4;39742:131;:::i;:::-;39734:139;;39461:419;;;:::o;39920:1048::-;40063:4;40058:3;40054:14;40143:73;40210:4;40203:5;40199:16;40192:5;40143:73;:::i;:::-;40229:107;40330:4;40325:3;40321:14;40307:12;40229:107;:::i;:::-;40078:268;40417:50;40461:4;40454:5;40450:16;40443:5;40417:50;:::i;:::-;40480:63;40537:4;40532:3;40528:14;40514:12;40480:63;:::i;:::-;40356:197;40623:50;40667:4;40660:5;40656:16;40649:5;40623:50;:::i;:::-;40686:63;40743:4;40738:3;40734:14;40720:12;40686:63;:::i;:::-;40563:196;40825:50;40869:4;40862:5;40858:16;40851:5;40825:50;:::i;:::-;40888:63;40945:4;40940:3;40936:14;40922:12;40888:63;:::i;:::-;40769:192;40032:936;39920:1048;;:::o;40974:315::-;41113:4;41151:3;41140:9;41136:19;41128:27;;41165:117;41279:1;41268:9;41264:17;41255:6;41165:117;:::i;:::-;40974:315;;;;:::o;41295:225::-;41435:34;41431:1;41423:6;41419:14;41412:58;41504:8;41499:2;41491:6;41487:15;41480:33;41295:225;:::o;41526:366::-;41668:3;41689:67;41753:2;41748:3;41689:67;:::i;:::-;41682:74;;41765:93;41854:3;41765:93;:::i;:::-;41883:2;41878:3;41874:12;41867:19;;41526:366;;;:::o;41898:419::-;42064:4;42102:2;42091:9;42087:18;42079:26;;42151:9;42145:4;42141:20;42137:1;42126:9;42122:17;42115:47;42179:131;42305:4;42179:131;:::i;:::-;42171:139;;41898:419;;;:::o;42323:191::-;42363:3;42382:20;42400:1;42382:20;:::i;:::-;42377:25;;42416:20;42434:1;42416:20;:::i;:::-;42411:25;;42459:1;42456;42452:9;42445:16;;42480:3;42477:1;42474:10;42471:36;;;42487:18;;:::i;:::-;42471:36;42323:191;;;;:::o;42520:152::-;42660:4;42656:1;42648:6;42644:14;42637:28;42520:152;:::o;42678:365::-;42820:3;42841:66;42905:1;42900:3;42841:66;:::i;:::-;42834:73;;42916:93;43005:3;42916:93;:::i;:::-;43034:2;43029:3;43025:12;43018:19;;42678:365;;;:::o;43049:419::-;43215:4;43253:2;43242:9;43238:18;43230:26;;43302:9;43296:4;43292:20;43288:1;43277:9;43273:17;43266:47;43330:131;43456:4;43330:131;:::i;:::-;43322:139;;43049:419;;;:::o
Swarm Source
ipfs://00e7446c45b2ec67e53d57c81ef33b0db698fe6805990c0c43c4753403dc7787
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.