false
true
0

Contract Address Details

0xF444620032c81EB0faAD9b332b23D7419C46a947

Token
VOXZILLA (ZILLA)
Creator
0x345fb2–25f90d at 0x14adaa–d2899c
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
636 Transactions
Transfers
0 Transfers
Gas Used
0
Last Balance Update
25941787
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
IcariaSmartToken




Optimization enabled
true
Compiler version
v0.8.28+commit.7893614a




Optimization runs
20
EVM Version
paris




Verified at
2025-04-10T23:58:40.981554Z

Constructor Arguments

0x00000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000345fb2409a75089bdea4cdb2eb032106d125f90d000000000000000000000000214a4542e048ef9c21feca0980b8500773c1b5d80000000000000000000000000000000000000000033b2e3c9fd0803ce800000000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000656ae27db6d2d85d9b7b45cf0c8201e6034c0176000000000000000000000000345fb2409a75089bdea4cdb2eb032106d125f90d000000000000000000000000acdf534bdd29697f4f1e768fc28d51bcca2fe2e00000000000000000000000000000000000000000000000000000000000000008564f585a494c4c4100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055a494c4c41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094534eeee131840b1c0f61847c572228bdfdde9300000000000000000000000000000000000000000000000000000000000003690000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000456548a9b56efbbd89ca0309edd17a9e20b0401800000000000000000000000000000000000000000000000000000000000003690000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000960000000000000000000000000000000000000000000000000000000000000369000000000000000000000000290d95b17873f75b6897844844bd204173ad25aa0000000000000000000000000000000000000000000000000000000000000369000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000ba410289d31f515de8ea1112ff787faf0932fbbd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
              

contracts/icaria/IcariaSmartToken.sol

//
//
//
//       ██╗ ██████╗ █████╗ ██████╗ ██╗ █████╗     ███████╗ ██████╗ ██████╗  ██████╗ ███████╗
//       ██║██╔════╝██╔══██╗██╔══██╗██║██╔══██╗    ██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██╔════╝
//       ██║██║     ███████║██████╔╝██║███████║    █████╗  ██║   ██║██████╔╝██║  ███╗█████╗  
//       ██║██║     ██╔══██║██╔══██╗██║██╔══██║    ██╔══╝  ██║   ██║██╔══██╗██║   ██║██╔══╝  
//       ██║╚██████╗██║  ██║██║  ██║██║██║  ██║    ██║     ╚██████╔╝██║  ██║╚██████╔╝███████╗
//       ╚═╝ ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝╚═╝  ╚═╝    ╚═╝      ╚═════╝ ╚═╝  ╚═╝ ╚═════╝ ╚══════╝
//                                                                                 
//     
//                                                                             
// Forge
// Web: https://forge.icaria.pro
// Tg:  https://t.me/icariaforge 
// 
// Icaria
// Web: https://icaria.pro
// Tg:  https://t.me/icarusprc20
// X:   https://x.com/IcarusPRC20     
//

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import { ERC20 } from "../ERC20.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IcariaRYManager } from "./IcariaRYManager.sol";
import { Ownable }from "@openzeppelin/contracts/access/Ownable.sol";
import { IUniswapV2Factory } from "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol";
import { IUniswapV2Router02 } from "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import { IUniswapV2Pair } from "@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol";
import { IIcariaHelpers } from "./interfaces/IIcariaHelpers.sol";
import { IIcariaSmartTrader } from "./interfaces/IIcariaSmartTrader.sol";
import { IIcariaSmartTokenFactory } from "./interfaces/IIcariaSmartTokenFactory.sol";
import { IWETH } from "./interfaces/IWETH.sol";

contract IcariaSmartToken is ERC20, Ownable, IcariaRYManager {
  uint256 public constant tokenVersion = 1;
  uint256 public initialSupply;

  uint256 private constant GLOBAL_DIVIDER = 10000;
  address private icariaSmartTrader;
  address private deployer;
  address private factory;
  address private wethAddress = 0xA1077a294dDE1B09bB078844df40758a5D0f9a27; // WPLS on PulseChain
  address[] private routers = [0x98bf93ebf5c380C0e6Ae8e192A7e2AE08edAcc02, 0x165C3410fC91EF562C50559f7d2289fEbed552d9, 0xcC73b59F8D7b7c532703bDfea2808a28a488cF47, 0xeB45a3c4aedd0F47F345fB4c8A1802BB5740d725];
  mapping (address => bool) isTaxExcluded;
  uint256 private currentSwapAmount;
  uint256 private accumulatedIcariaFee;

  bool private icariaFeeEnabled;
  bool private shouldAccumulateIcariaFee; 
  bool private reflectionsEnabled;
  bool private yieldEnabled;
  bool private firstPairInteractionHappened = false;
  bool private processedTaxesInTx;

  IIcariaHelpers.Tax[] public taxes;

  constructor(
    string memory name_, 
    string memory symbol_,
    address _owner,
    address _mintTo, 
    uint256 _initialSupply, 
    IIcariaHelpers.Tax[] memory _taxes, 
    address _icariaSmartTrader,
    address _factory,
    address _helpers
  ) ERC20(name_, symbol_) Ownable(_owner) IcariaRYManager(_helpers) {
    _mint(_mintTo, _initialSupply);
    deployer = _mintTo;
    initialSupply = _initialSupply;
    icariaSmartTrader = _icariaSmartTrader;
    factory = _factory;
    if(_taxes.length > 0) {
      address[] memory _yieldTokens;
      icariaFeeEnabled = true;
      (shouldAccumulateIcariaFee, reflectionsEnabled, yieldEnabled, taxes, _yieldTokens) = IIcariaHelpers(helpers).taxesInitialize(_taxes);
      inititlizeTaxExclusions();
      if (reflectionsEnabled || yieldEnabled) initializeReflectionExclusions();
      for(uint256 i = 0; i < _yieldTokens.length; i++) {
        addYieldToken(_yieldTokens[i]);
      }
    }
  }
  


  function _transfer(address from, address to, uint256 value) internal override {
    processedTaxesInTx = false;
    if(isDeadAddress(to)) {
      super._burn(from, value);
      return;
    }
    if (taxes.length == 0 || !firstPairInteractionHappened || isTaxExcluded[from] || isTaxExcluded[to] || inSwap) {
      super._transfer(from, to, value);
      
      if(!firstPairInteractionHappened && isPair(to)){
        firstPairInteractionHappened = true;
      }
      return;
    }
    
    if(isPair(to) && !isReflectionExcluded[to]) {
      isReflectionExcluded[to] = true;
    }
    
    currentSwapAmount = value;
    
    uint256 amountAfterTaxs = processTaxes(from, to, value);
    
    if (hasAccumulatedTaxes() && firstPairInteractionHappened && !inSwap && !processedTaxesInTx) {
      processAccumulatedTaxes();
      processedTaxesInTx = true;
    }
    
    if (yieldEnabled) {
      updateAndClaimYield(from, to, deployer);
    }
    
    if (reflectionsEnabled) {
      claimReflections(from, to);
    }
    
    if (shouldAccumulateIcariaFee && isSell(from, to)) {
      processIcariaFeeAccumulated();
    }
    
    super._transfer(from, to, amountAfterTaxs);
  }

  function processTaxes(address from, address to, uint256 amount) internal returns (uint256) {
    uint256 totalTaxAmount = 0;
    uint256 totalIcariaFee = 0;
    
    for (uint256 i = 0; i < taxes.length; i++) {
      IIcariaHelpers.Tax memory tax = taxes[i];
      
      (uint256 taxAmount, uint256 icariaFee) = calculateTaxAmount(amount, tax);
      
      totalTaxAmount += taxAmount;
      totalIcariaFee += icariaFee;
      
      if (tax.taxMoment == IIcariaHelpers.TaxMoment.Both) {
        processTaxType(from, taxAmount, tax);
      } else if (tax.taxMoment == IIcariaHelpers.TaxMoment.Buy && isBuy(from, to)) {
        processTaxType(from, taxAmount, tax);
      } else if (tax.taxMoment == IIcariaHelpers.TaxMoment.Sell && isSell(from, to)) {
        processTaxType(from, taxAmount, tax);
      }
    }
    
    if (totalIcariaFee > 0) {
      if (shouldAccumulateIcariaFee) {
        super._transfer(from, address(this), totalIcariaFee);
        accumulatedIcariaFee += totalIcariaFee;
      } else {
        super._transfer(from, getIcariaWallet(), totalIcariaFee);
      }
    }
    
    return amount - totalTaxAmount - totalIcariaFee;
  }

  function calculateTaxAmount(uint256 originalAmount, IIcariaHelpers.Tax memory tax) internal view returns (uint256 taxAmount, uint256 icariaFee) {
    return IIcariaHelpers(helpers).calculateTaxAmount(
      originalAmount, 
      tax.percentage, 
      getIcariaFee(),
      icariaFeeEnabled,
      GLOBAL_DIVIDER
    );
  }

  function processTaxType(address from, uint256 taxAmount, IIcariaHelpers.Tax memory tax) internal {
    if (tax.taxType == IIcariaHelpers.TaxType.Burn) {
      processBurnTax(from, taxAmount);
    } else if (tax.taxType == IIcariaHelpers.TaxType.Reflection) {
      processReflectionTax(from, taxAmount);
    } else if (tax.taxType == IIcariaHelpers.TaxType.Dev) {
      processDevTax(from, taxAmount, tax);
    } else if (tax.taxType == IIcariaHelpers.TaxType.ExternalBurn) {
      processExternalBurnTax(from, taxAmount, tax);
    } else if (tax.taxType == IIcariaHelpers.TaxType.Yield) {
      processYieldTax(from, taxAmount, tax);
    }
  }

  function processBurnTax(address from, uint256 taxAmount) internal {
    super._burn(from, taxAmount);
  }

  function processDevTax(address from, uint256 taxAmount, IIcariaHelpers.Tax memory tax) internal {
    if(!isTaxExcluded[tax.receiver]) isTaxExcluded[tax.receiver] = true;
    if (tax.rewardInPls) {
      super._transfer(from, address(this), taxAmount);
      taxes[tax.id].amountAccumulated += taxAmount;
    } else {
      super._transfer(from, tax.receiver, taxAmount);
    }
  }

  function processReflectionTax(address from, uint256 taxAmount) internal {
    super._transfer(from, address(this), taxAmount);
    uint256 supply = totalSupply() - balanceOf(address(this));
    if (supply > 0) {
      reflectionsPerShareAmount += (taxAmount * PRECISION) / supply;
    }
  }

  function processExternalBurnTax(address from, uint256 taxAmount, IIcariaHelpers.Tax memory tax) internal lockSwap {
    super._transfer(from, address(this), taxAmount);
    taxes[tax.id].amountAccumulated += taxAmount;
  }

  function processYieldTax(address from, uint256 taxAmount, IIcariaHelpers.Tax memory tax) internal lockSwap {
    super._transfer(from, address(this), taxAmount);
    taxes[tax.id].amountAccumulated += taxAmount;
  }

  function processAccumulatedTaxes() internal {
    if (inSwap) return;
    
    processAccumulatedTaxesBatch();
  }

function processAccumulatedTaxesBatch() internal lockSwap {
    uint256 totalToSwap = 0;
    uint256 totalTokenTypes = 0;
    
    bool[] memory taxesToProcess = new bool[](taxes.length);
    uint256[] memory taxAmounts = new uint256[](taxes.length);
    
    for (uint256 i = 0; i < taxes.length; i++) {
        IIcariaHelpers.Tax storage tax = taxes[i];
        if (tax.amountAccumulated == 0) continue;
        
        if (tax.taxType == IIcariaHelpers.TaxType.ExternalBurn || 
            (tax.taxType == IIcariaHelpers.TaxType.Dev && tax.rewardInPls) || 
            tax.taxType == IIcariaHelpers.TaxType.Yield) {
            
            (uint256 swapAmount, uint256 newAccumulatedAmount) = IIcariaHelpers(helpers).getProcessingAmount(tax.amountAccumulated, currentSwapAmount);
            if (swapAmount > 0) {
                taxesToProcess[i] = true;
                taxAmounts[i] = swapAmount;
                totalToSwap += swapAmount;
                totalTokenTypes++;
            }
            taxes[i].amountAccumulated = newAccumulatedAmount;
        }
    }
    
    if (totalToSwap == 0 || totalTokenTypes == 0) return;
    
    (/*address bestPair*/, address bestRouter) = IIcariaHelpers(helpers).getBestPair(address(this), wethAddress, routers);
    if (bestRouter == address(0)) return;
    
    _approve(address(this), icariaSmartTrader, totalToSwap);
    bool swapSuccess = _executeTokenSwap(
        bestRouter,
        address(this),
        totalToSwap,
        getTokenWPLSPath(address(this)),
        false
    );
    
    if (!swapSuccess) {
        for (uint256 i = 0; i < taxes.length; i++) {
            if (taxesToProcess[i]) {
                taxes[i].amountAccumulated += taxAmounts[i];
            }
        }
        return;
    }
    
    uint256 totalWethReceived = IERC20(wethAddress).balanceOf(address(this));
    if (totalWethReceived == 0) return;
    
    for (uint256 i = 0; i < taxes.length; i++) {
        if (!taxesToProcess[i] || taxAmounts[i] == 0) continue;
        
        uint256 wethPortion = (taxAmounts[i] * totalWethReceived) / totalToSwap;
        IIcariaHelpers.Tax storage tax = taxes[i];
        
        if (tax.taxType == IIcariaHelpers.TaxType.ExternalBurn) {
            processExternalBurnWeth(wethPortion, tax);
        } else if (tax.taxType == IIcariaHelpers.TaxType.Dev && tax.rewardInPls) {
            processDevWeth(wethPortion, tax);
        } else if (tax.taxType == IIcariaHelpers.TaxType.Yield) {
            processYieldWeth(wethPortion, tax);
        }
    }
}

function processExternalBurnWeth(uint256 wethAmount, IIcariaHelpers.Tax memory tax) internal {
    if (wethAmount == 0) return;
    
    if (tax.tokenAddress == wethAddress) {
        IERC20(wethAddress).transfer(tax.receiver, wethAmount);
        return;
    }
    
    (/*address bestTargetPair*/, address bestTargetRouter) = IIcariaHelpers(helpers).getBestPair(wethAddress, tax.tokenAddress, routers);
    
    IERC20(wethAddress).approve(icariaSmartTrader, wethAmount);
    
    try IIcariaSmartTrader(icariaSmartTrader).swapExactTokensForTokensSupportingFeeOnTransferTokens(
        bestTargetRouter,
        tax.receiver, 
        wethAmount,
        getWPLSBuyBurnPath(tax.tokenAddress)
    ) {
    } catch {
        IERC20(wethAddress).transfer(tax.receiver, wethAmount);
    }
}

function processDevWeth(uint256 wethAmount, IIcariaHelpers.Tax memory tax) internal {
  if (wethAmount == 0) return;
  try IWETH(wethAddress).withdraw(wethAmount){
    (bool success,) = tax.receiver.call{value: wethAmount}("");
    if (!success) {
      IERC20(wethAddress).transfer(tax.receiver, wethAmount);
    }
  } catch {
    IERC20(wethAddress).transfer(tax.receiver, wethAmount);
  }
}

function processYieldWeth(uint256 wethAmount, IIcariaHelpers.Tax memory tax) internal {
    if (wethAmount == 0) return;
    
    if (tax.tokenAddress == wethAddress) {
        uint256 tokenIndex = addYieldToken(tax.tokenAddress);
        uint256 supply = totalSupply() - balanceOf(address(this));
        if (supply > 0) {
            yieldTokens[tokenIndex].reflectionsPerShareAmount += (wethAmount * PRECISION) / supply;
        }
        return;
    }
    
    (/*address bestTargetPair*/, address bestTargetRouter) = IIcariaHelpers(helpers).getBestPair(wethAddress, tax.tokenAddress, routers);
    
    IERC20(wethAddress).approve(icariaSmartTrader, wethAmount);
    
    uint256 initialTokenBalance = IERC20(tax.tokenAddress).balanceOf(address(this));
    
    try IIcariaSmartTrader(icariaSmartTrader).swapExactTokensForTokensSupportingFeeOnTransferTokens(
        bestTargetRouter,
        address(this), 
        wethAmount,
        getWPLSBuyBurnPath(tax.tokenAddress)
    ) {
        uint256 finalTokenBalance = IERC20(tax.tokenAddress).balanceOf(address(this));
        uint256 boughtAmount = finalTokenBalance - initialTokenBalance;
        
        if (boughtAmount > 0) {
            uint256 tokenIndex = addYieldToken(tax.tokenAddress);
            
            uint256 supply = totalSupply() - balanceOf(address(this));
            if (supply > 0) {
                yieldTokens[tokenIndex].reflectionsPerShareAmount += (boughtAmount * PRECISION) / supply;
            }
        }
    } catch {
        // uint256 tokenIndex = addYieldToken(wethAddress);
        // uint256 supply = totalSupply() - balanceOf(address(this));
        // if (supply > 0) {
        //     yieldTokens[tokenIndex].reflectionsPerShareAmount += (wethAmount * PRECISION) / supply;
        // }
    }
}

  function processIcariaFeeAccumulated() internal {
    if (accumulatedIcariaFee == 0) return;
    (/*address bestPair*/, address router) = IIcariaHelpers(helpers).getBestPair(address(this), wethAddress, routers);
    if (router == address(0)) return;
    (uint256 amountToProcess, uint256 newAccumulatedAmount) = IIcariaHelpers(helpers).getProcessingAmount(accumulatedIcariaFee, currentSwapAmount);
    accumulatedIcariaFee = newAccumulatedAmount;

    _approve(address(this), icariaSmartTrader, amountToProcess);
    bool success = _executeTokenSwap(
      router,
      getIcariaWallet(), 
      amountToProcess,
      getTokenWPLSPath(address(this)),
      true 
    );
    
    if (!success) {
      accumulatedIcariaFee += amountToProcess;
    }
  }

 function _executeTokenSwap(
    address _router,
    address _recipient,
    uint256 _amount,
    address[] memory _path,
    bool _swapForETH
  ) internal returns (bool success) {
    if (_amount == 0 || _router == address(0)) return false;
    
    _approve(address(this), icariaSmartTrader, _amount);
    
    if (_swapForETH) {
      try IIcariaSmartTrader(icariaSmartTrader).swapExactTokensForETHSupportingFeeOnTransferTokens(
        _router,
        _recipient,
        _amount,
        _path
      ) {
        return true;
      } catch {
        return false;
      }
    } else {
      try IIcariaSmartTrader(icariaSmartTrader).swapExactTokensForTokensSupportingFeeOnTransferTokens(
        _router,
        _recipient,
        _amount,
        _path
      ) {
        return true;
      } catch {
        return false;
      }
    }
  }  

  function claimReflections(address from, address to) internal {
    (uint256 fromAmount, uint256 toAmount, uint256 deployerAmount) = updateAndClaimReflections(from, to, deployer);
    if(fromAmount != 0){
      if(!isPair(from)){
        super._transfer(address(this), from, fromAmount);
      }
    }
    if(toAmount != 0){
      if(!isPair(to)){
        super._transfer(address(this), to, toAmount);
      }
    }
    if(deployerAmount != 0){
      super._transfer(address(this), deployer, deployerAmount);
    }
  }

  function initializeReflectionExclusions() internal {
    isReflectionExcluded[address(0)] = true;
    isReflectionExcluded[address(this)] = true;
    for (uint256 i = 0; i < routers.length; ) {
      isReflectionExcluded[routers[i]] = true;
      unchecked { i++; }
    }
  }
  function isDeadAddress(address _address) internal view returns (bool) {
    return IIcariaHelpers(helpers).isDeadAddress(_address);
  }

  function isPair(address _address) internal view returns (bool) {
    return IIcariaHelpers(helpers).isPair(_address, address(this));
  }

  function isBuy(address from, address to) internal view returns (bool) {
    return IIcariaHelpers(helpers).isBuy(from, to, address(this));
  }

  function isSell(address from, address to) internal view returns (bool) {
    return IIcariaHelpers(helpers).isSell(from, to, address(this));
  }

  function getProcessingAmount(uint256 accumulatedAmount) internal view returns (uint256 processAmount, uint256 newAccumulatedAmount) {
    return IIcariaHelpers(helpers).getProcessingAmount(accumulatedAmount, currentSwapAmount);
  }

  function getTokenWPLSPath(address tokenAddress) internal view returns (address[] memory) {
    return IIcariaHelpers(helpers).getTokenWPLSPath(tokenAddress);
  }

  function getWPLSBuyBurnPath(address tokenAddress) internal view returns (address[] memory) {
    return IIcariaHelpers(helpers).getWPLSBuyBurnPath(tokenAddress);
  }

  function getTaxes() public view returns (IIcariaHelpers.Tax[] memory) {
    return taxes;
  }

  // function isExcludedFromTax(address from, address to) internal view returns (bool) {
  //   return IIcariaHelpers(helpers).isExcludedFromTax(
  //     from, 
  //     to, 
  //     icariaSmartTrader, 
  //     deployer, 
  //     address(this)
  //   );
  // }

  function getIcariaFee() public view returns (uint256) {
    return IIcariaSmartTokenFactory(factory).ICARIA_FEE();
  }

  function getIcariaWallet() public view returns (address) {
    return IIcariaSmartTokenFactory(factory).ICARIA_WALLET();
  }

  function getAccumulatedIcariaFee() external view returns (uint256) {
    return accumulatedIcariaFee;
  }

  function getTotalTaxs() external view returns (uint256) {
    return IIcariaHelpers(helpers).getTotalTaxs(taxes);
  }

  function forceProcessAccumulatedTaxes() external onlyOwner {
    processAccumulatedTaxes();
  }

  function claimYield() external returns (bool) {
    updateAndClaimYield(msg.sender, msg.sender, deployer);
    return true;
  }

  function hasAccumulatedTaxes() internal view returns (bool) {
    return IIcariaHelpers(helpers).hasAccumulatedTaxes(taxes);
  }

  function addTaxExclusion(address _address) external onlyOwner {
    isTaxExcluded[_address] = true;
  }

  function removeTaxExclusion(address _address) external onlyOwner {
    isTaxExcluded[_address] = false;
  }

  function inititlizeTaxExclusions() internal {
    isTaxExcluded[deployer] = true;
    isTaxExcluded[address(this)] = true;
    isTaxExcluded[icariaSmartTrader] = true;
  }
  
  receive() external payable {}
}
        

@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol

pragma solidity >=0.5.0;

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;
}
          

@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol

pragma solidity >=0.6.2;

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);
}
          

@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol

pragma solidity >=0.5.0;

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;
}
          

@openzeppelin/contracts/utils/Context.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}
          

@openzeppelin/contracts/access/Ownable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../utils/Context.sol";

/**
 * @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.
 *
 * The initial owner is set to the address provided by the deployer. 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;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(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 {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
          

@openzeppelin/contracts/interfaces/draft-IERC6093.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;

/**
 * @dev Standard ERC-20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
 */
interface IERC20Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC20InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC20InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     * @param allowance Amount of tokens a `spender` is allowed to operate with.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC20InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC20InvalidSpender(address spender);
}

/**
 * @dev Standard ERC-721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
 */
interface IERC721Errors {
    /**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
     * Used in balance queries.
     * @param owner Address of the current owner of a token.
     */
    error ERC721InvalidOwner(address owner);

    /**
     * @dev Indicates a `tokenId` whose `owner` is the zero address.
     * @param tokenId Identifier number of a token.
     */
    error ERC721NonexistentToken(uint256 tokenId);

    /**
     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param tokenId Identifier number of a token.
     * @param owner Address of the current owner of a token.
     */
    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC721InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC721InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param tokenId Identifier number of a token.
     */
    error ERC721InsufficientApproval(address operator, uint256 tokenId);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC721InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC721InvalidOperator(address operator);
}

/**
 * @dev Standard ERC-1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
 */
interface IERC1155Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     * @param tokenId Identifier number of a token.
     */
    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC1155InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC1155InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param owner Address of the current owner of a token.
     */
    error ERC1155MissingApprovalForAll(address operator, address owner);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC1155InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC1155InvalidOperator(address operator);

    /**
     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
     * Used in batch transfers.
     * @param idsLength Length of the array of token identifiers
     * @param valuesLength Length of the array of token amounts
     */
    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
          

@openzeppelin/contracts/token/ERC20/IERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-20 standard as defined in the ERC.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}
          

@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC-20 standard.
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}
          

@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol

pragma solidity >=0.6.2;

import './IUniswapV2Router01.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;
}
          

contracts/ERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.2.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {Context} from "@openzeppelin/contracts/utils/Context.sol";
import {IERC20Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * The default value of {decimals} is 18. To change this, you should override
 * this function so it returns a different value.
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC-20
 * applications.
 */
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
    mapping(address account => uint256) private _balances;

    mapping(address account => mapping(address spender => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual 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 default value returned by this function, unless
     * it's overridden.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `value`.
     */
    function transfer(address to, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, value);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, value);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Skips emitting an {Approval} event indicating an allowance update. This is not
     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `value`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `value`.
     */
    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, value);
        _transfer(from, to, value);
        return true;
    }

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _transfer(address from, address to, uint256 value) internal virtual {
        if (from == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        if (to == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(from, to, value);
    }

    /**
     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
     * this function.
     *
     * Emits a {Transfer} event.
     */
    function _update(address from, address to, uint256 value) internal virtual {
        if (from == address(0)) {
            // Overflow check required: The rest of the code assumes that totalSupply never overflows
            _totalSupply += value;
        } else {
            uint256 fromBalance = _balances[from];
            if (fromBalance < value) {
                revert ERC20InsufficientBalance(from, fromBalance, value);
            }
            unchecked {
                // Overflow not possible: value <= fromBalance <= totalSupply.
                _balances[from] = fromBalance - value;
            }
        }

        if (to == address(0)) {
            unchecked {
                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
                _totalSupply -= value;
            }
        } else {
            unchecked {
                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
                _balances[to] += value;
            }
        }

        emit Transfer(from, to, value);
    }

    /**
     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
     * Relies on the `_update` mechanism
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _mint(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(address(0), account, value);
    }

    /**
     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
     * Relies on the `_update` mechanism.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead
     */
    function _burn(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        _update(account, address(0), value);
    }

    /**
     * @dev Sets `value` 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.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */
    function _approve(address owner, address spender, uint256 value) internal {
        _approve(owner, spender, value, true);
    }

    /**
     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
     *
     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
     * `Approval` event during `transferFrom` operations.
     *
     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
     * true using the following override:
     *
     * ```solidity
     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
     *     super._approve(owner, spender, value, true);
     * }
     * ```
     *
     * Requirements are the same as {_approve}.
     */
    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
        if (owner == address(0)) {
            revert ERC20InvalidApprover(address(0));
        }
        if (spender == address(0)) {
            revert ERC20InvalidSpender(address(0));
        }
        _allowances[owner][spender] = value;
        if (emitEvent) {
            emit Approval(owner, spender, value);
        }
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `value`.
     *
     * Does not update the allowance value in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Does not emit an {Approval} event.
     */
    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance < type(uint256).max) {
            if (currentAllowance < value) {
                revert ERC20InsufficientAllowance(spender, currentAllowance, value);
            }
            unchecked {
                _approve(owner, spender, currentAllowance - value, false);
            }
        }
    }
}
          

contracts/icaria/IcariaRYManager.sol

//
//
//
//       ██╗ ██████╗ █████╗ ██████╗ ██╗ █████╗     ███████╗ ██████╗ ██████╗  ██████╗ ███████╗
//       ██║██╔════╝██╔══██╗██╔══██╗██║██╔══██╗    ██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██╔════╝
//       ██║██║     ███████║██████╔╝██║███████║    █████╗  ██║   ██║██████╔╝██║  ███╗█████╗  
//       ██║██║     ██╔══██║██╔══██╗██║██╔══██║    ██╔══╝  ██║   ██║██╔══██╗██║   ██║██╔══╝  
//       ██║╚██████╗██║  ██║██║  ██║██║██║  ██║    ██║     ╚██████╔╝██║  ██║╚██████╔╝███████╗
//       ╚═╝ ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝╚═╝  ╚═╝    ╚═╝      ╚═════╝ ╚═╝  ╚═╝ ╚═════╝ ╚══════╝
//                                                                                 
//     
//                                                                             
// Forge
// Web: https://forge.icaria.pro
// Tg:  https://t.me/icariaforge 
// 
// Icaria
// Web: https://icaria.pro
// Tg:  https://t.me/icarusprc20
// X:   https://x.com/IcarusPRC20     
//

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import { IERC20 }from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IIcariaHelpers } from "./interfaces/IIcariaHelpers.sol";

contract IcariaRYManager {
    // For yield tax tokens
    struct YieldToken {
        address tokenAddress;
        uint256 reflectionsPerShareAmount;
    }
    
    YieldToken[] internal yieldTokens;
    mapping(address => uint256[]) internal yieldTokenReflectionDebts;
    
    uint256 internal reflectionsPerShareAmount;
    mapping(address => uint256) internal reflectionDebt;
    mapping(address => bool) public isReflectionExcluded;
    uint256 internal PRECISION;
    address internal helpers;
    mapping(address => mapping(address => UserYield)) internal userYields;
    
    struct UserYield {
        uint256 reflectionDebt;
    }

    constructor(address _helpers) {
        PRECISION = 10**28;
        helpers = _helpers;
    }
    
    bool internal inSwap;
    
    modifier lockSwap() {
      inSwap = true;
      _;
      inSwap = false;
    }

    // ------------------------------------------ REFLECTIONS -------------------------------------------------//
    function getCurrentReflectionsPerShareAmount() external view returns (uint256) {
      return reflectionsPerShareAmount;
    }
    
    function isExcludedFromReflections(address account) public view returns (bool) {
      return isReflectionExcluded[account];
    }
    
    function pendingReflections(address account) public view returns (uint256) {
      if (isExcludedFromReflections(account)) {
        return 0;
      }
      return cleanPendingReflections(account);
    }

    function cleanPendingReflections(address account) internal view returns (uint256) {
      return IIcariaHelpers(helpers).cleanPendingReflections(
        account,
        address(this),
        reflectionsPerShareAmount,
        reflectionDebt[account],
        PRECISION
      );
    }


    function updateAndClaimReflections(address from, address to, address deployer) internal returns (uint256 fromAmount, uint256 toAmount, uint256 deployerAmount) {
        if (from == to) {
          fromAmount = isExcludedFromReflections(from) ? 0 : pendingReflections(from);
          toAmount = 0; // Set to zero to avoid double claiming
        } else {
          fromAmount = isExcludedFromReflections(from) ? 0 : pendingReflections(from);
          toAmount = isExcludedFromReflections(to) ? 0 : pendingReflections(to);
        }
        deployerAmount = cleanPendingReflections(deployer);
        reflectionDebt[deployer] = reflectionsPerShareAmount;
        reflectionDebt[from] = reflectionsPerShareAmount;
        reflectionDebt[to] = reflectionsPerShareAmount;
    }

    // function tokenPendingReflections() public view returns (uint256) {
    //     uint256 currentBalance = IERC20(address(this)).balanceOf(address(this));
    //     uint256 newReflectionDebt = reflectionsPerShareAmount;
    //     if (newReflectionDebt <= reflectionDebt[address(this)]) {
    //         return 0;
    //     }
    //     return (newReflectionDebt - reflectionDebt[address(this)]) * currentBalance / PRECISION;
    // }
    
    // ------------------------------------------ YIELD TOKENS REFLECTIONS -------------------------------------------------//
    
    function addYieldToken(address tokenAddress) internal returns (uint256 tokenIndex) {
      for (uint256 i = 0; i < yieldTokens.length; i++) {
        if (yieldTokens[i].tokenAddress == tokenAddress) {
          return i;
        }
      }
      
      yieldTokens.push(YieldToken({
        tokenAddress: tokenAddress,
        reflectionsPerShareAmount: 0
      }));
      
      return yieldTokens.length - 1;
    }
    
    function pendingYields(address account, uint256 tokenIndex) public view returns (uint256) {
      if (tokenIndex >= yieldTokenReflectionDebts[account].length) {
        return 0;
      }
      return IIcariaHelpers(helpers).pendingYields(
        account,
        address(this),
        yieldTokens[tokenIndex].reflectionsPerShareAmount,
        yieldTokenReflectionDebts[account][tokenIndex],
        PRECISION
      );
    }
    
    function updateAndClaimYield(address from, address to, address deployer) internal  {
      for (uint256 i = 0; i < yieldTokens.length; i++) {
        while (yieldTokenReflectionDebts[from].length <= i) {
          yieldTokenReflectionDebts[from].push(yieldTokens[i].reflectionsPerShareAmount);
        }
        while (yieldTokenReflectionDebts[to].length <= i) {
          yieldTokenReflectionDebts[to].push(yieldTokens[i].reflectionsPerShareAmount);
        }
        while (yieldTokenReflectionDebts[deployer].length <= i) {
          yieldTokenReflectionDebts[deployer].push(yieldTokens[i].reflectionsPerShareAmount);
        }
        
        uint256 fromAmount = isExcludedFromReflections(from) ? 0 : pendingYields(from, i);
        uint256 toAmount = 0;  // Initialize to 0
        uint256 deployerAmount = 0;  // Initialize to 0
        
        if (from != to) {
          toAmount = isExcludedFromReflections(to) ? 0 : pendingYields(to, i);
        }
        if (from != deployer && to != deployer) {
          deployerAmount = isExcludedFromReflections(deployer) ? 0 : pendingYields(deployer, i);
        }

        uint256[] memory transferAmounts = new uint256[](3);
        address[] memory recipients = new address[](3);
        uint256 recipientCount = 0;
        if (deployerAmount > 0) {
          transferAmounts[recipientCount] = deployerAmount;
          recipients[recipientCount] = deployer;
          recipientCount++;
        }
        if (fromAmount > 0) {
          transferAmounts[recipientCount] = fromAmount;
          recipients[recipientCount] = from;
          recipientCount++;
        }
        if (toAmount > 0) {
          transferAmounts[recipientCount] = toAmount;
          recipients[recipientCount] = to;
          recipientCount++;
        }

        for (uint256 j = 0; j < recipientCount; j++) {
          if(transferAmounts[j] > 0){
            try IERC20(yieldTokens[i].tokenAddress).transfer(recipients[j], transferAmounts[j]) {
              yieldTokenReflectionDebts[recipients[j]][i] = yieldTokens[i].reflectionsPerShareAmount;
            } catch {

            }
          }
        }
      }
    }
    
    function getYieldTokens() public view returns (YieldToken[] memory) {
      return yieldTokens;
    }

    function getYieldTokenReflectionDebts(address account) public view returns (uint256[] memory) {
      return yieldTokenReflectionDebts[account];
    }
    

    // function getYieldsPerShare(uint256 index) public view returns (uint256)   {
    //     return yieldTokens[index].reflectionsPerShareAmount;
    // }
    
    // ------------------------------------------ END REFLECTIONS -----------------------------------------------//

    //-------------------------------------------- HELPERS FUNCTIONS -------------------------------------------------//
    //   function excludeFromReflections(address account) external onlyOwner {
    //     require(!isExcludedFromReflections(account), "Account already excluded");
    //     isReflectionExcluded[account] = true;
    //     updateAndClaimReflections(account);
    //   }

    

    //   function includeInReflections(address account) external onlyOwner {
    //     require(isReflectionExcluded[account], "Not excluded");
    //     isReflectionExcluded[account] = false;
    //     reflectionDebt[account] = (balanceOf(account) * reflectionsPerShareAmount) / PRECISION;
    //   }

}
          

contracts/icaria/interfaces/IIcariaHelpers.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface IIcariaHelpers {
    enum TaxType { Burn, ExternalBurn, Dev, Reflection, Yield }
    enum TaxMoment { Both, Buy, Sell }

    struct Tax {
        uint256 id;
        TaxType taxType;
        TaxMoment taxMoment;
        uint256 percentage;
        address receiver;
        address tokenAddress;
        address burnAddress;
        bool rewardInPls;
        uint256 amountAccumulated;
    }

    function getBestPair(
        address tokenA, 
        address tokenB, 
        address[] memory routers
    ) external view returns (address bestPair, address bestRouter);

    function isPair(address _address, address _tokenAddress) external view returns (bool);

    function isBuy(address _from, address _to, address _tokenAddress) external view returns (bool);

    function isSell(address _from, address _to, address _tokenAddress) external view returns (bool);

    function getTokenWPLSPath(address tokenAddress) external pure returns (address[] memory path);

    function getWPLSBuyBurnPath(address tokenAddress) external pure returns (address[] memory path);

    function getProcessingAmount(
        uint256 accumulatedAmount, 
        uint256 currentSwapAmount
    ) external pure returns (uint256 processAmount, uint256 newAccumulatedAmount);
    
    function calculateTaxAmount(
        uint256 originalAmount, 
        uint256 taxPercentage, 
        uint256 icariaFee, 
        bool icariaFeeEnabled,
        uint256 globalDivider
    ) external pure returns (uint256 taxAmount, uint256 icariaFeeAmount);
    
    function hasAccumulatedTaxes(Tax[] memory taxes) external pure returns (bool);
    
    function getTotalTaxs(Tax[] memory taxes) external pure returns (uint256);
    
    function cleanPendingReflections(
        address account,
        address tokenAddress,
        uint256 reflectionsPerShareAmount,
        uint256 reflectionDebt,
        uint256 precision
    ) external view returns (uint256);
    
    function pendingYields(
        address account, 
        address tokenAddress,
        uint256 reflectionsPerShareAmount,
        uint256 reflectionDebt,
        uint256 precision
    ) external view returns (uint256);

    function isExcludedFromTax(
        address from, 
        address to, 
        address icariaSmartTrader, 
        address deployer,
        address thisContract
    ) external pure returns (bool);

    function taxesInitialize(IIcariaHelpers.Tax[] memory _taxes) external pure returns (bool, bool, bool, IIcariaHelpers.Tax[] memory, address[] memory);

    function isDeadAddress(address _address) external pure returns (bool);

}
          

contracts/icaria/interfaces/IIcariaSmartTokenFactory.sol

//
//
//
//       ██╗ ██████╗ █████╗ ██████╗ ██╗ █████╗     ███████╗ ██████╗ ██████╗  ██████╗ ███████╗
//       ██║██╔════╝██╔══██╗██╔══██╗██║██╔══██╗    ██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██╔════╝
//       ██║██║     ███████║██████╔╝██║███████║    █████╗  ██║   ██║██████╔╝██║  ███╗█████╗  
//       ██║██║     ██╔══██║██╔══██╗██║██╔══██║    ██╔══╝  ██║   ██║██╔══██╗██║   ██║██╔══╝  
//       ██║╚██████╗██║  ██║██║  ██║██║██║  ██║    ██║     ╚██████╔╝██║  ██║╚██████╔╝███████╗
//       ╚═╝ ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝╚═╝  ╚═╝    ╚═╝      ╚═════╝ ╚═╝  ╚═╝ ╚═════╝ ╚══════╝
//                                                                                 
//     
//                                                                             
// Forge
// Web: https://forge.icaria.pro
// Tg:  https://t.me/icariaforge 
// 
// Icaria
// Web: https://icaria.pro
// Tg:  https://t.me/icarusprc20
// X:   https://x.com/IcarusPRC20     
//

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface IIcariaSmartTokenFactory {
  function ICARIA_FEE() external view returns (uint256);
  function ICARIA_WALLET() external view returns (address);
}
          

contracts/icaria/interfaces/IIcariaSmartTrader.sol

//
//
//
//       ██╗ ██████╗ █████╗ ██████╗ ██╗ █████╗     ███████╗ ██████╗ ██████╗  ██████╗ ███████╗
//       ██║██╔════╝██╔══██╗██╔══██╗██║██╔══██╗    ██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██╔════╝
//       ██║██║     ███████║██████╔╝██║███████║    █████╗  ██║   ██║██████╔╝██║  ███╗█████╗  
//       ██║██║     ██╔══██║██╔══██╗██║██╔══██║    ██╔══╝  ██║   ██║██╔══██╗██║   ██║██╔══╝  
//       ██║╚██████╗██║  ██║██║  ██║██║██║  ██║    ██║     ╚██████╔╝██║  ██║╚██████╔╝███████╗
//       ╚═╝ ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝╚═╝  ╚═╝    ╚═╝      ╚═════╝ ╚═╝  ╚═╝ ╚═════╝ ╚══════╝
//                                                                                 
//     
//                                                                             
// Forge
// Web: https://forge.icaria.pro
// Tg:  https://t.me/icariaforge 
// 
// Icaria
// Web: https://icaria.pro
// Tg:  https://t.me/icarusprc20
// X:   https://x.com/IcarusPRC20     
//

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface IIcariaSmartTrader {
  function swapExactTokensForTokensSupportingFeeOnTransferTokens(
    address _router,
    address _receiver,
    uint256 amountIn,
    address[] memory path
  ) external;
  
  function swapExactTokensForETHSupportingFeeOnTransferTokens(
    address _router,
    address _receiver,
    uint256 amountIn,
    address[] calldata path
  ) external;
}
          

contracts/icaria/interfaces/IWETH.sol

//
//
//
//       ██╗ ██████╗ █████╗ ██████╗ ██╗ █████╗     ███████╗ ██████╗ ██████╗  ██████╗ ███████╗
//       ██║██╔════╝██╔══██╗██╔══██╗██║██╔══██╗    ██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██╔════╝
//       ██║██║     ███████║██████╔╝██║███████║    █████╗  ██║   ██║██████╔╝██║  ███╗█████╗  
//       ██║██║     ██╔══██║██╔══██╗██║██╔══██║    ██╔══╝  ██║   ██║██╔══██╗██║   ██║██╔══╝  
//       ██║╚██████╗██║  ██║██║  ██║██║██║  ██║    ██║     ╚██████╔╝██║  ██║╚██████╔╝███████╗
//       ╚═╝ ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝╚═╝  ╚═╝    ╚═╝      ╚═════╝ ╚═╝  ╚═╝ ╚═════╝ ╚══════╝
//                                                                                 
//     
//                                                                             
// Forge
// Web: https://forge.icaria.pro
// Tg:  https://t.me/icariaforge 
// 
// Icaria
// Web: https://icaria.pro
// Tg:  https://t.me/icarusprc20
// X:   https://x.com/IcarusPRC20     
//

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface IWETH {
  function withdraw(uint256 wad) external;
}
          

Compiler Settings

{"viaIR":true,"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata"],"":["ast"]}},"optimizer":{"runs":20,"enabled":true},"libraries":{},"evmVersion":"paris"}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"string","name":"name_","internalType":"string"},{"type":"string","name":"symbol_","internalType":"string"},{"type":"address","name":"_owner","internalType":"address"},{"type":"address","name":"_mintTo","internalType":"address"},{"type":"uint256","name":"_initialSupply","internalType":"uint256"},{"type":"tuple[]","name":"_taxes","internalType":"struct IIcariaHelpers.Tax[]","components":[{"type":"uint256","name":"id","internalType":"uint256"},{"type":"uint8","name":"taxType","internalType":"enum IIcariaHelpers.TaxType"},{"type":"uint8","name":"taxMoment","internalType":"enum IIcariaHelpers.TaxMoment"},{"type":"uint256","name":"percentage","internalType":"uint256"},{"type":"address","name":"receiver","internalType":"address"},{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"address","name":"burnAddress","internalType":"address"},{"type":"bool","name":"rewardInPls","internalType":"bool"},{"type":"uint256","name":"amountAccumulated","internalType":"uint256"}]},{"type":"address","name":"_icariaSmartTrader","internalType":"address"},{"type":"address","name":"_factory","internalType":"address"},{"type":"address","name":"_helpers","internalType":"address"}]},{"type":"error","name":"ERC20InsufficientAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"allowance","internalType":"uint256"},{"type":"uint256","name":"needed","internalType":"uint256"}]},{"type":"error","name":"ERC20InsufficientBalance","inputs":[{"type":"address","name":"sender","internalType":"address"},{"type":"uint256","name":"balance","internalType":"uint256"},{"type":"uint256","name":"needed","internalType":"uint256"}]},{"type":"error","name":"ERC20InvalidApprover","inputs":[{"type":"address","name":"approver","internalType":"address"}]},{"type":"error","name":"ERC20InvalidReceiver","inputs":[{"type":"address","name":"receiver","internalType":"address"}]},{"type":"error","name":"ERC20InvalidSender","inputs":[{"type":"address","name":"sender","internalType":"address"}]},{"type":"error","name":"ERC20InvalidSpender","inputs":[{"type":"address","name":"spender","internalType":"address"}]},{"type":"error","name":"OwnableInvalidOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorizedAccount","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addTaxExclusion","inputs":[{"type":"address","name":"_address","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"claimYield","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"forceProcessAccumulatedTaxes","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getAccumulatedIcariaFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getCurrentReflectionsPerShareAmount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getIcariaFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getIcariaWallet","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct IIcariaHelpers.Tax[]","components":[{"type":"uint256","name":"id","internalType":"uint256"},{"type":"uint8","name":"taxType","internalType":"enum IIcariaHelpers.TaxType"},{"type":"uint8","name":"taxMoment","internalType":"enum IIcariaHelpers.TaxMoment"},{"type":"uint256","name":"percentage","internalType":"uint256"},{"type":"address","name":"receiver","internalType":"address"},{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"address","name":"burnAddress","internalType":"address"},{"type":"bool","name":"rewardInPls","internalType":"bool"},{"type":"uint256","name":"amountAccumulated","internalType":"uint256"}]}],"name":"getTaxes","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTotalTaxs","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getYieldTokenReflectionDebts","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct IcariaRYManager.YieldToken[]","components":[{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"uint256","name":"reflectionsPerShareAmount","internalType":"uint256"}]}],"name":"getYieldTokens","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"initialSupply","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isExcludedFromReflections","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isReflectionExcluded","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"pendingReflections","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"pendingYields","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"uint256","name":"tokenIndex","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeTaxExclusion","inputs":[{"type":"address","name":"_address","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"id","internalType":"uint256"},{"type":"uint8","name":"taxType","internalType":"enum IIcariaHelpers.TaxType"},{"type":"uint8","name":"taxMoment","internalType":"enum IIcariaHelpers.TaxMoment"},{"type":"uint256","name":"percentage","internalType":"uint256"},{"type":"address","name":"receiver","internalType":"address"},{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"address","name":"burnAddress","internalType":"address"},{"type":"bool","name":"rewardInPls","internalType":"bool"},{"type":"uint256","name":"amountAccumulated","internalType":"uint256"}],"name":"taxes","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"tokenVersion","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"receive","stateMutability":"payable"}]
              

Contract Creation Code

0x60808060405234610bd257614123803803809161001c8285610bd7565b8339810161012082820312610bd25781516001600160401b038111610bd25781610047918401610bfa565b60208301519092906001600160401b038111610bd25782610069918301610bfa565b61007560408301610c69565b9361008260608401610c69565b608084015160a085015190959192916001600160401b038211610bd2576100aa918601610ca1565b956100b760c08601610c69565b936100d16101006100ca60e08901610c69565b9701610c69565b835190936001600160401b0382116109ed5760035490600182811c92168015610bc8575b6020831014610ae65781601f849311610b79575b50602090601f8311600114610b1157600092610b06575b50508160011b916000199060031b1c1916176003555b8051906001600160401b0382116109ed5760045490600182811c92168015610afc575b6020831014610ae65781601f849311610a8c575b50602090601f8311600114610a2457600092610a19575b50508160011b916000199060031b1c1916176004555b6001600160a01b0316908115610a0357600580546001600160a01b03198116841790915560405192906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a36b204fce5e3e25026110000000600b55600c80546001600160a01b03929092166001600160a01b03199283161790556013805473a1077a294dde1b09bb078844df40758a5d0f9a279216919091179055608081018181106001600160401b038211176109ed576040527398bf93ebf5c380c0e6ae8e192a7e2ae08edacc02815273165c3410fc91ef562c50559f7d2289febed552d9602082015273cc73b59f8d7b7c532703bdfea2808a28a488cf47604082015273eb45a3c4aedd0f47f345fb4c8a1802bb5740d72560608201526014546004601455806004106109a8575b50601460005260206000209060005b6004811061098b5750506018805460ff60201b19169055506001600160a01b03169283156109755760025481810180911161095f57600255600093808552846020526040852082815401905580857fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020604051868152a3601180546001600160a01b0319908116929092179055600f919091556010805482166001600160a01b03938416179055601280549091169290911691909117905581516103ae575b6040516132249081610edf8239f35b600160ff1960185416176018558060018060a01b03600c5416926040519384916316bc2cf360e21b83526024830160206004850152815180915260206044850192019085905b8082106108a95750505082809103915afa91821561089c578182908392849085966107a6575b5080519068010000000000000000821161079257601954826019558083106106e6575b506019865285907f944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9695906020015b8383106105de575050505062ff00009063ff00000061ff0060185492151560081b1694151560181b169063ffffff0019161791151560101b16171760185560018060a01b03601154168152601560205260408120600160ff19825416179055308152601560205260408120600160ff1982541617905560018060a01b03601054168152601560205260408120600160ff1982541617905560185460ff8160101c169081156105d0575b50610556575b805b825181101561054c57600581901b83016020015160019190610545906001600160a01b0316610dfd565b500161051b565b505050388061039f565b808052600a60205260408120600160ff19825416179055308152600a60205260408120600160ff19825416179055805b6014548110156105ca576000805160206141038339815191528101546001600160a01b03168252600a60205260408220805460ff1916600190811790915501610586565b50610519565b60ff915060181c1638610513565b80518051835560018301602082015160058110156106d2578154604084015160038110156106be5761ff0060089190911b1660ff9290921661ffff1991909116171790556060810151600284015560808101516003840180546001600160a01b039283166001600160a01b03199182161790915560a080840151600487018054918516919093161790915560c083015160058601805460e086015160ff60a01b90151590941b93909316919093166001600160a81b031990921691909117179055610100015160068301556001929092019160079091019060200161046a565b634e487b7160e01b8d52602160045260248dfd5b634e487b7160e01b8b52602160045260248bfd5b8060070290600782040361077e578260070260078104840361076a57601988527f944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c969591820191015b81811061073a575061043d565b8088600792558860018201558860028201558860038201558860048201558860058201558860068201550161072d565b634e487b7160e01b88526011600452602488fd5b634e487b7160e01b87526011600452602487fd5b634e487b7160e01b86526041600452602486fd5b9550505050503d8082843e6107bb8184610bd7565b82019160a081840312610898576107d181610c94565b6107dd60208301610c94565b6107e960408401610c94565b60608401519092906001600160401b038111610890578661080b918601610ca1565b608085015190946001600160401b03821161089457019580601f8801121561089057865161083881610c7d565b97610846604051998a610bd7565b8189526020808a019260051b82010192831161088c57602001905b828210610874575050509091923861041a565b6020809161088184610c69565b815201910190610861565b8780fd5b8580fd5b8680fd5b5080fd5b50604051903d90823e3d90fd5b929194509294508351805182526020810151600581101561094b5760208301526040810151600381101561094b5782610100602093610120936040600197015260608101516060840152858060a01b036080820151166080840152858060a01b0360a08201511660a0840152858060a01b0360c08201511660c084015260e0810151151560e084015201516101008201520194019201918594928794926103f4565b634e487b7160e01b88526021600452602488fd5b634e487b7160e01b600052601160045260246000fd5b63ec442f0560e01b600052600060045260246000fd5b81516001600160a01b0316818401556020909101906001016102df565b60146000526109e790600080516020614103833981519152017fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4f0610db1565b386102d0565b634e487b7160e01b600052604160045260246000fd5b631e4fbdf760e01b600052600060045260246000fd5b015190503880610184565b600460009081528281209350601f198516905b818110610a745750908460019594939210610a5b575b505050811b0160045561019a565b015160001960f88460031b161c19169055388080610a4d565b92936020600181928786015181550195019301610a37565b6004600052610ad6907f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b601f850160051c81019160208610610adc575b601f0160051c0190610db1565b3861016d565b9091508190610ac9565b634e487b7160e01b600052602260045260246000fd5b91607f1691610159565b015190503880610120565b600360009081528281209350601f198516905b818110610b615750908460019594939210610b48575b505050811b01600355610136565b015160001960f88460031b161c19169055388080610b3a565b92936020600181928786015181550195019301610b24565b6003600052610bc2907fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b601f850160051c81019160208610610adc57601f0160051c0190610db1565b38610109565b91607f16916100f5565b600080fd5b601f909101601f19168101906001600160401b038211908210176109ed57604052565b81601f82011215610bd2578051906001600160401b0382116109ed5760405192610c2e601f8401601f191660200185610bd7565b82845260208383010111610bd25760005b828110610c5457505060206000918301015290565b80602080928401015182828701015201610c3f565b51906001600160a01b0382168203610bd257565b6001600160401b0381116109ed5760051b60200190565b51908115158203610bd257565b81601f82011215610bd257805190610cb882610c7d565b92610cc66040519485610bd7565b8284526020610120818601940283010191818311610bd257602001925b828410610cf1575050505090565b61012084830312610bd2576040519061012082016001600160401b038111838210176109ed576040528451825260208501516005811015610bd25760208301526040850151906003821015610bd25782602092604061012095015260608701516060820152610d6260808801610c69565b6080820152610d7360a08801610c69565b60a0820152610d8460c08801610c69565b60c0820152610d9560e08801610c94565b60e0820152610100870151610100820152815201930192610ce3565b818110610dbc575050565b60008155600101610db1565b600654811015610de757600660005260206000209060011b0190600090565b634e487b7160e01b600052603260045260246000fd5b6006549060005b828110610eb3575060408051919082016001600160401b038111838210176109ed576040526001600160a01b0316815260006020820190815291680100000000000000008110156109ed57806001610e5f9201600655610dc8565b929092610e9d57905182546001600160a01b0319166001600160a01b03919091161782555160019190910155600654600019810190811161095f5790565b634e487b7160e01b600052600060045260246000fd5b610ebc81610dc8565b50546001600160a01b03838116911614610ed857600101610e04565b9150509056fe608080604052600436101561001d575b50361561001b57600080fd5b005b60003560e01c90816306fdde0314610c0957508063095ea7b314610be357806318160ddd14610bc557806323b872dd14610ad85780632973ef2d14610993578063313ce56714610977578063378dc3dc14610959578063406cf229146109315780634f30800d1461091357806356cdad1d146108f55780635f75baf6146108da578063695d69b3146108b75780636a2072d4146107fd578063709df63c1461070a57806370a08231146106d0578063715018a6146106735780638453ef99146106525780638da5cb5b146106295780639045be581461029957806395d89b41146105225780639b165f4e146104dd578063a9059cbb146104ac578063c5be2bc7146103f1578063cb78c16314610358578063dd62ed3e14610307578063e4f8d62e146102d8578063e6375d3e14610299578063eb50c06114610257578063f2fde38b146101cd578063f56b4d05146101a05763fec4ff171461017f573861000f565b3461019b57600036600319011261019b57602060405160018152f35b600080fd5b3461019b57600036600319011261019b5760206101bb611120565b6040516001600160a01b039091168152f35b3461019b57602036600319011261019b576101e6610d0d565b6101ee611c90565b6001600160a01b0316801561024157600580546001600160a01b0319811683179091556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b631e4fbdf760e01b600052600060045260246000fd5b3461019b57602036600319011261019b57610270610d0d565b610278611c90565b6001600160a01b03166000908152601560205260409020805460ff19169055005b3461019b57602036600319011261019b576001600160a01b036102ba610d0d565b16600052600a602052602060ff604060002054166040519015158152f35b3461019b57604036600319011261019b5760206102ff6102f6610d0d565b6024359061106b565b604051908152f35b3461019b57604036600319011261019b57610320610d0d565b610328610d23565b6001600160a01b039182166000908152600160209081526040808320949093168252928352819020549051908152f35b3461019b57600036600319011261019b57600c54604051625f8d8f60e81b81529060209082906001600160a01b0316818061039560048201610f46565b03915afa80156103e5576000906103b2575b602090604051908152f35b506020813d6020116103dd575b816103cc60209383610dcf565b8101031261019b57602090516103a7565b3d91506103bf565b6040513d6000823e3d90fd5b3461019b57602036600319011261019b5760043560195481101561019b5761041b61012091610d69565b5080549060ff600182015491600281015460018060a01b0360038301541660018060a01b0360048401541691610479600660058601549501549660405198895261046a60208a01888316610d39565b8660408a019160081c16610d5c565b6060870152608086015260a0808601919091526001600160a01b03821660c08601521c16151560e0830152610100820152f35b3461019b57604036600319011261019b576104d26104c8610d0d565b602435903361118c565b602060405160018152f35b3461019b57602036600319011261019b576104f6610d0d565b6104fe611c90565b6001600160a01b03166000908152601560205260409020805460ff19166001179055005b3461019b57600036600319011261019b5760405160006004548060011c9060018116801561061f575b60208310811461060b578285529081156105e75750600114610588575b6105848361057881850382610dcf565b60405191829182610cc4565b0390f35b600460009081527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b939250905b8082106105cd57509091508101602001610578610568565b9192600181602092548385880101520191019092916105b5565b60ff191660208086019190915291151560051b840190910191506105789050610568565b634e487b7160e01b84526022600452602484fd5b91607f169161054b565b3461019b57600036600319011261019b576005546040516001600160a01b039091168152602090f35b3461019b57600036600319011261019b5761066b611c90565b61001b611cb9565b3461019b57600036600319011261019b5761068c611c90565b600580546001600160a01b031981169091556000906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461019b57602036600319011261019b576001600160a01b036106f1610d0d565b1660005260006020526020604060002054604051908152f35b3461019b57600036600319011261019b5760065461072781610df0565b906107356040519283610dcf565b808252600660009081526020830191907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f835b8383106107c95784866040519182916020830190602084525180915260408301919060005b81811061079b575050500390f35b825180516001600160a01b03168552602090810151818601528695506040909401939092019160010161078d565b600260206001926040516107dc81610d9e565b848060a01b0386541681528486015483820152815201920192019190610768565b3461019b57602036600319011261019b576001600160a01b0361081e610d0d565b16600052600760205260406000206040518060208354918281520190819360005260206000209060005b8181106108a1575050508161085e910382610dcf565b6040519182916020830190602084525180915260408301919060005b818110610888575050500390f35b825184528594506020938401939092019160010161087a565b8254845260209093019260019283019201610848565b3461019b57602036600319011261019b5760206102ff6108d5610d0d565b610f14565b3461019b57600036600319011261019b5760206102ff610ead565b3461019b57600036600319011261019b576020601754604051908152f35b3461019b57600036600319011261019b576020600854604051908152f35b3461019b57600036600319011261019b576011546104d2906001600160a01b031633806118d0565b3461019b57600036600319011261019b576020600f54604051908152f35b3461019b57600036600319011261019b57602060405160128152f35b3461019b57600036600319011261019b576019546109b081610df0565b906109be6040519283610dcf565b808252601960009081526020830191907f944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9695835b838310610aba5784866040519182916020830190602084525180915260408301919060005b818110610a24575050500390f35b919350916020610120600192610100875180518352610a498582015186850190610d39565b610a5b60408201516040850190610d5c565b60608101516060840152858060a01b036080820151166080840152858060a01b0360a08201511660a0840152858060a01b0360c08201511660c084015260e0810151151560e08401520151610100820152019401910191849392610a16565b60076020600192610aca85610e07565b8152019201920191906109f1565b3461019b57606036600319011261019b57610af1610d0d565b610af9610d23565b6001600160a01b0382166000818152600160209081526040808320338452909152902054909260443592916000198110610b39575b506104d2935061118c565b838110610ba8578415610b92573315610b7c576104d2946000526001602052604060002060018060a01b0333166000526020528360406000209103905584610b2e565b634a1406b160e11b600052600060045260246000fd5b63e602df0560e01b600052600060045260246000fd5b8390637dc7a0d960e11b6000523360045260245260445260646000fd5b3461019b57600036600319011261019b576020600254604051908152f35b3461019b57604036600319011261019b576104d2610bff610d0d565b6024359033611ce5565b3461019b57600036600319011261019b5760006003548060011c90600181168015610cba575b60208310811461060b578285529081156105e75750600114610c5b576105848361057881850382610dcf565b600360009081527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b939250905b808210610ca057509091508101602001610578610568565b919260018160209254838588010152019101909291610c88565b91607f1691610c2f565b91909160208152825180602083015260005b818110610cf7575060409293506000838284010152601f8019910116010190565b8060208092870101516040828601015201610cd6565b600435906001600160a01b038216820361019b57565b602435906001600160a01b038216820361019b57565b906005821015610d465752565b634e487b7160e01b600052602160045260246000fd5b906003821015610d465752565b601954811015610d885760196000526007602060002091020190600090565b634e487b7160e01b600052603260045260246000fd5b604081019081106001600160401b03821117610db957604052565b634e487b7160e01b600052604160045260246000fd5b90601f801991011681019081106001600160401b03821117610db957604052565b6001600160401b038111610db95760051b60200190565b9060405161012081018181106001600160401b03821117610db957604052809280548252600181015460ff8116906005821015610d465760ff91602085015260081c166003811015610d465760408301526002810154606083015260038101546001600160a01b0390811660808401526004820154811660a080850191909152600583015491821660c08501521c60ff16151560e0830152600601546101009190910152565b60125460405163441062ed60e01b815290602090829060049082906001600160a01b03165afa9081156103e557600091610ee5575090565b90506020813d602011610f0c575b81610f0060209383610dcf565b8101031261019b575190565b3d9150610ef3565b6001600160a01b0381166000908152600a602052604090205460ff16610f4057610f3d90611c42565b90565b50600090565b60406020820191602081526019548093520190601960005260206000209060005b818110610f745750505090565b909192600761012060019286548152610faa84880154610f9a6020840160ff8316610d39565b60ff604084019160081c16610d5c565b60028701546060820152600387015460a085811b86900391821660808401526004890154821681840152600589015491821660c08401521c60ff16151560e08201526006870154610100820152019401929101610f67565b600654811015610d8857600660005260206000209060011b0190600090565b8054821015610d885760005260206000200190600090565b6001600160a01b0391821681529116602082015260408101919091526060810191909152608081019190915260a00190565b6001600160a01b038116600081815260076020526040902054919291821015611104576020916110c060018060a01b03600c54169160016110ab82611002565b50015493600052600785526040600020611021565b90549060031b1c91600b54946110ee6040519687958694859463a89055e560e01b8652309060048701611039565b03915afa9081156103e557600091610ee5575090565b505050600090565b51906001600160a01b038216820361019b57565b6012546040516327ab5d0f60e01b815290602090829060049082906001600160a01b03165afa9081156103e557600091611158575090565b90506020813d602011611184575b8161117360209383610dcf565b8101031261019b57610f3d9061110c565b3d9150611166565b6018805460ff60281b19169055600c54604051639ca7068f60e01b81526001600160a01b038085166004830181905294969495949260209183916024918391165afa9081156103e5576000916117fc575b506117f0576019541580156117e0575b80156117be575b80156117a6575b801561179a575b61174f5761120f85611e92565b80611736575b611718575b60168390556000948591825b60195484101561144b5761124261123c85610d69565b50610e07565b9360018060a01b03600c54169460608101519261125d610ead565b60ff601854169060405195632b8d28ef60e21b87528b60048801526024870152604486015215156064850152612710608485015260408460a4818a5afa9081156103e5576000948592611410575b50906112ba856112c093611ef1565b9b611ef1565b95604082018051916003831015610d46576000926112f0575050506112e8906001938861261e565b019296611226565b815160038110156113fc5760018b91149182611381575b50501561132257505061131d906001938861261e565b6112e8565b9392935190600382101561136d57506001939291906002148061135d575b61134c575b50506112e8565b611356918861261e565b3880611345565b506113688689611f2e565b611340565b634e487b7160e01b81526021600452602490fd5b6113a99250906020918a604051809581948293636468b51760e01b8452309160048501611f0b565b03915afa9081156113f15783916113c3575b508938611307565b6113e4915060203d81116113ea575b6113dc8183610dcf565b81019061189d565b386113bb565b503d6113d2565b6040513d85823e3d90fd5b634e487b7160e01b84526021600452602484fd5b6112ba95506112c0925061143a9060403d8111611444575b6114328183610dcf565b81019061201b565b90959092506112ab565b503d611428565b611463935061145e9197929495836116d9575b611efe565b600c5460405163ca497e2360e01b8152949193919060209086906001600160a01b0316818061149460048201610f46565b03915afa80156103e5576114f7956000916116ba575b50806116ab575b8061169e575b8061168e575b61166e575b60ff60185460181c16611652575b60ff60185460101c16611516575b5060ff60185460081c1680611506575b6114f957611de3565b565b611501612031565b611de3565b506115118282611f2e565b6114ee565b6011546001600160a01b038381169291169060008382036115fc575082600052600a60205260ff604060002054166000146115ee5760005b906000925b61155c81611c42565b60085460009283526009602052604080842082905596835286832081905592825294902055806115d0575b50806115b2575b5080156114de576011546115ac91906001600160a01b031630611de3565b386114de565b6115bb84611e92565b61158e576115ca908430611de3565b3861158e565b6115d984611e92565b611587576115e8908430611de3565b38611587565b6115f784610f14565b61154e565b838152600a602052604081205460ff1615611643575b9080600052600a60205260ff604060002054166000146116355760005b92611553565b61163e86610f14565b61162f565b5061164d84610f14565b611612565b601154611669906001600160a01b031684846118d0565b6114d0565b611676611cb9565b6018805460ff60281b1916600160281b1790556114c2565b5060ff60185460281c16156114bd565b5060ff600e5416156114b7565b5060ff60185460201c166114b1565b6116d3915060203d6020116113ea576113dc8183610dcf565b386114aa565b60185460081c60ff1615611706576116f2843089611de3565b6116fe84601754611ef1565b601755611efe565b61145e84611712611120565b89611de3565b83600052600a6020526040600020600160ff1982541617905561121a565b5083600052600a60205260ff6040600020541615611215565b9380935061175d9291611de3565b6018549060ff8260201c1615908161178a575b506117785750565b60ff60201b1916600160201b17601855565b6117949150611e92565b38611770565b5060ff600e5416611202565b5083600052601560205260ff604060002054166111fb565b506001600160a01b03821660009081526015602052604090205460ff166111f4565b5060ff60185460201c16156111ed565b93506114f79250611d4c565b611815915060203d6020116113ea576113dc8183610dcf565b386111dd565b80549190600160401b831015610db9578261183e9160016114f795018155611021565b90919082549060031b91821b91600019901b1916179055565b805115610d885760200190565b8051821015610d885760209160051b010190565b60001981146118875760010190565b634e487b7160e01b600052601160045260246000fd5b9081602091031261019b5751801515810361019b5790565b6001600160a01b039091168152602081019190915260400190565b9192600092606092916080905b600654861015611c39575b6001600160a01b038316600081815260076020526040902054871061193057600052600760205261192b6040600020600161192289611002565b5001549061181b565b6118e8565b5093909192935b6001600160a01b03851660008181526007602052604090205487106119765760005260076020526119716040600020600161192289611002565b611937565b5093909192935b6001600160a01b03871660008181526007602052604090205487106119bc5760005260076020526119b76040600020600161192289611002565b61197d565b506001600160a01b0385166000818152600a602052604090205491969395929492939160ff1615611c29576000905b6000916001600160a01b03871683818403611c02575b6001600160a01b038c16938085141580611bf8575b611bc5575b60405193611a298986610dcf565b600385528b36602087013760405195611a428a88610dcf565b600387528c36602089013760009780611ba3575b505080611b7f575b505080611b55575b505060005b838110611a7f5750505050600101946118dd565b80611a8c60019284611864565b51611a98575b01611a6b565b611aeb6020611aa688611002565b505460a085901b85900390811690611abe8589611864565b511690611acb8588611864565b5191600060405180968195829463a9059cbb60e01b8452600484016118b5565b03925af19081611b39575b5015611a9257611b3482611b0988611002565b500154838060a01b03611b1c8488611864565b5116600052600760205261183e886040600020611021565b611a92565b611b509060203d81116113ea576113dc8183610dcf565b611af6565b908491611b668496611b7795611864565b52611b718285611864565b52611878565b913880611a66565b908691611b90611b9b949887611864565b52611b718287611864565b933880611a5e565b90919750611bb086611857565b52611bba86611857565b526001953880611a56565b945083600052600a60205260ff60406000205416600014611be95760005b94611a1b565b611bf3868d61106b565b611be3565b5084831415611a16565b818152600a60205260ff604082205416600003611a015750611c24858961106b565b611a01565b611c33828561106b565b906119eb565b95505050505050565b602060018060a01b03600c54166008549060018060a01b0384166000526009835260406000205491600b54946110ee60405196879586948594631d2fa43b60e11b8652309060048701611039565b6005546001600160a01b03163303611ca457565b63118cdaa760e01b6000523360045260246000fd5b600e5460ff8116611ce25760ff1916600117600e55611cd66121b0565b60ff19600e5416600e55565b50565b6001600160a01b0316908115610b92576001600160a01b0316918215610b7c5760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918360005260018252604060002085600052825280604060002055604051908152a3565b6001600160a01b03168015611dcd57600091818352826020526040832054818110611db457817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef926020928587528684520360408620558060025403600255604051908152a3565b6064939263391434e360e21b8452600452602452604452fd5b634b637e8f60e11b600052600060045260246000fd5b6001600160a01b0316908115611dcd576001600160a01b0316918215611e7c576000828152806020526040812054828110611e625791604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef958760209652828652038282205586815280845220818154019055604051908152a3565b916064928463391434e360e21b8452600452602452604452fd5b63ec442f0560e01b600052600060045260246000fd5b600c54604051630d5c7b5d60e41b81526001600160a01b0392831660048201523060248201529160209183916044918391165afa9081156103e557600091611ed8575090565b610f3d915060203d6020116113ea576113dc8183610dcf565b9190820180921161188757565b9190820391821161188757565b6001600160a01b0391821681529181166020830152909116604082015260600190565b600c5460405163154b004960e31b81529260209284926001600160a01b03169183918291611f629130919060048501611f0b565b03915afa9081156103e557600091611ed8575090565b919082604091031261019b57610f3d6020611f928461110c565b930161110c565b6001600160a01b039182168152911660208201526060604082018190526014805491830182905260009081526080909201917fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec91905b818110611ffc5750505090565b82546001600160a01b0316845260209093019260019283019201611fef565b919082604091031261019b576020825192015190565b6017548015611ce257600c5460135460408051632a8ddb2f60e01b81526001600160a01b0393841694909390928491829161207191163060048401611f99565b0381865afa9182156103e55760009261214a575b506001600160a01b03821615612145576040906044601654918351958693849263059b6d4760e21b8452600484015260248301525afa80156103e55760009260009161211e575b5060175560105461210591906120ed9084906001600160a01b031630611ce5565b826120f6611120565b6120ff30612829565b926128ea565b1561210d5750565b61211990601754611ef1565b601755565b61210592935061213d915060403d604011611444576114328183610dcf565b9092916120cc565b505050565b61216d91925060403d604011612176575b6121658183610dcf565b810190611f78565b90509038612085565b503d61215b565b8181029291811591840414171561188757565b811561219a570490565b634e487b7160e01b600052601260045260246000fd5b60009081601954906121c182610df0565b906121cf6040519283610dcf565b828252601f196121de84610df0565b013660208401376121ee83610df0565b926121fc6040519485610dcf565b80845261220b601f1991610df0565b01366020850137845b6019548110156123725761222781610d69565b5060068101549081156123685760ff600182015416600581101580610d46576001821492831561233e575b50821561232d575b505061226c575b506001905b01612214565b600c546016546040805163059b6d4760e21b81526004810194909452602484019190915290829060449082906001600160a01b03165afa9081156103e557600090819261230c575b50806122d4575b509060019160066122cb83610d69565b50015590612261565b6122fe612304918493959960016122ec81978a611864565b52816122f8868b611864565b52611ef1565b97611878565b9290916122bb565b9050612326915060403d8111611444576114328183610dcf565b90386122b4565b909150610d4657600414388061225a565b6000935060028314915081612356575b509138612252565b60ff91506005015460a01c163861234e565b5050600190612266565b509392938315908115612615575b5061214557600c5460135460408051632a8ddb2f60e01b815292909183916001600160a01b0390811691839182916123bd91163060048401611f99565b03915afa9081156103e5576000916125f4575b506001600160a01b0381161561255e5760105461240f91906123fd9086906001600160a01b031630611ce5565b8461240730612829565b913090612995565b1561259b576013546040516370a0823160e01b8152306004820152929190602090849060249082906001600160a01b03165afa9283156103e557600093612564575b50821561255e5760005b6019548110156125575761246f8183611864565b51158015612545575b61253d57612499856124948661248e8588611864565b5161217d565b612190565b906124a381610d69565b5060ff600182015416926005841015610d46576001938481036124d957506124cd6124d392610e07565b90612eb4565b0161245b565b6000600282148061252c575b156125035750506124f86124fe92610e07565b90612d38565b6124d3565b50600414612513575b50506124d3565b61251f61252592610e07565b90612a23565b388061250c565b5060ff600585015460a01c166124e5565b6001906124d3565b506125508184611864565b5115612478565b5050505050565b50505050565b90926020823d602011612593575b8161257f60209383610dcf565b810103126125905750519138612451565b80fd5b3d9150612572565b92915060005b6019548110156125ee57806125b860019286611864565b516125c4575b016125a1565b6125ce8184611864565b516125e760066125dd84610d69565b5001918254611ef1565b90556125be565b50509050565b61260d915060403d604011612176576121658183610dcf565b9050386123d0565b90501538612380565b909160208101908151916005831015610d465760009261264557505050906114f791611d4c565b805160058110156113fc57859291906003036126ac57505061266c90612681933090611de3565b60406002549130815280602052205490611efe565b908161268b575050565b6126a79161249461269f92600b549061217d565b600854611ef1565b600855565b8091949392505160058110156127945760020361275357506080830180516001600160a01b031682526015602052604082205490919060ff161561272c575b5060e08301511561271657506125dd6127129261270c856006943090611de3565b51610d69565b9055565b516114f79392506001600160a01b031690611de3565b81516001600160a01b03168152601560205260409020805460ff19166001179055386126eb565b80949294516005811015612794576001036127735750506114f7926130b1565b5190600582101561136d575060041461278b57505050565b6114f7926130b1565b634e487b7160e01b83526021600452602483fd5b60208183031261019b578051906001600160401b03821161019b57019080601f8301121561019b5781516127db81610df0565b926127e96040519485610dcf565b81845260208085019260051b82010192831161019b57602001905b8282106128115750505090565b6020809161281e8461110c565b815201910190612804565b600c546040516343d7ef9f60e11b81526001600160a01b0392831660048201529160009183916024918391165afa9081156103e557600091612869575090565b610f3d91503d806000833e61287e8183610dcf565b8101906127a8565b60a091936020936080830195600180861b03168352600180851b03168483015260408201526080606082015284518094520192019060005b8181106128cb5750505090565b82516001600160a01b03168452602093840193909201916001016128be565b93929160009181158015612984575b61297c576010546129159083906001600160a01b031630611ce5565b6010546001600160a01b031690813b1561297857838095969761294e60405198899687958694630309079d60e31b865260048601612886565b03925af19182612968575b50906129625790565b50600190565b8161297291610dcf565b38612959565b8380fd5b509093505050565b506001600160a01b038616156128f9565b90929180158015612a12575b612a09576010546129bd9082906001600160a01b031630611ce5565b6010546001600160a01b031692833b1561019b576129ee91604051958694637e18437960e01b865260048601612886565b03825a9181600080958195f191826129685750906129625790565b50505050600090565b506001600160a01b038216156129a1565b60009181156121455760a00180516013549192916001600160a01b0391821691168114612d055750600c54601354835160408051632a8ddb2f60e01b815294936001600160a01b0393841693919286929182169183918291612a8a91168760048401611f99565b03915afa928315612cb1578593612cd9575b5060105460405163095ea7b360e01b815291602091839190829089908290612ad29089906001600160a01b0316600484016118b5565b03925af18015612cb157906024939291612cbc575b5083516040516370a0823160e01b81523060048201529360209185919082906001600160a01b03165afa928315612cb1578593612c79575b5060105484516001600160a01b039182169291612b3c91166131ae565b92823b15612c755791612b6c939187809460405196879586948593637e18437960e01b8552309060048601612886565b03925af19081612c61575b50612b8157505050565b81516040516370a0823160e01b81523060048201529190602090839060249082906001600160a01b03165afa8015612c56578490612c22575b612bc49250611efe565b9081612bcf57505050565b51612bfc90612be6906001600160a01b03166130e2565b9260406002549130815280602052205490611efe565b908115612145576125dd612c1c61271293612494600194600b549061217d565b93611002565b506020823d602011612c4e575b81612c3c60209383610dcf565b8101031261019b57612bc49151612bba565b3d9150612c2f565b6040513d86823e3d90fd5b84612c6e91959295610dcf565b9238612b77565b8680fd5b9092506020813d602011612ca9575b81612c9560209383610dcf565b81010312612ca557519138612b1f565b8480fd5b3d9150612c88565b6040513d87823e3d90fd5b612cd49060203d6020116113ea576113dc8183610dcf565b612ae7565b612ad291935082612cfa60209260403d604011612176576121658183610dcf565b905094925050612a9c565b612d14919250612be6906130e2565b9081612d1f57505050565b6125dd612c1c61271293612494600194600b549061217d565b906000908215612145576013546001600160a01b0316803b15612eb057828091602460405180948193632e1a7d4d60e01b83528960048401525af19081612e9c575b50612df45760135460809091015160405163a9059cbb60e01b81529360209285926001600160a01b0391821692849287928492612dbd92909116600484016118b5565b03925af1908115612de85750612dd05750565b611ce29060203d6020116113ea576113dc8183610dcf565b604051903d90823e3d90fd5b608001818080808660018060a01b038651165af13d15612e97573d6001600160401b038111612e835760405190612e35601f8201601f191660200183610dcf565b81528360203d92013e5b15612e4957505050565b601354905160405163a9059cbb60e01b81529360209285926001600160a01b0391821692849287928492612dbd92909116600484016118b5565b634e487b7160e01b84526041600452602484fd5b612e3f565b83612ea991949294610dcf565b9138612d7a565b8280fd5b9060009082156121455760a0810180516013549192916001600160a01b039081169116811461307a5750600c54601354835160408051632a8ddb2f60e01b815294936001600160a01b0393841693919286929182169183918291612f1d91168760048401611f99565b03915afa928315612cb157908691869461304e575b5060105460405163095ea7b360e01b8152926020928492909183918a918391612f6891906001600160a01b0316600484016118b5565b03925af18015612cb157613031575b506010546080919091018051935190936001600160a01b039283169290811691612fa191166131ae565b92823b1561302d57918691868094612fcf60405197889687958694637e18437960e01b865260048601612886565b03925af19081613019575b5061214557601354905160405163a9059cbb60e01b81529360209285926001600160a01b0391821692849287928492612dbd92909116600484016118b5565b8361302691949294610dcf565b9138612fda565b8580fd5b6130499060203d6020116113ea576113dc8183610dcf565b612f77565b60209194509161306f612f689360403d604011612176576121658183610dcf565b905094915091612f32565b60809091015160405163a9059cbb60e01b81529460209350859291839186918391612dbd916001600160a01b0316600484016118b5565b6125dd829361270c6130d494600694600160ff19600e541617600e553090611de3565b905560ff19600e5416600e55565b6006549060005b8281106131835750604051906130fe82610d9e565b6001600160a01b0316815260006020820190815291600160401b811015610db95780600161312f9201600655611002565b92909261316d57905182546001600160a01b0319166001600160a01b0391909116178255516001919091015560065460001981019081116118875790565b634e487b7160e01b600052600060045260246000fd5b61318c81611002565b50546001600160a01b038381169116146131a8576001016130e9565b91505090565b600c546040516377a9efe360e11b81526001600160a01b0392831660048201529160009183916024918391165afa9081156103e55760009161286957509056fea2646970667358221220a085958b0dd11905abd46fa85578010eb65d56c4e01e10644dea6beb6895feb364736f6c634300081c0033ce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec00000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000345fb2409a75089bdea4cdb2eb032106d125f90d000000000000000000000000214a4542e048ef9c21feca0980b8500773c1b5d80000000000000000000000000000000000000000033b2e3c9fd0803ce800000000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000656ae27db6d2d85d9b7b45cf0c8201e6034c0176000000000000000000000000345fb2409a75089bdea4cdb2eb032106d125f90d000000000000000000000000acdf534bdd29697f4f1e768fc28d51bcca2fe2e00000000000000000000000000000000000000000000000000000000000000008564f585a494c4c4100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055a494c4c41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094534eeee131840b1c0f61847c572228bdfdde9300000000000000000000000000000000000000000000000000000000000003690000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000456548a9b56efbbd89ca0309edd17a9e20b0401800000000000000000000000000000000000000000000000000000000000003690000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000960000000000000000000000000000000000000000000000000000000000000369000000000000000000000000290d95b17873f75b6897844844bd204173ad25aa0000000000000000000000000000000000000000000000000000000000000369000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000ba410289d31f515de8ea1112ff787faf0932fbbd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Deployed ByteCode

0x608080604052600436101561001d575b50361561001b57600080fd5b005b60003560e01c90816306fdde0314610c0957508063095ea7b314610be357806318160ddd14610bc557806323b872dd14610ad85780632973ef2d14610993578063313ce56714610977578063378dc3dc14610959578063406cf229146109315780634f30800d1461091357806356cdad1d146108f55780635f75baf6146108da578063695d69b3146108b75780636a2072d4146107fd578063709df63c1461070a57806370a08231146106d0578063715018a6146106735780638453ef99146106525780638da5cb5b146106295780639045be581461029957806395d89b41146105225780639b165f4e146104dd578063a9059cbb146104ac578063c5be2bc7146103f1578063cb78c16314610358578063dd62ed3e14610307578063e4f8d62e146102d8578063e6375d3e14610299578063eb50c06114610257578063f2fde38b146101cd578063f56b4d05146101a05763fec4ff171461017f573861000f565b3461019b57600036600319011261019b57602060405160018152f35b600080fd5b3461019b57600036600319011261019b5760206101bb611120565b6040516001600160a01b039091168152f35b3461019b57602036600319011261019b576101e6610d0d565b6101ee611c90565b6001600160a01b0316801561024157600580546001600160a01b0319811683179091556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b631e4fbdf760e01b600052600060045260246000fd5b3461019b57602036600319011261019b57610270610d0d565b610278611c90565b6001600160a01b03166000908152601560205260409020805460ff19169055005b3461019b57602036600319011261019b576001600160a01b036102ba610d0d565b16600052600a602052602060ff604060002054166040519015158152f35b3461019b57604036600319011261019b5760206102ff6102f6610d0d565b6024359061106b565b604051908152f35b3461019b57604036600319011261019b57610320610d0d565b610328610d23565b6001600160a01b039182166000908152600160209081526040808320949093168252928352819020549051908152f35b3461019b57600036600319011261019b57600c54604051625f8d8f60e81b81529060209082906001600160a01b0316818061039560048201610f46565b03915afa80156103e5576000906103b2575b602090604051908152f35b506020813d6020116103dd575b816103cc60209383610dcf565b8101031261019b57602090516103a7565b3d91506103bf565b6040513d6000823e3d90fd5b3461019b57602036600319011261019b5760043560195481101561019b5761041b61012091610d69565b5080549060ff600182015491600281015460018060a01b0360038301541660018060a01b0360048401541691610479600660058601549501549660405198895261046a60208a01888316610d39565b8660408a019160081c16610d5c565b6060870152608086015260a0808601919091526001600160a01b03821660c08601521c16151560e0830152610100820152f35b3461019b57604036600319011261019b576104d26104c8610d0d565b602435903361118c565b602060405160018152f35b3461019b57602036600319011261019b576104f6610d0d565b6104fe611c90565b6001600160a01b03166000908152601560205260409020805460ff19166001179055005b3461019b57600036600319011261019b5760405160006004548060011c9060018116801561061f575b60208310811461060b578285529081156105e75750600114610588575b6105848361057881850382610dcf565b60405191829182610cc4565b0390f35b600460009081527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b939250905b8082106105cd57509091508101602001610578610568565b9192600181602092548385880101520191019092916105b5565b60ff191660208086019190915291151560051b840190910191506105789050610568565b634e487b7160e01b84526022600452602484fd5b91607f169161054b565b3461019b57600036600319011261019b576005546040516001600160a01b039091168152602090f35b3461019b57600036600319011261019b5761066b611c90565b61001b611cb9565b3461019b57600036600319011261019b5761068c611c90565b600580546001600160a01b031981169091556000906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461019b57602036600319011261019b576001600160a01b036106f1610d0d565b1660005260006020526020604060002054604051908152f35b3461019b57600036600319011261019b5760065461072781610df0565b906107356040519283610dcf565b808252600660009081526020830191907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f835b8383106107c95784866040519182916020830190602084525180915260408301919060005b81811061079b575050500390f35b825180516001600160a01b03168552602090810151818601528695506040909401939092019160010161078d565b600260206001926040516107dc81610d9e565b848060a01b0386541681528486015483820152815201920192019190610768565b3461019b57602036600319011261019b576001600160a01b0361081e610d0d565b16600052600760205260406000206040518060208354918281520190819360005260206000209060005b8181106108a1575050508161085e910382610dcf565b6040519182916020830190602084525180915260408301919060005b818110610888575050500390f35b825184528594506020938401939092019160010161087a565b8254845260209093019260019283019201610848565b3461019b57602036600319011261019b5760206102ff6108d5610d0d565b610f14565b3461019b57600036600319011261019b5760206102ff610ead565b3461019b57600036600319011261019b576020601754604051908152f35b3461019b57600036600319011261019b576020600854604051908152f35b3461019b57600036600319011261019b576011546104d2906001600160a01b031633806118d0565b3461019b57600036600319011261019b576020600f54604051908152f35b3461019b57600036600319011261019b57602060405160128152f35b3461019b57600036600319011261019b576019546109b081610df0565b906109be6040519283610dcf565b808252601960009081526020830191907f944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9695835b838310610aba5784866040519182916020830190602084525180915260408301919060005b818110610a24575050500390f35b919350916020610120600192610100875180518352610a498582015186850190610d39565b610a5b60408201516040850190610d5c565b60608101516060840152858060a01b036080820151166080840152858060a01b0360a08201511660a0840152858060a01b0360c08201511660c084015260e0810151151560e08401520151610100820152019401910191849392610a16565b60076020600192610aca85610e07565b8152019201920191906109f1565b3461019b57606036600319011261019b57610af1610d0d565b610af9610d23565b6001600160a01b0382166000818152600160209081526040808320338452909152902054909260443592916000198110610b39575b506104d2935061118c565b838110610ba8578415610b92573315610b7c576104d2946000526001602052604060002060018060a01b0333166000526020528360406000209103905584610b2e565b634a1406b160e11b600052600060045260246000fd5b63e602df0560e01b600052600060045260246000fd5b8390637dc7a0d960e11b6000523360045260245260445260646000fd5b3461019b57600036600319011261019b576020600254604051908152f35b3461019b57604036600319011261019b576104d2610bff610d0d565b6024359033611ce5565b3461019b57600036600319011261019b5760006003548060011c90600181168015610cba575b60208310811461060b578285529081156105e75750600114610c5b576105848361057881850382610dcf565b600360009081527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b939250905b808210610ca057509091508101602001610578610568565b919260018160209254838588010152019101909291610c88565b91607f1691610c2f565b91909160208152825180602083015260005b818110610cf7575060409293506000838284010152601f8019910116010190565b8060208092870101516040828601015201610cd6565b600435906001600160a01b038216820361019b57565b602435906001600160a01b038216820361019b57565b906005821015610d465752565b634e487b7160e01b600052602160045260246000fd5b906003821015610d465752565b601954811015610d885760196000526007602060002091020190600090565b634e487b7160e01b600052603260045260246000fd5b604081019081106001600160401b03821117610db957604052565b634e487b7160e01b600052604160045260246000fd5b90601f801991011681019081106001600160401b03821117610db957604052565b6001600160401b038111610db95760051b60200190565b9060405161012081018181106001600160401b03821117610db957604052809280548252600181015460ff8116906005821015610d465760ff91602085015260081c166003811015610d465760408301526002810154606083015260038101546001600160a01b0390811660808401526004820154811660a080850191909152600583015491821660c08501521c60ff16151560e0830152600601546101009190910152565b60125460405163441062ed60e01b815290602090829060049082906001600160a01b03165afa9081156103e557600091610ee5575090565b90506020813d602011610f0c575b81610f0060209383610dcf565b8101031261019b575190565b3d9150610ef3565b6001600160a01b0381166000908152600a602052604090205460ff16610f4057610f3d90611c42565b90565b50600090565b60406020820191602081526019548093520190601960005260206000209060005b818110610f745750505090565b909192600761012060019286548152610faa84880154610f9a6020840160ff8316610d39565b60ff604084019160081c16610d5c565b60028701546060820152600387015460a085811b86900391821660808401526004890154821681840152600589015491821660c08401521c60ff16151560e08201526006870154610100820152019401929101610f67565b600654811015610d8857600660005260206000209060011b0190600090565b8054821015610d885760005260206000200190600090565b6001600160a01b0391821681529116602082015260408101919091526060810191909152608081019190915260a00190565b6001600160a01b038116600081815260076020526040902054919291821015611104576020916110c060018060a01b03600c54169160016110ab82611002565b50015493600052600785526040600020611021565b90549060031b1c91600b54946110ee6040519687958694859463a89055e560e01b8652309060048701611039565b03915afa9081156103e557600091610ee5575090565b505050600090565b51906001600160a01b038216820361019b57565b6012546040516327ab5d0f60e01b815290602090829060049082906001600160a01b03165afa9081156103e557600091611158575090565b90506020813d602011611184575b8161117360209383610dcf565b8101031261019b57610f3d9061110c565b3d9150611166565b6018805460ff60281b19169055600c54604051639ca7068f60e01b81526001600160a01b038085166004830181905294969495949260209183916024918391165afa9081156103e5576000916117fc575b506117f0576019541580156117e0575b80156117be575b80156117a6575b801561179a575b61174f5761120f85611e92565b80611736575b611718575b60168390556000948591825b60195484101561144b5761124261123c85610d69565b50610e07565b9360018060a01b03600c54169460608101519261125d610ead565b60ff601854169060405195632b8d28ef60e21b87528b60048801526024870152604486015215156064850152612710608485015260408460a4818a5afa9081156103e5576000948592611410575b50906112ba856112c093611ef1565b9b611ef1565b95604082018051916003831015610d46576000926112f0575050506112e8906001938861261e565b019296611226565b815160038110156113fc5760018b91149182611381575b50501561132257505061131d906001938861261e565b6112e8565b9392935190600382101561136d57506001939291906002148061135d575b61134c575b50506112e8565b611356918861261e565b3880611345565b506113688689611f2e565b611340565b634e487b7160e01b81526021600452602490fd5b6113a99250906020918a604051809581948293636468b51760e01b8452309160048501611f0b565b03915afa9081156113f15783916113c3575b508938611307565b6113e4915060203d81116113ea575b6113dc8183610dcf565b81019061189d565b386113bb565b503d6113d2565b6040513d85823e3d90fd5b634e487b7160e01b84526021600452602484fd5b6112ba95506112c0925061143a9060403d8111611444575b6114328183610dcf565b81019061201b565b90959092506112ab565b503d611428565b611463935061145e9197929495836116d9575b611efe565b600c5460405163ca497e2360e01b8152949193919060209086906001600160a01b0316818061149460048201610f46565b03915afa80156103e5576114f7956000916116ba575b50806116ab575b8061169e575b8061168e575b61166e575b60ff60185460181c16611652575b60ff60185460101c16611516575b5060ff60185460081c1680611506575b6114f957611de3565b565b611501612031565b611de3565b506115118282611f2e565b6114ee565b6011546001600160a01b038381169291169060008382036115fc575082600052600a60205260ff604060002054166000146115ee5760005b906000925b61155c81611c42565b60085460009283526009602052604080842082905596835286832081905592825294902055806115d0575b50806115b2575b5080156114de576011546115ac91906001600160a01b031630611de3565b386114de565b6115bb84611e92565b61158e576115ca908430611de3565b3861158e565b6115d984611e92565b611587576115e8908430611de3565b38611587565b6115f784610f14565b61154e565b838152600a602052604081205460ff1615611643575b9080600052600a60205260ff604060002054166000146116355760005b92611553565b61163e86610f14565b61162f565b5061164d84610f14565b611612565b601154611669906001600160a01b031684846118d0565b6114d0565b611676611cb9565b6018805460ff60281b1916600160281b1790556114c2565b5060ff60185460281c16156114bd565b5060ff600e5416156114b7565b5060ff60185460201c166114b1565b6116d3915060203d6020116113ea576113dc8183610dcf565b386114aa565b60185460081c60ff1615611706576116f2843089611de3565b6116fe84601754611ef1565b601755611efe565b61145e84611712611120565b89611de3565b83600052600a6020526040600020600160ff1982541617905561121a565b5083600052600a60205260ff6040600020541615611215565b9380935061175d9291611de3565b6018549060ff8260201c1615908161178a575b506117785750565b60ff60201b1916600160201b17601855565b6117949150611e92565b38611770565b5060ff600e5416611202565b5083600052601560205260ff604060002054166111fb565b506001600160a01b03821660009081526015602052604090205460ff166111f4565b5060ff60185460201c16156111ed565b93506114f79250611d4c565b611815915060203d6020116113ea576113dc8183610dcf565b386111dd565b80549190600160401b831015610db9578261183e9160016114f795018155611021565b90919082549060031b91821b91600019901b1916179055565b805115610d885760200190565b8051821015610d885760209160051b010190565b60001981146118875760010190565b634e487b7160e01b600052601160045260246000fd5b9081602091031261019b5751801515810361019b5790565b6001600160a01b039091168152602081019190915260400190565b9192600092606092916080905b600654861015611c39575b6001600160a01b038316600081815260076020526040902054871061193057600052600760205261192b6040600020600161192289611002565b5001549061181b565b6118e8565b5093909192935b6001600160a01b03851660008181526007602052604090205487106119765760005260076020526119716040600020600161192289611002565b611937565b5093909192935b6001600160a01b03871660008181526007602052604090205487106119bc5760005260076020526119b76040600020600161192289611002565b61197d565b506001600160a01b0385166000818152600a602052604090205491969395929492939160ff1615611c29576000905b6000916001600160a01b03871683818403611c02575b6001600160a01b038c16938085141580611bf8575b611bc5575b60405193611a298986610dcf565b600385528b36602087013760405195611a428a88610dcf565b600387528c36602089013760009780611ba3575b505080611b7f575b505080611b55575b505060005b838110611a7f5750505050600101946118dd565b80611a8c60019284611864565b51611a98575b01611a6b565b611aeb6020611aa688611002565b505460a085901b85900390811690611abe8589611864565b511690611acb8588611864565b5191600060405180968195829463a9059cbb60e01b8452600484016118b5565b03925af19081611b39575b5015611a9257611b3482611b0988611002565b500154838060a01b03611b1c8488611864565b5116600052600760205261183e886040600020611021565b611a92565b611b509060203d81116113ea576113dc8183610dcf565b611af6565b908491611b668496611b7795611864565b52611b718285611864565b52611878565b913880611a66565b908691611b90611b9b949887611864565b52611b718287611864565b933880611a5e565b90919750611bb086611857565b52611bba86611857565b526001953880611a56565b945083600052600a60205260ff60406000205416600014611be95760005b94611a1b565b611bf3868d61106b565b611be3565b5084831415611a16565b818152600a60205260ff604082205416600003611a015750611c24858961106b565b611a01565b611c33828561106b565b906119eb565b95505050505050565b602060018060a01b03600c54166008549060018060a01b0384166000526009835260406000205491600b54946110ee60405196879586948594631d2fa43b60e11b8652309060048701611039565b6005546001600160a01b03163303611ca457565b63118cdaa760e01b6000523360045260246000fd5b600e5460ff8116611ce25760ff1916600117600e55611cd66121b0565b60ff19600e5416600e55565b50565b6001600160a01b0316908115610b92576001600160a01b0316918215610b7c5760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918360005260018252604060002085600052825280604060002055604051908152a3565b6001600160a01b03168015611dcd57600091818352826020526040832054818110611db457817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef926020928587528684520360408620558060025403600255604051908152a3565b6064939263391434e360e21b8452600452602452604452fd5b634b637e8f60e11b600052600060045260246000fd5b6001600160a01b0316908115611dcd576001600160a01b0316918215611e7c576000828152806020526040812054828110611e625791604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef958760209652828652038282205586815280845220818154019055604051908152a3565b916064928463391434e360e21b8452600452602452604452fd5b63ec442f0560e01b600052600060045260246000fd5b600c54604051630d5c7b5d60e41b81526001600160a01b0392831660048201523060248201529160209183916044918391165afa9081156103e557600091611ed8575090565b610f3d915060203d6020116113ea576113dc8183610dcf565b9190820180921161188757565b9190820391821161188757565b6001600160a01b0391821681529181166020830152909116604082015260600190565b600c5460405163154b004960e31b81529260209284926001600160a01b03169183918291611f629130919060048501611f0b565b03915afa9081156103e557600091611ed8575090565b919082604091031261019b57610f3d6020611f928461110c565b930161110c565b6001600160a01b039182168152911660208201526060604082018190526014805491830182905260009081526080909201917fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec91905b818110611ffc5750505090565b82546001600160a01b0316845260209093019260019283019201611fef565b919082604091031261019b576020825192015190565b6017548015611ce257600c5460135460408051632a8ddb2f60e01b81526001600160a01b0393841694909390928491829161207191163060048401611f99565b0381865afa9182156103e55760009261214a575b506001600160a01b03821615612145576040906044601654918351958693849263059b6d4760e21b8452600484015260248301525afa80156103e55760009260009161211e575b5060175560105461210591906120ed9084906001600160a01b031630611ce5565b826120f6611120565b6120ff30612829565b926128ea565b1561210d5750565b61211990601754611ef1565b601755565b61210592935061213d915060403d604011611444576114328183610dcf565b9092916120cc565b505050565b61216d91925060403d604011612176575b6121658183610dcf565b810190611f78565b90509038612085565b503d61215b565b8181029291811591840414171561188757565b811561219a570490565b634e487b7160e01b600052601260045260246000fd5b60009081601954906121c182610df0565b906121cf6040519283610dcf565b828252601f196121de84610df0565b013660208401376121ee83610df0565b926121fc6040519485610dcf565b80845261220b601f1991610df0565b01366020850137845b6019548110156123725761222781610d69565b5060068101549081156123685760ff600182015416600581101580610d46576001821492831561233e575b50821561232d575b505061226c575b506001905b01612214565b600c546016546040805163059b6d4760e21b81526004810194909452602484019190915290829060449082906001600160a01b03165afa9081156103e557600090819261230c575b50806122d4575b509060019160066122cb83610d69565b50015590612261565b6122fe612304918493959960016122ec81978a611864565b52816122f8868b611864565b52611ef1565b97611878565b9290916122bb565b9050612326915060403d8111611444576114328183610dcf565b90386122b4565b909150610d4657600414388061225a565b6000935060028314915081612356575b509138612252565b60ff91506005015460a01c163861234e565b5050600190612266565b509392938315908115612615575b5061214557600c5460135460408051632a8ddb2f60e01b815292909183916001600160a01b0390811691839182916123bd91163060048401611f99565b03915afa9081156103e5576000916125f4575b506001600160a01b0381161561255e5760105461240f91906123fd9086906001600160a01b031630611ce5565b8461240730612829565b913090612995565b1561259b576013546040516370a0823160e01b8152306004820152929190602090849060249082906001600160a01b03165afa9283156103e557600093612564575b50821561255e5760005b6019548110156125575761246f8183611864565b51158015612545575b61253d57612499856124948661248e8588611864565b5161217d565b612190565b906124a381610d69565b5060ff600182015416926005841015610d46576001938481036124d957506124cd6124d392610e07565b90612eb4565b0161245b565b6000600282148061252c575b156125035750506124f86124fe92610e07565b90612d38565b6124d3565b50600414612513575b50506124d3565b61251f61252592610e07565b90612a23565b388061250c565b5060ff600585015460a01c166124e5565b6001906124d3565b506125508184611864565b5115612478565b5050505050565b50505050565b90926020823d602011612593575b8161257f60209383610dcf565b810103126125905750519138612451565b80fd5b3d9150612572565b92915060005b6019548110156125ee57806125b860019286611864565b516125c4575b016125a1565b6125ce8184611864565b516125e760066125dd84610d69565b5001918254611ef1565b90556125be565b50509050565b61260d915060403d604011612176576121658183610dcf565b9050386123d0565b90501538612380565b909160208101908151916005831015610d465760009261264557505050906114f791611d4c565b805160058110156113fc57859291906003036126ac57505061266c90612681933090611de3565b60406002549130815280602052205490611efe565b908161268b575050565b6126a79161249461269f92600b549061217d565b600854611ef1565b600855565b8091949392505160058110156127945760020361275357506080830180516001600160a01b031682526015602052604082205490919060ff161561272c575b5060e08301511561271657506125dd6127129261270c856006943090611de3565b51610d69565b9055565b516114f79392506001600160a01b031690611de3565b81516001600160a01b03168152601560205260409020805460ff19166001179055386126eb565b80949294516005811015612794576001036127735750506114f7926130b1565b5190600582101561136d575060041461278b57505050565b6114f7926130b1565b634e487b7160e01b83526021600452602483fd5b60208183031261019b578051906001600160401b03821161019b57019080601f8301121561019b5781516127db81610df0565b926127e96040519485610dcf565b81845260208085019260051b82010192831161019b57602001905b8282106128115750505090565b6020809161281e8461110c565b815201910190612804565b600c546040516343d7ef9f60e11b81526001600160a01b0392831660048201529160009183916024918391165afa9081156103e557600091612869575090565b610f3d91503d806000833e61287e8183610dcf565b8101906127a8565b60a091936020936080830195600180861b03168352600180851b03168483015260408201526080606082015284518094520192019060005b8181106128cb5750505090565b82516001600160a01b03168452602093840193909201916001016128be565b93929160009181158015612984575b61297c576010546129159083906001600160a01b031630611ce5565b6010546001600160a01b031690813b1561297857838095969761294e60405198899687958694630309079d60e31b865260048601612886565b03925af19182612968575b50906129625790565b50600190565b8161297291610dcf565b38612959565b8380fd5b509093505050565b506001600160a01b038616156128f9565b90929180158015612a12575b612a09576010546129bd9082906001600160a01b031630611ce5565b6010546001600160a01b031692833b1561019b576129ee91604051958694637e18437960e01b865260048601612886565b03825a9181600080958195f191826129685750906129625790565b50505050600090565b506001600160a01b038216156129a1565b60009181156121455760a00180516013549192916001600160a01b0391821691168114612d055750600c54601354835160408051632a8ddb2f60e01b815294936001600160a01b0393841693919286929182169183918291612a8a91168760048401611f99565b03915afa928315612cb1578593612cd9575b5060105460405163095ea7b360e01b815291602091839190829089908290612ad29089906001600160a01b0316600484016118b5565b03925af18015612cb157906024939291612cbc575b5083516040516370a0823160e01b81523060048201529360209185919082906001600160a01b03165afa928315612cb1578593612c79575b5060105484516001600160a01b039182169291612b3c91166131ae565b92823b15612c755791612b6c939187809460405196879586948593637e18437960e01b8552309060048601612886565b03925af19081612c61575b50612b8157505050565b81516040516370a0823160e01b81523060048201529190602090839060249082906001600160a01b03165afa8015612c56578490612c22575b612bc49250611efe565b9081612bcf57505050565b51612bfc90612be6906001600160a01b03166130e2565b9260406002549130815280602052205490611efe565b908115612145576125dd612c1c61271293612494600194600b549061217d565b93611002565b506020823d602011612c4e575b81612c3c60209383610dcf565b8101031261019b57612bc49151612bba565b3d9150612c2f565b6040513d86823e3d90fd5b84612c6e91959295610dcf565b9238612b77565b8680fd5b9092506020813d602011612ca9575b81612c9560209383610dcf565b81010312612ca557519138612b1f565b8480fd5b3d9150612c88565b6040513d87823e3d90fd5b612cd49060203d6020116113ea576113dc8183610dcf565b612ae7565b612ad291935082612cfa60209260403d604011612176576121658183610dcf565b905094925050612a9c565b612d14919250612be6906130e2565b9081612d1f57505050565b6125dd612c1c61271293612494600194600b549061217d565b906000908215612145576013546001600160a01b0316803b15612eb057828091602460405180948193632e1a7d4d60e01b83528960048401525af19081612e9c575b50612df45760135460809091015160405163a9059cbb60e01b81529360209285926001600160a01b0391821692849287928492612dbd92909116600484016118b5565b03925af1908115612de85750612dd05750565b611ce29060203d6020116113ea576113dc8183610dcf565b604051903d90823e3d90fd5b608001818080808660018060a01b038651165af13d15612e97573d6001600160401b038111612e835760405190612e35601f8201601f191660200183610dcf565b81528360203d92013e5b15612e4957505050565b601354905160405163a9059cbb60e01b81529360209285926001600160a01b0391821692849287928492612dbd92909116600484016118b5565b634e487b7160e01b84526041600452602484fd5b612e3f565b83612ea991949294610dcf565b9138612d7a565b8280fd5b9060009082156121455760a0810180516013549192916001600160a01b039081169116811461307a5750600c54601354835160408051632a8ddb2f60e01b815294936001600160a01b0393841693919286929182169183918291612f1d91168760048401611f99565b03915afa928315612cb157908691869461304e575b5060105460405163095ea7b360e01b8152926020928492909183918a918391612f6891906001600160a01b0316600484016118b5565b03925af18015612cb157613031575b506010546080919091018051935190936001600160a01b039283169290811691612fa191166131ae565b92823b1561302d57918691868094612fcf60405197889687958694637e18437960e01b865260048601612886565b03925af19081613019575b5061214557601354905160405163a9059cbb60e01b81529360209285926001600160a01b0391821692849287928492612dbd92909116600484016118b5565b8361302691949294610dcf565b9138612fda565b8580fd5b6130499060203d6020116113ea576113dc8183610dcf565b612f77565b60209194509161306f612f689360403d604011612176576121658183610dcf565b905094915091612f32565b60809091015160405163a9059cbb60e01b81529460209350859291839186918391612dbd916001600160a01b0316600484016118b5565b6125dd829361270c6130d494600694600160ff19600e541617600e553090611de3565b905560ff19600e5416600e55565b6006549060005b8281106131835750604051906130fe82610d9e565b6001600160a01b0316815260006020820190815291600160401b811015610db95780600161312f9201600655611002565b92909261316d57905182546001600160a01b0319166001600160a01b0391909116178255516001919091015560065460001981019081116118875790565b634e487b7160e01b600052600060045260246000fd5b61318c81611002565b50546001600160a01b038381169116146131a8576001016130e9565b91505090565b600c546040516377a9efe360e11b81526001600160a01b0392831660048201529160009183916024918391165afa9081156103e55760009161286957509056fea2646970667358221220a085958b0dd11905abd46fa85578010eb65d56c4e01e10644dea6beb6895feb364736f6c634300081c0033