ETH Price: $3,433.55 (-1.14%)
 

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Invest380628692025-11-12 2:38:0515 hrs ago1762915085IN
Rage: Buying Protocol
0 ETH0.000020520.01053583
Invest380579492025-11-11 23:54:0517 hrs ago1762905245IN
Rage: Buying Protocol
0 ETH0.000009160.00462482
Mint Rage380064472025-11-10 19:17:2146 hrs ago1762802241IN
Rage: Buying Protocol
0 ETH0.000001490.00184482
Mint Rage380057912025-11-10 18:55:2946 hrs ago1762800929IN
Rage: Buying Protocol
0 ETH0.000001970.00246662
Mint Rage380006272025-11-10 16:03:212 days ago1762790601IN
Rage: Buying Protocol
0 ETH0.000007560.0094681
Mint Rage379991032025-11-10 15:12:332 days ago1762787553IN
Rage: Buying Protocol
0 ETH0.000008820.01103842
Mint Rage379974962025-11-10 14:18:592 days ago1762784339IN
Rage: Buying Protocol
0 ETH0.000010510.01286748
Mint Rage379974872025-11-10 14:18:412 days ago1762784321IN
Rage: Buying Protocol
0 ETH0.00001420.01752246
Mint Rage379974772025-11-10 14:18:212 days ago1762784301IN
Rage: Buying Protocol
0 ETH0.000011330.01397013
Mint Rage379974682025-11-10 14:18:032 days ago1762784283IN
Rage: Buying Protocol
0 ETH0.0000140.01752655
Mint Rage379974572025-11-10 14:17:412 days ago1762784261IN
Rage: Buying Protocol
0 ETH0.000011730.01468134
Mint Rage379974452025-11-10 14:17:172 days ago1762784237IN
Rage: Buying Protocol
0 ETH0.000012980.01599436
Mint Rage379974362025-11-10 14:16:592 days ago1762784219IN
Rage: Buying Protocol
0 ETH0.000016050.02012215
Mint Rage379974252025-11-10 14:16:372 days ago1762784197IN
Rage: Buying Protocol
0 ETH0.00001740.02091236
Mint Rage379974132025-11-10 14:16:132 days ago1762784173IN
Rage: Buying Protocol
0 ETH0.000014750.01458555
Mint Rage379951162025-11-10 12:59:392 days ago1762779579IN
Rage: Buying Protocol
0 ETH0.000003140.00387192
Reserve Claim379724772025-11-10 0:25:012 days ago1762734301IN
Rage: Buying Protocol
0 ETH0.000005810.00930234
Mint Rage379709962025-11-09 23:35:392 days ago1762731339IN
Rage: Buying Protocol
0 ETH0.000003020.00299159
Mint Rage379108052025-11-08 14:09:174 days ago1762610957IN
Rage: Buying Protocol
0 ETH0.000003820.00458401
Mint Rage378837532025-11-07 23:07:334 days ago1762556853IN
Rage: Buying Protocol
0 ETH0.000000850.00105363
Invest378703602025-11-07 15:41:075 days ago1762530067IN
Rage: Buying Protocol
0 ETH0.000009130.0046694
Invest378701462025-11-07 15:33:595 days ago1762529639IN
Rage: Buying Protocol
0 ETH0.000008420.00436142
Invest378695202025-11-07 15:13:075 days ago1762528387IN
Rage: Buying Protocol
0 ETH0.000054470.02756748
Invest378684152025-11-07 14:36:175 days ago1762526177IN
Rage: Buying Protocol
0 ETH0.000011430.00586633
Mint Rage378664012025-11-07 13:29:095 days ago1762522149IN
Rage: Buying Protocol
0 ETH0.000003360.0042035
View all transactions

Latest 12 internal transactions

Parent Transaction Hash Block From To
377821402025-11-05 14:40:277 days ago1762353627
Rage: Buying Protocol
0.05 ETH
377492492025-11-04 20:24:057 days ago1762287845
Rage: Buying Protocol
1 ETH
376100142025-11-01 15:02:5511 days ago1762009375
Rage: Buying Protocol
0.068 ETH
375254792025-10-30 16:05:0513 days ago1761840305
Rage: Buying Protocol
0.26561 ETH
375219542025-10-30 14:07:3513 days ago1761833255
Rage: Buying Protocol
0.2111 ETH
374387812025-10-28 15:55:0915 days ago1761666909
Rage: Buying Protocol
0.34 ETH
374303352025-10-28 11:13:3715 days ago1761650017
Rage: Buying Protocol
0.02 ETH
373944482025-10-27 15:17:2316 days ago1761578243
Rage: Buying Protocol
1.9 ETH
373885652025-10-27 12:01:1716 days ago1761566477
Rage: Buying Protocol
0.2253 ETH
373552592025-10-26 17:31:0517 days ago1761499865
Rage: Buying Protocol
0.03 ETH
372785032025-10-24 22:52:3318 days ago1761346353
Rage: Buying Protocol
0.004 ETH
372740282025-10-24 20:23:2318 days ago1761337403
Rage: Buying Protocol
0.0027 ETH

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RageBuyingProtocol

Compiler Version
v0.8.26+commit.8a97fa7a

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
File 1 of 10 : RageBuyingProtocol.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

import {RageStructs} from "./RageStructs.sol";
import {IRageChaosEngine} from "./IRageChaosEngine.sol";
import {IRageSwapper} from "./IRageSwapper.sol";
import {IRageOracle} from "./IRageOracle.sol";
import {IRage} from "./IRage.sol";
import {ReentrancyGuard} from "./ReentrancyGuard.sol";
import {IERC20} from "./IERC20.sol";
import {IRageOptionNft} from "./IRageOptionNft.sol";
import {IRageCalculation} from "./IRageCalculation.sol";

contract RageBuyingProtocol is ReentrancyGuard {
  // constant
  uint256 private constant VERSION = 1;
  uint256 private constant CONFIG_INTERVAL = 1 hours;
  IERC20 private constant USDC = IERC20(0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913);
  IERC20 private constant HESTIA = IERC20(0xBC7755a153E852CF76cCCDdb4C2e7c368f6259D8);
  IERC20 private constant CIRCLE = IERC20(0x5baBfc2F240bc5De90Eb7e19D789412dB1dEc402);
  IERC20 private constant PHESTIA = IERC20(0xF760fD8fEB1F5E3bf3651E2E4f227285a82470Ff);
  IERC20 private constant PCIRCLE = IERC20(0x55A81dA2a319dD60fB028c53Cb4419493B56f6c0);
  address private constant MULTISIG = 0x507fbdE39ba40DA4Fc79426AD5E3C64944fE43d4;
  uint256 private constant MAX_DEADLINE_DURATION = 2 minutes;
  uint256 private constant TRANSACTION_COSTS = 3; // 3% reserved for costs, accounting for price impact, transaction costs (pool fee), and peapods fee
  uint256 private constant INITIAL_HESTIA_BACKING = 1912600000000000000;  // 1.9126 HESTIA
  uint256 private constant INITIAL_CIRCLE_BACKING = 1384800000000000000;  // 1.3848 CIRCLE

  // immutable
  IRageChaosEngine private immutable RAGE_CHAOS_ENGINE;
  IRage private immutable RAGE;
  IRageOracle private immutable RAGE_ORACLE;
  IRageCalculation private immutable RAGE_CALCULATION;
  IRageSwapper private immutable RAGE_SWAPPER;
  IRageOptionNft private immutable RAGE_OPTION_NFT;

  // state
  RageStructs.RbpStateValue private STATE;
  RageStructs.RbpConfig private CONFIG;
  RageStructs.RbpRecent private RECENT;
  address[] private CLAIM_WALLETS; // array which contain all wallets that made a claim
  mapping(uint256 => RageStructs.Option) private OPTIONS_MAP; // options allow multiple options per wallet, id is linked to the nft id
  mapping(address => RageStructs.Claim) private CLAIMS_MAP; // claims allow 1 claim per wallet, a new claim would replace the old

  // events
  event OptionCreated(uint256 indexed optionId);
  event RageMinted(uint256 indexed optionId);
  event OptionRefunded(uint256 indexed optionId);
  event ClaimReserved( address indexed wallet);
  event ClaimProcessed(address indexed wallet);

  // constructor
  constructor(address rce, address rage, address oracle, address calc, address swap, address rOption) {
    RAGE_CHAOS_ENGINE = IRageChaosEngine(rce);
    RAGE = IRage(rage);
    RAGE_ORACLE = IRageOracle(oracle);
    RAGE_CALCULATION = IRageCalculation(calc);
    RAGE_SWAPPER = IRageSwapper(swap);
    RAGE_OPTION_NFT = IRageOptionNft(rOption);

    // approve rage swaps for swapping
    USDC.approve(address(RAGE_SWAPPER), type(uint256).max);
    HESTIA.approve(address(RAGE_SWAPPER), type(uint256).max);
    CIRCLE.approve(address(RAGE_SWAPPER), type(uint256).max);
    PHESTIA.approve(address(RAGE_SWAPPER), type(uint256).max);
    PCIRCLE.approve(address(RAGE_SWAPPER), type(uint256).max);
    
    // initialize config with default values
    CONFIG = RageStructs.RbpConfig({
        minInvest: 10e6,
        maxInvest: 7500e6,
        hestiaPercent: 80,
        investorBonus: 6,
        mintDelay: 2 days,
        adpDelay: 60 days,
        adpPercent: 75,
        ecosystemBonus: 6,
        refundPercent: 85,
        refundDelay: 1000 days,
        claimFee: 10,
        claimDelay: 30 days,
        claimValidity: 10 days,
        minClaim: 1e18,
        maxClaim: 500e18,
        slippage: 500,
        twap: 30 seconds
    });
  }

  // getState
  // returns the complete state of the contract including config and last operations
  function getState() external view returns (RageStructs.RbpState memory) {
    return RageStructs.RbpState({
      version: VERSION,
      state: STATE,
      config: CONFIG,
      recent: RECENT
    });
  }

  // getViewState
  // returns the view state of the contract
  // this function may revert if the contract does not have active assets or active supply
  function getViewState() external view returns (RageStructs.RbpViewState memory) {
    uint256 price = getPrice(1e18);
    uint256 activeSupply = RAGE_CHAOS_ENGINE.getActiveSupply();
    uint256 fmv = getFmv();
    uint256 backingPerShare = getBackingPerShare();
    uint256 activeAssetsValue = getActiveAssetsUsdcValue();
    (uint256 investHestia, uint256 investCircle) = getInvestPercents();

    // assets
    (uint256 rawHestia, uint256 rawCircle) = getRawAssets();
    (uint256 pendingHestia, uint256 pendingCircle) = getPendingAssets();
    (uint256 bonusHestia, uint256 bonusCircle) = getBonusAssets();
    (uint256 activePhestia, uint256 activePcircle) = getActiveAssets();

    // underlying
    (
        uint256 underlyingHestia,
        uint256 underlyingCircle,
        uint256 hestiaValue,
        uint256 circleValue,
        uint256 totalValue,
        uint256 hestiaPercent,
        uint256 circlePercent
    ) = getRageUnderlying();

    // conversion with 1% amounts
    uint256 onePercentUsdc = activeAssetsValue / 100;
    uint256 onePercentRage = activeSupply / 100;
    uint256 rageFromUsdc = getRageFromUsdc(onePercentUsdc);
    (uint256 hestiaFromRage, uint256 circleFromRage) = getAssetsFromRage(onePercentRage);
    
    return RageStructs.RbpViewState({
        price: price,
        activeSupply: activeSupply,
        fmv: fmv,
        backingPerShare: backingPerShare,
        activeAssetsUsdcValue: activeAssetsValue,
        rawHestia: rawHestia,
        rawCircle: rawCircle,
        pendingHestia: pendingHestia,
        pendingCircle: pendingCircle,
        bonusHestia: bonusHestia,
        bonusCircle: bonusCircle,
        activePhestia: activePhestia,
        activePcircle: activePcircle,
        activeHestia: RAGE_ORACLE.getPhestiaInHestiaAfterDebond(activePhestia),
        activeCircle: RAGE_ORACLE.getPcircleInCircleAfterDebond(activePcircle),
        investPercentHestia: investHestia,
        investPercentCircle: investCircle,
        underlyingHestia: underlyingHestia,
        underlyingCircle: underlyingCircle,
        underlyingHestiaValue: hestiaValue,
        underlyingCircleValue: circleValue,
        underlyingTotalValue: totalValue,
        underlyingHestiaPercent: hestiaPercent,
        underlyingCirclePercent: circlePercent,
        rageFromOnePercentUsdc: rageFromUsdc,
        hestiaFromOnePercentRage: hestiaFromRage,
        circleFromOnePercentRage: circleFromRage
    });
  }

  // isAutomator
  function isAutomator(address value) private view returns(bool) {
    return value == RAGE_CHAOS_ENGINE.getAutomator();
  }

  // withdrawToken
  function withdrawToken(address tokenAdr, uint256 amount) external {
    require(isAutomator(msg.sender), "de");
    require(amount != 0, "am");

    if (tokenAdr == address(0)) {
        uint256 balance = address(this).balance;
        require(balance >= amount, "ba");
        (bool success, ) = payable(MULTISIG).call{value: amount}("");
        require(success, "tr");
    } else {
        IERC20 token = IERC20(tokenAdr);
        uint256 balance = token.balanceOf(address(this));
        require(balance >= amount, "ba");
        require(token.transfer(MULTISIG, amount), "tr");
    }
  }

  // setStatus
  // automator can set 0 or 1
  function setStatus(uint256 status) external nonReentrant {
    require(isAutomator(msg.sender), "de");
    require(status <= 1, "de");
    STATE.status = status;
  }

  // getClaimWallets
  // returns the claim wallets array
  function getClaimWallets() external view returns (address[] memory) {
    return CLAIM_WALLETS;
  }

  // getOption
  // returns the option struct for a given option ID
  function getOption(uint256 optionId) external view returns (RageStructs.Option memory) {
      return OPTIONS_MAP[optionId];
  }

  // getClaim
  // returns the claim struct for a given wallet address
  function getClaim(address wallet) external view returns (RageStructs.Claim memory) {
      return CLAIMS_MAP[wallet];
  }

  // setConfigs
  // automator can change a number of configuration on the contract
  function setConfigs(RageStructs.RbpConfig calldata newConfig) external nonReentrant {
    require(isAutomator(msg.sender), "de");
    require(block.timestamp >= STATE.nextConfigTime, "ti");

    require(newConfig.minInvest >= 1e6 && newConfig.minInvest <= 100e6 && newConfig.minInvest < newConfig.maxInvest, "co");
    require(newConfig.maxInvest >= 1000e6 && newConfig.maxInvest <= 100000e6, "co");
    require(newConfig.hestiaPercent >= 55 && newConfig.hestiaPercent <= 95, "co");
    require(newConfig.investorBonus >= 1 && newConfig.investorBonus <= 15, "co");
    require(newConfig.mintDelay >= 1 days && newConfig.mintDelay <= 90 days, "co");
    require(newConfig.adpDelay >= 30 days && newConfig.adpDelay <= 300 days, "co");
    require(newConfig.adpPercent >= 55 && newConfig.adpPercent <= 90 && newConfig.adpPercent <= newConfig.refundPercent, "co");
    require(newConfig.ecosystemBonus >= 1 && newConfig.ecosystemBonus <= 15, "co");
    require(newConfig.refundPercent >= 55 && newConfig.refundPercent <= 95, "co");
    require(newConfig.refundDelay >= 500 days && newConfig.refundDelay <= 1500 days, "co");
    require(newConfig.minClaim >= 1e15 && newConfig.minClaim <= 1e18 && newConfig.minClaim < newConfig.maxClaim, "co");
    require(newConfig.maxClaim >= 100e18, "co");
    require(newConfig.claimFee >= 1 && newConfig.claimFee <= 20, "co");
    require(newConfig.claimDelay >= 10 days && newConfig.claimDelay <= 100 days, "co");
    require(newConfig.claimValidity >= 1 days && newConfig.claimValidity <= 30 days, "co");
    require(newConfig.slippage <= 2500, "co");
    require(newConfig.twap >= 1 seconds && newConfig.twap <= 3600 seconds, "co");

    STATE.nextConfigTime = block.timestamp + CONFIG_INTERVAL;
    CONFIG = newConfig;
  }



  // getRageFromUsdc
  // returns the rage amount you should get from a usdc value
  function getRageFromUsdc(uint256 usdcAmount) public view returns (uint256) {
    require(usdcAmount != 0, "am");
    
    uint256 rageActiveSupply = RAGE_CHAOS_ENGINE.getActiveSupply();
    uint256 activeAssetsValue = getActiveAssetsUsdcValue();
    require(rageActiveSupply != 0, "am");
    require(activeAssetsValue != 0, "am");
    
    return RAGE_CALCULATION.calculateRageFromUsdc(
        rageActiveSupply,
        activeAssetsValue,
        usdcAmount
    );
}

  // getAssetsFromRage
  // returns the underlying assets from rage
  function getAssetsFromRage(uint256 rageAmount) public view returns (uint256 hestia, uint256 circle) {
      // returns the yield-bearing version of the tokens from rage
      uint256 rageActiveSupply = RAGE_CHAOS_ENGINE.getActiveSupply();
      uint256 totalActiveAssetsValue = getActiveAssetsUsdcValue();
      require(rageActiveSupply != 0, "am");
      require(totalActiveAssetsValue != 0, "am");
      
      (uint256 activePhestia, uint256 activePcircle) = getActiveAssets();
      
      // get pTokens
      (uint256 phestia, uint256 pcircle,,,) = RAGE_CALCULATION.getAssetsFromRage(
          rageAmount,
          rageActiveSupply,
          totalActiveAssetsValue,
          activePhestia,
          activePcircle,
          CONFIG.twap
      );
      
      // convert to underlying
      hestia = phestia > 0 ? RAGE_ORACLE.getPhestiaInHestiaAfterDebond(phestia) : 0;
      circle = pcircle > 0 ? RAGE_ORACLE.getPcircleInCircleAfterDebond(pcircle) : 0;
  }

  // getPendingAssets
  // return the balance of hestia, circle. Will revert if the balance in state variables are not in the contract
  function getPendingAssets() public view returns (uint256 pendingHestia, uint256 pendingCircle) {
    pendingHestia = STATE.pendingHestia;
    pendingCircle = STATE.pendingCircle;
    
    // verify the contract has enough balance to cover pending amounts
    (uint256 rawHestia, uint256 rawCircle) = getRawAssets();
    require(rawHestia >= pendingHestia, "ba");
    require(rawCircle >= pendingCircle, "ba");
  }

  // getActiveAssetsUsdcValue
  // returns the USDC value of the active assets
  function getActiveAssetsUsdcValue() public view returns (uint256 totalValue) {
    (uint256 activePhestia, uint256 activePcircle) = getActiveAssets();
    
    uint256 hestiaValue = activePhestia > 0 ? RAGE_ORACLE.getPhestiaUsdcPriceAfterDebond(activePhestia, CONFIG.twap) : 0;
    uint256 circleValue = activePcircle > 0 ? RAGE_ORACLE.getPcircleUsdcPriceAfterDebond(activePcircle, CONFIG.twap) : 0;
    
    totalValue = hestiaValue + circleValue;
  }

  // getRawAssets
  // returns the balance of hestia and circle in the contract
  function getRawAssets() public view returns (uint256 rawHestia, uint256 rawCircle) {
    rawHestia = HESTIA.balanceOf(address(this));
    rawCircle = CIRCLE.balanceOf(address(this));
  }

  // getActiveAssets
  // returns the balance of pHestia and pCircle in the contract
  function getActiveAssets() public view returns (uint256 activePhestia, uint256 activePcircle) {
    activePhestia = PHESTIA.balanceOf(address(this));
    activePcircle = PCIRCLE.balanceOf(address(this));
  }

  // getBonusAssets
  // return the balance of hestia, circle which are available for bonus
  function getBonusAssets() public view returns (uint256 bonusHestia, uint256 bonusCircle) {
    (uint256 pendingHestia, uint256 pendingCircle) = getPendingAssets();
    (uint256 rawHestia, uint256 rawCircle) = getRawAssets();

    // bonus assets are the balance minus pending amounts
    bonusHestia = rawHestia - pendingHestia;
    bonusCircle = rawCircle - pendingCircle;
  }

  // getRageUnderlying
  // returns the number of hestia and circle underlying 1 rage token and other details
  function getRageUnderlying() public view returns (
    uint256 underlyingHestia, 
    uint256 underlyingCircle, 
    uint256 hestiaValue, 
    uint256 circleValue, 
    uint256 totalValue, 
    uint256 hestiaPercent, 
    uint256 circlePercent
  ) {
    uint256 activeSupply = RAGE_CHAOS_ENGINE.getActiveSupply();
    (uint256 activePhestia, uint256 activePcircle) = getActiveAssets();

    return RAGE_CALCULATION.getDetailedRageUnderlying(activeSupply, activePhestia, activePcircle, CONFIG.twap);
  }

  // getPrice
  // returns rage price
  function getPrice(uint256 amount) public view returns (uint256) {
    return RAGE_ORACLE.getRageTwapUsdcPrice(amount, CONFIG.twap);
  }

  // getFmv
  // return the fair market value price for 1 rage token in USDC terms (6 decimals)
  function getFmv() public view returns (uint256) {
    return RAGE_CALCULATION.calculateRageFmv(RAGE_CHAOS_ENGINE.getActiveSupply(), getActiveAssetsUsdcValue());
  }

  // getBackingPerShare
  // returns the backing score per 1 rage token
  function getBackingPerShare() public view returns (uint256) {
    uint256 rageActiveSupply = RAGE_CHAOS_ENGINE.getActiveSupply();
    (uint256 pHestia, uint256 pCircle) = getActiveAssets();
    (uint256 percentHestia, uint256 percentCircle) = getInvestPercents();
    
    return RAGE_CALCULATION.calculateBackingPerShare(
      rageActiveSupply, pHestia, pCircle, percentHestia, percentCircle, INITIAL_HESTIA_BACKING, INITIAL_CIRCLE_BACKING
    );
  }

  // getInvestPercents
  // returns the invest percent to use for Hestia and Circle
  function getInvestPercents() public view returns (uint256 percentHestia, uint256 percentCircle) {
    percentHestia = CONFIG.hestiaPercent;
    percentCircle = 100 - CONFIG.hestiaPercent;
  }

  // getUsdcBalance
  // returns amount of USDC in contract
  function getUsdcBalance() private view returns (uint256) {
    return USDC.balanceOf(address(this));
  }

  // receive
  receive() external payable nonReentrant {
    investEthProcess("r", address(0));
  }

  // invest
  function invest(uint256 usdcAmount, address referral) external nonReentrant {
    require(USDC.transferFrom(msg.sender, address(this), usdcAmount), "tr");
    investProcess(usdcAmount, "i", referral);
  }

  // investEth
  function investEth(address referral) external payable nonReentrant {
    investEthProcess("e", referral);
  }

  // processEthInvestment
  function investEthProcess(string memory transactionType, address referral) private {
    require(msg.value != 0, "am");
    
    uint256 usdcBefore = getUsdcBalance();
    uint256 usdcAmount = RAGE_SWAPPER.swapEthForUsdc{value: msg.value}(block.timestamp + MAX_DEADLINE_DURATION);
    require(getUsdcBalance() >= usdcBefore + usdcAmount, "sw");
    
    investProcess(usdcAmount, transactionType, referral);
  }

  // investProcess
  function investProcess(uint256 usdcAmount, string memory transactionType, address referral) private {
      require(getUsdcBalance() >= usdcAmount, "am");
      RageStructs.InvestOverview memory overview = investOverview(msg.sender, usdcAmount);
      require(overview.canInvest, "op");
      overview.transactionType = transactionType;
      
      // buy the underlying assets
      (uint256 hestiaBefore, uint256 circleBefore) = getRawAssets();
      (uint256 hestiaReceived, uint256 circleReceived) = RAGE_SWAPPER.swapUsdcToAssets(
          usdcAmount,
          overview.configHestiaPercent,
          overview.configCirclePercent,
          CONFIG.slippage,
          CONFIG.slippage,
          block.timestamp + MAX_DEADLINE_DURATION
      );
      (uint256 hestiaAfter, uint256 circleAfter) = getRawAssets();
      require(hestiaAfter >= hestiaBefore + hestiaReceived, "sw");
      require(circleAfter >= circleBefore + circleReceived, "sw");
      
      // update pending assets (including investor bonus for all tokens)
      uint256 totalHestia = hestiaReceived + overview.hestiaInvestorBonus;
      uint256 totalCircle = circleReceived + overview.circleInvestorBonus;
      
      STATE.pendingHestia += totalHestia;
      STATE.pendingCircle += totalCircle;
      
      // create and store the Option
      uint256 optionId = STATE.totalOptions + 1;
      OPTIONS_MAP[optionId] = RageStructs.Option({
          id: optionId,
          version: VERSION,
          status: 1, // created
          transactionType: transactionType,
          walletCreated: msg.sender,
          walletUpdated: address(0),
          referral: referral,
          dateCreated: block.timestamp,
          dateUpdated: block.timestamp,
          dateMintable: overview.dateMintable,
          dateAdpAble: overview.dateAdpAble,
          dateRefundable: overview.dateRefundable,
          price: getPrice(1e18),
          fmv: getFmv(),
          backingPerShare: getBackingPerShare(),
          usdcInvest: overview.usdcInvest,
          usdcAdp: overview.usdcAdp,
          usdcRefund: overview.usdcRefund,
          pendingHestia: totalHestia,
          pendingCircle: totalCircle,
          rageEstimated: overview.rageEstimated,
          rageMinted: 0,
          usdcAdpDilution: 0,
          usdcInvestorBonus: overview.usdcInvestorBonus,
          hestiaInvestorBonus: overview.hestiaInvestorBonus,
          circleInvestorBonus: overview.circleInvestorBonus,
          usdcEcosystemBonus: overview.usdcEcosystemBonus,
          hestiaEcosystemBonus: overview.hestiaEcosystemBonus,
          circleEcosystemBonus: overview.circleEcosystemBonus,
          configHestiaPercent: overview.configHestiaPercent,
          configCirclePercent: overview.configCirclePercent,
          configInvestorBonus: overview.configInvestorBonus,
          configMintDelay: overview.configMintDelay,
          configAdpDelay: overview.configAdpDelay,
          configAdpPercent: overview.configAdpPercent,
          configRefundPercent: overview.configRefundPercent,
          configRefundDelay: overview.configRefundDelay
      });
      
      STATE.totalOptions++;
      STATE.totalDebt += overview.usdcRefund;
      STATE.totalInvest += usdcAmount;
      STATE.totalInvestorBonus += overview.usdcInvestorBonus;
      STATE.totalEcosystemBonus += overview.usdcEcosystemBonus;

      // ecosystem bonus - bond both tokens
      if (overview.hestiaEcosystemBonus > 0 || overview.circleEcosystemBonus > 0) {
          (uint256 pHestiaBefore, uint256 pCircleBefore) = getActiveAssets();
          (uint256 pHestiaReceived, uint256 pCircleReceived) = RAGE_SWAPPER.bondAssets(
              overview.hestiaEcosystemBonus, 
              overview.circleEcosystemBonus, 
              block.timestamp + MAX_DEADLINE_DURATION
          );
          (uint256 pHestiaAfter, uint256 pCircleAfter) = getActiveAssets();

          if (overview.hestiaEcosystemBonus > 0) {
              require(pHestiaAfter >= pHestiaBefore + pHestiaReceived, "sw");
          }
          if (overview.circleEcosystemBonus > 0) {
              require(pCircleAfter >= pCircleBefore + pCircleReceived, "sw");
          }
      }
      
      // mint NFT to the investor
      RAGE_OPTION_NFT.mint(msg.sender, optionId);
      
      RECENT.lastInvest = optionId;
      emit OptionCreated(optionId);
  }

  // mintRage
  function mintRage(uint256 optionId) external nonReentrant {    
    RageStructs.OptionOverview memory overview = optionOverview(msg.sender, optionId);
    require(overview.canMint, "op");
    require(overview.rageMint != 0, "am");
    
    RageStructs.Option storage opt = OPTIONS_MAP[optionId];
    
    // update pending assets (remove from pending)
    STATE.pendingHestia -= opt.pendingHestia;
    STATE.pendingCircle -= opt.pendingCircle;
    
    // bond the assets to pTokens
    (uint256 pHestiaBefore, uint256 pCircleBefore) = getActiveAssets();
    (uint256 pHestiaReceived, uint256 pCircleReceived) = RAGE_SWAPPER.bondAssets(
        opt.pendingHestia,
        opt.pendingCircle,
        block.timestamp + MAX_DEADLINE_DURATION
    );
     (uint256 pHestiaAfter, uint256 pCircleAfter) = getActiveAssets();
    require(pHestiaAfter >= pHestiaBefore + pHestiaReceived, "sw");
    require(pCircleAfter >= pCircleBefore + pCircleReceived, "sw");

    // determine if ADP was used
    bool useAdp = overview.canMintWithAdp && overview.usdcAdpDilution > 0;
    opt.status = useAdp ? 3 : 2; // 3 for minted with ADP, 2 for regular mint
    opt.rageMinted = overview.rageMint;
    opt.usdcAdpDilution = overview.usdcAdpDilution;
    opt.walletUpdated = msg.sender;
    opt.dateUpdated = block.timestamp;
    
    // update global state
    STATE.optionsMint++;
    if (useAdp) {
        STATE.optionsAdp++;
        STATE.optionsAdpValue += opt.usdcAdp;
    }
    STATE.totalDebt -= opt.usdcRefund;
    STATE.totalAdpDilution += overview.usdcAdpDilution;
    
    // transfer RAGE tokens to user through the Rage Chaos Engine
    RAGE_CHAOS_ENGINE.transferRage(msg.sender, overview.rageMint);
    
    RECENT.lastMintRage = optionId;
    emit RageMinted(optionId);
  }

  // refund
  function refund(uint256 optionId) external nonReentrant {      
      RageStructs.OptionOverview memory overview = optionOverview(msg.sender, optionId);
      require(overview.canRefund, "op");
      
      RageStructs.Option storage opt = OPTIONS_MAP[optionId];
      
      // update pending assets (remove from pending)
      STATE.pendingHestia -= opt.pendingHestia;
      STATE.pendingCircle -= opt.pendingCircle;
      
      // sell the pending assets back to USDC
      uint256 usdcBefore = getUsdcBalance();
      uint256 usdcReceived = RAGE_SWAPPER.swapAssetsToUsdc(
          opt.pendingHestia,
          opt.pendingCircle,
          CONFIG.slippage,
          CONFIG.slippage,
          block.timestamp + MAX_DEADLINE_DURATION
      );
      require(getUsdcBalance() >= usdcBefore + usdcReceived, "sw");
      
      // check if contract has enough USDC to cover the refund
      // if there is not enough USDC, there will need to be manual intervention by contract administrators to withdraw active assets, sell them and send back USDC to contract
      uint256 currentUsdcBalance = getUsdcBalance();
      require(currentUsdcBalance >= opt.usdcRefund, "ba");
      
      // update option status
      opt.status = 4; // 4 for refunded
      opt.walletUpdated = msg.sender;
      opt.dateUpdated = block.timestamp;
      
      // update global state
      STATE.optionsRefund++;
      STATE.optionsRefundValue += opt.usdcRefund;
      STATE.totalDebt -= opt.usdcRefund;
            
      // transfer refund to user
      require(USDC.transfer(msg.sender, opt.usdcRefund), "tr");
      
      RECENT.lastRefund = optionId;
      emit OptionRefunded(optionId);
  }

  // reserveClaim
  function reserveClaim(uint256 rageAmount) external nonReentrant {
    RageStructs.ReserveClaimOverview memory overview = reserveClaimOverview(msg.sender, rageAmount);
    require(overview.canReserve, "op");
    
    RageStructs.Claim storage existingClaim = CLAIMS_MAP[msg.sender];

    if (overview.isFirstClaim) {
      STATE.totalClaims++;
      CLAIM_WALLETS.push(msg.sender);
    }  
    
    CLAIMS_MAP[msg.sender] = RageStructs.Claim({
        wallet: msg.sender,
        version: VERSION,
        status: 1, // active
        claimedCount: existingClaim.claimedCount,
        rageBurn: overview.rageBurn, // full amount before fee
        rageAfterFee: overview.rageAfterFee, // amount after fee
        price: getPrice(1e18),
        fmv: getFmv(),
        backingPerShare: getBackingPerShare(),
        dateCreated: block.timestamp,
        dateUpdated: block.timestamp,
        dateClaimableStart: overview.dateClaimableStart,
        dateClaimableEnd: overview.dateClaimableEnd,
        claimHestia: overview.claimHestia, // amount after fee
        claimCircle: overview.claimCircle, // amount after fee
        lastClaimHestia: 0,
        lastClaimCircle: 0,
        totalClaimHestia: existingClaim.totalClaimHestia,
        totalClaimCircle: existingClaim.totalClaimCircle,
        configClaimFee: overview.configClaimFee,
        configClaimDelay: overview.configClaimDelay,
        configClaimValidity: overview.configClaimValidity
    });
    
    RECENT.lastReserveClaim = msg.sender;
    emit ClaimReserved(msg.sender);
  }

  // processClaim
  function processClaim() external nonReentrant {
    RageStructs.ClaimOverview memory overview = processClaimOverview(msg.sender);
    require(overview.canClaim, "op");
    RageStructs.Claim storage existingClaim = CLAIMS_MAP[msg.sender];
            
    // verify we have enough pTokens
    (uint256 pHestiaAvail, uint256 pCircleAvail) = getActiveAssets();
    require(pHestiaAvail >= overview.pHestiaNeeded, "ba");
    require(pCircleAvail >= overview.pCircleNeeded, "ba");
    
    // debond exact amounts needed
    (uint256 hestiaBefore, uint256 circleBefore) = getRawAssets();
    (uint256 hestiaDebonded, uint256 circleDebonded) = RAGE_SWAPPER.debondAssets(
        overview.pHestiaNeeded, 
        overview.pCircleNeeded,
        block.timestamp + MAX_DEADLINE_DURATION
    );
    
    // verify we received the expected amounts
    require(hestiaDebonded > 0, "insDeb");
    (uint256 hestiaAfter, uint256 circleAfter) = getRawAssets();
    require(hestiaAfter >= hestiaBefore + hestiaDebonded, "sw");
    require(circleAfter >= circleBefore + circleDebonded, "sw");

    // only return the lowest amount between actual debond and claimed amount
    // any residual would be left in bonus assets
    uint256 outHestia = hestiaDebonded < overview.claimHestia ? hestiaDebonded : overview.claimHestia;
    uint256 outCircle = circleDebonded < overview.claimCircle ? circleDebonded: overview.claimCircle;

    existingClaim.status = 2; // claimed
    existingClaim.claimedCount++; // increment claimed count
    existingClaim.dateUpdated = block.timestamp;
    existingClaim.lastClaimHestia = outHestia;
    existingClaim.lastClaimCircle = outCircle;
    existingClaim.totalClaimHestia += outHestia;
    existingClaim.totalClaimCircle += outCircle;

    STATE.claimsProcessed++;
    STATE.claimsHestia += outHestia;
    STATE.claimsCircle += outCircle;

    // burn RAGE tokens from user
    require(RAGE.transferFrom(msg.sender, address(this), existingClaim.rageBurn), "tr");
    RAGE.burn(existingClaim.rageBurn);
    
    // transfer
    require(HESTIA.transfer(msg.sender, outHestia), "tr"); // claimHestia cannot be 0
    if (outCircle > 0) require(CIRCLE.transfer(msg.sender, outCircle), "tr");

    RECENT.lastClaim = msg.sender;
    emit ClaimProcessed(msg.sender);
  }

  // investOverview
  function investOverview(address wallet, uint256 usdcAmount) public view returns (RageStructs.InvestOverview memory) {
      bool isAmountValid = usdcAmount >= CONFIG.minInvest && usdcAmount <= CONFIG.maxInvest;

      uint256 dateMintable = block.timestamp + CONFIG.mintDelay;
      uint256 dateAdpAble = block.timestamp + CONFIG.adpDelay;
      uint256 dateRefundable = block.timestamp + CONFIG.refundDelay;
      uint256 usdcAdp = (usdcAmount * CONFIG.adpPercent) / 100;
      uint256 usdcRefund = (usdcAmount * CONFIG.refundPercent) / 100;
      
      // get investment percentage
      (uint256 percentHestia, uint256 percentCircle) = getInvestPercents();
      bool isPercentValid = (percentHestia + percentCircle == 100);
      
      // bonus calculations
      uint256 usdcInvestorBonus = (usdcAmount * CONFIG.investorBonus) / 100;
      uint256 usdcEcosystemBonus = (usdcAmount * CONFIG.ecosystemBonus) / 100;
      
      // split bonus amounts according to investment percentages
      uint256 usdcInvestorBonusHestia = (usdcInvestorBonus * percentHestia) / 100;
      uint256 usdcInvestorBonusCircle = (usdcInvestorBonus * percentCircle) / 100;
      uint256 usdcEcosystemBonusHestia = (usdcEcosystemBonus * percentHestia) / 100;
      uint256 usdcEcosystemBonusCircle = (usdcEcosystemBonus * percentCircle) / 100;
      uint256 usdcHestiaBonus = usdcInvestorBonusHestia + usdcEcosystemBonusHestia;
      uint256 usdcCircleBonus = usdcInvestorBonusCircle + usdcEcosystemBonusCircle;

      // convert USDC bonus amounts to token amounts
      uint256 hestiaInvestorBonus = 0;
      uint256 hestiaEcosystemBonus = 0;
      uint256 circleInvestorBonus = 0;
      uint256 circleEcosystemBonus = 0;
      if (usdcInvestorBonus > 0 || usdcEcosystemBonus > 0) {
          uint256 hestiaPrice = RAGE_ORACLE.getHestiaTwapUsdcPrice(1e18, CONFIG.twap);
          uint256 circlePrice = RAGE_ORACLE.getCircleTwapUsdcPrice(1e18, CONFIG.twap);
          
          if (hestiaPrice > 0) {
              hestiaInvestorBonus = (usdcInvestorBonusHestia * 1e18) / hestiaPrice;
              hestiaEcosystemBonus = (usdcEcosystemBonusHestia * 1e18) / hestiaPrice;
          }
          
          if (circlePrice > 0) {
              circleInvestorBonus = (usdcInvestorBonusCircle * 1e18) / circlePrice;
              circleEcosystemBonus = (usdcEcosystemBonusCircle * 1e18) / circlePrice;
          }
      }

      // check if we have enough of each token for bonuses
      bool hasBonus = false;
      (uint256 availableHestia, uint256 availableCircle) = getBonusAssets();
      uint256 totalHestiaNeeded = hestiaInvestorBonus + hestiaEcosystemBonus;
      uint256 totalCircleNeeded = circleInvestorBonus + circleEcosystemBonus;
      if (availableHestia >= totalHestiaNeeded && availableCircle >= totalCircleNeeded) {
          hasBonus = true;
      }
      
      // calculate estimated RAGE tokens
      uint256 rageEstimated = 0;
      if (isPercentValid && isAmountValid && hasBonus) {
          // deduct 2% trading fee from USDC amount being swapped
          uint256 usdcAfterFee = (usdcAmount * (100 - TRANSACTION_COSTS)) / 100;
          // incoming assets value is the USDC invested after fee plus the investor bonus
          uint256 incomingAssetsValue = usdcAfterFee + usdcInvestorBonus;
          rageEstimated = getRageFromUsdc(incomingAssetsValue);
      }
      
      bool canInvest = rageEstimated > 0 && STATE.status == 1;

      return RageStructs.InvestOverview({
          wallet: wallet,
          transactionType: "o",
          canInvest: canInvest,
          isAmountValid: isAmountValid,
          isPercentValid: isPercentValid,
          hasBonus: hasBonus,
          rageEstimated: rageEstimated,
          rageEstimatedValue: getPrice(rageEstimated),
          dateMintable: dateMintable,
          dateAdpAble: dateAdpAble,
          dateRefundable: dateRefundable,
          usdcInvest: usdcAmount,
          usdcAdp: usdcAdp,
          usdcRefund: usdcRefund,
          usdcInvestorBonus: usdcInvestorBonus,
          usdcEcosystemBonus: usdcEcosystemBonus,
          usdcHestiaBonus: usdcHestiaBonus,
          usdcCircleBonus: usdcCircleBonus,
          hestiaInvestorBonus: hestiaInvestorBonus,
          hestiaEcosystemBonus: hestiaEcosystemBonus,
          circleInvestorBonus: circleInvestorBonus,
          circleEcosystemBonus: circleEcosystemBonus,
          configHestiaPercent: percentHestia,
          configCirclePercent: percentCircle,
          configInvestorBonus: CONFIG.investorBonus,
          configMintDelay: CONFIG.mintDelay,
          configAdpDelay: CONFIG.adpDelay,
          configAdpPercent: CONFIG.adpPercent,
          configRefundPercent: CONFIG.refundPercent,
          configRefundDelay: CONFIG.refundDelay
      });
  }

  // optionOverview
  function optionOverview(address wallet, uint256 optionId) public view returns (RageStructs.OptionOverview memory) {
      RageStructs.Option memory opt = OPTIONS_MAP[optionId];
      
      // check if option exists and NFT is owned by wallet
      bool isValidOption = opt.status == 1 && RAGE_OPTION_NFT.ownerOf(optionId) == wallet;
      
      // check time-based conditions
      bool canMint = isValidOption && block.timestamp >= opt.dateMintable && STATE.status == 1;
      bool canMintWithAdp = isValidOption && block.timestamp >= opt.dateAdpAble && STATE.status == 1;
      bool canRefund = isValidOption && block.timestamp >= opt.dateRefundable && STATE.status == 1;
      
      // calculate current value of pending assets
      uint256 usdcAssets = 0;
      if (isValidOption) {
          usdcAssets = RAGE_CALCULATION.getIncomingAssetsValue(
              opt.pendingHestia,
              opt.pendingCircle,
              CONFIG.twap
          );
      }
      
      // check if contract has enough USDC for refund (either directly or by selling assets)
      bool hasRefundUsdc = false;
      uint256 contractUsdcBalance = getUsdcBalance();
      if (isValidOption) {
          // account for 2% trading fee when selling assets back to USDC
          uint256 usdcAssetsAfterFee = (usdcAssets * (100 - TRANSACTION_COSTS)) / 100;
          // total available: USDC in contract + value of pending assets after fee
          uint256 totalAvailable = contractUsdcBalance + usdcAssetsAfterFee;
          hasRefundUsdc = totalAvailable >= opt.usdcRefund;
      }

      // determine which value to use and calculate mintable RAGE
      uint256 usdcCurrent = 0;
      uint256 usdcAdpDilution;
      uint256 rageMint = 0;
      uint256 rageMintValue = 0;
      if (isValidOption) {
          usdcCurrent = usdcAssets;
          if (canMintWithAdp && usdcAssets < opt.usdcAdp) {
              usdcCurrent = opt.usdcAdp;
              usdcAdpDilution = opt.usdcAdp - usdcAssets;
          }
          
          rageMint = getRageFromUsdc(usdcCurrent);
          rageMintValue = getPrice(rageMint);
      }
      
      // calculate profitability metrics
      uint256 backingPerShare = getBackingPerShare();
      bool mintValueProfitable = false;
      bool mintBackingProfitable = false;
      
      if (rageMint > 0) {
          // check if the RAGE value exceeds the assets being put in, this means the user gets more value in RAGE than they're contributing
          mintValueProfitable = rageMintValue > usdcCurrent;
          
          // check if backing per share has DECREASED since option creation
          // when backing decreases, users get MORE RAGE tokens for their assets
          mintBackingProfitable = backingPerShare < opt.backingPerShare;
      }

      return RageStructs.OptionOverview({
          wallet: opt.walletCreated,
          optionId: optionId,
          canMint: canMint,
          canMintWithAdp: canMintWithAdp,
          canRefund: canRefund,
          hasRefundUsdc: hasRefundUsdc,
          rageMint: rageMint,
          rageMintValue: rageMintValue,
          usdcAssets: usdcAssets,
          usdcCurrent: usdcCurrent,
          usdcBalance: contractUsdcBalance,
          usdcAdpDilution: usdcAdpDilution,
          backingPerShare: backingPerShare,
          mintValueProfitable: mintValueProfitable,
          mintBackingProfitable: mintBackingProfitable
      });
  }

  // reserveClaimOverview
  function reserveClaimOverview(address wallet, uint256 rageAmount) public view returns (RageStructs.ReserveClaimOverview memory) {
      // check if user has the RAGE balance
      uint256 userRageBalance = RAGE.balanceOf(wallet);
            
      // check if user has an active claim or if this is the first claim
      RageStructs.Claim memory existingClaim = CLAIMS_MAP[wallet];
      bool hasActiveClaim = existingClaim.status == 1;
      bool isFirstClaim = existingClaim.status == 0;

      // apply fee and get assets
      uint256 feeMultiplier = 100 - CONFIG.claimFee;
      uint256 rageAfterFee = (rageAmount * feeMultiplier) / 100;
      (uint256 claimHestia, uint256 claimCircle) = getAssetsFromRage(rageAfterFee);

      uint256 dateClaimableStart = block.timestamp + CONFIG.claimDelay;
      uint256 dateClaimableEnd = dateClaimableStart + CONFIG.claimValidity;
      
      bool canReserve = rageAmount >= CONFIG.minClaim && rageAmount <= CONFIG.maxClaim && wallet != MULTISIG && claimHestia > 0 && userRageBalance >= rageAmount && STATE.status == 1;

      return RageStructs.ReserveClaimOverview({
          wallet: wallet,
          canReserve: canReserve,
          hasActiveClaim: hasActiveClaim,
          isFirstClaim: isFirstClaim,
          rageBurn: rageAmount,
          rageBurnValue: getPrice(rageAmount),
          rageAfterFee: rageAfterFee,
          claimHestia: claimHestia,
          claimCircle: claimCircle,
          claimValue: RAGE_ORACLE.getHestiaCircleTwapUsdcPrice(claimHestia, claimCircle, CONFIG.twap),
          dateClaimableStart: dateClaimableStart,
          dateClaimableEnd: dateClaimableEnd,
          configClaimFee: CONFIG.claimFee,
          configClaimDelay: CONFIG.claimDelay,
          configClaimValidity: CONFIG.claimValidity
      });
  }

  // processClaimOverview
  // multisig cannot claim as the tokens from that wallet do not have backing
  function processClaimOverview(address wallet) public view returns (RageStructs.ClaimOverview memory) {
      RageStructs.Claim memory existingClaim = CLAIMS_MAP[wallet];
      
      // check if user can claim
      uint256 userRageBalance = RAGE.balanceOf(wallet);
      bool hasBalance = userRageBalance >= existingClaim.rageBurn;
      bool isValid = block.timestamp >= existingClaim.dateClaimableStart && block.timestamp <= existingClaim.dateClaimableEnd;

      // get what user would receive if they claim now (minimum of stored vs recalculated)
      (uint256 recalcClaimHestia, uint256 recalcClaimCircle) = getAssetsFromRage(existingClaim.rageAfterFee);
      uint256 claimHestia = existingClaim.claimHestia < recalcClaimHestia ? existingClaim.claimHestia : recalcClaimHestia;
      uint256 claimCircle = existingClaim.claimCircle < recalcClaimCircle ? existingClaim.claimCircle : recalcClaimCircle;

      // calculate exact pToken amounts needed for the claim
      uint256 pHestiaNeeded = RAGE_ORACLE.getPhestiaRequiredForHestia(claimHestia); // claimHestia can never be 0
      uint256 pCircleNeeded = claimCircle > 0 ? RAGE_ORACLE.getPcircleRequiredForCircle(claimCircle) : 0;

      bool canClaim = existingClaim.status == 1 && claimHestia > 0 && recalcClaimHestia > 0 && pHestiaNeeded > 0 && hasBalance && isValid && STATE.status == 1;

      return RageStructs.ClaimOverview({
          wallet: wallet,
          canClaim: canClaim,
          hasBalance: hasBalance,
          isValid: isValid,
          rageBurn: existingClaim.rageBurn,
          rageBurnValue: getPrice(existingClaim.rageBurn),
          claimHestia: claimHestia,
          claimCircle: claimCircle,
          claimValue: RAGE_ORACLE.getHestiaCircleTwapUsdcPrice(claimHestia, claimCircle, CONFIG.twap),
          pHestiaNeeded: pHestiaNeeded,
          pCircleNeeded: pCircleNeeded,
          recalcClaimHestia: recalcClaimHestia,
          recalcClaimCircle: recalcClaimCircle,
          recalcClaimValue: RAGE_ORACLE.getHestiaCircleTwapUsdcPrice(recalcClaimHestia, recalcClaimCircle, CONFIG.twap),
          backingPerShare: getBackingPerShare()
      });
  }
}

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

pragma solidity ^0.8.26;

/**
 * @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);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import {RageStructs} from "./RageStructs.sol";

interface IRage {
    // ERC20 Events
    event Transfer(address indexed from, address indexed to, uint256 amount);
    event Approval(address indexed owner, address indexed spender, uint256 amount);
    
    // Rage Events
    event RageChaosEngineSet(address indexed oldOwner, address indexed newOwner);
    event SupplyRequested(address indexed rce, uint256 amount, uint256 percent);
    event RageBurned(uint256 amount);
    
    // ERC20 Functions
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
    function transfer(address to, uint256 amount) external returns (bool);
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    
    // ERC20 Metadata
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
    
    // Rage Constants
    function FINAL_MAX_SUPPLY() external view returns (uint256);
    
    // Rage View Functions
    function getTotalSupply() external view returns (uint256);
    function getInitialSupply() external view returns (uint256);
    function getMintedSupply() external view returns (uint256);
    function getBurnedSupply() external view returns (uint256);
    function getMintableSupply() external view returns (uint256);
    function getState() external view returns (RageStructs.RageState memory);
    
    // Rage State-Changing Functions
    function burn(uint256 amount) external;
    function requestSupply(uint256 percent) external;
    function setRageChaosEngine(address newOwner) external;
}

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

interface IRageCalculation {
    // External functions
    function calculateRageFmv(uint256 rageActiveSupply, uint256 activeAssetsValue) external pure returns(uint256);
    
    function getRageFromAssets(
        uint256 hestiaIn, 
        uint256 circleIn,
        uint256 rageActiveSupply, 
        uint256 activeAssetsValue,
        uint32 interval
    ) external view returns(uint256);
    
    function getAssetsFromRage(
        uint256 rageSupply,
        uint256 rageActiveSupply,
        uint256 totalActiveAssetsValue,
        uint256 activePhestiaAmount,
        uint256 activePcircleAmount,
        uint32 interval
    ) external view returns(
        uint256 pHestiaOut, 
        uint256 pCircleOut, 
        uint256 pHestiaValueOut, 
        uint256 pCircleValueOut, 
        uint256 totalValueOut
    );
    
    // Public view functions
    function calculateRageUnderlying(
        uint256 rageActiveSupply, 
        uint256 activePhestia, 
        uint256 activePcircle
    ) external view returns (uint256 underlyingHestia, uint256 underlyingCircle);
    
    function getDetailedRawAssets(
        uint256 hestiaAmount,
        uint256 circleAmount,
        uint32 interval
    ) external view returns (
        uint256 hestiaValue,
        uint256 circleValue,
        uint256 totalValue,
        uint256 hestiaPercent,
        uint256 circlePercent
    );
    
    function getDetailedRageUnderlying(
        uint256 rageActiveSupply, 
        uint256 activePhestia, 
        uint256 activePcircle,
        uint32 interval
    ) external view returns (
        uint256 underlyingHestia, 
        uint256 underlyingCircle, 
        uint256 hestiaValue, 
        uint256 circleValue, 
        uint256 totalValue, 
        uint256 hestiaPercent, 
        uint256 circlePercent
    );
    
    function getDetailedActiveAssets(
        uint256 pHestiaIn, 
        uint256 pCircleIn,
        uint32 interval
    ) external view returns (
        uint256 underlyingHestia, 
        uint256 underlyingCircle, 
        uint256 hestiaValue, 
        uint256 circleValue, 
        uint256 totalValue, 
        uint256 hestiaPercent, 
        uint256 circlePercent
    );
    
    function calculateBackingPerShare(
        uint256 rageActiveSupply, 
        uint256 activePhestia, 
        uint256 activePcircle,
        uint256 percentHestia, 
        uint256 percentCircle,
        uint256 initialHestia,
        uint256 initialCircle
    ) external view returns (uint256);
    
    function getIncomingAssetsValue(
        uint256 hestiaIn, 
        uint256 circleIn,
        uint32 interval
    ) external view returns(uint256);
    
    // Public pure functions
    function calculateIncomingAssetsValue(
        uint256 hestiaIn, 
        uint256 circleIn, 
        uint256 hestiaUsdcPriceAfterBondDebond,
        uint256 circleUsdcPriceAfterBondDebond
    ) external pure returns(uint256);
    
    function calculateRageFromUsdc(
        uint256 rageActiveSupply, 
        uint256 activeAssetsValue, 
        uint256 incomingAssetsValue
    ) external pure returns(uint256);
    
    function calculateAssetsFromRage(
        uint256 rageSupply, 
        uint256 rageActiveSupply, 
        uint256 totalActiveAssetsValue
    ) external pure returns(uint256);
    
    function getActiveAssetsFromValue(
        uint256 outgoingAssetsValue,
        uint256 activePhestiaAmount,
        uint256 activePcircleAmount,
        uint32 interval
    ) external view returns(
        uint256 pHestiaOut, 
        uint256 pCircleOut, 
        uint256 pHestiaValueOut, 
        uint256 pCircleValueOut, 
        uint256 totalValueOut
    );
    
    function calculateActiveAssetsFromValue(
        uint256 outgoingAssetsValue,
        uint256 activePhestiaAmount,
        uint256 activePcircleAmount,
        uint256 pHestiaUsdcPriceAfterDebond,
        uint256 pCircleUsdcPriceAfterDebond
    ) external pure returns(
        uint256 pHestiaOut, 
        uint256 pCircleOut, 
        uint256 pHestiaValueOut, 
        uint256 pCircleValueOut, 
        uint256 totalValueOut
    );
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import {RageStructs} from "./RageStructs.sol";

interface IRageChaosEngine {
    // Events
    event LockNft(uint256 nftId);
    event AutomatorSet(address automator);
    event RageBuyingProtocolProposed(address indexed proposer, address indexed pendingRbp);
    event RageBuyingProtocolSet(address indexed newRbp);
    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);
    event SupplyRequested(uint256 percent);
    event SupplyBurned(uint256 amount);
    event YearlyAllowanceRequested(address indexed requester, address indexed recipient, uint256 amount, uint256 activeSupply);
    event RageTransferred(address recipient, uint256 amount);
    event ConfigChanged(uint256 stackRage, uint256 stackHestia, uint256 boostRage, uint128 crushDecrease, bool crushBuy, uint256 burstRage, uint256 burstLoop, uint256 slippage, address podAddress, address sideAddress1, address sideAddress2);
    event PoolBoosted(uint256 rageIncrease, uint256 usdcIncrease);
    event UnderlyingStacked(uint256 rageSold, uint256 pHestia, uint256 pCircle);
    event RageCrushed(uint256 rageBurned, uint256 usdcBought);
    event RageBursted(uint256 rageCollected, uint256 usdcCollected);
    
    // Withdrawal functions
    function withdrawEth() external;
    function withdrawToken(address tokenAdr) external;
    
    // NFT management
    function lockNFT() external;
    
    // Ownership and access control
    function transferOwnership(address newOwner) external;
    function setRageBuyingProtocol(address newRbp) external;
    function setAutomator(address automator) external;
    
    // RAGE token operations
    function requestSupply(uint256 percent) external;
    function burnSupply(uint256 amount) external;
    function requestYearlyAllowance(uint256 percent) external;
    function transferRage(address recipient, uint256 amount) external;
    
    // Configuration
    function setConfigs(RageStructs.RceConfig calldata newConfig) external;
    
    // Core functionality
    function stackUnderlying() external;
    function poolBoost() external;
    function rageCrush() external;
    function rageBurst() external;
    
    // View functions
    function getMultisig() external pure returns (address);
    function getAutomator() external view returns (address);
    function getOwners() external view returns (address owner1, address owner2);
    function getRageBuyingProtocol() external view returns (address);
    function getActiveSupply() external view returns (uint256);
    function getRageInNft() external view returns (uint256);
    function getState() external view returns (RageStructs.RceState memory);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import {RageStructs} from "./RageStructs.sol";

interface IRageOptionNft {
    // ERC721 Events
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
    
    // RageOptionNft Events
    event BaseUriUpdated(string newBaseURI);
    event OptionMinted(address indexed recipient, uint256 indexed tokenId);
    
    // ERC721 Functions
    function balanceOf(address owner) external view returns (uint256);
    function ownerOf(uint256 tokenId) external view returns (address);
    function safeTransferFrom(address from, address to, uint256 tokenId) external;
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
    function transferFrom(address from, address to, uint256 tokenId) external;
    function approve(address to, uint256 tokenId) external;
    function setApprovalForAll(address operator, bool approved) external;
    function getApproved(uint256 tokenId) external view returns (address);
    function isApprovedForAll(address owner, address operator) external view returns (bool);
    
    // ERC721 Metadata
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 tokenId) external view returns (string memory);
    
    // RageOptionNft Functions
    function exists(uint256 tokenId) external view returns (bool);
    function totalSupply() external view returns (uint256);
    function getRageChaosEngine() external view returns (address);
    function getRageBuyingProtocol() external view returns (address);
    function isAutomator(address account) external view returns (bool);
    function isRageBuyingProtocol(address account) external view returns (bool);
    function contractURI() external view returns (string memory);
    function getState() external view returns (RageStructs.RonState memory);
    function getOption(uint256 tokenId) external view returns (RageStructs.Option memory);
    function getAllForOwner(address owner, uint256 status) external view returns (RageStructs.Option[] memory);
    function getAllOptions(uint256 offset, uint256 limit) external view returns (RageStructs.Option[] memory);
    function getOptionsOverview(uint32 twap, uint256 refundTime) external view returns (RageStructs.OptionsOverview memory);
    function getAllClaims(uint256 offset, uint256 limit) external view returns (RageStructs.Claim[] memory);
    function getClaimsOverview() external view returns (RageStructs.ClaimsOverview memory);
    
    // State-changing functions
    function setBaseURI(string memory newBaseURI) external;
    function mint(address recipient, uint256 tokenId) external;
    
    // ERC165
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import {RageStructs} from "./RageStructs.sol";
interface IRageOracle {
    // TWAP price functions
    function getWethTwapUsdcPrice(uint256 amount, uint32 interval) external view returns (uint256);
    function getHestiaTwapUsdcPrice(uint256 amount, uint32 interval) external view returns (uint256);
    function getCircleTwapUsdcPrice(uint256 amount, uint32 interval) external view returns (uint256);
    function getHestiaCircleTwapUsdcPrice(uint256 hestiaAmount, uint256 circleAmount, uint32 interval) external view returns (uint256);
    function getRageTwapUsdcPrice(uint256 amount, uint32 interval) external view returns (uint256);
    
    // Price after bond/debond functions
    function getHestiaUsdcPriceAfterBondDebond(uint256 tknAmount, uint32 interval) external view returns (uint256);
    function getCircleUsdcPriceAfterBondDebond(uint256 tknAmount, uint32 interval) external view returns (uint256);
    
    // Price after debond functions for pTokens
    function getPhestiaUsdcPriceAfterDebond(uint256 ptknAmount, uint32 interval) external view returns (uint256);
    function getPcircleUsdcPriceAfterDebond(uint256 ptknAmount, uint32 interval) external view returns (uint256);
    
    // Token conversion functions
    function getPhestiaInHestiaAfterDebond(uint256 ptknAmount) external view returns (uint256);
    function getPcircleInCircleAfterDebond(uint256 ptknAmount) external view returns (uint256);
    
    // Required pToken amount functions
    function getPhestiaRequiredForHestia(uint256 tknAmount) external view returns (uint256);
    function getPcircleRequiredForCircle(uint256 tknAmount) external view returns (uint256);
    
    // prices function
    function getPrices(uint32 interval) external view returns (RageStructs.OraclePrices memory);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
interface IRageSwapper {
    // Administrative functions
    function withdrawEth() external;
    function withdrawToken(address tokenAdr) external;
    
    // ETH swap
    function swapEthForUsdc(uint256 deadline) external payable returns (uint256);
    
    // Individual token swaps
    function swapHestiaForUsdc(uint256 amount, uint256 slippage, uint256 deadline) external returns (uint256);
    function swapUsdcForHestia(uint256 amount, uint256 slippage, uint256 deadline) external returns (uint256);
    function swapRageForUsdc(uint256 amount, uint256 slippage, uint256 deadline) external returns (uint256);
    function swapUsdcForRage(uint256 amount, uint256 slippage, uint256 deadline) external returns (uint256);
    function swapCircleForUsdc(uint256 amount, uint256 slippage, uint256 deadline) external returns (uint256);
    function swapUsdcForCircle(uint256 amount, uint256 slippage, uint256 deadline) external returns (uint256);
    
    // Rage to underlying swap
    function swapRageForUnderlying(
        uint256 amount,
        uint256 percentHestia,
        uint256 percentCircle,
        uint256 slippage,
        uint256 deadline
    ) external returns (uint256 pHestiaOut, uint256 pCircleOut);
    
    // Bond/Debond conversions
    function convertHestiaToPHestia(uint256 amount, uint256 deadline) external returns (uint256);
    function convertPHestiaToHestia(uint256 amount, uint256 deadline) external returns (uint256);
    function convertCircleToPCircle(uint256 amount, uint256 deadline) external returns (uint256);
    function convertPCircleToCircle(uint256 amount, uint256 deadline) external returns (uint256);
    
    // Multi-asset swaps
    function swapUsdcToAssets(
        uint256 usdcIn,
        uint256 percentHestia,
        uint256 percentCircle,
        uint256 hestiaSlippage,
        uint256 circleSlippage,
        uint256 deadline
    ) external returns (uint256 hestiaOut, uint256 circleOut);
    
    function swapAssetsToUsdc(
        uint256 hestiaIn,
        uint256 circleIn,
        uint256 hestiaSlippage,
        uint256 circleSlippage,
        uint256 deadline
    ) external returns (uint256);
    
    // Multi-asset bond/debond
    function bondAssets(
        uint256 hestiaIn,
        uint256 circleIn,
        uint256 deadline
    ) external returns (uint256 pHestiaOut, uint256 pCircleOut);
    
    function debondAssets(
        uint256 pHestiaIn,
        uint256 pCircleIn,
        uint256 deadline
    ) external returns (uint256 hestiaOut, uint256 circleOut);
    
    // Uniswap callback
    function uniswapV3SwapCallback(int amount0, int amount1, bytes calldata data) external;
}

File 9 of 10 : RageStructs.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

library RageStructs {
  struct RbpState {
    uint256 version;                   // rbp version
    RageStructs.RbpStateValue state;   // rbp internal state
    RageStructs.RbpConfig config;      // rbp internal configurations
    RageStructs.RbpRecent recent;      // rbp most recent actions
  }

  struct RbpViewState {
    uint256 price;                     // current rage price
    uint256 activeSupply;              // active supply as declared by rce
    uint256 fmv;                       // current rage fmv
    uint256 backingPerShare;           // current rage backing per share
    uint256 activeAssetsUsdcValue;     // Total USDC value of active assets
    uint256 rawHestia;                 // Raw HESTIA balance
    uint256 rawCircle;                 // Raw CIRCLE balance
    uint256 pendingHestia;             // Pending HESTIA
    uint256 pendingCircle;             // Pending CIRCLE
    uint256 bonusHestia;               // Available bonus HESTIA
    uint256 bonusCircle;               // Available bonus CIRCLE
    uint256 activePhestia;             // Active pHESTIA balance
    uint256 activePcircle;             // Active pCIRCLE balance
    uint256 activeHestia;             // Active HESTIA balance
    uint256 activeCircle;             // Active CIRCLE balance
    uint256 investPercentHestia;       // HESTIA investment percentage
    uint256 investPercentCircle;       // CIRCLE investment percentage
    uint256 underlyingHestia;          // HESTIA per RAGE
    uint256 underlyingCircle;          // CIRCLE per RAGE
    uint256 underlyingHestiaValue;     // USDC value of HESTIA per RAGE
    uint256 underlyingCircleValue;     // USDC value of CIRCLE per RAGE
    uint256 underlyingTotalValue;      // Total USDC value per RAGE
    uint256 underlyingHestiaPercent;   // HESTIA percentage
    uint256 underlyingCirclePercent;   // CIRCLE percentage
    uint256 rageFromOnePercentUsdc;    // RAGE received from one percent of active value in USDC
    uint256 hestiaFromOnePercentRage;  // HESTIA received from one percent of Rage active supply
    uint256 circleFromOnePercentRage;  // CIRCLE received from one percent of Rage active supply 
 }

  struct RageState {
    uint256 version;                   // version of the rage contract
    address owner;                     // owner of the rage token
    uint256 supply;                    // current rage supply
    uint256 initial;                   // rage initial supply
    uint256 mint;                      // total minted rage
    uint256 burn;                      // total burned rage
    uint256 mintable;                  // supply that can still be minted
    uint256 lastRequestSupply;         // timestamp of last supply request
  }

  struct RonState {
    uint256 version;                   // version of the rage option contract
    address rce;                       // address of the rce contract
    address rbp;                       // address of the rbp contract
    uint256 supply;                    // total nft supply
    string baseUri;                    // base uri for the nft metadata
    string contractUri;                // uri of the contract metadata json file
  }

  struct RbpStateValue {
    uint256 status;                    // Protocol status (0 = off, 1 = on)
    uint256 nextConfigTime;            // Next allowed configuration update timestamp
    uint256 pendingHestia;             // Amount of HESTIA tokens in pending backing
    uint256 pendingCircle;             // Amount of CIRCLE tokens in pending backing
    uint256 totalOptions;              // Total number of investment options created
    uint256 optionsMint;               // Options converted to RAGE tokens
    uint256 optionsAdp;                // Options minted using Asset Decline Protection
    uint256 optionsAdpValue;           // USDC value of options minted using Asset Decline Protection
    uint256 optionsRefund;             // Options that were refunded
    uint256 optionsRefundValue;        // USDC value of refunded options
    uint256 totalInvest;               // USDC value of invest
    uint256 totalInvestorBonus;        // USDC value of bonus given to investor
    uint256 totalEcosystemBonus;       // USDC value of bonus given to ecosystem
    uint256 totalDebt;                 // Total USDC owed for potential refunds
    uint256 totalClaims;               // Total number of unique claim wallets
    uint256 totalAdpDilution;          // Total USDC value diluted through ADP
    uint256 claimsProcessed;           // Number of claims successfully processed
    uint256 claimsHestia;              // Total HESTIA tokens claimed
    uint256 claimsCircle;              // Total CIRCLE tokens claimed
  }
  
  struct OraclePrices {
    uint256 wethTwapUsdcPrice;         // TWAP price of WETH in USDC
    uint256 hestiaTwapUsdcPrice;       // TWAP price of HESTIA in USDC
    uint256 circleTwapUsdcPrice;       // TWAP price of CIRCLE in USDC
    uint256 hestiaCircleTwapUsdcPrice; // TWAP price of 1 Hestia and 1 Circle in USDC
    uint256 rageTwapUsdcPrice;         // TWAP price of RAGE in USDC
    uint256 hestiaUsdcPriceAfterBondDebond;  // HESTIA price after bond/debond fees
    uint256 circleUsdcPriceAfterBondDebond;  // CIRCLE price after bond/debond fees
    uint256 pHestiaUsdcPriceAfterDebond;     // pHESTIA value in USDC after debonding
    uint256 pCircleUsdcPriceAfterDebond;     // pCIRCLE value in USDC after debonding
    uint256 pHestiaInHestiaAfterDebond;      // HESTIA received per pHESTIA after debond
    uint256 pCircleInCircleAfterDebond;      // CIRCLE received per pCIRCLE after debond
    uint256 pHestiaRequiredForHestia;        // pHESTIA needed to get 1 HESTIA
    uint256 pCircleRequiredForCircle;        // pCIRCLE needed to get 1 CIRCLE
    uint256 pHestiaRequiredForHestiaResult;  // HESTIA received when doing pHestiaRequiredForHestia (should be close to 1)
    uint256 pCircleRequiredForCircleResult;  // CIRCLE received when doing pHestiaRequiredForHestia (should be close to 1)
  }
  
  struct RbpConfig {
    uint256 minInvest; // Adjustable from $1 to $100 (default $10) - determines the minimum amount of USDC to receive to create a position
    uint256 maxInvest; // Adjustable from $1000 to $100000 (default $10000) - determines the maximum amount of USDC to receive to create a position
    uint256 hestiaPercent; // Adjustable from 55% to 95% (default: 80%) - determines the percentage of each investment and bonus allocated to HESTIA tokens
    uint256 investorBonus; // Adjustable from 1% to 15% (default: 6%) - sets the bonus percentage in both tokens (at their ratios) given to investors on their token purchases to cover wrapping fees and provide net benefit
    uint256 mintDelay; // Adjustable from 1 to 90 days (default: 3 days) - controls the mandatory waiting period after investment before NFT receipts can be converted to RAGE tokens
    uint256 adpDelay; // Adjustable from 30 to 300 days (default: 60 days) - sets the waiting period after investment before Asset Decline Protection becomes available for NFT conversion
    uint256 adpPercent; // Adjustable from 55% to 90% (default: 75%) - determines the percentage of original investment value used for Asset Decline Protection calculations. Cannot be more than refund percent.
    uint256 ecosystemBonus; // Adjustable from 1% to 15% (default: 6%) - controls the bonus tokens (distributed at their ratios) added to active assets with each new investment
    uint256 refundPercent; // Adjustable from 55% to 95% (default: 85%) - sets the percentage of original investment recoverable through the USDC refund mechanism (does not affect Asset Decline Protection calculations)
    uint256 refundDelay; // Adjustable from 500 days to 1500 days (default 1000 days) - sets the waiting period after investment before a refund can be requested
    uint256 minClaim; // Adjustable from 1e15 to 1e18 (default 1e18) - sets the minimum amount of Rage to reserve a claim
    uint256 maxClaim; // Adjustable from 100e18 to infinity (default 1000e18) - sets the maximum amount of Rage to reserve a claim
    uint256 claimFee; // Adjustable from 1% to 20% (default: 10%) - determines the fee applied when users claim their RAGE tokens
    uint256 claimDelay; // Adjustable from 10 to 100 days (default: 30 days) - sets the waiting period between creating and executing claims
    uint256 claimValidity; // Adjustable from 1 to 30 days (default: 10 days) - sets the validity period of a claim
    uint256 slippage; // Adjustable from 0 (off) to 2500 (25%), default is 500 or 5%, slippage when swapping on the pool
    uint32 twap; // Adjustable from 1 seconds to 3600 seconds, default is 30 seconds, twap duration for price calculation
  }

  struct RceConfig {
    uint256 stackRage;      // amount of rage to sell in stack underlying (range: 100-10000, default: 100)
    uint256 stackHestia;    // percent of hestia for stack underlying (range: 0-100, default: 80)
    uint256 boostRage;      // amount of rage to sell in pool boost (0=off, range: 100-10000, default: 100)
    uint128 crushDecrease;  // liquidity decrease for rageCrush (0=off, range: 100-10000, default: 0)
    bool crushBuy;          // whether rageCrush buys with collected USDC (default: true)
    uint256 burstRage;      // amount of rage to sell in rage burst (range: 1e18-200e18, default: 10e18)
    uint256 burstLoop;      // number of loops to do in rage burst (range: 1-5, default: 2)
    uint256 slippage;       // slippage for swaps/liquidity (0=off, max: 2500, default: 500)
    address podAddress;     // pod address excluded from active supply (default: address(0))
    address sideAddress1;   // side pool address #1 excluded from active supply (default: address(0))
    address sideAddress2;   // side pool address #2 excluded from active supply (default: address(0))
  }

  struct RbpRecent {
    uint256 lastInvest;                // Option ID of most recent investment
    uint256 lastMintRage;              // Option ID of most recent RAGE mint
    uint256 lastRefund;                // Option ID of most recent refund
    address lastReserveClaim;          // Wallet address of most recent claim reservation
    address lastClaim;                 // Wallet address of most recent claim execution
  }
  
  struct Option {
    uint256 id;                        // Unique option identifier
    uint256 version;                   // Contract version when created
    uint8 status;                      // Option status (1=active, 2=minted, 3=minted with ADP, 4=refunded)
    string transactionType;            // Transaction type ("i"=invest, "e"=ETH invest, "r"=receive)
    address walletCreated;             // Original creator wallet address
    address walletUpdated;             // Wallet that last updated the option
    address referral;                  // Referral address if applicable
    uint256 dateCreated;               // Timestamp when option was created
    uint256 dateUpdated;               // Timestamp of last update
    uint256 dateMintable;              // Timestamp when RAGE minting becomes available
    uint256 dateAdpAble;               // Timestamp when ADP protection activates
    uint256 dateRefundable;            // Timestamp when refund becomes available
    uint256 price;                     // price per rage when option was created
    uint256 fmv;                       // fmv when option was created
    uint256 backingPerShare;           // backing per share at the moment the option was created
    uint256 usdcInvest;                // Original USDC investment amount
    uint256 usdcAdp;                   // USDC value protected by ADP
    uint256 usdcRefund;                // USDC amount refundable
    uint256 pendingHestia;             // HESTIA tokens pending in this option
    uint256 pendingCircle;             // CIRCLE tokens pending in this option
    uint256 rageEstimated;             // Estimated RAGE tokens at creation
    uint256 rageMinted;                // Actual RAGE tokens minted
    uint256 usdcAdpDilution;           // USDC value diluted if ADP was used
    uint256 usdcInvestorBonus;          // USDC value of bonus given to investor
    uint256 hestiaInvestorBonus;       // HESTIA bonus given to investor
    uint256 circleInvestorBonus;       // CIRCLE bonus given to investor
    uint256 usdcEcosystemBonus;          // USDC value of bonus given to ecosystem
    uint256 hestiaEcosystemBonus;       // HESTIA bonus given to ecosystem
    uint256 circleEcosystemBonus;       // CIRCLE bonus given to ecosystem
    uint256 configHestiaPercent;       // HESTIA allocation % at creation
    uint256 configCirclePercent;       // CIRCLE allocation % at creation
    uint256 configInvestorBonus;       // Investor bonus % at creation
    uint256 configMintDelay;           // Mint delay at creation
    uint256 configAdpDelay;            // ADP delay at creation
    uint256 configAdpPercent;          // ADP percentage at creation
    uint256 configRefundPercent;       // Refund percentage at creation
    uint256 configRefundDelay;         // Refund delay at creation
  }
  
  struct Claim {
    address wallet;                    // Wallet address making the claim
    uint256 version;                   // Contract version when created
    uint8 status;                      // Claim status (1=active, 2=claimed)
    uint256 claimedCount;              // Number of times this wallet has claimed
    uint256 dateCreated;               // Timestamp when claim was reserved
    uint256 dateUpdated;               // Timestamp of last update
    uint256 dateClaimableStart;        // Start of claim validity window
    uint256 dateClaimableEnd;          // End of claim validity window
    uint256 rageBurn;                  // RAGE tokens to burn (before fee)
    uint256 rageAfterFee;              // RAGE tokens after fee deduction
    uint256 price;                     // price per rage when claim was created
    uint256 fmv;                       // fmv when claim was created
    uint256 backingPerShare;           // backing per share at the moment the claim was created
    uint256 claimHestia;               // HESTIA tokens claimable
    uint256 claimCircle;               // CIRCLE tokens claimable
    uint256 lastClaimHestia;           // HESTIA claimed in last execution
    uint256 lastClaimCircle;           // CIRCLE claimed in last execution
    uint256 totalClaimHestia;           // All HESTIA claimed by this wallet
    uint256 totalClaimCircle;           // All CIRCLE claimed by this wallet
    uint256 configClaimFee;            // Claim fee % at reservation
    uint256 configClaimDelay;          // Claim delay at reservation
    uint256 configClaimValidity;       // Validity period at reservation
  }
  
  struct OptionsOverview {
    uint256 totalDebt;                // Total USDC owed for potential refunds
    uint256 totalDebtReal;            // Real debt considering current asset values
    uint256 adpDebt;                  // USDC owed for ADP-eligible options
    uint256 adpDebtReal;              // Real ADP debt considering current asset values
    uint256 refundDebt;               // USDC owed for refundable options
    uint256 refundDebtReal;           // Real refund debt considering current asset values
    uint256 mintableRage;             // Total RAGE tokens mintable from active options
    uint256 usdcInvested;             // Total USDC invested across all options
    uint256 usdcBonus;                // Total USDC value of all bonuses
    uint256 hestiaInvestorBonus;      // Total HESTIA given as investor bonus
    uint256 circleInvestorBonus;      // Total CIRCLE given as investor bonus
    uint256 optionActiveCount;        // Count of options with status 1
    uint256 optionMintCount;          // Count of options with status 2
    uint256 optionAdpCount;           // Count of options with status 3
    uint256 optionRefundCount;        // Count of options with status 4
    uint256 totalPendingHestia;       // Sum of all pendingHestia in active options
    uint256 totalPendingCircle;       // Sum of all pendingCircle in active options
    uint256 optionsRefundableWithinThreshold; // Options becoming refundable soon (for liquidation planning)
    uint256 refundDebtRealThreshold;     // Real refund debt in the next 30 days considering current asset values
    uint256 optionsMintableNow;      // Active options that can be minted right now
    uint256 optionsAdpAbleNow;       // Active options eligible for ADP right now
    uint256 optionsRefundableNow;    // Active options that can be refunded right now
    uint256 totalAdpDilution;         // Total USDC diluted through ADP (from status 3 options)
    uint256 totalRefundValue;         // Total USDC refunded (from status 4 options)
    uint256 totalRageMinted;          // Sum of rageMinted from minted options
  }

  struct ClaimsOverview {
    uint256 activeClaimsCount;        // Count of active claims (status 1)
    uint256 claimedCount;             // Count of claimed (status 2)
    uint256 pendingClaimsCount;       // Active claims not yet in claim window
    uint256 claimableNowCount;        // Active claims currently in claim window
    uint256 expiredClaimsCount;       // Active claims past their window
    uint256 pendingHestia;            // Total HESTIA in pending claims
    uint256 pendingCircle;            // Total CIRCLE in pending claims
    uint256 claimableHestia;          // Total HESTIA in claimable-now claims
    uint256 claimableCircle;          // Total CIRCLE in claimable-now claims
    uint256 totalRageToBurn;          // Total RAGE that will be burned from active claims
    uint256 totalClaimedHestia;       // Historical total of HESTIA claimed
    uint256 totalClaimedCircle;       // Historical total of CIRCLE claimed
  }

  struct InvestOverview {
    address wallet;                    // Investor wallet address
    string transactionType;            // Transaction type identifier
    bool canInvest;                    // Whether investment is allowed
    bool isAmountValid;                // Whether amount is within min/max limits
    bool isPercentValid;               // Whether allocation percentages sum to 100%
    bool hasBonus;                     // Whether bonus HESTIA is available
    uint256 rageEstimated;             // Estimated RAGE tokens to receive
    uint256 rageEstimatedValue;        // Estimated USDC value of Rage tokens to receive
    uint256 dateMintable;              // When RAGE minting becomes available
    uint256 dateAdpAble;               // When ADP protection activates
    uint256 dateRefundable;            // When refund becomes available
    uint256 usdcInvest;                // USDC amount to invest
    uint256 usdcAdp;                   // USDC protected by ADP
    uint256 usdcRefund;                // USDC refundable amount
    uint256 usdcInvestorBonus;         // USDC value of investor bonus
    uint256 usdcEcosystemBonus;        // USDC value of ecosystem bonus
    uint256 usdcHestiaBonus;            // USDC value of Hestia investor + ecosystem bonus
    uint256 usdcCircleBonus;            // USDC value of Circle investor + ecosystem bonus
    uint256 hestiaInvestorBonus;       // HESTIA tokens as investor bonus
    uint256 hestiaEcosystemBonus;      // HESTIA tokens as ecosystem bonus
    uint256 circleInvestorBonus;       // CIRCLE tokens as investor bonus
    uint256 circleEcosystemBonus;      // CIRCLE tokens as ecosystem bonus
    uint256 configHestiaPercent;       // Current HESTIA allocation %
    uint256 configCirclePercent;       // Current CIRCLE allocation %
    uint256 configInvestorBonus;       // Current investor bonus %
    uint256 configMintDelay;           // Current mint delay setting
    uint256 configAdpDelay;            // Current ADP delay setting
    uint256 configAdpPercent;          // Current ADP percentage
    uint256 configRefundPercent;       // Current refund percentage
    uint256 configRefundDelay;         // Current refund delay
  }

  struct OptionOverview {
    address wallet;                    // Option owner wallet address
    uint256 optionId;                  // Id of the option nft
    bool canMint;                      // Whether RAGE minting is available
    bool canMintWithAdp;               // Whether ADP minting is available
    bool canRefund;                    // Whether refund is available
    bool hasRefundUsdc;                // Whether contract has USDC for refund
    uint256 rageMint;                  // RAGE tokens that can be minted
    uint256 rageMintValue;             // USDC value of Rage tokens to be minted
    uint256 usdcAssets;                // Current USDC value of the assets
    uint256 usdcCurrent;               // Current USDC value for minting
    uint256 usdcBalance;               // Contract's USDC balance
    uint256 usdcAdpDilution;           // ADP dilution amount in USDC
    uint256 backingPerShare;           // Current backing per share
    bool mintValueProfitable;          // Whether minting rage is profitable (rageMintValue higher than assets or adp value)
    bool mintBackingProfitable;        // Whether minting rage now has less backing that when option was created
  }
  
  struct ReserveClaimOverview {
    address wallet;                    // Claimer wallet address
    bool canReserve;                   // Whether claim can be reserved
    bool hasActiveClaim;               // Whether wallet has active claim
    bool isFirstClaim;                 // Whether this is wallet's first claim
    uint256 rageBurn;                  // RAGE to burn (before fee)
    uint256 rageBurnValue;             // USDC value of rage to burn (before fee)
    uint256 rageAfterFee;              // RAGE after fee deduction
    uint256 claimHestia;               // HESTIA claimable
    uint256 claimCircle;               // CIRCLE claimable
    uint256 claimValue;                // USDC value of claim assets
    uint256 dateClaimableStart;        // Start of validity window
    uint256 dateClaimableEnd;          // End of validity window
    uint256 configClaimFee;            // Current claim fee %
    uint256 configClaimDelay;          // Current claim delay
    uint256 configClaimValidity;       // Current validity period
  }
  
  struct ClaimOverview {
    address wallet;                    // Claimer wallet address
    bool canClaim;                     // Whether claim can be executed
    bool hasBalance;                   // Whether wallet has RAGE balance
    bool isValid;                      // Whether within validity window
    uint256 rageBurn;                  // RAGE to burn (before fee)
    uint256 rageBurnValue;             // USDC value of rage to burn (before fee)
    uint256 claimHestia;               // HESTIA to receive
    uint256 claimCircle;               // CIRCLE to receive
    uint256 claimValue;                // USDC value of claim assets
    uint256 pHestiaNeeded;             // pHestia needed for debond
    uint256 pCircleNeeded;             // pCircle needed for debond
    uint256 recalcClaimHestia;         // Recalculated HESTIA amount
    uint256 recalcClaimCircle;         // Recalculated CIRCLE amount
    uint256 recalcClaimValue;          // USDC value of recalculated claim assets
    uint256 backingPerShare;           // Current backing per share
  }

  struct RceStateValue {
    uint256 nextBoostTime;
    uint256 nextStackTime;
    uint256 nextCrushTime;
    uint256 nextBurstTime;
    uint256 nextConfigTime;
    uint256 nextYearlyAllowance;
    address poolToken0;
    uint256 nftLocked;
    address rageBuyingProtocol;
    address pendingRbp;
    address ownerProposer;
    address owner1;
    address owner2;
    address automator;
    uint256 amountAllowance;
    uint256 amountTransfer;
    uint256 amountMint;
    uint256 amountRageStack;
    uint256 amountUsdcBoost;
    uint256 amountRageBoost;
    uint256 amountUsdcCrush;
    uint256 lastStackTime;
    uint256 lastStackAmount;
    uint256 lastBoostTime;
    uint256 lastBoostAmount;
    uint256 lastCrushTime;
    uint256 lastCrushAmount;
    uint256 lastBurstTime;
    uint256 lastBurstAmount;
  }

  struct RceState {
    uint256 version;                    // Contract version identifier
    address rageSwapper;               // Address of the Rage Swapper contract for DEX operations
    address multisig;                  // Multisig wallet address for admin operations
    address poolAddress;               // Uniswap V3 pool address for RAGE/USDC
    uint256 nftId;                     // Uniswap V3 NFT position ID
    uint256 nftSupply;                  // RAGE tokens within the NFT of the RAGE/USDC pool
    uint256 activeSupply;               // RAGE tokens that are active and backed by underlying assets
    uint256 rageBalance;               // Current RAGE balance in contract
    uint256 usdcBalance;               // Current USDC balance in contract
    RceConfig config;
    RceStateValue state;
  }
}

File 10 of 10 : ReentrancyGuard.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Gas optimized reentrancy protection for smart contracts.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
    uint256 private locked = 1;

    modifier nonReentrant() virtual {
        require(locked == 1, "REENTRANCY");

        locked = 2;

        _;

        locked = 1;
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "viaIR": true,
  "evmVersion": "paris",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"rce","type":"address"},{"internalType":"address","name":"rage","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"calc","type":"address"},{"internalType":"address","name":"swap","type":"address"},{"internalType":"address","name":"rOption","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"}],"name":"ClaimProcessed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"}],"name":"ClaimReserved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"optionId","type":"uint256"}],"name":"OptionCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"optionId","type":"uint256"}],"name":"OptionRefunded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"optionId","type":"uint256"}],"name":"RageMinted","type":"event"},{"inputs":[],"name":"getActiveAssets","outputs":[{"internalType":"uint256","name":"activePhestia","type":"uint256"},{"internalType":"uint256","name":"activePcircle","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getActiveAssetsUsdcValue","outputs":[{"internalType":"uint256","name":"totalValue","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"rageAmount","type":"uint256"}],"name":"getAssetsFromRage","outputs":[{"internalType":"uint256","name":"hestia","type":"uint256"},{"internalType":"uint256","name":"circle","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBackingPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBonusAssets","outputs":[{"internalType":"uint256","name":"bonusHestia","type":"uint256"},{"internalType":"uint256","name":"bonusCircle","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getClaim","outputs":[{"components":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint256","name":"version","type":"uint256"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"uint256","name":"claimedCount","type":"uint256"},{"internalType":"uint256","name":"dateCreated","type":"uint256"},{"internalType":"uint256","name":"dateUpdated","type":"uint256"},{"internalType":"uint256","name":"dateClaimableStart","type":"uint256"},{"internalType":"uint256","name":"dateClaimableEnd","type":"uint256"},{"internalType":"uint256","name":"rageBurn","type":"uint256"},{"internalType":"uint256","name":"rageAfterFee","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"fmv","type":"uint256"},{"internalType":"uint256","name":"backingPerShare","type":"uint256"},{"internalType":"uint256","name":"claimHestia","type":"uint256"},{"internalType":"uint256","name":"claimCircle","type":"uint256"},{"internalType":"uint256","name":"lastClaimHestia","type":"uint256"},{"internalType":"uint256","name":"lastClaimCircle","type":"uint256"},{"internalType":"uint256","name":"totalClaimHestia","type":"uint256"},{"internalType":"uint256","name":"totalClaimCircle","type":"uint256"},{"internalType":"uint256","name":"configClaimFee","type":"uint256"},{"internalType":"uint256","name":"configClaimDelay","type":"uint256"},{"internalType":"uint256","name":"configClaimValidity","type":"uint256"}],"internalType":"struct RageStructs.Claim","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getClaimWallets","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFmv","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInvestPercents","outputs":[{"internalType":"uint256","name":"percentHestia","type":"uint256"},{"internalType":"uint256","name":"percentCircle","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"optionId","type":"uint256"}],"name":"getOption","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"version","type":"uint256"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"transactionType","type":"string"},{"internalType":"address","name":"walletCreated","type":"address"},{"internalType":"address","name":"walletUpdated","type":"address"},{"internalType":"address","name":"referral","type":"address"},{"internalType":"uint256","name":"dateCreated","type":"uint256"},{"internalType":"uint256","name":"dateUpdated","type":"uint256"},{"internalType":"uint256","name":"dateMintable","type":"uint256"},{"internalType":"uint256","name":"dateAdpAble","type":"uint256"},{"internalType":"uint256","name":"dateRefundable","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"fmv","type":"uint256"},{"internalType":"uint256","name":"backingPerShare","type":"uint256"},{"internalType":"uint256","name":"usdcInvest","type":"uint256"},{"internalType":"uint256","name":"usdcAdp","type":"uint256"},{"internalType":"uint256","name":"usdcRefund","type":"uint256"},{"internalType":"uint256","name":"pendingHestia","type":"uint256"},{"internalType":"uint256","name":"pendingCircle","type":"uint256"},{"internalType":"uint256","name":"rageEstimated","type":"uint256"},{"internalType":"uint256","name":"rageMinted","type":"uint256"},{"internalType":"uint256","name":"usdcAdpDilution","type":"uint256"},{"internalType":"uint256","name":"usdcInvestorBonus","type":"uint256"},{"internalType":"uint256","name":"hestiaInvestorBonus","type":"uint256"},{"internalType":"uint256","name":"circleInvestorBonus","type":"uint256"},{"internalType":"uint256","name":"usdcEcosystemBonus","type":"uint256"},{"internalType":"uint256","name":"hestiaEcosystemBonus","type":"uint256"},{"internalType":"uint256","name":"circleEcosystemBonus","type":"uint256"},{"internalType":"uint256","name":"configHestiaPercent","type":"uint256"},{"internalType":"uint256","name":"configCirclePercent","type":"uint256"},{"internalType":"uint256","name":"configInvestorBonus","type":"uint256"},{"internalType":"uint256","name":"configMintDelay","type":"uint256"},{"internalType":"uint256","name":"configAdpDelay","type":"uint256"},{"internalType":"uint256","name":"configAdpPercent","type":"uint256"},{"internalType":"uint256","name":"configRefundPercent","type":"uint256"},{"internalType":"uint256","name":"configRefundDelay","type":"uint256"}],"internalType":"struct RageStructs.Option","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPendingAssets","outputs":[{"internalType":"uint256","name":"pendingHestia","type":"uint256"},{"internalType":"uint256","name":"pendingCircle","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"usdcAmount","type":"uint256"}],"name":"getRageFromUsdc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRageUnderlying","outputs":[{"internalType":"uint256","name":"underlyingHestia","type":"uint256"},{"internalType":"uint256","name":"underlyingCircle","type":"uint256"},{"internalType":"uint256","name":"hestiaValue","type":"uint256"},{"internalType":"uint256","name":"circleValue","type":"uint256"},{"internalType":"uint256","name":"totalValue","type":"uint256"},{"internalType":"uint256","name":"hestiaPercent","type":"uint256"},{"internalType":"uint256","name":"circlePercent","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRawAssets","outputs":[{"internalType":"uint256","name":"rawHestia","type":"uint256"},{"internalType":"uint256","name":"rawCircle","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getState","outputs":[{"components":[{"internalType":"uint256","name":"version","type":"uint256"},{"components":[{"internalType":"uint256","name":"status","type":"uint256"},{"internalType":"uint256","name":"nextConfigTime","type":"uint256"},{"internalType":"uint256","name":"pendingHestia","type":"uint256"},{"internalType":"uint256","name":"pendingCircle","type":"uint256"},{"internalType":"uint256","name":"totalOptions","type":"uint256"},{"internalType":"uint256","name":"optionsMint","type":"uint256"},{"internalType":"uint256","name":"optionsAdp","type":"uint256"},{"internalType":"uint256","name":"optionsAdpValue","type":"uint256"},{"internalType":"uint256","name":"optionsRefund","type":"uint256"},{"internalType":"uint256","name":"optionsRefundValue","type":"uint256"},{"internalType":"uint256","name":"totalInvest","type":"uint256"},{"internalType":"uint256","name":"totalInvestorBonus","type":"uint256"},{"internalType":"uint256","name":"totalEcosystemBonus","type":"uint256"},{"internalType":"uint256","name":"totalDebt","type":"uint256"},{"internalType":"uint256","name":"totalClaims","type":"uint256"},{"internalType":"uint256","name":"totalAdpDilution","type":"uint256"},{"internalType":"uint256","name":"claimsProcessed","type":"uint256"},{"internalType":"uint256","name":"claimsHestia","type":"uint256"},{"internalType":"uint256","name":"claimsCircle","type":"uint256"}],"internalType":"struct RageStructs.RbpStateValue","name":"state","type":"tuple"},{"components":[{"internalType":"uint256","name":"minInvest","type":"uint256"},{"internalType":"uint256","name":"maxInvest","type":"uint256"},{"internalType":"uint256","name":"hestiaPercent","type":"uint256"},{"internalType":"uint256","name":"investorBonus","type":"uint256"},{"internalType":"uint256","name":"mintDelay","type":"uint256"},{"internalType":"uint256","name":"adpDelay","type":"uint256"},{"internalType":"uint256","name":"adpPercent","type":"uint256"},{"internalType":"uint256","name":"ecosystemBonus","type":"uint256"},{"internalType":"uint256","name":"refundPercent","type":"uint256"},{"internalType":"uint256","name":"refundDelay","type":"uint256"},{"internalType":"uint256","name":"minClaim","type":"uint256"},{"internalType":"uint256","name":"maxClaim","type":"uint256"},{"internalType":"uint256","name":"claimFee","type":"uint256"},{"internalType":"uint256","name":"claimDelay","type":"uint256"},{"internalType":"uint256","name":"claimValidity","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"uint32","name":"twap","type":"uint32"}],"internalType":"struct RageStructs.RbpConfig","name":"config","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastInvest","type":"uint256"},{"internalType":"uint256","name":"lastMintRage","type":"uint256"},{"internalType":"uint256","name":"lastRefund","type":"uint256"},{"internalType":"address","name":"lastReserveClaim","type":"address"},{"internalType":"address","name":"lastClaim","type":"address"}],"internalType":"struct RageStructs.RbpRecent","name":"recent","type":"tuple"}],"internalType":"struct RageStructs.RbpState","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getViewState","outputs":[{"components":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"activeSupply","type":"uint256"},{"internalType":"uint256","name":"fmv","type":"uint256"},{"internalType":"uint256","name":"backingPerShare","type":"uint256"},{"internalType":"uint256","name":"activeAssetsUsdcValue","type":"uint256"},{"internalType":"uint256","name":"rawHestia","type":"uint256"},{"internalType":"uint256","name":"rawCircle","type":"uint256"},{"internalType":"uint256","name":"pendingHestia","type":"uint256"},{"internalType":"uint256","name":"pendingCircle","type":"uint256"},{"internalType":"uint256","name":"bonusHestia","type":"uint256"},{"internalType":"uint256","name":"bonusCircle","type":"uint256"},{"internalType":"uint256","name":"activePhestia","type":"uint256"},{"internalType":"uint256","name":"activePcircle","type":"uint256"},{"internalType":"uint256","name":"activeHestia","type":"uint256"},{"internalType":"uint256","name":"activeCircle","type":"uint256"},{"internalType":"uint256","name":"investPercentHestia","type":"uint256"},{"internalType":"uint256","name":"investPercentCircle","type":"uint256"},{"internalType":"uint256","name":"underlyingHestia","type":"uint256"},{"internalType":"uint256","name":"underlyingCircle","type":"uint256"},{"internalType":"uint256","name":"underlyingHestiaValue","type":"uint256"},{"internalType":"uint256","name":"underlyingCircleValue","type":"uint256"},{"internalType":"uint256","name":"underlyingTotalValue","type":"uint256"},{"internalType":"uint256","name":"underlyingHestiaPercent","type":"uint256"},{"internalType":"uint256","name":"underlyingCirclePercent","type":"uint256"},{"internalType":"uint256","name":"rageFromOnePercentUsdc","type":"uint256"},{"internalType":"uint256","name":"hestiaFromOnePercentRage","type":"uint256"},{"internalType":"uint256","name":"circleFromOnePercentRage","type":"uint256"}],"internalType":"struct RageStructs.RbpViewState","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"usdcAmount","type":"uint256"},{"internalType":"address","name":"referral","type":"address"}],"name":"invest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"referral","type":"address"}],"name":"investEth","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint256","name":"usdcAmount","type":"uint256"}],"name":"investOverview","outputs":[{"components":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"string","name":"transactionType","type":"string"},{"internalType":"bool","name":"canInvest","type":"bool"},{"internalType":"bool","name":"isAmountValid","type":"bool"},{"internalType":"bool","name":"isPercentValid","type":"bool"},{"internalType":"bool","name":"hasBonus","type":"bool"},{"internalType":"uint256","name":"rageEstimated","type":"uint256"},{"internalType":"uint256","name":"rageEstimatedValue","type":"uint256"},{"internalType":"uint256","name":"dateMintable","type":"uint256"},{"internalType":"uint256","name":"dateAdpAble","type":"uint256"},{"internalType":"uint256","name":"dateRefundable","type":"uint256"},{"internalType":"uint256","name":"usdcInvest","type":"uint256"},{"internalType":"uint256","name":"usdcAdp","type":"uint256"},{"internalType":"uint256","name":"usdcRefund","type":"uint256"},{"internalType":"uint256","name":"usdcInvestorBonus","type":"uint256"},{"internalType":"uint256","name":"usdcEcosystemBonus","type":"uint256"},{"internalType":"uint256","name":"usdcHestiaBonus","type":"uint256"},{"internalType":"uint256","name":"usdcCircleBonus","type":"uint256"},{"internalType":"uint256","name":"hestiaInvestorBonus","type":"uint256"},{"internalType":"uint256","name":"hestiaEcosystemBonus","type":"uint256"},{"internalType":"uint256","name":"circleInvestorBonus","type":"uint256"},{"internalType":"uint256","name":"circleEcosystemBonus","type":"uint256"},{"internalType":"uint256","name":"configHestiaPercent","type":"uint256"},{"internalType":"uint256","name":"configCirclePercent","type":"uint256"},{"internalType":"uint256","name":"configInvestorBonus","type":"uint256"},{"internalType":"uint256","name":"configMintDelay","type":"uint256"},{"internalType":"uint256","name":"configAdpDelay","type":"uint256"},{"internalType":"uint256","name":"configAdpPercent","type":"uint256"},{"internalType":"uint256","name":"configRefundPercent","type":"uint256"},{"internalType":"uint256","name":"configRefundDelay","type":"uint256"}],"internalType":"struct RageStructs.InvestOverview","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"optionId","type":"uint256"}],"name":"mintRage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint256","name":"optionId","type":"uint256"}],"name":"optionOverview","outputs":[{"components":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint256","name":"optionId","type":"uint256"},{"internalType":"bool","name":"canMint","type":"bool"},{"internalType":"bool","name":"canMintWithAdp","type":"bool"},{"internalType":"bool","name":"canRefund","type":"bool"},{"internalType":"bool","name":"hasRefundUsdc","type":"bool"},{"internalType":"uint256","name":"rageMint","type":"uint256"},{"internalType":"uint256","name":"rageMintValue","type":"uint256"},{"internalType":"uint256","name":"usdcAssets","type":"uint256"},{"internalType":"uint256","name":"usdcCurrent","type":"uint256"},{"internalType":"uint256","name":"usdcBalance","type":"uint256"},{"internalType":"uint256","name":"usdcAdpDilution","type":"uint256"},{"internalType":"uint256","name":"backingPerShare","type":"uint256"},{"internalType":"bool","name":"mintValueProfitable","type":"bool"},{"internalType":"bool","name":"mintBackingProfitable","type":"bool"}],"internalType":"struct RageStructs.OptionOverview","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"processClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"processClaimOverview","outputs":[{"components":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"bool","name":"canClaim","type":"bool"},{"internalType":"bool","name":"hasBalance","type":"bool"},{"internalType":"bool","name":"isValid","type":"bool"},{"internalType":"uint256","name":"rageBurn","type":"uint256"},{"internalType":"uint256","name":"rageBurnValue","type":"uint256"},{"internalType":"uint256","name":"claimHestia","type":"uint256"},{"internalType":"uint256","name":"claimCircle","type":"uint256"},{"internalType":"uint256","name":"claimValue","type":"uint256"},{"internalType":"uint256","name":"pHestiaNeeded","type":"uint256"},{"internalType":"uint256","name":"pCircleNeeded","type":"uint256"},{"internalType":"uint256","name":"recalcClaimHestia","type":"uint256"},{"internalType":"uint256","name":"recalcClaimCircle","type":"uint256"},{"internalType":"uint256","name":"recalcClaimValue","type":"uint256"},{"internalType":"uint256","name":"backingPerShare","type":"uint256"}],"internalType":"struct RageStructs.ClaimOverview","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"optionId","type":"uint256"}],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rageAmount","type":"uint256"}],"name":"reserveClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint256","name":"rageAmount","type":"uint256"}],"name":"reserveClaimOverview","outputs":[{"components":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"bool","name":"canReserve","type":"bool"},{"internalType":"bool","name":"hasActiveClaim","type":"bool"},{"internalType":"bool","name":"isFirstClaim","type":"bool"},{"internalType":"uint256","name":"rageBurn","type":"uint256"},{"internalType":"uint256","name":"rageBurnValue","type":"uint256"},{"internalType":"uint256","name":"rageAfterFee","type":"uint256"},{"internalType":"uint256","name":"claimHestia","type":"uint256"},{"internalType":"uint256","name":"claimCircle","type":"uint256"},{"internalType":"uint256","name":"claimValue","type":"uint256"},{"internalType":"uint256","name":"dateClaimableStart","type":"uint256"},{"internalType":"uint256","name":"dateClaimableEnd","type":"uint256"},{"internalType":"uint256","name":"configClaimFee","type":"uint256"},{"internalType":"uint256","name":"configClaimDelay","type":"uint256"},{"internalType":"uint256","name":"configClaimValidity","type":"uint256"}],"internalType":"struct RageStructs.ReserveClaimOverview","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"minInvest","type":"uint256"},{"internalType":"uint256","name":"maxInvest","type":"uint256"},{"internalType":"uint256","name":"hestiaPercent","type":"uint256"},{"internalType":"uint256","name":"investorBonus","type":"uint256"},{"internalType":"uint256","name":"mintDelay","type":"uint256"},{"internalType":"uint256","name":"adpDelay","type":"uint256"},{"internalType":"uint256","name":"adpPercent","type":"uint256"},{"internalType":"uint256","name":"ecosystemBonus","type":"uint256"},{"internalType":"uint256","name":"refundPercent","type":"uint256"},{"internalType":"uint256","name":"refundDelay","type":"uint256"},{"internalType":"uint256","name":"minClaim","type":"uint256"},{"internalType":"uint256","name":"maxClaim","type":"uint256"},{"internalType":"uint256","name":"claimFee","type":"uint256"},{"internalType":"uint256","name":"claimDelay","type":"uint256"},{"internalType":"uint256","name":"claimValidity","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"uint32","name":"twap","type":"uint32"}],"internalType":"struct RageStructs.RbpConfig","name":"newConfig","type":"tuple"}],"name":"setConfigs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"status","type":"uint256"}],"name":"setStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAdr","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

61014080604052346105625760c08161654880380380916100208285610567565b833981010312610562576100338161058a565b906100406020820161058a565b61004c6040830161058a565b6100586060840161058a565b9161007160a061006a6080870161058a565b950161058a565b600160009081556001600160a01b0396871660805291861660a05291851660c05291841660e052918316610100819052929091166101205260405163095ea7b360e01b8152600481019290925260001960248301526020908290604490829073833589fcd6edb6e08f4c7c32d4f71b54bda029135af180156104e257610545575b506101005160405163095ea7b360e01b81526001600160a01b0390911660048201526000196024820152602081604481600073bc7755a153e852cf76cccddb4c2e7c368f6259d85af180156104e257610528575b506101005160405163095ea7b360e01b81526001600160a01b03909116600482015260001960248201526020816044816000735babfc2f240bc5de90eb7e19d789412db1dec4025af180156104e25761050b575b506101005160405163095ea7b360e01b81526001600160a01b0390911660048201526000196024820152602081604481600073f760fd8feb1f5e3bf3651e2e4f227285a82470ff5af180156104e2576104ee575b506101005160405163095ea7b360e01b81526001600160a01b039091166004820152600019602482015260208160448160007355a81da2a319dd60fb028c53cb4419493b56f6c05af180156104e2576104b5575b5060405161022081016001600160401b0381118282101761049f57601e91610200916040526298968081526401bf08eb00602082015260506040820152600660608201526202a3006080820152624f1a0060a0820152604b60c0820152600660e082015260556101008201526305265c00610120820152670de0b6b3a7640000610140820152681b1ae4d6e2ef500000610160820152600a61018082015262278d006101a0820152620d2f006101c08201526101f46101e08201520152629896806014556401bf08eb00601555605060165560066017556202a300601855624f1a00601955604b601a556006601b556055601c556305265c00601d55670de0b6b3a7640000601e55681b1ae4d6e2ef500000601f55600a60205562278d00602155620d2f006022556101f4602355601e63ffffffff196024541617602455604051615f9190816105b78239608051818181611b6e01528181611d8a0152818161341301528181613a4a01528181613c4e01528181613ea7015281816140270152615ef1015260a051818181610fae015281816136a3015261417c015260c051818181611ea20152818161372001528181613d4a01528181613da90152818161437501528181614a0001528181614a6101528181614cae01528181614d1501528181614d8b0152614df7015260e05181818161347701528181613aea01528181613cf301528181613f21015281816140b501526152b0015261010051818181608501528181610c5b01528181610e8101528181611a87015281816123190152818161557c0152615cd30152610120518181816153900152615bac0152f35b634e487b7160e01b600052604160045260246000fd5b6104d69060203d6020116104db575b6104ce8183610567565b81019061059e565b610242565b503d6104c4565b6040513d6000823e3d90fd5b6105069060203d6020116104db576104ce8183610567565b6101ee565b6105239060203d6020116104db576104ce8183610567565b61019a565b6105409060203d6020116104db576104ce8183610567565b610146565b61055d9060203d6020116104db576104ce8183610567565b6100f2565b600080fd5b601f909101601f19168101906001600160401b0382119082101761049f57604052565b51906001600160a01b038216820361056257565b9081602091031261056257518015158103610562579056fe6108406040526004361015610148575b361561001a57600080fd5b610028600160005414613297565b6002600055604080519061003c8183613138565b60018252603960f91b60208301526100553415156133b7565b61005d61547a565b60784201804211610132578251630e543ca360e11b81526004810191909152602081602481347f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af192831561012857506000926100ef575b6100e8600085856100e3866100dc836100d661547a565b92613301565b111561330e565b6154bc565b6001600055005b90916020823d602011610120575b8161010a60209383613138565b8101031261011d575051906100e86100bf565b80fd5b3d91506100fd565b513d6000823e3d90fd5b634e487b7160e01b600052601160045260246000fd5b6000803560e01c80630bedc17714612f285780630c0dd73414612f0d5780630fd8aee814612ef2578063117dc51b14612ed75780631865c57d146129f65780631ce5e9a6146124a6578063278ecde1146122585780632867d07c14611c9b578063298fe70e146119b45780632e1717c6146119995780633d103b97146118e45780633f5632391461181c57806347249493146117f75780634b68b8af146117dc5780634cd3723a1461152257806358e82c44146111df57806359cb936f146111c4578063670791b414610dc157806369ba1a7514610d7857806386ce9e3714610d4d57806396bb2d5c14610d035780639c16860a14610bdd5780639e281a9814610a04578063b78f15bc146109e5578063cb66cbd414610906578063ce2beaa114610567578063d289ffdb146103bf578063e7572230146103a0578063fb3571651461037d5763fbae4f431461029e575061000f565b3461011d57604036600319011261011d576101e06102c66102bd612fa2565b60243590614ecf565b6101c06040519160018060a01b0381511683526020810151602084015260408101511515604084015260608101511515606084015260808101511515608084015260a0810151151560a084015260c081015160c084015260e081015160e08401526101008101516101008401526101208101516101208401526101408101516101408401526101608101516101608401526101808101516101808401526101a081015115156101a0840152015115156101c0820152f35b503461011d578060031936011261011d576020610398614d49565b604051908152f35b503461011d57602036600319011261011d576020610398600435614ce2565b503461011d57604036600319011261011d576103e56103dc612fa2565b60243590614511565b60405180916020825260018060a01b0381511660208301526103a061041b60208301516103c060408601526103e0850190612f61565b916040810151151560608501526060810151151560808501526080810151151560a085015260a0810151151560c085015260c081015160e085015260e08101516101008501526101008101516101208501526101208101516101408501526101408101516101608501526101608101516101808501526101808101516101a08501526101a08101516101c08501526101c08101516101e08501526101e08101516102008501526102008101516102208501526102208101516102408501526102408101516102608501526102608101516102808501526102808101516102a08501526102a08101516102c08501526102c08101516102e08501526102e08101516103008501526103008101516103208501526103208101516103408501526103408101516103608501526103608101516103808501526103808101518285015201516103c08301520390f35b503461011d5761022036600319011261011d576105876001825414613297565b6002815561059c61059733615edc565b613c05565b60025442106108dc57600435620f4240811015806108ce575b806108c3575b6105c4906144cc565b610736602435633b9aca00811015806108b4575b6105e1906144cc565b6044356037811015806108a9575b6105f8906144cc565b60643560018110158061089e575b61060f906144cc565b6084356201518081101580610891575b610628906144cc565b60a43562278d0081101580610883575b610641906144cc565b60c435603781101580610878575b8061086b575b61065e906144cc565b60e435600181101580610860575b610675906144cc565b6101043591603783101580610855575b61068e906144cc565b61012435936302932e0085101580610847575b6106aa906144cc565b610144359566038d7ea4c6800087101580610835575b80610829575b6106cf906144cc565b61016435976106e968056bc75e2d631000008a10156144cc565b610184359960018b10158061081e575b610702906144cc565b6101a4359b61071e620d2f008e10158e81610810575b506144cc565b6101c4359d620151808f10158f8161080257506144cc565b6101e4359e8f6109c4101561074a906144cc565b6107526144fd565b63ffffffff1660011115806107e4575b61076b906144cc565b610e1042018042116107cd57600255601455601555601655601755601855601955601a55601b55601c55601d55601e55601f5560205560215560225560235563ffffffff6107b76144fd565b1663ffffffff1960245416176024556001815580f35b50505060248f634e487b7160e01b81526011600452fd5b5061076b610e1063ffffffff6107f86144fd565b1611159050610762565b62278d00915011158f610718565b6283d600915011158e610718565b5060148b11156106f9565b506101643587106106c6565b50670de0b6b3a76400008711156106c0565b506307b98a008511156106a1565b50605f831115610685565b50600f81111561066c565b5061010435811115610655565b50605a81111561064f565b5063018b8200811115610638565b506276a70081111561061f565b50600f811115610606565b50605f8111156105ef565b5064174876e8008111156105d8565b5060243581106105bb565b506305f5e1008111156105b5565b60405162461bcd60e51b8152602060048201526002602482015261746960f01b6044820152606490fd5b503461011d57604036600319011261011d576101e061092f610926612fa2565b60243590614145565b6109e360405180926101c0809160018060a01b0381511684526020810151151560208501526040810151151560408501526060810151151560608501526080810151608085015260a081015160a085015260c081015160c085015260e081015160e08501526101008101516101008501526101208101516101208501526101408101516101408501526101608101516101608501526101808101516101808501526101a08101516101a08501520151910152565bf35b503461011d57602036600319011261011d576020610398600435614007565b503461011d57604036600319011261011d578080610a20612fa2565b60243590610a3061059733615edc565b610a3b8215156133b7565b6001600160a01b031680610ad057508181610a598293471015612fc5565b73507fbde39ba40da4fc79426ad5e3c64944fe43d45af13d15610ac7573d67ffffffffffffffff8111610ab357604051610ab09291610aa2601f8201601f191660200183613138565b81528360203d92013e613366565b80f35b634e487b7160e01b83526041600452602483fd5b610ab090613366565b6040516370a0823160e01b8152306004820152909250602081602481865afa908115610bd2578491610b94575b5081610b10602094936044931015612fc5565b604051948593849263a9059cbb60e01b845273507fbde39ba40da4fc79426ad5e3c64944fe43d4600485015260248401525af18015610b8957610ab0918391610b5a575b50613366565b610b7c915060203d602011610b82575b610b748183613138565b81019061334e565b38610b54565b503d610b6a565b6040513d84823e3d90fd5b935050906020833d602011610bca575b81610bb160209383613138565b81010312610bc55791518392919081610afd565b600080fd5b3d9150610ba4565b6040513d86823e3d90fd5b50602036600319011261011d57610bf2612fa2565b610bff6001835414613297565b600282556040908151610c128382613138565b60018152606560f81b6020820152610c2b3415156133b7565b610c3361547a565b60784201804211610cef578451630e543ca360e11b81526004810191909152602081602481347f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1948515610ce657508594610cb0575b50926100e3610ca9946100dc836100d661547a565b6001815580f35b93506020843d602011610cde575b81610ccb60209383613138565b81010312610bc5579251926100e3610c94565b3d9150610cbe565b513d87823e3d90fd5b634e487b7160e01b86526011600452602486fd5b503461011d578060031936011261011d5760e090610d1f613e91565b9560409591959492945197508752602087015260408601526060850152608084015260a083015260c0820152f35b503461011d57602036600319011261011d576040610d6c600435613c36565b82519182526020820152f35b503461011d57602036600319011261011d57600435610d9a6001835414613297565b60028255610daa61059733615edc565b610db76001821115613c05565b6001556001815580f35b503461011d578060031936011261011d57610ddf6001825414613297565b60028155610dec33613553565b610dfb602082015115156132d0565b338252602c6020526040822090610e1061315a565b610e2261012084019283511115612fc5565b610e3461014084019182511115612fc5565b610e3c613b50565b9251915160784201928342116111b0576040805163d568e56560e01b815260048101929092526024820192909252604481019390935282606481896001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af19182156111a55786908793611171575b50801561114357610ee2816100dc858a97610edd60e0976100dc610ed5613b50565b979092613301565b613301565b60c08501518082101561113b5750935b0151808210156111335750925b60028101600260ff1982541617905560038101610f1c815461333f565b905542600582015582600f82015583601082015560118101610f3f848254613301565b905560128101610f50858254613301565b9055610f5d60115461333f565b601155610f6c83601254613301565b601255610f7b84601354613301565b60135560080180546040516323b872dd60e01b815233600482015230602482015260448101919091526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016919060208160648187875af18015610bd257610ff0918591610b5a5750613366565b54813b1561112f578291602483926040519485938492630852cd8d60e31b845260048401525af18015610b895761111a575b505060405163a9059cbb60e01b815233600482015260248101919091526020816044818673bc7755a153e852cf76cccddb4c2e7c368f6259d85af1801561110f57611073918491610b5a5750613366565b806110ba575b50336001600160601b0360a01b6029541617602955337f4e9344e3e55e1ebd97b68bfc076e1c3082590c93fc7bb3ce04403430dfa13ed68280a26001815580f35b60405163a9059cbb60e01b8152336004820152602481019190915260208160448185735babfc2f240bc5de90eb7e19d789412db1dec4025af18015610b8957611109918391610b5a5750613366565b38611079565b6040513d85823e3d90fd5b8161112491613138565b61112f578238611022565b8280fd5b905092610eff565b905093610ef2565b60405162461bcd60e51b815260206004820152600660248201526534b739a232b160d11b6044820152606490fd5b905061119691925060403d60401161119e575b61118e8183613138565b8101906133e8565b919038610eb3565b503d611184565b6040513d88823e3d90fd5b634e487b7160e01b88526011600452602488fd5b503461011d578060031936011261011d576040610d6c613b50565b503461011d57602036600319011261011d576111fe6001825414613297565b6002815561120e60043533614145565b61121d602082015115156132d0565b338252602c6020526040822090606081015161148e575b600382015490608081015160c08201519061124d614c75565b946112566133fe565b9261125f613a35565b96610140860151976101608701519560e0880151926101008901519460118701549660120154976101808b0151996101a08c01519b6101c001519c6040519e8f916112a9836130e1565b3383526020830160019052604083016001905260608301524260808301524260a083015260c082015260e001526101008d01526101208c01526101408b01526101608a01526101808901526101a08801526101c0870152866101e0870152866102008701526102208601526102408501526102608401526102808301526102a0820152338252602c6020526040822090600160a01b60019003600160a01b60019003825116166001600160601b0360a01b83541617825560208101516001830155604081015160ff16600283019060ff1660ff19825416179055606081015160038301556080810151600483015560a0810151600583015560c0810151600683015560e0810151600783015561010081015160088301556101208101516009830155610140810151600a830155610160810151600b830155610180810151600c8301556101a0810151600d8301556101c0810151600e8301556101e0810151600f830155610200810151601083015561022081015160118301556102408101516012830155610260810151601383015561028081015160148301556102a001519060150155336001600160601b0360a01b6028541617602855337f37ad7683b355ff02aa5cc2c5459f75746c9ebfe6200244351d4ffb679eb06ff88280a26001815580f35b611499600f5461333f565b600f55602a546801000000000000000081101561150e576001810180602a558110156114fa57602a84527fbeced09521047d05b8960b7e7bcc1d1292cf3e4b2a6b63f48335cbde5f7545d20180546001600160a01b03191633179055611234565b634e487b7160e01b84526032600452602484fd5b634e487b7160e01b84526041600452602484fd5b503461011d57602036600319011261011d5760406102c091611542612fa2565b816102a08451611551816130e1565b82815282602082015282868201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a0820152826101c0820152826101e08201528261020082015282610220820152826102408201528261026082015282610280820152015260018060a01b03168152602c602052206102a06040516115f9816130e1565b601560018060a01b03845416938483526001810154602084015260ff60028201541660408401526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460e084015260088101546101008401526009810154610120840152600a810154610140840152600b810154610160840152600c810154610180840152600d8101546101a0840152600e8101546101c0840152600f8101546101e0840152601081015461020084015260118101546102208401526012810154610240840152601381015461026084015260148101546102808401520154828201526040519283526020810151602084015260ff6040820151166040840152606081015160608401526080810151608084015260a081015160a084015260c081015160c084015260e081015160e08401526101008101516101008401526101208101516101208401526101408101516101408401526101608101516101608401526101808101516101808401526101a08101516101a08401526101c08101516101c08401526101e08101516101e084015261020081015161020084015261022081015161022084015261024081015161024084015261026081015161026084015261028081015161028084015201516102a0820152f35b503461011d578060031936011261011d576020610398613a35565b503461011d57602036600319011261011d576101e061092f611817612fa2565b613553565b503461011d578060031936011261011d57604051806020602a5491828152018091602a85527fbeced09521047d05b8960b7e7bcc1d1292cf3e4b2a6b63f48335cbde5f7545d290855b8181106118c5575050508261187b910383613138565b604051928392602084019060208552518091526040840192915b8181106118a3575050500390f35b82516001600160a01b0316845285945060209384019390920191600101611895565b82546001600160a01b0316845260209093019260019283019201611865565b503461011d57604036600319011261011d576004356024356001600160a01b038116810361112f576119196001845414613297565b600283556040516323b872dd60e01b815233600482015230602482015260448101839052916020836064818773833589fcd6edb6e08f4c7c32d4f71b54bda029135af1928315610bd257610ca993611977918691610b5a5750613366565b60405190611986604083613138565b60018252606960f81b60208301526154bc565b503461011d578060031936011261011d5760206103986133fe565b503461011d57602036600319011261011d57600435906119d76001825414613297565b600281556119e58233614ecf565b6119f4604082015115156132d0565b60c0810190611a05825115156133b7565b838352602b6020526040832060128101611a228154600354612fb8565b60035560138201611a368154600454612fb8565b600455611a4161315a565b90925491546078420192834211611c875760408051636de19f8b60e01b8152600481019290925260248201929092526044810193909352826064818a6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1908115611c7c5791611b6895949391611ad99389928a92611c4f575b50610edd6100dc93946100dc610ed561315a565b606082015115159182611c40575b611b5c9161016060119285600014611c395760035b60028401805460ff191660ff929092169190911790558751601584015501805160168301556005820180546001600160a01b03191633179055426008830155600654909490611b4a9061333f565b600655611c13575b0154600e54612fb8565b600e5551601054613301565b601055517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b1561112f57604051634429bfc160e01b815233600482015260248101919091529082908290604490829084905af18015610b8957611c03575b5090806026557ff82d7919414fdf3350e6209f0613cc1a2bfb7c9f841543d78b2e59dd3b280f2b8280a26001815580f35b81611c0d91613138565b38611bd2565b611c1e60075461333f565b600755611c316010820154600854613301565b600855611b52565b6002611afc565b61016081015115159250611ae7565b6100dc9350610edd949250611c729060403d60401161119e5761118e8183613138565b9294909350611ac5565b6040513d89823e3d90fd5b634e487b7160e01b89526011600452602489fd5b503461011d578060031936011261011d5780610340604051611cbc816130c4565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a0820152826101c0820152826101e08201528261020082015282610220820152826102408201528261026082015282610280820152826102a0820152826102c0820152826102e082015282610300820152826103208201520152611d71614c75565b6101605260405163071c628160e41b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa8015610b89578261022052612220575b50611dcd6133fe565b90611dd6613a35565b6101c052611de2614d49565b61028052611dee61324a565b60a05291611e30611dfd613b50565b9061026052611e0a612ff6565b611e15939193612ff6565b611e2a611e23949294613b50565b9590612fb8565b93612fb8565b6102a052611e3c61315a565b949093611e47613e91565b610200526101e05261024052610180526101005260e05260c052611e7060646102805104614007565b6101a052611e8360646102205104613c36565b610140526101205260405163cc878ed960e01b815260048101869052967f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316602089602481845afa988915612215578a996121dc575b50602060249160405192838092630979d0cb60e41b82528c60048301525afa998a156121d057809a612199575b5050604051608052611f216080516130c4565b61016051608051526102205160206080510152604060805101526101c05160606080510152610280516080805101526102605160a0608051015260c0608051015260e06080510152610100608051015261012060805101526102a0516101406080510152610160608051015261018060805101526101a060805101526101c060805101526101e0608051015260a051610200608051015260c051610220608051015260e0516102406080510152610100516102606080510152610180516102806080510152610240516102a060805101526101e0516102c06080510152610200516102e060805101526101a0516103006080510152610120516103206080510152610140516103406080510152610360604051610160518152602060805101516020820152604060805101516040820152606060805101516060820152608080510151608082015260a0608051015160a082015260c0608051015160c082015260e0608051015160e0820152610100608051015161010082015261012060805101516101208201526101406080510151610140820152610160608051015161016082015261018060805101516101808201526101a060805101516101a08201526101c060805101516101c08201526101e060805101516101e0820152610200608051015161020082015261022060805101516102208201526102406080510151610240820152610260608051015161026082015261028060805101516102808201526102a060805101516102a08201526102c060805101516102c08201526102e060805101516102e0820152610300608051015161030082015261032060805101516103208201526103406080510151610340820152f35b909199506020823d6020116121c8575b816121b660209383613138565b8101031261011d575051973880611f0e565b3d91506121a9565b604051903d90823e3d90fd5b9098506020813d60201161220d575b816121f860209383613138565b810103126122095751976020611ee1565b8980fd5b3d91506121eb565b6040513d8c823e3d90fd5b6020813d602011612250575b8161223960209383613138565b8101031261224c57516102205238611dc4565b5080fd5b3d915061222c565b503461011d57602036600319011261011d5760043561227a6001835414613297565b60028255612296608061228d8333614ecf565b015115156132d0565b808252602b60205260408220601281016122b38154600354612fb8565b600355601382016122c78154600454612fb8565b6004556122d261547a565b9154905460235460784201918242116111b05760405163f6a6e1c360e01b815260048101949094526024840152604483018190526064830152608482015260208160a481887f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af190811561249b578591612461575b50916123686020926100dc612403956100d661547a565b61237061547a565b90612382601182019283541115612fc5565b60028101805460ff191660041790556005810180546001600160a01b03191633179055426008909101556009546123b89061333f565b6009556123c88154600a54613301565b600a556123d88154600e54612fb8565b600e555460405163a9059cbb60e01b8152336004820152602481019190915291829081906044820190565b03818673833589fcd6edb6e08f4c7c32d4f71b54bda029135af1801561110f57612433918491610b5a5750613366565b806027557e0f2353cc2b9054c072a7083055e8fc4edeba7bbfa38e68bd13d16d17fd68e48280a26001815580f35b9290506020833d602011612493575b8161247d60209383613138565b8101031261248f579151612368612351565b8480fd5b3d9150612470565b6040513d87823e3d90fd5b503461011d57602036600319011261011d57806104806040516124c8816130a7565b8281528260208201528260408201526060808201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a0820152826101c0820152826101e08201528261020082015282610220820152826102408201528261026082015282610280820152826102a0820152826102c0820152826102e08201528261030082015282610320820152826103408201528261036082015282610380820152826103a0820152826103c0820152826103e08201528261040082015282610420820152826104408201528261046082015201526004358152602b60205260408120604051906125d6826130a7565b805482526001810154602083015260ff60028201541660408301526003810160405190848154916126068361325d565b80855292600181169081156129cd5750600114612992575b50505061263081602494950382613138565b606084015260018060a01b03600482015416608084015260018060a01b0360058201541660a084015260018060a01b0360068201541660c0840152600781015460e084015260088101546101008401526009810154610120840152600a810154610140840152600b810154610160840152600c810154610180840152600d8101546101a0840152600e8101546101c0840152600f8101546101e08401526010810154610200840152601181015461022084015260128101546102408401526013810154610260840152601481015461028084015260158101546102a084015260168101546102c084015260178101546102e084015260188101546103008401526019810154610320840152601a810154610340840152601b810154610360840152601c810154610380840152601d8101546103a0840152601e8101546103c0840152601f8101546103e084015260208101546104008401526021810154610420840152602281015461044084015260238101546104608401520154610480820152604051809160208252805160208301526020810151604083015260ff60408201511660608301526104806127f660608301516104a060808601526104c0850190612f61565b9160018060a01b0360808201511660a085015260018060a01b0360a08201511660c085015260018060a01b0360c08201511660e085015260e08101516101008501526101008101516101208501526101208101516101408501526101408101516101608501526101608101516101808501526101808101516101a08501526101a08101516101c08501526101c08101516101e08501526101e08101516102008501526102008101516102208501526102208101516102408501526102408101516102608501526102608101516102808501526102808101516102a08501526102a08101516102c08501526102c08101516102e08501526102e08101516103008501526103008101516103208501526103208101516103408501526103408101516103608501526103608101516103808501526103808101516103a08501526103a08101516103c08501526103c08101516103e08501526103e08101516104008501526104008101516104208501526104208101516104408501526104408101516104608501526104608101518285015201516104a08301520390f35b908092965052602081205b8582106129b757508101602001935061263081602461261e565b600181602092548385870101520191019061299d565b60249798508593506020925061263094915060ff191682840152151560051b820101959461261e565b503461011d578060031936011261011d576060604051612a158161301f565b828152604051612a2481613051565b83815283602082015283604082015283838201528360808201528360a08201528360c08201528360e08201528361010082015283610120820152836101408201528361016082015283610180820152836101a0820152836101c0820152836101e08201528361020082015283610220820152836102408201526020820152604051612aae8161306e565b83815283602082015283604082015283838201528360808201528360a08201528360c08201528360e08201528361010082015283610120820152836101408201528361016082015283610180820152836101a0820152836101c0820152836101e082015283610200820152604082015260405192612b2b8461308b565b808452806020850152806040850152808385015260808401520152610540604051612b558161301f565b60018152604051612b6581613051565b6001548152600254602082015260035460408201526004546060820152600554608082015260065460a082015260075460c082015260085460e0820152600954610100820152600a54610120820152600b54610140820152600c54610160820152600d54610180820152600e546101a0820152600f546101c08201526010546101e08201526011546102008201526012546102208201526013546102408201526020820190815263ffffffff610200604051612c208161306e565b6014548152601554602082015260165460408201526017546060820152601854608082015260195460a0820152601a5460c0820152601b5460e0820152601c54610100820152601d54610120820152601e54610140820152601f546101608201526020546101808201526021546101a08201526022546101c08201526023546101e08201528260245416828201526040850190815261024060405194612cc58661308b565b60255486526026546020870152602754604087015260018060a01b0360285416606087015260018060a01b0360295416608087015260608701958652604051965187525180516020880152602081015160408801526040810151606088015260608101516080880152608081015160a088015260a081015160c088015260c081015160e088015260e08101516101008801526101008101516101208801526101208101516101408801526101408101516101608801526101608101516101808801526101808101516101a08801526101a08101516101c08801526101c08101516101e08801526101e0810151848801528381015161022088015261022081015182880152015161026086015251805161028086015260208101516102a086015260408101516102c086015260608101516102e0860152608081015161030086015260a081015161032086015260c081015161034086015260e08101516103608601526101008101516103808601526101208101516103a08601526101408101516103c08601526101608101516103e08601526101808101516104008601526101a08101516104208601526101c08101516104408601526101e08101516104608601520151166104808301525180516104a083015260208101516104c083015260408101516104e083015260018060a01b03606082015116610500830152608060018060a01b0391015116610520820152f35b503461011d578060031936011261011d576040610d6c61324a565b503461011d578060031936011261011d576040610d6c61315a565b503461011d578060031936011261011d576040610d6c612ff6565b503461011d578060031936011261011d576040610d6c612f46612ff6565b612f5b612f54939293613b50565b9490612fb8565b92612fb8565b919082519283825260005b848110612f8d575050826000602080949584010152601f8019910116010190565b80602080928401015182828601015201612f6c565b600435906001600160a01b0382168203610bc557565b9190820391821161013257565b15612fcc57565b60405162461bcd60e51b8152602060048201526002602482015261626160f01b6044820152606490fd5b600354906004549061301d828461301661300e613b50565b921115612fc5565b1015612fc5565b565b6080810190811067ffffffffffffffff82111761303b57604052565b634e487b7160e01b600052604160045260246000fd5b610260810190811067ffffffffffffffff82111761303b57604052565b610220810190811067ffffffffffffffff82111761303b57604052565b60a0810190811067ffffffffffffffff82111761303b57604052565b6104a0810190811067ffffffffffffffff82111761303b57604052565b610360810190811067ffffffffffffffff82111761303b57604052565b6102c0810190811067ffffffffffffffff82111761303b57604052565b6101e0810190811067ffffffffffffffff82111761303b57604052565b6103c0810190811067ffffffffffffffff82111761303b57604052565b90601f8019910116810190811067ffffffffffffffff82111761303b57604052565b6040516370a0823160e01b815230600482015260208160248173f760fd8feb1f5e3bf3651e2e4f227285a82470ff5afa90811561320c57600091613218575b50906040516370a0823160e01b81523060048201526020816024817355a81da2a319dd60fb028c53cb4419493b56f6c05afa90811561320c576000916131dd575090565b90506020813d602011613204575b816131f860209383613138565b81010312610bc5575190565b3d91506131eb565b6040513d6000823e3d90fd5b90506020813d602011613242575b8161323360209383613138565b81010312610bc5575138613199565b3d9150613226565b6016549081606403606481116101325790565b90600182811c9216801561328d575b602083101461327757565b634e487b7160e01b600052602260045260246000fd5b91607f169161326c565b1561329e57565b60405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606490fd5b156132d757565b60405162461bcd60e51b815260206004820152600260248201526106f760f41b6044820152606490fd5b9190820180921161013257565b1561331557565b60405162461bcd60e51b8152602060048201526002602482015261737760f01b6044820152606490fd5b60001981146101325760010190565b90816020910312610bc557518015158103610bc55790565b1561336d57565b60405162461bcd60e51b81526020600482015260026024820152613a3960f11b6044820152606490fd5b81156133a1570490565b634e487b7160e01b600052601260045260246000fd5b156133be57565b60405162461bcd60e51b8152602060048201526002602482015261616d60f01b6044820152606490fd5b9190826040910312610bc5576020825192015190565b60405163071c628160e41b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561320c576000916134b3575b50613455614d49565b60405163519074c360e11b8152600481019290925260248201526020816044817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561320c576000916131dd575090565b90506020813d6020116134dd575b816134ce60209383613138565b81010312610bc557513861344c565b3d91506134c1565b604051906134f2826130fe565b60006101c0838281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a08201520152565b61355b6134e5565b5060018060a01b031680600052602c60205260406000209060405161357f816130e1565b60018060a01b0383541681526001830154602082015260ff60028401541692604082019384526003810154606083015260048101546080830152600581015460a083015260068101549060c0830191825260078101549460e08401958652600882015495610100850196875260098301546101208601908152600a840154610140870152600b840154610160870152600c840154610180870152600d840154956101a081019687526102a06015600e870154966101c08401978852600f8101546101e08501526010810154610200850152601181015461022085015260128101546102408501526013810154610260850152601481015461028085015201549101526040516370a0823160e01b815287600482015260208160248160018060a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa90811561320c57600091613a03575b5088511115945142101591826139f5575b506136f09051613c36565b949095518681106000146139ed57935b51858110156139e6575b604051636e52ab1960e11b8152600481018690527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169590936020856024818a5afa94851561320c576000956139b2575b5082156139a657604051630cddd73160e01b8152600481018490526020816024818b5afa90811561320c57600091613973575b5060ff600191975b5116149a8b613969575b8b61395f575b8b613955575b8b61394c575b8b613943575b8b613937575b516137d081614ce2565b602480546040516386e114bb60e01b81526004810187905291820187905263ffffffff1660448201819052909990969193919060208b606481845afa97881561320c578d9b600099613900575b506040516386e114bb60e01b8152600481019e909e5260248e018d905263ffffffff1660448e01528c6064815a93602094fa9b8c1561320c5760009c6138cc575b50613867613a35565b9c6040519e8f91613877836130fe565b82521515602082015260400152151560608d015260808c015260a08b015260c08a015260e08901526101008801526101208701526101408601526101608501526101808401526101a08301526101c082015290565b909b506020813d6020116138f8575b816138e860209383613138565b81010312610bc557519a3861385e565b3d91506138db565b9b50975060208b3d60201161392f575b8161391d60209383613138565b81010312610bc5578c9a51973861381d565b3d9150613910565b60018054149b506137c6565b9a50809a6137c0565b9a50839a6137ba565b8515159b506137b4565b8915159b506137ae565b8215159b506137a8565b90506020813d60201161399e575b8161398e60209383613138565b81010312610bc5575160ff613796565b3d9150613981565b600160ff60009761379e565b90946020823d6020116139de575b816139cd60209383613138565b8101031261011d5750519338613763565b3d91506139c0565b508461370a565b508593613700565b5142111591506136f06136e5565b90506020813d602011613a2d575b81613a1e60209383613138565b81010312610bc55751386136d4565b3d9150613a11565b60405163071c628160e41b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561320c57600091613b1e575b50613a8c61315a565b90613a9561324a565b929091604051946312c1d01760e31b865260048601526024850152604484015260648301526084820152671a8aeb910d69800060a4820152671337cc4354f6000060c482015260208160e48160018060a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa90811561320c576000916131dd575090565b90506020813d602011613b48575b81613b3960209383613138565b81010312610bc5575138613a83565b3d9150613b2c565b6040516370a0823160e01b815230600482015260208160248173bc7755a153e852cf76cccddb4c2e7c368f6259d85afa90811561320c57600091613bd3575b50906040516370a0823160e01b8152306004820152602081602481735babfc2f240bc5de90eb7e19d789412db1dec4025afa90811561320c576000916131dd575090565b90506020813d602011613bfd575b81613bee60209383613138565b81010312610bc5575138613b8f565b3d9150613be1565b15613c0c57565b60405162461bcd60e51b8152602060048201526002602482015261646560f01b6044820152606490fd5b60405163071c628160e41b81529091906020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561320c57600091613e5f575b50613c90614d49565b613c9b8215156133b7565b613ca68115156133b7565b613cae61315a565b9163ffffffff602454169360405196636676fcb560e11b88526004880152602487015260448601526064850152608484015260a483015260a08260c481600180851b037f0000000000000000000000000000000000000000000000000000000000000000165afa91821561320c576000908193613e25575b508015613e1d5760405163cc878ed960e01b815260048101919091526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561320c57600091613deb575b505b918015613de557604051630979d0cb60e41b815260048101919091526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561320c576000916131dd575090565b50600090565b90506020813d602011613e15575b81613e0660209383613138565b81010312610bc5575138613d83565b3d9150613df9565b506000613d85565b925060a0833d60a011613e57575b81613e4060a09383613138565b8101031261011d5750602082519201519138613d26565b3d9150613e33565b906020823d602011613e89575b81613e7960209383613138565b8101031261011d57505138613c87565b3d9150613e6c565b60405163071c628160e41b8152906020826004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa91821561320c57600092613fd3575b50613ee961315a565b60248054604051631a5fb62360e21b8152600481019690965290850192909252604484015263ffffffff16606483015260e0826084817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561320c5760008093819382938380938193613f6e575b5096959493929190565b96509450955050505060e0823d60e011613fcb575b81613f9060e09383613138565b8101031261011d57508051602082015160408301516060840151608085015160a086015160c090960151939692959194909391929038613f64565b3d9150613f83565b9091506020813d602011613fff575b81613fef60209383613138565b81010312610bc557519038613ee0565b3d9150613fe2565b6140128115156133b7565b60405163071c628160e41b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa801561320c576000906140e9575b6020915061406b614d49565b906140778115156133b7565b6140828215156133b7565b6040516378e3b7d360e01b8152600481019190915260248101919091526044810192909252816064816001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa90811561320c576000916131dd575090565b6020823d602011614114575b8161410260209383613138565b8101031261011d57506020905161405f565b3d91506140f5565b9060618202918083046061149015171561013257565b8181029291811591840414171561013257565b9061414e6134e5565b506040516370a0823160e01b81526001600160a01b03928316600482018190529092602090849060249082907f0000000000000000000000000000000000000000000000000000000000000000165afa92831561320c57600093614498575b5080600052602c60205260406000206040516141c8816130e1565b60018060a01b038254168152600182015460208201526102a0601560ff600285015416938460408501526003810154606085015260048101546080850152600581015460a0850152600681015460c0850152600781015460e085015260088101546101008501526009810154610120850152600a810154610140850152600b810154610160850152600c810154610180850152600d8101546101a0850152600e8101546101c0850152600f8101546101e0850152601081015461020085015260118101546102208501526012810154610240850152601381015461026085015260148101546102808501520154910152602054908160640360648111610132576142d460649186614132565b04926142df84613c36565b90602154956142ee8742613301565b93602254986142fd8a87613301565b96601e548210159b8c61448b575b8c61446c575b8c614462575b8c614457575b508b61444b575b90614371959493929161433682614ce2565b602480546040516386e114bb60e01b81526004810189905291820189905263ffffffff16604482015297909390602090899081906064820190565b03817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa97881561320c57600098614417575b5060206040519e8f926143c0846130fe565b835215159101526001811460408e01521560608d015260808c015260a08b015260c08a015260e08901526101008801526101208701526101408601526101608501526101808401526101a08301526101c082015290565b9097506020813d602011614443575b8161443360209383613138565b81010312610bc5575196386143ae565b3d9150614426565b60018054149b50614324565b8211159b503861431d565b8515159c50614317565b73507fbde39ba40da4fc79426ad5e3c64944fe43d48414159c50614311565b601f548311159c5061430b565b9092506020813d6020116144c4575b816144b460209383613138565b81010312610bc5575191386141ad565b3d91506144a7565b156144d357565b60405162461bcd60e51b8152602060048201526002602482015261636f60f01b6044820152606490fd5b6102043563ffffffff81168103610bc55790565b9060006103a06040516145238161311b565b828152606060208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a0820152826101c0820152826101e08201528261020082015282610220820152826102408201528261026082015282610280820152826102a0820152826102c0820152826102e0820152826103008201528261032082015282610340820152826103608201528261038082015201526014548110156106a0526106a051614c66575b6018546106005261460d6106005142613301565b601954610620526146216106205142613301565b601d54610680526146356106805142613301565b91601a5461064052606461464c6106405186614132565b0494601c546106605260646146646106605187614132565b046106e05261467161324a565b6105c0526105a052606461468b6105c0516105a051613301565b146107a0526017546105e05260646146a66105e05187614132565b046107005260646146b9601b5487614132565b046107205260646146d06105a05161070051614132565b0460646146e36105c05161070051614132565b046107805260646146fa6105a05161072051614132565b046108205260646147116105c05161072051614132565b04610520526147236108205182613301565b610760526147376105205161078051613301565b6107e052600061080052610800516107c0526108005161074052610800516106c0526107005115801590614c5a575b6149c3575b506000614779612f46612ff6565b9061478a6107c05161080051613301565b61479a6106c05161074051613301565b91101591826149b8575b50506149b0575b6000906107a0516107a0516149a6575b8061499f575b614977575b8115158061496c575b6147d883614ce2565b93604051610580526147ec6105805161311b565b60018060a01b0316610580515260409081516148088382613138565b60018152606f60f81b602082015260206105805101521515906105805101526106a051151560606105805101526107a0516080610580510152151560a061058051015260c061058051015260e06105805101526101006105805101526101206105805101526101406105805101526101606105805101526101806105805101526106e0516101a0610580510152610700516101c0610580510152610720516101e0610580510152610760516102006105805101526107e051610220610580510152610800516102406105805101526107c051610260610580510152610740516102806105805101526106c0516102a06105805101526105a0516102c06105805101526105c0516102e06105805101526105e05161030061058051015261060051610320610580510152610620516103406105805101526106405161036061058051015261066051610380610580510152610680516103a06105805101526105805190565b5060018054146147cf565b905061499961499461070051606461498e8a61411c565b04613301565b614007565b906147c6565b50806147c1565b506106a0516147bb565b5060016147ab565b1015905038806147a4565b6024805460405163036651af60e61b8152670de0b6b3a7640000600482015263ffffffff9091169181018290526020816044816001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa8015614c18576108005161056052614c26575b5060405163433effe960e11b8152670de0b6b3a7640000600482015260248101919091526020816044817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa8015614c18576108005161054052614bdd575b5061056051614b49575b5061054051614ab8575b3861476b565b61078051670de0b6b3a7640000610780510204670de0b6b3a7640000146107805115171561013257614afa61054051670de0b6b3a76400006107805102613397565b6107405261052051670de0b6b3a7640000610520510204670de0b6b3a7640000146105205115171561013257614b4061054051670de0b6b3a76400006105205102613397565b6106c052614ab2565b80670de0b6b3a7640000810204670de0b6b3a76400001481151715614bc35761056051614b7f91670de0b6b3a764000002613397565b61080052670de0b6b3a76400006108205102610820518104670de0b6b3a764000014610820511517156101325761056051614bb991613397565b6107c05238614aa8565b634e487b7160e01b61080051526011600452602461080051fd5b6020813d602011614c10575b81614bf660209383613138565b81010312614c0957516105405238614a9e565b6108005180fd5b3d9150614be9565b6040513d61080051823e3d90fd5b6020813d602011614c52575b81614c3f60209383613138565b81010312614c0957516105605238614a35565b3d9150614c32565b50610720511515614766565b6015548111156106a0526145f9565b63ffffffff602454166040519063ea40c34760e01b8252670de0b6b3a76400006004830152602482015260208160448160018060a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa90811561320c576000916131dd575090565b6024805460405163ea40c34760e01b8152600481019390935263ffffffff16908201526020816044816001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa90811561320c576000916131dd575090565b614d5161315a565b908015614ea857602480546040516357bcec0f60e01b8152600481019390935263ffffffff16908201526020816044816001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa90811561320c57600091614e76575b505b8115614e695760248054604051632792a1d760e11b8152600481019490945263ffffffff16908301526020826044816001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa801561320c57600090614e35575b614e32925090613301565b90565b506020823d602011614e61575b81614e4f60209383613138565b81010312610bc557614e329151614e27565b3d9150614e42565b614e329150600090613301565b90506020813d602011614ea0575b81614e9160209383613138565b81010312610bc5575138614dbc565b3d9150614e84565b506000614dbe565b90816020910312610bc557516001600160a01b0381168103610bc55790565b614ed76134e5565b5081600052602b60205260406000209060405190614ef4826130a7565b825482526001830154602083015260ff60028401541690604083019182526003840160405190816000825492614f298461325d565b80845293600181169081156154585750600114615411575b50614f4e92500382613138565b606084015260018060a01b03600485015416926080810193845260018060a01b0360058601541660a082015260018060a01b0360068601541660c0820152600785015460e082015260088501546101008201526009850154906101208101918252600a860154936101408201948552600b870154906101608301918252600c880154610180840152600d8801546101a0840152600e880154976101c08401988952600f8101546101e08501526010810154926102008501938452600160ff6011840154946102208801958652601285015497610240810198895261048060246013880154976102608401988952601481015461028085015260158101546102a085015260168101546102c085015260178101546102e085015260188101546103008501526019810154610320850152601a810154610340850152601b810154610360850152601c810154610380850152601d8101546103a0850152601e8101546103c0850152601f8101546103e085015260208101546104008501526021810154610420850152602281015461044085015260238101546104608501520154910152511614958661536f575b8680985097615363575b5086615357575b859697869761534b575b508661533f575b9185939184938495615333575b5084615327575b83949560009561526d575b505060009061514861547a565b9661524c575b506000948597869387956151fc575b50615166613a35565b9960009b60009d866151ec575b50516040519e8f92916001600160a01b031661518e846130fe565b8352602083015215159060400152151560608d0152151560808c0152151560a08b015260c08a015260e089015261010088015261012087015261014086015261016085015261018084015215156101a083015215156101c082015290565b518c109d508887119c5038615173565b96509350915083948380615242575b61522b575b5061521a85614007565b9161522483614ce2565b933861515d565b51909650935061523b8385612fb8565b9538615210565b508051851061520b565b9050615263606461525c8661411c565b0487613301565b905111153861514e565b51905160248054604051632581316f60e11b815260048101949094529083019190915263ffffffff16604482015290939192506020816064816001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa9182156121d05790818794936152ed575b505092388061513b565b91509192506020823d60201161531f575b8161530b60209383613138565b8101031261011d57509084915138806152e3565b3d91506152fe565b60018054149450615130565b51421015945038615129565b6001805414965061511c565b51421015965038615115565b6001805414965061510b565b51421015965038615104565b6040516331a9108f60e11b8152600481018d905291979096506020826024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa91821561320c576000926153e0575b506001600160a01b039182169116149486906150fa565b61540391925060203d60201161540a575b6153fb8183613138565b810190614eb0565b90386153c9565b503d6153f1565b90506000929192526020600020906000915b81831061543c575050906020614f4e9282010138614f41565b6020919350806001915483858801015201910190918392615423565b905060209250614f4e94915060ff191682840152151560051b82010138614f41565b6040516370a0823160e01b815230600482015260208160248173833589fcd6edb6e08f4c7c32d4f71b54bda029135afa90811561320c576000916131dd575090565b919061030052610380526154d9816154d261547a565b10156133b7565b6154e38133614511565b610500526154ff604061050051015160006103405215156132d0565b610300516020610500510152615513613b50565b6102c0610500939293510151906102e061050051015160235490607842014211615e87576040519363f863485b60e01b85528560048601526024850152604484015280606484015260848301526078420160a483015260408260c4816103405160018060a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1938415615c5f5761034051926103405195615ea1575b50916155d4816100dc876155e395610edd6155f3986100dc610ed5613b50565b61024061050051015190613301565b9261028061050051015190613301565b9161560081600354613301565b60035561560f83600454613301565b60045560055492600184018411615e87578391610100610500510151610120610500510151610140610500510151615645614c75565b61564d6133fe565b615655613a35565b9161016061050051015193610180610500510151956101a061050051015197600160c06105005101519c6101c06105005101516102c0526102406105005101516104e0526102806105005101516104c0526101e06105005101516104a052610260610500510151610480526102a0610500510151610460526102c0610500510151610440526102e061050051015161042052610300610500510151610400526103206105005101516103e0526103406105005101516103c0526103606105005101516103a052610380610500510151610360526103a0610500510151610320526040516102e0526157486102e0516130a7565b016102e05152600160206102e0510152600160406102e05101526103005160606102e05101523360806102e05101526103405160a06102e051015260018060a01b03610380511660c06102e05101524260e06102e0510152426101006102e05101526101206102e05101526101406102e05101526101606102e05101526101806102e05101526101a06102e05101526101c06102e05101526101e06102e05101526102006102e05101526102206102e05101526102406102e05101526102606102e05101526102806102e0510152610340516102a06102e0510152610340516102c06102e05101526102c0516102e0805101526104e0516103006102e05101526104c0516103206102e05101526104a0516103406102e0510152610480516103606102e0510152610460516103806102e0510152610440516103a06102e0510152610420516103c06102e0510152610400516103e06102e05101526103e0516104006102e05101526103c0516104206102e05101526103a0516104406102e0510152610360516104606102e0510152610320516104806102e0510152600182016103405152602b602052604061034051206102e05151815560206102e0510151600182015560ff60406102e05101511660ff60028301911660ff1982541617905560606102e051015180519067ffffffffffffffff8211615e6d57615950600384015461325d565b601f8111615e20575b506020906001601f841114615da657918091615b629594936103405192615d9b575b50508160011b916000199060031b1c19161760038201555b6102e0805160808101516004840180546001600160a01b03199081166001600160a01b039384161790915560a08301516005808701805484169285169290921790915560c0840151600687018054909316931692909217905560e0820151600785015561010082015160088501556101208201516009850155610140820151600a850155610160820151600b850155610180820151600c8501556101a0820151600d8501556101c0820151600e8501556101e0820151600f850155610200820151601085015561022082015160118501556102408201516012850155610260820151601385015561028082015160148501556102a082015160158501556102c0820151601685015591810151601784015561030081015160188401556103208101516019840155610340810151601a840155610360810151601b840155610380810151601c8401556103a0810151601d8401556103c0810151601e8401556103e0810151601f8401556104008101516020840155610420810151602184015561044081015160228401556104608101516023840155610480015160249092019190915554615b409061333f565b600555615b576101a0610500510151600e54613301565b600e55600b54613301565b600b55615b796101c0610500510151600c54613301565b600c55615b906101e0610500510151600d54613301565b600d5561026061050051015115801590615d8a575b615c74575b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b15615c6d576040516340c10f1960e01b81526103408051336004840152600184016024840152905191939091849160449183915af1918215615c5f57600192615c4c575b50016025819055610340517ff244c95a01cd7c2eb6b82c48d18918858df587f10f2c3c2cb5675f5d102f26ce9080a2565b61034051615c5991613138565b38615c1b565b6040513d61034051823e3d90fd5b6103405180fd5b615cc4615c7f61315a565b610500516102608101516102a09091015160408051636de19f8b60e01b8152600481019390935260248301919091524260780160448301529093849081906064820190565b03816103405160018060a01b037f0000000000000000000000000000000000000000000000000000000000000000165af1928315615c5f5761034051906103405194615d66575b50615d1461315a565b93610260610500510151615d51575b5050506102a0610500510151615d3c575b505050615baa565b615d49926100dc91613301565b388080615d34565b615d5e926100dc91613301565b388080615d23565b9050615d8291935060403d60401161119e5761118e8183613138565b929038615d0b565b506102a06105005101511515615ba5565b01519050388061597b565b9060038401610340515280610340512091610340515b601f1985168110615e085750918391600193615b62979695601f19811610615def575b505050811b016003820155615993565b015160001960f88460031b161c19169055388080615ddf565b91926020600181928685015181550194019201615dbc565b60038401610340515260206103405120601f840160051c810160208510615e66575b601f830160051c82018110615e58575050615959565b610340518155600101615e42565b5080615e42565b634e487b7160e01b61034051526041600452602461034051fd5b634e487b7160e01b61034051526011600452602461034051fd5b610edd95506155f393506155e392916100dc615ece6155d49360403d60401161119e5761118e8183613138565b9850955092935091506155b4565b604051632b74522360e21b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561320c57600091615f3c575b506001600160a01b0391821691161490565b615f55915060203d60201161540a576153fb8183613138565b38615f2a56fea2646970667358221220513e59ed246b9f486f319985ea891534a3ccd72f4ad485c19c63ce177821db4964736f6c634300081a00330000000000000000000000004c15f778ab59f25d5dfd2dd508236a25ed2813fe000000000000000000000000c0df50143ea93aec63e38a6ed4e92b378079ea150000000000000000000000009b8a45c4a0fbd44158480d9b4b41e0bdca42874c000000000000000000000000b8ed155ab154b2dbadcc07b814cc52e92dc75ae100000000000000000000000003fee5ba01d5b71c7f7689490826ba75a2750c44000000000000000000000000e29a221ac6e69927161c3dfcc663f75119421178

Deployed Bytecode

0x6108406040526004361015610148575b361561001a57600080fd5b610028600160005414613297565b6002600055604080519061003c8183613138565b60018252603960f91b60208301526100553415156133b7565b61005d61547a565b60784201804211610132578251630e543ca360e11b81526004810191909152602081602481347f00000000000000000000000003fee5ba01d5b71c7f7689490826ba75a2750c446001600160a01b03165af192831561012857506000926100ef575b6100e8600085856100e3866100dc836100d661547a565b92613301565b111561330e565b6154bc565b6001600055005b90916020823d602011610120575b8161010a60209383613138565b8101031261011d575051906100e86100bf565b80fd5b3d91506100fd565b513d6000823e3d90fd5b634e487b7160e01b600052601160045260246000fd5b6000803560e01c80630bedc17714612f285780630c0dd73414612f0d5780630fd8aee814612ef2578063117dc51b14612ed75780631865c57d146129f65780631ce5e9a6146124a6578063278ecde1146122585780632867d07c14611c9b578063298fe70e146119b45780632e1717c6146119995780633d103b97146118e45780633f5632391461181c57806347249493146117f75780634b68b8af146117dc5780634cd3723a1461152257806358e82c44146111df57806359cb936f146111c4578063670791b414610dc157806369ba1a7514610d7857806386ce9e3714610d4d57806396bb2d5c14610d035780639c16860a14610bdd5780639e281a9814610a04578063b78f15bc146109e5578063cb66cbd414610906578063ce2beaa114610567578063d289ffdb146103bf578063e7572230146103a0578063fb3571651461037d5763fbae4f431461029e575061000f565b3461011d57604036600319011261011d576101e06102c66102bd612fa2565b60243590614ecf565b6101c06040519160018060a01b0381511683526020810151602084015260408101511515604084015260608101511515606084015260808101511515608084015260a0810151151560a084015260c081015160c084015260e081015160e08401526101008101516101008401526101208101516101208401526101408101516101408401526101608101516101608401526101808101516101808401526101a081015115156101a0840152015115156101c0820152f35b503461011d578060031936011261011d576020610398614d49565b604051908152f35b503461011d57602036600319011261011d576020610398600435614ce2565b503461011d57604036600319011261011d576103e56103dc612fa2565b60243590614511565b60405180916020825260018060a01b0381511660208301526103a061041b60208301516103c060408601526103e0850190612f61565b916040810151151560608501526060810151151560808501526080810151151560a085015260a0810151151560c085015260c081015160e085015260e08101516101008501526101008101516101208501526101208101516101408501526101408101516101608501526101608101516101808501526101808101516101a08501526101a08101516101c08501526101c08101516101e08501526101e08101516102008501526102008101516102208501526102208101516102408501526102408101516102608501526102608101516102808501526102808101516102a08501526102a08101516102c08501526102c08101516102e08501526102e08101516103008501526103008101516103208501526103208101516103408501526103408101516103608501526103608101516103808501526103808101518285015201516103c08301520390f35b503461011d5761022036600319011261011d576105876001825414613297565b6002815561059c61059733615edc565b613c05565b60025442106108dc57600435620f4240811015806108ce575b806108c3575b6105c4906144cc565b610736602435633b9aca00811015806108b4575b6105e1906144cc565b6044356037811015806108a9575b6105f8906144cc565b60643560018110158061089e575b61060f906144cc565b6084356201518081101580610891575b610628906144cc565b60a43562278d0081101580610883575b610641906144cc565b60c435603781101580610878575b8061086b575b61065e906144cc565b60e435600181101580610860575b610675906144cc565b6101043591603783101580610855575b61068e906144cc565b61012435936302932e0085101580610847575b6106aa906144cc565b610144359566038d7ea4c6800087101580610835575b80610829575b6106cf906144cc565b61016435976106e968056bc75e2d631000008a10156144cc565b610184359960018b10158061081e575b610702906144cc565b6101a4359b61071e620d2f008e10158e81610810575b506144cc565b6101c4359d620151808f10158f8161080257506144cc565b6101e4359e8f6109c4101561074a906144cc565b6107526144fd565b63ffffffff1660011115806107e4575b61076b906144cc565b610e1042018042116107cd57600255601455601555601655601755601855601955601a55601b55601c55601d55601e55601f5560205560215560225560235563ffffffff6107b76144fd565b1663ffffffff1960245416176024556001815580f35b50505060248f634e487b7160e01b81526011600452fd5b5061076b610e1063ffffffff6107f86144fd565b1611159050610762565b62278d00915011158f610718565b6283d600915011158e610718565b5060148b11156106f9565b506101643587106106c6565b50670de0b6b3a76400008711156106c0565b506307b98a008511156106a1565b50605f831115610685565b50600f81111561066c565b5061010435811115610655565b50605a81111561064f565b5063018b8200811115610638565b506276a70081111561061f565b50600f811115610606565b50605f8111156105ef565b5064174876e8008111156105d8565b5060243581106105bb565b506305f5e1008111156105b5565b60405162461bcd60e51b8152602060048201526002602482015261746960f01b6044820152606490fd5b503461011d57604036600319011261011d576101e061092f610926612fa2565b60243590614145565b6109e360405180926101c0809160018060a01b0381511684526020810151151560208501526040810151151560408501526060810151151560608501526080810151608085015260a081015160a085015260c081015160c085015260e081015160e08501526101008101516101008501526101208101516101208501526101408101516101408501526101608101516101608501526101808101516101808501526101a08101516101a08501520151910152565bf35b503461011d57602036600319011261011d576020610398600435614007565b503461011d57604036600319011261011d578080610a20612fa2565b60243590610a3061059733615edc565b610a3b8215156133b7565b6001600160a01b031680610ad057508181610a598293471015612fc5565b73507fbde39ba40da4fc79426ad5e3c64944fe43d45af13d15610ac7573d67ffffffffffffffff8111610ab357604051610ab09291610aa2601f8201601f191660200183613138565b81528360203d92013e613366565b80f35b634e487b7160e01b83526041600452602483fd5b610ab090613366565b6040516370a0823160e01b8152306004820152909250602081602481865afa908115610bd2578491610b94575b5081610b10602094936044931015612fc5565b604051948593849263a9059cbb60e01b845273507fbde39ba40da4fc79426ad5e3c64944fe43d4600485015260248401525af18015610b8957610ab0918391610b5a575b50613366565b610b7c915060203d602011610b82575b610b748183613138565b81019061334e565b38610b54565b503d610b6a565b6040513d84823e3d90fd5b935050906020833d602011610bca575b81610bb160209383613138565b81010312610bc55791518392919081610afd565b600080fd5b3d9150610ba4565b6040513d86823e3d90fd5b50602036600319011261011d57610bf2612fa2565b610bff6001835414613297565b600282556040908151610c128382613138565b60018152606560f81b6020820152610c2b3415156133b7565b610c3361547a565b60784201804211610cef578451630e543ca360e11b81526004810191909152602081602481347f00000000000000000000000003fee5ba01d5b71c7f7689490826ba75a2750c446001600160a01b03165af1948515610ce657508594610cb0575b50926100e3610ca9946100dc836100d661547a565b6001815580f35b93506020843d602011610cde575b81610ccb60209383613138565b81010312610bc5579251926100e3610c94565b3d9150610cbe565b513d87823e3d90fd5b634e487b7160e01b86526011600452602486fd5b503461011d578060031936011261011d5760e090610d1f613e91565b9560409591959492945197508752602087015260408601526060850152608084015260a083015260c0820152f35b503461011d57602036600319011261011d576040610d6c600435613c36565b82519182526020820152f35b503461011d57602036600319011261011d57600435610d9a6001835414613297565b60028255610daa61059733615edc565b610db76001821115613c05565b6001556001815580f35b503461011d578060031936011261011d57610ddf6001825414613297565b60028155610dec33613553565b610dfb602082015115156132d0565b338252602c6020526040822090610e1061315a565b610e2261012084019283511115612fc5565b610e3461014084019182511115612fc5565b610e3c613b50565b9251915160784201928342116111b0576040805163d568e56560e01b815260048101929092526024820192909252604481019390935282606481896001600160a01b037f00000000000000000000000003fee5ba01d5b71c7f7689490826ba75a2750c44165af19182156111a55786908793611171575b50801561114357610ee2816100dc858a97610edd60e0976100dc610ed5613b50565b979092613301565b613301565b60c08501518082101561113b5750935b0151808210156111335750925b60028101600260ff1982541617905560038101610f1c815461333f565b905542600582015582600f82015583601082015560118101610f3f848254613301565b905560128101610f50858254613301565b9055610f5d60115461333f565b601155610f6c83601254613301565b601255610f7b84601354613301565b60135560080180546040516323b872dd60e01b815233600482015230602482015260448101919091526001600160a01b037f000000000000000000000000c0df50143ea93aec63e38a6ed4e92b378079ea1516919060208160648187875af18015610bd257610ff0918591610b5a5750613366565b54813b1561112f578291602483926040519485938492630852cd8d60e31b845260048401525af18015610b895761111a575b505060405163a9059cbb60e01b815233600482015260248101919091526020816044818673bc7755a153e852cf76cccddb4c2e7c368f6259d85af1801561110f57611073918491610b5a5750613366565b806110ba575b50336001600160601b0360a01b6029541617602955337f4e9344e3e55e1ebd97b68bfc076e1c3082590c93fc7bb3ce04403430dfa13ed68280a26001815580f35b60405163a9059cbb60e01b8152336004820152602481019190915260208160448185735babfc2f240bc5de90eb7e19d789412db1dec4025af18015610b8957611109918391610b5a5750613366565b38611079565b6040513d85823e3d90fd5b8161112491613138565b61112f578238611022565b8280fd5b905092610eff565b905093610ef2565b60405162461bcd60e51b815260206004820152600660248201526534b739a232b160d11b6044820152606490fd5b905061119691925060403d60401161119e575b61118e8183613138565b8101906133e8565b919038610eb3565b503d611184565b6040513d88823e3d90fd5b634e487b7160e01b88526011600452602488fd5b503461011d578060031936011261011d576040610d6c613b50565b503461011d57602036600319011261011d576111fe6001825414613297565b6002815561120e60043533614145565b61121d602082015115156132d0565b338252602c6020526040822090606081015161148e575b600382015490608081015160c08201519061124d614c75565b946112566133fe565b9261125f613a35565b96610140860151976101608701519560e0880151926101008901519460118701549660120154976101808b0151996101a08c01519b6101c001519c6040519e8f916112a9836130e1565b3383526020830160019052604083016001905260608301524260808301524260a083015260c082015260e001526101008d01526101208c01526101408b01526101608a01526101808901526101a08801526101c0870152866101e0870152866102008701526102208601526102408501526102608401526102808301526102a0820152338252602c6020526040822090600160a01b60019003600160a01b60019003825116166001600160601b0360a01b83541617825560208101516001830155604081015160ff16600283019060ff1660ff19825416179055606081015160038301556080810151600483015560a0810151600583015560c0810151600683015560e0810151600783015561010081015160088301556101208101516009830155610140810151600a830155610160810151600b830155610180810151600c8301556101a0810151600d8301556101c0810151600e8301556101e0810151600f830155610200810151601083015561022081015160118301556102408101516012830155610260810151601383015561028081015160148301556102a001519060150155336001600160601b0360a01b6028541617602855337f37ad7683b355ff02aa5cc2c5459f75746c9ebfe6200244351d4ffb679eb06ff88280a26001815580f35b611499600f5461333f565b600f55602a546801000000000000000081101561150e576001810180602a558110156114fa57602a84527fbeced09521047d05b8960b7e7bcc1d1292cf3e4b2a6b63f48335cbde5f7545d20180546001600160a01b03191633179055611234565b634e487b7160e01b84526032600452602484fd5b634e487b7160e01b84526041600452602484fd5b503461011d57602036600319011261011d5760406102c091611542612fa2565b816102a08451611551816130e1565b82815282602082015282868201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a0820152826101c0820152826101e08201528261020082015282610220820152826102408201528261026082015282610280820152015260018060a01b03168152602c602052206102a06040516115f9816130e1565b601560018060a01b03845416938483526001810154602084015260ff60028201541660408401526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460e084015260088101546101008401526009810154610120840152600a810154610140840152600b810154610160840152600c810154610180840152600d8101546101a0840152600e8101546101c0840152600f8101546101e0840152601081015461020084015260118101546102208401526012810154610240840152601381015461026084015260148101546102808401520154828201526040519283526020810151602084015260ff6040820151166040840152606081015160608401526080810151608084015260a081015160a084015260c081015160c084015260e081015160e08401526101008101516101008401526101208101516101208401526101408101516101408401526101608101516101608401526101808101516101808401526101a08101516101a08401526101c08101516101c08401526101e08101516101e084015261020081015161020084015261022081015161022084015261024081015161024084015261026081015161026084015261028081015161028084015201516102a0820152f35b503461011d578060031936011261011d576020610398613a35565b503461011d57602036600319011261011d576101e061092f611817612fa2565b613553565b503461011d578060031936011261011d57604051806020602a5491828152018091602a85527fbeced09521047d05b8960b7e7bcc1d1292cf3e4b2a6b63f48335cbde5f7545d290855b8181106118c5575050508261187b910383613138565b604051928392602084019060208552518091526040840192915b8181106118a3575050500390f35b82516001600160a01b0316845285945060209384019390920191600101611895565b82546001600160a01b0316845260209093019260019283019201611865565b503461011d57604036600319011261011d576004356024356001600160a01b038116810361112f576119196001845414613297565b600283556040516323b872dd60e01b815233600482015230602482015260448101839052916020836064818773833589fcd6edb6e08f4c7c32d4f71b54bda029135af1928315610bd257610ca993611977918691610b5a5750613366565b60405190611986604083613138565b60018252606960f81b60208301526154bc565b503461011d578060031936011261011d5760206103986133fe565b503461011d57602036600319011261011d57600435906119d76001825414613297565b600281556119e58233614ecf565b6119f4604082015115156132d0565b60c0810190611a05825115156133b7565b838352602b6020526040832060128101611a228154600354612fb8565b60035560138201611a368154600454612fb8565b600455611a4161315a565b90925491546078420192834211611c875760408051636de19f8b60e01b8152600481019290925260248201929092526044810193909352826064818a6001600160a01b037f00000000000000000000000003fee5ba01d5b71c7f7689490826ba75a2750c44165af1908115611c7c5791611b6895949391611ad99389928a92611c4f575b50610edd6100dc93946100dc610ed561315a565b606082015115159182611c40575b611b5c9161016060119285600014611c395760035b60028401805460ff191660ff929092169190911790558751601584015501805160168301556005820180546001600160a01b03191633179055426008830155600654909490611b4a9061333f565b600655611c13575b0154600e54612fb8565b600e5551601054613301565b601055517f0000000000000000000000004c15f778ab59f25d5dfd2dd508236a25ed2813fe6001600160a01b031690813b1561112f57604051634429bfc160e01b815233600482015260248101919091529082908290604490829084905af18015610b8957611c03575b5090806026557ff82d7919414fdf3350e6209f0613cc1a2bfb7c9f841543d78b2e59dd3b280f2b8280a26001815580f35b81611c0d91613138565b38611bd2565b611c1e60075461333f565b600755611c316010820154600854613301565b600855611b52565b6002611afc565b61016081015115159250611ae7565b6100dc9350610edd949250611c729060403d60401161119e5761118e8183613138565b9294909350611ac5565b6040513d89823e3d90fd5b634e487b7160e01b89526011600452602489fd5b503461011d578060031936011261011d5780610340604051611cbc816130c4565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a0820152826101c0820152826101e08201528261020082015282610220820152826102408201528261026082015282610280820152826102a0820152826102c0820152826102e082015282610300820152826103208201520152611d71614c75565b6101605260405163071c628160e41b81526020816004817f0000000000000000000000004c15f778ab59f25d5dfd2dd508236a25ed2813fe6001600160a01b03165afa8015610b89578261022052612220575b50611dcd6133fe565b90611dd6613a35565b6101c052611de2614d49565b61028052611dee61324a565b60a05291611e30611dfd613b50565b9061026052611e0a612ff6565b611e15939193612ff6565b611e2a611e23949294613b50565b9590612fb8565b93612fb8565b6102a052611e3c61315a565b949093611e47613e91565b610200526101e05261024052610180526101005260e05260c052611e7060646102805104614007565b6101a052611e8360646102205104613c36565b610140526101205260405163cc878ed960e01b815260048101869052967f0000000000000000000000009b8a45c4a0fbd44158480d9b4b41e0bdca42874c6001600160a01b0316602089602481845afa988915612215578a996121dc575b50602060249160405192838092630979d0cb60e41b82528c60048301525afa998a156121d057809a612199575b5050604051608052611f216080516130c4565b61016051608051526102205160206080510152604060805101526101c05160606080510152610280516080805101526102605160a0608051015260c0608051015260e06080510152610100608051015261012060805101526102a0516101406080510152610160608051015261018060805101526101a060805101526101c060805101526101e0608051015260a051610200608051015260c051610220608051015260e0516102406080510152610100516102606080510152610180516102806080510152610240516102a060805101526101e0516102c06080510152610200516102e060805101526101a0516103006080510152610120516103206080510152610140516103406080510152610360604051610160518152602060805101516020820152604060805101516040820152606060805101516060820152608080510151608082015260a0608051015160a082015260c0608051015160c082015260e0608051015160e0820152610100608051015161010082015261012060805101516101208201526101406080510151610140820152610160608051015161016082015261018060805101516101808201526101a060805101516101a08201526101c060805101516101c08201526101e060805101516101e0820152610200608051015161020082015261022060805101516102208201526102406080510151610240820152610260608051015161026082015261028060805101516102808201526102a060805101516102a08201526102c060805101516102c08201526102e060805101516102e0820152610300608051015161030082015261032060805101516103208201526103406080510151610340820152f35b909199506020823d6020116121c8575b816121b660209383613138565b8101031261011d575051973880611f0e565b3d91506121a9565b604051903d90823e3d90fd5b9098506020813d60201161220d575b816121f860209383613138565b810103126122095751976020611ee1565b8980fd5b3d91506121eb565b6040513d8c823e3d90fd5b6020813d602011612250575b8161223960209383613138565b8101031261224c57516102205238611dc4565b5080fd5b3d915061222c565b503461011d57602036600319011261011d5760043561227a6001835414613297565b60028255612296608061228d8333614ecf565b015115156132d0565b808252602b60205260408220601281016122b38154600354612fb8565b600355601382016122c78154600454612fb8565b6004556122d261547a565b9154905460235460784201918242116111b05760405163f6a6e1c360e01b815260048101949094526024840152604483018190526064830152608482015260208160a481887f00000000000000000000000003fee5ba01d5b71c7f7689490826ba75a2750c446001600160a01b03165af190811561249b578591612461575b50916123686020926100dc612403956100d661547a565b61237061547a565b90612382601182019283541115612fc5565b60028101805460ff191660041790556005810180546001600160a01b03191633179055426008909101556009546123b89061333f565b6009556123c88154600a54613301565b600a556123d88154600e54612fb8565b600e555460405163a9059cbb60e01b8152336004820152602481019190915291829081906044820190565b03818673833589fcd6edb6e08f4c7c32d4f71b54bda029135af1801561110f57612433918491610b5a5750613366565b806027557e0f2353cc2b9054c072a7083055e8fc4edeba7bbfa38e68bd13d16d17fd68e48280a26001815580f35b9290506020833d602011612493575b8161247d60209383613138565b8101031261248f579151612368612351565b8480fd5b3d9150612470565b6040513d87823e3d90fd5b503461011d57602036600319011261011d57806104806040516124c8816130a7565b8281528260208201528260408201526060808201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a0820152826101c0820152826101e08201528261020082015282610220820152826102408201528261026082015282610280820152826102a0820152826102c0820152826102e08201528261030082015282610320820152826103408201528261036082015282610380820152826103a0820152826103c0820152826103e08201528261040082015282610420820152826104408201528261046082015201526004358152602b60205260408120604051906125d6826130a7565b805482526001810154602083015260ff60028201541660408301526003810160405190848154916126068361325d565b80855292600181169081156129cd5750600114612992575b50505061263081602494950382613138565b606084015260018060a01b03600482015416608084015260018060a01b0360058201541660a084015260018060a01b0360068201541660c0840152600781015460e084015260088101546101008401526009810154610120840152600a810154610140840152600b810154610160840152600c810154610180840152600d8101546101a0840152600e8101546101c0840152600f8101546101e08401526010810154610200840152601181015461022084015260128101546102408401526013810154610260840152601481015461028084015260158101546102a084015260168101546102c084015260178101546102e084015260188101546103008401526019810154610320840152601a810154610340840152601b810154610360840152601c810154610380840152601d8101546103a0840152601e8101546103c0840152601f8101546103e084015260208101546104008401526021810154610420840152602281015461044084015260238101546104608401520154610480820152604051809160208252805160208301526020810151604083015260ff60408201511660608301526104806127f660608301516104a060808601526104c0850190612f61565b9160018060a01b0360808201511660a085015260018060a01b0360a08201511660c085015260018060a01b0360c08201511660e085015260e08101516101008501526101008101516101208501526101208101516101408501526101408101516101608501526101608101516101808501526101808101516101a08501526101a08101516101c08501526101c08101516101e08501526101e08101516102008501526102008101516102208501526102208101516102408501526102408101516102608501526102608101516102808501526102808101516102a08501526102a08101516102c08501526102c08101516102e08501526102e08101516103008501526103008101516103208501526103208101516103408501526103408101516103608501526103608101516103808501526103808101516103a08501526103a08101516103c08501526103c08101516103e08501526103e08101516104008501526104008101516104208501526104208101516104408501526104408101516104608501526104608101518285015201516104a08301520390f35b908092965052602081205b8582106129b757508101602001935061263081602461261e565b600181602092548385870101520191019061299d565b60249798508593506020925061263094915060ff191682840152151560051b820101959461261e565b503461011d578060031936011261011d576060604051612a158161301f565b828152604051612a2481613051565b83815283602082015283604082015283838201528360808201528360a08201528360c08201528360e08201528361010082015283610120820152836101408201528361016082015283610180820152836101a0820152836101c0820152836101e08201528361020082015283610220820152836102408201526020820152604051612aae8161306e565b83815283602082015283604082015283838201528360808201528360a08201528360c08201528360e08201528361010082015283610120820152836101408201528361016082015283610180820152836101a0820152836101c0820152836101e082015283610200820152604082015260405192612b2b8461308b565b808452806020850152806040850152808385015260808401520152610540604051612b558161301f565b60018152604051612b6581613051565b6001548152600254602082015260035460408201526004546060820152600554608082015260065460a082015260075460c082015260085460e0820152600954610100820152600a54610120820152600b54610140820152600c54610160820152600d54610180820152600e546101a0820152600f546101c08201526010546101e08201526011546102008201526012546102208201526013546102408201526020820190815263ffffffff610200604051612c208161306e565b6014548152601554602082015260165460408201526017546060820152601854608082015260195460a0820152601a5460c0820152601b5460e0820152601c54610100820152601d54610120820152601e54610140820152601f546101608201526020546101808201526021546101a08201526022546101c08201526023546101e08201528260245416828201526040850190815261024060405194612cc58661308b565b60255486526026546020870152602754604087015260018060a01b0360285416606087015260018060a01b0360295416608087015260608701958652604051965187525180516020880152602081015160408801526040810151606088015260608101516080880152608081015160a088015260a081015160c088015260c081015160e088015260e08101516101008801526101008101516101208801526101208101516101408801526101408101516101608801526101608101516101808801526101808101516101a08801526101a08101516101c08801526101c08101516101e08801526101e0810151848801528381015161022088015261022081015182880152015161026086015251805161028086015260208101516102a086015260408101516102c086015260608101516102e0860152608081015161030086015260a081015161032086015260c081015161034086015260e08101516103608601526101008101516103808601526101208101516103a08601526101408101516103c08601526101608101516103e08601526101808101516104008601526101a08101516104208601526101c08101516104408601526101e08101516104608601520151166104808301525180516104a083015260208101516104c083015260408101516104e083015260018060a01b03606082015116610500830152608060018060a01b0391015116610520820152f35b503461011d578060031936011261011d576040610d6c61324a565b503461011d578060031936011261011d576040610d6c61315a565b503461011d578060031936011261011d576040610d6c612ff6565b503461011d578060031936011261011d576040610d6c612f46612ff6565b612f5b612f54939293613b50565b9490612fb8565b92612fb8565b919082519283825260005b848110612f8d575050826000602080949584010152601f8019910116010190565b80602080928401015182828601015201612f6c565b600435906001600160a01b0382168203610bc557565b9190820391821161013257565b15612fcc57565b60405162461bcd60e51b8152602060048201526002602482015261626160f01b6044820152606490fd5b600354906004549061301d828461301661300e613b50565b921115612fc5565b1015612fc5565b565b6080810190811067ffffffffffffffff82111761303b57604052565b634e487b7160e01b600052604160045260246000fd5b610260810190811067ffffffffffffffff82111761303b57604052565b610220810190811067ffffffffffffffff82111761303b57604052565b60a0810190811067ffffffffffffffff82111761303b57604052565b6104a0810190811067ffffffffffffffff82111761303b57604052565b610360810190811067ffffffffffffffff82111761303b57604052565b6102c0810190811067ffffffffffffffff82111761303b57604052565b6101e0810190811067ffffffffffffffff82111761303b57604052565b6103c0810190811067ffffffffffffffff82111761303b57604052565b90601f8019910116810190811067ffffffffffffffff82111761303b57604052565b6040516370a0823160e01b815230600482015260208160248173f760fd8feb1f5e3bf3651e2e4f227285a82470ff5afa90811561320c57600091613218575b50906040516370a0823160e01b81523060048201526020816024817355a81da2a319dd60fb028c53cb4419493b56f6c05afa90811561320c576000916131dd575090565b90506020813d602011613204575b816131f860209383613138565b81010312610bc5575190565b3d91506131eb565b6040513d6000823e3d90fd5b90506020813d602011613242575b8161323360209383613138565b81010312610bc5575138613199565b3d9150613226565b6016549081606403606481116101325790565b90600182811c9216801561328d575b602083101461327757565b634e487b7160e01b600052602260045260246000fd5b91607f169161326c565b1561329e57565b60405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606490fd5b156132d757565b60405162461bcd60e51b815260206004820152600260248201526106f760f41b6044820152606490fd5b9190820180921161013257565b1561331557565b60405162461bcd60e51b8152602060048201526002602482015261737760f01b6044820152606490fd5b60001981146101325760010190565b90816020910312610bc557518015158103610bc55790565b1561336d57565b60405162461bcd60e51b81526020600482015260026024820152613a3960f11b6044820152606490fd5b81156133a1570490565b634e487b7160e01b600052601260045260246000fd5b156133be57565b60405162461bcd60e51b8152602060048201526002602482015261616d60f01b6044820152606490fd5b9190826040910312610bc5576020825192015190565b60405163071c628160e41b81526020816004817f0000000000000000000000004c15f778ab59f25d5dfd2dd508236a25ed2813fe6001600160a01b03165afa90811561320c576000916134b3575b50613455614d49565b60405163519074c360e11b8152600481019290925260248201526020816044817f000000000000000000000000b8ed155ab154b2dbadcc07b814cc52e92dc75ae16001600160a01b03165afa90811561320c576000916131dd575090565b90506020813d6020116134dd575b816134ce60209383613138565b81010312610bc557513861344c565b3d91506134c1565b604051906134f2826130fe565b60006101c0838281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a08201520152565b61355b6134e5565b5060018060a01b031680600052602c60205260406000209060405161357f816130e1565b60018060a01b0383541681526001830154602082015260ff60028401541692604082019384526003810154606083015260048101546080830152600581015460a083015260068101549060c0830191825260078101549460e08401958652600882015495610100850196875260098301546101208601908152600a840154610140870152600b840154610160870152600c840154610180870152600d840154956101a081019687526102a06015600e870154966101c08401978852600f8101546101e08501526010810154610200850152601181015461022085015260128101546102408501526013810154610260850152601481015461028085015201549101526040516370a0823160e01b815287600482015260208160248160018060a01b037f000000000000000000000000c0df50143ea93aec63e38a6ed4e92b378079ea15165afa90811561320c57600091613a03575b5088511115945142101591826139f5575b506136f09051613c36565b949095518681106000146139ed57935b51858110156139e6575b604051636e52ab1960e11b8152600481018690527f0000000000000000000000009b8a45c4a0fbd44158480d9b4b41e0bdca42874c6001600160a01b03169590936020856024818a5afa94851561320c576000956139b2575b5082156139a657604051630cddd73160e01b8152600481018490526020816024818b5afa90811561320c57600091613973575b5060ff600191975b5116149a8b613969575b8b61395f575b8b613955575b8b61394c575b8b613943575b8b613937575b516137d081614ce2565b602480546040516386e114bb60e01b81526004810187905291820187905263ffffffff1660448201819052909990969193919060208b606481845afa97881561320c578d9b600099613900575b506040516386e114bb60e01b8152600481019e909e5260248e018d905263ffffffff1660448e01528c6064815a93602094fa9b8c1561320c5760009c6138cc575b50613867613a35565b9c6040519e8f91613877836130fe565b82521515602082015260400152151560608d015260808c015260a08b015260c08a015260e08901526101008801526101208701526101408601526101608501526101808401526101a08301526101c082015290565b909b506020813d6020116138f8575b816138e860209383613138565b81010312610bc557519a3861385e565b3d91506138db565b9b50975060208b3d60201161392f575b8161391d60209383613138565b81010312610bc5578c9a51973861381d565b3d9150613910565b60018054149b506137c6565b9a50809a6137c0565b9a50839a6137ba565b8515159b506137b4565b8915159b506137ae565b8215159b506137a8565b90506020813d60201161399e575b8161398e60209383613138565b81010312610bc5575160ff613796565b3d9150613981565b600160ff60009761379e565b90946020823d6020116139de575b816139cd60209383613138565b8101031261011d5750519338613763565b3d91506139c0565b508461370a565b508593613700565b5142111591506136f06136e5565b90506020813d602011613a2d575b81613a1e60209383613138565b81010312610bc55751386136d4565b3d9150613a11565b60405163071c628160e41b81526020816004817f0000000000000000000000004c15f778ab59f25d5dfd2dd508236a25ed2813fe6001600160a01b03165afa90811561320c57600091613b1e575b50613a8c61315a565b90613a9561324a565b929091604051946312c1d01760e31b865260048601526024850152604484015260648301526084820152671a8aeb910d69800060a4820152671337cc4354f6000060c482015260208160e48160018060a01b037f000000000000000000000000b8ed155ab154b2dbadcc07b814cc52e92dc75ae1165afa90811561320c576000916131dd575090565b90506020813d602011613b48575b81613b3960209383613138565b81010312610bc5575138613a83565b3d9150613b2c565b6040516370a0823160e01b815230600482015260208160248173bc7755a153e852cf76cccddb4c2e7c368f6259d85afa90811561320c57600091613bd3575b50906040516370a0823160e01b8152306004820152602081602481735babfc2f240bc5de90eb7e19d789412db1dec4025afa90811561320c576000916131dd575090565b90506020813d602011613bfd575b81613bee60209383613138565b81010312610bc5575138613b8f565b3d9150613be1565b15613c0c57565b60405162461bcd60e51b8152602060048201526002602482015261646560f01b6044820152606490fd5b60405163071c628160e41b81529091906020816004817f0000000000000000000000004c15f778ab59f25d5dfd2dd508236a25ed2813fe6001600160a01b03165afa90811561320c57600091613e5f575b50613c90614d49565b613c9b8215156133b7565b613ca68115156133b7565b613cae61315a565b9163ffffffff602454169360405196636676fcb560e11b88526004880152602487015260448601526064850152608484015260a483015260a08260c481600180851b037f000000000000000000000000b8ed155ab154b2dbadcc07b814cc52e92dc75ae1165afa91821561320c576000908193613e25575b508015613e1d5760405163cc878ed960e01b815260048101919091526020816024817f0000000000000000000000009b8a45c4a0fbd44158480d9b4b41e0bdca42874c6001600160a01b03165afa90811561320c57600091613deb575b505b918015613de557604051630979d0cb60e41b815260048101919091526020816024817f0000000000000000000000009b8a45c4a0fbd44158480d9b4b41e0bdca42874c6001600160a01b03165afa90811561320c576000916131dd575090565b50600090565b90506020813d602011613e15575b81613e0660209383613138565b81010312610bc5575138613d83565b3d9150613df9565b506000613d85565b925060a0833d60a011613e57575b81613e4060a09383613138565b8101031261011d5750602082519201519138613d26565b3d9150613e33565b906020823d602011613e89575b81613e7960209383613138565b8101031261011d57505138613c87565b3d9150613e6c565b60405163071c628160e41b8152906020826004817f0000000000000000000000004c15f778ab59f25d5dfd2dd508236a25ed2813fe6001600160a01b03165afa91821561320c57600092613fd3575b50613ee961315a565b60248054604051631a5fb62360e21b8152600481019690965290850192909252604484015263ffffffff16606483015260e0826084817f000000000000000000000000b8ed155ab154b2dbadcc07b814cc52e92dc75ae16001600160a01b03165afa90811561320c5760008093819382938380938193613f6e575b5096959493929190565b96509450955050505060e0823d60e011613fcb575b81613f9060e09383613138565b8101031261011d57508051602082015160408301516060840151608085015160a086015160c090960151939692959194909391929038613f64565b3d9150613f83565b9091506020813d602011613fff575b81613fef60209383613138565b81010312610bc557519038613ee0565b3d9150613fe2565b6140128115156133b7565b60405163071c628160e41b81526020816004817f0000000000000000000000004c15f778ab59f25d5dfd2dd508236a25ed2813fe6001600160a01b03165afa801561320c576000906140e9575b6020915061406b614d49565b906140778115156133b7565b6140828215156133b7565b6040516378e3b7d360e01b8152600481019190915260248101919091526044810192909252816064816001600160a01b037f000000000000000000000000b8ed155ab154b2dbadcc07b814cc52e92dc75ae1165afa90811561320c576000916131dd575090565b6020823d602011614114575b8161410260209383613138565b8101031261011d57506020905161405f565b3d91506140f5565b9060618202918083046061149015171561013257565b8181029291811591840414171561013257565b9061414e6134e5565b506040516370a0823160e01b81526001600160a01b03928316600482018190529092602090849060249082907f000000000000000000000000c0df50143ea93aec63e38a6ed4e92b378079ea15165afa92831561320c57600093614498575b5080600052602c60205260406000206040516141c8816130e1565b60018060a01b038254168152600182015460208201526102a0601560ff600285015416938460408501526003810154606085015260048101546080850152600581015460a0850152600681015460c0850152600781015460e085015260088101546101008501526009810154610120850152600a810154610140850152600b810154610160850152600c810154610180850152600d8101546101a0850152600e8101546101c0850152600f8101546101e0850152601081015461020085015260118101546102208501526012810154610240850152601381015461026085015260148101546102808501520154910152602054908160640360648111610132576142d460649186614132565b04926142df84613c36565b90602154956142ee8742613301565b93602254986142fd8a87613301565b96601e548210159b8c61448b575b8c61446c575b8c614462575b8c614457575b508b61444b575b90614371959493929161433682614ce2565b602480546040516386e114bb60e01b81526004810189905291820189905263ffffffff16604482015297909390602090899081906064820190565b03817f0000000000000000000000009b8a45c4a0fbd44158480d9b4b41e0bdca42874c6001600160a01b03165afa97881561320c57600098614417575b5060206040519e8f926143c0846130fe565b835215159101526001811460408e01521560608d015260808c015260a08b015260c08a015260e08901526101008801526101208701526101408601526101608501526101808401526101a08301526101c082015290565b9097506020813d602011614443575b8161443360209383613138565b81010312610bc5575196386143ae565b3d9150614426565b60018054149b50614324565b8211159b503861431d565b8515159c50614317565b73507fbde39ba40da4fc79426ad5e3c64944fe43d48414159c50614311565b601f548311159c5061430b565b9092506020813d6020116144c4575b816144b460209383613138565b81010312610bc5575191386141ad565b3d91506144a7565b156144d357565b60405162461bcd60e51b8152602060048201526002602482015261636f60f01b6044820152606490fd5b6102043563ffffffff81168103610bc55790565b9060006103a06040516145238161311b565b828152606060208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a0820152826101c0820152826101e08201528261020082015282610220820152826102408201528261026082015282610280820152826102a0820152826102c0820152826102e0820152826103008201528261032082015282610340820152826103608201528261038082015201526014548110156106a0526106a051614c66575b6018546106005261460d6106005142613301565b601954610620526146216106205142613301565b601d54610680526146356106805142613301565b91601a5461064052606461464c6106405186614132565b0494601c546106605260646146646106605187614132565b046106e05261467161324a565b6105c0526105a052606461468b6105c0516105a051613301565b146107a0526017546105e05260646146a66105e05187614132565b046107005260646146b9601b5487614132565b046107205260646146d06105a05161070051614132565b0460646146e36105c05161070051614132565b046107805260646146fa6105a05161072051614132565b046108205260646147116105c05161072051614132565b04610520526147236108205182613301565b610760526147376105205161078051613301565b6107e052600061080052610800516107c0526108005161074052610800516106c0526107005115801590614c5a575b6149c3575b506000614779612f46612ff6565b9061478a6107c05161080051613301565b61479a6106c05161074051613301565b91101591826149b8575b50506149b0575b6000906107a0516107a0516149a6575b8061499f575b614977575b8115158061496c575b6147d883614ce2565b93604051610580526147ec6105805161311b565b60018060a01b0316610580515260409081516148088382613138565b60018152606f60f81b602082015260206105805101521515906105805101526106a051151560606105805101526107a0516080610580510152151560a061058051015260c061058051015260e06105805101526101006105805101526101206105805101526101406105805101526101606105805101526101806105805101526106e0516101a0610580510152610700516101c0610580510152610720516101e0610580510152610760516102006105805101526107e051610220610580510152610800516102406105805101526107c051610260610580510152610740516102806105805101526106c0516102a06105805101526105a0516102c06105805101526105c0516102e06105805101526105e05161030061058051015261060051610320610580510152610620516103406105805101526106405161036061058051015261066051610380610580510152610680516103a06105805101526105805190565b5060018054146147cf565b905061499961499461070051606461498e8a61411c565b04613301565b614007565b906147c6565b50806147c1565b506106a0516147bb565b5060016147ab565b1015905038806147a4565b6024805460405163036651af60e61b8152670de0b6b3a7640000600482015263ffffffff9091169181018290526020816044816001600160a01b037f0000000000000000000000009b8a45c4a0fbd44158480d9b4b41e0bdca42874c165afa8015614c18576108005161056052614c26575b5060405163433effe960e11b8152670de0b6b3a7640000600482015260248101919091526020816044817f0000000000000000000000009b8a45c4a0fbd44158480d9b4b41e0bdca42874c6001600160a01b03165afa8015614c18576108005161054052614bdd575b5061056051614b49575b5061054051614ab8575b3861476b565b61078051670de0b6b3a7640000610780510204670de0b6b3a7640000146107805115171561013257614afa61054051670de0b6b3a76400006107805102613397565b6107405261052051670de0b6b3a7640000610520510204670de0b6b3a7640000146105205115171561013257614b4061054051670de0b6b3a76400006105205102613397565b6106c052614ab2565b80670de0b6b3a7640000810204670de0b6b3a76400001481151715614bc35761056051614b7f91670de0b6b3a764000002613397565b61080052670de0b6b3a76400006108205102610820518104670de0b6b3a764000014610820511517156101325761056051614bb991613397565b6107c05238614aa8565b634e487b7160e01b61080051526011600452602461080051fd5b6020813d602011614c10575b81614bf660209383613138565b81010312614c0957516105405238614a9e565b6108005180fd5b3d9150614be9565b6040513d61080051823e3d90fd5b6020813d602011614c52575b81614c3f60209383613138565b81010312614c0957516105605238614a35565b3d9150614c32565b50610720511515614766565b6015548111156106a0526145f9565b63ffffffff602454166040519063ea40c34760e01b8252670de0b6b3a76400006004830152602482015260208160448160018060a01b037f0000000000000000000000009b8a45c4a0fbd44158480d9b4b41e0bdca42874c165afa90811561320c576000916131dd575090565b6024805460405163ea40c34760e01b8152600481019390935263ffffffff16908201526020816044816001600160a01b037f0000000000000000000000009b8a45c4a0fbd44158480d9b4b41e0bdca42874c165afa90811561320c576000916131dd575090565b614d5161315a565b908015614ea857602480546040516357bcec0f60e01b8152600481019390935263ffffffff16908201526020816044816001600160a01b037f0000000000000000000000009b8a45c4a0fbd44158480d9b4b41e0bdca42874c165afa90811561320c57600091614e76575b505b8115614e695760248054604051632792a1d760e11b8152600481019490945263ffffffff16908301526020826044816001600160a01b037f0000000000000000000000009b8a45c4a0fbd44158480d9b4b41e0bdca42874c165afa801561320c57600090614e35575b614e32925090613301565b90565b506020823d602011614e61575b81614e4f60209383613138565b81010312610bc557614e329151614e27565b3d9150614e42565b614e329150600090613301565b90506020813d602011614ea0575b81614e9160209383613138565b81010312610bc5575138614dbc565b3d9150614e84565b506000614dbe565b90816020910312610bc557516001600160a01b0381168103610bc55790565b614ed76134e5565b5081600052602b60205260406000209060405190614ef4826130a7565b825482526001830154602083015260ff60028401541690604083019182526003840160405190816000825492614f298461325d565b80845293600181169081156154585750600114615411575b50614f4e92500382613138565b606084015260018060a01b03600485015416926080810193845260018060a01b0360058601541660a082015260018060a01b0360068601541660c0820152600785015460e082015260088501546101008201526009850154906101208101918252600a860154936101408201948552600b870154906101608301918252600c880154610180840152600d8801546101a0840152600e880154976101c08401988952600f8101546101e08501526010810154926102008501938452600160ff6011840154946102208801958652601285015497610240810198895261048060246013880154976102608401988952601481015461028085015260158101546102a085015260168101546102c085015260178101546102e085015260188101546103008501526019810154610320850152601a810154610340850152601b810154610360850152601c810154610380850152601d8101546103a0850152601e8101546103c0850152601f8101546103e085015260208101546104008501526021810154610420850152602281015461044085015260238101546104608501520154910152511614958661536f575b8680985097615363575b5086615357575b859697869761534b575b508661533f575b9185939184938495615333575b5084615327575b83949560009561526d575b505060009061514861547a565b9661524c575b506000948597869387956151fc575b50615166613a35565b9960009b60009d866151ec575b50516040519e8f92916001600160a01b031661518e846130fe565b8352602083015215159060400152151560608d0152151560808c0152151560a08b015260c08a015260e089015261010088015261012087015261014086015261016085015261018084015215156101a083015215156101c082015290565b518c109d508887119c5038615173565b96509350915083948380615242575b61522b575b5061521a85614007565b9161522483614ce2565b933861515d565b51909650935061523b8385612fb8565b9538615210565b508051851061520b565b9050615263606461525c8661411c565b0487613301565b905111153861514e565b51905160248054604051632581316f60e11b815260048101949094529083019190915263ffffffff16604482015290939192506020816064816001600160a01b037f000000000000000000000000b8ed155ab154b2dbadcc07b814cc52e92dc75ae1165afa9182156121d05790818794936152ed575b505092388061513b565b91509192506020823d60201161531f575b8161530b60209383613138565b8101031261011d57509084915138806152e3565b3d91506152fe565b60018054149450615130565b51421015945038615129565b6001805414965061511c565b51421015965038615115565b6001805414965061510b565b51421015965038615104565b6040516331a9108f60e11b8152600481018d905291979096506020826024817f000000000000000000000000e29a221ac6e69927161c3dfcc663f751194211786001600160a01b03165afa91821561320c576000926153e0575b506001600160a01b039182169116149486906150fa565b61540391925060203d60201161540a575b6153fb8183613138565b810190614eb0565b90386153c9565b503d6153f1565b90506000929192526020600020906000915b81831061543c575050906020614f4e9282010138614f41565b6020919350806001915483858801015201910190918392615423565b905060209250614f4e94915060ff191682840152151560051b82010138614f41565b6040516370a0823160e01b815230600482015260208160248173833589fcd6edb6e08f4c7c32d4f71b54bda029135afa90811561320c576000916131dd575090565b919061030052610380526154d9816154d261547a565b10156133b7565b6154e38133614511565b610500526154ff604061050051015160006103405215156132d0565b610300516020610500510152615513613b50565b6102c0610500939293510151906102e061050051015160235490607842014211615e87576040519363f863485b60e01b85528560048601526024850152604484015280606484015260848301526078420160a483015260408260c4816103405160018060a01b037f00000000000000000000000003fee5ba01d5b71c7f7689490826ba75a2750c44165af1938415615c5f5761034051926103405195615ea1575b50916155d4816100dc876155e395610edd6155f3986100dc610ed5613b50565b61024061050051015190613301565b9261028061050051015190613301565b9161560081600354613301565b60035561560f83600454613301565b60045560055492600184018411615e87578391610100610500510151610120610500510151610140610500510151615645614c75565b61564d6133fe565b615655613a35565b9161016061050051015193610180610500510151956101a061050051015197600160c06105005101519c6101c06105005101516102c0526102406105005101516104e0526102806105005101516104c0526101e06105005101516104a052610260610500510151610480526102a0610500510151610460526102c0610500510151610440526102e061050051015161042052610300610500510151610400526103206105005101516103e0526103406105005101516103c0526103606105005101516103a052610380610500510151610360526103a0610500510151610320526040516102e0526157486102e0516130a7565b016102e05152600160206102e0510152600160406102e05101526103005160606102e05101523360806102e05101526103405160a06102e051015260018060a01b03610380511660c06102e05101524260e06102e0510152426101006102e05101526101206102e05101526101406102e05101526101606102e05101526101806102e05101526101a06102e05101526101c06102e05101526101e06102e05101526102006102e05101526102206102e05101526102406102e05101526102606102e05101526102806102e0510152610340516102a06102e0510152610340516102c06102e05101526102c0516102e0805101526104e0516103006102e05101526104c0516103206102e05101526104a0516103406102e0510152610480516103606102e0510152610460516103806102e0510152610440516103a06102e0510152610420516103c06102e0510152610400516103e06102e05101526103e0516104006102e05101526103c0516104206102e05101526103a0516104406102e0510152610360516104606102e0510152610320516104806102e0510152600182016103405152602b602052604061034051206102e05151815560206102e0510151600182015560ff60406102e05101511660ff60028301911660ff1982541617905560606102e051015180519067ffffffffffffffff8211615e6d57615950600384015461325d565b601f8111615e20575b506020906001601f841114615da657918091615b629594936103405192615d9b575b50508160011b916000199060031b1c19161760038201555b6102e0805160808101516004840180546001600160a01b03199081166001600160a01b039384161790915560a08301516005808701805484169285169290921790915560c0840151600687018054909316931692909217905560e0820151600785015561010082015160088501556101208201516009850155610140820151600a850155610160820151600b850155610180820151600c8501556101a0820151600d8501556101c0820151600e8501556101e0820151600f850155610200820151601085015561022082015160118501556102408201516012850155610260820151601385015561028082015160148501556102a082015160158501556102c0820151601685015591810151601784015561030081015160188401556103208101516019840155610340810151601a840155610360810151601b840155610380810151601c8401556103a0810151601d8401556103c0810151601e8401556103e0810151601f8401556104008101516020840155610420810151602184015561044081015160228401556104608101516023840155610480015160249092019190915554615b409061333f565b600555615b576101a0610500510151600e54613301565b600e55600b54613301565b600b55615b796101c0610500510151600c54613301565b600c55615b906101e0610500510151600d54613301565b600d5561026061050051015115801590615d8a575b615c74575b7f000000000000000000000000e29a221ac6e69927161c3dfcc663f751194211786001600160a01b031690813b15615c6d576040516340c10f1960e01b81526103408051336004840152600184016024840152905191939091849160449183915af1918215615c5f57600192615c4c575b50016025819055610340517ff244c95a01cd7c2eb6b82c48d18918858df587f10f2c3c2cb5675f5d102f26ce9080a2565b61034051615c5991613138565b38615c1b565b6040513d61034051823e3d90fd5b6103405180fd5b615cc4615c7f61315a565b610500516102608101516102a09091015160408051636de19f8b60e01b8152600481019390935260248301919091524260780160448301529093849081906064820190565b03816103405160018060a01b037f00000000000000000000000003fee5ba01d5b71c7f7689490826ba75a2750c44165af1928315615c5f5761034051906103405194615d66575b50615d1461315a565b93610260610500510151615d51575b5050506102a0610500510151615d3c575b505050615baa565b615d49926100dc91613301565b388080615d34565b615d5e926100dc91613301565b388080615d23565b9050615d8291935060403d60401161119e5761118e8183613138565b929038615d0b565b506102a06105005101511515615ba5565b01519050388061597b565b9060038401610340515280610340512091610340515b601f1985168110615e085750918391600193615b62979695601f19811610615def575b505050811b016003820155615993565b015160001960f88460031b161c19169055388080615ddf565b91926020600181928685015181550194019201615dbc565b60038401610340515260206103405120601f840160051c810160208510615e66575b601f830160051c82018110615e58575050615959565b610340518155600101615e42565b5080615e42565b634e487b7160e01b61034051526041600452602461034051fd5b634e487b7160e01b61034051526011600452602461034051fd5b610edd95506155f393506155e392916100dc615ece6155d49360403d60401161119e5761118e8183613138565b9850955092935091506155b4565b604051632b74522360e21b81526020816004817f0000000000000000000000004c15f778ab59f25d5dfd2dd508236a25ed2813fe6001600160a01b03165afa90811561320c57600091615f3c575b506001600160a01b0391821691161490565b615f55915060203d60201161540a576153fb8183613138565b38615f2a56fea2646970667358221220513e59ed246b9f486f319985ea891534a3ccd72f4ad485c19c63ce177821db4964736f6c634300081a0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000004c15f778ab59f25d5dfd2dd508236a25ed2813fe000000000000000000000000c0df50143ea93aec63e38a6ed4e92b378079ea150000000000000000000000009b8a45c4a0fbd44158480d9b4b41e0bdca42874c000000000000000000000000b8ed155ab154b2dbadcc07b814cc52e92dc75ae100000000000000000000000003fee5ba01d5b71c7f7689490826ba75a2750c44000000000000000000000000e29a221ac6e69927161c3dfcc663f75119421178

-----Decoded View---------------
Arg [0] : rce (address): 0x4C15F778Ab59F25D5dFD2dD508236a25eD2813fe
Arg [1] : rage (address): 0xc0df50143EA93AeC63e38A6ED4E92B378079eA15
Arg [2] : oracle (address): 0x9B8a45C4A0fBD44158480D9b4B41e0bdCA42874C
Arg [3] : calc (address): 0xb8ed155Ab154B2DBadcC07b814CC52e92DC75ae1
Arg [4] : swap (address): 0x03FEe5bA01D5B71c7F7689490826Ba75a2750c44
Arg [5] : rOption (address): 0xe29a221Ac6e69927161c3DFCC663f75119421178

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000004c15f778ab59f25d5dfd2dd508236a25ed2813fe
Arg [1] : 000000000000000000000000c0df50143ea93aec63e38a6ed4e92b378079ea15
Arg [2] : 0000000000000000000000009b8a45c4a0fbd44158480d9b4b41e0bdca42874c
Arg [3] : 000000000000000000000000b8ed155ab154b2dbadcc07b814cc52e92dc75ae1
Arg [4] : 00000000000000000000000003fee5ba01d5b71c7f7689490826ba75a2750c44
Arg [5] : 000000000000000000000000e29a221ac6e69927161c3dfcc663f75119421178


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.