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 Name:
TaxFacet
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-06-16 */ // 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 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; 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"); // 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 _beforeTokenTransfer(sender, recipient, amount); 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":"_sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"},{"indexed":false,"internalType":"address","name":"_wallet","type":"address"},{"indexed":false,"internalType":"bool","name":"_isBuy","type":"bool"}],"name":"BuyBackTaxInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"},{"indexed":false,"internalType":"address","name":"_wallet","type":"address"},{"indexed":false,"internalType":"bool","name":"_isBuy","type":"bool"}],"name":"CustomTaxInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"ExcludedAccount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"IncludedAccount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"},{"indexed":false,"internalType":"address","name":"_wallet","type":"address"},{"indexed":false,"internalType":"bool","name":"_isBuy","type":"bool"}],"name":"LPTaxInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"MarketInit","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":"uint256","name":"tAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rTotal_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"teeTotal_","type":"uint256"}],"name":"Reflect","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"},{"indexed":false,"internalType":"address","name":"_wallet","type":"address"},{"indexed":false,"internalType":"bool","name":"_isBuy","type":"bool"}],"name":"TransactionTaxInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"_transfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"excludeAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"handleTaxes","outputs":[{"internalType":"uint256","name":"totalTaxAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"includeAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcluded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tAmount","type":"uint256"}],"name":"reflect","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tAmount","type":"uint256"},{"internalType":"bool","name":"deductTransferFee","type":"bool"}],"name":"reflectionFromToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rAmount","type":"uint256"}],"name":"tokenFromReflection","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50600062000024620000c860201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350620000d0565b600033905090565b6144ce80620000e06000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063715018a611610071578063715018a61461019d5780638da5cb5b146101a7578063cba0e996146101c5578063f2cc0c18146101f5578063f2fde38b14610211578063f84354f11461022d576100b4565b8063053ab182146100b95780632d838119146100d557806330e0789e1461010557806342966c68146101215780634549b0391461013d5780636d3a9db81461016d575b600080fd5b6100d360048036038101906100ce9190613796565b610249565b005b6100ef60048036038101906100ea9190613796565b610543565b6040516100fc91906137d2565b60405180910390f35b61011f600480360381019061011a919061384b565b6105ad565b005b61013b60048036038101906101369190613796565b610e0f565b005b610157600480360381019061015291906138d6565b610f77565b60405161016491906137d2565b60405180910390f35b6101876004803603810190610182919061384b565b610ffc565b60405161019491906137d2565b60405180910390f35b6101a5611b83565b005b6101af611cbd565b6040516101bc9190613925565b60405180910390f35b6101df60048036038101906101da9190613940565b611ce6565b6040516101ec919061397c565b60405180910390f35b61020f600480360381019061020a9190613940565b611d3f565b005b61022b60048036038101906102269190613940565b612022565b005b61024760048036038101906102429190613940565b6121ca565b005b6000610253612550565b9050600160110160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156102e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102dc906139f4565b60405180910390fd5b60006102f083612558565b505050509050806001600e0160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546103449190613a43565b6001600e0160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508060016015015461039b9190613a43565b600160150181905550826001601601546103b59190613a77565b6001601601819055507f055d20bc6ef98c21f1a870f40f93f021d59eb79b5a4c0f0ea7b3325e825300fd83826001601501546001601601546040516103fd9493929190613aab565b60405180910390a160006001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633c5c45e06001602301546040518263ffffffff1660e01b815260040161046a91906137d2565b602060405180830381865afa158015610487573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ab9190613b05565b90508073ffffffffffffffffffffffffffffffffffffffff1663a5841194600160220160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040161050b9190613925565b600060405180830381600087803b15801561052557600080fd5b505af1158015610539573d6000803e3d6000fd5b5050505050505050565b600060016015015482111561058d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058490613b7e565b60405180910390fd5b60006105976125b0565b905080836105a59190613bcd565b915050919050565b6001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166352ebc9c0336040518263ffffffff1660e01b815260040161060b9190613925565b602060405180830381865afa158015610628573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064c9190613c13565b6106f9576001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663805b5b74306040518263ffffffff1660e01b81526004016106ae9190613925565b602060405180830381865afa1580156106cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ef9190613c13565b6106f857600080fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610768576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075f90613c8c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036107d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ce90613cf8565b60405180910390fd5b6000811161081a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081190613d64565b60405180910390fd5b6108226125d4565b15610862576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085990613dd0565b60405180910390fd5b61086b836125ee565b156108ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a290613e3c565b60405180910390fd5b6108b4826125ee565b156108f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108eb90613ea8565b60405180910390fd5b6108fd326125ee565b1561093d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093490613e3c565b60405180910390fd5b6001800160000160029054906101000a900460ff1615610c6357600160110160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff168015610a005750600160110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b15610a1557610a10838383612647565b610c5e565b600160110160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16158015610abe5750600160110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b15610ad357610ace838383612897565b610c5d565b600160110160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16158015610b7d5750600160110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b15610b9257610b8d838383612ae7565b610c5c565b600160110160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff168015610c3a5750600160110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b15610c4f57610c4a838383612ca3565b610c5b565b610c5a838383612ae7565b5b5b5b5b610e0a565b610c6e838383612f87565b60006001600f0160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610cf8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cef90613f14565b60405180910390fd5b8181610d049190613a43565b6001600f0160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816001600f0160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610d9c9190613a77565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e0091906137d2565b60405180910390a3505b505050565b60006001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633c5c45e06001602301546040518263ffffffff1660e01b8152600401610e7491906137d2565b602060405180830381865afa158015610e91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb59190613b05565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610f235750610ef4611cbd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610f62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5990613f80565b60405180910390fd5b610f73610f6d611cbd565b83612f8c565b5050565b6000600160140154831115610fc1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb890613fec565b60405180910390fd5b81610fe0576000610fd184612558565b50505050905080915050610ff6565b6000610feb84612558565b505050915050809150505b92915050565b60006001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663805b5b74306040518263ffffffff1660e01b815260040161105c9190613925565b602060405180830381865afa158015611079573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109d9190613c13565b6110a657600080fd5b6000600160170160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156111875760019050600160240160009054906101000a900460ff166111865760018060240160006101000a81548160ff02191690831515021790555043600160260160000181905550426001602501819055507f28d2f4ea6561f8d14795662cac134f07474d90267b6f4142b81a883870850a92424360405161117d92919061400c565b60405180910390a15b5b600160170160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161580156112315750600160170160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b15611240576000915050611b7c565b8080156112995750600160210160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b156112a8576000915050611b7c565b801580156113025750600160210160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b15611311576000915050611b7c565b60006001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633c5c45e06001602301546040518263ffffffff1660e01b815260040161137691906137d2565b602060405180830381865afa158015611393573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b79190613b05565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16148061141e57508073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16145b1561142e57600092505050611b7c565b60006001800160000160019054906101000a900460ff16801561144f575082155b1561164c578173ffffffffffffffffffffffffffffffffffffffff16637bb45699600160220160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016114b29190613925565b602060405180830381865afa1580156114cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f39190613c13565b1561151f576001600d0154600160030160020154866115129190614035565b61151c9190613bcd565b90505b60008114611647576115328783836105ad565b8173ffffffffffffffffffffffffffffffffffffffff1663601db7b2306001601c0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401611592929190614077565b6020604051808303816000875af11580156115b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d59190613c13565b507fcedc103b11fb4f64c484647faca45cbca78b97cea771656b906df0b7162ac51f87826001601c0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660405161163094939291906140a0565b60405180910390a180846116449190613a77565b93505b600090505b6001800160000160009054906101000a900460ff161561177257821561169a576001600d0154600160030160000160000154866116899190614035565b6116939190613bcd565b90506116c4565b6001600d0154600160030160000160010154866116b79190614035565b6116c19190613bcd565b90505b6000811461176d576116fc87600160090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836105ad565b7ff33e1d2b8dd8b85ee6868d94eedafae526f785b7ba8d4fbba090f35cb96339b58782600160090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660405161175694939291906140a0565b60405180910390a1808461176a9190613a77565b93505b600090505b6001800160000160039054906101000a900460ff168015611791575082155b1561198e578173ffffffffffffffffffffffffffffffffffffffff16637bb45699600160220160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016117f49190613925565b602060405180830381865afa158015611811573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118359190613c13565b15611861576001600d0154600160030160040154866118549190614035565b61185e9190613bcd565b90505b60008114611989576118748783836105ad565b8173ffffffffffffffffffffffffffffffffffffffff1663fc9ad266306001601d0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b81526004016118d4929190614077565b6020604051808303816000875af11580156118f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119179190613c13565b507f4070e986347eb0eae7e22be6932aa9953657d5ab096c9d750558333789d95f0e87826001601d0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660405161197294939291906140a0565b60405180910390a180846119869190613a77565b93505b600090505b60006001600801805490501115611b785760005b6001600801805490508160ff161015611b765760008415611a0e576001600d015460016008018360ff16815481106119dd576119dc6140e5565b5b906000526020600020906004020160010160000154886119fd9190614035565b611a079190613bcd565b9050611a5b565b6001600d015460016008018360ff1681548110611a2e57611a2d6140e5565b5b90600052602060002090600402016001016001015488611a4e9190614035565b611a589190613bcd565b90505b8083611a679190613a77565b925060008314611b62578286611a7d9190613a77565b9550611ad58960016008018460ff1681548110611a9d57611a9c6140e5565b5b906000526020600020906004020160030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856105ad565b7f7963a72e3c4999b7a032deb496124d73638b46aada8ed1fc2bb9b009daa71d35898460016008018560ff1681548110611b1257611b116140e5565b5b906000526020600020906004020160030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688604051611b5594939291906140a0565b60405180910390a1600092505b508080611b6e90614121565b9150506119a2565b505b5050505b9392505050565b611b8b612550565b73ffffffffffffffffffffffffffffffffffffffff16611ba9611cbd565b73ffffffffffffffffffffffffffffffffffffffff1614611bff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf690614196565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600160110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b611d47612550565b73ffffffffffffffffffffffffffffffffffffffff16611d65611cbd565b73ffffffffffffffffffffffffffffffffffffffff1614611dbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611db290614196565b60405180910390fd5b600160110160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611e4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4290614202565b60405180910390fd5b60006001600e0160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611f2857611ee16001600e0160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610543565b6001600f0160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b60018060110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001601201819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fc710c6a47b6d612950c6ba7bb3bcc014922135bea0db8a995f7c9ab677faaef1816040516120179190613925565b60405180910390a150565b61202a612550565b73ffffffffffffffffffffffffffffffffffffffff16612048611cbd565b73ffffffffffffffffffffffffffffffffffffffff161461209e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161209590614196565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361210d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161210490614294565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6121d2612550565b73ffffffffffffffffffffffffffffffffffffffff166121f0611cbd565b73ffffffffffffffffffffffffffffffffffffffff1614612246576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223d90614196565b60405180910390fd5b600160110160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166122d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122cc90614300565b60405180910390fd5b60005b600160120180549050811015612515578173ffffffffffffffffffffffffffffffffffffffff1660016012018281548110612316576123156140e5565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603612502576001601201600180601201805490506123759190613a43565b81548110612386576123856140e5565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160120182815481106123c8576123c76140e5565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006001600f0160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600160110160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060016012018054806124c8576124c7614320565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690559055612515565b808061250d9061434f565b9150506122d8565b507f5bbc7a44cbb241c30f8cebfc3ea951fa728891fbe763493ea5e6575447b86885816040516125459190613925565b60405180910390a150565b600033905090565b600080600080600080600061256c886133d1565b91509150600061257a6125b0565b9050600080600061258c8c8686613409565b92509250925082828288889a509a509a509a509a5050505050505091939590929450565b60008060006125bd613452565b9150915080826125cd9190613bcd565b9250505090565b60006001601d0160149054906101000a900460ff16905090565b60006001601e0160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600080600080600061265886612558565b94509450945094509450856001600f0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546126b09190613a43565b6001600f0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550846001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546127449190613a43565b6001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550836001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546127d89190613a77565b6001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506128288382613723565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161288591906137d2565b60405180910390a35050505050505050565b60008060008060006128a886612558565b94509450945094509450846001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129009190613a43565b6001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816001600f0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129949190613a77565b6001600f0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550836001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612a289190613a77565b6001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612a788382613723565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612ad591906137d2565b60405180910390a35050505050505050565b6000806000806000612af886612558565b94509450945094509450846001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612b509190613a43565b6001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550836001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612be49190613a77565b6001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612c348382613723565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612c9191906137d2565b60405180910390a35050505050505050565b6000806000806000612cb486612558565b94509450945094509450856001600f0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612d0c9190613a43565b6001600f0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550846001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612da09190613a43565b6001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816001600f0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612e349190613a77565b6001600f0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550836001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612ec89190613a77565b6001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612f188382613723565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612f7591906137d2565b60405180910390a35050505050505050565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612ffb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ff2906143e3565b60405180910390fd5b600160350160019054906101000a900460ff1615613114576001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638b5823cc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613083573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a79190613b05565b73ffffffffffffffffffffffffffffffffffffffff16634a1fefbd83836040518363ffffffff1660e01b81526004016130e1929190614403565b600060405180830381600087803b1580156130fb57600080fd5b505af115801561310f573d6000803e3d6000fd5b505050505b61312082600083612f87565b6001800160000160029054906101000a900460ff16801561318e5750600160110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b1561326e57600061319e82612558565b505050509050806001600e0160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546131f29190613a43565b6001600e0160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550806001601501546132499190613a43565b600160150181905550816001601601546132639190613a77565b600160160181905550505b60006001600f0160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050818110156132f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132ef90614478565b60405180910390fd5b81816133049190613a43565b6001600f0160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816001601401600082825461335f9190613a43565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516133c491906137d2565b60405180910390a3505050565b6000806000600160030160030154846133ea9190613bcd565b9050600081856133fa9190613a43565b90508082935093505050915091565b600080600080848761341b9190614035565b90506000858761342b9190614035565b90506000818361343b9190613a43565b905082818395509550955050505093509350939050565b600080600060016015015490506000600160140154905060005b6001601201805490508110156136e157826001600e0160006001601201848154811061349b5761349a6140e5565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054118061358f5750816001600f01600060016012018481548110613527576135266140e5565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054115b156135ac576001601501546001601401549450945050505061371f565b6001600e016000600160120183815481106135ca576135c96140e5565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548361363b9190613a43565b92506001600f0160006001601201838154811061365b5761365a6140e5565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054826136cc9190613a43565b915080806136d99061434f565b91505061346c565b506001601401546001601501546136f89190613bcd565b8210156137165760016015015460016014015493509350505061371f565b81819350935050505b9091565b816001601501546137349190613a43565b6001601501819055508060016016015461374e9190613a77565b6001601601819055505050565b600080fd5b6000819050919050565b61377381613760565b811461377e57600080fd5b50565b6000813590506137908161376a565b92915050565b6000602082840312156137ac576137ab61375b565b5b60006137ba84828501613781565b91505092915050565b6137cc81613760565b82525050565b60006020820190506137e760008301846137c3565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613818826137ed565b9050919050565b6138288161380d565b811461383357600080fd5b50565b6000813590506138458161381f565b92915050565b6000806000606084860312156138645761386361375b565b5b600061387286828701613836565b935050602061388386828701613836565b925050604061389486828701613781565b9150509250925092565b60008115159050919050565b6138b38161389e565b81146138be57600080fd5b50565b6000813590506138d0816138aa565b92915050565b600080604083850312156138ed576138ec61375b565b5b60006138fb85828601613781565b925050602061390c858286016138c1565b9150509250929050565b61391f8161380d565b82525050565b600060208201905061393a6000830184613916565b92915050565b6000602082840312156139565761395561375b565b5b600061396484828501613836565b91505092915050565b6139768161389e565b82525050565b6000602082019050613991600083018461396d565b92915050565b600082825260208201905092915050565b7f4541000000000000000000000000000000000000000000000000000000000000600082015250565b60006139de600283613997565b91506139e9826139a8565b602082019050919050565b60006020820190508181036000830152613a0d816139d1565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613a4e82613760565b9150613a5983613760565b9250828203905081811115613a7157613a70613a14565b5b92915050565b6000613a8282613760565b9150613a8d83613760565b9250828201905080821115613aa557613aa4613a14565b5b92915050565b6000608082019050613ac060008301876137c3565b613acd60208301866137c3565b613ada60408301856137c3565b613ae760608301846137c3565b95945050505050565b600081519050613aff8161381f565b92915050565b600060208284031215613b1b57613b1a61375b565b5b6000613b2984828501613af0565b91505092915050565b7f414c520000000000000000000000000000000000000000000000000000000000600082015250565b6000613b68600383613997565b9150613b7382613b32565b602082019050919050565b60006020820190508181036000830152613b9781613b5b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613bd882613760565b9150613be383613760565b925082613bf357613bf2613b9e565b5b828204905092915050565b600081519050613c0d816138aa565b92915050565b600060208284031215613c2957613c2861375b565b5b6000613c3784828501613bfe565b91505092915050565b7f4554465a00000000000000000000000000000000000000000000000000000000600082015250565b6000613c76600483613997565b9150613c8182613c40565b602082019050919050565b60006020820190508181036000830152613ca581613c69565b9050919050565b7f4554545a00000000000000000000000000000000000000000000000000000000600082015250565b6000613ce2600483613997565b9150613ced82613cac565b602082019050919050565b60006020820190508181036000830152613d1181613cd5565b9050919050565b7f54475a0000000000000000000000000000000000000000000000000000000000600082015250565b6000613d4e600383613997565b9150613d5982613d18565b602082019050919050565b60006020820190508181036000830152613d7d81613d41565b9050919050565b7f5450000000000000000000000000000000000000000000000000000000000000600082015250565b6000613dba600283613997565b9150613dc582613d84565b602082019050919050565b60006020820190508181036000830152613de981613dad565b9050919050565b7f5342000000000000000000000000000000000000000000000000000000000000600082015250565b6000613e26600283613997565b9150613e3182613df0565b602082019050919050565b60006020820190508181036000830152613e5581613e19565b9050919050565b7f5242000000000000000000000000000000000000000000000000000000000000600082015250565b6000613e92600283613997565b9150613e9d82613e5c565b602082019050919050565b60006020820190508181036000830152613ec181613e85565b9050919050565b7f4554410000000000000000000000000000000000000000000000000000000000600082015250565b6000613efe600383613997565b9150613f0982613ec8565b602082019050919050565b60006020820190508181036000830152613f2d81613ef1565b9050919050565b7f5241000000000000000000000000000000000000000000000000000000000000600082015250565b6000613f6a600283613997565b9150613f7582613f34565b602082019050919050565b60006020820190508181036000830152613f9981613f5d565b9050919050565b7f414c530000000000000000000000000000000000000000000000000000000000600082015250565b6000613fd6600383613997565b9150613fe182613fa0565b602082019050919050565b6000602082019050818103600083015261400581613fc9565b9050919050565b600060408201905061402160008301856137c3565b61402e60208301846137c3565b9392505050565b600061404082613760565b915061404b83613760565b925082820261405981613760565b915082820484148315176140705761406f613a14565b5b5092915050565b600060408201905061408c6000830185613916565b6140996020830184613916565b9392505050565b60006080820190506140b56000830187613916565b6140c260208301866137c3565b6140cf6040830185613916565b6140dc606083018461396d565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff82169050919050565b600061412c82614114565b915060ff820361413f5761413e613a14565b5b600182019050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614180602083613997565b915061418b8261414a565b602082019050919050565b600060208201905081810360008301526141af81614173565b9050919050565b7f4145000000000000000000000000000000000000000000000000000000000000600082015250565b60006141ec600283613997565b91506141f7826141b6565b602082019050919050565b6000602082019050818103600083015261421b816141df565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061427e602683613997565b915061428982614222565b604082019050919050565b600060208201905081810360008301526142ad81614271565b9050919050565b7f4149000000000000000000000000000000000000000000000000000000000000600082015250565b60006142ea600283613997565b91506142f5826142b4565b602082019050919050565b60006020820190508181036000830152614319816142dd565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600061435a82613760565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361438c5761438b613a14565b5b600182019050919050565b7f45425a0000000000000000000000000000000000000000000000000000000000600082015250565b60006143cd600383613997565b91506143d882614397565b602082019050919050565b600060208201905081810360008301526143fc816143c0565b9050919050565b60006040820190506144186000830185613916565b61442560208301846137c3565b9392505050565b7f4542420000000000000000000000000000000000000000000000000000000000600082015250565b6000614462600383613997565b915061446d8261442c565b602082019050919050565b6000602082019050818103600083015261449181614455565b905091905056fea26469706673582212208cd1025029ac08018c83e687cc4837a714f7dd646612bcf2657dc9834355221b64736f6c63430008110033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100b45760003560e01c8063715018a611610071578063715018a61461019d5780638da5cb5b146101a7578063cba0e996146101c5578063f2cc0c18146101f5578063f2fde38b14610211578063f84354f11461022d576100b4565b8063053ab182146100b95780632d838119146100d557806330e0789e1461010557806342966c68146101215780634549b0391461013d5780636d3a9db81461016d575b600080fd5b6100d360048036038101906100ce9190613796565b610249565b005b6100ef60048036038101906100ea9190613796565b610543565b6040516100fc91906137d2565b60405180910390f35b61011f600480360381019061011a919061384b565b6105ad565b005b61013b60048036038101906101369190613796565b610e0f565b005b610157600480360381019061015291906138d6565b610f77565b60405161016491906137d2565b60405180910390f35b6101876004803603810190610182919061384b565b610ffc565b60405161019491906137d2565b60405180910390f35b6101a5611b83565b005b6101af611cbd565b6040516101bc9190613925565b60405180910390f35b6101df60048036038101906101da9190613940565b611ce6565b6040516101ec919061397c565b60405180910390f35b61020f600480360381019061020a9190613940565b611d3f565b005b61022b60048036038101906102269190613940565b612022565b005b61024760048036038101906102429190613940565b6121ca565b005b6000610253612550565b9050600160110160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156102e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102dc906139f4565b60405180910390fd5b60006102f083612558565b505050509050806001600e0160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546103449190613a43565b6001600e0160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508060016015015461039b9190613a43565b600160150181905550826001601601546103b59190613a77565b6001601601819055507f055d20bc6ef98c21f1a870f40f93f021d59eb79b5a4c0f0ea7b3325e825300fd83826001601501546001601601546040516103fd9493929190613aab565b60405180910390a160006001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633c5c45e06001602301546040518263ffffffff1660e01b815260040161046a91906137d2565b602060405180830381865afa158015610487573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ab9190613b05565b90508073ffffffffffffffffffffffffffffffffffffffff1663a5841194600160220160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040161050b9190613925565b600060405180830381600087803b15801561052557600080fd5b505af1158015610539573d6000803e3d6000fd5b5050505050505050565b600060016015015482111561058d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058490613b7e565b60405180910390fd5b60006105976125b0565b905080836105a59190613bcd565b915050919050565b6001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166352ebc9c0336040518263ffffffff1660e01b815260040161060b9190613925565b602060405180830381865afa158015610628573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064c9190613c13565b6106f9576001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663805b5b74306040518263ffffffff1660e01b81526004016106ae9190613925565b602060405180830381865afa1580156106cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ef9190613c13565b6106f857600080fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610768576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075f90613c8c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036107d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ce90613cf8565b60405180910390fd5b6000811161081a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081190613d64565b60405180910390fd5b6108226125d4565b15610862576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085990613dd0565b60405180910390fd5b61086b836125ee565b156108ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a290613e3c565b60405180910390fd5b6108b4826125ee565b156108f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108eb90613ea8565b60405180910390fd5b6108fd326125ee565b1561093d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093490613e3c565b60405180910390fd5b6001800160000160029054906101000a900460ff1615610c6357600160110160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff168015610a005750600160110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b15610a1557610a10838383612647565b610c5e565b600160110160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16158015610abe5750600160110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b15610ad357610ace838383612897565b610c5d565b600160110160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16158015610b7d5750600160110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b15610b9257610b8d838383612ae7565b610c5c565b600160110160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff168015610c3a5750600160110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b15610c4f57610c4a838383612ca3565b610c5b565b610c5a838383612ae7565b5b5b5b5b610e0a565b610c6e838383612f87565b60006001600f0160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610cf8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cef90613f14565b60405180910390fd5b8181610d049190613a43565b6001600f0160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816001600f0160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610d9c9190613a77565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e0091906137d2565b60405180910390a3505b505050565b60006001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633c5c45e06001602301546040518263ffffffff1660e01b8152600401610e7491906137d2565b602060405180830381865afa158015610e91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb59190613b05565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610f235750610ef4611cbd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610f62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5990613f80565b60405180910390fd5b610f73610f6d611cbd565b83612f8c565b5050565b6000600160140154831115610fc1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb890613fec565b60405180910390fd5b81610fe0576000610fd184612558565b50505050905080915050610ff6565b6000610feb84612558565b505050915050809150505b92915050565b60006001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663805b5b74306040518263ffffffff1660e01b815260040161105c9190613925565b602060405180830381865afa158015611079573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109d9190613c13565b6110a657600080fd5b6000600160170160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156111875760019050600160240160009054906101000a900460ff166111865760018060240160006101000a81548160ff02191690831515021790555043600160260160000181905550426001602501819055507f28d2f4ea6561f8d14795662cac134f07474d90267b6f4142b81a883870850a92424360405161117d92919061400c565b60405180910390a15b5b600160170160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161580156112315750600160170160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b15611240576000915050611b7c565b8080156112995750600160210160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b156112a8576000915050611b7c565b801580156113025750600160210160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b15611311576000915050611b7c565b60006001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633c5c45e06001602301546040518263ffffffff1660e01b815260040161137691906137d2565b602060405180830381865afa158015611393573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b79190613b05565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16148061141e57508073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16145b1561142e57600092505050611b7c565b60006001800160000160019054906101000a900460ff16801561144f575082155b1561164c578173ffffffffffffffffffffffffffffffffffffffff16637bb45699600160220160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016114b29190613925565b602060405180830381865afa1580156114cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f39190613c13565b1561151f576001600d0154600160030160020154866115129190614035565b61151c9190613bcd565b90505b60008114611647576115328783836105ad565b8173ffffffffffffffffffffffffffffffffffffffff1663601db7b2306001601c0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401611592929190614077565b6020604051808303816000875af11580156115b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d59190613c13565b507fcedc103b11fb4f64c484647faca45cbca78b97cea771656b906df0b7162ac51f87826001601c0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660405161163094939291906140a0565b60405180910390a180846116449190613a77565b93505b600090505b6001800160000160009054906101000a900460ff161561177257821561169a576001600d0154600160030160000160000154866116899190614035565b6116939190613bcd565b90506116c4565b6001600d0154600160030160000160010154866116b79190614035565b6116c19190613bcd565b90505b6000811461176d576116fc87600160090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836105ad565b7ff33e1d2b8dd8b85ee6868d94eedafae526f785b7ba8d4fbba090f35cb96339b58782600160090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660405161175694939291906140a0565b60405180910390a1808461176a9190613a77565b93505b600090505b6001800160000160039054906101000a900460ff168015611791575082155b1561198e578173ffffffffffffffffffffffffffffffffffffffff16637bb45699600160220160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016117f49190613925565b602060405180830381865afa158015611811573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118359190613c13565b15611861576001600d0154600160030160040154866118549190614035565b61185e9190613bcd565b90505b60008114611989576118748783836105ad565b8173ffffffffffffffffffffffffffffffffffffffff1663fc9ad266306001601d0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b81526004016118d4929190614077565b6020604051808303816000875af11580156118f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119179190613c13565b507f4070e986347eb0eae7e22be6932aa9953657d5ab096c9d750558333789d95f0e87826001601d0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660405161197294939291906140a0565b60405180910390a180846119869190613a77565b93505b600090505b60006001600801805490501115611b785760005b6001600801805490508160ff161015611b765760008415611a0e576001600d015460016008018360ff16815481106119dd576119dc6140e5565b5b906000526020600020906004020160010160000154886119fd9190614035565b611a079190613bcd565b9050611a5b565b6001600d015460016008018360ff1681548110611a2e57611a2d6140e5565b5b90600052602060002090600402016001016001015488611a4e9190614035565b611a589190613bcd565b90505b8083611a679190613a77565b925060008314611b62578286611a7d9190613a77565b9550611ad58960016008018460ff1681548110611a9d57611a9c6140e5565b5b906000526020600020906004020160030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856105ad565b7f7963a72e3c4999b7a032deb496124d73638b46aada8ed1fc2bb9b009daa71d35898460016008018560ff1681548110611b1257611b116140e5565b5b906000526020600020906004020160030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688604051611b5594939291906140a0565b60405180910390a1600092505b508080611b6e90614121565b9150506119a2565b505b5050505b9392505050565b611b8b612550565b73ffffffffffffffffffffffffffffffffffffffff16611ba9611cbd565b73ffffffffffffffffffffffffffffffffffffffff1614611bff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf690614196565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600160110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b611d47612550565b73ffffffffffffffffffffffffffffffffffffffff16611d65611cbd565b73ffffffffffffffffffffffffffffffffffffffff1614611dbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611db290614196565b60405180910390fd5b600160110160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611e4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4290614202565b60405180910390fd5b60006001600e0160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611f2857611ee16001600e0160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610543565b6001600f0160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b60018060110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001601201819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fc710c6a47b6d612950c6ba7bb3bcc014922135bea0db8a995f7c9ab677faaef1816040516120179190613925565b60405180910390a150565b61202a612550565b73ffffffffffffffffffffffffffffffffffffffff16612048611cbd565b73ffffffffffffffffffffffffffffffffffffffff161461209e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161209590614196565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361210d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161210490614294565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6121d2612550565b73ffffffffffffffffffffffffffffffffffffffff166121f0611cbd565b73ffffffffffffffffffffffffffffffffffffffff1614612246576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223d90614196565b60405180910390fd5b600160110160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166122d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122cc90614300565b60405180910390fd5b60005b600160120180549050811015612515578173ffffffffffffffffffffffffffffffffffffffff1660016012018281548110612316576123156140e5565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603612502576001601201600180601201805490506123759190613a43565b81548110612386576123856140e5565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160120182815481106123c8576123c76140e5565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006001600f0160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600160110160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060016012018054806124c8576124c7614320565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690559055612515565b808061250d9061434f565b9150506122d8565b507f5bbc7a44cbb241c30f8cebfc3ea951fa728891fbe763493ea5e6575447b86885816040516125459190613925565b60405180910390a150565b600033905090565b600080600080600080600061256c886133d1565b91509150600061257a6125b0565b9050600080600061258c8c8686613409565b92509250925082828288889a509a509a509a509a5050505050505091939590929450565b60008060006125bd613452565b9150915080826125cd9190613bcd565b9250505090565b60006001601d0160149054906101000a900460ff16905090565b60006001601e0160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600080600080600061265886612558565b94509450945094509450856001600f0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546126b09190613a43565b6001600f0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550846001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546127449190613a43565b6001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550836001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546127d89190613a77565b6001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506128288382613723565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161288591906137d2565b60405180910390a35050505050505050565b60008060008060006128a886612558565b94509450945094509450846001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129009190613a43565b6001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816001600f0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129949190613a77565b6001600f0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550836001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612a289190613a77565b6001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612a788382613723565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612ad591906137d2565b60405180910390a35050505050505050565b6000806000806000612af886612558565b94509450945094509450846001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612b509190613a43565b6001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550836001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612be49190613a77565b6001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612c348382613723565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612c9191906137d2565b60405180910390a35050505050505050565b6000806000806000612cb486612558565b94509450945094509450856001600f0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612d0c9190613a43565b6001600f0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550846001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612da09190613a43565b6001600e0160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816001600f0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612e349190613a77565b6001600f0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550836001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612ec89190613a77565b6001600e0160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612f188382613723565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612f7591906137d2565b60405180910390a35050505050505050565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612ffb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ff2906143e3565b60405180910390fd5b600160350160019054906101000a900460ff1615613114576001601b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638b5823cc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613083573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a79190613b05565b73ffffffffffffffffffffffffffffffffffffffff16634a1fefbd83836040518363ffffffff1660e01b81526004016130e1929190614403565b600060405180830381600087803b1580156130fb57600080fd5b505af115801561310f573d6000803e3d6000fd5b505050505b61312082600083612f87565b6001800160000160029054906101000a900460ff16801561318e5750600160110160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b1561326e57600061319e82612558565b505050509050806001600e0160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546131f29190613a43565b6001600e0160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550806001601501546132499190613a43565b600160150181905550816001601601546132639190613a77565b600160160181905550505b60006001600f0160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050818110156132f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132ef90614478565b60405180910390fd5b81816133049190613a43565b6001600f0160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816001601401600082825461335f9190613a43565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516133c491906137d2565b60405180910390a3505050565b6000806000600160030160030154846133ea9190613bcd565b9050600081856133fa9190613a43565b90508082935093505050915091565b600080600080848761341b9190614035565b90506000858761342b9190614035565b90506000818361343b9190613a43565b905082818395509550955050505093509350939050565b600080600060016015015490506000600160140154905060005b6001601201805490508110156136e157826001600e0160006001601201848154811061349b5761349a6140e5565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054118061358f5750816001600f01600060016012018481548110613527576135266140e5565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054115b156135ac576001601501546001601401549450945050505061371f565b6001600e016000600160120183815481106135ca576135c96140e5565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548361363b9190613a43565b92506001600f0160006001601201838154811061365b5761365a6140e5565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054826136cc9190613a43565b915080806136d99061434f565b91505061346c565b506001601401546001601501546136f89190613bcd565b8210156137165760016015015460016014015493509350505061371f565b81819350935050505b9091565b816001601501546137349190613a43565b6001601501819055508060016016015461374e9190613a77565b6001601601819055505050565b600080fd5b6000819050919050565b61377381613760565b811461377e57600080fd5b50565b6000813590506137908161376a565b92915050565b6000602082840312156137ac576137ab61375b565b5b60006137ba84828501613781565b91505092915050565b6137cc81613760565b82525050565b60006020820190506137e760008301846137c3565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613818826137ed565b9050919050565b6138288161380d565b811461383357600080fd5b50565b6000813590506138458161381f565b92915050565b6000806000606084860312156138645761386361375b565b5b600061387286828701613836565b935050602061388386828701613836565b925050604061389486828701613781565b9150509250925092565b60008115159050919050565b6138b38161389e565b81146138be57600080fd5b50565b6000813590506138d0816138aa565b92915050565b600080604083850312156138ed576138ec61375b565b5b60006138fb85828601613781565b925050602061390c858286016138c1565b9150509250929050565b61391f8161380d565b82525050565b600060208201905061393a6000830184613916565b92915050565b6000602082840312156139565761395561375b565b5b600061396484828501613836565b91505092915050565b6139768161389e565b82525050565b6000602082019050613991600083018461396d565b92915050565b600082825260208201905092915050565b7f4541000000000000000000000000000000000000000000000000000000000000600082015250565b60006139de600283613997565b91506139e9826139a8565b602082019050919050565b60006020820190508181036000830152613a0d816139d1565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613a4e82613760565b9150613a5983613760565b9250828203905081811115613a7157613a70613a14565b5b92915050565b6000613a8282613760565b9150613a8d83613760565b9250828201905080821115613aa557613aa4613a14565b5b92915050565b6000608082019050613ac060008301876137c3565b613acd60208301866137c3565b613ada60408301856137c3565b613ae760608301846137c3565b95945050505050565b600081519050613aff8161381f565b92915050565b600060208284031215613b1b57613b1a61375b565b5b6000613b2984828501613af0565b91505092915050565b7f414c520000000000000000000000000000000000000000000000000000000000600082015250565b6000613b68600383613997565b9150613b7382613b32565b602082019050919050565b60006020820190508181036000830152613b9781613b5b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613bd882613760565b9150613be383613760565b925082613bf357613bf2613b9e565b5b828204905092915050565b600081519050613c0d816138aa565b92915050565b600060208284031215613c2957613c2861375b565b5b6000613c3784828501613bfe565b91505092915050565b7f4554465a00000000000000000000000000000000000000000000000000000000600082015250565b6000613c76600483613997565b9150613c8182613c40565b602082019050919050565b60006020820190508181036000830152613ca581613c69565b9050919050565b7f4554545a00000000000000000000000000000000000000000000000000000000600082015250565b6000613ce2600483613997565b9150613ced82613cac565b602082019050919050565b60006020820190508181036000830152613d1181613cd5565b9050919050565b7f54475a0000000000000000000000000000000000000000000000000000000000600082015250565b6000613d4e600383613997565b9150613d5982613d18565b602082019050919050565b60006020820190508181036000830152613d7d81613d41565b9050919050565b7f5450000000000000000000000000000000000000000000000000000000000000600082015250565b6000613dba600283613997565b9150613dc582613d84565b602082019050919050565b60006020820190508181036000830152613de981613dad565b9050919050565b7f5342000000000000000000000000000000000000000000000000000000000000600082015250565b6000613e26600283613997565b9150613e3182613df0565b602082019050919050565b60006020820190508181036000830152613e5581613e19565b9050919050565b7f5242000000000000000000000000000000000000000000000000000000000000600082015250565b6000613e92600283613997565b9150613e9d82613e5c565b602082019050919050565b60006020820190508181036000830152613ec181613e85565b9050919050565b7f4554410000000000000000000000000000000000000000000000000000000000600082015250565b6000613efe600383613997565b9150613f0982613ec8565b602082019050919050565b60006020820190508181036000830152613f2d81613ef1565b9050919050565b7f5241000000000000000000000000000000000000000000000000000000000000600082015250565b6000613f6a600283613997565b9150613f7582613f34565b602082019050919050565b60006020820190508181036000830152613f9981613f5d565b9050919050565b7f414c530000000000000000000000000000000000000000000000000000000000600082015250565b6000613fd6600383613997565b9150613fe182613fa0565b602082019050919050565b6000602082019050818103600083015261400581613fc9565b9050919050565b600060408201905061402160008301856137c3565b61402e60208301846137c3565b9392505050565b600061404082613760565b915061404b83613760565b925082820261405981613760565b915082820484148315176140705761406f613a14565b5b5092915050565b600060408201905061408c6000830185613916565b6140996020830184613916565b9392505050565b60006080820190506140b56000830187613916565b6140c260208301866137c3565b6140cf6040830185613916565b6140dc606083018461396d565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff82169050919050565b600061412c82614114565b915060ff820361413f5761413e613a14565b5b600182019050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614180602083613997565b915061418b8261414a565b602082019050919050565b600060208201905081810360008301526141af81614173565b9050919050565b7f4145000000000000000000000000000000000000000000000000000000000000600082015250565b60006141ec600283613997565b91506141f7826141b6565b602082019050919050565b6000602082019050818103600083015261421b816141df565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061427e602683613997565b915061428982614222565b604082019050919050565b600060208201905081810360008301526142ad81614271565b9050919050565b7f4149000000000000000000000000000000000000000000000000000000000000600082015250565b60006142ea600283613997565b91506142f5826142b4565b602082019050919050565b60006020820190508181036000830152614319816142dd565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600061435a82613760565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361438c5761438b613a14565b5b600182019050919050565b7f45425a0000000000000000000000000000000000000000000000000000000000600082015250565b60006143cd600383613997565b91506143d882614397565b602082019050919050565b600060208201905081810360008301526143fc816143c0565b9050919050565b60006040820190506144186000830185613916565b61442560208301846137c3565b9392505050565b7f4542420000000000000000000000000000000000000000000000000000000000600082015250565b6000614462600383613997565b915061446d8261442c565b602082019050919050565b6000602082019050818103600083015261449181614455565b905091905056fea26469706673582212208cd1025029ac08018c83e687cc4837a714f7dd646612bcf2657dc9834355221b64736f6c63430008110033
Deployed Bytecode Sourcemap
77364:14576:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84522:552;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85498:213;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82602:1777;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;90746:244;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85082:408;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78775:3531;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8314:148;;;:::i;:::-;;7663:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86601:113;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85719:357;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;8617:244;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;86084:509;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;84522:552;84574:14;84591:12;:10;:12::i;:::-;84574:29;;84623:1;:13;;:21;84637:6;84623:21;;;;;;;;;;;;;;;;;;;;;;;;;84622:22;84614:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;84663:15;84686:19;84697:7;84686:10;:19::i;:::-;84662:43;;;;;;84756:7;84736:1;:9;;:17;84746:6;84736:17;;;;;;;;;;;;;;;;:27;;;;:::i;:::-;84716:1;:9;;:17;84726:6;84716:17;;;;;;;;;;;;;;;:47;;;;84798:7;84786:1;:9;;;:19;;;;:::i;:::-;84774:1;:9;;:31;;;;84846:7;84831:1;:12;;;:22;;;;:::i;:::-;84816:1;:12;;:37;;;;84869:50;84877:7;84886;84895:1;:9;;;84906:1;:12;;;84869:50;;;;;;;;;:::i;:::-;;;;;;;;84930:20;84977:1;:9;;;;;;;;;;;;84964:43;;;85008:1;:16;;;84964:61;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;84930:96;;85037:9;:14;;;85052:1;:13;;;;;;;;;;;;85037:29;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84563:511;;;84522:552;:::o;85498:213::-;85564:7;85604:1;:9;;;85593:7;:20;;85585:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;85632:19;85654:10;:8;:10::i;:::-;85632:32;;85692:11;85682:7;:21;;;;:::i;:::-;85675:28;;;85498:213;;;:::o;82602:1777::-;82773:1;:9;;;;;;;;;;;;82760:47;;;82808:10;82760:59;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;82756:157;;82857:1;:9;;;;;;;;;;;;82844:41;;;82894:4;82844:56;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;82836:65;;;;;;82756:157;82949:1;82931:20;;:6;:20;;;82923:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;83000:1;82979:23;;:9;:23;;;82971:40;;;;;;;;;;;;:::i;:::-;;;;;;;;;83039:1;83030:6;:10;83022:26;;;;;;;;;;;;:::i;:::-;;;;;;;;;83068:8;:6;:8::i;:::-;83067:9;83059:24;;;;;;;;;;;;:::i;:::-;;;;;;;;;83103:21;83117:6;83103:13;:21::i;:::-;83102:22;83094:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;83151:24;83165:9;83151:13;:24::i;:::-;83150:25;83142:40;;;;;;;;;;;;:::i;:::-;;;;;;;;;83203:24;83217:9;83203:13;:24::i;:::-;83202:25;83194:40;;;;;;;;;;;;:::i;:::-;;;;;;;;;83281:1;:13;;:23;;;;;;;;;;;;83278:1094;;;83325:1;:13;;:21;83339:6;83325:21;;;;;;;;;;;;;;;;;;;;;;;;;:50;;;;;83351:1;:13;;:24;83365:9;83351:24;;;;;;;;;;;;;;;;;;;;;;;;;83350:25;83325:50;83321:649;;;83392:48;83414:6;83422:9;83433:6;83392:21;:48::i;:::-;83321:649;;;83467:1;:13;;:21;83481:6;83467:21;;;;;;;;;;;;;;;;;;;;;;;;;83466:22;:50;;;;;83492:1;:13;;:24;83506:9;83492:24;;;;;;;;;;;;;;;;;;;;;;;;;83466:50;83462:508;;;83537:46;83557:6;83565:9;83576:6;83537:19;:46::i;:::-;83462:508;;;83610:1;:13;;:21;83624:6;83610:21;;;;;;;;;;;;;;;;;;;;;;;;;83609:22;:51;;;;;83636:1;:13;;:24;83650:9;83636:24;;;;;;;;;;;;;;;;;;;;;;;;;83635:25;83609:51;83605:365;;;83681:44;83699:6;83707:9;83718:6;83681:17;:44::i;:::-;83605:365;;;83751:1;:13;;:21;83765:6;83751:21;;;;;;;;;;;;;;;;;;;;;;;;;:49;;;;;83776:1;:13;;:24;83790:9;83776:24;;;;;;;;;;;;;;;;;;;;;;;;;83751:49;83747:223;;;83821:48;83843:6;83851:9;83862:6;83821:21;:48::i;:::-;83747:223;;;83910:44;83928:6;83936:9;83947:6;83910:17;:44::i;:::-;83747:223;83605:365;83462:508;83321:649;83278:1094;;;84042:47;84063:6;84071:9;84082:6;84042:20;:47::i;:::-;84106:21;84130:1;:9;;:17;84140:6;84130:17;;;;;;;;;;;;;;;;84106:41;;84187:6;84170:13;:23;;84162:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;84252:6;84236:13;:22;;;;:::i;:::-;84216:1;:9;;:17;84226:6;84216:17;;;;;;;;;;;;;;;:42;;;;84297:6;84273:1;:9;;:20;84283:9;84273:20;;;;;;;;;;;;;;;;:30;;;;;;;:::i;:::-;;;;;;;;84342:9;84325:35;;84334:6;84325:35;;;84353:6;84325:35;;;;;;:::i;:::-;;;;;;;;83987:385;83278:1094;82602:1777;;;:::o;90746:244::-;90794:17;90827:1;:9;;;;;;;;;;;;90814:43;;;90858:1;:16;;;90814:61;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90794:81;;90908:9;90894:23;;:10;:23;;;:48;;;;90935:7;:5;:7::i;:::-;90921:21;;:10;:21;;;90894:48;90886:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;90960:22;90966:7;:5;:7::i;:::-;90975:6;90960:5;:22::i;:::-;90783:207;90746:244;:::o;85082:408::-;85172:7;85211:1;:9;;;85200:7;:20;;85192:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;85244:17;85239:244;;85279:15;85302:19;85313:7;85302:10;:19::i;:::-;85278:43;;;;;;85343:7;85336:14;;;;;85239:244;85385:23;85415:19;85426:7;85415:10;:19::i;:::-;85383:51;;;;;;85456:15;85449:22;;;85082:408;;;;;:::o;78775:3531::-;78871:22;78993:1;:9;;;;;;;;;;;;78980:41;;;79030:4;78980:56;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;78972:65;;;;;;79048:10;79082:1;:10;;:18;79093:6;79082:18;;;;;;;;;;;;;;;;;;;;;;;;;79079:333;;;79125:4;79117:12;;79148:1;:12;;;;;;;;;;;;79144:257;;79196:4;79181:1;:12;;;:19;;;;;;;;;;;;;;;;;;79250:12;79219:1;:17;;:28;;:43;;;;79305:15;79281:1;:21;;:39;;;;79344:41;79355:15;79372:12;79344:41;;;;;;;:::i;:::-;;;;;;;;79144:257;79079:333;79428:1;:10;;:18;79439:6;79428:18;;;;;;;;;;;;;;;;;;;;;;;;;79427:19;:45;;;;;79451:1;:10;;:21;79462:9;79451:21;;;;;;;;;;;;;;;;;;;;;;;;;79450:22;79427:45;79424:85;;;79496:1;79489:8;;;;;79424:85;79524:5;:34;;;;;79533:1;:14;;:25;79548:9;79533:25;;;;;;;;;;;;;;;;;;;;;;;;;79524:34;79521:74;;;79582:1;79575:8;;;;;79521:74;79611:5;79610:6;:32;;;;;79620:1;:14;;:22;79635:6;79620:22;;;;;;;;;;;;;;;;;;;;;;;;;79610:32;79607:72;;;79666:1;79659:8;;;;;79607:72;79691:20;79738:1;:9;;;;;;;;;;;;79725:43;;;79769:1;:16;;;79725:61;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79691:96;;79819:9;79801:28;;:6;:28;;;:63;;;;79854:9;79833:31;;:9;:31;;;79801:63;79798:103;;;79888:1;79881:8;;;;;;79798:103;79936:11;79961:1;:13;;:24;;;;;;;;;;;;:34;;;;;79990:5;79989:6;79961:34;79958:555;;;80015:9;:28;;;80044:1;:13;;;;;;;;;;;;80015:43;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;80012:131;;;80114:1;:13;;;80094:1;:6;;:17;;;80085:6;:26;;;;:::i;:::-;:42;;;;:::i;:::-;80079:48;;80012:131;80181:1;80174:3;:8;80171:309;;80203:42;80213:6;80229:9;80241:3;80203:9;:42::i;:::-;80266:9;:28;;;80303:4;80318:1;:15;;;;;;;;;;;;80266:69;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;80359:65;80379:6;80387:3;80400:1;:15;;;;;;;;;;;;80418:5;80359:65;;;;;;;;;:::i;:::-;;;;;;;;80461:3;80443:21;;;;;:::i;:::-;;;80171:309;80500:1;80494:7;;79958:555;80526:1;:13;;:28;;;;;;;;;;;;80523:519;;;80574:5;80571:199;;;80643:1;:13;;;80615:1;:6;;:21;;:25;;;80606:6;:34;;;;:::i;:::-;:50;;;;:::i;:::-;80600:56;;80571:199;;;80741:1;:13;;;80712:1;:6;;:21;;:26;;;80703:6;:35;;;;:::i;:::-;:51;;;;:::i;:::-;80697:57;;80571:199;80794:1;80787:3;:8;80784:225;;80816:46;80826:6;80834:1;:22;;;;;;;;;;;;80858:3;80816:9;:46::i;:::-;80886:67;80910:6;80918:3;80923:1;:22;;;;;;;;;;;;80947:5;80886:67;;;;;;;;;:::i;:::-;;;;;;;;80990:3;80972:21;;;;;:::i;:::-;;;80784:225;81029:1;81023:7;;80523:519;81055:1;:13;;:19;;;;;;;;;;;;:29;;;;;81079:5;81078:6;81055:29;81052:514;;;81104:9;:28;;;81133:1;:13;;;;;;;;;;;;81104:43;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81101:126;;;81198:1;:13;;;81183:1;:6;;:12;;;81174:6;:21;;;;:::i;:::-;:37;;;;:::i;:::-;81168:43;;81101:126;81251:1;81244:3;:8;81241:292;;81273:42;81283:6;81299:9;81311:3;81273:9;:42::i;:::-;81334:9;:28;;;81371:4;81386:1;:10;;;;;;;;;;;;81334:64;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;81422:55;81437:6;81445:3;81458:1;:10;;;;;;;;;;;;81471:5;81422:55;;;;;;;;;:::i;:::-;;;;;;;;81514:3;81496:21;;;;;:::i;:::-;;;81241:292;81553:1;81547:7;;81052:514;81602:1;81579;:13;;:20;;;;:24;81576:719;;;81624:7;81620:664;81641:1;:13;;:20;;;;81637:1;:24;;;81620:664;;;81687:17;81726:5;81723:225;;;81804:1;:13;;;81777:1;:13;;81791:1;81777:16;;;;;;;;;;:::i;:::-;;;;;;;;;;;;:20;;:24;;;81768:6;:33;;;;:::i;:::-;:49;;;;:::i;:::-;81756:61;;81723:225;;;81915:1;:13;;;81887:1;:13;;81901:1;81887:16;;;;;;;;;;:::i;:::-;;;;;;;;;;;;:20;;:25;;;81878:6;:34;;;;:::i;:::-;:50;;;;:::i;:::-;81866:62;;81723:225;81973:9;81966:16;;;;;:::i;:::-;;;82011:1;82004:3;:8;82001:268;;82055:3;82037:21;;;;;:::i;:::-;;;82081:47;82091:6;82099:1;:13;;82113:1;82099:16;;;;;;;;;;:::i;:::-;;;;;;;;;;;;:23;;;;;;;;;;;;82124:3;82081:9;:47::i;:::-;82156:63;82175:6;82183:3;82188:1;:13;;82202:1;82188:16;;;;;;;;;;:::i;:::-;;;;;;;;;;;;:23;;;;;;;;;;;;82213:5;82156:63;;;;;;;;;:::i;:::-;;;;;;;;82248:1;82242:7;;82001:268;81668:616;81663:3;;;;;:::i;:::-;;;;81620:664;;;;81576:719;78895:3411;;;78775:3531;;;;;;:::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;86601:113::-;86660:4;86684:1;:13;;:22;86698:7;86684:22;;;;;;;;;;;;;;;;;;;;;;;;;86677:29;;86601:113;;;:::o;85719:357::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;85799:1:::1;:13;;:22;85813:7;85799:22;;;;;;;;;;;;;;;;;;;;;;;;;85798:23;85790:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;85863:1;85842;:9;;:18;85852:7;85842:18;;;;;;;;;;;;;;;;:22;85839:114;;;85902:39;85922:1;:9;;:18;85932:7;85922:18;;;;;;;;;;;;;;;;85902:19;:39::i;:::-;85881:1;:9;;:18;85891:7;85881:18;;;;;;;;;;;;;;;:60;;;;85839:114;85988:4;85963:1:::0;:13:::1;;:22;85977:7;85963:22;;;;;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;86003:1;:11;;86020:7;86003:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86044:24;86060:7;86044:24;;;;;;:::i;:::-;;;;;;;;85719:357:::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;86084:509::-;7894:12;:10;:12::i;:::-;7883:23;;:7;:5;:7::i;:::-;:23;;;7875:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;86163:1:::1;:13;;:22;86177:7;86163:22;;;;;;;;;;;;;;;;;;;;;;;;;86155:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;86208:9;86203:343;86227:1;:11;;:18;;;;86223:1;:22;86203:343;;;86289:7;86271:25;;:1;:11;;86283:1;86271:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;:25;;::::0;86267:268:::1;;86334:1;:11;;86367:1;86346::::0;:11:::1;;:18;;;;:22;;;;:::i;:::-;86334:35;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;86317:1;:11;;86329:1;86317:14;;;;;;;;:::i;:::-;;;;;;;;;;:52;;;;;;;;;;;;;;;;;;86409:1;86388;:9;;:18;86398:7;86388:18;;;;;;;;;;;;;;;:22;;;;86454:5;86429:1;:13;;:22;86443:7;86429:22;;;;;;;;;;;;;;;;:30;;;;;;;;;;;;;;;;;;86478:1;:11;;:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;86514:5;;86267:268;86247:3;;;;;:::i;:::-;;;;86203:343;;;;86561:24;86577:7;86561:24;;;;;;:::i;:::-;;;;;;;;86084:509:::0;:::o;6192:98::-;6245:7;6272:10;6265:17;;6192:98;:::o;88995:410::-;89054:7;89063;89072;89081;89090;89111:23;89136:12;89152:20;89164:7;89152:11;:20::i;:::-;89110:62;;;;89183:19;89205:10;:8;:10::i;:::-;89183:32;;89227:15;89244:23;89269:12;89285:39;89297:7;89306:4;89312:11;89285;:39::i;:::-;89226:98;;;;;;89343:7;89352:15;89369:4;89375:15;89392:4;89335:62;;;;;;;;;;;;;;;;88995:410;;;;;;;:::o;89984:160::-;90025:7;90046:15;90063;90082:19;:17;:19::i;:::-;90045:56;;;;90129:7;90119;:17;;;;:::i;:::-;90112:24;;;;89984:160;:::o;78120:83::-;78161:4;78185:1;:10;;;;;;;;;;;;78178:17;;78120:83;:::o;78211:117::-;78275:4;78299:1;:11;;:21;78311:8;78299:21;;;;;;;;;;;;;;;;;;;;;;;;;78292:28;;78211:117;;;:::o;87721:512::-;87824:15;87841:23;87866:12;87880:23;87905:12;87921:19;87932:7;87921:10;:19::i;:::-;87823:117;;;;;;;;;;87991:7;87971:1;:9;;:17;87981:6;87971:17;;;;;;;;;;;;;;;;:27;;;;:::i;:::-;87951:1;:9;;:17;87961:6;87951:17;;;;;;;;;;;;;;;:47;;;;88049:7;88029:1;:9;;:17;88039:6;88029:17;;;;;;;;;;;;;;;;:27;;;;:::i;:::-;88009:1;:9;;:17;88019:6;88009:17;;;;;;;;;;;;;;;:47;;;;88113:15;88090:1;:9;;:20;88100:9;88090:20;;;;;;;;;;;;;;;;:38;;;;:::i;:::-;88067:1;:9;;:20;88077:9;88067:20;;;;;;;;;;;;;;;:61;;;;88142:23;88154:4;88160;88142:11;:23::i;:::-;88198:9;88181:44;;88190:6;88181:44;;;88209:15;88181:44;;;;;;:::i;:::-;;;;;;;;87812:421;;;;;87721:512;;;:::o;87181:532::-;87282:15;87299:23;87324:12;87338:23;87363:12;87379:19;87390:7;87379:10;:19::i;:::-;87281:117;;;;;;;;;;87449:7;87429:1;:9;;:17;87439:6;87429:17;;;;;;;;;;;;;;;;:27;;;;:::i;:::-;87409:1;:9;;:17;87419:6;87409:17;;;;;;;;;;;;;;;:47;;;;87513:15;87490:1;:9;;:20;87500:9;87490:20;;;;;;;;;;;;;;;;:38;;;;:::i;:::-;87467:1;:9;;:20;87477:9;87467:20;;;;;;;;;;;;;;;:61;;;;87585:15;87562:1;:9;;:20;87572:9;87562:20;;;;;;;;;;;;;;;;:38;;;;:::i;:::-;87539:1;:9;;:20;87549:9;87539:20;;;;;;;;;;;;;;;:61;;;;87622:23;87634:4;87640;87622:11;:23::i;:::-;87678:9;87661:44;;87670:6;87661:44;;;87689:15;87661:44;;;;;;:::i;:::-;;;;;;;;87270:443;;;;;87181:532;;;:::o;86722:451::-;86821:15;86838:23;86863:12;86877:23;86902:12;86918:19;86929:7;86918:10;:19::i;:::-;86820:117;;;;;;;;;;86988:7;86968:1;:9;;:17;86978:6;86968:17;;;;;;;;;;;;;;;;:27;;;;:::i;:::-;86948:1;:9;;:17;86958:6;86948:17;;;;;;;;;;;;;;;:47;;;;87052:15;87029:1;:9;;:20;87039:9;87029:20;;;;;;;;;;;;;;;;:38;;;;:::i;:::-;87006:1;:9;;:20;87016:9;87006:20;;;;;;;;;;;;;;;:61;;;;87082:23;87094:4;87100;87082:11;:23::i;:::-;87138:9;87121:44;;87130:6;87121:44;;;87149:15;87121:44;;;;;;:::i;:::-;;;;;;;;86809:364;;;;;86722:451;;;:::o;88241:589::-;88344:15;88361:23;88386:12;88400:23;88425:12;88441:19;88452:7;88441:10;:19::i;:::-;88343:117;;;;;;;;;;88511:7;88491:1;:9;;:17;88501:6;88491:17;;;;;;;;;;;;;;;;:27;;;;:::i;:::-;88471:1;:9;;:17;88481:6;88471:17;;;;;;;;;;;;;;;:47;;;;88569:7;88549:1;:9;;:17;88559:6;88549:17;;;;;;;;;;;;;;;;:27;;;;:::i;:::-;88529:1;:9;;:17;88539:6;88529:17;;;;;;;;;;;;;;;:47;;;;88633:15;88610:1;:9;;:20;88620:9;88610:20;;;;;;;;;;;;;;;;:38;;;;:::i;:::-;88587:1;:9;;:20;88597:9;88587:20;;;;;;;;;;;;;;;:61;;;;88705:15;88682:1;:9;;:20;88692:9;88682:20;;;;;;;;;;;;;;;;:38;;;;:::i;:::-;88659:1;:9;;:20;88669:9;88659:20;;;;;;;;;;;;;;;:61;;;;88739:23;88751:4;88757;88739:11;:23::i;:::-;88795:9;88778:44;;88787:6;88778:44;;;88806:15;88778:44;;;;;;:::i;:::-;;;;;;;;88332:498;;;;;88241:589;;;:::o;84387:92::-;;;;:::o;91048:883::-;91151:1;91132:21;;:7;:21;;;91124:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;91178:1;:14;;;;;;;;;;;;91174:143;;;91242:1;:9;;;;;;;;;;;;91229:45;;;:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91209:79;;;91289:7;91298:6;91209:96;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91174:143;91330:49;91351:7;91368:1;91372:6;91330:20;:49::i;:::-;91395:1;:13;;:23;;;;;;;;;;;;:50;;;;;91423:1;:13;;:22;91437:7;91423:22;;;;;;;;;;;;;;;;;;;;;;;;;91422:23;91395:50;91392:285;;;91463:15;91486:18;91497:6;91486:10;:18::i;:::-;91462:42;;;;;;91561:7;91540:1;:9;;:18;91550:7;91540:18;;;;;;;;;;;;;;;;:28;;;;:::i;:::-;91519:1;:9;;:18;91529:7;91519:18;;;;;;;;;;;;;;;:49;;;;91607:7;91595:1;:9;;;:19;;;;:::i;:::-;91583:1;:9;;:31;;;;91659:6;91644:1;:12;;;:21;;;;:::i;:::-;91629:1;:12;;:36;;;;91447:230;91392:285;91689:22;91714:1;:9;;:18;91724:7;91714:18;;;;;;;;;;;;;;;;91689:43;;91769:6;91751:14;:24;;91743:40;;;;;;;;;;;;:::i;:::-;;;;;;;;;91832:6;91815:14;:23;;;;:::i;:::-;91794:1;:9;;:18;91804:7;91794:18;;;;;;;;;;;;;;;:44;;;;91862:6;91849:1;:9;;;:19;;;;;;;:::i;:::-;;;;;;;;91912:1;91886:37;;91895:7;91886:37;;;91916:6;91886:37;;;;;;:::i;:::-;;;;;;;;91113:818;91048:883;;:::o;89413:230::-;89473:7;89482;89502:12;89527:1;:6;;:16;;;89517:7;:26;;;;:::i;:::-;89502:41;;89554:23;89590:4;89580:7;:14;;;;:::i;:::-;89554:40;;89613:15;89630:4;89605:30;;;;;;89413:230;;;:::o;89651:325::-;89746:7;89755;89764;89784:15;89812:11;89802:7;:21;;;;:::i;:::-;89784:39;;89834:12;89856:11;89849:4;:18;;;;:::i;:::-;89834:33;;89878:23;89914:4;89904:7;:14;;;;:::i;:::-;89878:40;;89937:7;89946:15;89963:4;89929:39;;;;;;;;;89651:325;;;;;;;:::o;90152:586::-;90202:7;90211;90231:15;90249:1;:9;;;90231:27;;90269:15;90287:1;:9;;;90269:27;;90318:9;90313:305;90337:1;:11;;:18;;;;90333:1;:22;90313:305;;;90409:7;90381:1;:9;;:25;90391:1;:11;;90403:1;90391:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;90381:25;;;;;;;;;;;;;;;;:35;:74;;;;90448:7;90420:1;:9;;:25;90430:1;:11;;90442:1;90430:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;90420:25;;;;;;;;;;;;;;;;:35;90381:74;90377:109;;;90465:1;:9;;;90476:1;:9;;;90457:29;;;;;;;;;90377:109;90521:1;:9;;:25;90531:1;:11;;90543:1;90531:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;90521:25;;;;;;;;;;;;;;;;90511:7;:35;;;;:::i;:::-;90501:45;;90581:1;:9;;:25;90591:1;:11;;90603:1;90591:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;90581:25;;;;;;;;;;;;;;;;90571:7;:35;;;;:::i;:::-;90561:45;;90357:3;;;;;:::i;:::-;;;;90313:305;;;;90654:1;:9;;;90642:1;:9;;;:21;;;;:::i;:::-;90632:7;:31;90628:66;;;90673:1;:9;;;90684:1;:9;;;90665:29;;;;;;;;90628:66;90713:7;90722;90705:25;;;;;;90152:586;;;:::o;88838:149::-;88930:4;88918:1;:9;;;:16;;;;:::i;:::-;88906:1;:9;;:28;;;;88975:4;88960:1;:12;;;:19;;;;:::i;:::-;88945:1;:12;;:34;;;;88838:149;;:::o;88:117:1:-;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:118::-;1112:24;1130:5;1112:24;:::i;:::-;1107:3;1100:37;1025:118;;:::o;1149:222::-;1242:4;1280:2;1269:9;1265:18;1257:26;;1293:71;1361:1;1350:9;1346:17;1337:6;1293:71;:::i;:::-;1149:222;;;;:::o;1377:126::-;1414:7;1454:42;1447:5;1443:54;1432:65;;1377:126;;;:::o;1509:96::-;1546:7;1575:24;1593:5;1575:24;:::i;:::-;1564:35;;1509:96;;;:::o;1611:122::-;1684:24;1702:5;1684:24;:::i;:::-;1677:5;1674:35;1664:63;;1723:1;1720;1713:12;1664:63;1611:122;:::o;1739:139::-;1785:5;1823:6;1810:20;1801:29;;1839:33;1866:5;1839:33;:::i;:::-;1739:139;;;;:::o;1884:619::-;1961:6;1969;1977;2026:2;2014:9;2005:7;2001:23;1997:32;1994:119;;;2032:79;;:::i;:::-;1994:119;2152:1;2177:53;2222:7;2213:6;2202:9;2198:22;2177:53;:::i;:::-;2167:63;;2123:117;2279:2;2305:53;2350:7;2341:6;2330:9;2326:22;2305:53;:::i;:::-;2295:63;;2250:118;2407:2;2433:53;2478:7;2469:6;2458:9;2454:22;2433:53;:::i;:::-;2423:63;;2378:118;1884:619;;;;;:::o;2509:90::-;2543:7;2586:5;2579:13;2572:21;2561:32;;2509:90;;;:::o;2605:116::-;2675:21;2690:5;2675:21;:::i;:::-;2668:5;2665:32;2655:60;;2711:1;2708;2701:12;2655:60;2605:116;:::o;2727:133::-;2770:5;2808:6;2795:20;2786:29;;2824:30;2848:5;2824:30;:::i;:::-;2727:133;;;;:::o;2866:468::-;2931:6;2939;2988:2;2976:9;2967:7;2963:23;2959:32;2956:119;;;2994:79;;:::i;:::-;2956:119;3114:1;3139:53;3184:7;3175:6;3164:9;3160:22;3139:53;:::i;:::-;3129:63;;3085:117;3241:2;3267:50;3309:7;3300:6;3289:9;3285:22;3267:50;:::i;:::-;3257:60;;3212:115;2866:468;;;;;:::o;3340:118::-;3427:24;3445:5;3427:24;:::i;:::-;3422:3;3415:37;3340:118;;:::o;3464:222::-;3557:4;3595:2;3584:9;3580:18;3572:26;;3608:71;3676:1;3665:9;3661:17;3652:6;3608:71;:::i;:::-;3464:222;;;;:::o;3692:329::-;3751:6;3800:2;3788:9;3779:7;3775:23;3771:32;3768:119;;;3806:79;;:::i;:::-;3768:119;3926:1;3951:53;3996:7;3987:6;3976:9;3972:22;3951:53;:::i;:::-;3941:63;;3897:117;3692:329;;;;:::o;4027:109::-;4108:21;4123:5;4108:21;:::i;:::-;4103:3;4096:34;4027:109;;:::o;4142:210::-;4229:4;4267:2;4256:9;4252:18;4244:26;;4280:65;4342:1;4331:9;4327:17;4318:6;4280:65;:::i;:::-;4142:210;;;;:::o;4358:169::-;4442:11;4476:6;4471:3;4464:19;4516:4;4511:3;4507:14;4492:29;;4358:169;;;;:::o;4533:152::-;4673:4;4669:1;4661:6;4657:14;4650:28;4533:152;:::o;4691:365::-;4833:3;4854:66;4918:1;4913:3;4854:66;:::i;:::-;4847:73;;4929:93;5018:3;4929:93;:::i;:::-;5047:2;5042:3;5038:12;5031:19;;4691:365;;;:::o;5062:419::-;5228:4;5266:2;5255:9;5251:18;5243:26;;5315:9;5309:4;5305:20;5301:1;5290:9;5286:17;5279:47;5343:131;5469:4;5343:131;:::i;:::-;5335:139;;5062:419;;;:::o;5487:180::-;5535:77;5532:1;5525:88;5632:4;5629:1;5622:15;5656:4;5653:1;5646:15;5673:194;5713:4;5733:20;5751:1;5733:20;:::i;:::-;5728:25;;5767:20;5785:1;5767:20;:::i;:::-;5762:25;;5811:1;5808;5804:9;5796:17;;5835:1;5829:4;5826:11;5823:37;;;5840:18;;:::i;:::-;5823:37;5673:194;;;;:::o;5873:191::-;5913:3;5932:20;5950:1;5932:20;:::i;:::-;5927:25;;5966:20;5984:1;5966:20;:::i;:::-;5961:25;;6009:1;6006;6002:9;5995:16;;6030:3;6027:1;6024:10;6021:36;;;6037:18;;:::i;:::-;6021:36;5873:191;;;;:::o;6070:553::-;6247:4;6285:3;6274:9;6270:19;6262:27;;6299:71;6367:1;6356:9;6352:17;6343:6;6299:71;:::i;:::-;6380:72;6448:2;6437:9;6433:18;6424:6;6380:72;:::i;:::-;6462;6530:2;6519:9;6515:18;6506:6;6462:72;:::i;:::-;6544;6612:2;6601:9;6597:18;6588:6;6544:72;:::i;:::-;6070:553;;;;;;;:::o;6629:143::-;6686:5;6717:6;6711:13;6702:22;;6733:33;6760:5;6733:33;:::i;:::-;6629:143;;;;:::o;6778:351::-;6848:6;6897:2;6885:9;6876:7;6872:23;6868:32;6865:119;;;6903:79;;:::i;:::-;6865:119;7023:1;7048:64;7104:7;7095:6;7084:9;7080:22;7048:64;:::i;:::-;7038:74;;6994:128;6778:351;;;;:::o;7135:153::-;7275:5;7271:1;7263:6;7259:14;7252:29;7135:153;:::o;7294:365::-;7436:3;7457:66;7521:1;7516:3;7457:66;:::i;:::-;7450:73;;7532:93;7621:3;7532:93;:::i;:::-;7650:2;7645:3;7641:12;7634:19;;7294:365;;;:::o;7665:419::-;7831:4;7869:2;7858:9;7854:18;7846:26;;7918:9;7912:4;7908:20;7904:1;7893:9;7889:17;7882:47;7946:131;8072:4;7946:131;:::i;:::-;7938:139;;7665:419;;;:::o;8090:180::-;8138:77;8135:1;8128:88;8235:4;8232:1;8225:15;8259:4;8256:1;8249:15;8276:185;8316:1;8333:20;8351:1;8333:20;:::i;:::-;8328:25;;8367:20;8385:1;8367:20;:::i;:::-;8362:25;;8406:1;8396:35;;8411:18;;:::i;:::-;8396:35;8453:1;8450;8446:9;8441:14;;8276:185;;;;:::o;8467:137::-;8521:5;8552:6;8546:13;8537:22;;8568:30;8592:5;8568:30;:::i;:::-;8467:137;;;;:::o;8610:345::-;8677:6;8726:2;8714:9;8705:7;8701:23;8697:32;8694:119;;;8732:79;;:::i;:::-;8694:119;8852:1;8877:61;8930:7;8921:6;8910:9;8906:22;8877:61;:::i;:::-;8867:71;;8823:125;8610:345;;;;:::o;8961:154::-;9101:6;9097:1;9089:6;9085:14;9078:30;8961:154;:::o;9121:365::-;9263:3;9284:66;9348:1;9343:3;9284:66;:::i;:::-;9277:73;;9359:93;9448:3;9359:93;:::i;:::-;9477:2;9472:3;9468:12;9461:19;;9121:365;;;:::o;9492:419::-;9658:4;9696:2;9685:9;9681:18;9673:26;;9745:9;9739:4;9735:20;9731:1;9720:9;9716:17;9709:47;9773:131;9899:4;9773:131;:::i;:::-;9765:139;;9492:419;;;:::o;9917:154::-;10057:6;10053:1;10045:6;10041:14;10034:30;9917:154;:::o;10077:365::-;10219:3;10240:66;10304:1;10299:3;10240:66;:::i;:::-;10233:73;;10315:93;10404:3;10315:93;:::i;:::-;10433:2;10428:3;10424:12;10417:19;;10077:365;;;:::o;10448:419::-;10614:4;10652:2;10641:9;10637:18;10629:26;;10701:9;10695:4;10691:20;10687:1;10676:9;10672:17;10665:47;10729:131;10855:4;10729:131;:::i;:::-;10721:139;;10448:419;;;:::o;10873:153::-;11013:5;11009:1;11001:6;10997:14;10990:29;10873:153;:::o;11032:365::-;11174:3;11195:66;11259:1;11254:3;11195:66;:::i;:::-;11188:73;;11270:93;11359:3;11270:93;:::i;:::-;11388:2;11383:3;11379:12;11372:19;;11032:365;;;:::o;11403:419::-;11569:4;11607:2;11596:9;11592:18;11584:26;;11656:9;11650:4;11646:20;11642:1;11631:9;11627:17;11620:47;11684:131;11810:4;11684:131;:::i;:::-;11676:139;;11403:419;;;:::o;11828:152::-;11968:4;11964:1;11956:6;11952:14;11945:28;11828:152;:::o;11986:365::-;12128:3;12149:66;12213:1;12208:3;12149:66;:::i;:::-;12142:73;;12224:93;12313:3;12224:93;:::i;:::-;12342:2;12337:3;12333:12;12326:19;;11986:365;;;:::o;12357:419::-;12523:4;12561:2;12550:9;12546:18;12538:26;;12610:9;12604:4;12600:20;12596:1;12585:9;12581:17;12574:47;12638:131;12764:4;12638:131;:::i;:::-;12630:139;;12357:419;;;:::o;12782:152::-;12922:4;12918:1;12910:6;12906:14;12899:28;12782:152;:::o;12940:365::-;13082:3;13103:66;13167:1;13162:3;13103:66;:::i;:::-;13096:73;;13178:93;13267:3;13178:93;:::i;:::-;13296:2;13291:3;13287:12;13280:19;;12940:365;;;:::o;13311:419::-;13477:4;13515:2;13504:9;13500:18;13492:26;;13564:9;13558:4;13554:20;13550:1;13539:9;13535:17;13528:47;13592:131;13718:4;13592:131;:::i;:::-;13584:139;;13311:419;;;:::o;13736:152::-;13876:4;13872:1;13864:6;13860:14;13853:28;13736:152;:::o;13894:365::-;14036:3;14057:66;14121:1;14116:3;14057:66;:::i;:::-;14050:73;;14132:93;14221:3;14132:93;:::i;:::-;14250:2;14245:3;14241:12;14234:19;;13894:365;;;:::o;14265:419::-;14431:4;14469:2;14458:9;14454:18;14446:26;;14518:9;14512:4;14508:20;14504:1;14493:9;14489:17;14482:47;14546:131;14672:4;14546:131;:::i;:::-;14538:139;;14265:419;;;:::o;14690:153::-;14830:5;14826:1;14818:6;14814:14;14807:29;14690:153;:::o;14849:365::-;14991:3;15012:66;15076:1;15071:3;15012:66;:::i;:::-;15005:73;;15087:93;15176:3;15087:93;:::i;:::-;15205:2;15200:3;15196:12;15189:19;;14849:365;;;:::o;15220:419::-;15386:4;15424:2;15413:9;15409:18;15401:26;;15473:9;15467:4;15463:20;15459:1;15448:9;15444:17;15437:47;15501:131;15627:4;15501:131;:::i;:::-;15493:139;;15220:419;;;:::o;15645:152::-;15785:4;15781:1;15773:6;15769:14;15762:28;15645:152;:::o;15803:365::-;15945:3;15966:66;16030:1;16025:3;15966:66;:::i;:::-;15959:73;;16041:93;16130:3;16041:93;:::i;:::-;16159:2;16154:3;16150:12;16143:19;;15803:365;;;:::o;16174:419::-;16340:4;16378:2;16367:9;16363:18;16355:26;;16427:9;16421:4;16417:20;16413:1;16402:9;16398:17;16391:47;16455:131;16581:4;16455:131;:::i;:::-;16447:139;;16174:419;;;:::o;16599:153::-;16739:5;16735:1;16727:6;16723:14;16716:29;16599:153;:::o;16758:365::-;16900:3;16921:66;16985:1;16980:3;16921:66;:::i;:::-;16914:73;;16996:93;17085:3;16996:93;:::i;:::-;17114:2;17109:3;17105:12;17098:19;;16758:365;;;:::o;17129:419::-;17295:4;17333:2;17322:9;17318:18;17310:26;;17382:9;17376:4;17372:20;17368:1;17357:9;17353:17;17346:47;17410:131;17536:4;17410:131;:::i;:::-;17402:139;;17129:419;;;:::o;17554:332::-;17675:4;17713:2;17702:9;17698:18;17690:26;;17726:71;17794:1;17783:9;17779:17;17770:6;17726:71;:::i;:::-;17807:72;17875:2;17864:9;17860:18;17851:6;17807:72;:::i;:::-;17554:332;;;;;:::o;17892:410::-;17932:7;17955:20;17973:1;17955:20;:::i;:::-;17950:25;;17989:20;18007:1;17989:20;:::i;:::-;17984:25;;18044:1;18041;18037:9;18066:30;18084:11;18066:30;:::i;:::-;18055:41;;18245:1;18236:7;18232:15;18229:1;18226:22;18206:1;18199:9;18179:83;18156:139;;18275:18;;:::i;:::-;18156:139;17940:362;17892:410;;;;:::o;18308:332::-;18429:4;18467:2;18456:9;18452:18;18444:26;;18480:71;18548:1;18537:9;18533:17;18524:6;18480:71;:::i;:::-;18561:72;18629:2;18618:9;18614:18;18605:6;18561:72;:::i;:::-;18308:332;;;;;:::o;18646:541::-;18817:4;18855:3;18844:9;18840:19;18832:27;;18869:71;18937:1;18926:9;18922:17;18913:6;18869:71;:::i;:::-;18950:72;19018:2;19007:9;19003:18;18994:6;18950:72;:::i;:::-;19032;19100:2;19089:9;19085:18;19076:6;19032:72;:::i;:::-;19114:66;19176:2;19165:9;19161:18;19152:6;19114:66;:::i;:::-;18646:541;;;;;;;:::o;19193:180::-;19241:77;19238:1;19231:88;19338:4;19335:1;19328:15;19362:4;19359:1;19352:15;19379:86;19414:7;19454:4;19447:5;19443:16;19432:27;;19379:86;;;:::o;19471:167::-;19508:3;19531:22;19547:5;19531:22;:::i;:::-;19522:31;;19575:4;19568:5;19565:15;19562:41;;19583:18;;:::i;:::-;19562:41;19630:1;19623:5;19619:13;19612:20;;19471:167;;;:::o;19644:182::-;19784:34;19780:1;19772:6;19768:14;19761:58;19644:182;:::o;19832:366::-;19974:3;19995:67;20059:2;20054:3;19995:67;:::i;:::-;19988:74;;20071:93;20160:3;20071:93;:::i;:::-;20189:2;20184:3;20180:12;20173:19;;19832:366;;;:::o;20204:419::-;20370:4;20408:2;20397:9;20393:18;20385:26;;20457:9;20451:4;20447:20;20443:1;20432:9;20428:17;20421:47;20485:131;20611:4;20485:131;:::i;:::-;20477:139;;20204:419;;;:::o;20629:152::-;20769:4;20765:1;20757:6;20753:14;20746:28;20629:152;:::o;20787:365::-;20929:3;20950:66;21014:1;21009:3;20950:66;:::i;:::-;20943:73;;21025:93;21114:3;21025:93;:::i;:::-;21143:2;21138:3;21134:12;21127:19;;20787:365;;;:::o;21158:419::-;21324:4;21362:2;21351:9;21347:18;21339:26;;21411:9;21405:4;21401:20;21397:1;21386:9;21382:17;21375:47;21439:131;21565:4;21439:131;:::i;:::-;21431:139;;21158:419;;;:::o;21583:225::-;21723:34;21719:1;21711:6;21707:14;21700:58;21792:8;21787:2;21779:6;21775:15;21768:33;21583:225;:::o;21814:366::-;21956:3;21977:67;22041:2;22036:3;21977:67;:::i;:::-;21970:74;;22053:93;22142:3;22053:93;:::i;:::-;22171:2;22166:3;22162:12;22155:19;;21814:366;;;:::o;22186:419::-;22352:4;22390:2;22379:9;22375:18;22367:26;;22439:9;22433:4;22429:20;22425:1;22414:9;22410:17;22403:47;22467:131;22593:4;22467:131;:::i;:::-;22459:139;;22186:419;;;:::o;22611:152::-;22751:4;22747:1;22739:6;22735:14;22728:28;22611:152;:::o;22769:365::-;22911:3;22932:66;22996:1;22991:3;22932:66;:::i;:::-;22925:73;;23007:93;23096:3;23007:93;:::i;:::-;23125:2;23120:3;23116:12;23109:19;;22769:365;;;:::o;23140:419::-;23306:4;23344:2;23333:9;23329:18;23321:26;;23393:9;23387:4;23383:20;23379:1;23368:9;23364:17;23357:47;23421:131;23547:4;23421:131;:::i;:::-;23413:139;;23140:419;;;:::o;23565:180::-;23613:77;23610:1;23603:88;23710:4;23707:1;23700:15;23734:4;23731:1;23724:15;23751:233;23790:3;23813:24;23831:5;23813:24;:::i;:::-;23804:33;;23859:66;23852:5;23849:77;23846:103;;23929:18;;:::i;:::-;23846:103;23976:1;23969:5;23965:13;23958:20;;23751:233;;;:::o;23990:153::-;24130:5;24126:1;24118:6;24114:14;24107:29;23990:153;:::o;24149:365::-;24291:3;24312:66;24376:1;24371:3;24312:66;:::i;:::-;24305:73;;24387:93;24476:3;24387:93;:::i;:::-;24505:2;24500:3;24496:12;24489:19;;24149:365;;;:::o;24520:419::-;24686:4;24724:2;24713:9;24709:18;24701:26;;24773:9;24767:4;24763:20;24759:1;24748:9;24744:17;24737:47;24801:131;24927:4;24801:131;:::i;:::-;24793:139;;24520:419;;;:::o;24945:332::-;25066:4;25104:2;25093:9;25089:18;25081:26;;25117:71;25185:1;25174:9;25170:17;25161:6;25117:71;:::i;:::-;25198:72;25266:2;25255:9;25251:18;25242:6;25198:72;:::i;:::-;24945:332;;;;;:::o;25283:153::-;25423:5;25419:1;25411:6;25407:14;25400:29;25283:153;:::o;25442:365::-;25584:3;25605:66;25669:1;25664:3;25605:66;:::i;:::-;25598:73;;25680:93;25769:3;25680:93;:::i;:::-;25798:2;25793:3;25789:12;25782:19;;25442:365;;;:::o;25813:419::-;25979:4;26017:2;26006:9;26002:18;25994:26;;26066:9;26060:4;26056:20;26052:1;26041:9;26037:17;26030:47;26094:131;26220:4;26094:131;:::i;:::-;26086:139;;25813:419;;;:::o
Swarm Source
ipfs://8cd1025029ac08018c83e687cc4837a714f7dd646612bcf2657dc9834355221b
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.